Initialize with contents in the Flutter buildroot.

Imported from https://github.com/flutter/buildroot/tree/430b57c643883e6090b5af09faddd8048efee57c.

Only an extra .gitignore has been added.

Change-Id: Ibca759b00d2d894e714ef5743b15bbc4c63086e4
Reviewed-on: https://flutter-review.googlesource.com/c/third_party/libxml/+/24223
Reviewed-by: Jason Simmons <jsimmons@google.com>
Commit-Queue: Chinmay Garde <chinmaygarde@google.com>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1953972
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,26 @@
+# commonly generated files
+*.pyc
+*~
+.*.sw?
+.ccls-cache
+.checkstyle
+.clangd
+.classpath
+.cproject
+.DS_Store
+.gdb_history
+.gdbinit
+.idea
+.ignore
+.landmines
+.packages
+.project
+.pub
+.pydevproject
+.vscode
+.cache
+compile_commands.json
+cscope.*
+Session.vim
+tags
+Thumbs.db
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..f03d3ae
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,184 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Define an "os_include" variable that points at the OS-specific generated
+# headers.  These were generated by running the configure script offline.
+if (is_linux || is_android || is_nacl) {
+  os_include = "linux"
+} else if (is_mac || is_ios) {
+  os_include = "mac"
+} else if (is_win) {
+  os_include = "win32"
+}
+
+config("libxml_config") {
+  # Define LIBXML_STATIC as nothing to match how libxml.h (an internal header)
+  # defines LIBXML_STATIC, otherwise we get the macro redefined warning from
+  # GCC. ("defines" does "-DFOO" which defines the macro FOO as 1.)
+  cflags = [ "-DLIBXML_STATIC=" ]
+
+  include_dirs = [
+    "src/include",
+    "$os_include/include",
+  ]
+}
+
+static_library("libxml") {
+  output_name = "libxml2"
+  sources = [
+    "chromium/libxml_utils.cc",
+    "chromium/libxml_utils.h",
+    "linux/config.h",
+    "linux/include/libxml/xmlversion.h",
+    "mac/config.h",
+    "mac/include/libxml/xmlversion.h",
+    "src/DOCBparser.c",
+    "src/HTMLparser.c",
+    "src/HTMLtree.c",
+    "src/SAX.c",
+    "src/SAX2.c",
+    "src/acconfig.h",
+    "src/c14n.c",
+    "src/catalog.c",
+    "src/chvalid.c",
+    "src/debugXML.c",
+    "src/dict.c",
+    "src/elfgcchack.h",
+    "src/encoding.c",
+    "src/entities.c",
+    "src/error.c",
+    "src/globals.c",
+    "src/hash.c",
+    "src/include/libxml/DOCBparser.h",
+    "src/include/libxml/HTMLparser.h",
+    "src/include/libxml/HTMLtree.h",
+    "src/include/libxml/SAX.h",
+    "src/include/libxml/SAX2.h",
+    "src/include/libxml/c14n.h",
+    "src/include/libxml/catalog.h",
+    "src/include/libxml/chvalid.h",
+    "src/include/libxml/debugXML.h",
+    "src/include/libxml/dict.h",
+    "src/include/libxml/encoding.h",
+    "src/include/libxml/entities.h",
+    "src/include/libxml/globals.h",
+    "src/include/libxml/hash.h",
+    "src/include/libxml/list.h",
+    "src/include/libxml/parser.h",
+    "src/include/libxml/parserInternals.h",
+    "src/include/libxml/pattern.h",
+    "src/include/libxml/relaxng.h",
+    "src/include/libxml/schemasInternals.h",
+    "src/include/libxml/schematron.h",
+    "src/include/libxml/threads.h",
+    "src/include/libxml/tree.h",
+    "src/include/libxml/uri.h",
+    "src/include/libxml/valid.h",
+    "src/include/libxml/xinclude.h",
+    "src/include/libxml/xlink.h",
+    "src/include/libxml/xmlIO.h",
+    "src/include/libxml/xmlautomata.h",
+    "src/include/libxml/xmlerror.h",
+    "src/include/libxml/xmlexports.h",
+    "src/include/libxml/xmlmemory.h",
+    "src/include/libxml/xmlmodule.h",
+    "src/include/libxml/xmlreader.h",
+    "src/include/libxml/xmlregexp.h",
+    "src/include/libxml/xmlsave.h",
+    "src/include/libxml/xmlschemas.h",
+    "src/include/libxml/xmlschemastypes.h",
+    "src/include/libxml/xmlstring.h",
+    "src/include/libxml/xmlunicode.h",
+    "src/include/libxml/xmlwriter.h",
+    "src/include/libxml/xpath.h",
+    "src/include/libxml/xpathInternals.h",
+    "src/include/libxml/xpointer.h",
+    "src/include/win32config.h",
+    "src/include/wsockcompat.h",
+    "src/legacy.c",
+    "src/libxml.h",
+    "src/list.c",
+    "src/parser.c",
+    "src/parserInternals.c",
+    "src/pattern.c",
+    "src/relaxng.c",
+    "src/schematron.c",
+    "src/threads.c",
+    "src/tree.c",
+
+    #"src/trio.c",
+    #"src/trio.h",
+    #"src/triodef.h",
+    #"src/trionan.c",
+    #"src/trionan.h",
+    #"src/triop.h",
+    #"src/triostr.c",
+    #"src/triostr.h",
+    "src/uri.c",
+    "src/valid.c",
+    "src/xinclude.c",
+    "src/xlink.c",
+    "src/xmlIO.c",
+    "src/xmlmemory.c",
+    "src/xmlmodule.c",
+    "src/xmlreader.c",
+    "src/xmlregexp.c",
+    "src/xmlsave.c",
+    "src/xmlschemas.c",
+    "src/xmlschemastypes.c",
+    "src/xmlstring.c",
+    "src/xmlunicode.c",
+    "src/xmlwriter.c",
+    "src/xpath.c",
+    "src/xpointer.c",
+    "win32/config.h",
+    "win32/include/libxml/xmlversion.h",
+  ]
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+
+  public_configs = [ ":libxml_config" ]
+  public_deps = [
+    "//third_party/icu:icuuc",
+  ]
+  deps = [
+    "//third_party/zlib",
+  ]
+
+  if (is_win) {
+    cflags_c = [ "/wd4101" ]  # Unreferenced local variable.
+  } else if (is_mac || is_android) {
+    # http://www.xmlsoft.org/threads.html says that this is required when using
+    # libxml from several threads, which can possibly happen in chrome. On
+    # linux, this is picked up by transitivity from pkg-config output from
+    # build/linux/system.gyp.
+    defines = [ "_REENTRANT" ]
+  }
+
+  if (is_clang) {
+    cflags = [
+      # libxml passes `const unsigned char*` through `const char*`.
+      "-Wno-pointer-sign",
+
+      # pattern.c and uri.c both have an intentional `for (...);` /
+      # `while(...);` loop. I submitted a patch to move the `'` to its own
+      # line, but until that's landed suppress the warning:
+      "-Wno-empty-body",
+
+      # debugXML.c compares array 'arg' to NULL.
+      "-Wno-tautological-pointer-compare",
+
+      # threads.c attempts to forward declare a pthread_equal which doesn't
+      # match the prototype in pthreads.h
+      "-Wno-ignored-attributes",
+
+      # Comparison between xmlElementType and xmlXPathTypeVal.
+      # TODO(hans): See if we can fix upstream (http://crbug.com/763944).
+      "-Wno-enum-compare",
+    ]
+  }
+
+  include_dirs = [ "$os_include" ]
+}
diff --git a/DEPS b/DEPS
new file mode 100644
index 0000000..6dcfa15
--- /dev/null
+++ b/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  '+libxml',
+]
diff --git a/README.chromium b/README.chromium
new file mode 100644
index 0000000..1f3162f
--- /dev/null
+++ b/README.chromium
@@ -0,0 +1,62 @@
+Name: libxml
+URL: http://xmlsoft.org
+Version: 2.7.7
+License: MIT
+License File: src/Copyright
+Security Critical: yes
+
+Description:
+The src/ directory contains a partial snapshot of the libxml library
+with the patches in the patches/ directories applied.
+See the files in that directory for discussion of their effects.
+
+Current version: 2.7.7.
+
+Modifications:
+- Converted to utf-8 with: vim +"argdo write ++enc=utf-8" *.c
+- Import XPath fix http://git.gnome.org/browse/libxml2/commit/?id=91d19754d46acd4a639a8b9e31f50f31c78f8c9c
+- Import follow-on for above commit: http://git.gnome.org/browse/libxml2/commit/?id=ea90b894146030c214a7df6d8375310174f134b9
+- Import additional XPath fix http://git.gnome.org/browse/libxml2/commit/?id=df83c17e5a2646bd923f75e5e507bc80d73c9722
+- Import follow-on fix for above commit: http://git.gnome.org/browse/libxml2/commit/?id=fec31bcd452e77c10579467ca87a785b41115de6
+- And a follow-on fix to the previous two fixes, committed upstream: http://git.gnome.org/browse/libxml2/commit/?id=f5048b3e71fc30ad096970b8df6e7af073bae4cb (slightly differently, but we can drop our local fix on the next roll).
+- Add a fix for handling of unknown namespaces, commit upstream is pending.
+- Add fixes for ending the parse properly if a SAX callback calls xmlStopParser(), commit upstream is pending.
+- Add fix for entities, commit upstream is http://git.gnome.org/browse/libxml2/commit/?id=5bd3c061823a8499b27422aee04ea20aae24f03e
+- Import UTF-8 fix from upstream: http://git.gnome.org/browse/libxml2/commit/?id=0795348aeb86648723bc391e4d02e20631c10bca
+- Import XPath fix http://git.gnome.org/browse/libxml2/commit/xpath.c?id=2ddecc23862bab1a9a9e51e097aefc92ec305e28
+- Merge clang warning fix http://git.gnome.org/browse/libxml2/commit/?id=aae48e64dfbf2b46b157a4c1857e30645116388f
+- Add a fix for proper escaping of xpointer expressions, commit upstream is pending.
+- Add helper classes in chromium/libxml_utils.cc and chromium/include/libxml/libxml_utils.h.
+- Add a tweak to limit problems caused by excessive strings and buffers.
+- Change the xmlNs struct a little bit, so it looks like it has no children
+  if treated as a generic xmlNode object.
+- Fix pretty harmless use-after-free in generate-id function.
+- Merge a clang warning fix http://git.gnome.org/browse/libxml2/commit/?id=713434d2309da469d64b35e163ea6556dadccada
+- Import attribute normalization fix http://git.gnome.org/browse/libxml2/commit/?id=6a36fbe3b3e001a8a840b5c1fdd81cefc9947f0d
+- Merge a redundant comparison fix http://git.gnome.org/browse/libxml2/commit/?id=2af19f985b911b6dc6ada478ba8d201d2ddc9309
+- Merge a redundant comparisons fix https://git.gnome.org/browse/libxml2/commit/?id=eea38159be421dbafbee38f40e239f91734bc713
+- Merge XML_PARSER_EOF checks https://git.gnome.org/browse/libxml2/commit/?id=48b4cdde3483e054af8ea02e0cd7ee467b0e9a50 and https://git.gnome.org/browse/libxml2/commit/?id=e50ba8164eee06461c73cd8abb9b46aa0be81869
+- Prevent snprintf from being defined as _snprintf on VS 2015.
+- Make ucrt of Win10 SDK not define POSIX error codes.
+- Delete/disable nanoftp and nanohttp.
+
+To import a new snapshot of libxml:
+
+- Visit http://xmlsoft.org/downloads.html and download the latest source
+  distribution.
+- Copy the files into this directory, omitting files which have been omitted
+  here.  E.g.:  for i in $(find . -type f); do cp ../libxml-newver/$i $i; done
+  This should clobber all local changes to this directory.
+- Apply the patches in patches/ and fix any problems.
+  UPDATE THOSE PATCHES OR EVAN WILL HUNT YOU DOWN.
+- On a Linux system,
+    $ cd linux
+    $ ../configure --without-iconv --without-ftp --without-http
+  to generate config.h and include/libxml/xmlversion.h for Linux.
+- On a Mac,
+    $ cd mac
+    $ ../configure --without-iconv --without-ftp --without-http
+  to generate config.h and include/libxml/xmlversion.h for Macs.
+- On Windows, run build/generate-win32-headers.bat to re-generate config.h and
+  include/libxml/xmlversion.h for Windows builds.
+- Update this README to reflect the new version number.
diff --git a/build/generate-win32-headers.bat b/build/generate-win32-headers.bat
new file mode 100755
index 0000000..1d0f85d
--- /dev/null
+++ b/build/generate-win32-headers.bat
@@ -0,0 +1,9 @@
+REM Generate config.h and xmlversion.h.  We put the generated files in
+REM win32 so they don't get included on other platforms.
+
+cd %~dp0\..\win32
+cscript //E:jscript configure.js compiler=msvc iconv=no icu=yes
+move ..\config.h .
+
+md include\libxml
+move ..\include\libxml\xmlversion.h include\libxml\
diff --git a/chromium/libxml_utils.cc b/chromium/libxml_utils.cc
new file mode 100644
index 0000000..a237be5
--- /dev/null
+++ b/chromium/libxml_utils.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "libxml_utils.h"
+
+#include "libxml/xmlreader.h"
+
+std::string XmlStringToStdString(const xmlChar* xmlstring) {
+  // xmlChar*s are UTF-8, so this cast is safe.
+  if (xmlstring)
+    return std::string(reinterpret_cast<const char*>(xmlstring));
+  else
+    return "";
+}
+
+XmlReader::XmlReader() : reader_(NULL) {
+}
+
+XmlReader::~XmlReader() {
+  if (reader_)
+    xmlFreeTextReader(reader_);
+}
+
+bool XmlReader::Load(const std::string& input) {
+  const int kParseOptions = XML_PARSE_RECOVER |  // recover on errors
+                            XML_PARSE_NONET;     // forbid network access
+  // TODO(evanm): Verify it's OK to pass NULL for the URL and encoding.
+  // The libxml code allows for these, but it's unclear what effect is has.
+  reader_ = xmlReaderForMemory(input.data(), static_cast<int>(input.size()),
+                               NULL, NULL, kParseOptions);
+  return reader_ != NULL;
+}
+
+bool XmlReader::LoadFile(const std::string& file_path) {
+  const int kParseOptions = XML_PARSE_RECOVER |  // recover on errors
+                            XML_PARSE_NONET;     // forbid network access
+  reader_ = xmlReaderForFile(file_path.c_str(), NULL, kParseOptions);
+  return reader_ != NULL;
+}
+
+bool XmlReader::NodeAttribute(const char* name, std::string* out) {
+  xmlChar* value = xmlTextReaderGetAttribute(reader_, BAD_CAST name);
+  if (!value)
+    return false;
+  *out = XmlStringToStdString(value);
+  xmlFree(value);
+  return true;
+}
+
+bool XmlReader::IsClosingElement() {
+  return NodeType() == XML_READER_TYPE_END_ELEMENT;
+}
+
+bool XmlReader::ReadElementContent(std::string* content) {
+  const int start_depth = Depth();
+
+  if (xmlTextReaderIsEmptyElement(reader_)) {
+    // Empty tag.  We succesfully read the content, but it's
+    // empty.
+    *content = "";
+    // Advance past this empty tag.
+    if (!Read())
+      return false;
+    return true;
+  }
+
+  // Advance past opening element tag.
+  if (!Read())
+    return false;
+
+  // Read the content.  We read up until we hit a closing tag at the
+  // same level as our starting point.
+  while (NodeType() != XML_READER_TYPE_END_ELEMENT || Depth() != start_depth) {
+    *content += XmlStringToStdString(xmlTextReaderConstValue(reader_));
+    if (!Read())
+      return false;
+  }
+
+  // Advance past ending element tag.
+  if (!Read())
+    return false;
+
+  return true;
+}
+
+bool XmlReader::SkipToElement() {
+  do {
+    switch (NodeType()) {
+    case XML_READER_TYPE_ELEMENT:
+      return true;
+    case XML_READER_TYPE_END_ELEMENT:
+      return false;
+    default:
+      // Skip all other node types.
+      continue;
+    }
+  } while (Read());
+  return false;
+}
+
+
+// XmlWriter functions
+
+XmlWriter::XmlWriter()
+    : writer_(NULL),
+      buffer_(NULL) {}
+
+XmlWriter::~XmlWriter() {
+  if (writer_)
+    xmlFreeTextWriter(writer_);
+  if (buffer_)
+    xmlBufferFree(buffer_);
+}
+
+void XmlWriter::StartWriting() {
+  buffer_ = xmlBufferCreate();
+  writer_ = xmlNewTextWriterMemory(buffer_, 0);
+  xmlTextWriterSetIndent(writer_, 1);
+  xmlTextWriterStartDocument(writer_, NULL, NULL, NULL);
+}
+
+void XmlWriter::StopWriting() {
+  xmlTextWriterEndDocument(writer_);
+  xmlFreeTextWriter(writer_);
+  writer_ = NULL;
+}
diff --git a/chromium/libxml_utils.h b/chromium/libxml_utils.h
new file mode 100644
index 0000000..9091f49
--- /dev/null
+++ b/chromium/libxml_utils.h
@@ -0,0 +1,180 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_
+#define THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_
+#pragma once
+
+#include <string>
+
+#include "libxml/xmlreader.h"
+#include "libxml/xmlwriter.h"
+
+// Converts a libxml xmlChar* into a UTF-8 std::string.
+// NULL inputs produce an empty string.
+std::string XmlStringToStdString(const xmlChar* xmlstring);
+
+// libxml uses a global error function pointer for reporting errors.
+// A ScopedXmlErrorFunc object lets you change the global error pointer
+// for the duration of the object's lifetime.
+class ScopedXmlErrorFunc {
+ public:
+  ScopedXmlErrorFunc(void* context, xmlGenericErrorFunc func) {
+    old_error_func_ = xmlGenericError;
+    old_error_context_ = xmlGenericErrorContext;
+    xmlSetGenericErrorFunc(context, func);
+  }
+  ~ScopedXmlErrorFunc() {
+    xmlSetGenericErrorFunc(old_error_context_, old_error_func_);
+  }
+
+ private:
+  xmlGenericErrorFunc old_error_func_;
+  void* old_error_context_;
+};
+
+// XmlReader is a wrapper class around libxml's xmlReader,
+// providing a simplified C++ API.
+class XmlReader {
+ public:
+  XmlReader();
+  ~XmlReader();
+
+  // Load a document into the reader from memory.  |input| must be UTF-8 and
+  // exist for the lifetime of this object.  Returns false on error.
+  // TODO(evanm): handle encodings other than UTF-8?
+  bool Load(const std::string& input);
+
+  // Load a document into the reader from a file.  Returns false on error.
+  bool LoadFile(const std::string& file_path);
+
+  // Wrappers around libxml functions -----------------------------------------
+
+  // Read() advances to the next node.  Returns false on EOF or error.
+  bool Read() { return xmlTextReaderRead(reader_) == 1; }
+
+  // Next(), when pointing at an opening tag, advances to the node after
+  // the matching closing tag.  Returns false on EOF or error.
+  bool Next() { return xmlTextReaderNext(reader_) == 1; }
+
+  // Return the depth in the tree of the current node.
+  int Depth() { return xmlTextReaderDepth(reader_); }
+
+  // Returns the "local" name of the current node.
+  // For a tag like <foo:bar>, this is the string "foo:bar".
+  std::string NodeName() {
+    return XmlStringToStdString(xmlTextReaderConstLocalName(reader_));
+  }
+
+  // When pointing at a tag, retrieves the value of an attribute.
+  // Returns false on failure.
+  // E.g. for <foo bar:baz="a">, NodeAttribute("bar:baz", &value)
+  // returns true and |value| is set to "a".
+  bool NodeAttribute(const char* name, std::string* value);
+
+  // Returns true if the node is a closing element (e.g. </foo>).
+  bool IsClosingElement();
+
+  // Helper functions not provided by libxml ----------------------------------
+
+  // Return the string content within an element.
+  // "<foo>bar</foo>" is a sequence of three nodes:
+  // (1) open tag, (2) text, (3) close tag.
+  // With the reader currently at (1), this returns the text of (2),
+  // and advances past (3).
+  // Returns false on error.
+  bool ReadElementContent(std::string* content);
+
+  // Skip to the next opening tag, returning false if we reach a closing
+  // tag or EOF first.
+  // If currently on an opening tag, doesn't advance at all.
+  bool SkipToElement();
+
+ private:
+  // Returns the libxml node type of the current node.
+  int NodeType() { return xmlTextReaderNodeType(reader_); }
+
+  // The underlying libxml xmlTextReader.
+  xmlTextReaderPtr reader_;
+};
+
+// XmlWriter is a wrapper class around libxml's xmlWriter,
+// providing a simplified C++ API.
+// StartWriting must be called before other methods, and StopWriting
+// must be called before GetWrittenString() will return results.
+class XmlWriter {
+ public:
+  XmlWriter();
+  ~XmlWriter();
+
+  // Allocates the xmlTextWriter and an xmlBuffer and starts an XML document.
+  // This must be called before any other functions. By default, indenting is
+  // set to true.
+  void StartWriting();
+
+  // Ends the XML document and frees the xmlTextWriter.
+  // This must be called before GetWrittenString() is called.
+  void StopWriting();
+  // Wrappers around libxml functions -----------------------------------------
+
+  // All following elements will be indented to match their depth.
+  void StartIndenting() { xmlTextWriterSetIndent(writer_, 1); }
+
+  // All follow elements will not be indented.
+  void StopIndenting() { xmlTextWriterSetIndent(writer_, 0); }
+
+  // Start an element with the given name. All future elements added will be
+  // children of this element, until it is ended. Returns false on error.
+  bool StartElement(const std::string& element_name) {
+    return xmlTextWriterStartElement(writer_,
+                                     BAD_CAST element_name.c_str()) >= 0;
+  }
+
+  // Ends the current open element. Returns false on error.
+  bool EndElement() {
+    return xmlTextWriterEndElement(writer_) >= 0;
+  }
+
+  // Appends to the content of the current open element.
+  bool AppendElementContent(const std::string& content) {
+    return xmlTextWriterWriteString(writer_,
+                                    BAD_CAST content.c_str()) >= 0;
+  }
+
+  // Adds an attribute to the current open element. Returns false on error.
+  bool AddAttribute(const std::string& attribute_name,
+                    const std::string& attribute_value) {
+    return xmlTextWriterWriteAttribute(writer_,
+                                       BAD_CAST attribute_name.c_str(),
+                                       BAD_CAST attribute_value.c_str()) >= 0;
+  }
+
+  // Adds a new element with name |element_name| and content |content|
+  // to the buffer. Example: <|element_name|>|content|</|element_name|>
+  // Returns false on errors.
+  bool WriteElement(const std::string& element_name,
+                    const std::string& content) {
+    return xmlTextWriterWriteElement(writer_,
+                                     BAD_CAST element_name.c_str(),
+                                     BAD_CAST content.c_str()) >= 0;
+  }
+
+  // Helper functions not provided by xmlTextWriter ---------------------------
+
+  // Returns the string that has been written to the buffer.
+  std::string GetWrittenString() {
+    if (buffer_ == NULL)
+      return "";
+    return XmlStringToStdString(buffer_->content);
+  }
+
+ private:
+  // The underlying libxml xmlTextWriter.
+  xmlTextWriterPtr writer_;
+
+  // Stores the output.
+  xmlBufferPtr buffer_;
+};
+
+#endif  // THIRD_PARTY_LIBXML_CHROMIUM_INCLUDE_LIBXML_LIBXML_UTILS_H_
diff --git a/linux/config.h b/linux/config.h
new file mode 100644
index 0000000..ca2f440
--- /dev/null
+++ b/linux/config.h
@@ -0,0 +1,312 @@
+/* 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.7"
+#define HAVE_LIBZ 1
+/* #undef HAVE_LIBM */
+#define HAVE_ISINF /**/
+#define HAVE_ISNAN /**/
+/* #undef HAVE_LIBHISTORY */
+/* #undef HAVE_LIBREADLINE */
+#define HAVE_LIBPTHREAD /**/
+#define HAVE_PTHREAD_H /**/
+
+/* Define if IPV6 support is there */
+#define SUPPORT_IP6 /**/
+
+/* Define if getaddrinfo is there */
+#define HAVE_GETADDRINFO /**/
+
+/* Define to 1 if you have the <ansidecl.h> header file. */
+/* #undef HAVE_ANSIDECL_H */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Whether struct sockaddr::__ss_family exists */
+/* #undef HAVE_BROKEN_SS_FAMILY */
+
+/* Define to 1 if you have the `class' function. */
+/* #undef HAVE_CLASS */
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Have dlopen based dso */
+#define HAVE_DLOPEN /**/
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the `fpclass' function. */
+/* #undef HAVE_FPCLASS */
+
+/* Define to 1 if you have the `fprintf' function. */
+#define HAVE_FPRINTF 1
+
+/* Define to 1 if you have the `fp_class' function. */
+/* #undef HAVE_FP_CLASS */
+
+/* Define to 1 if you have the <fp_class.h> header file. */
+/* #undef HAVE_FP_CLASS_H */
+
+/* Define to 1 if you have the `ftime' function. */
+#define HAVE_FTIME 1
+
+/* Define if getaddrinfo is there */
+#define HAVE_GETADDRINFO /**/
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+/* #undef HAVE_IEEEFP_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <inttypes.h.h> header file. */
+/* #undef HAVE_INTTYPES_H_H */
+
+/* Define if isinf is there */
+#define HAVE_ISINF /**/
+
+/* Define if isnan is there */
+#define HAVE_ISNAN /**/
+
+/* Define to 1 if you have the `isnand' function. */
+/* #undef HAVE_ISNAND */
+
+/* Define if history library is there (-lhistory) */
+/* #undef HAVE_LIBHISTORY */
+
+/* Define if pthread library is there (-lpthread) */
+#define HAVE_LIBPTHREAD /**/
+
+/* Define if readline library is there (-lreadline) */
+/* #undef HAVE_LIBREADLINE */
+
+/* Have compression library */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `localtime' function. */
+#define HAVE_LOCALTIME 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the <math.h> header file. */
+#define HAVE_MATH_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <nan.h> header file. */
+/* #undef HAVE_NAN_H */
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* 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 */
+#define HAVE_PTHREAD_H /**/
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Have shl_load based dso */
+/* #undef HAVE_SHLLOAD */
+
+/* Define to 1 if you have the `signal' function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `sprintf' function. */
+#define HAVE_SPRINTF 1
+
+/* Define to 1 if you have the `sscanf' function. */
+#define HAVE_SSCANF 1
+
+/* Define to 1 if you have the `stat' function. */
+#define HAVE_STAT 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* 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.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Whether va_copy() is available */
+#define HAVE_VA_COPY 1
+
+/* Define to 1 if you have the `vfprintf' function. */
+#define HAVE_VFPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `vsprintf' function. */
+#define HAVE_VSPRINTF 1
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#define HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the `_stat' function. */
+/* #undef HAVE__STAT */
+
+/* Whether __va_copy() is available */
+/* #undef HAVE___VA_COPY */
+
+/* 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"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* 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 ""
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#define PROTOTYPES 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Support for IPv6 */
+#define SUPPORT_IP6 /**/
+
+/* Version number of package */
+#define VERSION "2.7.7"
+
+/* Determine what socket length (socklen_t) data type is */
+#define XML_SOCKLEN_T socklen_t
+
+/* Using the Win32 Socket implementation */
+/* #undef _WINSOCKAPI_ */
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#define __PROTOTYPES 1
+
+/* Win32 Std C name mangling work-around */
+/* #undef snprintf */
+
+/* ss_family is not defined here, use __ss_family instead */
+/* #undef ss_family */
+
+/* Win32 Std C name mangling work-around */
+/* #undef vsnprintf */
diff --git a/linux/include/libxml/xmlversion.h b/linux/include/libxml/xmlversion.h
new file mode 100644
index 0000000..9e849fa
--- /dev/null
+++ b/linux/include/libxml/xmlversion.h
@@ -0,0 +1,467 @@
+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.7.7"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 20707
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "20707"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA ""
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * 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(20707);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 1
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if 1
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if 1
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if 1
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if 1
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if 1
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if 1
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if 1
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 0
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 0
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if 1
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 1
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if 1
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 1
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 1
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 1
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 1
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 1
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 1
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ICU_ENABLED:
+ *
+ * Whether icu support is available
+ */
+#if 1
+#define LIBXML_ICU_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if 1
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 1
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 1
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 1
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if 1
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION ".so" 
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if 1
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+
diff --git a/linux/xml2-config b/linux/xml2-config
new file mode 100755
index 0000000..799fc11
--- /dev/null
+++ b/linux/xml2-config
@@ -0,0 +1,106 @@
+#! /bin/sh
+
+prefix=/usr/local
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+usage()
+{
+    cat <<EOF
+Usage: xml2-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix=DIR		change libxml prefix [default $prefix]
+  --exec-prefix=DIR	change libxml exec prefix [default $exec_prefix]
+  --libs		print library linking information
+  --cflags		print pre-processor and compiler flags
+  --modules		module support enabled
+  --help		display this help and exit
+  --version		output version information
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+cflags=false
+libs=false
+
+while test $# -gt 0; do
+    case "$1" in
+    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) optarg= ;;
+    esac
+
+    case "$1" in
+    --prefix=*)
+	prefix=$optarg
+	includedir=$prefix/include
+	libdir=$prefix/lib
+	;;
+
+    --prefix)
+	echo $prefix
+	;;
+
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      libdir=$exec_prefix/lib
+      ;;
+
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+
+    --version)
+	echo 2.7.7
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+       	echo -I${includedir}/libxml2 
+       	;;
+
+    --libtool-libs)
+	if [ -r ${libdir}/libxml2.la ]
+	then
+	    echo ${libdir}/libxml2.la
+	fi
+        ;;
+
+    --modules)
+       	echo 1
+       	;;
+
+    --libs)
+        if [ "`uname`" = "Linux" ]
+	then
+	    if [ "-L${libdir}" = "-L/usr/lib" -o "-L${libdir}" = "-L/usr/lib64" ]
+	    then
+		echo -lxml2 -lz   -lm  
+	    else
+		echo -L${libdir} -lxml2 -lz   -lm  
+	    fi
+	else
+	    echo -L${libdir} -lxml2 -lz   -lm  
+	fi
+       	;;
+
+    *)
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+
+exit 0
diff --git a/mac/config.h b/mac/config.h
new file mode 100644
index 0000000..d647bf0
--- /dev/null
+++ b/mac/config.h
@@ -0,0 +1,312 @@
+/* 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.7"
+#define HAVE_LIBZ 1
+/* #undef HAVE_LIBM */
+#define HAVE_ISINF /**/
+#define HAVE_ISNAN /**/
+/* #undef HAVE_LIBHISTORY */
+/* #undef HAVE_LIBREADLINE */
+#define HAVE_LIBPTHREAD /**/
+#define HAVE_PTHREAD_H /**/
+
+/* Define if IPV6 support is there */
+#define SUPPORT_IP6 /**/
+
+/* Define if getaddrinfo is there */
+#define HAVE_GETADDRINFO /**/
+
+/* Define to 1 if you have the <ansidecl.h> header file. */
+/* #undef HAVE_ANSIDECL_H */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Whether struct sockaddr::__ss_family exists */
+/* #undef HAVE_BROKEN_SS_FAMILY */
+
+/* Define to 1 if you have the `class' function. */
+/* #undef HAVE_CLASS */
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Have dlopen based dso */
+#define HAVE_DLOPEN /**/
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the `fpclass' function. */
+/* #undef HAVE_FPCLASS */
+
+/* Define to 1 if you have the `fprintf' function. */
+#define HAVE_FPRINTF 1
+
+/* Define to 1 if you have the `fp_class' function. */
+/* #undef HAVE_FP_CLASS */
+
+/* Define to 1 if you have the <fp_class.h> header file. */
+/* #undef HAVE_FP_CLASS_H */
+
+/* Define to 1 if you have the `ftime' function. */
+#define HAVE_FTIME 1
+
+/* Define if getaddrinfo is there */
+#define HAVE_GETADDRINFO /**/
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+/* #undef HAVE_IEEEFP_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <inttypes.h.h> header file. */
+/* #undef HAVE_INTTYPES_H_H */
+
+/* Define if isinf is there */
+#define HAVE_ISINF /**/
+
+/* Define if isnan is there */
+#define HAVE_ISNAN /**/
+
+/* Define to 1 if you have the `isnand' function. */
+/* #undef HAVE_ISNAND */
+
+/* Define if history library is there (-lhistory) */
+/* #undef HAVE_LIBHISTORY */
+
+/* Define if pthread library is there (-lpthread) */
+#define HAVE_LIBPTHREAD /**/
+
+/* Define if readline library is there (-lreadline) */
+/* #undef HAVE_LIBREADLINE */
+
+/* Have compression library */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `localtime' function. */
+#define HAVE_LOCALTIME 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define to 1 if you have the <math.h> header file. */
+#define HAVE_MATH_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <nan.h> header file. */
+/* #undef HAVE_NAN_H */
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* 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 */
+#define HAVE_PTHREAD_H /**/
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Have shl_load based dso */
+/* #undef HAVE_SHLLOAD */
+
+/* Define to 1 if you have the `signal' function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `sprintf' function. */
+#define HAVE_SPRINTF 1
+
+/* Define to 1 if you have the `sscanf' function. */
+#define HAVE_SSCANF 1
+
+/* Define to 1 if you have the `stat' function. */
+#define HAVE_STAT 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strndup' function. */
+/* #undef HAVE_STRNDUP */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* 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.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Whether va_copy() is available */
+#define HAVE_VA_COPY 1
+
+/* Define to 1 if you have the `vfprintf' function. */
+#define HAVE_VFPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `vsprintf' function. */
+#define HAVE_VSPRINTF 1
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#define HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the `_stat' function. */
+/* #undef HAVE__STAT */
+
+/* Whether __va_copy() is available */
+/* #undef HAVE___VA_COPY */
+
+/* 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"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* 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 ""
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#define PROTOTYPES 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Support for IPv6 */
+#define SUPPORT_IP6 /**/
+
+/* Version number of package */
+#define VERSION "2.7.7"
+
+/* Determine what socket length (socklen_t) data type is */
+#define XML_SOCKLEN_T socklen_t
+
+/* Using the Win32 Socket implementation */
+/* #undef _WINSOCKAPI_ */
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#define __PROTOTYPES 1
+
+/* Win32 Std C name mangling work-around */
+/* #undef snprintf */
+
+/* ss_family is not defined here, use __ss_family instead */
+/* #undef ss_family */
+
+/* Win32 Std C name mangling work-around */
+/* #undef vsnprintf */
diff --git a/mac/include/libxml/xmlversion.h b/mac/include/libxml/xmlversion.h
new file mode 100644
index 0000000..9e849fa
--- /dev/null
+++ b/mac/include/libxml/xmlversion.h
@@ -0,0 +1,467 @@
+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.7.7"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 20707
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "20707"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA ""
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * 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(20707);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 1
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if 1
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if 1
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if 1
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if 1
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if 1
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if 1
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if 1
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 0
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 0
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if 1
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 1
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if 1
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 1
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 1
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 1
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 1
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 1
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 1
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ICU_ENABLED:
+ *
+ * Whether icu support is available
+ */
+#if 1
+#define LIBXML_ICU_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if 1
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 1
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 1
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 1
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if 1
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION ".so" 
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if 1
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+
diff --git a/patches/LoadLibraryA b/patches/LoadLibraryA
new file mode 100644
index 0000000..89fff15
--- /dev/null
+++ b/patches/LoadLibraryA
@@ -0,0 +1,16 @@
+Change 'LoadLibrary' to 'LoadLibraryA' (used with 'const char*' as an
+argument)
+
+Index: libxml/xmlmodule.c
+===================================================================
+--- libxml.orig/xmlmodule.c	2010-07-09 14:17:46.959288280 -0700
++++ libxml/xmlmodule.c	2010-07-09 14:17:55.419051003 -0700
+@@ -300,7 +300,7 @@
+ static void *
+ xmlModulePlatformOpen(const char *name)
+ {
+-    return LoadLibrary(name);
++    return LoadLibraryA(name);
+ }
+ 
+ /*
diff --git a/patches/bug_651202 b/patches/bug_651202
new file mode 100644
index 0000000..5f93fd7
--- /dev/null
+++ b/patches/bug_651202
@@ -0,0 +1,13 @@
+Fix for https://bugzilla.gnome.org/show_bug.cgi?id=651202
+
+--- libxml/xmlschemas.c.orig	Thu May 26 20:21:54 2011
++++ libxml/xmlschemas.c	Thu May 26 20:22:02 2011
+@@ -13946,7 +13946,7 @@
+     */
+     if ((sub->negNsSet != NULL) &&
+ 	(super->negNsSet != NULL) &&
+-	(sub->negNsSet->value == sub->negNsSet->value))
++	(sub->negNsSet->value == super->negNsSet->value))
+ 	return (0);
+     /*
+     * 3.1 sub must be a set whose members are either namespace names or �absent�.
diff --git a/patches/icu b/patches/icu
new file mode 100644
index 0000000..4503f92
--- /dev/null
+++ b/patches/icu
@@ -0,0 +1,453 @@
+Add code support for ICU.
+
+diff --git a/third_party/libxml/encoding.c b/third_party/libxml/encoding.c
+index b86a547..0f41df9 100644
+--- a/third_party/libxml/encoding.c
++++ b/third_party/libxml/encoding.c
+@@ -58,7 +58,7 @@ static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
+ static int xmlCharEncodingAliasesNb = 0;
+ static int xmlCharEncodingAliasesMax = 0;
+ 
+-#ifdef LIBXML_ICONV_ENABLED
++#if defined(LIBXML_ICONV_ENABLED) || defined(LIBXML_ICU_ENABLED)
+ #if 0
+ #define DEBUG_ENCODING  /* Define this to get encoding traces */
+ #endif
+@@ -97,6 +97,54 @@ xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val)
+                     NULL, 0, val, NULL, NULL, 0, 0, msg, val);
+ }
+ 
++#ifdef LIBXML_ICU_ENABLED
++static uconv_t* 
++openIcuConverter(const char* name, int toUnicode)
++{
++  UErrorCode status = U_ZERO_ERROR;
++  uconv_t *conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
++  if (conv == NULL)
++    return NULL;
++
++  conv->uconv = ucnv_open(name, &status);
++  if (U_FAILURE(status))
++    goto error;
++
++  status = U_ZERO_ERROR;
++  if (toUnicode) {
++    ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP, 
++                        NULL, NULL, NULL, &status);
++  }
++  else {
++    ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP, 
++                        NULL, NULL, NULL, &status);
++  }
++  if (U_FAILURE(status))
++    goto error;
++
++  status = U_ZERO_ERROR;
++  conv->utf8 = ucnv_open("UTF-8", &status);
++  if (U_SUCCESS(status))
++    return conv;
++
++error:
++  if (conv->uconv) 
++    ucnv_close(conv->uconv);
++  xmlFree(conv);
++  return NULL;
++}
++
++static void
++closeIcuConverter(uconv_t *conv)
++{
++  if (conv != NULL) {
++    ucnv_close(conv->uconv);
++    ucnv_close(conv->utf8);
++    xmlFree(conv);
++  }
++}
++#endif /* LIBXML_ICU_ENABLED */
++
+ /************************************************************************
+  *									*
+  *		Conversions To/From UTF8 encoding			*
+@@ -1306,7 +1354,11 @@ xmlNewCharEncodingHandler(const char *name,
+ #ifdef LIBXML_ICONV_ENABLED
+     handler->iconv_in = NULL;
+     handler->iconv_out = NULL;
+-#endif /* LIBXML_ICONV_ENABLED */
++#endif
++#ifdef LIBXML_ICU_ENABLED
++    handler->uconv_in = NULL;
++    handler->uconv_out = NULL;
++#endif
+ 
+     /*
+      * registers and returns the handler.
+@@ -1371,7 +1423,7 @@ xmlInitCharEncodingHandlers(void) {
+     xmlNewCharEncodingHandler("ASCII", asciiToUTF8, NULL);
+     xmlNewCharEncodingHandler("US-ASCII", asciiToUTF8, NULL);
+ #endif /* LIBXML_OUTPUT_ENABLED */
+-#ifndef LIBXML_ICONV_ENABLED
++#if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
+ #ifdef LIBXML_ISO8859X_ENABLED
+     xmlRegisterCharEncodingHandlersISO8859x ();
+ #endif
+@@ -1578,6 +1630,10 @@ xmlFindCharEncodingHandler(const char *name) {
+     xmlCharEncodingHandlerPtr enc;
+     iconv_t icv_in, icv_out;
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    xmlCharEncodingHandlerPtr enc;
++    uconv_t *ucv_in, *ucv_out;
++#endif /* LIBXML_ICU_ENABLED */
+     char upper[100];
+     int i;
+ 
+@@ -1647,6 +1703,35 @@ xmlFindCharEncodingHandler(const char *name) {
+ 		    "iconv : problems with filters for '%s'\n", name);
+     }
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    /* check whether icu can handle this */
++    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) {
++                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;
++#ifdef DEBUG_ENCODING
++            xmlGenericError(xmlGenericErrorContext,
++		    "Found ICU converter handler for encoding %s\n", name);
++#endif
++	    return enc;
++    } else if (ucv_in != NULL || ucv_out != NULL) {
++            closeIcuConverter(ucv_in);
++            closeIcuConverter(ucv_out);
++	    xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
++		    "ICU converter : problems with filters for '%s'\n", name);
++    }
++#endif /* LIBXML_ICU_ENABLED */
+ 
+ #ifdef DEBUG_ENCODING
+     xmlGenericError(xmlGenericErrorContext,
+@@ -1737,6 +1822,75 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
+ 
+ /************************************************************************
+  *									*
++ *		ICU based generic conversion functions	         	*
++ *									*
++ ************************************************************************/
++
++#ifdef LIBXML_ICU_ENABLED
++/**
++ * xmlUconvWrapper:
++ * @cd: ICU uconverter data structure
++ * @toUnicode : non-zero if toUnicode. 0 otherwise.
++ * @out:  a pointer to an array of bytes to store the result
++ * @outlen:  the length of @out
++ * @in:  a pointer to an array of ISO Latin 1 chars
++ * @inlen:  the length of @in
++ *
++ * 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.
++ */
++static int
++xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
++                const unsigned char *in, int *inlen) {
++    const char *ucv_in = (const char *) in;
++    char *ucv_out = (char *) out;
++    UErrorCode err = U_ZERO_ERROR;
++
++    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
++        if (outlen != NULL) *outlen = 0;
++        return(-1);
++    }
++
++    /* 
++     * TODO(jungshik)
++     * 1. is ucnv_convert(To|From)Algorithmic better?
++     * 2. had we better use an explicit pivot buffer?
++     * 3. error returned comes from 'fromUnicode' only even
++     *    when toUnicode is true !
++     */
++    if (toUnicode) {
++        /* encoding => UTF-16 => UTF-8 */
++        ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen,
++                       &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
++                       0, TRUE, &err);
++    } else {
++        /* UTF-8 => UTF-16 => encoding */
++        ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen,
++                       &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
++                       0, TRUE, &err);
++    }
++    *inlen = ucv_in - (const char*) in; 
++    *outlen = ucv_out - (char *) out;
++    if (U_SUCCESS(err))
++        return 0;
++    if (err == U_BUFFER_OVERFLOW_ERROR)
++        return -1;
++    if (err == U_INVALID_CHAR_FOUND || err == U_ILLEGAL_CHAR_FOUND)
++        return -2;
++    /* if (err == U_TRUNCATED_CHAR_FOUND) */
++    return -3;
++}
++#endif /* LIBXML_ICU_ENABLED */
++
++/************************************************************************
++ *									*
+  *		The real API used by libxml for on-the-fly conversion	*
+  *									*
+  ************************************************************************/
+@@ -1810,6 +1964,16 @@ xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+ 	if (ret == -1) ret = -3;
+     }
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    else if (handler->uconv_in != NULL) {
++	ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
++	                      &written, in->content, &toconv);
++	xmlBufferShrink(in, toconv);
++	out->use += written;
++	out->content[out->use] = 0;
++	if (ret == -1) ret = -3;
++    }
++#endif /* LIBXML_ICU_ENABLED */
+ #ifdef DEBUG_ENCODING
+     switch (ret) {
+         case 0:
+@@ -1915,6 +2079,17 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
+             ret = -3;
+     }
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    else if (handler->uconv_in != NULL) {
++        ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
++                              &written, in->content, &toconv);
++        xmlBufferShrink(in, toconv);
++        out->use += written;
++        out->content[out->use] = 0;
++        if (ret == -1)
++            ret = -3;
++    }
++#endif /* LIBXML_ICU_ENABLED */
+     switch (ret) {
+         case 0:
+ #ifdef DEBUG_ENCODING
+@@ -2015,6 +2190,15 @@ retry:
+ 	    out->content[out->use] = 0;
+ 	}
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++	else if (handler->uconv_out != NULL) {
++	    ret = xmlUconvWrapper(handler->uconv_out, 0,
++                              &out->content[out->use],
++ 				              &written, NULL, &toconv);
++	    out->use += written;
++	    out->content[out->use] = 0;
++	}
++#endif /* LIBXML_ICU_ENABLED */
+ #ifdef DEBUG_ENCODING
+ 	xmlGenericError(xmlGenericErrorContext,
+ 		"initialized encoder\n");
+@@ -2061,6 +2245,26 @@ retry:
+ 	}
+     }
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    else if (handler->uconv_out != NULL) {
++	ret = xmlUconvWrapper(handler->uconv_out, 0,
++                              &out->content[out->use],
++	                      &written, in->content, &toconv);
++	xmlBufferShrink(in, toconv);
++	out->use += written;
++	writtentot += written;
++	out->content[out->use] = 0;
++	if (ret == -1) {
++	    if (written > 0) {
++		/*
++		 * Can be a limitation of iconv
++		 */
++		goto retry;
++	    }
++	    ret = -3;
++	}
++    }
++#endif /* LIBXML_ICU_ENABLED */
+     else {
+ 	xmlEncodingErr(XML_I18N_NO_OUTPUT,
+ 		       "xmlCharEncOutFunc: no output function !\n", NULL);
+@@ -2173,6 +2377,22 @@ xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
+ 	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;
++	if (handler->uconv_out != NULL) {
++	    closeIcuConverter(handler->uconv_out);
++	    handler->uconv_out = NULL;
++	}
++	if (handler->uconv_in != NULL) {
++	    closeIcuConverter(handler->uconv_in);
++	    handler->uconv_in = NULL;
++	}
++	xmlFree(handler);
++    }
++#endif
+ #ifdef DEBUG_ENCODING
+     if (ret)
+         xmlGenericError(xmlGenericErrorContext,
+@@ -2248,6 +2468,22 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) {
+ 		    cur += toconv;
+ 		} while (ret == -2);
+ #endif
++#ifdef LIBXML_ICU_ENABLED
++	    } else if (handler->uconv_out != NULL) {
++	        do {
++		    toconv = in->end - cur;
++		    written = 32000;
++		    ret = xmlUconvWrapper(handler->uconv_out, 0, &convbuf[0],
++	                      &written, cur, &toconv);
++		    if (ret < 0) {
++		        if (written > 0)
++			    ret = -2;
++			else
++			    return(-1);
++		    }
++		    unused += written;
++		    cur += toconv;
++		} while (ret == -2);
+             } else {
+ 	        /* could not find a converter */
+ 	        return(-1);
+@@ -2259,8 +2495,9 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) {
+     }
+     return(in->consumed + (in->cur - in->base));
+ }
++#endif
+ 
+-#ifndef LIBXML_ICONV_ENABLED
++#if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
+ #ifdef LIBXML_ISO8859X_ENABLED
+ 
+ /**
+diff --git a/third_party/libxml/include/libxml/encoding.h b/third_party/libxml/include/libxml/encoding.h
+index c74b25f..b5f8b48 100644
+--- a/third_party/libxml/include/libxml/encoding.h
++++ b/third_party/libxml/include/libxml/encoding.h
+@@ -26,6 +26,24 @@
+ 
+ #ifdef LIBXML_ICONV_ENABLED
+ #include <iconv.h>
++#else 
++#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" {
+@@ -125,6 +143,13 @@ typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
+  * Block defining the handlers for non UTF-8 encodings.
+  * If iconv is supported, there are two extra fields.
+  */
++#ifdef LIBXML_ICU_ENABLED
++struct _uconv_t {
++  UConverter *uconv; /* for conversion between an encoding and UTF-16 */
++  UConverter *utf8; /* for conversion between UTF-8 and UTF-16 */
++};
++typedef struct _uconv_t uconv_t;
++#endif
+ 
+ typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
+ typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
+@@ -136,6 +161,10 @@ struct _xmlCharEncodingHandler {
+     iconv_t                    iconv_in;
+     iconv_t                    iconv_out;
+ #endif /* LIBXML_ICONV_ENABLED */
++#ifdef LIBXML_ICU_ENABLED
++    uconv_t                    *uconv_in;
++    uconv_t                    *uconv_out;
++#endif /* LIBXML_ICU_ENABLED */
+ };
+ 
+ #ifdef __cplusplus
+diff --git a/third_party/libxml/include/libxml/parser.h b/third_party/libxml/include/libxml/parser.h
+index dd79c42..3580b63 100644
+--- a/third_party/libxml/include/libxml/parser.h
++++ b/third_party/libxml/include/libxml/parser.h
+@@ -1222,6 +1222,7 @@ typedef enum {
+     XML_WITH_DEBUG_MEM = 29,
+     XML_WITH_DEBUG_RUN = 30,
+     XML_WITH_ZLIB = 31,
++    XML_WITH_ICU = 32,
+     XML_WITH_NONE = 99999 /* just to be sure of allocation size */
+ } xmlFeature;
+ 
+diff --git a/third_party/libxml/include/libxml/xmlversion.h.in b/third_party/libxml/include/libxml/xmlversion.h.in
+index 4739f3a..de310ab 100644
+--- a/third_party/libxml/include/libxml/xmlversion.h.in
++++ b/third_party/libxml/include/libxml/xmlversion.h.in
+@@ -269,6 +269,15 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+ #endif
+ 
+ /**
++ * LIBXML_ICU_ENABLED:
++ *
++ * Whether icu support is available
++ */
++#if @WITH_ICU@
++#define LIBXML_ICU_ENABLED
++#endif
++
++/**
+  * LIBXML_ISO8859X_ENABLED:
+  *
+  * Whether ISO-8859-* support is made available in case iconv is not
+diff --git a/third_party/libxml/parser.c b/third_party/libxml/parser.c
+index 85e7599..3ba2a06 100644
+--- a/third_party/libxml/parser.c
++++ b/third_party/libxml/parser.c
+@@ -954,6 +954,12 @@ xmlHasFeature(xmlFeature feature)
+ #else
+             return(0);
+ #endif
++        case XML_WITH_ICU:
++#ifdef LIBXML_ICU_ENABLED
++            return(1);
++#else
++            return(0);
++#endif
+         default:
+ 	    break;
+      }
diff --git a/patches/icu-configure b/patches/icu-configure
new file mode 100644
index 0000000..f7e2395
--- /dev/null
+++ b/patches/icu-configure
@@ -0,0 +1,28 @@
+Modifications to configure.in:
+- set the WITH_ICU flag unconditionally
+- only output files we use
+
+Index: libxml/configure.in
+===================================================================
+--- libxml.orig/configure.in	2010-07-09 15:00:21.600113911 -0700
++++ libxml/configure.in	2010-07-09 15:02:50.299108047 -0700
+@@ -1229,6 +1229,9 @@
+ fi
+ AC_SUBST(WITH_OUTPUT)
+ 
++WITH_ICU=1
++AC_SUBST(WITH_ICU)
++
+ WITH_ICONV=0
+ if test "$with_iconv" = "no" ; then
+     echo Disabling ICONV support
+@@ -1456,7 +1459,7 @@
+ ln -s Copyright COPYING
+ 
+ # keep on one line for cygwin c.f. #130896
+-AC_OUTPUT(libxml2.spec:libxml.spec.in Makefile include/Makefile include/libxml/Makefile doc/Makefile doc/examples/Makefile doc/devhelp/Makefile example/Makefile python/Makefile python/tests/Makefile xstc/Makefile include/libxml/xmlversion.h xml2-config libxml-2.0.pc libxml-2.0-uninstalled.pc python/setup.py)
++AC_OUTPUT(include/libxml/xmlversion.h xml2-config)
+ 
+-chmod +x xml2-config python/setup.py
++chmod +x xml2-config
+ echo Done configuring
diff --git a/patches/icu-win32 b/patches/icu-win32
new file mode 100644
index 0000000..2ea8f21
--- /dev/null
+++ b/patches/icu-win32
@@ -0,0 +1,68 @@
+diff --git a/third_party/libxml/win32/Makefile.msvc b/third_party/libxml/win32/Makefile.msvc
+index 2409905..253c46e 100644
+--- a/third_party/libxml/win32/Makefile.msvc
++++ b/third_party/libxml/win32/Makefile.msvc
+@@ -71,6 +71,9 @@ LIBS = $(LIBS) wsock32.lib ws2_32.lib
+ !if "$(WITH_ICONV)" == "1"
+ LIBS = $(LIBS) iconv.lib
+ !endif 
++!if "$(WITH_ICU)" == "1"
++LIBS = $(LIBS) icu.lib
++!endif
+ !if "$(WITH_ZLIB)" == "1"
+ LIBS = $(LIBS) zdll.lib
+ !endif
+diff --git a/third_party/libxml/win32/configure.js b/third_party/libxml/win32/configure.js
+index e71d2af..75def3f 100644
+--- a/third_party/libxml/win32/configure.js
++++ b/third_party/libxml/win32/configure.js
+@@ -40,6 +40,7 @@ var withXpath = true;
+ var withXptr = true;
+ var withXinclude = true;
+ var withIconv = true;
++var withIcu = false;
+ var withIso8859x = false;
+ var withZlib = false;
+ var withDebug = true;
+@@ -124,6 +125,7 @@ function usage()
+ 	txt += "  xptr:       Enable XPointer support (" + (withXptr? "yes" : "no")  + ")\n";
+ 	txt += "  xinclude:   Enable XInclude support (" + (withXinclude? "yes" : "no")  + ")\n";
+ 	txt += "  iconv:      Enable iconv support (" + (withIconv? "yes" : "no")  + ")\n";
++	txt += "  icu:        Enable icu support (" + (withIcu? "yes" : "no")  + ")\n";
+ 	txt += "  iso8859x:   Enable ISO8859X support (" + (withIso8859x? "yes" : "no")  + ")\n";
+ 	txt += "  zlib:       Enable zlib support (" + (withZlib? "yes" : "no")  + ")\n";
+ 	txt += "  xml_debug:  Enable XML debbugging module (" + (withDebug? "yes" : "no")  + ")\n";
+@@ -233,6 +235,7 @@ function discoverVersion()
+ 	vf.WriteLine("WITH_XPTR=" + (withXptr? "1" : "0"));
+ 	vf.WriteLine("WITH_XINCLUDE=" + (withXinclude? "1" : "0"));
+ 	vf.WriteLine("WITH_ICONV=" + (withIconv? "1" : "0"));
++	vf.WriteLine("WITH_ICU=" + (withIcu? "1" : "0"));
+ 	vf.WriteLine("WITH_ISO8859X=" + (withIso8859x? "1" : "0"));
+ 	vf.WriteLine("WITH_ZLIB=" + (withZlib? "1" : "0"));
+ 	vf.WriteLine("WITH_DEBUG=" + (withDebug? "1" : "0"));
+@@ -319,6 +322,8 @@ function configureLibxml()
+ 			of.WriteLine(s.replace(/\@WITH_XINCLUDE\@/, withXinclude? "1" : "0"));
+ 		} else if (s.search(/\@WITH_ICONV\@/) != -1) {
+ 			of.WriteLine(s.replace(/\@WITH_ICONV\@/, withIconv? "1" : "0"));
++		} else if (s.search(/\@WITH_ICU\@/) != -1) {
++			of.WriteLine(s.replace(/\@WITH_ICU\@/, withIcu? "1" : "0"));
+ 		} else if (s.search(/\@WITH_ISO8859X\@/) != -1) {
+ 			of.WriteLine(s.replace(/\@WITH_ISO8859X\@/, withIso8859x? "1" : "0"));
+ 		} else if (s.search(/\@WITH_ZLIB\@/) != -1) {
+@@ -462,6 +467,8 @@ for (i = 0; (i < WScript.Arguments.length) && (error == 0); i++) {
+ 			withXinclude = strToBool(arg.substring(opt.length + 1, arg.length));
+ 		else if (opt == "iconv")
+ 			withIconv = strToBool(arg.substring(opt.length + 1, arg.length));
++		else if (opt == "icu")
++			withIcu = strToBool(arg.substring(opt.length + 1, arg.length));
+ 		else if (opt == "iso8859x")
+ 			withIso8859x = strToBool(arg.substring(opt.length + 1, arg.length));
+ 		else if (opt == "zlib")
+@@ -646,6 +653,7 @@ txtOut += "     XPath support: " + boolToStr(withXpath) + "\n";
+ txtOut += "  XPointer support: " + boolToStr(withXptr) + "\n";
+ txtOut += "  XInclude support: " + boolToStr(withXinclude) + "\n";
+ txtOut += "     iconv support: " + boolToStr(withIconv) + "\n";
++txtOut += "     icu   support: " + boolToStr(withIcu) + "\n";
+ txtOut += "  iso8859x support: " + boolToStr(withIso8859x) + "\n";
+ txtOut += "      zlib support: " + boolToStr(withZlib) + "\n";
+ txtOut += "  Debugging module: " + boolToStr(withDebug) + "\n";
diff --git a/patches/snprintf_config b/patches/snprintf_config
new file mode 100644
index 0000000..9d1ca62
--- /dev/null
+++ b/patches/snprintf_config
@@ -0,0 +1,14 @@
+diff --git a/third_party/libxml/win32/config.h b/third_party/libxml/win32/config.h
+index 3fc9be5..5112ce6 100644
+--- a/third_party/libxml/win32/config.h
++++ b/third_party/libxml/win32/config.h
+@@ -95,7 +95,9 @@ static int isnan (double d) {
+ 
+ #if defined(_MSC_VER)
+ #define mkdir(p,m) _mkdir(p)
++#if _MSC_VER < 1900
+ #define snprintf _snprintf
++#endif
+ #if _MSC_VER < 1500
+ #define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+ #endif
diff --git a/patches/snprintf_win32config b/patches/snprintf_win32config
new file mode 100644
index 0000000..3fec790
--- /dev/null
+++ b/patches/snprintf_win32config
@@ -0,0 +1,14 @@
+diff --git a/third_party/libxml/src/include/win32config.h b/third_party/libxml/src/include/win32config.h
+index 3fc9be5..5112ce6 100644
+--- a/third_party/libxml/src/include/win32config.h
++++ b/third_party/libxml/src/include/win32config.h
+@@ -95,7 +95,9 @@ static int isnan (double d) {
+ 
+ #if defined(_MSC_VER)
+ #define mkdir(p,m) _mkdir(p)
++#if _MSC_VER < 1900
+ #define snprintf _snprintf
++#endif
+ #if _MSC_VER < 1500
+ #define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+ #endif
diff --git a/patches/win32-clobber-makefile b/patches/win32-clobber-makefile
new file mode 100644
index 0000000..2f7fbb4
--- /dev/null
+++ b/patches/win32-clobber-makefile
@@ -0,0 +1,19 @@
+Index: libxml/win32/configure.js
+===================================================================
+--- libxml.orig/win32/configure.js	2010-07-09 14:56:07.769093841 -0700
++++ libxml/win32/configure.js	2010-07-09 15:36:48.590268611 -0700
+@@ -611,7 +611,13 @@
+ 	makefile = ".\\Makefile.mingw";
+ else if (compiler == "bcb")
+ 	makefile = ".\\Makefile.bcb";
+-fso.CopyFile(makefile, ".\\Makefile", true);
++var new_makefile = ".\\Makefile";
++var f = fso.FileExists(new_makefile);
++if (f) {
++       var t = fso.GetFile(new_makefile);
++       t.Attributes = 0;
++}
++fso.CopyFile(makefile, new_makefile, true);
+ WScript.Echo("Created Makefile.");
+ // Create the config.h.
+ var confighsrc = "..\\include\\win32config.h";
diff --git a/patches/win32-no-posix-error-codes b/patches/win32-no-posix-error-codes
new file mode 100644
index 0000000..38be7f7
--- /dev/null
+++ b/patches/win32-no-posix-error-codes
@@ -0,0 +1,14 @@
+diff --git a/third_party/libxml/src/libxml.h b/third_party/libxml/src/libxml.h
+index 1656ac2..f8a368c 100644
+--- a/third_party/libxml/src/libxml.h
++++ b/third_party/libxml/src/libxml.h
+@@ -17,6 +17,9 @@
+ #define _FILE_OFFSET_BITS 64
+ #endif
+ #endif
++#ifndef _CRT_NO_POSIX_ERROR_CODES
++#define _CRT_NO_POSIX_ERROR_CODES
++#endif
+ 
+ #if defined(macintosh)
+ #include "config-mac.h"
diff --git a/patches/xmlregexp-bogus-cast b/patches/xmlregexp-bogus-cast
new file mode 100644
index 0000000..aaebfaa
--- /dev/null
+++ b/patches/xmlregexp-bogus-cast
@@ -0,0 +1,15 @@
+Change bogus '(unsigned long)' cast to '(unsigned short)'
+
+Index: libxml/xmlregexp.c
+===================================================================
+--- libxml.orig/xmlregexp.c	2010-07-09 14:16:36.990430641 -0700
++++ libxml/xmlregexp.c	2010-07-09 14:16:40.939742007 -0700
+@@ -6470,7 +6470,7 @@
+     if (name != NULL) {
+ 	value += 30 * (*name);
+ 	while ((ch = *name++) != 0) {
+-	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
++	    value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch);
+ 	}
+     }
+     return (value);
diff --git a/src/AUTHORS b/src/AUTHORS
new file mode 100644
index 0000000..cf2e9a6
--- /dev/null
+++ b/src/AUTHORS
@@ -0,0 +1,5 @@
+Daniel Veillard <daniel@veillard.com>
+Bjorn Reese <breese@users.sourceforge.net>
+William Brack <wbrack@mmm.com.hk>
+Igor Zlatkovic <igor@zlatkovic.com> for the Windows port
+Aleksey Sanin <aleksey@aleksey.com>
diff --git a/src/ChangeLog b/src/ChangeLog
new file mode 100644
index 0000000..36045e6
--- /dev/null
+++ b/src/ChangeLog
@@ -0,0 +1,19678 @@
+Fri Jul 10 16:11:34 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a regression in entity parsing when using the reader
+	  introduced because we were not reusing _private on entities parsing
+	  context
+
+Thu Jul  9 10:21:00 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	Aleksey Sanin support for c14n 1.1
+	* c14n.c include/libxml/c14n.h: adds support for C14N 1.1,
+	  new flags at the API level
+	* runtest.c Makefile.am testC14N.c xmllint.c: add support in CLI
+	  tools and test binaries
+	* result/c14n/1-1-without-comments/* test/c14n/1-1-without-comments/*:
+	  add a new batch of tests
+
+Thu Jul  9 08:52:35 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in: update of libtool seems to have modified it
+	* python/libxml2class.txt: python update modified the order
+	  of classes apparently
+
+Thu Jul  9 08:43:06 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: avoid calling xmlAddID with NULL values
+	* parser.c: add a few xmlInitParser in some entry points
+
+Fri Jun 19 19:51:08 CEST 2009 Rob Richards <rrichards@cdatazone.org>
+
+	* parser.c: use options from current parser context when creating 
+	  a parser context within xmlParseCtxtExternalEntity
+	* xmlwriter.c: fix error message when unable to create output file
+
+Thu Jun  4 11:17:23 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c debugXML.c doc/examples/io2.c parser.c schematron.c
+	  valid.c xmlschemas.c xmlwriter.c xpath.c: use %s to printf string
+	  patch by Christian Persch, fixes #581612
+
+Thu Jun  4 11:06:07 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c threads.c: change the threading initialization sequence
+	  as suggested by Igor Novoseltsev to avoid crash if xmlInitParser()
+	  is called from a thread which is not the main one, should fix
+	  #584605
+
+Fri May 15 17:54:48 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: make sure we keep line numbers fixes #580705
+	  based Aaron Patterson patch
+
+Tue May 12 09:13:58 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: a broken HTML table attributes initialization,
+	  fixes #581803, by Roland Steiner <rolandsteiner@google.com>
+
+Tue May 12 08:54:20 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* libxml2.doap: adding RDF dope file.
+
+Tue May 12 08:42:52 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: adapt the extra version detection code to git
+
+Wed Apr 29 16:09:38 CEST 2009 Rob Richards <rrichards@cdatazone.org>
+
+	* parser.c: do not set error code in xmlNsWarn
+
+Wed Apr 15 11:18:24 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h include/libxml/xmlwriter.h
+	  include/libxml/relaxng.h include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h.in include/libxml/valid.h
+	  include/libxml/xmlschemas.h include/libxml/xmlerror.h: change
+	  ATTRIBUTE_PRINTF into LIBXML_ATTR_FORMAT to avoid macro name
+	  collisions with other packages and headers as reported by
+	  Belgabor and Mike Hommey
+
+Thu Apr  2 13:57:15 CEST 2009 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: fix structured error handling problems #564217
+
+Thu Mar 26 19:08:08 CET 2009 Rob Richards <rrichards@cdatazone.org>
+
+	* parser.c: use options from current parser context when creating 
+	  an entity parser context
+
+Wed Mar 25 11:40:34 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*: updated SVN URL for GNOME as pointed by Vincent Lefevre
+	  and regenerated docs
+
+Wed Mar 25 11:21:26 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: hide the nbParse* variables used for debugging
+	  as pointed by Mike Hommey
+
+Wed Mar 25 10:50:05 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/wsockcompat.h win32/Makefile.bcb xpath.c: fixes for
+	  Borland/CodeGear/Embarcadero compilers by Eric Zurcher
+
+Wed Mar 25 10:43:07 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: xmlXPathRegisterNs should not allow enpty prefixes
+
+Mon Mar 23 20:27:15 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: add a missing check in xmlAddSibling, patch by Kris Breuker
+	* xmlIO.c: avoid xmlAllocOutputBuffer using XML_BUFFER_EXACT which
+	  leads to performances problems especially on Windows.
+
+Tue Mar  3 14:30.28 HKT 2009 William Brack <wbrack@mmm.com.hk>
+
+	* trio.h: changed include of config.h to be surrounded by
+	  quotation marks #570806
+
+Sat Feb 21 10:20:34 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c parser.c: more warnings about xmlCleanupThreads and
+	  xmlCleanupParser to avoid troubles like #571409
+
+Fri Feb 20 09:40:04 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: cleanups and error reports when xmlTextWriterVSprintf
+	  fails, by Jinmei Tatuya
+
+Fri Feb 20 09:18:56 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: remove a couple of leaks on errors reported by
+	  Jinmei Tatuya
+
+Sun Jan 18 22:37:59 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/xml.html doc/*: preparing 0.7.3 release
+	* include/libxml/parserInternals.h SAX2.c: fix a typo in a name
+
+Sun Jan 18 21:48:28 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h include/libxml/xmlwriter.h
+	  include/libxml/relaxng.h include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h.in include/libxml/valid.h
+	  include/libxml/xmlschemas.h include/libxml/xmlerror.h:
+	  port patch from Marcus Meissner to add gcc checking for
+	  printf like functions parameters, should fix #65068
+	* doc/apibuild.py doc/*: modified the script accordingly
+	  and regenerated
+	* xpath.c xmlmemory.c threads.c: fix a few warnings
+
+Sun Jan 18 20:40:42 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlwin32version.h.in: windows header should
+	  get the same define
+
+Sun Jan 18 18:22:33 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlversion.h.in include/libxml/xmlmemory.h:
+	  apply patch from Marcus Meissner to add gcc attribute alloc_size
+	  should fix #552505
+	* doc/apibuild.py doc/* testapi.c: regenerate the API
+	* include/libxml/parserInternals.h: fix a comment problem raised
+	  by apibuild.py
+
+Sun Jan 18 16:39:01 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: also remove pthread key when stopping thread
+	  support, patch based on Alex Ott one should fix #564723
+
+Sun Jan 18 15:55:18 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: patch from Daniel Zimmermann fixing a memory leak
+	  in an edge case, solves #562230
+
+Sun Jan 18 15:06:05 CET 2009 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parserInternals.h SAX2.c: add a new define
+	  XML_MAX_TEXT_LENGTH limiting the maximum size of a single text
+	  node, the defaultis 10MB and can be removed with the HUGE
+	  parsing option
+
+Mon Jan 05 18:28:41 CET 2009 Rob Richards <rrichards@cdatazone.org>
+
+	* include/libxml/parser.h parser.c: add XML_PARSE_OLDSAX parser 
+	  option to enable pre 2.7 SAX behavior.
+
+Wed Dec 31 23:11:37 CET 2008 Rob Richards <rrichards@cdatazone.org>
+
+	* tree.c: set doc on last child tree in xmlAddChildList for 
+	  bug #546772. Fix problem adding an attribute via with xmlAddChild 
+	  reported by Kris Breuker.
+
+Sun Dec 27 14:16:13 CET 2008 Rob Richards <rrichards@cdatazone.org>
+
+	* xmlwriter.c: fix indenting in xmlTextWriterFullEndElement for 
+	  bug# 554353.
+
+Thu Nov 27 16:24:52 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h tree.c python/generator.py: adds
+	  element traversal support
+	* valid.c: avoid a warning
+	* doc/*: regenerated
+
+Mon Nov 17 16:56:18 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c parser.c: fix for CVE-2008-4226, a memory overflow
+	  when building gigantic text nodes, and a bit of cleanup
+	  to better handled out of memory problem in that code.
+	* tree.c: fix for CVE-2008-4225, lack of testing leads to
+	  a busy loop test assuming one have enough core memory.
+
+Thu Nov  6 14:34:35 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: Matthias Kaehlcke reported a build problem when
+	  not compiling HTML support in.
+
+Fri Oct 17 15:24:08 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/Makefile.am: patch from Adrian Bunk which
+	  adds --disable-rebuild-docs to avoid rebuilding them
+
+Fri Oct  3 09:43:45 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* NEWS: preparing the release of 2.7.2
+	* dict.c: fix the Solaris portability issue
+	* parser.c: additional cleanup on #554660 fix
+	* test/ent13 result/ent13* result/noent/ent13*: added the
+	  example in the regression test suite.
+	* HTMLparser.c: handle leading BOM in htmlParseElement()
+
+Thu Oct  2 22:53:39 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a nasty bug introduced when cleaning up
+	  entities processing in 2.7.x , fixes #554660
+
+Thu Sep 25 18:04:20 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix an HTML parsing error on large data sections
+	  reported by Mike Day
+	* test/HTML/utf8bug.html result/HTML/utf8bug.html.err
+	  result/HTML/utf8bug.html.sax result/HTML/utf8bug.html: add the
+	  reproducer to the test suite
+
+Thu Sep 25 17:35:57 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* runxmlconf.c: fix compilation if XPath is not included
+
+Thu Sep 25 16:54:04 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: patch from Riccardo Scussat fixing custom error
+	  handlers problems.
+
+Thu Sep 25 16:30:11 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlsave.h xmlsave.c: new options to serialize
+	  as XML/HTML/XHTML and restore old entry point behaviours
+
+Mon Sep  1 16:49:05 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/news.html configure.in python/setup.py NEWS:
+	  prepare release of 2.7.1
+
+Mon Sep  1 15:35:13 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c xpath.c: applied a couple of patches from Martin
+	  avoiding some leaks, fixinq QName checks in XPath, XPath debugging
+	  and schematron code cleanups.
+	* python/tests/Makefile.am python/tests/xpathleak.py: add the
+	  specific regression tests, just tweak it to avoid output by default
+
+Mon Sep  1 15:02:05 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* trionan.c: Borland C fix from Moritz Both
+	* testapi.c: regenerate, workaround a problem for buffer testing
+	* xmlIO.c HTMLtree.c: new internal entry point to hide even better
+	  xmlAllocOutputBufferInternal
+	* tree.c: harden the code around buffer allocation schemes
+	* parser.c: restore the warning when namespace names are not absolute
+	  URIs
+	* runxmlconf.c: continue regression tests if we get the expected
+	  number of errors
+	* Makefile.am: run the python tests on make check
+	* xmlsave.c: handle the HTML documents and trees
+	* python/libxml.c: convert python serialization to the xmlSave APIs
+	  and avoid some horrible hacks
+
+Sat Aug 30 16:58:40 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in, doc/*: preparing 2.7.0 release
+	* tree.c: remove some testing traces
+	* parser.c xmlIO.c xmlschemas.c: remove some warnings
+
+Sat Aug 30 14:50:16 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h tree.c: make a new kind of buffer where
+	  shrinking and adding in head can avoid reallocation or full
+	  buffer memmoves
+	* encoding.c xmlIO.c: use the new kind of buffers for output
+	  buffers
+
+Sat Aug 30 10:18:13 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/* testapi.c: regenerated
+
+Fri Aug 29 21:53:12 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/reader3.c: patch from  Robert Schwebel , allows to
+	  compile the example if configured without output support fixes
+	  #545582
+	* Makefile.am: add testrecurse to the make check tests
+	* HTMLparser.c: if the parser got a encoding argument it should be
+	  used over what the meta specifies, patch fixing #536346
+
+Fri Aug 29 14:41:38 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: a couple more fixes
+	* nanohttp.c nanoftp.c: patch from Andreas Färber to compile on Haiku
+	  fixes #527880
+	* doc/examples/*: regenerated
+
+Thu Aug 28 17:31:46 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parser.h: completely different fix for
+	  the recursion detection based on entity density, big cleanups
+	  in the entity parsing code too
+	* result/*.sax*: the parser should not ask for used defined versions
+	  of the predefined entities
+	* testrecurse.c: automatic test for entity recursion checks
+	* Makefile.am: added testrecurse
+	* test/recurse/lol* test/recurse/good*: a first set of tests for
+	  the recursion
+
+Wed Aug 27 21:55:34 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlerror.h parser.c: a bit of cleanup and
+	  added checks based on the regression tests of the xmlconf suite
+
+Wed Aug 27 19:22:35 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: bug in parsing RFC 3986 uris with port numbers
+
+Wed Aug 27 17:30:48 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in Makefile.am: add an --with-coverage configure option
+	  and a 'make cov' target based on gcc profiling and the lcov
+	  tool. Currently at 68.9% coverage out of 'make check' and 
+	  runsuite executions.
+	* xmlreader.c: remove warnings due to C++ comments
+
+Wed Aug 27 15:00:54 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parserInternals.h parser.c: cleanup entity
+	  pushing error handling based on a patch from Ashwin
+
+Wed Aug 27 13:41:26 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: fix a small initialization problem raised by Ashwin
+	* testapi.c gentest.py: increase testing especially for document
+	  with an internal subset, and entities
+	* tree.c: fix a deallocation issue when unlinking entities from
+	  a document.
+	* valid.c: fix a missing entry point test not found previously.
+	* doc/*: regenerated the APIs, docs etc.
+
+Tue Aug 26 15:02:58 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h parser.c xmllint.c: strengthen some
+	  of the internal parser limits, add an XML_PARSE_HUGE option
+	  to bypass them all. More internal parser limits will still need
+	  to be added.
+
+Tue Aug 26 09:42:08 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: add the testchar to 'make check'
+	* xmlschemas.c: Volker Grabsch pointed out a typo
+	* xmlregexp.c: production [19] from XML Schemas regexps were a
+	  mistake removed in version REC-xmlschema-2-20041028, Volker Grabsch
+	  provided a patch to remove it
+	* test/schemas/regexp-char-ref_0.xml test/schemas/regexp-char-ref_0.xsd
+	  test/schemas/regexp-char-ref_1.xsd result/schemas/regexp-char-ref_0_0
+	  result/schemas/regexp-char-ref_1_0: Volker Grabsch also provided
+	  regession tests for this
+
+Tue Aug 26 09:25:39 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h xinclude.c xmllint.c: patch based on
+	  Wieant Nielander contribution to add the option of not doing
+	  URI base fixup in XInclude
+
+Mon Aug 25 16:52:53 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied patch from Aswin to fix tree skipping
+	* include/libxml/entities.h entities.c: fixed a comment and
+	  added a new xmlNewEntity() entry point
+	* runtest.c: be less verbose
+	* tree.c: space and tabs cleanups
+
+Mon Aug 25 10:56:30 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/entities.h entities.c SAX2.c parser.c: rework
+	  the patch to avoid some ABI issue with people allocating
+	  entities structure directly
+
+Wed Aug 20 19:02:01 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h include/libxml/entities.h entities.c
+	  parserInternals.c parser.c: fix for CVE-2008-3281
+
+Sun Aug 10 17:06:13 CEST 2008 Rob Richards <rrichards@ctindustries.net>
+
+	* dict.c: fix non GNUC builds.
+
+Fri Aug  8 14:13:06 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* makefile.am: adding a check-valgrind target
+
+Fri Aug  8 14:01:59 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am testdict.c: add the new test in 'make check' and
+	  update it to check subdictionaries processing.
+
+Fri Aug  8 12:07:20 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* testdict.c: added a program to regression test the dictionary code
+	* dict.c: improve the lookup efficiency by caching the key.
+
+Thu Aug  7 18:30:55 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: chased and found a couple of nasty issues
+
+Thu Aug  7 15:51:31 CEST 2008 Sven Herzberg <sven@imendio.com>
+
+	Bug 546629 – runtests doesn't pass on my mac
+	Reviewed by William M. Brack.
+
+	* runtest.c: use libpthread on Mac OS X as well
+
+Wed Aug  6 12:24:33 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: allow [ and ] in fragment identifiers, 3986 disallow them
+	  but it's widely used for XPointer, and would break DocBook
+	  processing among others
+
+Wed Aug  6 11:32:21 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: change the big key algorithm to work properly with QName
+	  too, fix a bug with dict size and sub dictionaries
+
+Mon Aug  4 17:27:27 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c include/libxml/uri.h: rewrite the URI parser to update to
+	  rfc3986 (from 2396)
+	* test/errors/webdav.xml result/errors/webdav.xml*: removed the
+	  error test, 'DAV:' is a correct URI under 3986
+	* Makefile.am: small cleanup in make check
+
+Thu Jul 31 21:49:45 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* runxmlconf.c: more progresses against the official regression tests
+	* runsuite.c: small cleanup for non-leak reports
+	* include/libxml/tree.h: parsing flags and other properties are
+	  now added to the document node, this is generally useful and
+	  allow to make Name and NmToken validations based on the parser
+	  flags, more specifically the 5th edition of XML or not
+	* HTMLparser.c tree.c: small side effects for the previous changes
+	* parser.c SAX2.c valid.c: the bulk of teh changes are here,
+	  the parser and validation behaviour can be affected, parsing
+	  flags need to be copied, lot of changes. Also fixing various
+	  validation problems in the regression tests.
+
+Thu Jul 31 10:15:53 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* runxmlconf.c: added a skipped list, insert rmt-ns10-035
+	* Makefile.am: improve 'make check'
+	* include/libxml/xmlerror.h parser.c: clean up namespace errors
+	  checking and reporting, errors when a document is labelled
+	  as UTF-16 while it is parsed as UTF-8 and no encoding was given
+	  explicitely.
+	* result/errors/webdav.xml.*: some warnings are no recategorized
+	  as Namespace errors
+
+Wed Jul 30 14:55:54 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlmemory.h xmlmemory.c: add xmlMemDisplayLast to
+	  help debug incremental memory leaks, and some cleanups
+	* runxmlconf.c: use that new call and avoid ever touching the
+	  system catalog in the regression tests
+
+Wed Jul 30 14:33:33 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/xmlerror.h: an XML-1.0 document can't load
+	  an 1.1 entity
+	* runxmlconf.c: when using entities make sure we load them
+
+Tue Jul 29 18:43:07 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a bug not detecting cross entity comments probably
+	  when comment parsing got optimized.
+	* Makefile.am: add make check
+	* runxmlconf.c: fix the log file name
+
+Tue Jul 29 18:09:26 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* runxmlconf.c Makefile.am: add a C program to run the W3C test
+	  suite, work in progress
+	* xmllint.c: add a new option --oldxml10 to use the old parser
+	* parser.c: fix the XML_PARSE_OLD10 processing of the new option
+	  and a bug in version parsing
+
+Tue Jul 29 11:12:40 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: space and tabs cleanup
+
+Tue Jul 29 10:59:36 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h include/libxml/xmlerror.h parser.c:
+	  implement XML-1.0 5th edition, add parser option XML_PARSE_OLD10
+	  to stick to old behaviour
+	* testapi.c gentest.py: modified slightly and regenerated
+	* Makefile.am: add testchar
+
+Thu Jul 24 16:57:20 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am testchar.c Makefile.tests README.tests: add a
+	  new regression test program for testing character ranges and
+	  UTF8 encoding/decoding
+
+Wed Jul 23 15:32:39 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: fix the build root
+
+Wed Jul 16 22:28:48 PDT 2008 William Brack <wbrack@mmm.com.hk>
+
+	* pattern.c: fix problem with xmlStreamPop when pattern includes
+	  a "." element (see discussion on libxslt list)
+
+Mon Jul  7 15:49:59 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fix line number on text nodes, problem raised by Ralf Junker
+
+Sun Jun 29 17:04:28 CEST 2008 Rob Richards <rrichards@ctindustries.net>
+	* xmlschemas.c: fix crash with invalid whitespace facet
+
+Wed Jun 11 10:13:02 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/FAQ.html: add a section in the FAQ about
+	  multithread and xmlCleanupParser
+
+Tue Jun 10 16:52:17 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: apply a couple of fixes based on a Coverity report
+	  forwarded by Derrick Price.
+	* VxWorks/README VxWorks/Makefile VxWorks/build.sh: instructions
+	  Makefile, and shell script to build on VxWorks 6.4+ provided by
+	  Jim Wert.
+
+Tue Jun  3 18:07:13 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/setup.py: apply patch from Martin fixing
+	  python whitespaces
+	* NEWS: following previous commit rebuilt now in UTF-8
+
+Mon Jun  2 17:39:42 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* ChangeLog: patch from Hans de Goede to switch the file to UTF-8
+	* doc/news.xsl: switch to generate the NEWS file in UTF-8 instead of
+	  ISO-8859-1
+
+Mon May 12 15:12:44 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: avoid a regexp crash, should fix #523738
+
+Mon May 12 14:56:06 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c runtest.c testapi.c include/libxml/xmlreader.h
+	  python/types.c python/libxml_wrap.h python/libxml.c: fx compilation
+	  when configured without the reader should fix #513110
+	* doc/*: regenerated
+
+Sat May  3 14:33:29 CEST 2008 Rob Richards <rrichards@ctindustries.net>
+
+	* dict.c: check for stdint.h and define types when using MSVC
+
+Mon Apr 28 20:06:12 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: applied patch from Ashwin to avoid a potential
+	  double-free
+
+Thu Apr 24 13:56:53 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied patch from Ashwin fixing a number of realloc problems
+	* HTMLparser.c: improve handling for misplaced html/head/body
+
+Tue Apr 22 10:27:17 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: improvement on the hashing of the dictionnary, with visible
+	  speed up as the number of strings in the hash increases, work from
+	  Stefan Behnel
+
+Fri Apr 11 14:44:00 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlschemas.h xmlschemas.c: added new function
+	  xmlSchemaValidCtxtGetParserCtxt based on Holger Kaelberer patch
+	* doc/apibuild.py doc/*: regenerated the doc, chased why the new
+	  function didn't got any documentation, added more checking in the
+	  generator
+	* include/libxml/relaxng.h include/libxml/schematron.h
+	  include/libxml/xmlschemas.h include/libxml/c14n.h
+	  include/libxml/xmlregexp.h include/libxml/globals.h
+	  include/libxml/xmlreader.h threads.c xmlschemas.c: various changes
+	  and cleanups following the new reports
+
+
+Thu Apr 10 10:07:00 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: extend the cleanup rule
+	* xmlschemas.c: space cleanup
+
+Wed Apr  9 19:43:25 CEST 2008 Rob Richards <rrichards@ctindustries.net>
+
+	* include/wsockcompat.h: support older win32 platforms when building
+	  with newer versions of VS
+
+Tue Apr  8 16:56:07 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: preparing release of 2.6.32
+
+Tue Apr  8 10:19:01 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix a bug introduced when fixing #438208 and reported by
+	  Ashwin
+	* python/generator.py: fix an infinite loop bug
+
+Mon Apr  7 14:44:51 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fix a link to XmlNodeType doc reported by Martijn Arts
+	* docs/*: rebuilt
+
+Fri Apr  4 18:09:50 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: improve the *Recover* functions documentation
+
+Thu Apr  3 14:57:15 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: patch from Mark Rowe fixing BOM or encoding detection
+	  in external parsed entities, should fix #440415
+
+Thu Apr  3 13:16:01 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix some problems with the *EatName functions when
+	  running out of memory raised by Eric Schrock , should fix #438208
+
+Thu Apr  3 12:41:29 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: horror around the definition of the lexical
+	  values for decimal and derived types, fixing to reject empty 
+	  values, should fix #503268
+
+Thu Apr  3 11:44:57 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: buffer may not be  large enough to convert to
+	  UCS4, patch from Christian Fruth , fixes #504015
+
+Thu Apr  3 11:02:02 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: apparently it's okay to forget the semicolumn after
+	  entity refs in HTML, fixing char refs parsing accordingly based on
+	  T. Manske patch, this should fix #517653
+
+Thu Apr  3 09:30:29 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: avoid a scary realloc() loop should fix #520383
+
+Thu Apr  3 08:22:52 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: more realloc problems pointed out by Ashwin
+
+Thu Apr  3 07:40:13 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am: applied patch from Mike Hommey fixing distclean,
+	  fixes #520387
+
+Thu Apr  3 06:52:32 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xpath.h: small doc improvement for xmlXPathContext
+	  from Jack Jansen, fixes #524759
+	* doc/newapi.xsl doc/*: fixed a problem and regenerated the docs
+
+Tue Apr  1 09:59:22 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: two patches from Alvaro Herrera to avoid problem when
+	  running out of memory in XPath evaluations.
+
+Mon Mar 31 11:23:19 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: lot of out of memory handling fixes from Ashwin
+	* elfgcchack.h doc/elfgcchack.xsl: work around a problem with xmlDllMain
+	* include/libxml/threads.h: indenting cleanups
+
+Mon Mar 31 10:25:37 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c docs/*: trying to clarify even more the xmlCleanupParser()
+	  use and the memory documentation
+
+Wed Mar 26 18:39:58 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: changes based on  Alex Khesin patch where xmlParseCharRef
+	  seems to not be checked correctly, fixes #520198
+
+Wed Mar 26 15:03:49 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: patch from Ashwin to avoid a problem of attribute
+	  redefinition in the DTD. Remove a warning too.
+
+Wed Mar 26 14:38:31 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fix a problem in externalSubsetSplit with a patch
+	  from Ashwin
+
+Tue Mar 25 17:48:02 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix various attribute normalisation problems reported
+	  by Ashwin
+	* result/c14n/without-comments/example-4
+	  result/c14n/with-comments/example-4: this impacted the result of
+	  two c14n tests :-\
+	* test/att9 test/att10 test/att11 result//att9* result//att10*
+	  result//att11*: added 3 specific regression tests coming from the
+	  XML spec revision and from Ashwin
+
+Tue Mar 25 14:20:49 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fix saving for file:///X:/ URI embedding Windows file paths
+	  should fix #524253 
+
+Mon Mar 24 21:42:33 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a problem reported by Ashwin for system parameter
+	  entities referenced from entities in external subset, add a
+	  specific loading routine.
+	* test/valid/dtds/external.ent test/valid/dtds/external2.ent
+	  test/valid/t11.xml result/valid/t11.xml*: added the test to
+	  the regression suite
+
+Mon Mar 24 15:04:54 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fix an XML Schemas crash raised by Stefan Behnel
+	  when testing with W3C test suite
+
+Mon Mar 24 12:12:00 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: check some allocation with Ashwin patch
+
+Wed Mar 19 16:41:52 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* vms/build_libxml.com: update from Tycho Hilhorst, should fix #523378
+
+Tue Mar 18 09:23:05 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: check some malloc returns with Ashwin patch, add
+	  error messages and reindent the module.
+
+Fri Mar 14 15:28:43 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: patch from Ashwin removing duplicate tests
+
+Fri Mar 14 13:44:29 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/schematron.h include/libxml/xmlerror.h schematron.c:
+	  applied patch from Tobias Minich to allow plugin schematron error
+	  reporting in the normal error system, should fix #513998
+
+Fri Mar 14 11:52:09 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xinclude.c: patch from Vasily Chekalkin fixes memory
+	  leaks, should fix 512647
+
+Thu Mar 13 08:17:58 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: found a nasty bug in regexp automata build,
+	  reported by Ashwin and Bjorn Reese
+
+Wed Mar 12 18:56:22 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: patch from Arnold Hendriks improving parsing of
+	  html within html bogus data, still not a complete fix though
+
+Wed Mar 12 10:22:01 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c: fix a memory errro when using namespace nodes
+	  returned from XPath queries, should fix #521699
+	* python/tests/Makefile.am python/tests/xpathns.py: add a specific
+	  regression test for it
+
+Mon Mar 10 16:25:32 CET 2008 Rob Richards <rrichards@ctindustries.net>
+
+	* include/win32config.h: add ICONV_CONST define for win32 build
+	  to satisfy encoding.c change in rev 3693
+
+Fri Mar  7 17:45:27 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c parser.c: fix handling of empty CDATA nodes as 
+	  reported and discussed around #514181 and associated patches
+	* test/emptycdata.xml result/emptycdata.xml* 
+	  result/noent/emptycdata.xml: added a specific test in the
+	  regression suite.
+
+Thu Mar  6 15:23:10 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: poblem with encoding detection for UTF-16 reported by
+	  Ashwin and found by Bill
+	* test/valid/dtds/utf16b.ent test/valid/dtds/utf16l.ent
+	  test/valid/UTF16Entity.xml result/valid/UTF16Entity.xml*: added
+	  the example to the regression tests
+
+Tue Mar  4 14:16:38 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: patch from Alex Khesin fixing CDATA output after
+	  a text node.
+	* parser.c: fixed the comment for xmlParserCleanup
+	* globals.c: fixed indentation
+
+Mon Feb 25 16:42:19 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* testModule.c: patch from Florent Guiliani to fix build on
+	  SCO OpenServer
+
+Thu Feb 21 22:46:08 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: made one of the changes suggested by Brian Krahmer
+	* testRegexp.c: allow to pass '--' on the command line to allow
+	  regexps starting with the character '-'
+
+Tue Feb 19 08:49:32 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/tests/Makefile.am: applied cleanup
+	  patches for cross compilation and MinGW from Roumen Petrov
+
+Sat Feb 16 11:06:54 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fix output bug reported by Petr Pajas and analyzed by
+	  Bill
+
+Fri Feb 15 09:32:11 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlerror.h tree.c: patch from Julien Charbon
+	  to simplify the processing of xmlSetProp()
+
+Fri Feb 15 08:45:32 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in encoding.c: patch from Roumen Petrov
+	  to detect if iconv() needs a const for the second parameter
+
+Fri Feb 15 08:41:31 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* macos/src/XMLTestPrefix2.h win32/Makefile.msvc: EOL cleanups
+	  from Florent Guiliani
+
+Wed Feb 13 10:56:38 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied patch from Alfred Mickautsch to flush the
+	  output at the end of document.
+
+Fri Feb  8 11:57:03 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/examples.xml: regenerated, it was truncated.
+
+Fri Feb  8 11:47:18 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmodule.c: apply simple patch from Carlo Bramini to avoid
+	  compilation problems with Mingw32
+
+Fri Feb  8 11:33:15 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: apply patch from Andrew Tosh to fix behaviour
+	  when '.' is used in a posCharGroup
+	* test/schemas/poschargrp0_0.* result/schemas/poschargrp0_0_0*:
+	  added the test to the regression suite
+
+Fri Feb  8 10:54:09 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: applied patch from Florent Guilian to remove an
+	  useless mutex in the xmlDict structure.
+
+Wed Feb  6 17:00:20 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: another leak reported by Ashwin
+	* xinclude.c: fixed the behaviour when XIncluding a fragment
+	  of the current document, patch from Chris Ryan
+
+Wed Feb  6 12:10:08 HKT 2008 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: added space for port number (when not 80) in
+	  xmlNanoHTTPMethodRedir, plus a few more comments. Should
+	  fix #514521.
+
+Tue Feb  5 09:41:46 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* schemas.c: apply fix suggested by Ashwin correcting a cut-n-paste
+	  error about the SAX callback in cdataBlockSplit when streaming
+	  XSD validation 
+
+Tue Feb  5 09:36:46 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied a patch based on Petr Sumbera one to avoid a 
+	  problem with paths starting with //
+
+Mon Feb  4 17:48:30 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/xmlmem.html: added a small section on returning
+	  memory to the kernel by compacting the heap provided by Wolfram Sang
+
+Fri Jan 25 20:01:42 CET 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* include/win32config.h win32/Makefile.msvc: fix build under VS 2008.
+	  patch by David Wimsey
+
+Thu Jan 24 15:37:04 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a memeory leak in internal subset parsing with
+	  a fix from Ashwin
+	* test/errors/content1.xml result/errors/content1.xml*:
+	  add test to regressions
+
+Fri Jan 11 09:00:09 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/*: preparing release of 2.6.31
+
+Fri Jan 11 08:58:49 CET 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: avoid a warning on 64bits introduced earlier
+	* parserInternals.c: make more checking on the UTF-8 input
+
+Fri Jan 11 15:37:05 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: avoid stopping parsing when encountering
+	  out of range characters in an HTML file, report and 
+	  continue processing instead, should fix #472696
+
+Fri Jan 11 15:13:35 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* check-relaxng-test-suite2.py check-relaxng-test-suite.py
+	  Makefile.am python/tests/Makefile.am python/Makefile.am
+	  check-xsddata-test-suite.py: patches from John Carr to
+	  start cleaning up 'make diskcheck' problems c.f. #506228
+
+Fri Jan 11 14:48:40 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: apply fix from Stefan Kost to avoid a crash
+	  in xmllint, fixes 504284
+
+Fri Jan 11 14:39:03 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xml2-config.in: apply patch from Fred Crozat to avoid
+	  outputting -L/usr/lib from xml2-config, fixes #497012
+
+Fri Jan 11 14:18:09 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix definition for <embed> to avoid error
+	  when saving back, patch from Stefan Behnel fixing 495213
+
+Fri Jan 11 14:06:09 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Christian Schmidt fixing a 
+	  column counter update problem, fixes #472696
+
+Fri Jan 11 13:22:14 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: handle a erroneous parsing of attributes in 
+	  case said attribute has been redeclared in the DTD with a
+	  different type
+	* hash.c: fix the hash scanner to not crash if a first element
+	  from the hash list is been removed in the callback
+
+Wed Jan  9 10:15:50 CST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: fix indentation in xmlTextWriterFullEndElement,
+	  as raised by Felipe Pena, should fix #508156
+
+Tue Dec  6 11:07:42 CET 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* pattern.c: fix crash from double free of name for bug #501760
+
+Fri Nov 23 11:47:48 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: remove unused variable in __xmlGlobalInitMutexLock
+	  reported by Hannes Eder
+
+Mon Nov 19 18:39:26 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: remove a cut-and-paste copy error
+
+Fri Nov 16 11:55:36 CET 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* globals.c threads.c include/libxml/threads.h: 
+	  __xmlGlobalInitMutexDestroy() will free global_init_lock on Win32.
+	  Patch from Marc-Antoine Ruel.
+
+Tue Nov 13 21:26:27 CET 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* schematron.c: fix crash/leaks from xmlSchematronParse due to improper
+	  schema document ownership for bug #495215
+
+Tue Oct 30 21:24:55 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: xmlFree(NULL) should not crash in debug mode
+	  should fix #491651
+
+Tue Oct 16 13:58:41 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* testURI.c: add a debug option printing all the fields within
+	  the parsed URI structure
+
+Wed Oct 10 10:25:52 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: fix to avoid a crash when dumping an attribute from
+	  an XHTML document, patch contributed to fix #485298
+
+Tue Aug 28 19:32:28 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: another nasty regexp case fixed.
+	* test/regexp/ranges2 result/regexp/ranges2: added to regression
+	  suite
+
+Fri Aug 24 10:58:58 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: Enhanced to include port number (if not == 80) on the
+	  "Header:" URL (bug #469681).
+	* xmlregexp.c: Fixed a typo causing a warning message.
+
+Thu Aug 23 22:48:20 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c: fix an open() call with creation without 3rd argument
+	  hopefully that interface is never used.
+
+Thu Aug 23 17:00:49 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/*: preparing release of 2.6.30
+
+Thu Aug 23 20:58:28 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed xmlXPathCompOpEvalPositionalPredicate problem
+	  with object caching (bug #469410)
+
+Thu Aug 23 11:28:38 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c test/schemas/*455953* result/schemas/bug455953*:
+	  applied patch from Frank Gross fixing Schemas IDC import bug
+	  #455953 and also add the test to the regression suite
+
+Wed Aug 22 18:29:42 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: try to fix for the nth time the automata generation
+	  in case of complex ranges. I suppose that time it is actually okay
+
+Tue Aug 14 15:51:05 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: aligned xmlSAXUserParseMemory() to match 
+	  xmlSAXUserParseFile() logic based on Ashwin post, and ifdef
+	  cleanup
+
+Tue Aug 14 11:42:27 CEST 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlIO.c: fixed windows path determination (patch from
+	  Roland Schwarz, bug #462877)
+	* win32/Makefile.mingw win32/configure.js: fixed mingw build
+	  (patch from Roland Schwarz, bug #462877)
+
+Wed Aug  1 09:50:12 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a parser bug where invalid char in comment may
+	  not be detected, reported by Ashwin Sinha
+	* test/errors/comment1.xml result/errors/comment1.xml*: added
+	  the example to the regression suite
+
+Thu Jul 26 13:42:26 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: fixed problem reported on bug #460415
+
+Thu Jul 19 18:10:58 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: applied patch from from Patrik Fimml.  Fixes bug #458268.
+
+Wed Jul 18 11:05:08 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: applied patch from bug #454608 from Patrik Fimml.
+	  Fixes bug #454608.
+
+Wed Jul 11 19:57:59 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch for xsi:nil from Frank Gross, this
+	  should fix bug #358125
+
+Wed Jul  4 17:44:20 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: patch from Dodji Seketeli to avoid a leak on repeated
+	  uses of xmlTextWriterStartDocument()
+
+Tue Jun 26 13:30:50 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fix a crash on solaris when a printf %s with a NULL
+	  argument occurs, should fix #450936
+
+Wed Jun 13 13:33:38 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem in previous fix to xmlXPathNodeSetSort
+
+Tue Jun 12 18:17:28 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* doc/* configure.in NEWS: release of libxml2 2.6.29
+	* valid.c: patch from Dagfinn I. Mannsåker for idness of name
+	  in HTML, c.f. bug #305885.
+
+Tue Jun 12 17:14:08 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fixing bug #319964, parsing of HTML attribute really
+	  should not have namespace processing.
+
+Tue Jun 12 16:42:14 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed the push mode when a big comment occurs before
+	  an internal subset, should close bug #438835
+	* test/comment6.xml result//comment6.xml*: added a special
+	  test in the regression suite
+
+Tue Jun 12 15:41:09 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix bug #414846 where invalid characters in attributes
+	  would sometimes not be detected.
+	* test/errors/attr4.xml result/errors/attr4.xml*: added a specific
+	  test case to the regression tests
+
+Tue Jun 12 14:23:24 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am: apply patch from Ryan Hill to cope with changes
+	  in GNU tar, should fix #396751
+
+Tue Jun 12 12:03:36 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c: try to allow compilation on old python version
+	  should fix #398125
+
+Tue Jun 12 11:48:15 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: htmlNodeDumpFormatOutput didn't handle XML_ATTRIBUTE_NODe
+	  fixes bug #438390
+
+Tue Jun 12 11:37:55 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: workaround misgenerated file: URIs c.f. #437385
+
+Tue Jun 12 11:22:47 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed bug #407436 a crash in a specific case of
+	  Relax-NG validation
+
+Tue Jun 12 11:12:50 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixed bug #383687, some case of recursion on next
+	  were not caught in the catalog code.
+
+Tue Jun 12 10:37:42 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed bug #381877, avoid reading over the end
+	  of stream when generating an UTF-8 encoding error.
+
+Tue Jun 12 10:16:48 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #366161, trivially added the check in
+	  xmlCtxtReset()
+
+Fri Jun  8 21:48:21 CEST 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* win32/configure.js win32/Makefile.msvc: add --vcmanifest flag (yes/no) 
+	  for VC8 build support to embed manifest within files. Under MS VC, build 
+	  libxml2_a_dll.lib by default (LIBXML_STATIC_FOR_DLL flag).
+
+Fri Jun  8 21:37:46 CEST 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* threads.c include/libxml/threads.h: use specified calling convention 
+	  for xmlDllMain. Old SDKs (VC6) only support InterlockedCompareExchange.
+	  add xmlDllMain to header for win32 when building for static dll
+
+Fri Jun  8 10:51:28 CEST 2007 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlwriter.c: fixed problem with namespace declaration being 
+	  written more than once per element start tag
+
+Wed Jun  6 10:18:28 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with xmlXPathNodeSetSort;
+	  fixed problem with xmlXPathNodeTrailingSorted (both bug#413451)
+
+Wed May 30 22:05:08 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with string value for PI node
+	  (bug #442275)
+
+Mon May 28 16:14:50 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fix bug reported by François Delyon
+
+Tue May 22 08:59:48 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c: Fixed typo in xmlCharEncFirstLine pointed out
+	  by Mark Rowe (bug #440159)
+	* include/libxml/xmlversion.h.in: Added check for definition of
+	  _POSIX_C_SOURCE to avoid warnings on Apple OS/X (patch from
+	  Wendy Doyle and Mark Rowe, bug #346675)
+	* schematron.c, testapi.c, tree.c, xmlIO.c, xmlsave.c: minor
+	  changes to fix compilation warnings - no change to logic.
+
+Tue May 15 22:18:08 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: small enhancement to last fix, pointed out
+	  by Alex Cornejo
+
+Tue May 15 12:38:38 PDT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: fixed problem on gzip streams (bug #438045)
+	* xpath.c: fixed minor spot of redundant code - no logic change.
+
+Fri May 11 22:45:18 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: enhanced the coding for xmlXPathCastNumberToString
+	  in order to produce the required number of significant digits
+	  (bug #437179)
+
+Thu May 10 01:52:42 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* list.c: applied patch to fix xmlListAppend() from 
+	  Georges-André SILBER
+	* valid.c: also fix the place wher it was called.
+
+Wed May  2 18:47:33 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: tried to fix an error problem on entity content failure
+	  reported by Michael Day
+
+Wed May  2 18:23:35 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: typo patch from Bjorn Reese
+
+Wed May  2 18:12:58 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied patch from Michael Day to add support for
+	  <embed>
+
+Thu Apr 26 10:58:50 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: Jean-Daniel Dupas pointed a couple of problems
+	  in htmlCreateDocParserCtxt.
+
+Thu Apr 26 10:36:26 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c include/libxml/uri.h: patch from Richard Jones to save
+	  the query part in raw form.
+	* libxml2-python-api.xml: also added accessor for the python bindings
+
+Wed Apr 25 15:57:32 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am doc/examples/Makefile.am Makefile.am: applied
+	  patch from Richard Jones to for the silent flag on valgrind
+	  when doing "make valgrind"
+	* xmlregexp.c: raise a regexp error when '\' is misused to escape
+	  a standard character.
+
+Tue Apr 24 20:15:14 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Richard Jones reported xmlBufferAdd (buf, "", -1), fixing it
+
+Tue Apr 24 10:59:28 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fix xmlURIUnescapeString comments which was confusing
+
+Wed Apr 18 09:52:25 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* include/win32config.h libxml.h: new patch from Andreas Stricke to
+	  better integrate support for Windows CE
+
+Tue Apr 17 16:50:12 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* doc/* configure.in NEWS: release of libxml2 2.6.28
+
+Tue Apr 17 14:47:42 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c libxml.h win32/wince/wincecompat.h win32/wince/wincecompat.c
+	  xmlIO.c nanohttp.c nanoftp.c trio.c triostr.c triostr.h: applied 
+	  patch from Andreas Stricke to ease the compilation on Windows CE
+
+Tue Apr 17 14:34:45 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c catalog.c: "xmllint unusable on win32" so applied
+	  a libxml2 patch from Christian Ehrlicher
+
+Mon Apr 16 09:05:01 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: change the way script/style are parsed to
+	  not try to detect comments, reported by Mike Day
+	* result/HTML/doc3.*: affects the result of that test
+
+Wed Apr 11 22:38:18 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: small enhancement for quantifier range with
+	  min occurs of 0; fixes bug 425542.
+	
+Fri Mar 30 14:41:57 CEST 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied change from Michael Day to avoid a problem when
+	  compiled without zlib support.
+
+Wed Mar 21 17:58:13 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xpath.h: applied documentation patch from James Dennett
+
+Wed Mar 21 21:20:48 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: fixed problem with 0x2d in Char Range (bug #420596)
+	* test/regexp/bug420596, result/regexp/bug420596: added regression
+	  test for this
+
+Wed Mar 21 14:23:08 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c: fixed memory access error on parsing of meta data
+	  which had errors (bug #382206).  Also cleaned up a few warnings
+	  by adding some additional DECL macros.
+
+Tue Mar 20 09:58:13 CET 2007  Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: applied patch from Björn Wiberg to try to fix again
+	  the silly __ss_familly problem on various AIXes, should fix #420184
+
+Wed Mar 14 20:30:38 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in: corrected small error in last commit
+	* xmlreader.c: corrected small typo in last commit
+
+Wed Mar 14 19:35:28 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: fixed problem with referenced attribute groups
+	  (bug #417621)
+	* configure.in: re-ordered some includes for types.h / socket.h
+	  (bug #416001)
+
+Fri Mar  9 17:54:40 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied patch from Julien Reichel cleaning up mode
+	  and state internal flags mixups
+
+Wed Mar  7 16:18:18 HKT 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed xmlXPathCmpNodes for incorrect result on certain
+	  cases when comparing identical nodes (bug #415567) with patch
+	  from Oleg Paraschenko
+
+Fri Feb 16 09:13:38 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* python/libxml.py: fixed tab problem with patch from
+	  Andreas Hanke (bug #408626)
+
+Thu Feb 15 12:43:28 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* doc/xml.html: Changed all references to libxml2 CVS over to
+	  the corresponding SVN.  A few other spelling/grammar/links
+	  also changed.
+	* doc/libxml2-api.xml, doc/*.html: Regenerated all docs.
+
+Tue Feb 13 18:15:58 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: Fixed memory bug with invalid function reported by
+	  Francois Delyon on mailing list
+
+Mon Feb 12 16:40:48 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem with invalid char encountered
+	  during text include (reported on xslt mailing list)
+
+Mon Feb 12 18:30:01 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: small cleanup to avoid packaging .svn
+	* libxml.h threads.c parser.c: applied patch to avoid a problem
+	  in concurrent threaded initialization fix from Ted Phelps
+
+Thu Feb 08 15:35:18 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: added a GROW when parsing complex comments (bug #405666)
+	* gentest.py, testapi.c: added a hack to prevent destruction of any
+	  param with 'destroy' in it's description (i.e. param destroyed by
+	  the routine under test, so shouldn't be destroyed by testapi)
+	* xmlreader.c: added freeing of 'input' param even on error
+	  (fixes leak detected by testapi)
+
+Wed Jan 31 10:25:38 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* testAutomata.c, testRegexp.c, testThreads.c, testThreadsWin32.c,
+	  xmlwriter.c: repositioned #include for libxml.h to avoid
+	  compilation error on some architectures (bug #398277)
+	* fixed screwed-up ChangeLog (deleted some duplicate entries)
+
+Fri Jan 26 00:05:18 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* implemented patch from Stéphane Bidoul for uri.c (bug #389767)
+
+Thu Jan 25 11:15:08 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: added checks for alloc fail on calls to
+	  xmlXPathNewContext (libxslt bug #400242)
+
+Thu Jan 11 15:38:08 PST 2007 William Brack <wbrack@mmm.com.hk>
+
+	* Re-generated the documentation (API chunks 27-29 were missing)
+	  (also causes changes to testapi.c, elfgcchack.h and
+	  win32/libxml2.def.src)
+
+Tue Jan  9 22:24:26 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: fix a memory leak in the python string handling
+	  when SAX event are passed back to the python handlers
+
+Thu Jan  4 18:27:49 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fix xmlTextReaderSetup() description
+	* test/relaxng/empty1.rng test/relaxng/comps_0.xml
+	  test/relaxng/empty1_0.xml test/relaxng/comps.rng
+	  test/relaxng/empty0.rng test/relaxng/empty0_0.xml
+	  test/relaxng/empty1_1.xml: tests which were apparently 
+	  never commited to CVS
+
+Wed Jan  3 16:05:21 PST 2007 Aleksey Sanin <aleksey@aleksey.com>
+
+	* xmlreader.c include/libxml/xmlreader.h win32/libxml2.def.src:
+	expose xmlTextReaderSetup() function
+
+Wed Jan  3 16:14:13 CET 2007 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: adapt the extra versioning code to SVN
+
+Thu Dec 14 16:52:34 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.py: apparently id() sometimes
+	  generate negative values and %X outputs -XXXX :-(
+
+Mon Dec  4 10:30:25 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/tree.h: patch from Michael Day on standalone
+	  and XML declaration detection, and associated documentation change
+
+Mon Dec  4 10:27:01 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: another XInclude user data propagation patch from
+	  Michael Day
+
+Thu Nov 23 17:22:03 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied patch from Steven Rainwater to fix 
+	  UTF8ToHtml behaviour on code points which are not mappable to
+	  predefined HTML entities, fixes #377544
+
+Thu Nov 23 17:11:23 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed a bug where the principal node type of an axis
+	  wasn't tested on name check, fixes bug #377432
+
+Wed Nov  8 10:19:27 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: change htmlCtxtReset() following Michael Day bug
+	  report and suggestion.
+
+Mon Nov  6 09:56:41 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied patch from Igor for path conversion on Windows
+
+Thu Nov  2 11:29:17 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: another small change on the algorithm for the
+	  elimination of epsilon transitions, should help on #362989 too
+
+Wed Nov  1 16:33:10 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied documentation patches from Markus Keim
+	* xmlregexp.c: fixed one bug and added a couple of optimisations
+	  while working on bug #362989
+
+Fri Oct 27 14:54:07 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied a reworked version of Usamah Malik patch
+	  to avoid growing the parser stack in some autoclose cases, should
+	  fix #361221
+
+Thu Oct 26 10:54:40 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: William spotted an obvious bug
+
+Wed Oct 25 18:04:50 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in testapi.c doc//*: preparing release of
+	  libxml2-2.6.27
+	* include/libxml/tree.h: fix a small problem with preproc flags
+
+Fri Oct 20 14:55:47 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix comment for xmlDocSetRootElement c.f. #351981
+	* xmllint.c: order XPath elements when using --shell
+
+Tue Oct 17 23:23:26 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: applied fix from Christopher Boumenot for bug
+	  #362714 on regexps missing ']'
+
+Tue Oct 17 22:32:42 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: applied patch from Marius Konitzer to avoid
+	  leaking in xmlNewInputFromFile() in case of HTTP redirection
+
+Tue Oct 17 22:19:02 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix one problem found in htmlCtxtUseOptions()
+	  and pointed in #340591
+
+Tue Oct 17 22:04:31 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed teh 2 stupid bugs affecting htmlReadDoc() and
+	  htmlReadIO() this should fix #340322
+
+Tue Oct 17 21:39:23 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied patch from Olaf Walkowiak which should fix #334104
+
+Tue Oct 17 18:12:34 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixing HTML minimized attribute values to be generated
+	  internally if not present, fixes bug #332124
+	* result/HTML/doc2.htm.sax result/HTML/doc3.htm.sax 
+	  result/HTML/wired.html.sax: this affects the SAX event strem for
+	  a few test cases
+
+Tue Oct 17 17:56:31 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixing HTML entities in attributes parsing bug #362552
+	* result/HTML/entities2.html* test/HTML/entities2.html: added to
+	  the regression suite
+
+Tue Oct 17 01:21:37 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: started to switch xmllint to use xmlSaveDoc to test
+	  #342556
+	* xmlsave.c: fixed #342556 easy and a whole set of problems with
+	  encodings, BOM and xmlSaveDoc()
+
+Mon Oct 16 15:14:53 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix #348252 if the document clains to be in a
+	  different encoding in the meta tag and it's obviously wrong,
+	  don't screw up the end of the content.
+
+Mon Oct 16 11:32:09 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix a chunking and script bug #347708
+
+Mon Oct 16 09:51:05 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: remove a warning
+	* encoding.c: check with uppercase for AIX iconv() should fix #352644
+	* doc/examples/Makefile.am: partially handle one bug report
+
+Sun Oct 15 22:31:42 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix the patch for unreproductable #343000 but
+	  also fix a line/column keeping error
+	* result/errors/attr1.xml.err result/errors/attr2.xml.err
+	  result/errors/name.xml.err result/errors/name2.xml.err 
+	  result/schemas/anyAttr-processContents-err1_0_0.err 
+	  result/schemas/bug312957_1_0.err: affected lines in error output
+	  of the regression tests
+
+Sat Oct 14 10:46:46 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixing bug #344390 with xmlReconciliateNs
+
+Sat Oct 14 00:31:49 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added --html --memory to test htmlReadMemory to 
+	  test #321632
+	* HTMLparser.c: added various initialization calls which may help 
+	  #321632 but not conclusive
+	* testapi.c tree.c include/libxml/tree.h: fixed compilation with
+	  --with-minimum --with-sax1 and --with-minimum --with-schemas
+	  fixing #326442
+
+Fri Oct 13 18:30:55 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fix a Relax-NG bug related to element content processing,
+	  fixes bug #302836
+	* test/relaxng/302836.rng test/relaxng/302836_0.xml
+	  result/relaxng/302836*: added to regression tests
+
+Fri Oct 13 14:42:44 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a problem in xmlSplitQName resulting in bug #334669
+
+Fri Oct 13 12:27:22 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed xmlIOParseDTD handling of @input in error case,
+	  Should fix #335085
+	* testapi.c: reset the http_proxy env variable to not waste time
+	  on regression tests
+
+Thu Oct 12 23:07:43 CEST 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlIO.c: fix Windows compile - missing xmlWrapOpen.
+
+Thu Oct 12 18:21:18 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed the heuristic used when trying to detect mixed-content
+	  elememts if the parser wants to treat ignorable whitespaces 
+	  in a non-standard way, should fix bug #300263
+
+Thu Oct 12 14:52:38 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a first arg error in SAX callback pointed out by
+	  Mike Hommey, and another one still hanging around. Should fix #342737
+
+Wed Oct 11 23:11:58 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlversion.h.in: fix comment on versions
+	* xmlmemory.c: do not spend too much time digging in dumped memory
+
+Wed Oct 11 18:40:00 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed a weird error where validity context whould not
+	  show up if warnings were disabled pointed out by Bob Stayton
+	* xmlIO.c doc/generator.py: cleanup and fix to regenerate the docs
+	* doc//* testapi.c: rebuilt the docs
+
+Wed Oct 11 14:32:00 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* libxml-2.0.pc.in: applied patch from Mikhail Zabaluev to separate
+	  library flags for shared and static builds, fixes #344594. If this
+	  bites you, use xml2-config.
+
+Wed Oct 11 11:27:37 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: remove the build path recorded in the python
+	  shared module as Peter Breitenlohner pointed out, should fix #346022
+
+Wed Oct 11 11:14:51 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Mikhail Zabaluev fixing the conditions
+	  of unescaping from URL to filepath, should fix #344588.
+
+Wed Oct 11 10:24:58 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xstc/Makefile.am: applied patch from Peter Breitenlohner
+	  for wget detection and fix of a Python path problem, should fix
+	  #340993
+
+Tue Oct 10 22:02:29 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/entities.h entities.c SAX2.c parser.c: trying to
+	  fix entities behaviour when using SAX, had to extend entities 
+	  content and hack on the entities processing code, but that should
+	  fix the long standing bug #159219
+
+Tue Oct 10 14:36:18 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c include/libxml/uri.h: add a new function xmlPathToUri()
+	  to provide a clean conversion when setting up a base
+	* SAX2.c tree.c: use said function when setting up doc->URL
+	  or using the xmlSetBase function. Should fix #346261
+
+Tue Oct 10 11:05:59 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied a portability patch from Emelyanov Alexey
+
+Tue Oct 10 10:52:01 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied and slightly modified a patch from Michael Day to 
+	  keep _private in the parser context when parsing external entities
+
+Tue Oct 10 10:33:43 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py python/types.c: applied patch from Ross Reedstrom,
+	  Brian West and Stefan Anca to add XPointer suport to the Python bindings
+
+Fri Sep 29 11:13:59 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: fixed a comment
+	* xinclude.c include/libxml/xinclude.h: applied a patch from Michael Day
+	  to add a new function providing the _private field for the generated
+	  parser contexts xmlXIncludeProcessFlagsData()
+
+Thu Sep 21 10:36:11 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Michael Day doing some refactoring
+	  for the catalog entity loaders.
+
+Thu Sep 21 08:53:06 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c include/libxml/HTMLparser.h: exports htmlNewParserCtxt()
+	  as Michael Day pointed out this is needed to use htmlCtxtRead*()
+
+Tue Sep 19 14:42:59 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Ben Darnell on #321545, I could not
+	  reproduce the problem but 1/ this is safe 2/ it's better to be safe.
+
+Sat Sep 16 16:02:23 CEST 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: xmlTextConcat works with comments and PI nodes (bug #355962).
+	* parser.c: fix resulting tree corruption when using XML namespace 
+	  with existing doc in xmlParseBalancedChunkMemoryRecover.
+
+Fri Sep  1 11:52:55 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: another patch from Emelyanov Alexey to clean up a few things
+	  in the previous patch.
+
+Wed Aug 30 15:10:09 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Roland Schwingel to fix the problem
+	  with file names in UTF-8 on Windows, and compat on older win9x 
+	  versions.
+
+Tue Aug 22 16:51:22 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed a bug #203125 in Red hat bugzilla, crashing PHP4
+	  on validation errors, the heuristic to guess is a vctxt user
+	  pointer is the parsing context was insufficient.
+
+Mon Aug 21 10:40:10 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmlcatalog.1 doc/xmlcatalog_man.xml doc/xmllint.1 doc/xmllint.xml:
+	  applied patch to man pages from Daniel Leidert and regenerated
+
+Thu Aug 17 00:48:31 CEST 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlwriter.c: Add a document to the xmlwriter structure and 
+	  pass document when writing attribute content for encoding support.
+
+Wed Aug 16 01:15:12 CEST 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* HTMLtree.c xmlsave.c: Add linefeeds to error messages allowing 
+	  for consistant handling.
+
+Tue Aug 15 15:02:18 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Applied the proposed fix for the documentation
+	  of xmlXPathCastToString(); see bug #346202.
+
+Tue Aug 15 14:49:18 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: While investigating bug #350247, I noticed
+	  that xmlSchemaIDCMatcher structs are massively recreated
+	  although only a maximum of 3 structs is used at the same
+	  time; added a cache for those structures to the
+	  validation context.
+
+Sat Aug 12 16:12:53 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Marton Illes to fix an allocation
+	  bug in xmlSchemaXPathEvaluate should close #351032
+
+Mon Aug  7 13:08:46 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Bertrand Fritsch to fix a bug in
+	  xmlSchemaClearValidCtxt
+
+Fri Aug  4 14:50:41 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: fixed the conversion of long parameters
+
+Thu Jul 13 15:03:11 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlsave.c: Removed the automatic generation of CDATA sections
+	  for the content of the "script" and "style" elements when
+	  serializing XHTML. The issue was reported by Vincent Lefevre,
+	  bug #345147.
+	* result/xhtml1 result/noent/xhtml1: Adjusted regression test
+	  results due to the serialization change described above.
+
+Thu Jul 13 08:32:21 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in parser.c xmllint.c include/libxml/parser.h
+	  include/libxml/xmlversion.h.in: applied patch from Andrew W. Nosenko
+	  to expose if zlib support was compiled in, in the header, in the
+	  feature API and in the xmllint --version output.
+
+Thu Jul 13 08:24:14 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: refactor to use normal warnings for entities problem
+	  and not straight SAX callbacks.
+
+Wed Jul 12 17:13:03 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed bug #347316, reported by David Belius:
+	  The simple type, which was the content type definition
+	  of a complex type, which in turn was the base type of a
+	  extending complex type, was missed to be set on this
+	  extending complex type in the derivation machinery.
+
+Mon Jul  3 13:36:43 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Changed xmlXPathCollectAndTest() to use
+	  xmlXPathNodeSetAddNs() when adding a ns-node in case of
+	  NODE_TEST_TYPE (the ns-node was previously added plainly
+	  to the list). Since for NODE_TEST_ALL and NODE_TEST_NAME
+	  this specialized ns-addition function was already used,
+	  I assume it was missed to be used with NODE_TEST_TYPE.
+
+Mon Jul  3 10:57:33 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied const'ification of strings patch from
+	  Matthias Clasen
+
+Thu Jun 29 13:51:12 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: patch from Andrew W. Nosenko, xmlFreeRMutex forgot to
+	  destroy the condition associated to the mutex.
+
+Thu Jun 29 12:48:00 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Fixed a double-free in xmlXPathCompOpEvalToBoolean(),
+	  revealed by a Libxslt regression test.
+
+Thu Jun 29 12:28:07 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Enhanced xmlXPathCompOpEvalToBoolean() to be also
+	  usable outside predicate evaluation; the intention is to
+	  use it via xmlXPathCompiledEvalToBoolean() for XSLT tests,
+	  like in <xsl:if test="/foo">.
+	  
+Wed Jun 28 19:11:16 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Fix a memory leak which occurred when using
+	  xmlXPathCompiledEvalToBoolean().
+
+Mon Jun 26 17:24:28 UTC 2006 William Brack <wbrack@mmm.com.hk>
+
+	* python/libxml.c, python/libxml.py, python/tests/compareNodes.py,
+	  python/tests/Makefile.am:
+	  Added code submitted by Andreas Pakulat to provide node
+	  equality, inequality and hash functions, plus a single
+	  test program to check the functions (bugs 345779 + 345961).
+
+Mon Jun 26 18:38:51 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Added xmlXPathCompiledEvalToBoolean() to the API and
+	  adjusted/added xmlXPathRunEval(), xmlXPathRunStreamEval(),
+	  xmlXPathCompOpEvalToBoolean(), xmlXPathNodeCollectAndTest()
+	  to be aware of a boolean result request. The new function
+	  is now used to evaluate predicates.
+
+Mon Jun 26 16:22:50 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Fixed an bug in xmlXPathCompExprAdd(): the newly
+	  introduced field @rewriteType on xmlXPathStepOp was not
+	  initialized to zero here; this could lead to the activation
+	  of the axis rewrite code in xmlXPathNodeCollectAndTest() when
+	  @rewriteType is randomly set to the value 1. A test
+	  (hardcoding the intial value to 1) revealed that the
+	  resulting incorrect behaviour is similar to the behaviour
+	  as described by Arnold Hendriks on the mailing list; so I
+	  hope that will fix the issue.	  
+
+Fri Jun 23 18:26:08 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Fixed an error in xmlXPathEvalExpr(), which
+	  was introduced with the addition of the d-o-s rewrite
+	  and made xpath.c unable to compile if XPATH_STREAMING
+	  was not defined (reported by Kupriyanov Anatolij -
+	  #345752). Fixed the check for d-o-s rewrite
+	  to work on the correct XPath string, which is ctxt->base
+	  and not comp->expr in this case.
+
+Mon Jun 19 12:23:41 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Added optimization for positional predicates
+	  (only short-hand form "[n]"), which have a preceding
+	  predicate: "/foo[descendant::bar][3]".
+
+Sun Jun 18 20:59:02 EDT 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: try to fix the crash raised by the parser in
+	  recover mode as pointed by Ryan Phillips
+
+Sun Jun 18 18:44:56 EDT 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c: patch from Nic Ferrier to provide a better type
+	  mapping from XPath to python
+
+Sun Jun 18 18:35:50 EDT 2006 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: applied patch from Boz for VMS and reporting
+	  Schemas errors.
+
+Sun Jun 18 18:22:25 EDT 2006 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c: applied patch from Felipe Contreras when compiling
+	  with --with-minimum
+
+Fri Jun 16 21:37:44 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c include/libxml/tree.h: Fixed a bug in
+	  xmlDOMWrapAdoptNode(); the tree traversal stopped if the
+	  very first given node had an attribute node :-( This was due
+	  to a missed check in the traversal mechanism.
+	  Expanded the xmlDOMWrapCtxt: it now holds the namespace map
+	  used in xmlDOMWrapAdoptNode() and xmlDOMWrapCloneNode() for
+	  reusal; so the map-items don't need to be created for every
+	  cloning/adoption. Added a callback function to it for
+	  retrieval of xmlNsPtr to be set on node->ns; this is needed
+	  for my custom handling of ns-references in my DOM wrapper.
+	  Substituted code which created the XML namespace decl on
+	  the doc for a call to xmlTreeEnsureXMLDecl(). Removed
+	  those nastly "warnigns" from the docs of the clone/adopt
+	  functions; they work fine on my side.
+	  
+Mon Jun 12 13:23:11 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/pattern/namespaces: Adjusted the result of a
+	  regression test, since the fix of xmlGetNodePath() revealed a
+	  bug in this test result.
+
+Mon Jun 12 13:06:03 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Got rid of a compiler warning in xmlGetNodePath().
+
+Mon Jun 12 12:54:25 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Fixed xmlGetNodePath() to generate the node test "*"
+	  for elements in the default namespace, rather than generating
+	  an unprefixed named node test and loosing the namespace
+	  information.
+
+Fri Jun  9 21:45:02 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* include/libxml/parser.h: Clarified in the docs that the tree
+	  must not  be tried to be modified if using the parser flag
+	  XML_PARSE_COMPACT as suggested by Stefan Behnel
+	  (#344390).
+
+Tue Jun  6 17:50:43 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.ini NEWS doc//* libxml.spec.in : preparing release of 2.6.26
+
+Tue Jun  6 17:25:23 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Fixed self-invented a segfault in xmlXPathCtxtCompile(),
+	  when the expression was not valid and @comp was NULL and I
+	  tried to do the d-o-s rewrite.
+
+Tue Jun  6 15:19:57 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.ini NEWS doc//* libxml.spec.in : preparing release of 2.6.25
+
+Tue Jun  6 11:28:15 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Enabled the compound traversal again; I added a
+	  check to use this only if the have an expression starting
+	  with the document node; so in the case of "//foo", we
+	  already know at compilation-time, that there will be only
+	  1 initial context node. Added the rewrite also to
+	  xmlXPathEvalExpr().
+
+Tue Jun  6 10:23:10 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fix bug #343968, include='text' can't lead to a 
+	  recursion.
+
+Fri Jun  2 22:47:08 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Disabled the compound traversal for the release;
+	  I need first to assure that this is done only if we have
+	  1 initial node.
+
+Wed May 31 13:53:41 PST 2006 Aleksey Sanin <aleksey@aleksey.com>
+      
+	* xpath.c: fixed memory leak in xpath error reporting
+
+Wed May 31 15:30:16 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h triodef.h: applied patch from Olli Savia for LynxOS
+
+Wed May 31 14:33:00 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c include/libxml/xpath.h runsuite.c:
+	  Changed the name of the recently added public function
+	  xmlXPathContextSetObjectCache() to
+	  xmlXPathContextSetCache(); so a more generic one, in
+	  case we decide to cache more things than only XPath
+	  objects.
+
+Tue May 30 21:36:16 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Optimized xmlXPathNodeCollectAndTest() and
+	  xmlXPathNodeCollectAndTestNth() to evaluate a compound
+	  traversal of 2 axes when we have a "//foo" expression.
+	  This is done with a rewrite of the XPath AST in
+	  xmlXPathRewriteDOSExpression(); I added an additional field
+	  to xmlXPathStepOp for this (but the field's name should be
+	  changed). The mechanism: the embracing descendant-or-self
+	  axis traversal (also optimized to return only nodes which
+	  can hold elements), will produce context nodes for the
+	  inner traversal of the child axis. This way we avoid a full
+	  node-collecting traversal of the descendant-or-self axis.
+	  Some tests indicate that this can reduce execution time of
+	  "//foo" to 50%. Together with the XPath object cache this
+	  all significantly speeds up libxslt.
+
+Tue May 30 11:38:47 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: A warning will now be reported in the value of
+	  the XSD attribute 'schemaLocation' does not consist of tuples
+	  (namespace-name, document-URI). A warning will be reported
+	  if a schema document could not be found at the specified
+	  location (via 'schemaLocation' or
+	  'noNamespaceSchemaLocation').
+	* include/libxml/xmlerror.h: Added XML_SCHEMAV_MISC to
+	  xmlParserErrors.
+
+Tue May 30 11:21:34 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Enhanced xmlXPathNodeCollectAndTest() to avoid
+	  recreation (if possible) of the node-set which is used to
+	  collect the nodes in the current axis for the currect context
+	  node. Especially for "//foo" this will decrease dramatically
+	  the number of created node-sets, since for each node in the
+	  result node-set of the evaluation of descendant-or-self::node()
+	  a new temporary node-set was created. Added node iterator
+	  xmlXPathNextChildElement() as a tiny optimization for
+	  child::foo.
+
+Mon May 29 18:06:17 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c include/libxml/xpath.h: Added an XPath object cache.
+	  It sits on an xmlXPathContext and need to be explicitely
+	  activated (or deactivated again) with
+	  xmlXPathContextSetObjectCache(). The cache consists of 5
+	  lists for node-set, string, number, boolean and misc XPath
+	  objects. Internally the xpath.c module will use object-
+	  deposition and -acquisition functions which will try to reuse
+	  as many XPath objects as possible, and fallback to normal
+	  free/create behaviour if no cache is available or if the cache
+	  is full.
+	* runsuite.c: Adjusted to deactivate the cache for XML Schema
+	  tests if a cache-creation is turned on by default for the whole
+	  library, e.g. for testing purposes of the cache. It is
+	  deactivated here in order to avoid confusion of the memory leak
+	  detection in runsuite.c.
+
+Wed May 24 10:54:25 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Removed a memcpy if xmlXPathNodeSetMerge(); it
+	  seems we really need to walk the whole list, since those
+	  nastly namespace nodes need to be added with
+	  xmlXPathNodeSetDupNs(); thus a pure memcpy is not possible.
+	  A flag on the node-set indicating if namespace nodes are in
+	  the set would help here; this is the 3rd flag which would
+	  be usefull with node-sets. The current flags I have in mind:
+	  1) Is a node-set already sorted?
+	     This would allow for rebust and optimizable sorting
+	     behaviour.
+	  2) Of what type are the nodes in the set (or of mixed type)?
+	     This would allow for faster merging of node-sets.
+	  3) Are namespace nodes in the set?
+	     This would allow to skipp all the namespace node specific
+	     special handling. Faster node-set merging if the first
+	     set is empty; just memcpy the set.
+
+Mon May 22 17:14:00 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Optimization of count(): eliminated sorting
+	  (see bug #165547). Optimization of XPATH_OP_FILTER if the
+	  predicate is a [1] (disable with XP_OPTIMIZED_FILTER_FIRST if
+	  it produces trouble). Tiny opt in xmlXPathNodeSetMerge().
+	  
+Mon May 22 13:33:12 CEST 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: Revert behavior change in xmlSetProp to handle attributes
+	  with colons in name and no namespace.
+
+Fri May 19 21:56:43 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Substituted all remaining calls to xmlXPathCmpNodes()
+	  for xmlXPathCmpNodesExt(). Tiny further enhancement of
+	  xmlXPathCmpNodesExt(). Added additional checks in various code
+	  parts to avoid calling sorting or merging functions if the
+	  node-set(s) don't need them; i.e., if they are empty or contain
+	  just one node.
+
+Fri May 19 13:16:58 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Optimized the comparison for non-element nodes
+	  in xmlXPathCmpNodesExt(); the comparison is used for sorting
+	  of node-sets. This enhancement is related to bug #165547.
+	  There are other places where the old comparison function
+	  xmlXPathCmpNodes() is still called, but I currently don't
+	  know exactly what those calls are for; thus if they can be
+	  substituted (if it makes sense) for the new function.
+
+Tue May 16 16:55:13 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xpath.c: Applied patch from Rob Richards, fixing a potential
+	  memory leak in xmlXPathTryStreamCompile(), when a list of
+	  namespaces was assigned to the XPath compilation context;
+	  here a new namespace list was created and passed to
+	  xmlPatterncompile(); but this list was not freed afterwards.
+	  Additionally we avoid now in xmlXPathTryStreamCompile() to
+	  compile the expression, if it has a colon - indicating
+	  prefixed name tests - and no namespace list was given. The
+	  streaming XPath mechanism needs a namespace list at
+	  compilation time (unlike normal XPath, where we can bind
+	  namespace names to prefixes at execution time).
+	* pattern.c: Enhanced to use a string dict for local-names,
+	  ns-prefixes and and namespace-names.
+	  Fixed xmlStreamPushInternal() not to use string-pointer
+	  comparison if a dict is available; this won't work, since
+	  one does not know it the given strings originate from the
+	  same dict - and they normally don't do, since e.g.
+	  namespaces are hold on xmlNs->href. I think this would be
+	  worth an investigation: if we can add a @doc field to xmlNs
+	  and put the @href in to a additionan namespace dict hold
+	  in xmlDoc. Daniel will surely not like this idea :-) But
+	  evaluation of tons of elements/attributes in namespaces
+	  with xmlStrEqual() isn't the way we should go forever.
+	  
+Thu May 11 18:03:49 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed bug #341337, reported by David Grohmann.
+	  The code expected a node (xmlNodePtr) on the info for a
+	  non-existent default attribute, which clearly cannot be
+	  expected, since the attribute does not exist. I can only
+	  guess that this sneaked trying to eliminate the query
+	  for the owner-element, which is unavoidable actually.
+	  Note that creation of default attributes won't have an
+	  effect if validating via SAX/XMLReader; i.e., the processor
+	  won't fire additional start-attribute events (I'm not even
+	  sure if Libxml2 has such a SAX-event; I think it hands them
+	  all over in the start-element event).
+
+Tue May  9 21:47:58 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed bug #341150, reported by Michael Romer.
+	  In xmlSchemaBuildContentModelForSubstGroup(),
+	  xmlAutomataNewOnceTrans2() was incorrectly used instead of
+	  xmlAutomataNewTransition2() to mimic a xs:choice for
+	  substitution-groups.
+	* test/schemas/subst-group-1_1.xsd
+	  test/schemas/subst-group-1_0.xml
+	  result/schemas/subst-group-1_0_1
+	  result/schemas/subst-group-1_0_1.err: Added regression test
+	  supplied by Michael Romer for bug #341150.
+
+Sat May  6 11:05:24 HKT 2006 William M. Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: Fixed compilation error with patch supplied by
+	  Graham Bennett.
+
+Thu May  4 19:14:03 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: We'll raise an internal error and stop
+	  validation now when an entity is found in the instance
+	  document, since we don't support automatic entity
+	  substitution by the schema processor (yet?) -
+	  see bug #340316, reported by Nick Wellnhofer.
+
+Wed May  3 15:16:00 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: applied another Python detection patch from Joseph Sacco
+	* libxml.spec.in: cleanup the changelog section, asciifies the spec file
+	  too
+
+Tue May  2 22:34:54 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fix a mix of code and declarations showing up on Windows
+	  patch from Kjartan Maraas, fixing #340404
+
+Tue May  2 14:24:40 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fixing bug #340398 xmlCharEncOutFunc writing to
+	  input buffer
+
+Fri Apr 28 18:29:22 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in doc//*: preparing 2.6.24 release, fixed Python
+	  paths at the last moment
+	* relaxng.c testapi.c tree.c: fix some comments
+
+Thu Apr 27 10:15:45 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Roland Schwingel to allow UTF-8
+	  file paths on Windows
+
+Thu Apr 27 10:10:58 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: patch from Jason Viers for line breaks after EndPI
+
+Tue Apr 25 22:22:58 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix compilation without tree
+
+Tue Apr 25 18:17:37 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: applied patch from Gary Coady to really make sure
+	  xmllint --nonet would not reach the network, should fix #337483.
+
+Tue Apr 25 14:52:15 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: applied patch from Joseph Sacco changing slightly
+	  the python detection scheme should fix bug #338526
+
+Mon Apr 24 10:50:19 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix the error message for invalid code point in content
+	  c.f. bug #339311
+
+Wed Apr 19 13:16:23 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c test/schemas/restriction-enum-1*
+	  result/schemas/restriction-enum-1*: Fixed incorrect
+	  validation of restricted enumerations. Added related
+	  regression tests.
+
+Thu Apr 13 09:47:25 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixing a deallocation problem in xmlSchemaAddSchemaDoc()
+	  in case of errors, should fix bug #338303
+
+Thu Apr 13 09:31:45 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixing a deallocation problem in xmlRelaxNGParse() 
+	  in case of errors, should fix bug #338306
+
+Thu Apr  6 10:22:17 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmlcatalog.1 doc/xmlcatalog_man.xml doc/xmllint.1 doc/xmllint.xml:
+	  applied man page improvements from Daniel Leidert
+
+Mon Mar 27 11:44:07 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: removed unused code or variables, from Stefan Kost
+	  fixing #336163 and #336164
+
+Mon Mar 27 11:38:21 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Stefan Kost fixing #336160
+
+Mon Mar 27 11:23:39 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* chvalid.c genChRanges.py genUnicode.py xmlunicode.c
+	  include/libxml/chvalid.h include/libxml/xmlunicode.h: applied
+	  patches from Aivars Kalvans to make unicode tables const, fixes
+	  bug #336096, this also updates to Unicode 4.01 final with a couple
+	  of character ranges fixes.
+
+Mon Mar 27 00:51:40 CEST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* chvalid.c genChRanges.py include/libxml/chvalid.h: fixed bug
+	  #335603 and resync'ed genChRanges.py to the expected output.
+
+Wed Mar 22 00:14:34 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: applied patch from Youri Golovanov fixing bug
+	  #316338 and adding a couple of optimizations in the regexp
+	  compilation engine.
+	* test/regexp/bug316338 result/regexp/bug316338: added regression
+	  tests based on the examples provided in the bug report.
+
+Fri Mar 10 08:40:55 EST 2006 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c encoding.c xmlschemas.c xpath.c xpointer.c: fix a few
+	  warning raised by gcc-4.1 and latests changes
+
+Fri Mar 10 01:34:42 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c schematron.c testAutomata.c tree.c valid.c xinclude.c
+	  xmlcatalog.c xmlreader.c xmlregexp.c xpath.c: end of first
+	  pass on coverity reports.
+
+Thu Mar  9 19:36:14 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlschemas.c xmlschemastypes.c: more cleanups based
+	  on coverity reports.
+	
+Thu Mar  9 17:47:40 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c catalog.c encoding.c entities.c example/gjobread.c
+	  python/libxml.c: more cleanups based on coverity reports.
+
+Thu Mar  9 15:12:19 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c parser.c parserInternals.c pattern.c uri.c: a bunch
+	  of small cleanups based on coverity reports.
+
+Thu Mar  9 09:42:10 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.bcb: added schematron as pointed out by Eric Zurcher
+
+Tue Mar  7 09:50:09 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xml2-config.in: fix Red Hat bug #184170
+
+Mon Mar  6 14:21:08 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Simplified usage of the internal xmlNsMap. Added a
+	  "strict" lookup for namespaces based on a prefix. Fixed a
+	  namespace processing issue in the clone-node function, which
+	  occured if a @ctxt argument was given.
+	  
+Fri Mar  3 17:44:10 CET 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* valid.c: fix HTML attribute ID checking for input element.
+	  Maintain current attribute "name" behavior for now.
+
+Thu Mar  2 18:59:50 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Bundled lookup of attr-nodes and retrieving their
+	  values into the functions xmlGetPropNodeInternal() and
+	  xmlGetPropNodeValueInternal(). Changed relevant code
+	  to use those functions.
+
+Mon Feb 27 20:42:04 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: workaround HP-UX compiler bug by Rick Jones
+
+Mon Feb 27 10:57:05 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml2.py: remove a tab, as pointed out on IRC
+
+Sat Feb 25 18:12:10 CET 2006 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: Fix the add sibling functions when passing attributes.
+	  Modify testing for ID in xmlSetProp.
+	  No longer remove IDness when unlinking or replacing an attribute.
+
+Fri Feb 24 21:20:33 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: Martin Cole pointed out a bug in xmlCatalogAdd()
+	  if /etc/xml/catalog doesn't exist.
+
+Thu Feb 23 23:06:18 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc//*: updated the Ruby bindings links, and regenerated the
+	  docs.
+
+Thu Feb 23 09:12:27 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: improve catalog debugging message patch from Rick Jones
+
+Wed Feb 22 16:09:10 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c: Nic Ferrier found debug statement left in the
+	  XPath conversion code
+
+Tue Feb 21 20:23:14 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.xml: small man page improvements from
+	  Daniel Leidert
+
+Mon Feb 20 15:45:19 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a side-effect of the previous XSI bugfix:
+	  The constructor needs a bucket to be assigned during component
+	  fixup.
+
+Mon Feb 20 14:32:36 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlschemastypes.c: Fixed xs:boolean to reject
+	  the empty string (reported by Bas Driessen on the mailing-list).
+	  Fixed schema XSI-acquisition and construction: the schemata
+	  (xmlSchema) didn't get the targetNamespace in some cases, thus	  
+	  the component resolution mechanism failed to work. The XSI
+	  stuff needs to be tested more intensively; think about how
+	  to test this for regression.
+
+Mon Feb 20 09:57:41 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.xml: more man page improvements from
+	  Daniel Leidert
+
+Sun Feb 19 22:31:33 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.xml: man page improvements from Daniel
+	  Leidert, c.f. #331290
+
+Sun Feb 19 17:54:04 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: fix an error report when using --path and --valid
+	  closes bug #331290
+
+Sun Feb 19 16:20:43 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: trying to fix #331062, this is again a problem
+	  around interleave, there is no good fix unless reimplementing
+	  but this works around some cases and allow to validate in that
+	  case.
+
+Wed Feb 15 11:55:22 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Fixed bug #328896 reported by Liron. The path
+	  for text- and CDATA-section-nodes was computed incorrectly
+	  in xmlGetNodePath().
+
+Sun Feb 12 20:12:22 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: bug fixes for #327167 as well as some cleanups
+	  and more thorough tests on atoms comparisons.
+
+Thu Feb  9 10:07:20 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* include/wsockcompat.h: patch from Eric Zurcher to compile with
+	  Borland C++ 6
+
+Sun Feb  5 04:03:59 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: bill pointed out a missing block in xmlParseComment
+	  trying to fill with a normal processing of the given character.
+
+Sun Feb  5 03:41:39 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed the comment streaming bug raised by Graham Bennett
+	* test/badcomment.xml result//badcomment.xml*: added to the regression
+	  suite.
+
+Fri Feb  3 17:36:41 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* include/libxml/tree.h: Added the xmlDOMWrapCloneNode() to
+	  the header file.
+
+Fri Feb  3 17:29:22 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Added an initial version of xmlDOMWrapCloneNode() to
+	  the API. It will be used to reflect DOM's Node.cloneNode and
+	  Document.importNode methods.
+	  The pros: 1) non-recursive, 2) optimized ns-lookup
+	  (mostly pointer comparison), 3) user defined ns-lookup,
+	  4) save ns-processing. The function is in an unfinished
+	  and experimental state and should be only used to test it.
+
+Fri Feb  3 10:42:48 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied patch from Rob Richards fixing the URI regressions
+	  tests on Windows which seems to indicate bad escaping.
+
+Thu Feb  2 13:11:26 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Fixed some bugs xmlDOMWrapReconcileNamespaces() wrt
+	  the previous addition of the removal of redundant ns-decls.
+
+Wed Feb  1 17:32:25 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Enhanced xmlDOMWrapReconcileNamespaces() to remove
+	  redundant ns-decls if the option XML_DOM_RECONNS_REMOVEREDUND
+	  was given. Note that I haven't moved this option to the
+	  header file yet; so just call this function with an @option
+	  of 1 to test the behaviour.	  
+
+Wed Feb  1 12:21:08 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tapi.c win32/Makefile.*: Added changed as proposed on
+	  the mailing list by venkat naidu in order to compile
+	  testapi.c on windows.
+
+Thu Jan 19 09:57:28 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xml2-config.in: trying to fix windows/configure
+	  issues reported by Tim Van Holder
+
+Wed Jan 18 18:21:15 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c libxml.h parser.c: try to fix xmlParseInNodeContext
+	  when operating on an HTML document.
+
+Mon Jan  9 17:27:15 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* relaxng.c include/libxml/relaxng.h: Added
+	  xmlRelaxNGSetParserStructuredErrors() to the API.
+
+Mon Jan  9 15:33:16 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: reverted first patches for #319279 which led to #326295
+	  and fixed the problem in xmlParseChunk() instead
+	* test/ent11 result//ent11*: added test for #326295 to the regression
+	  suite
+
+Thu Jan  5 16:25:06 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in libxml.spec.in testapi.c doc/*: upated the news
+	  regenerated the docs, preparing for release of 2.6.23
+	* pattern.c xmlschemas.c: fixed some comments
+	
+Thu Jan  5 15:48:27 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/XPath/docs/nodes test/XPath/tests/nodespat
+	  result/XPath/tests/nodespat: Added regression tests for
+	  the latest XPath/pattern fixes.
+
+Thu Jan  5 15:43:38 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c: Another fix to handle "foo//.": "foo" was not
+	  included in the resulting node-set.
+
+Thu Jan  5 13:22:29 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c xpath.c include/libxml/pattern.h:
+	  Fixed bug #322928, reported by Erich Schubert: The bug was
+	  in pattern.c, which is used for a tiny subset of xpath
+	  expression which can be evaluated in an optimized way.
+	  The doc-node was never considered when evaluating "//"
+	  expressions. Additionally, we fixed resolution
+	  to nodes of any type in pattern.c; i.e. a "//." didn't work
+	  yet, as it did select only element-nodes. Due to this
+	  issue the pushing of nodes in xpath.c needed to be adjusted
+	  as well.
+
+Wed Jan  4 18:07:47 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: tiny refactoring patch from Bjorn Reese
+
+Wed Jan  4 15:00:51 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fix bug #324432 with <xml:foo/>
+	* test/ns7 resul//ns7*: added to the regression tests
+
+Wed Jan  4 10:53:56 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* include/wsockcompat.h: applied patch from Mark Junker, fixing a 
+	  MinGW compilation problem, should close bug #324943
+
+Tue Jan  3 11:49:54 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed last dependency on the obsolete enum
+	  xmlSchemaValidError.
+
+Mon Jan  2 11:20:00 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h xmlschemas.c: compilation
+	  and doc build fixes from Michael Day
+
+Wed Dec 28 22:12:34 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: bug in xmlRegExecPushString2() pointed out by 
+	  Sreeni Nair.
+
+Tue Dec 20 16:55:31 CET 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: fix bug #322136 in xmlNodeBufGetContent when entity ref is 
+	  a child of an element (fix by Oleksandr Kononenko).
+	* HTMLtree.c include/libxml/HTMLtree.h: Add htmlDocDumpMemoryFormat.
+
+Tue Dec 20 11:43:06 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlstring.c: Fixed a segfault during
+	  text concatenation when validating a node tree:
+	  xmlStrncat was called with a @len of -1; but unlike
+	  xmlStrncatNew, it does not calculate the length
+	  automatically in such a case (reported by Judy Hay
+	  on the mailing list).
+	  Updated the descriptions of the involved string
+	  functions to note this.
+
+Thu Dec 15 12:11:07 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c: applied patch from Gary Coady to accept gzipped
+	  http resources.
+
+Wed Dec 14 18:41:26 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* win32/configure.js: Added enable/disable of runtime
+	  debugging (LIBXML_DEBUG_RUNTIME).
+
+Wed Dec 14 18:11:50 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* include/libxml/xmlversion.h.in: Fixed to define
+	  LIBXML_DEBUG_RUNTIME on the basis of @WITH_RUN_DEBUG@.
+
+Tue Dec 13 12:49:23 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/bug321475* result/schemas/bug321475*:
+	  Added regression test for bug #321475 (reported by
+	  Gabor Nagy). Fixing of bug #323510 seemed to have
+	  fixed this bug as well.
+
+Mon Dec 12 16:19:16 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/bug323510* result/schemas/bug323510*:
+	  Added regression test for bug #323510.
+
+Mon Dec 12 16:11:13 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Workaround for bug #323510 (reported by
+	  Jonathan Filiatrault): substituted the epsilon transition
+	  for a labelled transition, in order to avoid a bug in
+	  xmlregexp.c which eliminated the epsilon transition and
+	  marked the initial state as final.
+
+Mon Dec 12 14:25:46 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: Gary Coady pointed a memory leak in
+	  xmlTextReaderReadInnerXml() applied patch fixing #323864
+
+Sat Dec 10 12:08:28 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c configure.in parserInternals.c runsuite.c runtest.c
+	  testapi.c xmlschemas.c xmlschemastypes.c xmlstring.c: fixed a number
+	  of warnings shown by HP-UX compiler and reported by Rick Jones
+
+Fri Dec  9 18:57:31 CET 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlwriter.c: Insert space between pubid and sysid when both 
+	  passed to xmlTextWriterStartDTD and indenting not being used.
+	  Remove no longer used Mem callbacks.
+
+Fri Dec  9 11:01:16 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* runsuite.c: Changed to instantly mark instance-tests as
+	  failed if the corresponding schema was invalid. This
+	  reflects the side of the Python code for the XML Schema test
+	  suite. We now get the same number of failed tests on both
+	  sides.
+
+Wed Dec  7 14:59:01 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlreader.c include/libxml/xmlreader.h: Added
+	  xmlTextReaderSchemaValidateCtxt() to the API.
+
+Wed Dec  7 12:59:56 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a segfault: the instance document was
+	  still tried to be validated, if the schema, dynamically
+	  acquired using XSI was invalid, thus mangled. The
+	  validation will stop (or rather won't validate) now in
+	  such a case. The schema parser error code will be set
+	  on the validion context now; this is somehow not nice,
+	  but it assures that the validation context indicates an
+	  error in there was a parser error.
+
+Tue Dec  6 18:57:23 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: small doc patch from Aron Stansvik
+	* legacy.c: another doc patch for a deprecated API
+
+Mon Dec  5 16:23:49 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* Makefile.am: Tiny change for 'make tests': raised
+	  the number of expected failures for James Clark's
+	  XML Schema datatype tests from 10 to 11. The additional
+	  reported error was agreed to be correct long time ago,
+	  but we missed to adjust the message reported by
+	  the testing script.
+
+Fri Dec  2 13:51:14 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/decimal* result/schemas/bug322411*:
+	  Added missing regression test results for the latest IDC
+	  and xs:decimal bugs.
+
+Wed Nov 30 12:22:23 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/decimal* test/schemas/bug322411*: Added
+	  regression tests for the latest IDC and xs:decimal bugs.
+
+Wed Nov 30 11:57:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed bubbling of duplicate IDC nodes: the
+	  parent's list of duplicates was filled with NULLs instead
+	  of the nodes under certain conditions. This lead to a
+	  segfault when the list's entries were accessed.
+
+Mon Nov 28 17:28:53 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Fixed parsing of xs:decimal to
+	  allow/deny special lexical forms. Fixed the totalDigits
+	  for values in the range (x < 1) &&  (x > -1) && (x != 0);
+	  E.g "0.123" has now a totalDigits of 3 (was 4 previously).
+	  Adjusted the comparison function for decimals due to this
+	  change. As a side effect comparison against zeroes was
+	  optimized.
+
+Mon Nov 28 13:25:11 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: An assignment to a local variable, which was
+	  used to access the IDC node list, was missing after the
+	  reallocation of the list (reported by Fabrice GUY
+	  bug #322411). Renamed the define ENABLE_IDC_NODE_TABLES
+	  to ENABLE_IDC_NODE_TABLES_TEST and *disabled* it, since
+	  it is used to force bubbling of IDC node tables even
+	  if not necessary; this was intended to be used for test
+	  purposes, but I obviously missed to disable it (although
+	  it apparently helped finding the bug).
+
+Wed Nov 23 17:34:52 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: In xmlSchemaAssembleByXSI() the return value
+	  of xmlSchemaGetMetaAttrInfo() was not assigned to anything;
+	  this caused XSI-driven-dynamic schema acquisition to fail
+	  with @noNamespaceSchemaLocation (reported by Julien Lamy
+	  on the mailing list).
+
+Tue Nov 22 18:31:34 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a bug in xmlSchemaFindRedefCompInGraph()
+	  which caused the search for components to stop at the
+	  first encountered attribute group component.
+	  Fixed error report in xmlSchemaCheckSRCRedefineFirst(): the
+	  designation of a not-found component was not reported.
+
+Mon Nov 21 12:23:28 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: Albert Chin found another signed/unsigned problem
+	  in the date and time code raised on IRIX 6.5
+
+Fri Nov 18 18:13:38 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/xmlschemas.h:
+	  Added xmlSchemaSetParserStructuredErrors() to the API.
+	  Fixed channeling of error relevant information to
+	  subsequent parser/validation contexts.
+
+Thu Nov 17 14:11:43 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: removed unreachable code pointed out by 
+	  Oleksandr Kononenko, fixes bug #321695
+
+Thu Nov 17 08:24:31 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: use ctxt->standalone = -2 to indicate that the
+	  XMLDecl was parsed but no standalone attribute was found,
+	  suggested by Michael Day to detect if an XMLDecl was found.
+
+Tue Nov 15 09:49:24 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: Hisashi Fujinaka pointed that errors in Schemas tests
+	  were not properly reported.
+
+Sun Nov 13 13:42:41 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Geert Jansen to remove xmlBufferClose()
+	  which is not needed.
+
+Fri Nov 11 13:48:52 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Changed xmlSchemaFormatIDCKeySequence()
+	  to use xmlSchemaGetCanonValueWhtspExt() in order to
+	  correctly report values for xs:anySimpleType.
+	* test/schemas/idc-keyref-err1*
+	  result/schemas/idc-keyref-err1*: Added a test for this change.
+
+Wed Nov  9 13:07:24 EST 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlIO.c xmlwriter.c: function consolidation when writing to xmlBuffer.
+	  Return error condition not len if xmlwriter fails writing to buffer.
+
+Wed Nov  9 09:54:54 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c xmlIO.c include/libxml/xmlIO.h include/libxml/xmlsave.h:
+	  applied patch from Geert Jansen to implement the save function to 
+	  a xmlBuffer, and a bit of cleanup.
+
+Mon Nov  7 14:58:39 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlschemastypes.c: Fixed the type of the
+	  totalDigits value to be positiveInteger.
+	  Fixed crash in an error report function when we gave it
+	  the document node; only element and attribute nodes are
+	  processed now (reported by Rob Richards).
+
+Tue Nov  1 16:22:29 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fix bug #319897, problem with counted atoms
+	  when the transition itself is counted too
+	* result/regexp/hard test/regexp/hard: augmented the regression
+	  tests with the problem exposed.
+
+Tue Nov  1 11:54:39 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.mingw include/win32config.h: applied patch from
+	  Mark Junker to fix compilation with MinGW
+
+Fri Oct 28 18:36:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.3: tiny fix from Albert Chin
+	* runsuite.c runtest.c testapi.c: portability cleanup for arch
+	  needing trio for *printf
+
+Fri Oct 28 12:21:39 EDT 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: add additional checks to prevent tree corruption. fix problem 
+	  copying attribute using xmlDocCopyNode from one document to another.
+
+Fri Oct 28 17:58:13 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in vms/config.vms macos/src/config-mac.h:
+	  cleanup from Albert Chin
+	* doc/Makefile.am: html/index.sgml doesn't exist anymore
+
+Fri Oct 28 16:53:51 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c xmlmodule.c: more portability patches from Albert Chin for
+	  HP-UX and AIX
+
+Fri Oct 28 10:36:10 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmodule.c configure.in: applied 2 patches from Albert Chin for
+	  module portability
+
+Fri Oct 28 10:24:39 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: fixing a portability problem on some old Unices with
+	  patch from Albert Chin
+
+2005-10-27  Aleksey Sanin <aleksey@aleksey.com>
+
+	* c14n.c  result/c14n/exc-without-comments/test-2
+	  test/c14n/exc-without-comments/test-2.xml
+	  test/c14n/exc-without-comments/test-2.xpath: fixing
+	  bug in exc-c14n namespace visibility + test case (bug #319367)
+
+Thu Oct 27 16:10:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: remove warnings to stdout patch from Nic Ferrier
+
+Thu Oct 27 13:54:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c xmlregexp.c include/libxml/valid.h
+	  include/libxml/xmlregexp.h: avoid function parameters names 'list'
+	  as this seems to give troubles with VC6 and stl as reported by
+	  Samuel Diaz Garcia.
+
+Wed Oct 26 10:59:21 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fix a problem in some error case on Solaris
+	  when passed a NULL filename, pointed by Albert Chin.
+
+Tue Oct 25 14:34:58 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: script HTML parser error fix, corrects bug #319715
+	* result/HTML/53867* test/HTML/53867.html: added test from Michael Day
+	  to the regression suite 
+
+Tue Oct 25 14:21:11 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: typo fix from Michael Day
+
+Mon Oct 24 20:16:23 EDT 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* tree.c: fix issue adding non-namespaced attributes in xmlAddChild(), 
+	  xmlAddNextSibling() and xmlAddPrevSibling() (bug #319108) - part 1.
+
+Sat Oct 22 10:00:41 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed second spot where CRLF split between chunks
+	  could cause trouble (bug #319279)
+	* gentest.py, testapi.c: fixed two problems involved with
+	  --with-minimum compilation (compilation errors with schematron
+	  and formal expressions tests)
+
+Fri Oct 21 10:50:14 EDT 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlsave.c: prevent output of fragment tags when serializing XHTML.
+
+Wed Oct 19 16:53:47 BST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: commiting a some fixes and debug done yesterday in
+	  the London airport.
+
+Thu Oct 20 12:54:23 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed creation of a temporary parser context
+	  during validation when processing xsi:type; this previously
+	  added a string to the dict of the schema - to assure thread
+	  safety, we don't want to modify a given schema during
+	  validation.
+
+Thu Oct 20 17:05:29 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xmlwriter.c: fixed problem in xmlTextWriterVSprintf caused by
+	  misuse of vsnprintf
+	* configure.in, config.h.in: added a configuration check for
+	  va_copy and added a define for VA_COPY for xmlwriter.c fix
+	* parser.c: fixed problem with CRLF split between chunks (bug
+	  #319279) (fix provided by Brion Vibber)
+
+Wed Oct 19 18:49:52 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a potential memory leak in
+	  xmlSchemaCheckCSelectorXPath() when an internal error occurs.
+	  Fixed setting of ctxt->err to the given error code in
+	  the parsing error functions.
+	* pattern.c: Added internal xmlCompileIDCXPathPath() as a
+	  starting point for IDC XPath compilation; this and some other
+	  tiny changes fixes issues regarding whitespace in the
+	  expressions and IDC selector/field relevant restrictions of
+	  the subset of XPath. Fixed a missing blocking of attributes
+	  in xmlStreamPushInternal().
+
+Mon Oct 17 15:06:05 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: removed the error message
+	* relaxng.c xmlschemas.c: removed 2 instability warnings from function
+	  documentation
+	* include/libxml/schemasInternals.h: changed warning about API stability
+	* xmlregexp.c: trying to improve runtime execution of non-deterministic
+	  regexps and automata. Not fully finished but should be way better.
+
+Mon Oct 17 16:12:02 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a memory leak in
+	  xmlSchemaContentModelDump(). Added output of local types
+	  in xmlSchemaElementDump(). Tiny cosmetical changes to the
+	  dump output.
+
+Mon Oct 17 14:29:08 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c pattern.c: Silenced intel compiler warnings (reported
+	  by Kjartan Maraas, bug #318517).
+	* xmlschemas.c: The above changes in pattern.c revealed an
+	  inconsistency wrt IDCs: we now _only_ pop XPath states, if
+	  we really pushed them beforehand; this was previously not
+	  checked for the case when we discover an element node to be
+	  invalid wrt the content model.
+	  Fixed segfault in xmlSchemaGetEffectiveValueConstraint().
+
+Fri Oct 14 16:40:18 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/*.err: Adapted regression test results.
+
+Fri Oct 14 16:21:22 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+	
+	* xmlschemas.c: Fixed some identity-constraint issues:
+	  Restructured IDC node-tables
+	  Allowed IDCs to resolve also to nodes of complex type with
+	  simple content.
+	  Added check for keyrefs with references to keyrefs.
+	  IDC target-nodes were interferring with IDC node-tables,
+	  since they used one list of entries only. I separated this
+	  one big list into 3 lists: 1 for IDC node-table entries,
+	  1 for _duplicates_ of IDC node-table entries and 1 for
+	  IDC target-nodes. More code, but cleaner and it works at last.
+	  Keyrefs will fail to resolve to duplicate key/unique entries.
+	  I thought this was already working this way, but it didn't.
+	  The wording of the definition for [node table] in the spec
+	  can lead to a scenario, where keyrefs resolve perfectly, even
+	  if the relevant key-sequences of the referenced key/unique have
+	  duplicates in the subtree. Currently only Saxon 8.5.1 is
+	  dissallowing resolution to duplicate entries correctly - we
+	  will follow Saxon here.
+	  Removed some intel compiler warnings (reported by
+	  Kjartan Maraas, bug #318517).
+	* pattern.c: Fixed an IDC-XPath problem when resolving to
+	  attributes.	  
+
+Mon Oct 14 01:15:14 CEST 2005 Rob Richards <rrichards@ctindustries.net>
+	* nanohttp.c include/wsockcompat.h: applied patch from Kolja Nowak 
+	  to use getaddrinfo() if supported in Windows build (bug# 317431).
+
+Mon Oct 10 15:33:48 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/*: Adapted regression test results.
+
+Mon Oct 10 15:12:43 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h
+	  include/libxml/xmlerror.h: Initial implementation for
+	  redefinitions; this still misses checks for restrictions
+	  of the content model of complex types.
+	  Fixed default/fixed values for attributes (looks like they
+	  did not work in the last  releases).
+	  Completed constraints for attribute uses.
+	  Seperated attribute derivation from attribute constraints.
+	  Completed constraints for attribute group definitions.
+	  Disallowing <import>s of schemas in no target namespace if the
+	  importing schema is a chameleon schema. This contradicts
+	  the way Saxon, Xerces-J, XSV and IBM's SQC works, but the
+	  W3C XML Schema WG, thinks it is correct to dissalow such
+	  imports.
+	  Added cos-all-limited constraints.
+	  Restructured reference resolution to model groups and element
+	  declarations.
+	  Misc cleanup.
+
+Fri Oct  7 04:34:12 CEST 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* schematron.c xmlregexp.c: remove warnings under Windows.
+
+Wed Sep 28 23:42:14 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Massimo Morara fixing bug #317447
+	  about risk of invalid write in xmlStringLenDecodeEntities
+
+Tue Sep 27 11:20:57 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: Adrian Mouat pointed out redundancies in xmlReportError()
+
+Mon Sep 26 19:18:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: seems a test to avoid duplicate transition is 
+	  really needed at all times. Luka Por gave an example hitting
+	  this. Changed back the internal API.
+
+Thu Sep 22 13:14:07 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixing leak in xmlTextReaderReadString() #316924
+
+Thu Sep 15 16:12:44 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: more fixes to the behaviour of xmlBuildRelativeURI
+
+Thu Sep 15 15:08:21 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: detect combinatory explosion and return with
+	  a runtime error in those case, c.f. #316338 though maybe we
+	  should not see such an explosion with that specific regexp,
+	  more checking needs to be done.
+
+Wed Sep 14 19:52:18 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* include/libxml/schemasInternals.h: Added some comments for the
+	  struct fields.
+
+Wed Sep 14 13:24:27 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: fixed problem when xmlBuildRelativeURI was given a
+	  blank path (bug 316224)
+
+Mon Sep 12 23:41:40 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in doc//*: release of 2.6.22 updated doc and
+	  rebuild.
+	* xmlsave.c include/libxml/xmlsave.h: added XML_SAVE_NO_XHTML
+	  xmlSaveOption
+	* xmlschemas.c: minor cleanups
+
+Mon Sep 12 21:42:47 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+	
+	* test/schemas/import1_0.xsd: And adapting another one.
+
+Mon Sep 12 21:29:35 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/derivation-ok-extension_0_0: Adapted result.
+
+Mon Sep 12 21:20:41 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/allsg_0_3.err result/schemas/allsg_0_4.err
+	  result/schemas/changelog093_1_0.err
+	  result/schemas/derivation-ok-extension_0_0.err
+	  result/schemas/import1_0_0.err
+	  result/schemas/derivation-ok-restriction-2-1-1_0_0.err:
+	  Adapted regression results.
+
+Mon Sep 12 21:00:53 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h
+	  include/libxml/xmlerror.h: Completion of the schema graph.
+	  Centralisation, more robustness of the schema document
+	  aquisition story. Centralised and restructured component fixup.
+	  Fixed attribute derivation when 'prohibiting' attribute uses.
+	  Added warnings: when schema documents cannot be localized
+	  during imports; when we get duplicate and pointless attribute
+	  prohibitions. Changed error reports for IDCs to report
+	  the relevant IDC designation as well (requested by GUY Fabrice).
+	  Misc code-cleanup.
+
+Mon Sep 12 16:02:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: applied second patch from David Madore to be less intrusive
+	  when handling scripts and style elements in XHTML1 should fix #316041
+	* test/xhtml1 result//xhtml1\*: updated the test accordingly
+
+Mon Sep 12 15:09:09 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in doc/devhelp/*: finished the integration with
+	  devhelp, completing the index and inserted into the gtk-doc
+	  database at "make install" stage
+
+Mon Sep 12 14:14:12 CEST 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* include/libxml/xmlsave.h xmlsave.c: add XML_SAVE_NO_EMPTY save option
+	  and use option from xmlSaveCtxtPtr rather than global during output.
+	* xmlsave.c: fix some output formatting for meta element under XHTML.
+
+Mon Sep 12 11:12:03 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h parser.c xmllint.c: damn XML_FEATURE_UNICODE
+	  clashes with Expat headers rename to XML_WITH_ to fix bug #316053. 
+	* doc/Makefile.am: build devhelp before the examples.
+	* doc/*: regenerated the API
+
+Mon Sep 12 02:03:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: fix bug #316034, where xmlElemDump() can crash if 
+	  given a document pointer instead of an element
+
+Mon Sep 12 01:26:16 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/devhelp/devhelp.xsl: improvements on the html generation,
+	  should be complete with navigation, what is left done is glueing
+
+Mon Sep 12 00:03:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml
+	  doc/devhelp/*: started work needed to generate devhelp content,
+	  not too hard based on the existing format and extractor.
+
+Fri Sep  9 12:56:19 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixes bug #315617 when using push CDATA in some cases.
+
+Thu Sep  8 23:39:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: patch from Stéphane Bidoul to compile without schematron
+
+Wed Sep  7 00:16:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: patch from Oleg Paraschenko to fix xmlDebugDumpNode()
+	  when handled a namespace node.
+
+Sun Sep  4 23:36:45 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS elfgcchack.h testapi.c doc/*: updated the docs and rebuild
+	  releasing 2.6.21
+	* include/libxml/threads.h threads.c: removed xmlIsThreadsEnabled()
+	* threads.c include/libxml/threads.h xmllint.c: added the more
+	  generic xmlHasFeature() as suggested by Bjorn Reese, xmllint uses it.
+
+Sun Sep  4 22:45:49 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* configure.in: prepare for release
+	* xpath.c: work for #303289, fix a formatting bug for MIN_INT
+
+Sun Sep  4 15:48:57 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: real fix for #314881 and #314759 is was a bit more complex
+	  than initially expected as ctxt->error == NULL had behaviour side
+	  effects at the compilation level itself.
+
+Sun Sep  4 14:01:00 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xpath.c include/libxml/pattern.h: fixing yet another
+	  pattern induced XPath bug #314282
+	* relaxng.c: reverted back last change it was seriously broken
+
+Sat Sep  3 16:51:55 CEST 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlsave.c: check for NULL to prevent crash with meta elements
+
+Sat Sep  3 16:26:55 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: structured error reporting problem with Relax-NG
+	  should fix #314881 and #314759
+
+Sat Sep  3 15:42:29 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c: fixes a portability problem raised by C370 on Z/OS
+
+Sat Sep  3 15:26:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c tree.c valid.c: fixing a number of issues raised by xml:id
+	  but more generally related to attributes and ID handling, fixes
+	  #314358 among other things
+
+Fri Sep  2 14:26:43 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c parserInternals.c: avoid passing a char[] as snprintf
+	  first argument.
+	* threads.c include/libxml/threads.h: implemented xmlIsThreadsEnabled()
+	  based on Andrew W. Nosenko idea.
+	* doc/* elfgcchack.h: regenerated the API
+
+Thu Sep  1 14:44:42 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: the use of AM_PATH_PYTHON is not portable enough
+	  reverting back to AM_PATH_PROG
+
+Thu Sep  1 11:42:39 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: Applied the last patch from Gary Coady for #304637
+	  changing the behaviour when text nodes are found in body
+	* result/HTML/*: this changes the output of some tests
+
+Thu Sep  1 11:22:37 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/downloads.html doc/xml.html: adding reference to Bull AIX rpms
+	  c.f. #160598
+
+Wed Aug 31 11:39:02 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xml2-config.in: removed the obsolete --libtool-libs option, c.f.
+	  bug #314853
+
+Fri Aug 26 17:33:26 CEST 2005 Rob Richards <rrichards@ctindustries.net>
+
+	* xmlsave.c: move handling of meta element for http-equiv in XHTML docs 
+	  to serialization and no longer modify internal tree.
+
+Fri Aug 26 00:51:58 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: the profiling usually don't work, disabled
+	* doc/*: rebuilt
+
+Thu Aug 25 23:47:55 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: trying to fix the first part of #310033 by
+	  detecting gcc <= 3.2
+
+Thu Aug 25 22:13:37 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: fixed bug #310033, the URI extraction code given a
+	  node is a bit twisted and broke in the last months.
+
+Thu Aug 25 16:18:15 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c result/XPath/xptr/strrange2: uninitialized field and
+	  fix on test.
+
+Thu Aug 25 16:03:05 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: change verbosity depending on API
+	* result/XPath/tests/* result/XPath/xptr/* result/xmlid/*: get back
+	  to previous outputs
+
+Thu Aug 25 15:14:56 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c parser.c SAX2.c debugXML.c tree.c valid.c xmlreader.c
+	  xmllint.c include/libxml/HTMLparser.h include/libxml/parser.h:
+	  added a parser XML_PARSE_COMPACT option to allocate small 
+	  text nodes (less than 8 bytes on 32bits, less than 16bytes on 64bits)
+	  directly within the node, various changes to cope with this.
+	* result/XPath/tests/* result/XPath/xptr/* result/xmlid/*: this 
+	  slightly change the output
+
+Thu Aug 25 12:16:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: patch from Andrew W. Nosenko, use se $GCC = 'yes'
+	  instead of $CC = 'gcc' because GCC may have a different name
+
+Thu Aug 25 00:18:20 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: changes the way the python binary is found, should
+	  also fix bug #308004
+
+Wed Aug 24 16:44:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: found another bug while looking at #309616 on missing
+	  entities.
+	* result/ent2.sax* result/ent7.sax* result/xml2.sax*: this changed the
+	  SAX stream in missing conditions for a few tests
+
+Wed Aug 24 16:19:00 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: applied the patch suggested #309565 which can avoid
+	  looping in error conditions.
+
+Wed Aug 24 16:04:17 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c tree.c: line numbers are now carried by most nodes, fixing
+	  xmlGetLineNo() c.f. bug #309205
+
+Wed Aug 24 14:43:34 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c error.c include/libxml/xmlerror.h: finally converted
+	  the encoding module to the common error reporting mechanism
+	* doc/* doc/html/libxml-xmlerror.html: rebuilt
+
+Wed Aug 24 11:35:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: removed a potentially uninitialized variable error
+	* python/generator.py: fixed a deprecation warning
+	* python/tests/tstLastError.py: silent the damn test when Okay !
+
+Wed Aug 24 00:11:16 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c globals.c runtest.c testC14N.c testapi.c tree.c
+	  include/libxml/SAX2.h include/libxml/xmlregexp.h: fixed compilation
+	  when configured --without-sax1 and other cleanups fixes bug #172683
+	* doc/* elfgcchack.h: regenerated
+
+Tue Aug 23 20:05:05 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #170489 reported by Jirka Kosek
+	* test/valid/objednavka.xml test/valid/dtds/objednavka.dtd
+	  result/valid/objednavka*: added the test to the regression suite.
+
+Tue Aug 23 18:04:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c include/libxml/HTMLparser.h: added a recovery mode
+	  for the HTML parser based on the suggestions of bug #169834 by
+	  Paul Loberg
+
+Tue Aug 23 15:38:46 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* elfgcchack.h testapi.c doc/*: regenerated
+	* schematron.c: fixed a compilation problem
+	* xmlregexp.c include/libxml/xmlregexp.h: some cleanups and one bug fix
+	* result/expr/base: slightly changes the number of Cons.
+
+Mon Aug 22 23:19:50 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* elfgcchack.h testapi.c doc/*: rescanned code and rebuilt
+	* xmlregexp.c: small cleanup
+	* include/libxml/schematron.h include/libxml/xmlexports.h
+	  include/libxml/xmlversion.h.in: cleanup problems from code scanner
+
+Mon Aug 22 18:00:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: applied patch from Kuba Nowakowski fixing bug
+	  #313982
+	* result/schemas/bug313982* test/schemas/bug313982*: also added
+	  the test case to the regression suite.
+
+Mon Aug 22 17:50:20 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testRegexp.c: printed the wrong string
+
+Mon Aug 22 16:42:07 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testRegexp.c xmlregexp.c include/libxml/xmlregexp.h: exported
+	  xmlExpExpDerive(), added it to the testRegexp command line 
+	  tool when providing multiple expressions.
+
+Mon Aug 22 14:57:13 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am result/expr/base test/expr/base: added the first
+	  regression test suite set for the new expression support
+
+Mon Aug 22 13:49:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed an uninitialized variable
+	* xmlregexp.c include/libxml/xmlregexp.h: extended the API to
+	  add the parser, serializer and some debugging
+	* include/libxml/xmlversion.h.in: made the new support compiled
+	  by default if Schemas is included
+	* testRegexp.c: cleanup and integration of the first part of the
+	  new code with a special switch
+	* xmllint.c: show up Expr in --version if compiled in
+	* include/libxml/tree.h: moved the xmlBuffer definition up
+
+Mon Aug 22 12:11:10 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Some preparation for the creation of a graph
+	  of imported/included/redefined schemas; this is needed for
+	  at least the redefinitions.
+	  Centralized the creation of the parser context in one function.
+
+Mon Aug 22 02:19:33 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c include/libxml/xmlregexp.h: pushing the formal expression
+	  handling code to have it in CVs from now. Not plugged, and misses 
+	  APIs it's not compiled in yet.
+
+Sat Aug 20 23:13:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied another patch from Rob Richards to fix
+	  xmlTextReaderGetAttributeNs and xmlTextReaderMoveToAttributeNs
+
+Wed Aug 17 09:06:33 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied patch from Rob Richards to fix 
+	  xmlTextReaderGetAttribute behaviour with namespace declarations
+
+Fri Aug 12 14:12:56 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/xmlerror.h:
+	  Changed output for keyref-match errors; the target-node will
+	  be now reported rather than the scope-node of the keyref
+	  definition - allowing easier chasing of instance errors.
+	  This was reported by Guy Fabrice to the mailing list.
+	  Some initial parsing code for schema redefinitions.
+	* result/schemas/bug303566_1_1.err
+	  result/schemas/bug312957_1_0.err: Adapted test results due
+	  to the keyref changes.
+
+Fri Aug 12 12:17:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: applied patch from Derek Poon fixing bug #310692
+
+Wed Aug 10 23:39:02 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fix for bug #312945 as pointed by Dean Hill, the
+	  context type was not always properly initialized. 
+
+Wed Aug 10 18:21:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed bug #307377 about validation of choices in
+	  list values.
+	* test/relaxng/307377* result/relaxng/307377* Makefile.am runtest.c:
+	  added examples to the regression tests, problem is that streaming
+	  version gives slightly more informations.
+
+Wed Aug 10 15:25:53 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixed bug #302302, nasty but the fix is rather simple.
+
+Wed Aug 10 11:59:46 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/any6_1_0*: Added missing test results.
+
+Tue Aug  9 23:37:22 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixed a determinism detection problem exposed by
+	  ##other tests commited by Kasimier, also added a small speedup
+	  of determinism detection.
+	* test/results/any6_2_0* any8_1_0* any7_1_2* any7_2_2*: added 
+	  the results to the regression tests now
+
+Tue Aug  9 15:54:09 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/any7_2.xml test/schemas/any6_2.xsd
+	  test/schemas/any8_1.xsd test/schemas/any8_0.xml:
+	  Added some more tests for element wildcards.
+
+Tue Aug  9 14:22:47 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed #312957 reported by Carol Hunter:
+	  streaming XPath states were not popped in every case,
+	  thus failed to resolve correctly for subsequent input.
+	* test/schemas/bug312957* result/schemas/bug312957*:
+	  Added the test submitted by Carol Hunter.
+
+Tue Aug  9 13:07:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c: trying to nail down the remaining
+	  ##other issues
+	* result/schemas/any7* test/schemas/any7: completed the tests
+	  and added the results
+	* result/schemas/any3_0_0.err result/schemas/any5_0_0.err
+	  result/schemas/any5_1_0.err: this slightly chnages the output
+	  from 3 existing tests
+
+Mon Aug  8 22:33:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c xmlschemastypes.c: applied patch from 
+	  Marcus Boerger to remove warnings on Windows.
+
+Mon Aug  8 16:43:04 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c include/libxml/xmlsave.h: fixed #145092 by adding 
+	  an xmlSaveOption to omit XML declaration
+
+Mon Aug  8 15:44:54 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixed bug #310333 with a patch close to the provided
+	  patch for HTML UTF-8 serialization
+	* result/HTML/script2.html: this changed the output of that test
+
+Mon Aug  8 15:01:51 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixed bug #310264, basically it's about reentrancy
+	  of count based transition, when going though the counter must
+	  be reset to 0
+	* test/schemas/bug310264* result/schemas/bug310264*: added the
+	  regression test.
+
+Mon Aug  8 14:40:52 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a memory leak: xmlSchemaFreeAnnot() was
+	  only freeing the first annotation in the list.
+
+Mon Aug  8 09:44:34 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied patch from Rob Richards fixing
+	  xmlTextReaderGetAttribute
+
+Mon Aug  8 01:41:53 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed an uninitialized memory access spotted by
+	  valgrind
+
+Sun Aug  7 12:39:35 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* test/relaxng/docbook_0.xml: get rid of the dependancy on a locally
+	  installed DTD
+	* uri.c include/libxml/uri.h xmlIO.c nanoftp.c nanohttp.c: try to
+	  cleanup the Path/URI conversion mess, needed fixing in various 
+	  layers and a new API to the uri module which also fixes #306861
+	* runtest.c: integrated a regression test specific to check the
+	  URI conversions done before calling the I/O handlers.
+
+Sat Aug  6 11:06:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/XSLT.html doc/xml.html: small doc fix for #312647
+
+Tue Aug  2 13:26:42 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* win32/configure.js: applied patch from Rob Richards to allow
+	  disabling modules in win32, fixes #304071
+
+Mon Aug  1 07:18:53 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: applied fix from Jakub Piotr Clapa for
+	  xmlAttr.parent(), closing #312181
+
+Sun Jul 31 18:48:55 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c: report improvement
+	* test/schematron/zvon* result/schematron/zvon*: more tests
+
+Sun Jul 31 16:02:59 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.msvc win32/configure.js: applied patch from Rob
+	  Richards to add schematron to the build on Windows
+	* test/schematron/zvon3* result/schematron/zvon3*: second test
+	* test/schematron/zvon10* result/schematron/zvon10*: this is the
+	  real second test 10 and 2 are swapped.
+
+Sun Jul 31 15:42:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c: more bug fixes, improve the error reporting.
+	* test/schematron/zvon2* result/schematron/zvon2*: second test
+
+Sun Jul 31 14:15:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c xmllint.c: fixing the loop bug, fixing schematron
+	  text error rendering
+	* Makefile.am result/schematron/* test/schematron/zvon1*.sct:
+	  started integrating within "make tests"
+
+Sat Jul 30 17:26:58 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* test/schematron/*: a few first tests from Zvon unfortunately
+	  with the old syntax
+
+Sat Jul 30 17:08:07 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c xmllint.c include/libxml/schematron.h: commiting
+	  work done on the plane last week-end
+
+Sat Jul 30 15:16:29 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: allows an extra argument to subset the tests
+	* xmlregexp.c: big speedup for validation, basically avoided
+	  transition creation explosion when removing epsilon transition
+	  
+Sat Jul 30 00:00:46 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am globals.c parserInternals.c xmlreader.c xmlunicode.c
+	  xmlwriter.c: more cleanups based on sparse reports, added 
+	  "make sparse"
+
+Fri Jul 29 12:11:25 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: don't output any message on failed resolver lookups,
+	  better done by the python user provided resolver layer.
+
+Fri Jul 29 01:48:02 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c SAX2.c encoding.c globals.c parser.c relaxng.c
+	  runsuite.c runtest.c schematron.c testHTML.c testReader.c
+	  testRegexp.c testSAX.c testThreads.c valid.c xinclude.c xmlIO.c
+	  xmllint.c xmlmodule.c xmlschemas.c xpath.c xpointer.c: a lot of 
+	  small cleanups based on Linus' sparse check output.
+
+Thu Jul 28 21:28:33 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/Makefile.am: added schematron.h, oops ...
+
+Thu Jul 28 02:38:21 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Added creation of the content type of
+	  xs:anyType. This is needed when trying to extend xs:anyType
+	  (although it makes no sense to extend it; IMHO the schema
+	  people should have ruled this out). This was reported
+	  by Yong Chen to the mailing list.
+	* xmlschemas.c: Fixed handling of xs:anyType in
+	  xmlSchemaCheckCOSCTExtends() (reported by Young Chen). Tiny
+	  adjustment to an error report output.
+	* test/schemas/extension2* result/schemas/extension2*:
+	  Added a test case provided by Young Chen.
+
+Mon Jul 25 11:41:18 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: enhanced xmlBuildRelativeURI to allow the URI and the
+	  base to be in "relative" form
+
+Sun Jul 24 10:25:41 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* schematron.c xmllint.c: started adding schematron to the xmllint
+	  tool, the report infrastructure is gonna be fun.
+
+Sat Jul 23 23:23:51 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/any6* test/schemas/any7*: Added regression tests
+	  (they fail currently), but did not added results yet.
+
+Sat Jul 23 23:07:05 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed the workaround code in
+	  xmlSchemaValidateElemWildcard() for the <any> wildcard
+	  with namespace == ##other. Support for such wildcards was
+	  implemented by Daniel at the automaton level recently, and
+	  the workaround code iterfered with it.
+
+Sat Jul 23 10:55:50 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c include/libxml/pattern.h: changed xmlPatterncompile
+	  signature to pass an int and not an enum since it can generate
+	  ABI compat troubles.
+	* include/libxml/schematron.h schematron.c: adding the new 
+	  schematron code, work in progress lots to be left and needing
+	  testing
+	* include/libxml/xmlversion.h.in include/libxml/xmlwin32version.h.in
+	  Makefile.am configure.in: integration of schematron into the
+	  build
+	* xpath.c include/libxml/xpath.h: adding flags to control compilation
+	  options right now just XML_XPATH_CHECKNS.
+
+Sat Jul 23 16:39:35 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed an "internal error" message from
+	  xmlSchemaBuildAContentModel() when an empty model group
+	  definition is hit.
+
+Sat Jul 23 00:34:07 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c: Changed xmlCompileStepPattern() and
+	  xmlCompileAttributeTest() to handle the "xml" prefix without
+	  caring if the XML namespace was supplied by the user.
+
+Fri Jul 22 00:08:43 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed xmlSchemaPSimpleTypeErr(), which did not
+	  output the given string arguments correctly.
+
+Thu Jul 21 09:21:00 EDT 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c globals.c parser.c runtest.c testHTML.c testSAX.c
+	  threads.c valid.c xmllint.c xmlreader.c xmlschemas.c xmlstring.c
+	  xmlwriter.c include/libxml/parser.h include/libxml/relaxng.h
+	  include/libxml/valid.h include/libxml/xmlIO.h
+	  include/libxml/xmlerror.h include/libxml/xmlexports.h
+	  include/libxml/xmlschemas.h: applied a patch from Marcus Boerger
+	  to fix problems with calling conventions on Windows this should
+	  fix #309757
+
+Wed Jul 20 14:45:39 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: an optimization of the char data inner loop,
+	  can gain up to 10% in pure SAX2 parsing speed
+	* xmlschemas.c: applied patch from Kupriyanov Anatolij fixing
+	  a bug in XML Schemas facet comparison #310893
+
+Tue Jul 19 17:27:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c: fixed the error reporting for
+	  not transitions
+	* result/schemas/any5_0_0* result/schemas/any5_0_2*
+	  result/schemas/any5_1_0*: fixed output
+
+Tue Jul 19 15:34:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c include/libxml/xmlautomata.h: fixing
+	  bug #172215 about foreign namespaces by adding support for
+	  negated string transitions. Error messages still need to be
+	  improved.
+	* test/schemas/any5* result/schemas/any5*: adding regression
+	  tests for this.
+
+Tue Jul 19 12:33:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch from Alexander Pohoyda fixing xmlGetNodePath
+	  on namespaced attributes #310417.
+
+Mon Jul 18 23:01:15 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.html doc/xmllint.xml: --nonet was
+	  ducplicated
+
+Mon Jul 18 20:49:28 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed xsd:all when used in conjunction with
+	  substitution groups
+	* test/schemas/allsg_* result/schemas/allsg_*: adding specific
+	  regression tests, strangely missing from NIST/Sun/Microsoft
+	  testsuites
+
+Sun Jul 17 07:11:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed bug #307508, a bad automata was built but
+	  this showed as an indeterminist result
+
+Thu Jul 14 17:53:02 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: found the last bug raised by NIST tests in
+	  comparing base64 strings, result from runsuite:
+	  ## NIST test suite for Schemas version NIST2004-01-14
+	  Ran 23170 tests (3953 schemata), no errors
+
+Thu Jul 14 14:57:36 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testRegexp.c: fixed where xmlMemoryDump() should be called.
+	* xmlregexp.c: fixed handling of {0}, \n, \r and \t, two bugs
+	  affecting NIST regression tests
+
+Thu Jul 14 11:30:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: applied a patch from Gerrit P. Haase to add
+	  module support on cygwin
+
+Thu Jul 14 10:56:42 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed a potential buffer overrun error introduced
+	  on last commit to htmlParseScript() c.f. #310229
+
+Thu Jul 14 23:48:17 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: Changed the behaviour of xmlXPathEqualNodeSetFloat to
+	  return TRUE if a nodeset with a numeric value of NaN is compared
+	  for inequality with any numeric value (bug 309914).
+	  
+Thu Jul 14 01:03:03 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c relaxng.c xmlreader.c xmlschemas.c include/libxml/relaxng.h
+	  include/libxml/xmlschemas.h: applied patch from Marcus Boerger
+	  to route relaxng and schemas error messages when using the reader
+	  through the structured interface if activated.
+	* elfgcchack.h doc/* testapi.c: rebuilt since this add  new APIs
+	  to test.
+
+Wed Jul 13 18:35:47 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied UTF-8 script parsing bug #310229 fix from
+	  Jiri Netolicky 
+	* result/HTML/script2.html* test/HTML/script2.html: added the test
+	  case from the regression suite
+
+Tue Jul 12 17:08:11 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c: fixed bug #310105 with http_proxy environments with
+	  patch provided by Peter Breitenlohner
+
+Mon Jul 11 00:28:10 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am NEWS configure.in doc/*: preparing release 2.6.20 
+	* xmllint.c: removed a compilation problem
+
+Sun Jul 10 23:33:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am README README.tests Makefile.tests Makefile.am:
+	  preparing to make testsuite releases along with code source releases
+	* gentest.py testapi.c: fixed a couple of problem introduced by
+	  the new Schemas support for Readers
+	* xpath.c: fixed the XPath attribute:: bug #309580, #309864 in a crude
+	  but simple way.
+	* xmlschemas.c include/libxml/tree.h: fixed a couple of problems
+	  raised by the doc builder.
+	* doc/*: made rebuild
+
+Sun Jul 10 21:51:16 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed a bug introduced on last commit
+
+Sun Jul 10 21:00:54 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.html doc/xmllint.xml: fixed a typo
+	  pointed by Jeroen Ruigrok
+	* include/libxml/xmlreader.h include/libxml/xmlschemas.h: increased
+	  the APIs for xmlReader schemas validation support
+	* xmllint.c xmlreader.c xmlschemas.c: xmlReader schemas validation
+	  implementation and testing as xmllint --stream --schema ...
+
+Sun Jul 10 16:11:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlwin32version.h.in: try to avoid conflicts.
+
+Sat Jul  9 19:29:10 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix for #309761 from Dylan Shell  
+	* xmlschemas.c include/libxml/xmlschemas.h: added xmlSchemaSAXPlug
+	  and xmlSchemaSAXUnplug generic APIs for SAX Schemas validation.
+	* xmllint.c: couple of fixes plus added descriptions for --sax and
+	  --sax1
+
+Fri Jul  8 23:35:00 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added c-props-correct constraint to check
+	  for equal cardinality of keyref/key.
+	* include/libxml/xmlerror.h: Added an error code.
+
+Fri Jul  8 21:56:04 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c: Fixed evaluation of attributes. Actually only
+	  attribute at the first level were evaluated (e.g. "@attr");
+	  expression like "foo/@attr" always failed.
+
+Fri Jul  8 20:04:29 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: tiny fix in xmlSchemaValidateStream() if a
+	  user-provided SAX handler is given.
+
+Fri Jul  8 19:25:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix some potential leaks in error cases.
+	* xmllint.c: added --sax, to allow testing of --schemas --sax and
+	  various other combinations.
+	* xmlschemas.c: fix a couple of tiny problems in
+	  xmlSchemaValidateStream()
+
+Fri Jul  8 18:34:22 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+	
+	* xmlschemas.c: Changed xmlSchemaValidateFile() to use
+	  xmlSchemaValidateStream() internally.
+
+Fri Jul  8 17:02:14 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* test/relaxng/docbook_0.xml: added the missing entity to the
+	  document internal subset to avoid errors if the DocBook catalogs
+	  are not there
+	* xmlschemas.c: first cut at implementing xmlSchemaValidateStream()
+	  untested yet
+
+Wed Jul  6 15:45:48 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed problem with free on dupl attribute in
+	  dtd (bug309637).
+	* test/errors/attr3.xml, result/errors/attr3.*: added
+	  regression test for this
+
+Wed Jul  6 13:11:35 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* win32/Makefile.msvc: try again to fix file format for Windows
+
+Wed Jul  6 12:20:13 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* win32/Makefile.msvc: removed spurious ^M
+	* runtest.c: added check for option O_BINARY
+	* test/schemas/bug309338*, result/schemas/bug309338*: changed
+	  sticky tag to 'binary'
+
+Wed Jul  6 10:38:02 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* debugXML.c: excluded content string check for XML_ELEMENT_DECL
+	  in xmlCtxtGenericNodeCheck
+	* runtest.c: changed "open" calls to include O_BINARY for Windows
+
+Wed Jul  6 17:14:03 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing bug #166777 (and #169838), it was an heuristic
+	  in areBlanks which failed.
+	* result/winblanks.xml* result/noent/winblanks.xml test/winblanks.xml:
+	  added the input file to the regression tests
+
+Wed Jul  6 13:40:22 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Fixed bug #309338, reported by Kupriyanov
+	  Anotolij.
+	* test/schemas/bug309338* result/schemas/bug309338*:
+	  Added a regression test for the above bug.
+
+Tue Jul  5 16:03:05 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: first steps toward a testsuite dist
+	* SAX2.c include/libxml/xmlerror.h: fixed bug #307870
+
+Tue Jul  5 12:38:36 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* runsuite.c runtest.c: Tiny portability adjustment for win.
+	* win32/Makefile.*: Added runtest.exe and runsuite.exe to
+	  be created.
+
+Mon Jul  4 17:44:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c: first stb at unimplemnted detection
+	* runtest.c: fixing Windows code
+
+Mon Jul  4 17:19:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c: fix on schemas error
+	* runtest.c: portability glob() on Windows
+
+Mon Jul  4 16:23:54 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c runtest.c: cleanups, logfile and portability
+	* xmllint.c: fixed a memory leak
+
+Mon Jul  4 13:11:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a bug failing to detect UTF-8 violations in
+	  CData in push mode.
+	* result/errors/cdata.xml* test/errors/cdata.xml: added the test
+	  to the regressions
+
+Mon Jul  4 11:26:57 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: added enhancement for #309057 in xmllint shell
+
+Mon Jul  4 00:58:44 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied patch from James Bursa fixing an html parsing
+	  bug in push mode
+	* result/HTML/repeat.html* test/HTML/repeat.html: added the test to the
+	  regression suite
+
+Sun Jul  3 23:42:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c tree.c: fixing a leak detected by testapi in 
+	  xmlDOMWrapAdoptNode, and fixing another side effect in testapi
+	  seems to pass tests fine now.
+	* include/libxml/parser.h parser.c: xmlStopParser() is no more limited
+	  to push mode
+	* error.c: remove a warning
+	* runtest.c xmllint.c: avoid compilation errors if only some parts
+	  of the library are compiled in.
+
+Mon Jul  4 00:39:35 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: fix a problem with previous patch to
+	  testapi.c
+
+Sun Jul  3 22:59:28 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c runtest.c tree.c: fixing compilations when
+	  disabling parts of the library at configure time.
+
+Sun Jul  3 18:17:58 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fix bug raised by zamez on IRC
+	* testapi.c: regenerated, seems to pop-up leaks in new tree functions
+	* tree.c: added comments missing.
+	* doc/*: regenerated
+
+Sun Jul  3 18:06:55 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c runsuite.c runtest.c: fixing #307823 and a couple of
+	  assorted bugs
+	* python/generator.py python/libxml2-python-api.xml: fixed 
+	  conditionals in generator too
+	* doc/apibuild.py doc/libxml2-api.xml doc/* elfgcchack.h: some
+	  cleanups too and rebuilt
+
+Sun Jul  3 16:42:00 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fixed bug #307503 misplaced #ifdef
+
+Sun Jul  3 16:34:47 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c: expanded test
+	* xmlregexp.c: found and fixed the leak exposed by Microsoft regtests
+
+Sat Jul  2 23:38:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c: a bit of progresses on xstc
+
+Sat Jul  2 09:30:13 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runsuite.c: completed the simple checks for Relax-NG suites
+	  back to the same 11 errors as in the Python runs.
+
+Thu Jun 30 15:01:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: complete, checking on other platforms is needed
+	* README: updated 
+	* debugXML.c: fix a bug raised by bill on IRC
+	* relaxng.c: fix a leak in weird circumstances
+	* runsuite.c Makefile.am: standalone test tool agaisnt
+	  the regression suites, work in progress
+
+Tue Jun 28 08:30:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: adding URI tests
+
+Mon Jun 27 23:55:56 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: adding xml:id
+
+Mon Jun 27 23:29:36 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: finishing XPath, adding XPointer
+
+Mon Jun 27 17:39:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: adding more coverage, XInclude and starting XPath
+
+Mon Jun 27 17:02:14 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c include/libxml/tree.h: Added allocation/deallocation
+	  functions for the DOM-wrapper context.
+
+Mon Jun 27 15:41:30 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Commented the new functions to be experimental.
+
+Mon Jun 27 14:41:14 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* error.c valid.c: working some weird error reporting problem for
+	  DTD validation.
+	* runtest.c: augmented with DTD validation tests
+	* result/VC/OneID*: slight change in validation output.
+
+Mon Jun 27 13:44:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: added most HTML tests
+
+Mon Jun 27 14:06:10 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/namespaces/reconcile/tests.xml
+	  test/namespaces/reconcile/tests-to-c.xsl: Added initial tests
+	  for some new DOM-wrapper helping functions.
+
+Mon Jun 27 14:01:06 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/xstc-to-python.xsl: Cleanup.
+	* xstc/sun-test-def.xml xstc/nist-test-def.xml xstc/ms-test-def.xml:
+	  Removed, those are not needed anymore due to the new test suite.
+
+Mon Jun 27 11:39:50 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* result/*.sax2 MAkefile.am: added SAXv2 regression tests apparently
+	  missing.
+	* runtest.c: added SAX1/SAX2 checks.
+
+Mon Jun 27 12:24:54 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c include/libxml/tree.h: Added
+	  xmlDOMWrapReconcileNamespaces(), xmlDOMWrapAdoptNode() and
+	  xmlDOMWrapRemoveNode() to the API. These are functions intended
+	  to be used with DOM-wrappers.
+
+Mon Jun 27 10:14:57 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: continue to increase the tests
+
+Mon Jun 27 09:21:49 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: continue to increase the tests
+
+Mon Jun 27 01:01:32 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* runtest.c: continue to increase the tests
+
+Sun Jun 26 20:08:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/valid.h valid.c: avoid name glob in agruments as
+	  it matches the glob() routine.
+	* runtest.c Makefile.am: first steps toward a C regression test
+	  framework.
+
+Sat Jun 25 01:37:22 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in: fixed a problem with the detection of
+	  ss_family for ipV6, as reported on the mailing list by
+	  Doug Orleans.
+
+Tue Jun 21 10:44:34 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/empty-value* result/schemas/empty-value*:
+	  Added regression tests (from Dhyanesh).
+
+Tue Jun 21 10:35:43 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed NULL values to be validated as empty
+	  string values (reported by Dhyanesh to the mailing list).
+	  Adjusted text concatenation of mixed content.
+
+Mon Jun 20 18:11:32 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c valid.c: applied patch from Rob Richards for removal
+	  of ID (and xml:id)
+	* xmlreader.c: applied patch from James Wert implementing 
+	  xmlTextReaderReadInnerXml and xmlTextReaderReadOuterXml
+
+Thu Jun 16 14:38:22 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed SAX2 validation: grow of internal
+	  namespace list, appending of element character content.
+	* xstc/xstc.py: Added "--sax" option for SAX2 validation.
+
+Wed Jun 15 15:34:52 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Added missing function descriptions.
+
+Wed Jun 15 15:26:14 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: if sax1 is used and input is a file use the old
+	  API xmlParseFile()
+	* xmlschemas.c: cleanups
+	* doc/* testapi.c elfgcchack.h: rebuilt to add python bindings
+	  for the new functions in Schemas.
+
+Wed Jun 15 14:50:48 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: Added
+	  xmlSchemaValidateFile() to the public API. This will use
+	  SAX2-driven validation.
+
+Wed Jun 15 11:11:38 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/bug306806_1_0 result/schemas/bug306806_1_0.err:
+	  Added schema test results (Tom Browder, bug #306806).
+
+Wed Jun 15 11:08:34 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/bug306806_1.xsd test/schemas/bug306806_0.xml:
+	  Added schema tests submitted by Tom Browder (bug #306806).
+
+Tue Jun 14 15:03:22 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* pattern.c: adjusted last change to xmlCompilePathPattern,
+	  fixed one compilation warning
+
+Tue Jun 14 21:19:16 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c: Some changes/fixes to the streaming evaluation.
+	* xmlschemas.c: A bit of support for parsing the schema for
+	  schema. Fixed attribute derivation when the use is
+	  "prohibited" and was "optional". Fixed an attribute construction
+	  bug, a left-over from the time, where <complexContent>,
+	  <extension>, etc. where created as structs.
+
+Tue Jun 14 12:35:12 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* libxml-2.0.pc.in: removed a redundant include path
+
+Mon Jun 13 14:58:33 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/Makefile.am: Some more adjustments.
+
+Mon Jun 13 14:35:59 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/Makefile.am: Changed test extraction process, since some
+	  boxes don't know about "tar --strip-path".
+
+Mon Jun 13 13:39:43 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed a bug exposed by Rob Richards in the mailing-list
+	* result//compare0* test//compare0*: added the regression test in
+	  the suite as this went unnoticed !
+
+Wed Jun  9 11:07:42 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* pattern.c, xpath.c, include/libxml/pattern.h: Further
+	  enhancement for XPath streaming, consolidated with
+	  schemas usage of pattern.c.  Added a new enum
+	  xmlPatternFlags.
+	* doc/*, testapi.c, elfgcchack.h: updated to reflect new
+	  enum.
+	* test/XPath/tests/mixedpat, test/XPath/docs/mixed,
+	  result/XPath/mixedpat: added regression test for problems
+	  reported in bug306348
+
+Thu Jun  9 16:51:31 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Changed non-prefixed QNames to be bound to a
+	  default namespace if existent.
+
+Thu Jun  9 15:11:38 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Fixed a bug which I invented: hexBinary's string
+	  values were not duplicated corrently when creating a computed value
+	  in xmlSchemaValAtomicType.
+
+Thu Jun  9 13:20:57 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c result/schemas/include1_0_0.err:
+	  Fixed an attribute fixed/default value constraint error.
+
+Thu Jun  9 12:51:23 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/*: Adapted regression test results.
+
+Thu Jun  9 12:22:45 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/schemasInternals.h
+	  include/libxml/xmlschemastypes.h: Changed the validation process
+	  to be able to work in streaming mode. Some datatype fixes,
+	  especially for list and union types. Due to the changes the
+	  error report output has changed in most cases. Initial migration to
+	  functions usable by both, the parser and the validator. This should
+	  ease a yet-to-come XS construction API in the long term as well.
+
+Thu Jun  9 10:16:11 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Malcolm Rowe to avoid namespace
+	  troubles on rollback parsing of elements start #304761
+	* test/nsclean.xml result/noent/nsclean.xml result/nsclean.xml*:
+	  added it to the regression tests.
+
+Thu Jun  9 00:33:50 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/xmlerror.h: applied patch from Rob Richards
+	  for xml:space and xml:lang handling with SAX2 api.
+
+Wed Jun  8 19:41:38 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: applied patch from Morten Welinder, closing bug #306901
+	  on compiling subsets of the library
+
+Wed Jun  8 19:11:42 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/Makefile.am xstc.py xstc-to-python.xsl: Adapted the
+	  XS tests to use the new release of tests and test-definitions.
+
+2005-06-07  Aleksey Sanin <aleksey@aleksey.com>
+
+	* c14n.c: fix rendering of attributes when parent node
+	is not in the node set
+
+2005-06-06  Aleksey Sanin <aleksey@aleksey.com>
+
+	* c14n.c: fixed xml attributes processing bug in exc c14n
+	* xmllint.c: added --exc-c14n command line option
+
+Mon Jun  6 06:43:33 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c, pattern.c: Enhanced xmlXPathRunStreamEval, fixed
+	  handling of depth/level for cases like union operator
+	  (bug #306348 reported by Bob Stayton).  Also enhanced
+	  several comments throughout pattern.c.
+	* doc/apibuild.py: fixed problem in handling of
+	  'signed' declaration.  Rebuilt the docs.
+	  
+Tue May 31 20:35:27 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: Enhanced handling of xml:base for included
+	  elements, fixing bugs 169209 and 302353.
+
+Wed May 25 18:59:53 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed facet errors to be channelled back for
+	  union type members; facet-validation will stop now on the
+	  first error. Reported by GUY Fabrice to the mailing-list.
+	* xmlschemastypes.c: Changed to ignore lengh-related facet
+	  validation for QNames and NOTATIONs as proposed by the
+	  schema people.
+	* test/schemas/union2* result/schemas/union2*: Added
+	  regression tests for union types (by GUY Fabrice).
+
+Fri May 20 20:48:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: applied patch from Mark Vakoc fixing saving of
+	  CDATA with NULL content.
+
+Thu May 12 15:14:26 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Changed the VALID_TZO macro to restrict
+	  the timezone to -840 to 840.
+
+Thu May 12 15:05:11 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Applied patch from Steve Nairn (bug #303670)
+	  for "signed int" of the date-time timezone field. Silenced
+	  a warning.
+
+Wed May 11 20:04:09 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch for replaceNode from Brent Hendricks
+
+Tue May 10 17:27:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed bug #303682 of a leak reported by Malcolm Rowe
+
+Tue May 10 11:50:16 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c: applied patch from Steve Nairn tof fix the compilation
+	  problem exposed in bug #303640
+
+Tue May 10 11:11:26 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/bug303566_1* result/schemas/bug303566_1_1*:
+	  Added regression a test provided by Heiko Oberdiek (bug #303566).
+
+Mon May  9 17:56:58 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c: Changed the XPath "." to resolve only on the first
+	  level for XML Schema IDCs (bug #303566 reported by Heiko Oberdiek).
+	  This should not affect pattern-like resolution on every level.
+
+Sun May  8 13:35:39 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: fixed #169630 segfault in xmlMemDisplay
+
+Fri May  6 13:40:03 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: fixing bug #303068 increasing the nanoftp buffer.
+	* doc/apibuild.py: fixed __attribute() parsing problem
+	* doc/* testapi.c: regenerated the descriptions and docs.
+
+Wed May  4 11:16:00 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in threads.c: on linux/gcc use weak definitions
+	  to avoid linking with pthread library on non-threaded environments.
+	* xpath.c: applied patch from Mark Vakoc w.r.t. a buggy namespace
+	  list allocation.
+
+Fri Apr 29 11:27:37 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* parser.c: Fixed a test for duplicate attributes: Non-prefixed
+	  attributes were treated as being bound to the default namespace.
+
+Tue Apr 19 17:51:32 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Fixed date-time related validation
+	  (reported by David Crossley, bug #300576).
+
+Tue Apr 19 16:55:40 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlregexp.c: Removed 5 unnecessary
+	  dereferences (reported by Andriy, bug #301074).
+
+Tue Apr 19 22:33:18 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: Added some code to avoid integer overflow for
+	  ceil, floor and round functions (bug 301162)
+
+Tue Apr 19 13:21:54 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed workaround for bug #172215, since it
+	  does more harm in some scenarios. Added some of the
+	  "Particle Restriction OK" constraints - not yet enabled.	  
+
+Mon Apr 18 13:02:55 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* result/schemas/changelog093*: Added test results.
+
+Mon Apr 18 12:42:14 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added output of canonical values in
+	  identity-constraint error messages.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h:
+	  Added xmlSchemaGetCanonValueWhtsp() to the API.
+	  Further enhancement of the canonical value
+	  conversion.
+	* test/schemas/changelog093_0.*: Added test with an XSD
+	  submitted by Randy J. Ray.
+
+Fri Apr 15 09:33:21 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: Applied Daniel's fix for memory leak in dtd
+	  prefix (bug 300550).
+	* xpath.c: minor change to comment only
+
+Thu Apr 14 20:52:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: added the call to the breakpoint routine
+	  when a monitored block is reallocated or freed
+
+Wed Apr 13 05:55:51 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c: applied patch from Aron Stansvik for bug #172525
+	  about HTTP query string parameter being lost
+
+Tue Apr 12 04:03:32 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/libxml.py: applied patch from Brent Hendricks
+	  adding namespace removal at the python level #300209
+	* python/tests/Makefile.am python/tests/nsdel.py: added the regression
+	  test
+
+Sun Apr 10 09:03:22 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed several places where memory cleanup was not
+	  properly done after an error was detected (problem was
+	  reported on the mailing list by Pawel Palucha)
+
+Fri Apr  8 21:58:04 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added substitution group constraints; changed
+	  the build of the pre-computed substitution groups. Channeled
+	  errors during xsi assembling of schemas to the validation
+	  context. Fixed a big memory leak, which occured when using
+	  IDCs: the precomputed value of attributes was not freed if
+	  the attribute did not resolve to an IDC field (discovered
+	  with the help of Randy J. Ray's schema, posted to the
+	  xmlschema-dev maling list).
+
+Fri Apr  8 13:22:01 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added "Particle correct 2" to parsing of model groups.
+	  Added handling substitution groups inside <choice> and <sequence>;
+	  for <all> this is not supported yet. Changed circular checks for
+	  model groups definitions. "memberTypes" are processed at different
+	  levels now: component resolution first, construction later; this
+	  goes hand in hand with a global change to handle component
+	  resolution in a distinct phase. Fixed invalid default values for
+	  elements to mark the schema as invalid; this just resulted in an
+	  error report previously, but the schema was handled as valid.
+	  Separated the assignment of the model groups to referencing
+	  model group definition references (i.e. particles); this was
+	  needed to perform the circularity check for model group definitions.
+	  Added "Element Declaration Properties Correct (e-props-correct)"
+	  constraints. Separated component resolution for simple/complex
+	  types.
+	* include/libxml/schemasInternals.h: Added a flag for substitution
+	  group heads.	  
+
+Wed Apr  6 23:14:03 CEST 2005 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.*: make install cleanup
+
+Wed Apr  6 22:42:23 CEST 2005 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.mingw: fixed mingw compilation
+	* testModule.c: removed mingw warnings
+
+Wed Apr  6 21:59:11 CEST 2005 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* .cvsignore: added Eclipse project files to ignore list
+
+Wed Apr  6 16:08:10 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed the bug in lang() as raised by Elliotte Rusty Harold
+	* result/XPath/tests/langsimple test/XPath/tests/langsimple
+	  test/XPath/docs/lang: added a regression test
+
+Tue Apr  5 23:48:35 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: applied fix from Rob Richards to compile on Windows.
+
+Tue Apr  5 17:02:58 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added "Type Derivation OK (Complex)" constraints
+	  and anchored them in the "Element Locally Valid (Element)"
+	  constraints. This restricts the type substitution via "xsi:type".
+
+Tue Apr  5 13:10:06 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: patch from Matthew Burgess to improve some schemas
+	  facets validation messages.
+
+Sat Apr  2 12:48:41 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/* configure.in NEWS: preparing release 2.6.19, updated docs and
+	  rebuilding.
+
+Sat Apr  2 13:27:32 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am: integrated fixup-tests.py
+
+Fri Apr  1 19:14:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: fixed a lack of comment and missing test for
+	  a pointer in the API.
+
+Fri Apr  1 17:54:22 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/fixup-tests.py: A tiny script to fixup some of the schema
+	  files used for the tests.
+
+Fri Apr  1 17:33:50 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h
+	  result/schemas/src-element2-*.err result/schemas/element-*.err:
+	  Committing again, since the CVS server aborted.
+
+Fri Apr  1 15:29:27 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Corrected 'length' facet validation for
+	  QNames and notations. Corrected xmlSchemaGetCanonValue: some
+	  data types did not return a value if already in normalized
+	  form.
+	* xmlschemas.c include/libxml/schemasInternals.h:
+	  Eliminated creation of structs for <restriction>, <extension>,
+	  <simpleContent>, <complexContent>, <list> and <union>: the
+	  information is now set directly on the corresponding simple/
+	  complex type. Added some more complex type constraints.
+	  Added facet derivation constraints. Introduced "particle"
+	  components, which seem to be really needed if applying
+	  constraints. Corrected/change some of the parsing functions.
+	  This is all a bit scary, since a significant change to the code.
+	* result/schemas/src-element2-*.err result/schemas/element-*.err:
+	  Adapted regression test results.
+
+Fri Apr  1 16:07:59 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/apibuild.py doc/elfgcchack.xsl: revamped the elfgcchack.h 
+	  format to cope with gcc4 change of aliasing allowed scopes, had
+	  to add extra informations to doc/libxml2-api.xml to separate
+	  the header from the c module source.
+	* *.c: updated all c library files to add a #define bottom_xxx
+	  and reimport elfgcchack.h thereafter, and a bit of cleanups.
+	* doc//* testapi.c: regenerated when rebuilding the API
+
+Thu Mar 31 17:20:32 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: fixed bug reported by Petr Pajas, in the absence of
+	  encoding UTF-8 should really be assumed. This may break if 
+	  the HTTP headers indicates for example ISO-8859-1 since this
+	  then becomes a well formedness error.
+
+Thu Mar 31 16:57:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixed #172260 redundant assignment.
+	* parser.c include/libxml/parser.h: fixed xmlSAXParseDoc() and 
+	  xmlParseDoc() signatures #172257.
+
+Thu Mar 31 16:11:10 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix potential crash if ctxt->sax->ignorableWhitespace
+	  is NULL as reported by bug #172255
+
+Thu Mar 31 15:36:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed a problem in Relax-NG validation #159968
+	* test/relaxng/list.* result/relaxng/list_*: added the test
+	  to the regression suite
+
+Thu Mar 31 13:06:02 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: fixed bug #168504
+
+Thu Mar 31 12:22:54 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in nanoftp.c nanohttp.c xmllint.c
+	  macos/src/config-mac.h: use XML_SOCKLEN_T instead of SOCKLEN_T
+	  since apparently IBM can't avoid breaking common defines #166922
+
+Thu Mar 31 10:41:45 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fix unitinialized variable in not frequently used
+	  code bug #172182
+
+Thu Mar 31 00:45:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.py: another patch from Brent
+	  Hendricks to add new handlers with the various validity contexts
+	* python/tests/Makefile.am python/tests/validDTD.py
+	  python/tests/validRNG.py python/tests/validSchemas.py: also 
+	  added the regression tests he provided
+
+Wed Mar 30 09:39:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c: applied patch from Brent
+	  Hendricks to avoid leak in python bindings when using schemas
+	  error handlers.
+
+Tue Mar 29 22:29:28 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixing bug 168196, <a name=""> must be URI escaped too
+
+Sun Mar 27 13:24:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: cleanup of the Prop related functions and xmlNewNodeEatName
+	  by Rob Richards
+
+Thu Mar 24 19:01:22 PST 2005 William Brack <wbrack@mmm.com.hk>
+
+	* gentest.py, testapi.c: fixed problem with 'minimal library'
+	  compilation (LIBXML_PATTERN_ENABLED not properly checked) reported
+	  by Greg Morgan
+
+Thu Mar 24 12:01:30 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed call to a facet error report: the type of
+	  the error was wrong, resulting in a segfault (bug #171220, reported
+	  by GUY Fabrice).
+
+Mon Mar 21 22:58:37 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed a stupid bug in xmlSchemaValidateAttributes,
+	  failing to build a linked list correctly (bug #169898, reported
+	  by bing song, hmm...).
+
+Mon Mar 21 21:09:07 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a segfault, which occured during bubbling
+	  of IDC nodes (bug #170779 and #170778, reported by GUY Fabrice):
+	  a variable was missed to be reset in a loop. Deactivated bubbling,
+	  if not referenced by a keyref.
+
+Sun Mar 20 11:13:02 PST 2005 Aleksey Sanin <aleksey@aleksey.com>
+	
+	* c14n.c include/libxml/xmlerror.h: special case "DAV:" namespace
+	in c14n relative namespaces check and add structured error messages
+	to c14n code
+
+Thu Mar 17 12:55:23 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Removed inheritance of "mixed" content type for
+	  short-hand restrictions of "anyType" (reported by Guy Fabrice
+	  to the mailing list). Added the namespace conversion (chameleon
+	  includes) for the base type reference of <restriction> and
+	  <extension>.
+	* test/schemas/bug152470_1.xsd: Adapted due to the above change
+	  of "mixed" inheritance.
+
+Thu Mar 17 11:03:59 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed a = -> == error pointed by GUY Fabrice
+
+Wed Mar 16 22:53:53 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: more debug messages from Matthew Burgess
+	* xmlschemastypes.c: xmlSchemaValidateLengthFacet API missing check.
+
+Wed Mar 16 17:37:04 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Aaaannnd putting back the previous changes done
+	  by Daniel, which I overwrote with the previous commit.
+
+Wed Mar 16 17:20:25 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/xmlschemastypes.h:
+	  Hopefully finished validation against facets to use the normalized
+	  value of both, the facets and instance values. Added 
+	  xmlSchemaValidateLengthFacetWhtsp(), xmlSchemaValidateFacetWhtsp()
+	  and xmlSchemaGetValType() to the schema API.
+
+Wed Mar 16 13:55:31 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: do not package .la files
+	* xmllint.c: applied patch from Gerry Murphy for xmllint return code
+	* xmlschemastypes.c: fixed a couple of missing tests of parameters
+	  at public API entry points.
+
+Tue Mar 15 23:31:14 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemastypes.c: a couple of more changes to various
+	  decimal-handling routines.  Fixes python some problems
+	  turned up by the python tests.
+	* Makefile.am: change SchemasPythonTests message to warn
+	  that there are 10 'expected' errors (rather than 6) since
+	  we now reject a '+' sign on an unsigned.
+
+Tue Mar 15 15:43:27 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c xmlschemastypes.h: In preparation to use
+	  normalized values of facets during validation: changed the
+	  arguments of some string comparison functions; added a static
+	  xmlSchemaValidateFacetInternal() with more arguments to be
+	  more flexible. Prepared XML_SCHEMA_FACET_ENUMERATION validation
+	  to use the comparison functions. Fixed some assignments in
+	  xmlSchemaValAtomicType(): total digit count, lo, mi, hi.
+
+Sun Mar 13 19:32:03 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in testapi.c doc/*: preparing release of 2.6.18
+	  updated docs and rebuilt
+	* libxml.spec.in: reactivated gcc profiling for gcc >= 4.0.0
+
+Sat Mar 12 19:50:22 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: removed a static buffer in xmlByteConsumed(),
+	  as pointed by Ben Maurer, fixes #170086
+	* xmlschemas.c: remove a potentially uninitialized pointer warning
+
+Fri Mar 11 23:53:13 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemastypes.c: enhanced the parsing of XML_SCHEMAS_DECIMAL
+	  and much of the routine xmlSchemaCompareDecimals.  The
+	  changes were necessary to fix a problem reported on the
+	  mailing list by John Hockaday.
+
+Fri Mar 11 13:22:52 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: The schema parser will stop if components could
+	  not be resolved. This is not conforming to the spec but for now
+	  will avoid internal errors during type fixup and content model
+	  creation. Restructured inclusion/import of schemata: this avoids
+	  duplicate, self and circular inclusion. Chameleon includes are
+	  still workarounded. Added restriction to disallow references to
+	  non-imported namespaces. Corrected parsing of <group>.
+	* result/schemas/bug167754_0_0*: Added a missing test result.
+
+Thu Mar 10 16:02:17 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/encoding.html: Enriched encoding.html with more
+	  link and foreword warning to avoid problem with ignorant
+	  programmers, c.f #169721
+
+Thu Mar 10 15:01:34 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/tests/Makefile.am python/tests/readernext.py: added
+	  a regression test from Rob Richards for the previous bug
+
+Thu Mar 10 13:22:36 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: applied fix for xmlTextReaderNext() bug from
+	  Rob Richards
+
+Thu Mar 10 11:35:57 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmodule.c: second patch from Rick Jones, portability fix for
+	  HP-UX
+	* doc/examples/xpath1.c doc/examples/xpath2.c: first fix from Rick Jones
+	  to avoid warnings.
+
+Thu Mar 10 10:20:23 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/hash.h libxml.h libxml.spec.in: some gcc4 portability
+	  patches, including a serious aliasing bug exposed in s390 
+	  when trying to convert data pointer to code pointer.
+
+Mon Mar  7 18:34:00 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Tiny restructuring of the validation start-up
+	  functions. Added cleanup of the validation context at the
+	  end of validation. This takes care of the validation context
+	  being reused.
+
+Mon Mar  7 12:12:01 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemastypes.c: Tiny changes in the comparison functions
+	  I forgot to commit last time.
+
+Fri Mar  4 22:51:42 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added IDC validation of anySimpleType attribute
+	  values; anyway the IDC key comparison is restricted to
+	  anySimpleType <--> string based types. For other types we
+	  would possibly need the canonical lexical representation of
+	  them; this sounds not performant, since we would need to
+	  build such a representation each time we want to compare against
+	  anySimpleType. TODO: think about buffering the canonical values
+	  somewhere. Fixed error reports for default attributes to work
+	  without a node being specified. This all and the enabling of IDC
+	  validation fixes bug #165346 (reported by Benoit Gr?goire - could
+	  not read his last name correctly from bugzilla).
+
+Fri Mar  4 18:57:44 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Enabled IDC parsing and validation.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h: 
+	  Added xmlSchemaCopyValue to the API; this was done due to
+	  validation of default attributes against IDCs: since IDC keys
+	  consume the precomputed value, one needs a copy.
+	* pattern.c: Enabled IDC support; this is currently done
+	  via calling xmlPatterncompile with a flag arg of 1.
+
+Wed Mar  2 11:45:18 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am doc/examples/Makefile.am python/tests/Makefile.am
+	  xstc/Makefile.am: try to fix a problem with valgrind.
+	* python/generator.py python/libxml.c python/tests/Makefile.am
+	  python/tests/tstmem.py: applied memory leak fix from Brent Hendricks
+	  c.f. bug #165349
+
+Mon Feb 28 11:18:24 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* tree.c: Changed xmlSearchNsByHref to call xmlNsInScope with
+	  the prefix instead of the namespace name.
+	* test/schemas/annot-err_0.xsd test/schemas/element-err_0.xsd:
+	  Adapted invalid values of the "id" attribute, since they are
+	  validated now.
+
+Fri Feb 25 08:31:16 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: new version with fixes from Rob Richards
+
+Thu Feb 24 16:37:51 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: applied patch from Rich Salz for multithreading on
+	  Windows.
+
+Wed Feb 23 15:04:46 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied a patch from Rob Richards fixing a couple
+	  of bugs in the writer
+
+Mon Feb 21 21:51:03 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xmlsave.c: fixed problem when XMLLINT_INDENT was empty (bug 168033).
+	* xpath.c: fixed compilation warning, no change to logic.
+	* xmlschemastypes.c: fixed compilation warning, no change to logic.
+
+Mon Feb 21 14:48:27 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied patch from Rob Richards to fix a problem with
+	  xmlTextWriterStartAttributeNS
+
+Mon Feb 21 11:41:41 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xpath.c: fixed remaining known bugs in the XPath streaming,
+	  and switched XPath to use it by default when possible
+
+Sat Feb 19 19:25:14 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: a bit of cleanup
+	* elfgcchack.h testapi.c doc/*: rebuilt the API the tests and
+	  the documentation as a result.
+
+Fri Feb 18 20:34:03 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h: applied patch from
+	  Aron Stansvik to add xmlTextReaderByteConsumed()
+	* testReader.c: added a test option
+	* xmlschemastypes.c: fix a lack of pointer checking in APIs
+
+Fri Feb 18 12:41:10 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/bug167754_0*: Added the regression test of Frans
+	  Englich for bug #167754.
+
+Fri Feb 18 12:31:49 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Started support for IDC resolution to default
+	  attributes. If building the content model for <all>: ensured
+	  to put element declarations and not the particles into the
+	  content model automaton (this was bug #167754, reported by
+	  Frans Englich).
+
+Thu Feb 17 22:31:58 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* pattern.c pattern.h: Some experimental addition for parsing
+	  of expressions and streamable validation.
+	  Added xmlStreamPushAttr to the API.
+
+Thu Feb 17 19:57:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added validation for the attribute "id" in the
+	  schemata; doing this needed error report fixes for notations,
+	  facets and group. Changed NOTATION validation to work with the
+	  declared NOTATIONs in the schema; this does have no impact on
+	  the validation via the relaxng module.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h:
+	  Added xmlSchemaNewNOTATIONValue to the API to be able to do
+	  the NOTATION validation described above.
+	* test/schemas/element-err_0.xsd test/schemas/annot-err_0.xsd:
+	  Fixed the values of the "id" attributes, which were not validated
+	  previously.  
+
+Thu Feb 17 12:03:46 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed comparison for default/fixed attribute
+	  values, if the type was 'xsd:string'. Changed the comparison
+	  for IDCs to use the whitespace aware comparison function.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h:
+	  Added xmlSchemaGetCanonValue, xmlSchemaNewStringValue and
+	  xmlSchemaCompareValuesWhtsp to the API. Added functions
+	  to compare strings with whitespace combinations of "preserve",
+	  "replace" and "collapse".
+
+Wed Feb 16 13:24:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Further work on IDCs, especially evaluation for
+	  attribute nodes.
+
+Wed Feb 16 01:19:27 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fix the comment to describe the real return values
+	* pattern.c xpath.c include/libxml/pattern.h: lot of work on
+	  the patterns, pluggin in the XPath default evaluation, but
+	  disabled right now because it's not yet good enough for XSLT.
+	  pattern.h streaming API are likely to be changed to handle
+	  relative and absolute paths in the same expression.
+
+Tue Feb 15 15:33:32 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Added IDC evaluation for attribute nodes.
+	  Made 'nil'ed elements work. Added a specific error message
+	  for 'strict' attribute wildcards.
+	* include/libxml/xmlerror.h: Added an error code for
+	  wildcards.
+	* result/schemas/anyAttr-processContents-err1_0_0.err: Adapted.  
+
+Sun Feb 13 16:15:03 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	This change started out as a simple desire to speed up the
+	execution time of testapi.c, which was being delayed by
+	nameserver requests for non-existent URL's.  From there it
+	just sort of grew, and grew....
+	* nanohttp.c, nanoftp.c: changed the processing of URL's
+	  to use the uri.c routines instead of custom code.
+	* include/libxml/xmlerror.h: added code XML_FTP_URL_SYNTAX
+	* uri.c: added accepting ipV6 addresses, in accordance with
+	  RFC's 2732 and 2373 (TODO: allow ipV4 within ipV6)
+	* gentest.py, testapi.c: fixed a few problems with the
+	  testing of the nanoftp and nanohttp routines.
+	* include/libxml/xmlversion.h: minor change to fix a
+	  warning on the docs generation
+	* regenerated the docs
+
+Sat Feb 12 09:07:11 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed xmlXIncludeParseFile to prevent
+	  overwriting XML_COMPLETE_ATTRS when setting pctxt->loadsubset
+	  (bug 166199)
+	* Makefile.am, python/tests/Makefile.am, xstc/Makefile.am: added
+	  code to add $(top_builddir)/.libs to LD_LIBRARY_PATH whenever
+	  PYTHONPATH is set, to assure new libxml2 routines are used.
+
+Fri Feb 11 22:20:41 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed problem when no initial "chunk" was
+	  given to xmlCreatePushParser (bug 162613)
+
+Fri Feb 11 18:37:22 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* dict.c: fixed compilation warning
+	* parser.c: changed xmlWarningMsg so ctxt->errNo is not set
+	* xmllint.c: changed to return non-zero status if error
+	  on xinclude processing
+	* xmlsave.c: minor deletion of a redundant condition statement
+	
+Wed Feb  9 17:47:40 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch to xmlSetNsProp from Mike Hommey
+
+Sun Feb  6 00:17:57 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xmllint.c: fixed implementation for |
+	* test/pattern/conj.* result/pattern/conj: added a specific regression
+	  test
+
+Sat Feb  5 18:36:56 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c: first implementation for | support
+
+Sat Feb  5 14:58:46 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c: fixed the namespaces support
+	* tree.c: fixed xmlGetNodePath when namespaces are used
+	* result/pattern/multiple result/pattern/namespaces
+	  test/pattern/multiple.* test/pattern/namespaces.*: added
+	  more regression tests
+
+Fri Feb  4 18:26:43 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed one internal function
+	* doc/Makefile.am doc/wiki.xsl: applied patch from Joel Reed
+	* testapi.c doc/libxml2-api.xml doc/libxml2-refs.xml: regenerated
+
+Fri Feb  4 00:25:43 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: use the walker to test the patterns instead of
+	  the normal reader
+	* pattern.c xmllint.c: bug fixes in the train including fixing the
+	  stupid build break.
+
+Tue Feb  1 18:15:52 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c: more bug fixes for the XPath streaming code.
+
+Mon Jan 31 17:59:24 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Integrated the streaming pattern from the
+	  pattern module. Fixed some IDC code bugs. Changed
+	  fallback for attribute declaration addition to work like for
+	  element declarations.	
+
+Mon Jan 31 01:27:22 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xmllint.c: bugfixes around the streaming patterns
+
+Sun Jan 30 23:35:19 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in result/pattern/simple 
+	  test/pattern/simple.*: added first test for the patterns
+	* pattern.c xmllint.c: a few fixes
+
+Sun Jan 30 19:27:23 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c include/libxml/pattern.h xmllint.c: added a 
+	  streaming pattern detector for a subset of XPath, should
+	  help Kasimier for identity constraints
+	* python/generator.py: applied Stéphane Bidoul patch to find
+	  paths without breaking.
+
+Fri Jan 28 18:53:40 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed an untested pointer dereference and a & vs &&
+
+Fri Jan 28 18:37:18 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: implementation of xmlTextReaderReadString by
+	  Bjorn Reese
+
+Fri Jan 28 16:51:47 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Corrected an ambigious symbol-space for
+	  local attribute declarations. IFDEFed more IDC code to
+	  surpress compiler warnings.
+
+Fri Jan 28 00:57:04 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* bakefile/Readme.txt bakefile/Bakefiles.bkgen bakefile/libxml2.bkl:
+	  files for the Bakefile generator for Makefiles from Francesco
+	  Montorsi
+	* win32/configure.js: fixes for Windows compilation with non-default
+	  flags by Joel Reed
+
+Thu Jan 27 18:23:50 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed xmlCopyDoc to also copy the doc->URL as pointed
+	  by Martijn Faassen
+
+Thu Jan 27 13:39:04 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h:
+	  Added an initial skeleton for indentity-constraints. This is all
+	  defined out, since not complete, plus it needs support from other
+	  modules.
+	  Added machanism to store element information for the
+	  ancestor-or-self axis; this is needed for identity-constraints
+	  and should be helpfull for a future streamable validation.
+	* include/libxml/xmlerror.h: Added an error code for
+	  identity-constraints.
+
+Wed Jan 26 01:03:37 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: had to fix generation and rebuild.
+	* valid.c: the testapi found a bug in the last code of course !
+
+Wed Jan 26 00:43:05 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am testapi.c doc/Makefile.am: fixing the way testapi.c
+	  is generated, fixes bug #161386
+	* dict.c: fix a comment typo
+	* elfgcchack.h doc/*: regenerated
+
+Tue Jan 25 22:39:33 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: found and fixed 2 problems in the internal subset scanning
+	  code affecting the push parser (and the reader), fixes #165126
+	* test/intsubset2.xml result//intsubset2.xml*: added the test case
+	  to the regression tests.
+
+Tue Jan 25 01:20:11 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* testdso.c xmlregexp.c: warning patches from Peter Breitenlohner
+	* include/libxml/valid.h valid.c parser.c: serious DTD parsing
+	  speedups, start to deprecate 3 ElementDef related entry point
+	  and replace them with better ones.
+
+Mon Jan 24 00:47:41 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: more hash dictionary interning changes
+
+Sun Jan 23 23:54:39 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* hash.c include/libxml/hash.h: added xmlHashCreateDict where
+	  the hash reuses the dictionnary for internal strings
+	* entities.c valid.c parser.c: reuse that new API, leads to a decent
+	  speedup when parsing for example DocBook documents.
+
+Sun Jan 23 21:14:20 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: small speedup in skipping blanks characters
+	* entities.c: interning the entities strings 
+
+Sun Jan 23 18:35:00 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: boosting common commnent parsing code, it was really
+	  slow.
+	* test/comment[3-5].xml result//comment[3-5].xml*: added sprecific
+	  regression tests
+
+Sun Jan 23 01:00:09 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: small optimization back.
+
+Sat Jan 22 00:40:31 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c parser.c include/libxml/dict.h: a single lock version
+	  mostly avoid the cost penalty of the lock in case of low 
+	  parallelism, so applying that version instead.
+
+Fri Jan 21 17:54:06 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: patch from Gary Coady to fix a race in dict reference
+	  counting in multithreaded apps.
+
+Fri Jan 21 16:08:21 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #164556 where non-fatal errors stopped
+	  push parsing and xmlreader.
+	* Makefile.am: fixup
+	* test/errors/webdav.xml result/errors/webdav*: adding regression
+	  test for this problem.
+
+Wed Jan 19 17:24:34 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Corrected targetNamespace in
+	  xmlSchemaElementDump. Cosmetic changes to the dump output.	
+
+Sun Jan 16 21:00:53 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: preparing release of 2.6.17,
+	  updated and rebuilt the docs
+
+Sun Jan 16 19:58:36 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: better fix for #151694 not killing c14n regression tests
+	* xmlschemastypes.c: fixing bug #157653
+
+Sun Jan 16 19:01:06 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing bug #151694, line should always be set in the
+	  elements.
+
+Sun Jan 16 01:04:18 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: trying to fix at least the message from
+	  bug #158628
+	* include/libxml/xmlsave.h xmlsave.c: added first xmlsave option
+	  for format, c.f. bug #159997
+
+Sat Jan 15 18:44:30 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: make __str__ call serialize() on nodes, c.f. 
+	  bug #157872
+
+Sat Jan 15 18:18:07 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: applied patch from Dan McNichol for compilation on AIX
+
+Sat Jan 15 13:35:19 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed bug #157633 in relaxng choice optimization
+	* result/relaxng/choice0* test/relaxng/choice0*: added regression
+	  tests about it.
+	* doc/*: rebuilt
+	* testdso.c: removed a warning due to a missing void in signature.
+
+Thu Jan 13 17:42:55 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* include/libxml/schemasInternals.h xmlschemas.c: 
+	  Exposed targetNamespace for simple/complex types, model groups,
+	  attribute groups and notations (reported by Michael Hewarth 
+	  to the mailing list). Added targetNamespace to xmlSchemaType, 
+	  xmlSchemaAttributeGroup and xmlSchemaNotation.
+	  Tiny cosmetic change to the content model error report output.
+	* result//all_*.err result//any3_0_0.err result//choice_*.err 
+	  result//list0_0_1.err result//list0_1_1.err: Adapted output 
+	  of regression tests.
+
+Thu Jan 13 13:20:51 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Put the fix of Daniel (from Tue Jan 11 14:41:47 CET)
+	  back in, since I missed to update xmlschemas.c before doing
+	  the previous commit.
+	
+Thu Jan 13 12:59:25 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Integrated xmlRegExecErrInfo and xmlRegExecNextValues
+	  from xmlregexp.c to report expected elements on content model errors.
+	* all_*.err any3_0_0.err choice_*.err list0_0_1.err list0_1_1.err:
+	  Adapted output of regression tests.
+
+Thu Jan 13 12:24:09 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in xmlmodule.c: trying to work around
+	  the compilation problem on HP-UX
+
+Wed Jan 12 22:03:33 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c: fixed the fixed size array structure problem reported by
+	  Patrick Streule
+
+Wed Jan 12 15:15:02 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* elfgcchack.h testapi.c doc/libxml2-api.xml doc/*: regenerated
+	  the API description, rebuilt, improved navigation in documentation
+	  a bit.
+
+Wed Jan 12 14:17:14 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlregexp.h xmlregexp.c: extended xmlRegExecErrInfo()
+	  and xmlRegExecNextValues() to return error transition strings too,
+	  and sink state detection and handling.
+
+Tue Jan 11 14:41:47 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed bug #163641 when the value passed for
+	  an atomic list type is NULL.
+
+Tue Jan 11 10:14:33 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* Makefile.am configure.in: fixed dependency on python 2.3,
+	  also small improvement for cygwin (bug 163273)
+
+Sun Jan  9 18:46:32 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: William noticed I forgot to add special
+	  support for xmlmodules.c define
+	* xmlregexp.c include/libxml/xmlregexp.h: added terminal to
+	  xmlRegExecErrInfo() API, adding new xmlRegExecNextValues()
+	  entry point and refactored to use both code.
+
+Mon Jan 10 01:02:41 HKT 2006 William Brack <wbrack@mmm.com.hk>
+
+	* doc/xml.html, doc/FAQ.html: added an FAQ under Developer for
+	  setting up a "private" library (after some list posts about
+	  people having trouble doing it)
+
+Sat Jan  8 23:04:10 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixing behaviour for xmlRegExecErrInfo in case of
+	  rollback
+
+Fri Jan  7 14:54:51 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* TODO: small update
+	* xmlregexp.c: trying to add an API to get useful error informations
+	  back from a failing regexp context.
+
+Thu Jan  6 17:35:41 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with xmlXPathErr when error number
+	  subscript was out of range (bug 163055)
+
+Thu Jan  6 09:57:03 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: fixed problem with xmlURIEscape when query part was
+	  empty (actually fixed xmlURIEscapeStr to return an empty
+	  string rather than NULL for empty string input) (bug 163079)
+	  
+Tue Jan  4 17:08:45 PST 2005 Aleksey Sanin <aleksey@aleksey.com>
+
+	* parser.c, parserInternal.c: fixed "col" calculation for 
+          struct _xmlParserInput (based on patch from Rob Richards) 
+	* include/libxml/xmlerror.h, error.c: propagated error column
+          number in the xmlError structure
+
+Tue Jan  4 22:47:22 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed namespace bug in push mode reported by 
+	  Rob Richards
+	* test/ns6 result//ns6*: added it to the regression tests
+	* xmlmodule.c testModule.c include/libxml/xmlmodule.h:
+	  added an extra option argument to module opening and defined
+	  a couple of flags to the API.
+
+Tue Jan  4 21:16:05 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmodule.c include/libxml/xmlmodule.h: applied patch from
+	  Bjorn Reese, plus some cleanups
+	* elfgcchack.h doc/elfgcchack.xsl: fixed the stylesheet to 
+	  add the new header
+	* doc/* testapi.c: regenerated the API
+
+Tue Jan  4 18:47:19 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: making DSO support an option
+	* xmlmodule.c xmlreader.c include/libxml/xmlmodule.h: code
+	  and documentation cleanups
+	* elfgcchack.h testapi.c doc/*: regenerated the docs and
+	  checks for new module
+	* test/valid/REC-xml-19980210.xml: fix a small change introduced
+	  previously
+
+Tue Jan  4 16:07:52 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am config.h.in configure.in error.c libxml-2.0.pc.in
+	  testModule.c testdso.c xml2-config.in xmllint.c xmlmodule.c
+	  include/libxml/Makefile.am include/libxml/xmlerror.h
+	  include/libxml/xmlmodule.h include/libxml/xmlversion.h.in 
+	  include/libxml/xmlwin32version.h.in: applied DSO support
+	  patch 2 from Joel Reed
+
+Tue Jan  4 15:30:15 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: applied patch from Marcin Konicki for BeOS
+
+Mon Jan  3 13:57:21 PST 2005 Aleksey Sanin <aleksey@aleksey.com>
+
+	* parser.c: added GetLineNumber and GetColumnNumber functions for xmlReader
+
+Sun Jan  2 17:51:18 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	Re-examined the problems of configuring a "minimal" library.
+	Synchronized the header files with the library code in order
+	to assure that all the various conditionals (LIBXML_xxxx_ENABLED)
+	were the same in both.  Modified the API database content to more
+	accurately reflect the conditionals.  Enhanced the generation
+	of that database.  Although there was no substantial change to
+	any of the library code's logic, a large number of files were
+	modified to achieve the above, and the configuration script
+	was enhanced to do some automatic enabling of features (e.g.
+	--with-xinclude forces --with-xpath).  Additionally, all the format
+	errors discovered by apibuild.py were corrected.
+	* configure.in: enhanced cross-checking of options
+	* doc/apibuild.py, doc/elfgcchack.xsl, doc/libxml2-refs.xml,
+	  doc/libxml2-api.xml, gentest.py: changed the usage of the
+	  <cond> element in module descriptions
+	* elfgcchack.h, testapi.c: regenerated with proper conditionals
+	* HTMLparser.c, SAX.c, globals.c, tree.c, xmlschemas.c, xpath.c,
+	  testSAX.c: cleaned up conditionals
+	* include/libxml/[SAX.h, SAX2.h, debugXML.h, encoding.h, entities.h,
+	  hash.h, parser.h, parserInternals.h, schemasInternals.h, tree.h,
+	  valid.h, xlink.h, xmlIO.h, xmlautomata.h, xmlreader.h, xpath.h]:
+	  synchronized the conditionals with the corresponding module code
+	* doc/examples/tree2.c, doc/examples/xpath1.c, doc/examples/xpath2.c:
+	  added additional conditions required for compilation
+	* doc/*.html, doc/html/*.html: rebuilt the docs
+	
+Sat Dec 25 18:10:02 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parserInternals.c: fixed to skip (if necessary) the BOM for
+	  encoding 'utf-16'.  Completes the fix for bug #152286.
+	* tree.c, parser.c: minor warning cleanup, no change to logic
+	
+Fri Dec 24 16:31:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/generator.py: added most required entires to
+	  foreign encoding table, plus some additional logic to
+	  assure only the 1st param uses the 't#' format.  Fixes
+	  bug #152286, but may still have some other UTF-16 problems.
+
+Thu Dec 23 23:44:08 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* Makefile.am, gentest.py: enhanced for enabling build in
+	  a different directory.  Added (optional) param to gentest.py
+	  to specify the source directory (bug #155468)
+	* doc/Makefile.am: changed destination of NEWS from (top_srcdir)
+	  to (top_builddir) (bug #155468)
+	* python/Makefile.am, python/generator.py: enhanced for enabling
+	  build in a different directory(bug #155468).  Added (optional)
+	  param to generator.py to specify the source directory.  Added
+	  a new table of functions which have possible "foreign" encodings
+	  (e.g. UTF16), and code to use python 't' format instead of
+	  'z' format (mostly solving bug #152286, but still need to
+	  populate the table).
+	  
+Tue Dec 21 08:10:44 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/site.xsl, doc/xml.html, plus rebuilt all the html pages
+	Change reference to new site for Solaris binaries, fixing bug
+	160598
+
+
+Mon Dec 20 08:02:57 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: reset input->base within xmlStopParser
+	* xmlstring.c: removed call to xmlUTF8Strlen from within
+	  xmlUTF8Strpos (Bill Moseley pointed out it was not
+	  useful)
+
+Fri Dec 17 16:03:41 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: changed xmlErrValidWarning to use ctxt->warning
+	  instead of ctxt->error for its reports (bug #160662)
+
+Fri Dec 17 14:52:17 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/generator.py: modified to allow the ns and nsDefs
+	  accessors to return None instead of error when no namespace
+	  is present (bug #)
+
+Fri Dec 17 11:40:21 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* doc/Makefile.am: changed maintainer-clean dependency with
+	  suggestion from Crispin Flowerday (bug #157634)
+	* debugXML.c: fixed crash when ATTRIBUTE or DOCUMENT nodes
+	  were specified with debugDumpNode (bug #160621)
+
+Fri Dec 10 11:24:41 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed ID deallocation problem based on patch from
+	  Steve Shepard fixes bug #160893
+	* xmlmemory.c: improving comment.
+	* testapi.c: new test for xmlDictExists() is generated.
+
+Wed Dec  1 22:35:37 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* dict.c, xpath.c, include/libxml/hash.h: fixed up some gcc warnings,
+	  no change to logic.  New macro XML_CAST_FPTR to circumvent gcc
+	  warnings on function pointer <-> object pointer (a hack).
+
+Mon Nov 29 14:07:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed a memory leak on errors in some circumstances #159812
+
+Fri Nov 26 23:20:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlIO.c: added a check within xmlOutputBufferWriteEscape to prevent
+	  a dead loop on bad data (bug 159550)
+
+Fri Nov 26 13:09:04 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed strict/lax element wildcards: the children
+	  of elements for which a declaration existed were still processed
+	  by the wildcard mechanism (reported by philippe ventrillon to the
+	  mailing list).
+	  Changed the import and include machanism to share dictionaries.
+
+Fri Nov 26 11:44:36 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c parser.c: make sure xmlCtxtReadFile and htmlCtxtReadFile
+	  go through the catalog resolution.
+	* gentest.py testapi.c: fix a side effect wrning of the change
+
+Wed Nov 24 13:41:52 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c include/libxml/dict.h: added xmlDictExists() to the 
+	  dictionnary interface.
+	* xmlreader.c: applying xmlTextReaderHasAttributes fix for namespaces
+	  from Rob Richards
+
+Wed Nov 17 13:54:37 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: tiny enhancement for content model error reports
+	  (#157190, #143948). Removed abbreviations: CT, ST and WC 
+	  (#157190, reported by Frans  Englich).
+	  Initial: no report of local components.
+	* result/schemas/all* result/schemas/any3_0_0.err
+	  result/schemas/choice*
+	  result/schemas/cos-st-restricts-1-2-err_0_0.err
+	  result/schemas/derivation-ok-extension-err_0_0.err
+	  result/schemas/derivation-ok-extension_0_0.err
+	  result/schemas/derivation-ok-restriction-2-1-1_0_0.err
+	  result/schemas/derivation-ok-restriction-4-1-err_0_0.err 
+	  result/schemas/deter0_0_0.err result/schemas/extension1_0_2.err
+	  result/schemas/facet-unionST-err1_0_0.err
+	  result/schemas/hexbinary_0_1.err
+	  result/schemas/list* result/schemas/restriction-attr1_0_0.err
+	  result/schemas/vdv-first4_0_1.err result/schemas/vdv-first4_0_2.err:
+	  Adapted output.
+
+Mon Nov 15 13:04:28 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Moved execution of xmlSchemaCheckDefaults to
+	  xmlSchemaTypeFixup; this ensures facets of inherited types to be
+	  checked prior to facets of derived types - which caused a seg
+	  fault otherwise (bug #158216, reported by Frans Englich).
+
+Sun Nov 14 22:23:18 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* gentest.py, testapi.c: further enhancement, now all
+	  compilation warnings have been fixed.
+	* xmlschemastypes.c: added NULL check for one function
+
+Fri Nov 12 23:58:14 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: trivial change (changed CHECK_CONTEXT to CHECK_CTXT
+	  on a couple of lines)
+	* gentest.py, testapi.c: enhanced to reduce compilation warnings
+
+Fri Nov 12 16:12:48 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Un-commented a TODO in xmlSchemaParseElement.
+
+Fri Nov 12 14:55:36 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Correct symbol space for 'all' and 'choice'.
+	* xmlschemastypes.c include/xmlschemastypes.h: Added 'replace' 
+	  normalization for 'normalizedString'.  
+	  Added xmlSchemaWhiteSpaceReplace to the API.
+
+Thu Nov 11 21:43:02 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: forgot a $(srcdir)
+	* encoding.c: stupid error wrong name #157976
+
+Wed Nov 10 15:35:25 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in doc/*: preparing release of libxml2-2.6.16
+
+Wed Nov 10 12:55:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml2class.txt
+	  python/libxml_wrap.h python/types.c: Applied patch from Brent
+	  Hendricks adding support for late DTD validation.
+	* python/tests/Makefile.am python/tests/dtdvalid.py
+	  python/tests/test.dtd: integrated the provided regression test
+
+Tue nov  9 19:24:31 CET 2004 Dodji Seketeli <dodji@seketeli.org>
+
+	* configure.in: detect when struct sockaddr_storage
+	  has the __ss_family member instead of ss_family and
+	  behave accordingly. We now can use ipv6 on aix.
+
+Tue Nov  9 17:15:46 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am gentest.py testapi.c: integrated in "make tests"
+	  added -q option, and more conditional features fixes
+	* catalog.c debugXML.c parser.c testThreads.c xmllint.c
+	  xmlschemastypes.c xmlwriter.cinclude/libxml/catalog.h
+	  include/libxml/debugXML.h: various compilation and conditional
+	  cleanups.
+	* doc/*: regenerated
+
+Tue Nov  9 15:59:50 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: better handling of conditional features
+	* HTMLparser.c SAX2.c parserInternals.c xmlwriter.c: more testing
+	  on parser contexts closed leaks, error messages
+
+Tue Nov  9 10:21:37 GMT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem concerning XPath context corruption
+	  during function argument evaluation (bug 157652)
+	  
+Mon Nov  8 18:54:52 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c: more types.
+	* parserInternals.c xpath.c: more fixes
+
+Mon Nov  8 18:16:43 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: better parser options coverage
+	* SAX2.c xpath.c: more cleanups.
+
+Tue Nov  9 01:50:08 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c: trying to fix some optional support brokenness
+
+Mon Nov  8 17:25:27 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more coverage
+	* debugXML.c parser.c xmlregexp.c xpath.c: more fixes
+
+Mon Nov  8 15:02:39 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more coverage
+	* SAX2.c parser.c parserInternals.c: more fixes
+
+Mon Nov  8 12:55:16 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c testapi.c xmlIO.c xmlstring.c: more fixes.
+
+Mon Nov  8 11:24:57 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more types, more coverage
+	* parser.c parserInternals.c relaxng.c valid.c xmlIO.c
+	  xmlschemastypes.c: more problems fixed
+	  
+Mon Nov  8 10:24:28 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* gentest.py: fixed test file corruption problem
+
+Sun Nov  7 13:18:05 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: fixed typos and avoid Catalogs verbosity
+
+Sat Nov  6 23:25:16 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testapi.c: augmented the number of types
+
+Sat Nov  6 20:24:07 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c tree.c xmlreader.c xmlwriter.c: a number of new
+	  bug fixes and documentation updates.
+
+Sat Nov  6 15:50:11 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: augmented type autogeneration for enums
+	* xpath.c include/libxml/xpath.h: removed direct error reporting.
+
+Sat Nov  6 14:27:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fixed a regression in iconv support.
+
+Fri Nov  5 18:19:23 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: autogenerate a minimal NULL value sequence
+	  for unknown pointer types
+	* HTMLparser.c SAX2.c chvalid.c encoding.c entities.c parser.c
+	  parserInternals.c relaxng.c valid.c xmlIO.c xmlreader.c 
+	  xmlsave.c xmlschemas.c xmlschemastypes.c xmlstring.c xpath.c
+	  xpointer.c: This uncovered an impressive amount of entry points
+	  not checking for NULL pointers when they ought to, closing all
+	  the open gaps.
+
+Fri Nov  5 16:26:28 UTC 2004 William Brack <wbrack@mmm.com.hk>
+
+	* catalog.c: fixed problem with NULL entry (bug 157407)
+	* xpath.c: fixed a couple of warnings (no change to logic)
+
+Fri Nov  5 15:30:43 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more coverage
+	* xmlunicode.c: one fix
+
+Fri Nov  5 23:15:51 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: fixed a compilation problem on a recent change
+
+Fri Nov  5 12:50:09 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more coverage
+	* nanoftp.c tree.c: more fixes
+
+Fri Nov  5 11:02:28 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: fixed the way the generator works,
+	  extended the testing, especially with more real trees and nodes.
+	* HTMLtree.c tree.c valid.c xinclude.c xmlIO.c xmlsave.c: a bunch
+	  of real problems found and fixed.
+	* entities.c: fix error reporting to go through the new handlers
+
+Thu Nov  4 18:44:56 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: dohh ... stupid change killing xmlParseDoc()
+
+Thu Nov  4 18:32:22 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: changing the way the .c is generated,
+	  extending the tests coverage
+	* include/libxml/nanoftp.h nanoftp.c elfgcchack.h doc/*: fixing some
+	  function signatures, regenerating stuff
+	* SAX2.c parser.c xmlIO.c: another set of bug fixes and API hardening
+
+Thu Nov  4 13:32:19 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: extending the tests coverage
+
+Thu Nov  4 11:52:28 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: gentest.py was missing from the EXTRA_DIST
+
+Thu Nov  4 11:48:47 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: extending the tests coverage
+	* HTMLtree.c tree.c xmlsave.c xpointer.c: more fixes and cleanups
+
+Thu Nov  4 00:25:36 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more fixes and extending the tests coverage
+	* nanoftp.c xmlIO.c: more fixes and hardening
+	
+Wed Nov  3 20:16:24 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more fixes and extending the tests coverage
+	* valid.c: bunch of cleanups and 2 leaks removed 
+
+Wed Nov  3 18:06:44 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more fixes and extending the tests coverage
+	* list.c tree.c: more fixes and hardening
+
+Wed Nov  3 15:19:22 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more fixes and extending the tests coverage
+	* relaxng.c include/libxml/relaxng.h: adding a type init interface
+	* include/libxml/xmlerror.h parser.c xmlreader.c xmlwriter.c: more
+	  cleanups and bug fixes raised by the regression tests
+
+Wed Nov  3 12:49:30 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more fixes and extending the tests coverage
+	* xmlwriter.c list.c: more hardeing of APIs
+	* doc/apibuild.py: skip testapi.c when scanning the C files.
+
+Tue Nov  2 23:09:06 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more testing and coverage
+	* elfgcchack.h xmlstring.c include/libxml/xmlstring.h: more cleanups
+	* doc/*: rebuilt
+
+Tue Nov  2 19:44:32 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* gentest.py testapi.c: more developments on the API testing
+	* HTMLparser.c tree.c: more cleanups
+	* doc/*: rebuilt
+
+Tue Nov  2 15:49:34 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c include/libxml/xmlmemory.h: adding xmlMemBlocks()
+	* Makefile.am gentest.py testapi.c: work on generator of an
+	  automatic API regression test tool.
+	* SAX2.c nanoftp.c parser.c parserInternals.c tree.c xmlIO.c
+	  xmlstring.c: various API hardeing changes as a result of running
+	  teh first set of automatic API regression tests.
+	* test/slashdot16.xml: apparently missing from CVS, commited it
+
+Mon Nov  1 15:54:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed an UTF-8 parsing bug reported by Markus Bertheau
+	  on #fedora-devel
+
+Sun Oct 31 22:03:38 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a bug reported by Petr Pajas on the list and
+	  affecting XML::Libxml
+
+Sun Oct 31 16:33:54 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c doc/examples/testWriter.c: Fixed bug #153937, making
+	  sure the conversion functions return the number of byte written.
+	  Had to fix one of the examples.
+
+Fri Oct 29 14:16:56 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.1 doc/xmllint.xml: indicate - means stdin closing #156626
+
+Fri Oct 29 14:03:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: register xmlSchemaSetValidErrors, patch from
+	  Brent Hendricks in the mailing-list
+	* include/libxml/valid.h HTMLparser.c SAX2.c valid.c
+	  parserInternals.c: fix #156626 and more generally how to find out
+	  if a validation contect is part of a parsing context or not. This
+	  can probably be improved to make 100% sure that vctxt->userData
+	  is the parser context too. It's a bit hairy because we can't 
+	  change the xmlValidCtxt structure without breaking the ABI since
+	  this change xmlParserCtxt information indexes.
+
+Wed Oct 27 19:26:20 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* ChangeLog NEWS configure.in doc/*: preparing release 2.6.15
+	* debugXML.c nanoftp.c xmlschemas.c xmlschemastypes.c: cleanups
+
+Wed Oct 27 09:31:24 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: fixed a stupid mistake in xmlBuildRelativeURI
+	  (bug 156527)
+
+Wed Oct 27 11:44:35 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c: second part of the security fix for
+	  xmlNanoFTPConnect() and xmlNanoHTTPConnectHost().
+
+Tue Oct 26 23:57:02 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: applied fixes for a couple of potential security problems
+	* tree.c valid.c xmllint.c: more fixes on the string interning checks
+
+Tue Oct 26 18:09:59 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/xmlerror.h: added checking for names
+	  values and dictionnaries generates a tons of errors
+	* SAX2.ccatalog.c parser.c relaxng.c tree.c xinclude.c xmlwriter.c
+	  include/libxml/tree.h: fixing the errors in the regression tests
+
+Mon Oct 25 16:04:22 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: modified the handling of _private for entity
+	  expansion (bug 155816)
+
+Mon Oct 25 17:11:37 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed the leak reported by Volker Roth on the list
+	* test/ent10 result//ent10*: added a specific test for the problem
+
+Sat Oct 23 11:07:41 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: unlinked the internal subset within xmlValidateDtd
+	  (bug 141827)
+	* configure.in: added -Wall to developer's flags
+	* doc/examples/reader4.res: added to CVS
+
+Fri Oct 22 16:36:50 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: added support for HTML PIs #156087
+	* test/HTML/python.html result/HTML/python.html*: added specific tests
+
+Fri Oct 22 15:20:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: fixed nasty bug #156087
+
+Fri Oct 22 21:04:20 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: fixed a problem occuring only in x86_64 when
+	  very large error messages are raised to the Python handlers.
+
+Thu Oct 21 18:03:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed a memory bug
+	* doc/examples/reader4.c doc/examples/*: added test from Graham Bennett
+	  and regenerated the directory
+
+Tue Oct 19 11:06:39 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlreader.h xmlreader.c: applied patch from
+	  Graham Bennett adding 4 convenience functions to the reader API.
+
+Fri Oct 15 11:22:48 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* debugXML.c: excluded a few nodes (with no content) from the
+	  string check routine.
+
+Fri Oct 15 10:48:30 EDT 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/xmlerror.h: added UTF-8 string checking,
+	  raise a problem, need debug
+
+Wed Oct 13 02:17:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: applied patch from Thomas Fitzsimmons fixing
+	  #155240 building outside the source tree. but make tests fails.
+
+Mon Oct 11 16:26:51 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/xmlerror.h: added namespace checking
+
+Sat Oct  9 22:36:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: some framework preparation to add namespace checkings
+
+Thu Oct  7 15:12:58 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/debugXML.h include/libxml/xmlerror.h:
+	  adding the tree debug mode
+	* parser.c relaxng.c tree.c xpath.c: fixing various problems reported
+	  by the debug mode.
+	* SAX2.c: another tree fix from Rob Richards
+
+Wed Oct  6 10:50:03 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* catalog.c: small change to last fix, to get xml:base right
+
+Wed Oct  6 09:33:51 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* catalog.c: added code to handle <group>, including dumping
+	  to output (bug 151924).
+	* xmlcatalog.c, xmlstring.c, parser.c: minor compiler warning 
+	  cleanup (no change to logic)
+	  
+Mon Oct  4 16:09:07 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in debugXML.c include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h.in: revamped the XML debugging
+	  module and prepare for a new checking mode
+
+Mon Oct  4 13:53:24 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Malcolm Tredinnick fixing bug #152426
+
+Mon Oct  4 12:26:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/tests/outbuf.py: 
+	  applied patch from Malcolm Tredinnick fixing bug #154294
+	  related to saving to python file objects.
+
+Sat Oct  2 21:08:51 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: changed xmlHasNsProp to properly handle a request for
+	  the default namespace (bug 153557)
+
+Sat Oct  2 18:18:27 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed problem with dictionary handling within
+	  xmlParseInNodeContext (bug 153175)
+
+Sat Oct  2 15:46:37 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* check-relaxng-test-suite.py, check-relaxng-test-suite2.py,
+	  check-xinclude-test-suite.py, check-xml-test-suite.py,
+	  check-xsddata-test-suite.py, doc/examples/index.py: changed
+	  changed sys.path setting from 'append' to 'insert' (patch
+	  supplied by Malcolm Tredinnick) (bug 153716)
+
+Sat Oct  2 15:03:14 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/parserInternals.h: added two new macros
+	  IS_ASCII_LETTER and IS_ASCII_DIGIT used with (html)
+	  parsing and xpath for testing data not necessarily
+	  unicode.
+	* HTMLparser.c, xpath.c: changed use of IS_LETTER_CH and
+	  IS_DIGIT_CH macros to ascii versions (bug 153936).
+	  
+Fri Oct  1 20:37:25 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* error.c: added some coding to attempt to display which file
+	  contains an error when using XInclude (bug 152623)
+
+Thu Sep 30 11:19:17 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: stupid cut'n paste bug in xmllint detection
+
+Wed Sep 29 17:47:56 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/*: releasing 2.6.14, rebuilding the docs
+	  
+Wed Sep 29 15:00:11 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/xmlerror.h include/libxml/xmlschemas.h
+	  include/libxml/schemasInternals.h: Parsing of <complexContent>
+	  - handle attribute 'mixed', catch illegal attributes.
+	  Parsing of <complexType> - handle attributes 'abstract',
+	  'final' and 'block', catch illegal attributes.
+	  Validation of complex types - handle abstract types.
+	  Added handling of default/fixed attributes and element values.
+	  Per validation option attribute nodes/text nodes are created
+	  on the instance.
+	  Added the corresponding constraints for fixed/default.
+	  Added xmlSchemaSetValidOptions, xmlSchemaGetValidOptions
+	  to the external API.
+	  Extended element declaration constraints.  
+	  Got rid of perseverative creation of temporery validation/parser 
+	  contexts.
+	  Added handling of xsi:schemaLocation and
+	  xsi:noNamespaceSchemaLocation.
+	  Fixed xsi:type component resolution if using non-prefixed
+	  QNames.
+	* xmlregexp.c xmlschemas.c include/libxml/xmlautomata.h:
+	  Enabled namespace awareness of the content model if using the
+	  model group "all".
+	* test/schemas/bug152470_1.xsd: Removed an "abstract" attribute,
+	  which broke the test.
+	* xstc/xstc.py:  Workaround to accomodate case insensitive
+	  test definitions in ms-test.def.xml (was missing in a previous
+	  commit).
+
+Wed Sep 29 11:03:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/drv_libxml2.py: another patch from Malcolm Tredinnick
+	  adding option not to load dtd from the drv_libxml2.py module
+	  #134633
+
+Tue Sep 28 14:30:22 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* acconfig.h config.h.in configure.in xmlIO.c xmlregexp.c xmlschemas.c
+	  xmlschemastypes.c: another patch from Malcolm Tredinnick fixing
+	  warning generated by the Nonstop Kernel Open System Services 
+	  compiler #151710
+
+Tue Sep 28 13:07:37 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: applied patch from Malcolm Tredinnick fixing
+	  python exception hierarchy #139824
+
+Sun Sep 26 16:40:24 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c TODO: applied patch from Malcolm Tredinnick fixing errata
+	  E20 concerning NMTOKENS and co. validation #153722
+	* result/VC/AttributeNmtokens test/VC/AttributeNmtokens
+	  test/VCM/AttributeNmtokens.xml: also added tests from Malcolm
+
+Sun Sep 26 16:24:44 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/xstc.py: applied patch from Malcolm Tredinnick fixing space/tabs
+	  #153713
+	* xpath.c: fixed a realloc potential problem
+
+Fri Sep 24 16:14:12 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: fixed make valgrind xstc 
+
+Thu Sep 23 18:23:46 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: fixing an out of bound adressing issue
+
+Thu Sep 23 15:14:12 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c parser.c relaxng.c xmlschemas.c: more memory related
+	  code cleanups.
+
+Thu Sep 23 01:04:30 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a bunch of errors when realloc failed.
+
+Wed Sep 22 23:56:05 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c uri.c: couple of memory fixes from Mark Vakoc reported
+	  by Purify on Windows.
+
+Mon Sep 20 22:01:47 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added --timing --copy timing for the copy
+	* vms/build_libxml.com: applied patch from Craig Berry
+	  to build with recent releases
+
+Fri Sep 17 21:25:33 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c, include/libxml/nanohttp.h: added the routine
+	  xmlNanoHTTPContentLength to the external API (bug151968).
+	* parser.c: fixed unnecessary internal error message (bug152060);
+	  also changed call to strncmp over to xmlStrncmp.
+	* encoding.c: fixed compilation warning (bug152307).
+	* tree.c: fixed segfault in xmlCopyPropList (bug152368); fixed
+	  a couple of compilation warnings.
+	* HTMLtree.c, debugXML.c, xmlmemory.c: fixed a few compilation
+	  warnings; no change to logic.
+
+Fri Sep 17 10:40:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: removed some extern before function code reported by
+	  Kjartan Maraas on IRC
+	* legacy.c: fixed compiling when configuring out the HTML parser
+	* Makefile.am: added a declaration for CVS_EXTRA_DIST
+	* HTMLparser.c: beginning of an attempt at cleaning up the construction
+	  of the HTML parser data structures, current data generate a huge
+	  amount of ELF relocations at loading time.
+
+Fri Sep 17 10:36:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* ChangeLog: applied fix from Stepan Kasal to fix duplication
+	  in the change log and cleanup of space/tabs issues.
+
+Thu Sep 16 13:24:27 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h 
+	  test/schemas/bug152470_1.* result/schemas/bug152470_1_1*: 
+	  Simpified attribute wildcard creation and assignment to get rid 
+	  of memory leaks.
+	  Restructured the validation process.
+	  Restructured and expanded parsing of <attributeGroup>.
+	  Added initial handing of xsi:type.
+	  Advanced handling of xsi:nil (should work now for simple types).
+	  Added construction of schemata using xsi:schemaLocation and 
+	  xsi:noNamespaceSchemaLocation; this is not enabled, since 
+	  no corresponding API exists yet.
+	  Moved the content model to complex type components.
+	  Resolution of types for attributes will look for simple types
+	  only (incl. all the built-in simple types).
+	  Extended parsing of 'anyAttribute'.
+	  Fixed content-type type for complex types if derived from 
+	  'anyType' using the short-hand form (see bug # 152470,
+	  submitted by Thilo Jeremias).
+	* include/libxml/xmlschematypes.h: Cleaned up some comments.
+	* xstc/xstc.py: Workaround to accomodate case insensitive
+	  test definitions in ms-test.def.xml.
+	* result/schemas/deter0_0_0.err result/schemas/ns0_0_2.err
+	  result/schemas/ns0_1_2.err: Adapted.
+
+Sat Sep 11 09:04:22 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlwriter.c: changed char array initialisation to avoid a
+	  complaint from some compiler(s) (bug 152308)
+
+Thu Sep  9 07:22:11 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c: applied fixes for the UTF8ToISO8859x transcoding
+	  routine suggested by Mark Itzcovitz
+
+Wed Sep  8 22:50:27 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c xmlsave.c: fixed 2 problems raised by #152140, one
+	  which is that notation not in the internal subset should
+	  not be saved, and the second more nasty on an error saving
+	  NOTATIONs, if there is a proof that nobody uses notations !
+
+Wed Sep  8 11:04:27 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: Added the function
+	  xmlSchemaValidateOneElement to the XML Schema validation API, 
+	  as proposed by Jeffrey Fink - see bug # 152073.
+
+Tue Sep  7 11:10:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/Makefile.am xstc/Makefile.am: some cleanup
+	  checking for xmllint and xsltproc in configure.in, fixed
+	  make dist w.r.t. the new xstc subdir.
+	* doc/*: rebuilt
+
+Mon Sep  6 16:42:59 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/xstc.py: Changed to finally validate instance documents.
+
+Mon Sep  6 16:04:01 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am Makefile.am: integrated to "make valgrind",
+	  heavy ... weight 250MB of VM !
+
+Mon Sep  6 14:54:39 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xstc/Makefile.am xstc/xstc-to-python.xsl xstc/xstc.py Makefile.am:
+	  more cleanup in integrating the xstc testsuite
+
+Mon Sep  6 13:56:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in xstc/.cvsignore xstc/Makefile.am:
+	  starting to integrate the xstc suite in the normal regression
+	  tests
+
+Mon Sep  6 13:14:11 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/sun-test-def.xml: The "tsDir" attribute was not
+	  set correctly.
+
+Mon Sep  6 11:52:50 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* check-xinclude-test-suite.py: when output and expected do not match
+	  exactly run diff to put the differences in the log c.f. #148691
+
+Mon Sep  6 11:17:35 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xstc/xstc-to-python.xslt xstc/ms-test-def.xml xstc/nist-test-def.xml
+	  xstc/sun-test-def.xml: Initial release of generation files to 
+	  create python test scripts, which will run the W3C XML Schema Test
+	  Collection. The ms-test-def.xml and sun-test-def.xml files
+	  were extracted from the online HTML XSTC results [1], since they did
+	  not exist for the SUN tests, and only partially did exist for the 
+	  MS tests. The NIST definition file was created by concatenation
+	  of the existing definition files for each single datatype.
+	  The stylesheet "xstc-to-python.xslt" should be run against the
+	  definition files to produce the python scripts.
+	  [1] "http://www.w3.org/XML/2001/05/xmlschema-test-collection/
+	  results-master.html"
+
+Fri Sep  3 20:29:59 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c include/libxml/schemasInternals.h
+	  include/libxml/xmlerror.h: Fixed a seg fault in xmlGetQNameProp:
+	  a format argument was missing.
+	  Fixed wrong assignment of the owner of a wildcard in
+	  xmlSchemaBuildAttributeValidation (in the shorthandform of
+	  <complexType>; this caused a seg fault, due to a double-free
+	  of the wildcard.
+	  Added a check for circular attribute group references.
+	  Added a check for circular model group definition references.
+	  Fixed a dublicate xmlParserErrors enum value - see bug #151738.
+
+Fri Sep  3 10:08:13 PDT 2004 William Brack <wbrack@mmmm.com.hk>
+
+	* xmlstring.c: modified comments on xmlGetUTF8Char in
+	  response to bug 151760 (no change to logic)
+
+Tue Aug 31 09:46:18 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlstring.c: fixed error reported on the list caused by
+	  my last change
+
+Tue Aug 31 15:41:52 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in doc/*: release of libxml2-2.6.13
+
+Tue Aug 31 14:14:30 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fixing #151456, an encoding error could generate
+	  a serialization loop.
+
+Tue Aug 31 11:34:04 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: also produce a tar ball with just the sources
+	* xmllint.c: added --path option and --load-trace options to
+	  xmllint, RFE #147740 based on xsltproc versions
+	* doc/xmllint.* doc/*: updated the man page and rebuilt
+
+Tue Aug 31 10:37:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: "" is a valid hexbinary string dixit xmlschema-dev
+	* result/schemas/hexbinary_0_1.err test/schemas/hexbinary_1.xml: 
+	  update the test.
+	* test/ns5 result//ns5*: added a test for the namespace bug fixed
+	  in previous commit.
+	* Makefile.am: added a message in the regression tests
+
+Mon Aug 30 23:36:21 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c: fixed bug introduced during OOM fixup causing problems
+	  with default namespace when a named prefix with the same href
+	  was present (reported on the mailing list by Karl Eichwalder.
+	* xmlstring.c: modified xmlCheckUTF8 with suggested code from
+	  Julius Mittenzwei.
+	* dict.c: added a typecast to try to avoid problem reported by
+	  Pascal Rodes.
+
+Mon Aug 30 12:45:46 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: Fixed a bug in xmlSchemasCheckFacet, which did
+	  not create a computed value on a facet and thus crashed during
+	  validation of instances.
+	  Expanded validity checks for min/maxOccurs attributes.
+	  Expanded validity checks for the value of the attribute "form".
+
+Fri Aug 27 18:32:24 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlstring.c: fixed a problem with xmlCheckUTF8 reported on the
+	  mailing list by Julius Mittenzwei
+
+Fri Aug 27 00:13:39 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: added BuildRequires:  zlib-devel, fixes
+	  Red Hat bug #124942
+
+Thu Aug 26 12:27:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: remove a warning on Solaris
+	* xmlschemastype.c: fix a crashing bug #151111
+
+Wed Aug 25 22:20:18 CEST 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* test/schemas/import-bad-1_0.imp: Added missing test file.
+	* xmlschemas.c include/libxml/xmlerror.h include/libxml/xmlschemas.h:
+	  Substituted the obsolete xmlSchemaValidError(s) for xmlParserErrors
+	  - see #150840. 
+	  Changed the import of schemas to allow failure of location
+	  of a resource to be imported.
+	* result/schemas/all_* result/schemas/any3_0_0.err 
+	  result/schemas/choice_* result/schemas/import1_0_0.err
+	  result/schemas/list0_0_1.err result/schemas/list0_1_0.err
+	  result/schemas/list0_1_1.err result/schemas/ns0_0_2.err
+	  result/schemas/ns0_1_2.err: Adapted regression test results.
+
+Tue Aug 24 20:49:15 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml, xmltutorial.pdf, *.html
+	fix Xpath memory leak (thanks to sKaBoy and William Brack)
+
+Tue Aug 24 21:10:59 CEST 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* parser.c: fixed path problem in DTD loading reported by 
+	  Sameer Abhinkar
+
+Tue Aug 24 16:40:51 CEST 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/configure.js: added support for version extra
+	* win32/Makefile.*: upgraded to zlib 1.2.1
+
+Mon Aug 23 14:33:54 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: removing -O -g from default gcc flags #150828
+
+Sun Aug 22 16:26:46 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* NEWS: preparing 2.6.12 release, updated and
+	  and rebuilt the docs.
+
+Sun Aug 22 16:07:20 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: fix a problem on last commit
+
+Sun Aug 22 15:16:53 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c xpath.c include/libxml/xpath.h 
+	  include/libxml/xpathInternals.h python/libxml.c 
+	  python/libxml_wrap.h: trying to remove some warning when compiling
+	  on Fedora Core 3 and 64bits
+
+Sat Aug 21 0:035:10 CET 2004 Kasimier Buchcik <libxml2-cvs@cazic.net>
+
+	* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
+	  <sequence>, <choice>, <include>, <import>.
+	  Fixed schema defaults (elementFormDefault, etc.) for included
+	  schemas.
+	  Fixed a bug which reported attributes as invalid on
+	  elements declarations with the built-in type 'anyType'.
+	  Added "lax" validation of the content of elements of type
+	  'anyType'.
+	  Fixed: element declarations with the same name were treated
+	  as duplicate if located in the subtree of <choice> -> <sequence>.
+	  (This was bug 150623, submitted by Roland Lezuo)
+	  Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
+	  by Igor Kapitanker. (This was bug 150647, submitted by Igor
+	  Kapitanker)
+	* xmlschemastypes.c: Changed the type of anyType to
+	  XML_SCHEMAS_ANYTYPE.
+	* include/libxml/xmlerror.h: Added schema parser errors.
+	* result/schemas/bug145246_0_0*
+	  result/schemas/extension1_0_2.err: Changed test results.
+	* result/schemas/ct-sc-nobase_0_0*
+	  result/schemas/facet-whiteSpace_0_0*
+	  result/schemas/import1_0_0* result/schemas/import2_0_0*
+	  result/schemas/include2_0_0* result/schemas/include3_0_0*
+	  result/schemas/restriction-attr1_0_0*
+	  result/schemas/seq-dubl-elem1_0_0*
+	  result/schemas/xsd-list-itemType_0_0*: Added new rest results.
+	  test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
+	  test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
+	  test/schemas/import2_0* test/schemas/include2_0*
+	  test/schemas/include3_0* test/schemas/restriction-attr1_0*
+	  test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
+	  test/schemas/xsd-list-itemType_0*: Added new tests and missing
+	  files.  	      
+
+Fri Aug 20 18:51:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in: a bit of cleanup and a extra variable for
+	  CVS dist
+
+Thu Aug 19 07:44:07 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml, xmllint.1, xmllint.html:
+	Edit and rebuild the man pages with Daniel's C14 update
+
+Wed Aug 18 19:15:27 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed missing line numbers on entity as reported
+	  on the list by Steve Cheng
+
+Wed Aug 18 14:04:31 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in globals.c include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h.in: added some code to
+	  include the CVS ChangeLog version in the xmlParserVersion
+	  string (printed by xmllint with --version)
+
+Wed Aug 18 11:14:06 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlschemas.h python/generator.py
+	  python/libxml.c python/libxml_wrap.h python/types.c
+	  python/tests/schema.py python/tests/Makefile.am: Applied patch
+	  from Torkel Lyng to add Schemas support to the Python bindings
+	  and extend the schemas error API, registered a new test.
+	* doc/* elfgcchack.h: rebuilt to regenerate the bindings
+
+Mon Aug 16 14:36:25 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: added help for new set shell command
+	* xinclude.c xmllint.c xmlreader.c include/libxml/parser.h:
+	  added parser option to not generate XInclude start/end nodes,
+	  added a specific option to xmllint to test it fixes #130769
+	* Makefile.am: regression test the new feature
+	* doc/xmllint.1 doc/xmllint.xml: updated man page to document option.
+
+Mon Aug 16 02:42:30 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: small typo pointed out by Mike Hommey
+	* doc/xmllint.xml, xmllint.html, xmllint.1: slightly improved
+	  the --c14n description, c.f. #144675 .
+	* nanohttp.c nanoftp.c: applied a first simple patch from 
+	  Mike Hommey for $no_proxy, c.f. #133470
+	* parserInternals.c include/libxml/parserInternals.h
+	  include/libxml/xmlerror.h: cleanup to avoid 'error' identifier 
+	  in includes #137414
+	* parser.c SAX2.c debugXML.c include/libxml/parser.h:
+	  first version of the inplementation of parsing within
+	  the context of a node in the tree #142359, new function
+	  xmlParseInNodeContext(), added support at the xmllint --shell
+	  level as the "set" function
+	* test/scripts/set* result/scripts/* Makefile.am: extended
+	  the script based regression tests to instrument the new function.
+
+Sat Aug 14 18:53:08 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml, xmllint.html, xmllint.1:
+	add c14n to man page (man, it's hard to keep up with
+	Daniel!)
+
+Sat Aug 14 18:45:38 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml, xmllint.html, xmllint.1:
+	add pattern, walker, maxmem, output and xmlout to man page
+	fixes #144675
+
+Sun Aug 15 00:41:12 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added a --c14n option to canonicalize the output
+	  should close the RFE #143226
+
+Sat Aug 14 23:50:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Dodji pointed out a bug in xmlGetNodePath()
+	* xmlcatalog.c: applied patch from Albert Chin to add a
+	  --no-super-update option to xmlcatalog see #145461
+	  and another patch also from Albert Chin to not crash 
+	  on -sgml --del without args see #145462
+	* Makefile.am: applied another patch from Albert Chin to
+	  fix a problem with diff on Solaris #145511
+	* xmlstring.c: fix xmlCheckUTF8() according to the suggestion
+	  in bug #148115
+	* python/libxml.py: apply fix from Marc-Antoine Parent about
+	  the errors in libxml(2).py on the node wrapper #135547
+
+Sat Aug 14 13:18:57 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: added a dumb rule to able to compile tst.c
+	  when people submit a sample test program
+	* xmlschemas.c: applied small patch from Eric Haszlakiewicz
+	  to document xmlSchemasSetValidErrors() limitations, #141827
+	* error.c: Add information in generic and structured error
+	  setter functions that this need to be done per thread #144308
+	* xmlsave.c: fixed bug whith missing NOTATION(s) serialization
+	  bug #144162
+	* doc/xmllint.xml: typo fix #144840
+
+Tue Aug 10 07:19:31 PDT 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xmlregexp.c xmlschemas.c xmlschemastypes.c
+	  include/libxml/schemasInternals.h include/libxml/xmlerror.h
+	  include/libxml/xmlschemastypes.h: applied Schemas patches
+	  from Kasimier Buchcik
+	* test/ result/ bug141333* annot-err* any[1-4]* bug145246*
+	  element-err* element-minmax-err* include1* restrict-CT-attr-ref*:
+	  lot of new tests for things fixed by the patch
+
+Fri Aug  6 09:22:34 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: fixed my mis-handling of External ID on last
+	  change.
+
+Wed Aug  4 23:40:21 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: changed the parsing of a document's DTD to use
+	  the proper base path (bug 144366)
+
+Wed Aug  4 16:58:08 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am config.h.in configure.in python/Makefile.am:
+	  applied a patch from Gerrit P. Haase to get python bindings
+	  on Cygwin
+
+Tue Aug  3 15:08:22 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/valid.h: elaborated on description of
+	  xmlValidityWarningFunc and xmlValidityErrorFunc (bug
+	  144760)
+	* xmlIO.c, xmlschemastypes.c, include/libxml/schemasinternals.h:
+	  minor fixes to comments for doc rebuilding errors.
+	* doc/*.html: rebuilt the docs
+
+Tue Aug  3 23:59:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/ChangeLog.xsl doc/downloads.html doc/xml.html doc/*:
+	  fixes documentation glitches raised by Oliver Stoeneberg
+
+Tue Aug  3 09:42:31 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: fixed problem with memory leak on text nodes in DTD
+	  (bug 148965) with patch provided by Darrell Kindred
+
+Tue Aug  3 08:14:44 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c: fixed initialisation problem for htmlReadMemory
+	  (bug 149041)
+
+Sat Jul 31 11:01:33 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* doc/buildDocBookCatalog: enhanced per bug 119876.  Further
+	  info posted to the mailing list.
+
+Sat Jul 31 09:12:44 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c, encoding.c, error.c, parser.c, tree.c, uri.c, xmlIO.c,
+	  xmlreader.c, include/libxml/tree.h: many further little changes
+	  for OOM problems.  Now seems to be getting closer to "ok".
+	* testOOM.c: added code to intercept more errors, found more
+	  problems with library. Changed method of flagging / counting
+	  errors intercepted.
+
+Fri Jul 30 13:57:55 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied a couple of patch one from Oliver Stoeneberg
+	  and another one from Rob Richards fixing #148448
+
+Thu Jul 29 13:20:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: 1 line patch, apparently htmlNewDoc() was not
+	  setting doc->charset.
+
+Thu Jul 29 00:05:58 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c, tree.c, uri.c, xmlIO.c, xmlreader.c: further
+	  fixes for out of memory condition, mostly from Olivier
+	  Andrieu.
+	* testOOM.c: some further improvement by Olivier, with
+	  a further small enhancement for easier debugging.
+
+Tue Jul 27 00:34:07 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c, error.c, parser.c, tree.c, xmlreader.c:
+	  implemented patches supplied by Olivier Andrieu 
+	  (bug 148588), plus made some further enhancements, to
+	  correct some problems with out of memory conditions.
+	* testOOM.c: improved with patches from Olivier Andrieu
+
+Mon Jul 26 11:03:18 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: put in patch for Windows buffer re-allocation
+	  submitted by Steve Hay (bug 146697)
+
+Sun Jul 25 17:18:39 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: added some code to check, when an include is
+	  done, whether the requested URL gets mapped to some other
+	  location (e.g. with a catalog entry) and, if so, take care
+	  of the xml:base properly (bug 146988)
+
+Sun Jul 25 14:02:24 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* error.c: fixed to assure user data param is set correctly
+	  when user structured error handler is called (bug 144823)
+
+Thu Jul 22 10:14:48 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlreader.c: fixed problem with reader state after
+	  processing attributes (bug 147993)
+
+Wed Jul 21 17:04:27 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in, Makefile.am: put in an auto* check for the
+	  path to perl (if it exists), and modified make Timingtests
+	  to use that path instead of just executing the dbgenattr.pl
+	  script (bug 148056)
+
+Fri Jul 16 18:36:33 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/generator.py: added a check on the argument for some
+	  classes (e.g. xmlDoc and xmlNode) to prevent a segfault (as
+	  reported on the list).  Further enhancement should be done
+	  to auto-create the appropriate object.
+	* python/libxml.c: minor fix for a warning message; added a
+	  routine, currently not used, to report the description of a
+	  PyCObject.
+	* python/libxml2class.txt: regenerated
+
+Fri Jul 16 11:01:40 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c test/catalogs/white* result/catalogs/white*:
+	  applied patches from Peter Breitenlohner to fix handling
+	  of white space normalization in public ids and add tests
+
+Tue Jul 13 17:24:13 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: applied a small fix from Steve Hay
+
+Tue Jul 13 23:02:19 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: Added code to in PREDICATE/FILTER handling to reset
+	  the xpath context document pointer (part of fix to libxslt
+	  bug 147445)
+
+Tue Jul 13 00:14:08 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/libxml.py: ran 'expand' on the file to get rid of mixture
+	  of tabs and spaces (bug 147424)
+
+Sun Jul 11 22:38:29 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/drv_libxml.py: added an encoding "special comment" to avoid
+	  warning message in python2.3 (bug 146889)
+	* Makefile.am, python/Makefile.am, python/tests/Makefile.am: small
+	  change to make "make tests" a little quieter (MAKEFLAGS+=--silent)
+	* xpath.c: enhanced to take advantage of current libxslt handling
+	  of tmpRVT.  Fixes bug 145547.
+
+Fri Jul  9 14:02:54 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h uri.c: fixed a couple of problems in the new
+	  elfgcchack.h trick pointed by Peter Breitenlohner
+
+Wed Jul  7 00:45:48 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* elfgcchack.h doc/apibuild.py doc/libxml2-api.xml: fixed a bug
+	  which prevented building with --with-minimum
+
+Mon Jul  5 19:43:51 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/*: releasing 2.6.11, updated and regenerated the
+	  docs
+
+Mon Jul  5 18:43:47 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: make the push interfaces synchronous
+	* python/tests/sync.py: added a specific test
+	* python/tests/Makefile.am doc/examples/Makefile.am
+	  doc/examples/index.py: added the new test, cleaning up 
+	  "make tests" output
+
+Mon Jul  5 15:09:17 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Kasimier to fix some Relax-NG
+	  datatype facet problem with recent changes.
+
+Sat Jul  3 11:31:02 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* python/libxml.c: Changed the number of XPath extension functions
+	  allowed to be variable-length (patch supplied by Marc-Antoine
+	  Parent, bug 143805).  Added code to "unregister" the functions
+	  when the parser cleanup takes place.
+
+Fri Jul  2 14:22:14 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c python/libxml.c python/libxml2-python-api.xml:
+	  some updates with memory debugging facilities while messing
+	  with libxslt python bindings
+
+Thu Jul  1 14:53:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/generator.py python/libxml.py
+	  python/libxml2-python-api.xml python/libxml2class.txt:
+	  applied patch from Stéphane Bidoul to fix some Python bindings
+	  initialization, then had to change the parserCleanup() 
+	  to handle memory released there.
+	* xmlmemory.c: added more debugging comments.
+
+Thu Jul  1 13:18:02 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: seems the reader buffer could be used while not
+	  allocated, fixes bug #145218
+
+Thu Jul  1 11:34:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: do not provide functions used as destructor
+	  of classes as public methods to avoid double-free problem like
+	  in bug #145185
+
+Wed Jun 30 19:45:23 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c, xmlschemastypes.c: warning message cleanup.
+	  Now compiles warning-free, all tests passed.
+	* SAX2.c: small change to comments for documentation.
+	  No change to logic.
+
+Tue Jun 29 15:00:13 PDT 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: more fixes with Kasimier, looks far cleaner :-)
+
+Tue Jun 29 23:00:05 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: Kasimier Buchcik fixed the memory access and
+	  allocation problem
+
+Tue Jun 29 19:00:32 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h
+	  include/libxml/schemasInternals.h include/libxml/xmlschemastypes.h:
+	  applied Schemas patches from Kasimier Buchcik, there is still
+	  one open issue about referencing freed memory.
+	* test/schemas/* result/schemas/*: updated with new tests from 
+	  Kasimier
+
+Tue Jun 29 14:52:18 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/globals.h include/libxml/xmlIO.h
+	  doc/libxml2-api.xml doc/libxml2-refs.xml: moved some definitions
+	  to globals.h to avoid some troubles pointed out by Rob Richards
+
+Mon Jun 28 11:25:31 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.m4: applied changes suggested by Mike Hommey, remove
+	  libxml1 support and use CPPFLAGS instead of CFLAGS
+
+Sun Jun 27 14:17:15 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: another, more 'experimental' feature to 
+	  get compiler optimization based on gcc runtime profiling
+
+Sun Jun 27 14:02:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* elfgcchack.h doc/elfgcchack.xsl libxml.h: hack based on Arjan van de
+	  Ven suggestion to reduce ELF footprint and generated code. Based on
+	  aliasing of libraries function to generate direct call instead of
+	  indirect ones
+	* doc/libxml2-api.xml doc/Makefile.am doc/apibuild.py: added automatic
+	  generation of elfgcchack.h based on the API description, extended
+	  the API description to show the conditionals configuration flags
+	  required for symbols.
+	* nanohttp.c parser.c xmlsave.c include/libxml/*.h: lot of cleanup
+	* doc/*: regenerated the docs.
+
+Sun Jun 27 10:02:28 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* regressions.py, regressions.xml: new files for running
+	  regression tests under Python.  Not yet complete, but
+	  should provide good testing under both Linux and Windows.
+	* testHTML.c, testSAX.c, xmllint.c: changed the 'fopen' used
+	  for --push testing to include the 'rb' param when compiled
+	  under Windows.
+
+Fri Jun 25 13:38:57 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c: fixed a problem when base path was "./xxx"
+	* result/XInclude/*: 5 test results changed by above.
+	* Makefile.am: fixed a couple of spots where a new
+	  result file used different flags that the testing one.
+
+Thu Jun 24 16:27:44 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: suppressed warnings from within xmlValidGetValidElements
+	  (bug 144644)
+	* doc/examples/testWriter.c: corrected typo in comment for ISO-8859-1
+	  (bug 144245)
+
+Thu Jun 24 10:17:31 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: implemented bugfix from Massimo Morara for DTD
+	  dumping problem.
+	* test/valid/t10.xml, result/valid/t10.*: added regression
+	  for above
+	* configure.in: small change for my profile settings
+
+Wed Jun 23 20:18:19 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog_man.xml, xmlcatalog.1
+	Docs patch from Ville Skytta, bugzilla #144841
+
+Sat Jun 19 18:34:11 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml, xmllint.html, xmllint.1
+	update man page to reflect William's newly disciplined return
+	code mojo
+
+Thu Jun 17 00:51:55 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/io2.c doc/examples/parse4.c: fixing a couple of
+	  compilation errors when configured with --with-minimum
+
+Wed Jun 16 16:07:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: applied patch from Stefano Debenedetti to register
+	  namespaces in the debug shell
+
+Mon Jun 14 21:56:31 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fix from Steve Ball and update of the comment.
+	* Makefile.am result/errors/*.str: William pointed out that 
+	  the streaming error checking part wasn't streaming, fixing
+
+Mon Jun 14 14:11:52 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: patch from Igor for the default catalog path on Windows
+
+Sat Jun 12 09:03:57 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in: apparently wasn't updated last time
+
+Thu Jun 10 20:57:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in, xmlmemory.c, globals.c: fixed problem when
+	  configuring using --with-thread-alloc
+
+Wed Jun  9 16:31:24 CEST 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/configure.js win32/Makefile.* minor changes for the new
+	  layout of the Windows binary package
+
+Tue Jun  8 19:50:25 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlerror.h: applied another patch
+	  from Kasimier Buchcik for Schema Component Constraints
+	* test/schemas/* result/schemas/*: added the regression tests
+
+Tue Jun  8 21:27:03 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmllint.c: fixed missing error return code for schema
+	  validation (bug 143880), also changed over to an enum for
+	  defining the error return codes for all conditions.
+
+Tue Jun  8 14:01:14 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xmlreader.c include/libxml/parser.h: fixed a serious
+	  problem when substituing entities using the Reader, the entities
+	  content might be freed and if rereferenced would crash
+	* Makefile.am test/* result/*: added a new test case and a new
+	  test operation for the reader with substitution of entities.
+
+Tue Jun  8 12:14:16 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c xmlIO.c include/libxml/globals.h include/libxml/xmlIO.h:
+	  applied patch from Rob Richards for the per thread I/O mappings
+
+Tue Jun  8 09:58:31 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: some further enhancement to take care of
+	  xml:base for XPointer elements (bug 143886).  Also fixed
+	  a problem when xml:base was already specified on an
+	  XInclude'd element.
+
+Mon Jun  7 22:14:58 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: fixed a problem with internal cleanup of <DIV> element
+	  (bug 143738).
+
+Mon Jun  7 16:57:43 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* uri.c, include/libxml/uri.h: added a new routine
+	  xmlBuildRelativeURI needed for enhancement of xinclude.c
+	* xinclude.c: changed handling of xml:base (bug 135864)
+	* result/XInclude/*: results of 5 tests changed as a result
+	  of the above change
+
+Fri Jun  4 11:27:37 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* test/schemas/* result/schemas/*: added a bunch of tests from
+	  Kasimier Buchcik posted on May 11
+
+Thu Jun  3 17:58:25 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: new patch from  Kasimier Buchcik for processContents
+	  of wildcards attribute handling
+	* test/schemas/anyAttr-* result/schemas/anyAttr-*: added specific
+	  regression tests
+
+Thu Jun  3 13:20:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a bug where invalid charrefs may not be detected
+	  sometimes as pointed by Morus Walter.
+	* test/errors/charref1.xm result/errors/charref1.xml*: added the
+	  test in the regression suite.
+
+Thu Jun  3 18:38:27 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: small change to xmlSchemaValidateAttributes,
+	  also corrected typo on error code enum.
+	* include/libxml/xmlerror.h: corrected typo on schema error
+	  code enum
+
+Thu Jun  3 10:12:38 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: minor cosmetic changes, no change to logic.
+	* result/schemas/attruse_0_[12].err: regenerated
+	* globals.c: added a newline at end to make gcc happy
+
+Wed Jun  2 21:16:26 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/schemasInternals.h 
+	  include/libxml/xmlerror.h: applied a patch from Kasimier Buchcik
+	  implementing attribute uses and wildcards.
+	* test/schemas/* result/schemas/*: added/fixed a bunch of tests
+
+Wed Jun  2 18:15:51 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c xmlIO.c include/libxml/globals.h: applied patch from 
+	  Rob Richards for custom I/O BufferCreateFilenane fixes bug
+	  #143366
+
+Wed Jun 02 16:25:32 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with predicate evaluation on an
+	  empty nodeset (bug 143409)
+
+Wed Jun 02 11:26:41 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* testSAX.c: fixed problem with attribute listing (bug 142674)
+	  and added macro LIBXML_TEST_VERSION to assure xmlInitParser
+	  gets called (bug 142686)
+
+Sat May 29 21:35:52 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* test/schemas/date_0.xml xmlschemastypes.c: applied a patch from
+	  Charles Bozeman fixing a side effect in date handling
+
+Thu May 27 19:47:48 MDT 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml fix lack of cast in Xpath example
+	* doc/tutorial/*.html, xmltutorial.pdf rebuild html, pdf
+
+2004-05-25  Aleksey Sanin <aleksey@aleksey.com>
+
+	* c14n.c: fixed c14n bug with serializing attribute namespaces
+
+Mon May 24 08:22:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed to allow '+' in exponent of number
+	  (bug 143005)
+	* SAX2.c: fixed typo in last commit
+
+Sat May 22 09:08:24 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c: skipped call to xmlValidateNCName when compiling
+	  --with-minimum (bug 142917)
+
+Tue May 18 06:48:00 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: reverted the broken change.
+
+Mon May 17 23:07:15 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/*: updated the docs for 2.6.10
+
+Mon May 17 05:52:03 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in : releasing 2.6.10
+
+Sun May 16 23:12:35 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: avoid returning default namespace when searching
+	  from an attribute
+	* entities.c xmlwriter.c: reverse xmlEncodeSpecialChars() behaviour
+	  back to escaping " since the normal serialization routines do not
+	  use it anymore, should close bug #134477 . Tried to make 
+	  the writer avoid it too but it didn't work.
+
+Sun May 16 01:07:16 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/ChangeLog.awk doc/ChangeLog.xsl: fixed escaping
+	  handling and added direct links to bugzilla report for
+	  bug numbers.
+
+Sun May 16 11:11:13 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* error.c: modified to assure proper user data is sent to
+	  structured error routine (bug 142598)
+
+Sun May 16 03:18:52 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: a couple of large static variable which should really
+	  not be declared as such cluttered the .bss section.
+
+Sun May 16 03:06:31 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/ChangeLog.awk: fixed a couple of problems when parsing
+	  libxslt ChangeLog
+
+Sat May 15 20:14:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/ChangeLog.awk doc/ChangeLog.xsl: first steps of a good
+	  ChangeLog page generation. The awk shoudl escape characters
+	  not okay in XML and the xslt should make links to functions
+	  or variables or bug reported in the entries.
+
+Sat May 15 14:57:40 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c include/libxml/xmlsave.h: start adding API for 
+	  escaping customization.
+
+Sat May 15 12:38:17 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: more xmlSave cleanup, optimization and refactoring
+
+Fri May 14 17:51:48 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c xmlsave.c: third pass at the escaping refactoring.
+
+Fri May 14 12:37:24 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: enhanced the enhancement, fixed another couple of
+	  special cases.
+
+Fri May 14 11:48:33 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: small enhancement to dtd handling of (a?)+ (bug 142487)
+
+Thu May 13 23:19:00 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c xmlsave.c include/libxml/xmlIO.h: second pass on escaping
+	  handling, start to looks better, need to be completed and added
+	  directly at the saving context level.
+
+Thu May 13 10:31:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c xmlsave.c include/libxml/xmlIO.h: first pass at refactoring
+	  the escape on save routines for better performances (less malloc)
+	  and more flexibility using the new saving context. Preliminary
+	  work, interface will change.
+
+Wed May 12 22:34:03 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: added code in xmlSchemaBuildAContentModel to handle
+	  element reference within the xs:all construct (bug 139897)
+
+Wed May 12 17:27:18 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: a little further fixing of fallback processing, this
+	  time for fallback with children (bug 139520).
+
+Wed May 12 08:21:33 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: added code in xmlSchemaBuildContentModel to
+	  allow ref in group definition (bug 134411).  Also fixed
+	  misc compilation warning messages.
+	* result/schema/group0_0_0, result/schema/group0_0_0.err:
+	  regenerated (now no error reported).
+
+Tue May 11 11:55:59 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fix to the fix for #141864 from Paul Elseth  
+	* HTMLparser.c result/HTML/doc3.htm: apply fix from David Gatwood for
+	  #141195 about text between comments.
+
+Tue May 11 23:04:47 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c, include/libxml/schemasInternals.h,
+	  include/libxml/xmlerror.h: Applied patches supplied by
+	  Kasimier Buchcik.
+	* test/schemas/po1_0.xml, test/schemas/po1_0.xsd:
+	  changed test to account for above patch.
+
+Tue May 11 09:06:53 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/tests/tstLastError.py: better portability fix for f(*args),
+	  use apply(f, args) as Stéphane Bidoul suggested
+
+Mon May 10 15:49:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: enhanced xmlRegStateAddTrans to check if transition
+	  is already present and, if so, to ignore the request to add it.
+	  This has a very dramatic effect on memory requirements as well
+	  as efficiency.  It also fixes bug 141762.
+
+Sun May  9 20:40:59 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am python/tests/Makefile.am python/tests/tstLastError.py:
+	  applied patch from Ed Davis to allow "make tests" to work
+	  with Python 1.5
+
+Sun May  9 19:46:13 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: apply fix for XHTML1 formating from Nick Wellnhofer
+	  fixes bug #141266
+	* test/xhtmlcomp result//xhtmlcomp*: added the specific regression
+	  test
+
+Sun May  9 14:07:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: fix for a pedantic make check without make all request
+
+Sat May  8 22:56:22 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c xmlIO.c: fixing some problems in URI unescaping
+	  and output buffer opening, this should fix #141864
+
+Fri May  7 22:31:54 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c include/libxml/valid.h: fixes the use of 'list' as a parameter
+	* xmlIO.c include/libxml/xmlIO.h: added xmlPopInputCallback for
+	  Matt Sergeant
+
+Thu May  6 21:14:38 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: enhanced the handling of subexpression ranges
+	  which have a minOccurs of 0 (bug 140478 again); cleaned up
+	  comments throughout the module.
+
+Tue May  4 00:52:16 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: adding a --maxmem option to check memory used.
+
+Sat May  1 01:08:44 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c xmlsave.c python/generator.py python/libxml.c: Fixed
+	  bug #141529 i.e. various problems when building with --without-html
+
+Fri Apr 30 18:12:31 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c xmlreader.c: fixing bug #141384 where the reader didn't
+	  call the deregistering functions. Also added the check to
+	  xmllint --stream --chkregister .
+
+Fri Apr 30 08:57:47 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.msvc: applied a second patch from Mark Vakoc for
+	  regression tests on Windows
+
+Thu Apr 29 21:47:23 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: never commit without running make tests first !
+
+Thu Apr 29 20:15:20 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fix a nasty problem with reading over the end
+	* xmlsave.c: fix a reported memory leak apparently
+
+Thu Apr 29 17:05:00 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.msvc: patch from Mark Vakoc for regression tests
+	  on Windows.
+	* xpath.c: the NaN problem also shows up on Borland
+
+Mon Apr 26 23:37:12 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: enhanced xmlFARegExec range evaluation for min
+	  occurs 0 problems - fixes bug 140478.
+
+Thu Apr 22 09:12:47 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* rngparser.c: tiny path fixes the "xmlConvertCRNGFile" function name
+	  from Kasimier Buchcik
+	* xmlschemas.c: recursive xs:extension fix from taihei goi
+
+Wed Apr 21 00:19:29 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: small buffer resizing improvement from Morten Welinder
+	  closes #140629
+
+Tue Apr 20 23:40:14 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: last version of the fix for MSC version 1200
+
+Tue Apr 20 19:40:37 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: killing the strncmp vs. memcmp controversy and #140593
+
+Tue Apr 20 13:27:06 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/SAX2.h: Kasimier Buchcik pointed out some 
+	  inexistent functions, cleaned them out.
+
+Tue Apr 20 11:42:50 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: Johnson Cameron pointed out that
+	  initGenericErrorDefaultFunc() was really wrong.
+	* xmlreader.c include/libxml/xmlreader.h: xmlTextReaderMode enum
+	  must be made public, added some missing comments on the XMLReader
+	  header.
+	* c14n.c: Alexsey fixed C14N bug with processing namespaces
+	  from attributes
+
+Mon Apr 19 23:27:46 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed a stupid () error + Mark name.
+
+Sun Apr 18 23:45:46 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.6.9 release
+	* doc/* News: updated and rebuilt the docs
+
+Sun Apr 18 22:51:43 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: relaxed id() to not check taht the name(s) passed
+	  are actually NCName, decided this in agreement with Aleksey Sanin
+	  since existing specs like Visa3D broke that conformance checking
+	  and other tools seems to not implement it sigh...
+	* SAX2.c: check attribute decls for xml:id and the value is an
+	  NCName.
+	* test/xmlid/id_err* result/xmlid/id_err*: added error testing
+
+Sun Apr 18 21:46:17 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: work around Microsoft compiler NaN bug raise reported
+	  by Mark Vakoc
+	* xmlschemas.c include/libxml/schemasInternals.h 
+	  include/libxml/xmlerror.h: fixed a recusive extention schemas
+	  compilation error raised by taihei goi
+
+Sun Apr 18 16:57:02 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: keep the ChangeLog compressed 
+	* xmlreader.c: fix a segfault when using Close()
+	* python/tests/Makefile.am python/tests/reader8.py: test for
+	  the Close() reader API.
+
+Sat Apr 17 22:42:13 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c, xmlwriter.c, doc/examples/parse4.c,
+	  doc/examples/io2.c: minor warning cleanup (no change to logic)
+	* xinclude: fixed return value for internal function
+	  xmlXIncludeLoadFallback (now always 0 or -1)
+
+Sat Apr 17 21:32:32 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: small enhancement to fix bug 139791
+
+Fri Apr 16 18:44:47 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/schemasInternals.h
+	  include/libxml/xmlerror.h: applied patches from Kasimier Buchcik
+	  for the attribute use support
+	* test/schemas/attruse* result/schemas/attruse*: added the
+	  tests to the regression suite.
+
+Fri Apr 16 18:22:25 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: move the TODO as comments as the function while not
+	  finished are usable as-is
+	* xmlschemas.c include/libxml/xmlerror.h: patch from Kasimier Buchcik
+	  implementing union
+	* test/schemas/union_0_0.x* result/schemas/union_0_0*: added example
+	* python/Makefile.am: applied fix from Mike Hommey
+
+Fri Apr 16 23:58:42 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed problem with detecting external dtd
+	  encoding (bug 135229).
+	* Makefile.am: minor change to test label
+
+Fri Apr 16 16:09:31 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem causing duplicate fallback
+	  execution (bug 139520)
+	* test/XInclude/docs/fallback2.xml result/XInclude/fallback2.*:
+	  added testcase
+
+Fri Apr  9 23:49:37 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c include/libxml/tree.h: adding xml:id draft support
+	* Makefile.am test/xmlid/id_tst* result/xmlid/id_tst*: adding
+	  4 first regression tests
+
+Fri Apr  9 11:56:08 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: fixing Red Hat bug #120482 , libxml2-python
+	  should depend on the version of python used to compile it.
+
+Mon Apr  5 09:07:24 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied patch from James Bursa, frameset should
+	  close head.
+
+Fri Apr  2 22:02:24 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: fixed problem in xmlRelaxNGCompareNameClasses
+	  which was causing check-relaxng-test-suite.py test 351 to fail.
+
+Fri Apr  2 17:03:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: implemented fix for M$ IIS redirect provided
+	  by Ian Hummel
+	* relaxng.c: fixed problem with notAllowed compilation
+	  (bug 138793)
+
+Thu Apr  1 22:07:52 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fix for xmlUriEscape on "http://user@somewhere.com"
+	  from Mark Vakoc.
+
+2004-04-01  Johan Dahlin  <johan@gnome.org>
+
+	* python/.cvsignore: Add generated files, to make cvs silent.
+
+Thu Apr  1 12:41:36 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: small signed-ness patch from Steve Little
+
+Wed Mar 31 17:47:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: patched a bug in parsing production 1 and 2 of
+	  xmlschemas regexp that William pointed out while working on
+	  #134120
+	* test/regexp/branch result/regexp/branch: added a specific
+	  regression test
+
+Wed Mar 31 09:50:32 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* Makefile.am: added PYTHONPATH to python tests for Schemas
+	  and RelaxNG
+	* test/xsdtest/xsdtestsuite.xml: added testfile for
+	  SchemasPythonTests
+
+Mon Mar 29 16:56:49 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/examples.xsl doc/examples/index.html: added
+	  information about compiling on Unix
+
+Mon Mar 29 14:18:12 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixes the comments for xmlCatalogDump and xmlDumpACatalog
+	* doc/*: rebuilt to update
+
+Sun Mar 28 18:11:41 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: optimize indentation based on the new context
+
+Sun Mar 28 14:17:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/xpath2.c doc/examples/xpath2.res: handle and explain
+	  a very tricky problem when modifying the tree based on an XPath
+	  result query.
+
+Sat Mar 27 09:56:14 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: fixed problem with IS_COMPILABLE flag
+	  (bug 130216)
+
+Fri Mar 26 18:28:32 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Dave Beckett to correct line number
+	  errors when using push with CDATA
+
+Fri Mar 26 14:53:58 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/xpath1.c: added a test template
+	* doc/examples/xpath2.c doc/examples/xpath2.res doc/examples/*:
+	  added a new example, and make valgrind target 
+
+Fri Mar 26 11:47:29 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: apply fix for #136693
+
+Thu Mar 25 20:21:01 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/examples/io2.c
+	* doc/examples/io2.res
+	add xmlDocDumpMemory example in response to mailing list FAQ
+	(rebuilt xml and html also)
+
+Thu Mar 25 10:33:05 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c testXPath.c xmllint.c xmlschemastypes.c: applied
+	  patch from Mark Vakoc avoiding using xmlParse* option and use
+	  xmlRead* instead
+	* win32/Makefile.bcb: patch to Borland C++ builder from Eric Zurcher
+	  to avoid problems with some pathnames.
+
+Tue Mar 23 12:35:08 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* News: preparing 2.6.8 release, updated and rebuilt
+	  the docs.
+	* Makefile.am: use valgring fro the new Python based regression tests
+
+Mon Mar 22 20:07:27 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: remove a memory leak on schemas type facets.
+	* check-relaxng-test-suite.py check-relaxng-test-suite2.py
+	  check-xsddata-test-suite.py: reduce verbosity
+	* configure.in Makefile.am: incorporated the Python regressions
+	  tests for Relax-NG and Schemas Datatype to "make tests"
+
+Mon Mar 22 16:16:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c include/libxml/xmlwriter.h doc/* : applied patch from
+	  Alfred Mickautsch for better DTD support.
+	* SAX2.c HTMLparser.c parser.c xinclude.c xmllint.c xmlreader.c
+	  xmlschemas.c: fixed bug #137867 i.e. fixed properly the way
+	  reference counting is handled in the XML parser which had the
+	  side effect of removing a lot of hazardous cruft added to try
+	  to fix the problems associated as they popped up.
+	* xmlIO.c: FILE * close fixup for stderr/stdout
+
+Sun Mar 21 19:19:41 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: added an error message when an element is not
+	  found within a <choice> (bug 126093)
+
+Sat Mar 20 22:25:18 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: enhanced the logic of parsing char groups to
+	  better handle initial or ending '-' (bug 135972)
+
+Sat Mar 20 19:26:03 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: added check for external reference in 
+	  xmlRelaxNGGetElements (bug 137718)
+	* test/relaxng/rngbug-001.*, result/relaxng/rngbug-001*: added
+	  regression test for above
+
+Wed Mar 17 16:37:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* nanohttp.c: added a close for the local file descriptor
+	  (bug 137474)
+
+Mon Mar 15 15:46:59 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlsave.c: switched the output routines to use the new context.
+
+Mon Mar 15 10:37:18 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* relaxng.c: enhanced to ignore XML_XINCLUDE_START and XML_XINCLUDE_END
+	  nodes (bug 137153)
+
+Sun Mar 14 13:19:20 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: applied patch from John Belmonte for anyURI.
+
+Wed Mar 10 17:22:48 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix bug reported by Holger Rauch
+	* test/att8 result/noent/att8 result/att8 result/att8.rdr
+	  result/att8.sax: added the test to th regression suite
+
+Wed Mar 10 19:42:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* doc/search.php: Minor change for later verson of php requiring
+	  $HTTP_GET_VARS.
+
+Wed Mar 10 00:12:31 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: Changed the flag to xmlDocCopyNode (and similar routines),
+	  previously used only for recursion, to use a value of '2' to
+	  indicate copy properties & namespaces, but not children.
+	* xinclude.c: changed the handling of ranges to use the above new
+	  facility.  Fixes Bug 134268.
+
+Tue Mar  9 18:48:51 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* win32/Makefile.bcb, win32/Makefile.mingw, win32/Makefile.msvc:
+	  added new module xmlsave with patch supplied by Eric Zurcher
+	  (second attempt - don't know what happened to the first one!)
+
+Tue Mar  9 09:59:25 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/libxml.py: applied patch from Anthony Carrico
+	  providing Python bindings for the Canonicalization C14N support.
+
+Mon Mar  8 11:12:23 CET 2004 Hagen Moebius <hagen.moebius@starschiffchen.de>
+
+	* .cvsignore and python/.cvsignore patched
+
+Mon Mar  8 22:33:14 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: enhanced to assure that if xpointer is called
+	  for a document, the XML_PARSE_NOENT flag is set before parsing
+	  the included document so that entities will automatically get
+	  taken care of.
+	* xpointer.c: corrected code so that, if an XML_ENTITY_REF node
+	  is encountered, it will log it and not crash (bug 135713)
+
+Sun Mar  7 19:03:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: modified to make sub-includes inherit the
+	  parse flags from the parent document (bug 132597)
+
+Fri Mar  5 01:13:22 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: QName handling fixes for the XML Schemas
+	  support from Adam Dickmeiss
+	* test/schemas/po1_0.xsd: also fix the schemas
+	* test/schemas/ns[12]* result/schemas/ns[12]*: added the specific
+	  regression tests
+
+Thu Mar  4 23:03:02 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/Makefile.am include/libxml/Makefile.am:
+	  paalied patch from Julio M. Merino Vidal fixing bug #134751
+	  to fix --with-html-dir option.
+	* doc/*: rebuilt fully the docs 
+	* doc/html/libxml-xmlsave.html: new file from new header.
+
+Thu Mar  4 16:57:50 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c testHTML.c tree.c doc/examples/*.c
+	  include/libxml/xmlsave.h: fixing compilation bug with some options
+	  disabled as well as --with-minimum should fix #134695
+
+Thu Mar  4 15:00:45 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c: allow fallback to URI lookup when SYSTEM fails,
+	  should close #134092
+
+Thu Mar  4 14:39:38 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am tree.c xmlsave.c include/libxml/xmlsave.h: commiting
+	  the new xmlsave module before the actuall big code change.
+
+Thu Mar  4 12:38:53 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Adam Dickmeiss for mixed content
+	* test/schemas/mixed* result/schemas/mixed*: added his regression
+	  tests too.
+
+Mon Mar  1 15:22:06 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testSAX.c: fix a compilation problem about a missing timb include
+
+Sat Feb 28 22:35:32 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* testSAX.c: small enhancement to prevent trying to print
+	  strings with null pointers (caused "make tests" errors on
+	  HP-UX)
+
+Thu Feb 26 20:19:40 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml
+	* doc/xmllint.1
+	* doc/xmllint.html
+	* doc/xmlcatalog_man.xml
+	* doc/xmlcatalog.1
+	* doc/xmlcatalog_man.html
+	applying patch from Mike Hommey to clarify XML_CATALOG_FILES
+	use
+
+Thu Feb 26 23:47:43 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: patch for cross-compilation to Windows from
+	  Christophe de VIENNE.
+
+Thu Feb 26 18:52:11 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* doc/*.html, doc/html/*.html: regenerated docs using older
+	  version of xsltproc pending resolution of AVT problem
+
+Thu Feb 26 10:56:29 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: applied patch from Charles Bozeman to not use
+	  the system xmllint.
+
+Wed Feb 25 18:07:05 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlexports.h: applied patch from Roland Schwingel
+	  for MingW
+
+Wed Feb 25 13:57:25 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am catalog.c configure.in: applied a cleanup patch
+	  from Peter Breitenlohner
+	* tree.c: removed a doc build warning by fixing a param comment
+	* doc/* : rebuilt the docs
+
+Wed Feb 25 13:33:07 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c HTMLparser.c: avoid ID error message if using
+	  HTML_PARSE_NOERROR should fix #130762
+
+Wed Feb 25 12:50:53 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c relaxng.c valid.c xinclude.c xmllint.c xmlreader.c:
+	  fixing compilation and link option when configuring with
+	  --without-valid should fix #135309
+
+Wed Feb 25 11:36:06 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixed the main issues reported by Peter Breitenlohner
+	* parser.c: cleanup
+	* valid.c: speedup patch from Petr Pajas
+
+Wed Feb 25 16:07:14 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed a memory leak (xmlXPathLangFunction) reported
+	  on the list by Mike Hommey
+
+Mon Feb 23 17:28:34 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/* NEWS configure.in: preparing 2.6.7 release, updated and
+	  rebuilt the documentation.
+
+Mon Feb 23 11:52:12 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/tests/*.py: applied patch from Malcolm Tredinnick
+	  to avoid tabs in python sources, should fix #135095
+
+Sun Feb 22 23:16:23 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testSAX.c: add --timing option
+	* relaxng.c: use the psvi field of the nodes instead of _private
+	  which may be used for other purposes.
+
+Sat Feb 21 16:57:48 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: small patch to try to fix a warning with Sun One compiler
+
+Sat Feb 21 16:22:35 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: small patch removing a warning with MS compiler.
+
+Sat Feb 21 13:52:30 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: added "relaxng" option to the debugging shell
+	* Makefile.am test/errors/* result/errors/*: some regression tests
+	  for some error tests cases.
+
+Fri Feb 20 09:56:47 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: xmlAttrSerializeTxtContent don't segfault if NULL
+	  is passed.
+	* test/att7 result//att7*: adding an old regression test
+	  laying around on my laptop
+
+Thu Feb 19 17:33:36 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed xmllint --memory --stream memory consumption
+	  on large file by using xmlParserInputBufferCreateStatic() with
+	  the mmap'ed file 
+
+Thu Feb 19 13:56:53 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: some clarification in xmlDocDumpMemory() documentation
+	* xmllint.c: fixed xmllint --stream --timing to get timings back
+
+Wed Feb 18 15:20:42 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a problem in push mode when attribute contains
+	  unescaped '>' characters, fixes bug #134566
+	* test/att6 result//att6*: added the test to the regression suite
+
+Tue Feb 17 17:26:31 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: removing a non-linear behaviour from ID/IDREF raised
+	  by Petr Pajas. Call xmlListAppend instead of xmlListInsert in
+	  xmlAddRef
+
+Tue Feb 17 13:27:27 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/tests/indexes.py python/tests/reader.py: indicated
+	  encoding of the test file, needed for python 2.3
+
+Tue Feb 17 21:08:11 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with numbers having > 19
+	  fractional places (bug 133921)
+
+Tue Feb 17 12:47:20 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied optimization patch from Petr Pajas
+
+Tue Feb 17 12:39:08 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c include/libxml/xmlwriter.h: applied update
+	  from Alfred Mickautsch and the added patch from Lucas Brasilino
+
+Sun Feb 15 12:01:30 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* benchmark.png index.html xml.html: updating the benchmark
+	  graph and using a PNG instead of a GIF
+	* xmlreader.c: updated the TODO
+
+Sat Feb 14 18:55:40 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml
+	* doc/tutorial/xmltutorial.pdf
+	* doc/tutorial/*.html
+	Fix bug in XPath example in the tutorial, thanks to Carlos, whose
+	last name I don't know, for pointing this out
+
+Thu Feb 12 16:28:12 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in: preparing release of 2.6.6
+	* doc/*: updated the docs and rebuilt them
+
+Thu Feb 12 13:41:16 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixing bug #132930 with the provided patch, a bit
+	  suspicious about it but this is fairly contained and regression
+	  tests still passes.
+	* test/schemas/all1* result/schemas/all1*: added the test to
+	  the regression suite.
+
+Thu Feb 12 12:54:26 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #132575 about finding the end of the
+	  internal subset in push mode.
+	* test/intsubset.xml result/intsubset.xml* result/noent/intsubset.xml:
+	  added the test to the regression suite
+
+Wed Feb 11 14:19:31 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c xmlIO.c encoding.c include/libxml/parser.h
+	  include/libxml/xmlIO.h: added xmlByteConsumed() interface
+	* doc/*: updated the benchmark rebuilt the docs
+	* python/tests/Makefile.am python/tests/indexes.py: added a
+	  specific regression test for xmlByteConsumed()
+	* include/libxml/encoding.h rngparser.c tree.c: small cleanups
+
+Wed Feb 11 08:13:58 HKT 2004 William Brack <wbrack@mmm.com.hk
+
+	* tree.c: fixed missing output of internal DTD param entities when
+	  nothing else present in DTD (bug 134052)
+
+Tue Feb 10 19:24:38 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c: applied patch supplied by Christophe Dubach
+	  to fix problem with --with-minimum configuration
+	  (bug 133773)
+	* nanoftp.c: fixed potential buffer overflow problem,
+	  similar to fix just applied to nanohttp.c.
+
+Mon Feb  9 18:40:21 CET 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* nanohttp.c: fixed the fix for the buffer overflow, thanx
+	  William :-)
+
+Mon Feb  9 22:37:14 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* acinclude.m4, configure.in: fixed problem concerning
+	  determining SOCKLEN_T as pointed out by Daniel Richard G.
+	  on the mailing list
+
+Mon Feb  9 15:31:24 CET 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* nanohttp.c: fixed buffer overflow reported by Yuuichi Teranishi
+
+Mon Feb  9 13:45:59 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: small patch from Philip Ludlam to avoid warnings.
+
+Mon Feb  9 13:41:47 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: applied a small patch from Alfred Mickautsch
+	  to avoid an out of bound error in isolat1ToUTF8()
+
+Mon Feb  9 13:35:50 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: remove the warning on the 2001 namespace
+	* parser.c parserInternals.c xpath.c: remove some warnings
+	  when compiling with MSVC6
+	* nanohttp.c: applied a patch when using _WINSOCKAPI_
+
+Sun Feb  8 12:09:55 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: added a small hack to fix interference between
+	  my fixes for bugs 132585 and 132588.
+	* python/libxml.c: fixed problem with serialization of namespace
+	  reported on the mailing list by Anthony Carrico
+
+Sat Feb  7 16:53:11 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem with function xmlXIncludeCopyRange
+	  (bug 133686).
+
+Fri Feb  6 21:03:41 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlwriter.c: fixed problem with return value of
+	  xmlTextWriterWriteIndent() (bug 133297)
+
+Fri Feb  6 19:07:04 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: changed coding to output good XIncludes when
+	  one or more bad ones are present (bug 132588)
+
+Fri Feb  6 17:34:21 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: corrected handling of empty fallback condition
+	  (bug 132585)
+
+Fri Feb  6 15:28:36 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c: added initialisation for ctxt->vctxt
+	  in HTMLInitParser (bug 133127)
+	* valid.c: minor cosmetic change (removed ATTRIBUTE_UNUSED
+	  from several function params)
+
+Tue Feb  3 16:48:57 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem regarding freeing of dictionary
+	  when there are errors within an XInclude file (bug 133106).
+	  Thanks to Oleg Paraschenko for the assistance.
+
+Tue Feb  3 09:53:18 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemastypes.c: fixed validation of maxLength with no
+	  content using patch submitted by Eric Haszlakiewicz
+	  (bug 133259)
+
+Tue Feb  3 09:21:09 CET 2004 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/xmlreader.h include/libxml/xmlmemory.h: added
+	  calling convention to the public function prototypes (rep by
+	  Cameron Johnson)
+	* include/libxml/xmlexports.h: fixed mingw+msys compilation
+	  (rep by Mikhail Grushinskiy)
+
+Mon Feb  2 20:22:18 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlwriter.c: enhanced output indenting (bug 133264)
+
+Mon Feb  2 16:13:33 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlreader.c, include/libxml/xmlreader.h: applied patch from
+	  Steve Ball to provide structured error reports.
+
+Sun Feb  1 01:48:14 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c, include/libxml/tree.h: moved serialization of
+	  attribute text data (xmlSerializeContent) into a separate
+	  routine (xmlSerializeTxtContent) so it can be used by xmlwriter.c
+	* xmlwriter.c: changed handling of attribute string to use the
+	  routine above (fixed bug 131548)
+
+Sat Jan 31 08:22:02 MST 2004 John Fleck <jfleck@inkstain.net
+
+	* doc/examples/reader1.c, reader2.c, reader3.c
+	* doc/examples/examples.xml
+	* doc/examples/*.html
+	add note that reader examples need libmxl2 > 2.6, rebuild
+	html - this time doing it correctly :-)
+
+Fri Jan 30 20:45:36 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/examples/examples.xml
+	* doc/examples/*.html
+	add note that reader examples need libmxl2 > 2.6, rebuild
+	html
+
+Thu Jan 29 23:51:48 PST 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: added (void *) type override to prevent
+	  warning on Solaris (Bug 132671)
+
+Wed Jan 28 07:20:37 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/examples/Makefile.am
+	per Jan. 15 email to the list from oliverst, the index.html
+	file from this directory wasn't making it into the tarball
+
+Mon Jan 26 18:01:00 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* acinclude.m4: applied fix from Alexander Winston for a problem
+	  related to automake-1.8 , c.f. #132513 and #129861
+
+Mon Jan 26 12:53:11 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/index.py: don't rely on . being on the path for
+	  make tests, should keep Mr. Crozat quiet until next time...
+
+Sun Jan 25 21:45:03 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: preparing release 2.6.5, rebuilt the
+	  docs, checked rngparser stuff does not end up in the tarball
+
+Sun Jan 25 20:59:20 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: applied patch from Frederic Peters
+	  fixing the wrong arg order in xpath callback in bug #130980
+
+Sun Jan 25 20:52:09 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixing #130453 XInclude element with no href attribute
+	* relaxng.c rngparser.c include/libxml2/relaxng.h: fully integrating 
+	  the compact syntax will require more work, postponed for the
+	  2.6.5 release.
+
+Sat Jan 24 09:30:22 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/schemasInternals.h xmlschemas.c: applied patch from
+	  Steve Ball to avoid a double-free.
+
+Fri Jan 23 14:03:21 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/*: added io1.c an example ox xmlIO usage and io1.res
+	  test result, fixed a awful lot of memory leaks showing up in
+	  testWriter.c, changed the examples and the Makefiles to test
+	  memory leaks.
+	* xmlwriter.c: fixed a memory leak
+	* Makefile.am: run the doc/examples regression tests as part of
+	  make tests
+	* xpath.c include/libxml/xpath.h: added xmlXPathCtxtCompile() to
+	  compile an XPath expression within a context, currently the goal
+	  is to be able to reuse the XSLT stylesheet dictionnary, but this
+	  opens the door to others possible optimizations.
+	* dict.c include/libxml/dict.h: added xmlDictCreateSub() which allows
+	  to build a new dictionnary based on another read-only dictionnary.
+	  This is needed for XSLT to keep the stylesheet dictionnary read-only
+	  while being able to reuse the strings for the transformation
+	  dictionnary.
+	* xinclude.c: fixed a dictionnar reference counting problem occuring
+	  when document parsing failed.
+	* testSAX.c: adding option --repeat for timing 100times the parsing
+	* doc/* : rebuilt all the docs
+
+Thu Jan 22 14:17:05 2004  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* xmlmemory.c: make xmlReallocLoc() accept NULL pointer
+
+Thu Jan 22 08:26:20 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: applied patch from John Belmonte for
+	  normalizedString datatype support.
+
+Thu Jan 22 10:43:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed problem with union when last() is used
+	  in predicate (bug #131971)
+	* xpointer.c: minor change to comment for doc generation
+
+Wed Jan 21 17:03:17 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #131745 raised by Shaun McCance with the
+	  suggested patch
+
+Wed Jan 21 10:59:55 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied patch from Alfred Mickautsch fixing a memory
+	  leak reported on the list.
+
+Thu Jan 15 00:48:46 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/tests/tstLastError.py: applied
+	  patch from Stéphane Bidoul to add enums to the Python bindings.
+
+Tue Jan 13 21:50:05 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* testHTML.c: another small patch from Mark Vakoc
+
+Tue Jan 13 21:39:58 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c relaxng.c testRelax.c testSchemas.c: applied
+	  patch from Mark Vakoc to not use SAX1 unless necessary.
+
+Mon Jan 12 17:22:57 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c parser.c xmlstring.c: some parser optimizations,
+	  xmllint --memory --timing --repeat --stream ./db10000.xml
+	  went down from 16.5 secs to 15.5 secs.
+
+Thu Jan  8 17:57:50 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: removed a memory leak remaining from the switch
+	  to a dictionnary for string allocations c.f. #130891
+
+Thu Jan  8 17:48:46 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixing some problem if configured --without-xinclude
+	  c.f. #130902
+
+Thu Jan  8 17:42:48 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: changed AC_OUTPUT() macro to avoid a cygwin problem
+	  c.f. #130896
+
+Thu Jan  8 00:36:00 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.bcb win32/Makefile.mingw win32/Makefile.msvc:
+	  applying patch from Mark Vakoc for Windows
+	* doc/catalog.html doc/encoding.html doc/xml.html: applied doc
+	  fixes from Sven Zimmerman
+
+Tue Jan  6 23:51:46 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml2-python-api.xml python/libxml_wrap.h python/types.c
+	  python/tests/Makefile.am python/tests/tstLastError.py: applied 
+	  patch from Stéphane Bidoul for structured error handling from
+	  python, and the associated test
+
+Tue Jan  6 23:18:11 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* configure.in: fixed Bug130593
+	* xmlwriter.c: fixed compilation warning
+
+Tue Jan  6 15:15:23 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlstring.h: fixed the comment in the header
+	* doc/*: rebuilt the docs
+
+Tue Jan  6 19:40:04 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c, parser.c, xmlstring.c, Makefile.am,
+	  include/libxml/Makefile.am, include/libxml/catalog.c,
+	  include/libxml/chvalid.h, include/libxml/encoding.h,
+	  include/libxml/parser.h, include/libxml/relaxng.h,
+	  include/libxml/tree.h, include/libxml/xmlwriter.h,
+	  include/libxml/xmlstring.h:
+	  moved string and UTF8 routines out of parser.c and encoding.c
+	  into a new module xmlstring.c with include file
+	  include/libxml/xmlstring.h mostly using patches from Reid
+	  Spencer.  Since xmlChar now defined in xmlstring.h, several
+	  include files needed to have a #include added for safety.
+	* doc/apibuild.py: added some additional sorting for various
+	  references displayed in the APIxxx.html files.  Rebuilt the
+	  docs, and also added new file for xmlstring module.
+	* configure.in: small addition to help my testing; no effect on
+	  normal usage.
+	* doc/search.php: added $_GET[query] so that persistent globals
+	  can be disabled (for recent versions of PHP)
+
+Mon Jan  5 20:47:07 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/customfo.xsl
+	* doc/tutorial/customhtml.xsl
+	update custom tutorial-building stylesheets in preparation
+	for tutorial update
+
+Tue Jan  6 00:10:33 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* rngparser.c: commiting the compact relax ng parser. It's not
+	  completely finished, it's not integrated but I want to save the
+	  current state
+
+Mon Jan  5 22:22:48 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* doc/apibuild.py, doc/APIconstructors.html, doc/libxml2-refs.xml,
+	  win32/libxml2.def.src: fixed apibuild.py's generation of
+	  "constructors" to be in alphabetical order (instead of previous
+	  random sequence); regenerated resulting files.
+
+Mon Jan  5 14:03:59 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied patch from Lucas Brasilino fixing an indent
+	  problem.
+
+Sun Jan  4 18:54:29 MST 2004 John Fleck <jfleck@inkstain.net>
+
+	* doc/newapi.xsl: change background color of function
+	declaration to improve readability
+	* doc/*: rebuild docs with new stylesheet
+
+Sun Jan  4 22:45:14 HKT 2004 William Brack <wbarck@mmm.com.hk>
+
+	* parser.c, include/libxml/parser.h: added a routine
+	  xmlStrncatNew to create a new string from 2 frags.
+	* tree.c: added code to check if node content is from
+	  dictionary before trying to change or concatenate.
+
+Sun Jan  4 08:57:51 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xmlmemory.c: applied suggestion from Miloslav Trmac (see
+	  Bug 130419) and eliminated xmlInitMemoryDone.  More
+	  improvement needed.
+	* xml2-config.in: added an additional flag (--exec-prefix) to
+	  allow library directory to be different from include directory
+	  (Bug 129558).
+
+Fri Jan  2 21:22:18 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: applied patch from Stéphane Bidoul for structured error
+	  reporting.
+
+Fri Jan  2 21:03:17 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlwriter.h xmlwriter.c: applied the patch from
+	  Lucas Brasilino to add indentation support to xmlWriter
+
+Fri Jan  2 22:58:29 HKT 2004 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem with "recursive" include (fallback
+	  contains another include - Bug 129969)
+
+Fri Jan  2 11:40:06 CET 2004 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: found and fixed a bug misallocating some non
+	  blank text node strings from the dictionnary.
+	* xmlmemory.c: fixed a problem with the memory debug mutex
+	  release.
+
+Wed Dec 31 22:02:37 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xinclude.c: fixed problem caused by wrong dictionary
+	  reference count, reported on the list by Christopher
+	  Grayce.
+
+Wed Dec 31 15:55:55 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* python/generator.py, python/libxml2class.txt: fixed problem
+	  pointed out by Stéphane Bidoul on the list.
+	* xinclude.c, xpointer.c, xpath.c, include/libxml/xpointer.h:
+	  completed modifications required to fix Bug 129967 (at last!).
+	  Now wait to see how long before further trouble...
+
+Tue Dec 30 16:26:13 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c, xmlmemory.c, include/libxml/xmlmemory.h: Fixed
+	  memory leak reported by Dave Beckett
+	* xmlschemas.c: Removed spurious comment reported on the mailing
+	  list
+	* xinclude.c, xpath.c, xpointer.c, libxml/include/xpointer.h:
+	  Further work on Bug 129967 concerning xpointer range handling
+	  and range-to function; much better, but still not complete
+
+Mon Dec 29 18:08:05 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: xmlValidateElement could crash for element holding a 
+	  namespace declaration but not in a namespace. Oliver Fischer 
+	  provided the example.
+
+Mon Dec 29 11:29:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: issue validation status on stderr, not stdout as suggested
+	  by Pawel Palucha
+	* result/relaxng/*: this change slightly all the output from RNG 
+	  regressions.
+
+Mon Dec 28 10:47:32 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: edited a couple of comments in accordance with
+	  posting on the mailing list (no logic change)
+	* xpointer.c: working on Bug 129967, added check for NULL
+	  nodeset to prevent crash.  Further work required.
+	* xpath.c: working on Bug 129967, added code to handle
+	  XPATH_LOCATIONSET in RANGETO code, also added code to
+	  handle it in xmlXPathEvaluatePredicateResult.  Further
+	  work required.
+
+Sat Dec 27 12:32:58 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: added tests for xs:all to assure minOccurs
+	  and maxOccurs <= 1 (Bug 130020)
+
+Sat Dec 27 09:53:06 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: fixed xmlFAParseCharRange for Unicode ranges
+	  with patch from Charles Bozeman.
+
+Fri Dec 26 14:03:41 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlregexp.c: fixed problem causing segfault on validation error
+	  condition (reported on mailing list)
+
+Thu Dec 25 21:16:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlschemas.c: fixed missing dictionaries for Memory and Doc
+	  parser contexts (problem reported on mailing list)
+	* doc/apibuild.py: small change to prevent duplicate lines
+	  on API functions list.  It will take effect the next time
+	  the docs are rebuilt.
+
+Wed Dec 24 12:54:25 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: updated the docs and prepared a new
+	  release 2.6.4
+
+Wed Dec 24 12:07:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* legacy.c: remove deprecated warning on startElement()
+
+Wed Dec 24 12:04:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c result/XInclude/nodes2.*: XInclude xpointer support
+	  was broken with the new namespace. Fixes #129932
+
+Wed Dec 24 00:29:30 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/schemasInternals.h: types might be
+	  redefined in includes, quick fix to allow this but lacks the 
+	  equality of the redefinition test.
+
+Tue Dec 23 15:14:37 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: fixed bug concerning validation using external
+	  dtd of element with mutiple namespace declarations
+	  (Bug 129821)
+
+Tue Dec 23 11:41:42 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: inhibited production of "(null):" in xmlGetNodePath
+	  when node has default namespace (Bug 129710)
+
+Tue Dec 23 09:29:14 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: small enhancement to xmlXPathCmpNodes to assure
+	  document order for attributes is retained (Bug 129331)
+
+Mon Dec 22 19:06:16 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xmlreader.c: change xmlReadFd() xmlCtxtReadFd()
+	  xmlReaderNewFd() xmlReaderForFd(), change those to not close
+	  the file descriptor. Updated the comment, should close #129683
+
+Mon Dec 22 00:34:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixed a serious problem in XInclude #129021
+
+Sun Dec 21 13:59:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed bug #129489, propagation of parsing flags 
+	  in entities.
+	* parser.c xmlreader.c: improved the comments of parsing options
+
+Sun Dec 21 18:14:04 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* python/Makefile.am, python/tests/Makefile.am,
+	  doc/Makefile.am: applied fixes to allow build from
+	  'outside' directory (Bug 129172)
+
+Sat Dec 20 16:42:07 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* tree.c - add explanation of namespace inheritance when
+	ns is NULL to xmlNewChild and xmlNewTextChild API doc
+
+Sat Dec 20 18:17:28 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/xpathInternals.h: undid last change (my
+	  bad).  Put necessary fix in libxslt/libexslt instead.
+	* include/libxml/DOCBparser.h: put test for __GCC__ on
+	  warning directive (Bug 129105)
+
+Sat Dec 20 10:48:37 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/xpathInternals.h: fixed xmlXPathReturnString
+	  to cater for NULL pointer (bug 129561)
+	* globals.c: added comment to suppress documentation warning
+	* doc/apibuild.py: fixed problem which caused last APIchunkxx.html
+	  to be lost.  Rebuilt doc/* (including adding APIchunk26.html)
+
+Fri Dec 19 18:24:02 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: trying to fix #129692 xmlTextReaderExpand() when
+	  using an xmlReaderWalker()
+
+Thu Dec 18 20:10:34 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* tree.c: fix misc. typos in doc comments
+	* include/libxml/tree.h: elaborate on macro define doc comments
+	* doc/*: rebuild docs
+
+Wed Dec 17 16:07:33 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/*: don't call the result files .out but .res as
+	  the Makefiles tend to try generating binaries for .out targets...
+
+Tue Dec 16 20:53:54 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/html/libxml-pattern.html: - cvs add API docs for new
+	pattern stuff
+
+Tue Dec 16 20:40:40 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* tree.c
+	* doc/*:
+	Elaborate in documentation discussion of xmlNewChild
+	and xmlNewTextChild. Thanks to Steve Lenti for pointing
+	out the usefulness of a more explicit explanation of the
+	reserved character escaping issue.
+
+Fri Dec 12 15:55:15 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c: applied patch from Stefan Kost
+
+Thu Dec 11 15:15:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/testWriter.c: applied small fix from Lucas Brasilino
+
+Thu Dec 11 14:55:22 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.* win32/configure.js: Added pattern support
+
+Wed Dec 10 14:11:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* libxml.spec.in: preparing release of
+	  libxml2-2.6.3, updated and regenerated the docs.
+
+Wed Dec 10 11:43:33 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c pattern.c: removed some compilation warnings
+
+Wed Dec 10 11:16:29 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: fixing bug #119264 xmllint failing to report
+	  serialization errors in some cases.
+
+Tue Dec  9 23:50:23 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: fixed an XML entites content serialization 
+	  potentially triggered by XInclude, see #126817
+
+Tue Dec  9 16:12:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied the patch to xmlTextWriterStartPI()
+	  suggested by Daniel Schulman in #128313
+
+Tue Dec  9 15:18:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in Makefile.am: another patch from Kenneth Haley
+	  for Mingw, c.f. #128787
+
+Tue Dec  9 15:07:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlexports.h: applied patch from Kenneth Haley
+	  for compiling on Mingw see #128786
+
+Tue Dec  9 14:52:59 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: some flags were not passed down correctly as
+	  parsing options. Fixes #126806
+
+Tue Dec  9 12:29:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c xmllint.c xmlreader.c include/libxml/xinclude.h
+	  include/libxml/xmlerror.h: augmented the XInclude API
+	  to be able to pass XML parser flags down to the Inclusion
+	  process. Also resynchronized with the Last Call W3C Working
+	  Draft 10 November 2003 for the xpointer attribute.
+	* Makefile.am test/XInclude/docs/nodes[23].xml 
+	  result/XInclude/*: augmented the tests for the new namespace and
+	  testing the xpointer attribute, changed the way error messages
+	  are tested
+	* doc/*: regenerated the documentation
+
+Mon Dec  8 18:38:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: filter warning messages if the global setting blocks them
+	* xinclude.c xmlreader.c include/libxml/xinclude.h
+	  include/libxml/xmlerror.h: updated the change of namespace at
+	  the XInclude level, raise a warning if the old one is found,
+	  and some cleanup
+
+Mon Dec  8 13:09:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: tentative fix for #126117 character reference in
+	  attributes output problem in some cornercase.
+
+Mon Dec  8 11:08:45 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: tried to fix the problems reported in 
+	  bug #126735
+	* xpath.c SAX2.c error.c parser.c valid.c include/libxml/xmlerror.h:
+	  fixed again some problem trying to use the structured error
+	  handlers, c.f. bug #126735
+	* result/VC/ElementValid: tiny change due to the fix
+
+Sun Dec  7 22:27:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c: fixed __xmlRaiseError to use structured error handlers
+	  defined by xmlSetStructuredErrorFunc(), fixes bug #126211
+
+Sun Dec  7 20:30:53 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: attempt to fix #126211 ... 
+
+Fri Dec  5 17:07:29 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xmlreader.c xmllint.c include/libxml/pattern.h
+	  include/libxml/xmlreader.h: fixed the pattern interfaces
+	  but not yet the parser to handle the namespaces.
+	* doc/examples/reader3.c doc/*: fixed the example, rebuilt the docs.
+
+Fri Dec  5 15:49:44 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c xmlwriter.c doc/apibuild.py include/libxml/globals.h 
+	  include/libxml/pattern.h include/libxml/schemasInternals.h
+	  include/libxml/xmlexports.h include/libxml/xmlwriter.h: cleanup
+	  the make rebuild in doc, this include new directive to stop
+	  documentation warnings
+	* doc/* doc/html/*: rebuilt the docs
+	* pattern.c xmlreader.c include/libxml/pattern.h
+	  include/libxml/xmlreader.h: adding xmlTextReaderPreservePattern()
+	  to save nodes while scanning the tree with the reader, cleanup
+	  the way element were freed, and xmlTextReaderPreserve()
+	  implementation, the API might change for namespace binding support
+	  when compiling patterns.
+	* doc/examples/*: added reader3.c exposing the xmlTextReaderPreserve()
+
+Thu Dec  4 15:10:57 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: oops forgot to modify/commit the new code.
+
+Thu Dec  4 13:29:19 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml_wrap.h:
+	  cleanup the output buffer support to at least get the basic
+	  to work
+	* python/tests/outbuf.py python/tests/serialize.py: fixes and
+	  cleanup.
+	* include/libxml/xmlwriter.h: cleanup
+
+Wed Dec  3 21:38:56 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* include/libxml/xmlversion.h.in
+	* doc/*: add WITH_TRIO comment so it shows up in the docs, rebuild
+	  docs
+
+Wed Dec  3 13:10:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in xmlregexp.c: fix bug #128401 affecting
+	  regexp quantifiers
+
+Tue Dec  2 23:29:56 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c include/libxml/pattern.h: adding the pattern node
+	  selection code. Inheried in part from libxslt but smaller.
+	* Makefile.am configure.in include/libxml/xmlversion.h.in:
+	  integrated the pattern module, made it a configure time option
+	* xmllint.c: added --pattern to test when doing --stream
+
+Tue Dec  2 11:25:25 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed a problem in xmlreader validation when
+	  streaming exposed by reader2 example.
+
+Mon Dec  1 20:40:51 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xml.html
+	* doc/docs.html:
+	add reference to the Code Examples page to docs.html list
+	of resources
+
+Mon Dec  1 12:30:28 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.bcb win32/configure.js: Applied the BCB patch
+	  from Eric
+
+Sun Nov 30 21:33:37 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* include/libxml/xinclude.h
+	* doc/*: Add comments for macro definitions in xinclude.h and
+	rebuild the docs
+
+Sun Nov 30 21:06:29 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/docdescr.doc
+	Updating William's explanation of how to build docs, 
+	reflecting Daniel's new docs build system
+
+Sat Nov 29 18:38:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlmemory.c: enhanced by adding mutex to protect global
+	  structures in a multi-threading environment.  This fixed
+	  some random errors on the Threads regression tests.
+
+Fri Nov 28 21:39:49 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xml.html doc/python.html: fix tst.py text, which didn't
+	  import sys
+
+Fri Nov 28 17:28:47 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c, include/libxml/encoding.h: Enhanced the handling of
+	  UTF-16, UTF-16LE and UTF-16BE encodings.  Now UTF-16 output is
+	  handled internally by default, with proper BOM and UTF-16LE
+	  encoding.  Native UTF-16LE and UTF-16BE encoding will not generate
+	  BOM on output, and will be automatically recognized on input.
+	* test/utf16lebom.xml, test/utf16bebom.xml, result/utf16?ebom*:
+	  added regression tests for above.
+
+Thu Nov 27 19:25:10 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.* win32/configure.js: Modified to allow coexistent 
+	  build with all compilers. Added C-Runtime option for MSVC. Included
+	  xmlWriter.
+	* xmlwriter.c: Added IN_LIBXML macro
+
+Wed Nov 26 21:54:01 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.bcb: applied patch from Eric
+
+Wed Nov 26 21:33:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h: stefan on IRC pointed out that XML_GET_LINE
+	  is broken on 2.6.x
+
+Tue Nov 25 18:39:44 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: fixed #127877, never output &quot; in element content
+	* result/isolat3 result/slashdot16.xml result/noent/isolat3
+	  result/noent/slashdot16.xml result/valid/REC-xml-19980210.xml
+	  result/valid/index.xml result/valid/xlink.xml: this changes the
+	  output of a few tests
+
+Tue Nov 25 16:36:21 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/schemasInternals.h include/libxml/xmlerror.h
+	  testSchemas.c xmlschemas.c: added xsd:include support, fixed
+	  testSchemas behaviour when a schemas failed to parse.
+	* test/schemas/vdv-* result/schemas/vdv-first5_0_0*: added one
+	  test for xsd:include from Eric Van der Vlist
+
+Tue Nov 25 08:18:12 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: swapped the attribute defaulting and attribute checking
+	  parts of parsing a new element start, fixes bug #127772
+	* result/valid/127772.* test/valid/127772.xml
+	  test/valid/dtds/127772.dtd: added the example in the regression tests
+
+Tue Nov 25 08:00:15 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: moved xmlCleanupThreads() to the end of xmlCleanupParser()
+	  to avoid bug #127851
+
+Mon Nov 24 15:26:21 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixing some Negative Character Group and
+	  Character Class Subtraction handling.
+
+Mon Nov 24 14:01:57 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c: more XML Schemas fixes based
+	  on Eric van der Vlist examples
+	* result/schemas/vdv-first4* test/schemas/vdv-first4*:
+	  added regression tests
+	* doc/examples/Makefile.am doc/examples/index.py: do not
+	  regenerate the index on make all target, but only on
+	  make rebuild to avoid troubles.
+
+Sat Nov 22 21:35:42 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h
+	  include/libxml/schemasInternals.h: lot of bug fixes, cleanup,
+	  starting to add proper namespace support too.
+	* test/schemas/* result/schemas/*: added a number of tests
+	  fixed the result from some regression tests too.
+
+Fri Nov 21 20:50:59 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xml.html, docs.html: remove reference to gtk-doc now that
+	Daniel has removed it, fix link to George's IBM article, other
+	minor edits
+
+Fri Nov 21 01:26:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: applied patch from Robert Stepanek to start 
+	  import os schemas support, cleaned up stuff and the patch.
+	* test/schemas/import0_0.* result/schemas/import0_0_0*: added test
+	  to regression, fixed a few regressions too.
+
+Thu Nov 20 22:58:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied two parsing fixes from James Bursa
+
+Thu Nov 20 19:20:46 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/*: added two xmlReader examples
+	* xmlreader.c: cleaned up some bugs in the process
+
+Thu Nov 20 12:54:30 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c include/libxml/xmlwriter.h: applied patch from
+	  Alfred Mickautsch, bugfixes and comments
+	* doc/examples/*: added his test as the xmlWriter example
+	* doc/html/ doc/*.html: this resulted in some improvements
+	* include/libxml/hash.h: fixed an inclusion problem when
+	  <libxml/hash.h> wasn't preceeded by <xml/parser.h>
+
+Wed Nov 19 17:19:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fix an error message
+	* doc/examples/*: added tree2 example from Lucas Brasilino
+
+Wed Nov 19 17:50:47 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/newapi.xsl: improve the sort sequence for page content
+	* doc/html/*.html: regenerate the web pages
+
+Wed Nov 19 00:48:56 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: do not package cvs versioning temp files.
+	* doc/apibuild.py doc/libxml2-api.xml doc/newapi.xsl: more cleanup,
+	  slightly improved the API xml format, fixed a lot of small
+	  rendering problems
+	* doc/html/libxml*.html: rebuilt
+
+Tue Nov 18 21:51:15 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/*.h include/libxml/*.h.in: modified the file
+	  header to add more informations, painful...
+	* genChRanges.py genUnicode.py: updated to generate said changes
+	  in headers
+	* doc/apibuild.py: extract headers, add them to libxml2-api.xml
+	* *.html *.xsl *.xml: updated the stylesheets to flag geprecated
+	  APIs modules. Updated the stylesheets, some cleanups, regenerated
+	* doc/html/*.html: regenerated added back book1 and libxml-lib.html
+
+Tue Nov 18 14:43:16 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am doc/*.xsl doc/*.html doc/apibuild.py: cleaned up
+	  the build process to remove all remains from the old gtk-doc
+	  inherited, libxml2-refs.xml is now generated by apibuild.py, the
+	  stylesheets have been improved, and the API*html now generated
+	  are XHTML1 valid too
+
+Tue Nov 18 14:28:32 HKT 2003 William Brack <mmm.com.hk>
+
+	* genChRanges.py, chvalid.c, include/libxml/chvalid.h: minor
+	  enhancement to prevent comment with unreferenced variable.
+	* threads.c xmlreader.c xmlwriter.c: edited some comments to
+	  improve auto-generation of documentation
+	* apibuild.py: minor change to an error message
+
+Mon Nov 17 17:55:51 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/apibuild.py doc/libxml2-api.xml doc/newapi.xsl: more cleanup,
+	  improving navigation
+	* doc/html/*.html: updated the result
+
+Mon Nov 17 14:54:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml doc/newapi.xsl:
+	  improvement of the stylesheets, fixed a API generation problem,
+	  switched the stylesheet and Makefile to build the HTML output.
+	* doc/html/*.html: complete update, ditched some old files, might
+	  introduce some breakage...
+
+Mon Nov 17 12:50:28 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/newapi.xsl: lot of improvements, this starts looking good
+	  enough to be usable.
+
+Mon Nov 17 00:58:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/newapi.xsl: stylesheet to build HTML pages from the
+	  API XML description, Work in Progress
+
+Sun Nov 16 16:03:24 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed bug 126976 (string != empty nodeset
+	  should be false)
+
+Sun Nov 16 14:00:08 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/html/*.html: Finally - found the problem with the
+	  page generation (XMLPUBFUN not recognized by gtkdoc).
+	  Re-created the pages using a temporary version of
+	  include/libxml/*.h.
+	* testOOMlib.c,include/libxml/encoding.h,
+	  include/libxml/schemasInternals.h,include/libxml/valid.h,
+	  include/libxml/xlink.h,include/libxml/xmlwin32version.h,
+	  include/libxml/xmlwin32version.h.in,
+	  include/libxml/xpathInternals.h: minor edit of comments
+	  to help automatic documentation generation
+	* doc/docdescr.doc: small elaboration
+	* doc/examples/test1.c,doc/examples/Makefile.am: re-commit
+	  (messed up on last try)
+	* xmlreader.c: minor change to clear warning.
+
+Sat Nov 15 19:20:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Copyright: fixed some wording
+	* libxml.spec.in: make sure doc/examples is packaged
+	* include/libxml/tree.h valid.c xmlreader.c: fixed the really
+	  annoying problem about xmlRemoveID and xmlReader streaming.
+	  Thing looks fixed now, had to add a doc reference to the
+	  xmlID structure though...
+
+Sat Nov 15 09:53:36 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/docdescr.doc: added description of man page building
+
+Sat Nov 15 19:08:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/html/libxml-chvalid.html, doc/html/libxml-dict.html,
+	  doc/html/libxml-list.html, doc/html/libxml-testOOMlib.html,
+	  doc/html/libxml-wincecompat, doc/html/winsockcompat.html,
+	  doc/html/libxml-xmlexports.html, doc/html/libxml-xmlversion.html,
+	  doc/html/libxml-xmlwin32version.html, doc/html/libxml-xmlwriter.html:
+	  added missing pages for the website.
+
+Sat Nov 15 18:23:48 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/Makefile.am doc/*.html doc/html/*.html: rebuilt the
+	  generated pages (again), manually restored doc/html/index.html
+	  and manually edited generated file doc/gnome-xml.xml to put
+	  in appropriate headings.
+	* doc/docdescr.doc: new file to describe details of the
+	  document generation (helps my memory for the next time)
+	* genChRanges.py,chvalid.c,include/libxml/chvalid.h: minor
+	  enhancement to please the automatic documentation generation.
+
+Fri Nov 14 23:47:31 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* catalog.c,relaxng.c,testAutomata.c,xpointer.c,genChRanges.py,
+	  chvalid.c,include/libxml/chvalid.h,doc/examples/test1.c:
+	  minor error cleanup for gcc-3.3.[12] compilation warnings.
+
+Fri Nov 14 15:08:13 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* tree.c: minor changes to some comments
+	* doc/*.html: rebuilt the generated HTML pages for changes
+	  from jfleck (bug 126945)
+
+Thu Nov 13 12:44:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/*: added Dodji's example, added output handling
+
+Thu Nov 13 11:35:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/examples/*: added Aleksey XPath example, fixed bugs
+	  in the indexer
+
+Wed Nov 12 23:48:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*: integrating the examples in the navigation menus
+	* doc/examples/*: added make tests, updated the navigation,
+	  added a new test, cleanups, updates.
+
+Wed Nov 12 17:50:36 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*.html: rebuilt the generated HTML pages
+	* doc/examples/*: updated the stylesheets, added a synopsis,
+	  Makefile.am is now generated by index.py
+
+Wed Nov 12 01:38:16 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/site.xsl doc/examples/Makefile.am doc/examples/index.html:
+	  added autogeneration of a web page for the examples
+	* doc/examples/example1.c doc/examples/.cvsignore
+	  doc/examples/examples.xml doc/examples/index.py: updated the
+	  informations extracted, improved the format and indexing.
+
+Tue Nov 11 22:08:59 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xinclude-test-suite.py: less verbose on difference
+	* libxml.spec.in: cleanup
+	* parser.c: fixed xmlCleanupParser() doc
+	* doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml
+	  doc/examples/Makefile.am doc/examples/example1.c 
+	  doc/examples/examples.xml doc/examples/index.py
+	  doc/examples/test1.xml: work on adding C examples and
+	  generating automated information about those. examples.xml
+	  is autogenerated describing the examples.
+	* example/Makefile.am: cleanup
+
+Mon Nov 10 23:47:03 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genUnicode.py, xmlunicode.c, include/libxml/xmlunicode.h:
+	  fixed missing '-' in block names, enhanced the hack for
+	  ABI aliasing.
+
+Sun Nov  9 20:28:21 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genUnicode.py, xmlunicode.c, include/libxml/xmlunicode.h,
+	  python/libxml2class.txt: enhanced for range checking,
+	  updated to Unicode version 4.0.1 (API docs also updated)
+	* python/generator.py: minor change to fix a warning
+
+Wed Nov  5 23:46:36 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: apply fix from Karl Eichwalder for script path
+
+Wed Nov  5 10:49:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/configure.js: applied patch from Mark Vakoc to simplify
+	  his work from CVS checkouts.
+
+Tue Nov  4 21:16:47 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlreader.html: minor cleanups
+
+Tue Nov  4 15:52:28 PST 2003 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/xmlversion.h.in: changed macro ATTRIBUTE_UNUSED
+	  for gcc so that, if undefined, it's defined as
+	  __attribute__((unused))
+
+Tue Nov  4 15:28:07 PST 2003 William Brack <wbrack@mmm.com.hk>
+
+	* python/generator.py: small enhancement to assure ATTRIBUTE_UNUSED
+	  appears after the variable declaration.
+	* valid.c: trivial change to eliminate a warning message
+
+Tue Nov  4 11:24:04 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: preparing release 2.6.2, updated and
+	  rebuilt the docs
+
+Tue Nov  4 09:38:46 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: change --html to make sure we use the HTML serialization
+	  rule by default when HTML parser is used, add --xmlout to allow to
+	  force the XML serializer on HTML.
+	* HTMLtree.c: ugly tweak to fix the output on <p> element and 
+	  solve #125093
+	* result/HTML/*: this changes the output of some tests
+
+Mon Nov  3 17:51:28 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixed bug #125812, about XPointer in XInclude 
+	  failing but not returning an error.
+
+Mon Nov  3 17:18:22 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed bug #125811 related to DTD post validation
+	  where the DTD doesn't pertain to a document.
+
+Mon Nov  3 15:25:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xmlIO.c include/libxml/parserInternals.h: implemented
+	  the XML_PARSE_NONET parser option.
+	* xmllint.c: converted xmllint.c to use the option instead of 
+	  relying on the global resolver variable.
+
+Mon Nov  3 13:26:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c xmlreader.c include/libxml/xinclude.h: adding XInclude
+	  support to the reader interface. Lot of testing of the walker,
+	  various bug fixes.
+	* xmllint.c: added --walker and made sure --xinclude --stream --debug
+	  works as expected
+	* Makefile.am result/dtd11.rdr result/ent6.rdr test/dtd11 test/ent6
+	  result/XInclude/*.rdr: added regression tests for the walker and
+	  XInclude xmlReader support, had to slightly change a couple of tests
+	  because the walker can't distinguish <foo/> from <foo></foo>
+
+Sat Nov  1 17:42:27 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c nanohttp.c threads.c: second BeOS patch from 
+	  Marcin 'Shard' Konicki
+
+Fri Oct 31 15:35:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: always generate line numbers
+
+Fri Oct 31 11:53:46 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed another regression introduced in fixing #125823
+
+Fri Oct 31 11:33:18 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: previous fix for #124044 was broken, correct
+	  fix provided.
+	* HTMLparser.c parser.c parserInternals.c xmlIO.c: fix xmlStopParser()
+	  and the error handlers to address #125877
+
+Thu Oct 30 23:10:46 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: side effect of #123105 patch, namespace resolution
+	  would fail when defined in internal entities, fixes #125823
+
+Thu Oct 30 14:10:42 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: be more defensive in the xmlReader python bindings
+	  fixing bug #124044
+
+Thu Oct 30 11:14:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: the a-posteriori DTD validation code was not validating
+	  the namespace declarations, this fixes #124110
+
+Wed Oct 29 14:13:03 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlIO.c: enhanced to bypass compression detection code
+	  when input file is stdin (bug 125801)
+
+Wed Oct 29 18:21:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fix needed when HTTP is not compiled in by Mark Vakoc
+
+Wed Oct 29 18:05:53 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: more fixes about unregistering objects
+	* include/libxml/relaxng.h: applied patch from Mark Vakoc
+	  missing _cplusplus processing clause
+
+Wed Oct 29 07:49:52 2003  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* include/libxml/parser.h parser.c: added xmlStrVPrintf function
+
+Wed Oct 29 14:37:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c testThreads.c threads.c: applied patch from
+	  Marcin 'Shard' Konicki to provide BeOS thread support.
+
+Wed Oct 29 14:20:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: applied patch
+	  from Steve Ball to make a schema parser from a preparsed document.
+
+Wed Oct 29 13:52:25 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied a couple of patches from Mark Lilback about text
+	  nodes coalescing
+
+Wed Oct 29 12:16:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: change suggested by Anthony Carrico when unregistering
+	  a namespace prefix to a context
+	* hash.c: be more careful about calling callbacks with NULL payloads.
+
+Wed Oct 29 00:04:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/*: preparing release 2.6.1, updated and
+	  regenerated docs and APIs
+	* parser.c: cleanup and last change to fix #123105
+
+Tue Oct 28 23:02:29 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: Fix #124907 by simply backporting the same
+	  fix as for the XML parser
+	* result/HTML/doc3.htm.err: change to ID detecting modified one
+	  test result.
+
+Tue Oct 28 22:28:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parser.h: included a new function
+	  to reuse a Push parser context, based on Graham Bennett original
+	  code
+	* valid.c: in HTML, a name in an input is not an ID
+	* TODO: bug list update
+
+Tue Oct 28 19:54:37 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied patch from nico@xtradyne.com for #125030
+
+Tue Oct 28 16:42:16 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: cleanup
+	* error.c valid.c include/libxml/xmlerror.h: fixing bug #125653
+	  sometimes the error handlers can get a parser context on DTD
+	  errors, and sometime they don't. So be very careful when trying
+	  to grab those informations.
+
+Tue Oct 28 15:26:18 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch from Kasimier Buchcik which fixes a 
+	  problem in xmlSearchNs introduced in 2.6.0
+
+Tue Oct 28 14:57:03 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed #123263, the encoding is mandatory in a textdecl.
+
+Tue Oct 28 13:48:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix bug #125047 about serializing when finding a 
+	  document fragment node.
+
+Mon Oct 27 11:11:29 EST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* testSAX.c: fix bug #125592 need a NULL check
+	* include/libxml/chvalid.h: rename a parameter
+
+Mon Oct 27 09:43:48 EST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from #123105 about defaulted attributes
+	  from element coming from an entity
+
+Mon Oct 27 21:12:27 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmllint.c: fixed warning message from IRIX (bug 125182)
+	* python/libxml.py: removed tabs, replaced with spaces
+	  (bug 125572)
+
+Mon Oct 27 06:17:30 EST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h parserInternals.c xmlIO.c: make sure we report errors
+	  if xmlNewInputFromFile() fails.
+	* xmlreader.c: avoid using _private for the node or document
+	  elements.
+
+Sat Oct 25 17:33:59 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/configure.js: added declaration for verMicroSuffix
+
+Fri Oct 24 23:08:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.m4: applied patch from Patrick Welche provided in
+	  bug #125432 , future proofing the .m4 file.
+	* parser.c: resetting the context should also reset the error
+	* TODO: problem of conformance w.r.t. E20 was raised in the
+	  XML Core telconf and libxml2 isn't conformant there.
+
+Wed Oct 22 14:33:05 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlwriter.c: applied patch from Alfred Mickautsch fixing #125180
+
+Wed Oct 22 10:50:31 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* chvalid.c genChRanges.py: Stéphane Bidoul pointed out another
+	  small glitch missing a const
+
+Wed Oct 22 10:43:21 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* chvalid.c genChRanges.py: Stéphane Bidoul pointed out that
+	  it doesn't define IN_LIBXML
+
+Tue Oct 21 21:14:55 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.mingw: typo pointed out by Stéphane Bidoul
+
+Tue Oct 21 11:26:36 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.bcb win32/Makefile.mingw win32/Makefile.msvc
+	  win32/configure.js: set of Win32 patches for 2.6.0 by Joachim Bauch
+
+Tue Oct 21 02:07:22 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: last minute patch from Eric Zurcher making it into 2.6.0
+
+Tue Oct 21 02:03:03 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS doc/libxml2.xsa: preparing libxml2-2.6.0
+	* doc/*: updated and regenerated the docs and API
+
+Tue Oct 21 01:01:55 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c error.c tree.c: moved the line number to their proper
+	  field in elements now.
+
+Tue Oct 21 00:28:20 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xmlwriter.c Makefile.am include/libxml/xmlwriter.h
+	  include/libxml/Makefile.am include/libxml/xmlversion.h.in:
+	  added the xmlWriter module contributed by Alfred Mickautsch
+	* include/libxml/tree.h: added room for line and extra information
+	* xmlreader.c python/tests/reader6.py: bugfixing some problem some
+	  of them introduced in September
+	* win32/libxml2.def.src doc/libxml2-api.xml: regenerated the API
+
+Mon Oct 20 19:02:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in xmldwalk.c xmlreader.c
+	  include/libxml/Makefile.am include/libxml/xmldwalk.h
+	  include/libxml/xmlversion.h.in: removing xmldwalk module
+	  since it got merged with the xmlreader.
+	* parser.c: cleanup
+	* win32/libxml2.def.src python/libxml2class.txt doc/libxml2-api.xml:
+	  rebuilt the API
+	* python/tests/Makefile.am python/tests/reader7.py
+	  python/tests/walker.py: adding regression testing for the
+	  new xmlreader APIs, new APIs for reader creation, including
+	  makeing reader "walker" operating on preparsed document trees.
+
+Sun Oct 20 22:37:03 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* entities.c, valid.c: fixed problem reported on the mailing
+	  list by Melvyn Sopacua - wrong argument order on functions
+	  called through xmlHashScan.
+
+Sun Oct 19 23:57:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c xmlIO.c: fixes for compiling using --with-minimum
+
+Sun Oct 19 23:46:04 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: cleanup xmlNodeGetContent() reusing xmlNodeBufGetContent(),
+	  tested it through the xslt regression suite.
+
+Sun Oct 19 22:42:16 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c include/libxml/tree.h: adding xmlNodeBufGetContent()
+	  allowing to grab the content without forcing allocations.
+	* python/libxml2class.txt doc/libxml2-api.xml: rebuilt the API
+	* xpath.c xmldwalk.c: removed a couple of comment errors.
+
+Sun Oct 19 16:39:36 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch from Chris Anderson to change back
+	  memcmp with CMPx()
+
+Sun Oct 19 16:24:19 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed to not send NULL to %s printing
+	* python/tests/error.py result/HTML/doc3.htm.err
+	  result/HTML/test3.html.err result/HTML/wired.html.err
+	  result/valid/t8.xml.err result/valid/t8a.xml.err: cleaning
+	  up some of the regression tests error
+
+Sun Oct 19 15:31:43 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/nanohttp.h include/libxml/parserInternals.h 
+	  include/libxml/xmlIO.h nanohttp.c parserInternals.c xmlIO.c:
+	  Fixed the HTTP<->parser interraction, which should fix 2 long
+	  standing bugs #104790 and #124054 , this also fix the fact that
+	  HTTP error code (> 400) should not generate data, we usually
+	  don't want to parse the HTML error information instead of the
+	  resource looked at.
+
+Sun Oct 19 19:20:48 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/Makefile.am: enhanced the installation of tutorial files
+	  to avoid installing CVS subdirectories (bug 122943)
+
+Sun Oct 19 17:33:27 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlIO.c: fixed segfault when input file not present
+	* tree.c: changed output formatting of XML_CDATA_SECTION
+	  (bug 120917)
+
+Sun Oct 19 00:15:38 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* include/libxml/parserInternals.h HTMLparser.c HTMLtree.c
+	  SAX2.c catalog.c debugXML.c entities.c parser.c relaxng.c
+	  testSAX.c tree.c valid.c xmlschemas.c xmlschemastypes.c
+	  xpath.c: Changed all (?) occurences where validation macros
+	  (IS_xxx) had single-byte arguments to use IS_xxx_CH instead
+	  (e.g. IS_BLANK changed to IS_BLANK_CH).  This gets rid of
+	  many warning messages on certain platforms, and also high-
+	  lights places in the library which may need to be enhanced
+	  for proper UTF8 handling.
+
+Sat Oct 18 20:34:18 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genChRanges.py, chvalid.c, include/libxml/chvalid.h,
+	  doc/apibuild.py: enhanced to include enough comments to
+	  make the api doc generation happy.
+
+Sat Oct 18 07:28:25 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c xmlIO.c include/libxml/nanohttp.h: starting work
+	  to fix the HTTP/XML parser integration.
+
+Sat Oct 18 11:04:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h: added new APIs
+	  for creating reader from sources or reusing a reader with
+	  a new source, like the xmlReadxx and xmlCtxtReadxxx
+	* win32/libxml2.def.src doc/libxml2-api.xml doc/apibuild.py
+	  doc/Makefile.am: regenerated the APIs
+	* doc/xml.html: applied a patch from Stefan Kost for namesapce docs
+
+Sat Oct 18 12:46:02 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genChRanges.py, chvalid.c, include/libxml/chvalid.h,
+	  include/libxml/parserInternals.h: enhanced macros to avoid
+	  breaking ABI from previous versions.
+	* catalog.c, parser.c, tree.c: modified to use IS_* macros
+	  defined in parserInternals.h.  Makes maintenance much easier.
+	* testHTML.c, testSAX.c, python/libxml.c: minor fixes to avoid
+	  compilation warnings
+	* configuration.in: fixed pushHTML test error; enhanced for
+	  better devel (me) testing
+
+Fri Oct 17 14:38:54 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* legacy.c: remove the warning for startDocument(), as it is used by
+	  glade (or glade-python)
+	* parser.c relaxng.c xmlschemastypes.c: fixed an assorted set of
+	  invalid accesses found by running some Python based regression
+	  tests under valgrind. There is still a few leaks reported by the
+	  relaxng regressions which need some attention.
+	* doc/Makefile.am: fixed a make install problem c.f. #124539
+	* include/libxml/parserInternals.h: addition of xmlParserMaxDepth
+	  patch from crutcher
+
+Wed Oct 15 12:47:33 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Marc Liyanage pointed out that xmlCleanupParser()
+	  was missing xmlCleanupInputCallbacks and xmlCleanupOutputCallbacks
+	  calls.
+
+Wed Oct 15 10:16:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* vms/build_libxml.com trionan.c: VMS patch from Craig A. Berry
+
+Mon Oct 13 21:46:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: small fix from Bjorn Reese
+
+Mon Oct 13 15:59:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fix a call missing arguments
+
+Sun Oct 12 18:42:18 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genChRanges.py, chvalid.c, include/libxml/chvalid.h: fixed
+	  a bug in the range search; enhanced range generation (inline code
+	  if a small number of intervals); enhanced the readability of the
+	  output files.
+
+Sun Oct 12 00:52:14 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* chvalid.def chvalid.c include/libxml/chvalid.h: rebuilt 
+	  chvalid.def from scratch based on XML 2nd edition REC
+	  and regenerated the code.
+
+Sat Oct 11 22:54:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: removed some annoying warnings
+	* chvalid.def chvalid.c include/libxml/chvalid.h: fixed a bug
+	  in the PubidChars definition, regenerated, there is still
+	  a bug left somewhere
+	* genChRanges.py: save the header directly in include/libxml/
+	* configure.in: I generated a 2.6.0beta6 earlier today
+
+Sat Oct 11 23:32:47 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* fixed small error on previous commit (chvalid.h in
+	  base dir instead of include directory)
+
+Sat Oct 11 23:11:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* genChRange.py, chvalid.def, chvalid.c, include/libxml/chvalid.h:
+	  new files for a different method for doing range validation
+	  of character data.
+	* Makefile.am, parserInternals.c, include/libxml/Makefile.am,
+	  include/libxml/parserInternals.h: modified for new range method.
+	* catalog.c: small enhance for warning message (using one
+	  of the new range routines)
+
+Sat Oct 11 13:24:57 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c include/libxml/valid.h: adding an serror field to
+	  the validation context breaks the ABI for the xmlParserCtxt
+	  structure since it's embedded by content and not by reference
+
+Sat Oct 11 12:46:49 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: patch from Mike Hommey
+	* threads.c: applied Windows patch from Jesse Pelton and Stephane
+	  Bidoul
+	* parser.c: fix the potentially nasty access to ctxt->serror
+	  without checking first that the SAX block is version 2
+
+Fri Oct 10 21:34:01 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fixed a nasty bug with interning some text strings
+	* configure.in: prepare for beta5 of 2.6.0
+	* libxml.h nanoftp.c nanohttp.c xmlIO.c include/libxml/xmlerror.h:
+	  better error handling for I/O and converted FTP and HTTP
+	* parser.c: fixed another bug
+
+Fri Oct 10 16:45:20 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fixed uninitialized new field.
+	* result/VC/OneID2 result/relaxng/*.err: fixed a typo updating
+	  all messages
+
+Fri Oct 10 16:19:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h: make room in Doc, Element, Attributes
+	  for PSVI type informations.
+
+Fri Oct 10 16:08:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c c14n.c catalog.c error.c globals.c parser.c
+	  parserInternals.c relaxng.c valid.c xinclude.c xmlIO.c xmlregexp.c
+	  xmlschemas.c xpath.c xpointer.c include/libxml/globals.h
+	  include/libxml/parser.h include/libxml/valid.h 
+	  include/libxml/xmlerror.h: Setting up the framework for structured
+	  error reporting, touches a lot of modules, but little code now
+	  the error handling trail has been cleaned up.
+
+Fri Oct 10 14:29:42 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c include/libxml/xmlerror.h: converted the C14N module too
+
+Fri Oct 10 13:40:51 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: cleanup
+	* xpointer.c include/libxml/xmlerror.h: migrated XPointer module
+	  to the new error mechanism
+
+Fri Oct 10 12:49:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c xmlschemas.c: a bit of cleanup
+	* result/schemas/*.err: updated with the new result strings
+
+Fri Oct 10 03:58:39 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: fixed bug 124061
+
+Fri Oct 10 02:47:22 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: cleanup
+	* encoding.c: fix a funny typo
+	* error.c xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h:
+	  converted the Schemas code to the new error handling. PITA,
+	  still need to check output from regression tests.
+
+Thu Oct  9 15:13:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c include/libxml/xmlerror.h: converted too
+	* tree.c: small cleanup
+
+Thu Oct  9 13:44:57 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: comment fix
+	* catalog.c include/libxml/xmlerror.h: migrating the catalog code
+	  to the new infrastructure
+
+Thu Oct  9 00:36:03 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: final error handling cleanup
+	* xinclude.c error.c: converted XInclude to the new error handling
+	* include/libxml/xmlerror.h: added XInclude errors
+
+Wed Oct  8 23:31:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: bug in compression saving was crashing galeon
+	  reported by teuf
+
+Wed Oct  8 21:18:12 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c tree.c xmlIO.c xmllint.c: more cleanup through the
+	  I/O error path
+
+Wed Oct  8 20:57:27 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: better handling of error cases
+
+Wed Oct  8 13:51:14 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c xmllint.c include/libxml/xmlerror.h: first pass at
+	  cleaning up error handling in the I/O module.
+
+Wed Oct  8 10:52:05 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c include/libxml/xmlerror.h: error handling
+	  cleanup of the Regexp module.
+
+Wed Oct  8 01:09:05 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: converting the tree module too
+	* error.c include/libxml/xmlerror.h: created a simpler internal
+	  error reporting function.
+
+Tue Oct  7 23:19:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c include/libxml/xmlerror.h include/libxml/xpath.h
+	  include/libxml/xpathInternals.h xpath.c: cleaning up XPath
+	  error reporting that time. 
+	* threads.c: applied the two patches for TLS threads
+	  on Windows from Jesse Pelton
+	* parser.c: tiny safety patch for xmlStrPrintf() make sure the
+	  return is always zero terminated. Should also help detecting
+	  passing wrong buffer size easilly.
+	* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
+	  updated the results to follow the errors string generated by
+	  last commit.
+
+Tue Oct  7 14:16:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c include/libxml/xmlerror.h: last cleanup of error
+	  handling in the Relax-NG module.
+
+Tue Oct  7 13:30:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c relaxng.c include/libxml/xmlerror.h: switched Relax-NG
+	  module to teh new error reporting. Better default report, adds
+	  the element associated if found, context and node are included
+	  in the xmlError
+	* python/tests/reader2.py: the error messages changed.
+	* result/relaxng/*: error message changed too.
+
+Mon Oct  6 10:46:35 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.bcb win32/Makefile.mingw win32/Makefile.msvc
+	  win32/configure.js: applied patch from Stéphane Bidoul to
+	  fix the compilation of 2.6.0 code on Win32
+
+Mon Oct  6 10:16:30 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: fixing the script
+	* parser.c: replace sequences of RAW && NXT(.) == '.' with
+	  memcmp calls, seems to not break conformance, slightly inflate
+	  the size of the gcc generated code though.
+
+Sun Oct  5 23:30:48 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c parser.c valid.c include/libxml/parserInternals.h:
+	  more cleanup of error handling in parserInternals, sharing the
+	  routine for memory errors.
+
+Sun Oct  5 15:49:14 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c Makefile.am legacy.c parser.c parserInternals.c
+	  include/libxml/xmlerror.h: more code cleanup, especially around
+	  error messages, the HTML parser has now been upgraded to the new
+	  handling.
+	* result/HTML/*: a few changes in the resulting error messages
+
+Sat Oct  4 23:06:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/xmlerror.h: more error/warning
+	  handling cleanups, the XML parser module should be okay now.
+
+Sat Oct  4 01:58:27 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in xmldwalk.c include/libxml/Makefile.am
+	  include/libxml/xmldwalk.h include/libxml/xmlversion.h.in:
+	  integrated the xmlDocWalker API given by Alfred Mickautsch,
+	  and providing an xmlReader like API but working on a xmlDocPtr.
+
+Sat Oct  4 00:18:29 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: more cleanup in make tests
+	* error.c valid.c parser.c include/libxml/xmlerror.h: more work
+	  in the transition to the new error reporting strategy.
+	* python/tests/reader2.py  result/VC/* result/valid/*:
+	  few changes in the strings generated by the validation output
+
+Fri Oct  3 00:19:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: changed 'make tests' to use a concise output,
+	  scrolling to see where thing broke wasn't pleasant
+	* configure.in: some beta4 preparation, but not ready yet
+	* error.c globals.c include/libxml/globals.h include/libxml/xmlerror.h:
+	  new error handling code, last error informations are stored
+	  in the parsing context or a global variable, new APIs to
+	  handle the xmlErrorPtr type.
+	* parser.c parserInternals.c valid.c : started migrating to the
+	  new error handling code, it's a royal pain.
+	* include/libxml/parser.h include/libxml/parserInternals.h:
+	  moved the definition of xmlNewParserCtxt()
+	* parser.c: small potential buffer access problem in push code
+	  provided by Justin Fletcher
+	* result/*.sax result/VC/PENesting* result/namespaces/*
+	  result/valid/*.err: some error messages were sligthly changed.
+
+Thu Oct  2 13:01:13 2003  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* include/libxml/parser.h parser.c: introduced xmlStrPrintf
+	function (wrapper around snprintf)
+
+Wed Oct  1 21:12:06 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: Fix error on output of high codepoint charref like
+	  &#x10FFFF; , reported by Eric Hanchrow
+
+Wed Oct  1 14:20:10 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c include/libxml/DOCBparser.h: let's see how much
+	  of a pain murrayc is really gonna be.
+
+Wed Oct  1 11:03:40 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: Applied fix for bug #123481 reported by Peter Derr
+
+Tue Sep 30 15:34:31 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c legacy.c parser.c: made the predefined entities
+	  static predefined structures to avoid the work, memory and
+	  hazards associated to initialization/cleanup.
+
+Tue Sep 30 14:30:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c Makefile.am configure.in legacy.c parser.c
+	  parserInternals.c testHTML.c xmllint.c include/libxml/HTMLparser.h
+	  include/libxml/parser.h include/libxml/parserInternals.h
+	  include/libxml/xmlversion.h.in: added a new configure
+	  option --with-push, some cleanups, chased code size anomalies.
+	  Now a library configured --with-minimum is around 150KB,
+	  sounds good enough.
+
+Tue Sep 30 12:31:00 AEST 2003 Malcolm Tredinnick <malcolm@commsecure.com.au>
+
+	* libxml-2.0-uninstalled.pc.in: New file for building against
+	uninstalled libxml2 builds.
+	* configure.in, Makefile.am: Support the *-uninstalled.pc file.
+	* .cvsignore: Ignore the new generated *.pc file.
+
+Tue Sep 30 02:38:16 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am SAX.c SAX2.c configure.in globals.c parser.c
+	  parserInternals.c testReader.c testSAX.c xmlIO.c xmllint.c
+	  xmlreader.c example/gjobread.c include/libxml/xmlversion.h.in:
+	  added 2 new configure option: --with-reader --with-sax1
+	  to allow removing the reader or non-xmlReadxxx() interfaces.
+
+Mon Sep 29 19:58:26 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in entities.c tree.c valid.c xmllint.c
+	  include/libxml/tree.h include/libxml/xmlversion.h.in:
+	  Adding a configure option to remove tree manipulation
+	  code which is not strictly needed by the parser.
+
+Mon Sep 29 15:23:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c: last finishing touch to the BeOS
+	  patch from Marcin 'Shard' Konicki
+
+Mon Sep 29 15:15:08 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c SAX2.c c14n.c catalog.c configure.in debugXML.c
+	  encoding.c entities.c nanoftp.c nanohttp.c parser.c relaxng.c
+	  testAutomata.c testC14N.c testHTML.c testRegexp.c testRelax.c
+	  testSchemas.c testXPath.c threads.c tree.c valid.c xmlIO.c
+	  xmlcatalog.c xmllint.c xmlmemory.c xmlreader.c xmlschemas.c
+	  example/gjobread.c include/libxml/HTMLtree.h include/libxml/c14n.h
+	  include/libxml/catalog.h include/libxml/debugXML.h
+	  include/libxml/entities.h include/libxml/nanohttp.h
+	  include/libxml/relaxng.h include/libxml/tree.h
+	  include/libxml/valid.h include/libxml/xmlIO.h
+	  include/libxml/xmlschemas.h include/libxml/xmlversion.h.in
+	  include/libxml/xpathInternals.h python/libxml.c:
+	  Okay this is scary but it is just adding a configure option
+	  to disable output, this touches most of the files.
+
+Mon Sep 29 12:53:56 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: better fix, avoids breaking the python bindings
+
+Mon Sep 29 11:21:33 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: fix a compilation problem when configuring
+	  with debug but without mem-debug
+
+Sun Sep 28 20:53:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: cleanup, creating a new legacy.c module,
+	  made sure make tests ran in reduced conditions
+	* SAX.c SAX2.c configure.in entities.c globals.c parser.c
+	  parserInternals.c tree.c valid.c xlink.c xmlIO.c xmlcatalog.c
+	  xmlmemory.c xpath.c xmlmemory.c include/libxml/xmlversion.h.in:
+	  increased the modularization, allow to configure out 
+	  validation code and legacy code, added a configuration
+	  option --with-minimum compiling only the mandatory code
+	  which then shrink to 200KB.
+
+Sun Sep 28 02:15:07 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix a bug raised by the Mips compiler.
+	* include/libxml/SAX.h include/libxml/parser.h: move the 
+	  SAXv1 block definitions to parser.h fixes bug #123380
+	* xmlreader.c include/libxml/xmlreader.h: reinstanciate
+	  the attribute and element pool borken 2 commits ago.
+	  Start playing with an entry point to preserve a subtree.
+	* entities.c: remove a warning.
+
+Sat Sep 27 12:19:38 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c, parser.c, relaxng.c: further (final?) minor
+	  changes for compilation warnings. No change to logic.
+
+Fri Sep 26 18:03:42 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* parser.c: fixed small problem with missing entities (test/ent2)
+
+Sat Sep 27 01:25:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: William's change allowed to spot a nasty bug in xmlDoRead
+	  if the result is not well formed that ctxt->myDoc is not NULL
+	  and uses the context dictionnary.
+
+Fri Sep 26 21:09:34 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: other patches from William Brack to avoid
+	  compilation warnings on AIX.
+
+Fri Sep 26 11:03:08 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c, entities.c, xmlreader.c: minor change to
+	  avoid compilation warnings on some (e.g. AIX) systems
+
+Fri Sep 26 16:49:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fixed a backward compatibility problem
+	  when formatting "deprecated SAXv1 function ignorableWhitespace"
+	  could be reproduced by xmllint --format
+
+Fri Sep 26 15:50:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/libxml2-api.xml: rebuilt the API
+	* xmllint.c doc/xmllint.1 doc/xmllint.xml: added the new options
+	  --nocdata and --nsclean to remove CDATA section and surperfluous
+	  namespace declarations
+	* parser.c SAX2.c: implementation of the 2 new options
+
+Fri Sep 26 14:41:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c testHTML.c xmllint.c include/libxml/HTMLparser.h:
+	  added the same htmlRead APIs than their XML counterparts
+	* include/libxml/parser.h: new parser options, not yet implemented,
+	  added an options field to the context.
+	* tree.c: patch from Shaun McCance to fix bug #123238 when ]]>
+	  is found within a cdata section.
+	* result/noent/cdata2 result/cdata2 result/cdata2.rdr
+	  result/cdata2.sax test/cdata2: add one more cdata test
+
+Thu Sep 25 23:03:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xmllint.c doc/libxml2-api.xml include/libxml/parser.h:
+	  Changed the new xmlRead/xmlCtxtRead APIs to have an extra
+	  base URL parameter when not loading from a file or URL.
+
+Thu Sep 25 16:23:58 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing a beta3 solving the ABI problems
+	* globals.c parser.c parserInternals.c testHTML.c HTMLparser.c SAX.c
+	  include/libxml/globals.h include/libxml/SAX.h: make sure the
+	  global variables for the default SAX handler are V1 ones to
+	  avoid ABI compat problems.
+	* xmlreader.c: cleanup of uneeded code
+	* hash.c: fix a comment
+
+Thu Sep 25 14:16:51 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c hash.c parser.c include/libxml/xmlexports.h 
+	  include/libxml/xmlmemory.h include/libxml/xmlversion.h.in:
+	  fixing some comments to avoid warnings from apibuild.py
+
+Wed Sep 24 23:42:08 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/configure.js: patch from Stéphane Bidoul for configuring
+	  the beta2 version #123104
+
+Wed Sep 24 23:17:59 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: adding repeated parsing and validating tests
+	* SAX2.c parser.c tree.c include/libxml/parser.h: make the new
+	  DOM tree building interfaces use the dictionary from the 
+	  parsing context to build the element and attributes names
+	  as well as formatting spaces and short text nodes
+	* include/libxml/dict.h dict.c: added some reference counting
+	  for xmlDictPtr because they can be shared by documents and
+	  a parser context.
+	* xmlreader.c: a bit of cleanup, remove the specific tree freeing
+	  functions and use the standard ones now.
+	* xmllint.c: add --nodict
+	* python/libxml.c: fix a stupid bug so that ns() works on 
+	  attribute nodes.
+
+Tue Sep 23 23:07:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parser.h: adding a new set of
+	  API for parsing xmlReadDoc() xmlReadFile() ... xmlReadIO()
+	  and xmlCtxtReadDoc() ... xmlCtxtReadIO(). That with
+	  a clear define of xmlParserOption, xmlCtxtUseOptions()
+	  should simplify custom parsing without being tempted to
+	  use global variables, and xmlCtxtReset() should allow reuse
+	  of a context for multiple parsing.
+	* xmllint.c: switched to use xmlReadXXX, allow options to
+	  be used simultaneously with less troubles.
+	* tree.c: simple warning removal
+	* doc/apibuild.py: small fix
+	* doc/libxml2-api.xml win32/libxml2.def.src: updated
+
+Tue Sep 23 11:15:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: revert xmlCreateDocParserCtxt() since this break
+	  the parseDoc() python bindings
+
+Tue Sep 23 11:00:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: make sure xmlDetectSAX2() is called only at 
+	  parsing time to avoid breaking apps changing the SAX
+	  callbacks after context allocation, change xmlCreateDocParserCtxt()
+	  to use an immutable buffer instead of a copy
+
+Tue Sep 23 09:40:33 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied patch from Markus Keim fixing a problem
+	  with I/O callback registration.
+	* include/libxml/xmlerror.h: fixed #122994 comment numbering
+	  for xmlParserErrors
+
+Mon Sep 22 12:21:11 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c include/libxml/tree.h: the uri arg to xmlNodeSetBase is
+	  really a const xmlChar*
+	* xmlreader.c include/libxml/xmlreader.h: addin the
+	  xmlTextReaderConstString() to get an interned string from
+	  the reader
+
+Sun Sep 20 17:22:20 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* error.c: fixed a warning message (trivial)
+	* doc/search.php: removed incorrect warning message when word
+	  search not found in last of multiple tables (bug 119535)
+
+Fri Sep 19 14:26:28 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing a 2.6.0-beta2 release
+	* xmlIO.c: avoid a warning
+	* tree.c: avoid duplicate code in xmlReplaceNode as pointed out
+	  by Chris Ryland
+	* include/libxml/dict.h: add a QName access lookup to the
+	  dictionary.
+	* xmlreader.c include/libxml/xmlreader.h: adding const access
+	  based on the dictionary interface for string read from the
+	  reader, the node content access is still TODO, it's too different
+
+Fri Sep 19 00:01:08 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fixing namespace DTD validations
+	* result/valid/ns2.xml result/valid/ns.xml: the output of defaulted
+	  namespaces is slightly different now.
+	* Makefile.am: report the memory used in Timingtests (as well as time)
+
+Thu Sep 18 15:29:46 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: add streaming on memory regression tests, found
+	  bad bugs in the reader interface
+	* xmlreader.c: fixing bugs w.r.t. very large names, and special
+	  condition in end of file.
+	* xmlIO.c tree.c include/libxml/tree.h include/libxml/xmlIO.h:
+	  adding immutable buffers, and parser input based on those,
+	  but this should not be used (yet) for general parsing
+	* parser.c: added a comment about using immutable buffers for
+	  general parsing.
+	* result/bigname.xml.rdr result/bigname2.xml.rdr: fixing the
+	  output of the regression tests
+	* xmllint.c: using the immutable buffers when streaming on
+	  mmaped file (--stream --memory)
+
+Thu Sep 18 12:04:50 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: the last patch broke unicity of returned strings, removed
+
+Thu Sep 18 00:31:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: add a Timingtests target to check bad behaviour
+	  from the streaming engine
+	* dbgen.pl dbgenattr.pl: perl script to generate big instances
+	* xmlreader.c: fix a bad behaviour on large buffer inputs
+
+Wed Sep 17 23:25:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c xmlreader.c: two small improvements
+
+Wed Sep 17 22:53:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: avoid a leak with previous patch
+
+Wed Sep 17 22:06:11 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: use stderr and not stdout for default errors
+	  in python environment bug #122552
+
+Wed Sep 17 21:33:57 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: small fix from Rob Richards for input filename
+	* xmllint.c: fixes for --repeat and --memory/--stream for speed tests
+	* xmlIO: adding a guard in one function
+
+Wed Sep 17 15:57:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting
+	  reducing memory allocation and free and avoiding expensive routines
+
+Wed Sep 17 12:23:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c parser.c parserInternals.c xmlreader.c: started messing
+	  seriously with per-document dict and element and attribute nodes
+	  reuse in the xmlReader. This seems to lead to an interesting
+	  speedup of the xmlReader already.
+
+Wed Sep 17 01:07:56 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c include/libxml/dict.h: do string allocations in large
+	  pools, allowing to find if a string pertain to a dict quickly
+	* xmllint.c: fix --stream --repeat --timing
+	* Makefile.am: the testThreads run output should be seen.
+
+Mon Sep 15 16:46:28 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c include/libxml/parser.h: starting work on reusing the
+	  parser dictionary for the element and attribute tag names.
+	  Add pools for Element and Attributes in the parser context,
+	  which should help speeding up the reader.
+	* Makefile.am result/*.rdr : adding non-python reader regression
+	  tests.
+
+Mon Sep 15 14:54:42 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c parser.c valid.c: starting to cleanup some of the
+	  problems exposed by the W3C/NIST regression suite.
+	* result/ent7.sax result/xml2.sax: small fixes.
+
+Mon Sep 15 11:46:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: more parser error factoring
+
+Sun Sep 14 21:53:39 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLtree.c: Fixed bug 121394 - missing ns on attributes
+
+Sun Sep 14 21:43:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/xmlerror.h: factoring of more 
+	  error handling code, serious size reduction and more lisibility
+	  of the resulting code.
+	* parserInternals.c parser.c include/libxml/parserInternals.h
+	  include/libxml/parser.h: changing the way VC:Proper Group/PE Nesting
+	  checks are done, use a counter for entities. Entities where freed and
+	  reallocated at the same address failing the check.
+	* tree.c: avoid a warning
+	* result/valid/* result/VC/*: this slightly changes some validation
+	  error messages.
+
+Sun Sep 14 11:03:27 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* valid.c: fixed bug 121759 - early declaration of
+	  attribute-list in external DTD
+
+Sat Sep 13 14:42:11 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/xmlerror.h: starting cleaning up
+	  error handling, factorize error processing
+	* doc/xmllint.html: update of the page, remove --sgml
+
+Sat Sep 13 02:13:50 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am DOCBparser.c parserInternals.c testDocbook.c
+	  xmllint.c doc/xmllint.xml doc/xmllint.1: removing the 
+	  broken pseudo SGML DocBook parser code.
+
+Fri Sep 12 17:24:11 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fix a problem with strcpy() in xmlXPathFormatNumber()
+	  valgrind pointed out the strings overlapped. cleanup .
+
+Fri Sep 12 11:43:12 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied speedup to xmlSearchNs() as suggested by
+	  Luca Padovani. Cleaned up xmlSearchNsByHref() in the process
+	  applying the same trick.
+
+Fri Sep 12 01:36:20 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c parserInternals.c tree.c include/libxml/parser.h
+	  include/libxml/xmlerror.h: adding namespace checkings
+	  while making sure they still parse as wellformed documents.
+	  Add an nsWellFormed status report to the context, and 
+	  provide new appropriate error codes.
+	* Makefile.am result/namespaces/* test/namespaces/*: add 
+	  specific regression testing for the new namespace support
+	* test/att5 result/noent/att5 result/att5 result/att5.sax:
+	  add more coverage for the attribute parsing and normalization
+	  code.
+
+Fri Sep 12 01:34:19 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: backport of a thread bugfix from 2_5_X branch
+
+Thu Sep 11 18:29:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a bug in one corner case of attribute parsing.
+
+Thu Sep 11 16:21:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* : 2.6.0beta1 changes
+	* SAX2.c hash.c parser.c parserInternals.c: Fixing attribute
+	  normalization, might not be totally fixed but this should 
+	  make sure SAX event provide the right strings for attributes
+	  except entities for which libxml2 is different by default
+	  This should fix #109564
+	* result/attrib.xml.sax result/ent3.sax result/p3p.sax: minor changes
+	  in attribute callback values
+	* result/c14n/with-comments/example-4
+	  result/c14n/without-comments/example-4: this also fixes a subtle
+	  bug in the canonicalization tests.
+
+Wed Sep 10 12:38:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	Time to commit 3 days of work rewriting the parser internal,
+	fixing bugs and migrating to SAX2 interface by default. There
+	is some work letf TODO, like namespace validation and attributes
+	normalization (this break C14N right now)
+	* Makefile.am: fixed the test rules
+	* include/libxml/SAX2.h include/libxml/parser.h
+	  include/libxml/parserInternals.h SAX2.c parser.c
+	  parserInternals.c: changing the parser, migrating to SAX2,
+	  adding new interface to switch back to SAX1 or initialize a
+	  SAX block for v1 or v2. Most of the namespace work is done
+	  below SAX, as well as attribute defaulting
+	* globals.c: changed initialization of the default SAX handlers
+	* hash.c tree.c include/libxml/hash.h: added QName specific handling
+	* xmlIO.c: small fix
+	* xmllint.c testSAX.c: provide a --sax1 switch to test the old
+	  version code path
+	* result/p3p result/p3p.sax result/noent/p3p test/p3p: the new code
+	  pointed out a typo in a very old test namespace
+
+Sun Sep  7 19:58:33 PTD 2003 William Brack <wbrack@mmm.com.hk>
+
+	* xmlIO.c include/libxml/xmlIO.h parser.c: Implemented detection
+	  of compressed files, setting doc->compressed appropriately
+	  (bug #120503).
+
+Sun Sep  7 22:53:06 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: try to cope with the fact that apps may still
+	  have allocated smaller SAX callbak block
+
+Sun Sep  7 11:11:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c: allow to give -1 for undefined length in lookups
+	* include/libxml/parser.h parser.c parserInternals.c testSAX.c:
+	  first round of work on the new SAX2 interfaces, the API
+	  will change but commiting before changing for historical
+	  reference.
+
+Sat Sep  6 10:55:01 PTD 2003 William Brack <wbrack@mmm.com.hk>
+
+	* SAX2.c, xmlIO.c: fixed bug #121210 (callback to sax->error,
+	  sax->warning with wrong params).
+
+Fri Sep  5 10:33:42 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/globals.h: patch from Stéphane Bidoul to export
+	  globals entry points to the python bindings
+
+Wed Sep  3 15:24:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: when creating a DOCTYPE use "html" lowercase
+	  by default instead of "HTML"
+	* parser.c xmlreader.c: optimization, gain a few % parsing speed by
+	  avoiding calls to "areBlanks" when not needed.
+	* include/libxml/parser.h include/libxml/tree.h: some structure
+	  extensions for future work on using per-document dictionaries.
+
+Wed Sep  3 15:08:06 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am results/*.sax SAXResult/*: removing the SAXresults
+	  tree, keeping result in the same tree, added SAXtests to the
+	  default "make tests"
+
+Tue Sep  2 15:59:04 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/xmlexports.h: defined additional macros which
+	  affect exports and added mingw section
+
+Mon Sep  1 15:15:18 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/index.py: fixed problem parsing xhtml docs
+	* doc/xmlreader.html,doc/guidelines.html: small modification
+	  to avoid problem in python parsing.
+	* doc/search.php: fixed upper case filename problem for XSLT docs
+
+Mon Sep  1 22:55:09 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: patch from Mark Vakoc that allows compiling 
+	  with XInclude but without XPointer support.
+
+Mon Sep  1 22:31:38 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xml2-config.in: Applied a patch from Kevin P. Fleming
+	  to add --libtool-libs option to xml2-config script.
+
+Sun Aug 31 21:52:12 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/README.docs, doc/Makefile.am: new file added,
+	  giving some description of the documentation generation process
+	* doc/search.php: fixed problem with upper case on filenames
+
+Fri Aug 29 12:25:01 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.bcb: updates by Eric Zurcher
+
+Thu Aug 28 22:58:38 PDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/apibuild.py, doc/libxml2-api.xml: enhanced code
+	  to compensate for pollution from Igor's header taint
+	  (quick before Daniel notices)
+
+Thu Aug 28 23:01:36 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX2.c: fixed a namespace error on attribute reporting bug
+	  pointed out by Tobias Reif
+	* test/p3p result/p3p result/noent/p3p: this test case was wrong
+	  using xmlsn instead of xmlns...
+
+Thu Aug 28 18:25:07 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/globals.h include/libxml/xmlexports.h: fixed
+	  typos reported by Mark Vakoc
+
+Thu Aug 28 08:59:51 MDT 2003 John Fleck <jfleck@inkstain.net>
+
+	add:
+	* doc/tutorial/api.html
+	* doc/tutorial/ar01s09.html
+	* doc/tutorial/includexpath.c
+	updated
+	* doc/tutorial/*.html
+	fix my bad - forgot to check in new files when I last
+	updated
+
+Thu Aug 28 14:31:13 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.bcb: new file, support for Borland C++
+	* xmllint.c: fixed time inclusion for various compilers
+
+Thu Aug 28 12:32:59 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* parser.c parserInternals.c DOCBparser.c HTMLparser.c: added
+	  few casts to shut the compiler warnings
+
+Thu Aug 28 12:23:51 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.* win32/configure.js: fixed for mingw
+
+Thu Aug 28 10:01:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c threads.c: fixing bug #120870 try to avoid problem
+	  with uninitialized mutexes
+
+Wed Aug 27 16:12:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed an error reporting bug in Relax-NG when we end
+	  up with multiple states, select the "best" one. Fix #120682
+	* result/relaxng/tutor11_2_3.err: small change resulting 
+
+Wed Aug 27 11:25:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: applied base64 support patch from Anthony Carrico
+
+Wed Aug 27 10:58:51 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/[threads-xpointer].h: realigned parameters
+	  after taint
+
+Wed Aug 27 09:59:54 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/xmlexports.h: fixed defs for Borland compiler,
+	  as reported by Eric Zurcher
+
+Tue Aug 26 15:54:04 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed bug #120386 again a problem introduced when
+	  trying to reuse automata for content validation. Fix a bug report
+	  problem on zeroOrMore
+	* result/relaxng/tutor3_7_err: change slightly error reporting.
+
+Mon Aug 25 13:24:57 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/Makefile.am: make sure the new header will
+	  be included when generating a new distribution.
+
+Mon Aug 25 12:37:05 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed a couple of stupid bugs in the state allocation
+	  routines which led to bug #120040 and the ones reported by
+	  Martijn Faassen
+
+Mon Aug 25 12:37:23 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/parserInternals.h include/libxml/relaxng.h
+	  include/libxml/SAX.h include/libxml/SAX2.h: realigned the
+	  parameters after taint.
+
+Mon Aug 25 11:16:01 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/xmlversion.h.in: moved export defs to a separate
+	  file for consistency.
+	* include/libxml/xmlexports.h: new file, contains export defs.
+
+Mon Aug 25 11:01:49 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* include/libxml/*.h genUnicode.py: exportability taint
+	  of the headers.
+
+Thu Aug 21 12:37:46 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: make the deprecated interfaces log an error message
+	  to be sure it won't get used.
+
+Thu Aug 21 00:50:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am SAX2.c include/libxml/Makefile.am include/libxml/SAX2.h:
+	  Adding new version of the SAX interface, it's not there yet,
+	  currently just preparing the work
+	* globals.c parser.c SAX.c include/libxml/SAX.h 
+	  include/libxml/globals.h include/libxml/parser.h: doing some
+	  refactoring of the SAXv1 interfaces, obsoleting a bunch of them
+	  while keeping functionalities, preparing SAX2 integration.
+	* dict.c: small cleanup.
+
+Wed Aug 20 00:20:01 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixes a small bug introduced in last commit and detected
+	  by valgrind.
+
+Tue Aug 19 16:54:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c hash.c: optimization when freeing hash tables.
+	* parser.c xmlIO.c include/libxml/tree.h: some tuning of buffer
+	  allocations
+	* parser.c parserInternals.c include/libxml/parser.h: keep a
+	  single allocated block for all the attributes callbacks,
+	  avoid useless malloc()/free()
+	* tree.c: do not realloc() when growing a buffer if the buffer
+	  ain't full, malloc/memcpy/free avoid copying memory.
+
+Mon Aug 18 18:37:01 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c doc/xmllint.xml doc/xmllint.1: added option
+	  --dtdvalidfpi for Tobias Reif
+
+Mon Aug 18 14:03:03 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* dict.c include/libxml/dict.h Makefile.am include/libxml/Makefile.am:
+	  new dictionary module to keep a single instance of the names used
+	  by the parser
+	* DOCBparser.c HTMLparser.c parser.c parserInternals.c valid.c:
+	  switched all parsers to use the dictionary internally
+	* include/libxml/HTMLparser.h include/libxml/parser.h
+	  include/libxml/parserInternals.h include/libxml/valid.h:
+	  Some of the interfaces changed as a result to receive or return
+	  "const xmlChar *" instead of "xmlChar *", this is either
+	  insignificant from an user point of view or when the returning
+	  value changed, those function are really parser internal methods
+	  that no user code should really change
+	* doc/libxml2-api.xml doc/html/*: the API interface changed and
+	  the docs were regenerated
+
+Sun Aug 17 23:05:38 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied patch to xmlCleanupParser from Dave Beckett
+
+Sat Aug 16 22:53:42 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/parsedecl.py, doc/libxml2-refs.xml, doc/API*.html:
+	  fixed part (2) of bug 119535 (wrong alpha case on filenames)
+
+Sat Aug 16 20:35:28 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/API*.html, doc/html/*: regenerated API documentation
+	  for xmlsoft.org (part of Bug 119535)
+
+Fri Aug 15 14:58:37 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c, threads.c, include/libxml/HTMLparser.h,
+	  doc/libxml2-api.xml: Minor changes to comments, etc. for
+	  improving documentation generation
+	* doc/Makefile.am: further adjustment to auto-generation of
+	  win32/libxml2.def.src
+
+Fri Aug 15 02:24:20 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* News configure.in: preparing libxml2-2.5.10 release
+	* doc/* : updated the doc and rebuilt
+
+Fri Aug 15 01:55:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing the xmlSAXParseDTD bug #119536 raised by
+	  Malcolm Tredinnick with the patch he suggested.
+
+Fri Aug 15 01:37:10 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: allocation error #119784 raised by Oliver Stoeneberg
+
+Fri Aug 15 00:41:58 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fixing an use of strcpy() where both strings overlap
+	  pointed out by valgrind.
+
+Thu Aug 14 17:10:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c globals.c include/libxml/xmlmemory.h: get rid of
+	  some compilation warnings.
+	* xinclude.c: fix the performance problem reported by Kevin Ruscoe
+	  plus some cleanup and better error reporting.
+
+Thu Aug 14 14:13:43 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: applied UTF-16 encoding handling patch provided by
+	  Mark Itzcovitz
+	* encoding.c parser.c: more cleanup and fixes for UTF-16 when 
+	  not having iconv support.
+
+Thu Aug 14 03:19:08 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in example/Makefile.am libxml.h nanoftp.c
+	  nanohttp.c xmllint.c: Applied patch from Mikhail Grushinskiy for
+	  mingw compiler on Windows.
+
+Thu Aug 14 02:28:36 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed the serious CPU usage problem reported by
+	  Grant Goodale
+	* HTMLparser.c: applied patch from Oliver Stoeneberg about a free
+	  missing in htmlSAXParseDoc
+
+Tue Aug 12 22:48:10 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* doc/Makefile.am: Removed dependency from libxml2.def.src
+
+Tue Aug 12 18:55:08 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* autogen.sh: took away the requirement for automake-1.4,
+	  changed the messages for getting auto* tools to current
+	  gnu pages.
+	* configure.in: added check for Linux Dec alpha requiring
+	  -ieee flag, fixed test for ipv6
+	* trionan.c: fixed problem for compiling on Linux Dec alpha
+	  using native compiler
+	* doc/Makefile.am: implemented regeneration of win32/libxml2.def.src
+	  whenever libxml2-api.xml is changed.
+
+Mon Aug 11 17:02:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: cleaning up a problem when parsing UTF-16 and libiconv
+	  is not used.
+
+Sun Aug 10 08:13:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* win32/libxml2.def.src: renerated with fixed libxml2-api.xml
+
+Sun Aug 10 00:22:55 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* News configure.in: preparing libxml2-2.5.9 release
+	* doc/* : updated the doc and rebuilt
+
+Sat Aug  9 20:00:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlreader.h doc/libxml2-api.xml: changing an enum
+	  definition to get a correct API XML description. This was apparently
+	  breaking Windows build.
+
+Sat Aug  9 13:41:21 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed a nasty bug #119387, bad heuristic from
+	  the progressive HTML parser front-end on large character data
+	  island leading to an erroneous end of data detection by the
+	  parser. Some cleanup too to get closer from the XML progressive
+	  parser.
+
+Sat Aug  9 00:42:47 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* win32/configure.js: Added in support for the ISO8859X
+	  module (patch provided by Jesse Pelton)
+
+Fri Aug  8 15:56:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c tree.c threads.c: hum try to avoid some troubles
+	  when the library is not initialized and one try to save, the 
+	  locks in threaded env might not been initialized, playing safe
+	* xmlschemastypes.c: apply patch for hexBinary from Charles Bozeman
+	* test/schemas/hexbinary_* result/schemas/hexbinary_*: also added
+	  his tests to the regression suite.
+
+Fri Aug  8 18:47:38 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* win32/defgen.xsl, win32/libxml2.def.src: Bug 119343
+	  (with apologies to Igor) - Enhanced handling of docb and
+	  nanohttp.
+
+Thu Aug  7 21:13:22 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* encoding.c: further small changes for warnings when
+	  configured with --with-iconv=no
+
+Wed Aug  6 12:32:11 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* error.c trionan.[ch] testThreads.c python/generator.py:
+	  further small changes to elminate most of the remaining
+	  warnings.
+
+Tue Aug  5 23:51:21 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* error.c HTMLparser.c testC14N.c testHTML.c testURI.c
+	  xmlcatalog.c xmlmemory.c xmlreader.c xmlschemastypes.c
+	  python/libxml.c include/libxml/xmlmemory.h: small changes
+	  to syntax to get rid of compiler warnings.  No changes
+	  to logic.
+
+Mon Aug  4 22:40:54 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/libxml2-api.xml doc/html/*: rebuilt the API and docs.
+
+Mon Aug  4 21:40:34 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed a small problem in the patch for #118763
+	* result/HTML/doc3.htm*: this reverts back to the previous result
+
+Sun Aug  3 21:41:49 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/FAQ.html doc/xml.html: applied doc patch to xml.html
+	  and rebuilt, apparently some C++ wrappers are not available,
+	  c.f. bug #118943
+
+Sun Aug  3 21:30:31 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixing HTML attribute serialization bug #118763
+	  applying a modified version of the patch from Bacek
+	* result/HTML/doc3.htm*: this modifies the output from one test
+
+Sun Aug  3 21:02:30 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c include/libxml/tree.h: added a new API to split a
+	  QName without generating any memory allocation
+	* valid.c: fixed another problem with namespaces on element
+	  in mixed content case
+	* python/tests/reader2.py: updated the testcase with 
+	  Bjorn Reese fix to reader for unsignificant white space
+	* parser.c HTMLparser.c: cleanup.
+
+Sun Aug  3 20:55:40 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: trying to fix #118754 of possible recursion in the
+	  catalogs. Not fantastically happy about the current fix since
+	  it's likely to break under very thread intensive concurrent
+	  access to the catalog. Better solution might to keep the depth
+	  an extra argument to the resolution functions.
+
+Sun Aug  3 18:56:54 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed bug #118712 about mixed content, and namespaced
+	  element names.
+	* test/valid/mixed_ns.xml result/valid/mixed_ns*: added a check
+	  in the regression tests
+
+Fri Aug 1 23:55:23 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	Coninuing work on bug 118559
+	* DOCBparser.c: removed 2 unsed vars
+	* xmlregexp.c: changed some numeric const to their enum symbols
+	* xmlreader.c: changed one var define from int to enum
+	  (a little more to be done, awaiting co-ordination)
+	* relaxng.c: deleted one unused var
+	* xmllint.c: deleted some unused vars, changed one arg
+	  val from int to enum
+	* testHTML.c, testDocbook.c: changed some arg vals to enum const
+	* xmlIO.c: fixed typo from last night (small warning msg)
+
+Thu Jul 31 22:44:33 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	Working on bug 118559
+	* error.c: deleted unused variable
+	* parserInternals.c: deleted unneeded 'const' qualifier
+	* parser.c: changed variable type for enum temp storage
+	* xmlIO.c: changed debugging var to be inside #ifdef
+	* valid.c: removed unused variable
+	* HTMLparser.c: removed some unneeded 'const' qualifiers
+	* xpath.c: added some type casts, removed some unused vars
+	* xinclude.c: added one type cast
+	* nanohttp.c: repositioned some #ifdef to avoid unused var
+	* nanoftp.c: removed unused var
+
+Wed Jul 30 14:57:55 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied a patch from William Brack about
+	  the problem of parsing very large HTML instance with comments
+	  as raised by Nick Kew
+
+Wed Jul 30 12:29:38 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h: applying cleanup
+	  patch from Bjorn Reese for xmlTextReaderNodeType() and 
+	  significant whitespace. There is an enum for node type
+	  values now.
+
+Wed Jul 30 11:08:21 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: applying patch from Peter Jacobi to added 
+	  ISO-8859-x encoding support when iconv is not available
+	* configure.in include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h.in: added the glue needed
+	  at the configure level and made it the default for Windows
+
+Tue Jul 29 16:43:48 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml2class.txt:
+	  patch from Joachim Bauch + cleanup for Relax NG error callbacks
+	  in python
+
+Tue Jul 29 12:46:08 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c parserInternals.c tree.c: applied Peter Jacobi encoding
+	  cleanup patch, and also avoided a possible memory leak
+
+Tue Jul 29 09:28:09 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fix the previous commit
+
+Tue Jul 29 12:28:17 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c: fixed problem with comments reported by Nick Kew
+	* encoding.c: added routines xmlUTF8Size and xmlUTF8Charcmp for
+	  some future cleanup of UTF8 handling
+
+Mon Jul 28 16:39:14 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied a change suggested by Sean Griffin in bug
+	  #118494 about a memory leak in EXSLT
+
+Sun Jul 27 14:30:56 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed a Relax-NG compilation/streaming bug introduced
+	  when fixing the previous Relax-NG bugs
+	* result/relaxng/*: This slightly changes the output messages of
+	  some regression tests.
+	* configure.in: added support of -with-fexceptions for nested C++
+	  support.
+
+Thu Jul 24 15:46:02 MDT 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/apa.html
+	* doc/tutorial/apb.html
+	* doc/tutorial/apc.html
+	* doc/tutorial/apd.html
+	* doc/tutorial/ape.html
+	* doc/tutorial/apf.html
+	* doc/tutorial/apg.html
+	* doc/tutorial/aph.html
+	* doc/tutorial/ar01s02.html
+	* doc/tutorial/ar01s03.html
+	* doc/tutorial/ar01s04.html
+	* doc/tutorial/ar01s05.html
+	* doc/tutorial/ar01s06.html
+	* doc/tutorial/ar01s07.html
+	* doc/tutorial/ar01s08.html
+	* doc/tutorial/index.html
+	* doc/tutorial/ix01.html
+	* doc/tutorial/xmltutorial.pdf
+	* doc/tutorial/xmltutorial.xml
+	update tutorial with XPath example
+
+Thu Jul 24 17:07:06 IST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c parser.c: fixing a bug about a special case of namespace
+	  handling, this closes bug #116841
+
+Wed Jul 23 20:52:36 IST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c result/relaxng/*: checked and fixed the compilation
+	  of RNG schemas, fixes a couple of bugs #117097 and #117001 .
+	  This slightly changes the output messages of some regression tests.
+
+Wed Jul 23 15:15:08 IST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed an out of bound error #118052 , the good
+	  part if that base64 code was not in use yet ...
+
+Tue Jul 22 19:42:15 MDT 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.html
+	include html version of the xmllint man page, so an
+	up-to-date version is visible on the Web
+
+Mon Jul 21 21:53:43 IST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c include/libxml/xinclude.h: added a new API
+	  xmlXIncludeProcessTree() to process XInclude only on a subtree
+	  this should fix bug #115385
+
+Fri Jul 18 17:11:42 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c include/libxml/relaxng.h: adding Get interface for
+	  the error callback and parameters of parsing and validation
+	  contexts
+	* xmlreader.c: patch to fix bug #117702 about incomplete Read()
+	  on text nodes.
+
+Wed Jul 16 23:15:53 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: patch from Dodji Seketeli about UTF16 BOM
+	  when using the push XML parser.
+	* result/utf16bom.xml result/noent/utf16bom.xml test/utf16bom.xml:
+	  added the test to the regression suite.
+
+Tue Jul 15 22:03:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: add xmlThrDefMutex = NULL in xmlCleanupGlobals() 
+	  as suggested by Rob Richards
+
+Tue Jul 15 15:30:55 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c HTMLparser.c entities.c parser.c relaxng.c 
+	  xmlschemas.c xpath.c: removed some warnings by casting xmlChar
+	  to unsigned int and a couple of others.
+
+Fri Jul 11 16:44:22 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: fixes a segfault on empty hexBinary strings
+
+Thu Jul 10 16:02:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c: cleanup patches from Peter Breitenlohner
+
+Tue Jul  8 16:02:19 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c threads.c: fixes some problem when freeing unititialized
+	  mutexes
+
+Tue Jul  8 14:15:07 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c: the modules should not import <config.h>
+	  directly, some cleanups
+	* xmlschemas.c: Peter Sobisch found a nasty bug in the Schemas
+	  validation code.
+
+Mon Jul  7 18:00:51 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/configure.js: Jesse Pelton pointed out a problem in the
+	  javascript code.
+
+Mon Jul  7 16:39:31 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/*: regenerated
+	* nanoftp.c nanohttp.c: might fix includes problems with the
+	  Ipv6 support on solaris
+	* tree.c: patch from Markus Keim about xmlHasNsProp() on attributes
+	  defined as #IMPLIED
+
+Sun Jul  6 23:09:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/*: preparing release 2.5.8
+	* nanohttp.c: changed some preprocessor block
+	* xmlschemastypes.c: applied patch from Charles Bozeman adding
+	  hexBinary schema datatype and adding support for totalDigits and
+	  fractionDigits facets.
+
+Sun Jul  6 19:56:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c xpath.c: fixed 2 bugs pointed in #116448
+
+Sun Jul  6 19:34:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixed bug #116095 removing the error message when
+	  reapplying XInclude to a document.
+
+Sat Jul  5 22:40:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied small changes to portability layer for 
+	  compilation on DJGPP Ms-DOS compiler.
+
+Sat Jul  5 22:30:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c HTMLparser.c: use the character() SAX callback
+	  if the cdataBlock ain't defined.
+	* xpath.c: fix bug #115349 allowing compilation when configured
+	  with --without-xpath since the Schemas code needs NAN and co.
+
+Sat Jul 5 00:51:30 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+	Fixed problem with multi-threading, shown by the test program
+	testThreads.  After fix, ran mutiple tests on various speed
+	machines (single and dual processor X86), which all seem okay.
+
+	* catalog.c: added missing xmlRMutexUnlock in xmlLoadCatalog
+
+	* threads.c: added missing initialisation for condition variable
+	  in xmlNewRMutex.
+
+Sat Jun 21 16:10:24 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	Applying IPv6 patch from Archana Shah <archana.shah@wipro.com>
+	closing bug #114837
+
+	* configure.in: Added checks for IPv6 support and getaddrinfo().
+
+	* acconfig.h: Defined HAVE_GETADDRINFO and SUPPORT_IP6.
+
+	* config.h.in: Defined HAVE_GETADDRINFO and SUPPORT_IP6.
+
+	* nanoftp.c: Structure xmlNanoFTPCtxt contains either sockaddr_storage
+	  field or sockaddr_in field, depending upon the availability of IPv6
+	  support.
+	  have_ipv6(): Added to check for run-time IPv6 support.
+	  (xmlNanoFTPScanURL), (xmlNanoFTPUpdateURL), (xmlNanoFTPScanProxy):
+	  Modified to parse a URI with IPv6 address given in [].
+	  (xmlNanoFTPConnect): Changed to use getaddrinfo for address
+	  resolution, if it is available on the system, as gethostbyname
+	  does not return IPv6 addresses on some platforms.
+	  (xmlNanoFTPGetConnection): Modified type of dataAddr variable to
+	  sockaddr_storage or sockaddr_in depending upon the IPv6 support.
+	  Sending EPSV, EPRT or PASV, PORT depending upon the type of address
+	  we are dealing with.
+
+	* nanohttp.c: (have_ipv6): Added to check for run-time IPv6 support.
+	  (xmlNanoHTTPScanURL), (xmlNanoHTTPScanProxy): Modified to parse
+	  a URI with IPv6 address given in [].
+	  (xmlNanoHTTPConnectHost): Modified to use getaddrinfo if it is
+	  available on the system. Also IPv6 addresses will be resolved by
+	  gethostbyname only if IPv6 run-time support is available.
+	  (xmlNanoHTTPConnectAttempt): Modified to deal with IPv6 address.
+
+Sat Jun 14 18:46:51 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/configure.js include/win32config.h 
+	  include/libxml/xmlversion.h.in: Applied the patch for BCB
+	  by Eric Zurcher.
+
+Fri Jun 13 14:27:19 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am doc/html/*: reverted back patch for #113521,
+	  due to #115104 and while fixing #115101 . HTML URLs must not
+	  be version dependant.
+
+Fri Jun 13 12:03:30 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: do not generate &quot; for " outside of attributes
+	* result//*: this changes the output of some tests
+
+Mon Jun  9 12:28:58 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xmlIO.c: trying to fix #114277 about when file
+	  remapping and escaping should really be attempted.
+
+Mon Jun  9 11:06:09 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*: applied a patch from Gman for building docs
+	* valid.c xmllint.c include/libxml/valid.h: applied a patch from
+	  Gary Pennington to provide an allocator for xmlValidCtxt
+	* xmlreader.c: applied patch from Jacek Konieczny fixing bug
+	  #113580 about data not being passed immediately.
+
+Thu Jun  5 11:31:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied a couple of patches from Mark Itzcovitz
+	  to handle saving back "UTF-16" documents.
+
+Mon Jun  2 21:56:15 MVT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
+	  some work done while in the Maldives (hence the timezone on the
+	  laptop !)
+	* result/schemas/length3* test/schemas/deter0_*
+	  test/schemas/group0_*: some tests added too
+
+Mon Jun  2 15:34:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: small fix
+	* xmlIO.c: fixed an error message
+
+Tue May 20 14:21:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fixing Red Hat bug #91013 where xmllint was
+	  accepting an improper UTF8 sequence
+
+Sat May 17 12:53:11 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* threads.c: applied the patch from Stéphane Bidoul for getting
+	  rid of extra threads in a dynamic library.
+	* win32/configure.js: threads default to 'native' now.
+
+Fri May 16 13:17:52 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixing  bug #112904: html output method escaped
+	  plus sign character in URI attribute.
+
+Thu May 15 18:06:18 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* build_glob.py global.data globals.c parser.c
+	  include/libxml/globals.h: patch from Stéphane Bidoul for setting
+	  up threads global defaults.
+	* doc/libxml2-api.xml: this extends the API with new functions
+	* python/tests/Makefile.am python/tests/reader2.py
+	  python/tests/thread2.py: integrated the associated testcase and
+	  fixed the error string used in reader2
+
+Wed May 14 14:56:46 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in libxml.spec.in python/Makefile.am: trying
+	  to conciliate --with-python= requirements and RPM builds,
+	  a PITA really...
+
+Tue May 13 18:30:34 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: oops last commit introduced a memory leak.
+
+Tue May 13 18:10:38 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c doc/xmllint.xml: added --nonet option
+	* doc/Makefile.am: fixing #112803 by adding --nonet when calling
+	  xsltproc or xmllint
+	* doc/xmllint.xml doc/xmllint.1: also added --schema doc and
+	  rebuilt
+	* HTMLparser.c: cleaned up the HTML parser context build when 
+	  using an URL
+
+Tue May 13 16:35:04 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: added a comment about bug #112902 
+
+Mon May 12 21:58:00 EDT 2003 William Brack <wbrack@mmm.com.hk>
+
+	* minor cleanup of configure '--help' display
+	* error.c: enhanced xmlParserPrintFileContext to fix bug #109942
+
+Mon May 12 17:53:30 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: PI nodes in external subset were not freed :-\
+	  fixes bug #112842
+
+Mon May 12 11:23:27 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added --schema option to run WXS schema validation
+	* xmlschemas.c xmlschemastypes.c include/libxml/schemasInternals.h:
+	  tried to improve error reporting in the Schema code, some cleanup
+	  too.
+
+Sun May 11 16:13:20 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed some problems in the handling of errors,
+	  and attributes addressed by references.
+	* test/schemas/* result/schemas/*: dropped the verbosity level
+	  and added a couple of new tests
+
+Sat May 10 16:01:21 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: Stéphane Bidoul found an off by one addressing
+	  error on the error handling.
+
+Fri May  9 19:08:20 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: trying to fix #112673
+
+Fri May  9 18:14:16 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c catalog.c parser.c relaxng.c: removed multiple
+	  warning, this fixed a bug and should close #111574
+
+Fri May  9 15:34:32 EDT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixing bug #104081 with xs:all with an element
+	  holding minOccurs="0"
+	* test/schemas/all_* result/schemas/all_*: added some regression
+	  tests for that bug
+	* xmllint.c xmlreader.c: patches from Joerg Schmitz-Linneweber and
+	  Garry Pennington to compile without schemas support.
+
+Thu May  1 10:02:35 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed a problem with xmlUnlinkNode() for DTDs.
+
+Wed Apr 30 14:16:08 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xml2-config.in: try to fix Red hat bug #89957, do not
+	  output -L/usr/lib64
+	* xmlreader.c: fixed a typo in a comment
+
+Tue Apr 29 07:32:02 MDT 2003 John Fleck <jfleck@inkstain.ent>
+
+	* doc/tutorial/aph.html, ix01.html
+	forgot to cvs add the new files. Thanks to Roland van Laar
+	for pointing this out
+
+Tue Apr 29 14:36:49 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c doc/libxml2-api.xml: fixing a function comment
+	* doc/Makefile.am doc/apibuild.py doc/gnome-xml.sgml: switching
+	  to the XML/XSLT doc generation closing #111799
+	* doc/html/*: complete update of the HTML results
+
+Mon Apr 28 14:51:41 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/defgen.xsl: fixed the conditional for unicode map,
+	  removed hardcoded schema entries
+
+Mon Apr 28 02:19:00 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/defgen.xsl: new file, stylesheet for generating 
+	  win32/libxml2.def.src from doc/libxml2-api.xml
+	* win32/libxml2.def.src: is autogenerated from now on, changes
+	  to this file will not appear here anymore
+
+Mon Apr 28 00:12:11 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* win32/configure.js python/setup.py.in: applied patch
+	  from Stéphane Bidoul for the Python bindings on the new
+	  release.
+
+Sun Apr 27 17:56:21 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* debugXML.c: included libxml/uri.h for xmlCanonicPath
+	  declaration
+	* win32/configure.js: thread-enabled build is now default
+	* win32/libxml2.def.src: added more exports
+
+Sun Apr 27 00:23:05 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/*.xsl doc/*.html: updated the web site separated
+	  developers from common pages, made the transition to XHTML1,
+	  added validity checking to the makefile rules.
+
+Sat Apr 26 23:17:51 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fix for xmlIOParseDTD same as previous and reported
+	  by Petr Pajas
+
+Sat Apr 26 15:26:04 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied fix to xmlSAXParseDTD from Malcolm Tredinnick
+	  closing #111638
+
+Sat Apr 26 14:00:58 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: fixed a problem in the generator where
+	  the way functions are remapped as methods on classes was
+	  not symetric and dependant on python internal hash order,
+	  as reported by Stéphane Bidoul
+
+Fri Apr 25 21:52:33 MDT 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial:
+	xmltutorial.xml
+	xmltutorial.pdf
+	*.html
+	add appendix on generating compiler flags, more indexing
+
+Sat Apr 26 01:10:48 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* triodef.h vms/build_libxml.com: applied patch from Craig A. Berry
+	  to get libxml-2.5.7 to compile on OpenVMS
+
+Fri Apr 25 18:42:35 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing an xmlParseDTD bug raised by Petr Pajas
+
+Fri Apr 25 15:20:29 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am doc/xmlcatalog.1 doc/xmlcatalog_man.xml
+	  doc/xmllint.1 doc/xmllint.xml: automated the generation of the
+	  man page based on xsltproc and a stylesheet PI in the XML.
+
+Fri Apr 25 12:37:33 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmllint.*: trying to fix #110541 where &nbsp; generated
+	  character preventing rendering by the man command.
+
+Fri Apr 25 01:09:23 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS configure.in: preparing release 2.5.7
+	* doc/*: updated and rebuilt the docs
+	* doc/apibuild.py: fixed the script
+
+Thu Apr 24 19:11:12 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am doc/apibuild.py: make sure the OOM code don't
+	  get in the way of the builds
+	* doc/libxml2-api.xml python/libxml2class.txt: automatic update
+
+Thu Apr 24 18:01:46 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am testOOM.c testOOMlib.[ch] : integrated the Out Of
+	  Memory test from Havoc Pennington #109368
+	* SAX.c parser.c parserInternals.c tree.c uri.c valid.c
+	  xmlmemory.c xmlreader.c xmlregexp.c include/libxml/tree.h
+	  include/libxml/parser.h: a lot of memory allocation cleanups
+	  based on the results of the OOM testing
+	* check-relaxng-test-suite2.py: seems I forgot to commit the
+	  script.
+
+Wed Apr 23 17:16:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: trivial fix for 109774 removing a warning
+
+Wed Apr 23 15:49:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c SAX.c catalog.c debugXML.c parser.c: try to find
+	  more places where xmlCanonicPath() must be used to convert
+	  filenames to URLs, trying to fix #111088
+
+Wed Apr 23 09:35:12 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/libxml.py: applied patch from 
+	  Brent M Hendricks adding binding for xmlCatalogAddLocal
+
+Tue Apr 22 15:18:01 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: tried to fix #98879 again in a more solid
+	  way.
+
+Tue Apr 22 13:58:43 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/libxml2.def.src: added more exports from the relaxng and
+	  xmlreader clan
+
+Tue Apr 22 10:35:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c test/valid/ns* test/result/ns*: applied the patch
+	  provided by Brent Hendricks fixing #105992 and integrated the
+	  examples in the testsuite.
+
+Tue Apr 22 01:06:09 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* TODO: updated a bit
+	* configure.in: fixed the comment, threads now default to on
+	* parserInternals.c: fixed an erroneous xmlMallocAtomic() call
+
+Mon Apr 21 23:33:38 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c libxml.h parser.c parserInternals.c tree.c xmllint.c
+	  xmlreader.c include/libxml/parser.h: a lot of performance work
+	  especially the speed of streaming through the reader and push
+	  interface. Some thread related optimizations. Nearly doubled the
+	  speed of parsing through the reader.
+
+Sun Apr 20 10:36:05 MDT 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml
+	* doc/xmllint.1
+	update man page to explain use of --stream
+
+Sat Apr 19 02:03:24 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c HTMLparser.c c14n.c catalog.c encoding.c globals.c
+	  nanohttp.c parser.c parserInternals.c relaxng.c tree.c uri.c
+	  xmlmemory.c xmlreader.c xmlregexp.c xpath.c xpointer.c
+	  include/libxml/globals.h include/libxml/xmlmemory.h: added
+	  xmlMallocAtomic() to be used when allocating blocks which
+	  do not contains pointers, add xmlGcMemSetup() and xmlGcMemGet()
+	  to allow registering the full set of functions needed by
+	  a garbage collecting allocator like libgc, ref #109944
+
+Fri Apr 18 16:37:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: switched to have thread support enabled by default,
+	  didn't got troubles with ABI compatibility on Linux, hope it
+	  won't break on strange OSes, if yes, report the system ID
+	* doc/libxml2-api.xml: just rebuilt the API
+
+Fri Apr 18 14:31:15 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h include/libxml/parser.h parser.c xmlIO.c DOCBparser.c: 
+	  added support for large file, tested with a 3+GB instance,
+	  and some cleanup.
+	* catalog.c: added a TODO
+	* Makefile.am: added some "make tests" comments
+
+Thu Apr 17 14:51:57 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: some cleanups
+	* doc/xmlreader.html: extended the document to cover RelaxNG and
+	  tree operations
+	* python/tests/Makefile.am python/tests/reader[46].py: added some
+	  xmlReader example/regression tests
+	* result/relaxng/tutor*.err: updated the output of a number of tests
+
+Thu Apr 17 11:35:37 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: valgrind pointed out an uninitialized variable error.
+
+Thu Apr 17 11:06:28 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/relaxng.h relaxng.c include/libxml/xmlreader.h
+	  xmlreader.c: augnemting the APIs, cleanups.
+	* parser.c: cleanup bug #111005
+	* xmlIO.c: added some missing comments
+
+Wed Apr 16 17:46:50 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmllint.c: more work on RelaxNG streaming validation
+	  trying to improve the subset compiled, and more testing.
+	* doc/downloads.html doc/xml.html doc/xmlmem.html: some updates on the
+	  documentation
+	* test/relaxng/tutor11_1_3.xml: fixes the DTD path
+	* result/relaxng/*.err: fix some of the outputs
+
+Wed Apr 16 01:28:15 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlreader.c xmllint.c include/libxml/relaxng.h
+	  include/libxml/xmlreader.h: implemented streaming of
+	  RelaxNG (when possible) on top of the xmlReader interface,
+	  provided it as xmllint --stream --relaxng .rng .xml
+	  This seems to mostly work.
+	* Makefile.am: updated to test RelaxNG streaming
+
+Mon Apr 14 18:08:33 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c include/libxml/relaxng.h: integrated the regexp
+	  based validity checking of fragments of the document for
+	  which the RNG can be compiled to regexps. Works on all regression
+	  tests, only fix needed is related to error messages.
+
+Sun Apr 13 21:51:00 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlregexp.c include/libxml/xmlautomata.h
+	  include/libxml/xmlregexp.h: Starting work precompiling
+	  parts of RelaxNG schemas. Not plugged onto validity checking
+	  yet, just the regexp building part. Needed to extend some
+	  of the automata and regexp APIs.
+
+Fri Apr 11 21:36:21 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c xmlreader.c include/libxml/xmlreader.h: make sure
+	  xmllint --stream and xmllint --stream --valid returns errors
+	  code appropriately
+
+Fri Apr 11 10:59:24 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h: Added the Expand()
+	  and Next() operation to work on subtrees within the reader
+	  framework.
+	* doc/libxml2-api.xml python/libxml2class.txt: resulting updates
+	* python/tests/reader5.py: added an example for those new
+	  functions of the reader.
+
+Thu Apr 10 23:38:13 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: patch from Vasily Tchekalkin to fix #109865
+
+Thu Apr 10 15:32:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixing HasValue for namespace as raised by 
+	  Denys Duchier
+
+Wed Apr  9 14:07:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c include/libxml/HTMLparser.h:  exported
+	  htmlCreateMemoryParserCtxt() it was static
+
+Wed Apr  9 13:21:48 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/xmlschemas.h:
+	  update from Charles Bozeman for date and duration types
+	* test/schemas/date_0.* test/schemas/dur_0.*
+	  result/schemas/date_0.* result/schemas/dur_0.*: updated too
+
+Mon Apr  7 12:19:26 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c valid.c xpath.c include/libxml/tree.h include/libxml/valid.h:
+	  fixing bug #107129, removing excessive allocation and calls
+	  to *printf in the code to build QName strings.
+
+Sat Apr  5 11:41:36 CEST 2003 Igoe Zlatkovic <igor@zlatkovic.com>
+
+	* win32/libxml2.def.src: fixed conditional exports, reported by
+	  Luke Murray.
+
+Fri Apr  4 18:08:00 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a possible problem with xmlRecoverMemory()
+
+Thu Apr  3 17:24:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* trio.c trio.h triodef.h trionan.c trionan.h triop.h triostr.c
+	  triostr.h: Bjorn sent an update for the TRIO portability layer.
+
+Tue Apr  1 21:57:26 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/libxml2.def.src: exported new functions
+
+Tue Apr  1 13:09:46 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS: preparing release 2.5.6
+	* doc/*: updated and rebuilt the docs
+
+Tue Apr  1 11:52:15 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixed an uninitialized memory access pointed by valgrind
+	  on C14Ntests
+
+Tue Apr  1 00:12:28 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: one more fixup of error message reporting
+
+Mon Mar 31 18:36:32 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on bug #109225, and fixed an uninitialized
+	  variable pointed out by valgrind
+
+Mon Mar 31 18:05:22 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: try to work on bug #109225 and provide better
+	  error reports.
+	* result/relaxng/* : this change the output of a number of tests
+	* xinclude.c: fixing the parsed entity redefinition problem
+	  raised on the list.
+	* test/schemas/date_0.xsd: updated the date test c.f. E2-12
+
+Mon Mar 31 13:19:04 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: fixed date comparison to handle the tzo
+	  The only failures left are disagreements on Notations and
+	  '+1' not being allowed for ulong, uint, ushort and ubyte.
+
+Mon Mar 31 12:11:47 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: fixed gMonth parsing routine accordingly
+	  to the XML Schemas errata
+	  http://www.w3.org/2001/05/xmlschema-errata#e2-12
+
+Sun Mar 30 23:04:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlschemastypes.c: more work on XML Schemas datatypes
+	  and facets support. Currently only schemas with binHex or
+	  base64 don't compile. A few error left in the test suite:
+	  found 1035 test instances: 919 success 23 failures
+	  most are gdate or gdateyear failing check, and a few cases where
+	  James clark tests results are strange.
+	* valid.c: allow to reuse the Notation checking routine without
+	  having a validation context.
+	* SAX.c: removed a #if 0
+
+Sat Mar 29 17:35:05 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: forgot to apply one check from #106931 patch
+	* xmlschemastypes.c: more work on XML Schemas datatypes
+
+Sat Mar 29 11:49:25 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c include/libxml/relaxng.h xmlschemastypes.c: more work
+	  on cleaning up XML Schemas datatypes based on James Clark tests
+	  test/xsdtest/xsdtest.xml
+
+Fri Mar 28 14:24:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: implemented comparisons for Schemas values.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h: fixed
+	  some bugs in duration handling, comparisons for durations
+	  and decimals, removed all memory leaks pointed out by James
+	  testsuite. Current status is now
+	  found 238 test schemas: 197 success 41 failures
+	  found 1035 test instances: 803 success 130 failures
+
+Fri Mar 28 00:41:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: fixed bugs and memory
+	  leaks in the W3C XML Schemas code
+	* xmlschemastypes.c: implemented nonPositiveInteger
+	* test/schemas/length2_0.xsd result/schemas/length2_0_0.err:
+	  fixed the test and result.
+
+Thu Mar 27 22:23:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c tree.c: two patches from James Bursa on the HTML
+	  parser and a typo
+	* xmlschemastypes.c: reindenting, fixing a memory access
+	  problem with dates.
+
+Thu Mar 27 15:53:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing #109227 providing more context in case of 
+	  start/end tag mismatch
+	* python/tests/ctxterror.py python/tests/readererr.py: update the
+	  tests accordingly
+
+Thu Mar 27 15:22:41 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: should fix #109327 errors on memory accesses
+
+Thu Mar 27 15:06:13 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: Fixed reopening of #78662 <form action="...">
+	  is an URI reference
+
+Wed Mar 26 22:38:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed bug #109160 on non-ASCII IDs
+
+Wed Mar 26 17:30:37 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Norm suggested a nicer error message for xml:space values
+	  errors
+
+Wed Mar 26 01:34:19 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c include/libxml/xpath.h: first part of the fix to
+	  performance bug #108905, adds xmlXPathOrderDocElems() providing
+	  document order for nodes.
+	* python/libxml.c: Python may require TRIO as Albert Chin pointed out
+
+Tue Mar 25 16:07:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: removing a warning with Sun compiler
+	  bug #109154
+
+Tue Mar 25 07:02:56 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml
+	* doc/xmllint.1
+	update xmllint man page with --relaxng option
+
+Tue Mar 25 12:07:03 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/setup.py.in : was missing "drv_libxml2.py"
+
+Mon Mar 24 19:38:05 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c xpath.c: some changes related to the new way of 
+	  handling Result Value Tree, before 2.5.5
+
+Mon Mar 24 16:36:23 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS: preparing release 2.5.5
+	* doc/* : updated the documentation and regenerated it.
+
+Mon Mar 24 14:56:01 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed some problems related to #75813 about handling
+	  of Result Value Trees
+
+Sun Mar 23 22:57:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied a set of patches from Lorenzo Viali correcting
+	  URI parsing errors.
+
+Sun Mar 23 22:00:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: validity status was not passed back when validating in
+	  entities, but raised by Oliver Fischer
+
+Sun Mar 23 21:30:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: avoid escaping ',' in URIs
+
+Sun Mar 23 12:57:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing bug #108976 get the ID/REFs to reference 
+	  the ID in the document content and not in the entity copy
+	* SAX.c include/libxml/parser.h: more checking of the ID/REF
+	  stuff, better solution for #107208
+	* xmlregexp.c: removed a direct printf, dohhh
+	* xmlreader.c: fixed a bug on streaming validation of empty 
+	  elements in entities
+	* result/VC/ElementValid8 test/VCM/v20.xml result/valid/xhtml1.xhtml:
+	  cleanup of the validation tests
+	* test/valid/id* test/valid/dtds/destfoo.ent result/valid/id*:
+	  added more ID/IDREF tests to the suite
+
+Sat Mar 22 23:38:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed #107043 removing 2 warnings with Sun One
+	  compiler.
+
+Sat Mar 22 18:50:45 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: valgrind'ed and cleaned up a couple of memory issues.
+
+Sat Mar 22 16:15:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fix bug #107208 avoid false duplicates when ID/REFs are
+	  defined in entities content
+
+Sat Mar 22 15:53:27 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: Fixed validation bug #108858 on namespace names using
+	  entities and reported by Brent Hendricks
+	* xmllint.c: report xmlTextReaderHasValue() result in --stream
+	  --debug output.
+
+Sat Mar 22 13:32:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed bug #108801 reported by Malcolm Tredinnick
+	  about the DocType node not being reported sometimes.
+	* python/tests/reader.py: added to test to the regression checks
+
+Sat Mar 22 01:57:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed bug #108546 on long CDATA (or text nodes)
+	  reported by Edd Dumbill
+
+Sat Mar 23 01:00:24 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c parser.c parserInternals.c: patch from
+	  johan@evenhuis.nl for #107937 fixing some line counting
+	  problems, and some other cleanups.
+	* result/HTML/: this result in some line number changes
+
+Fri Mar 21 22:19:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in Makefile.am: fixed Red Hat bug #86118 use libxml2.spec
+	  instead of libxml.spec
+	* relaxng.c: fixed some of the error reporting excessive
+	  verbosity
+	* catalog.c debugXML.c valid.c xmlreader.c xmlschemas.c xpath.c
+	  xmlschemastypes.c: removed some warnings from gcc
+	* doc/libxml2-api.xml: rebuilt
+
+Fri Mar 21 17:25:23 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: another optimization, for choice this time
+	* result/relaxng/spec1* result/relaxng/tutor12_1* 
+	  result/relaxng/tutor3_7: cleanups.
+
+Fri Mar 21 13:41:23 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed xmlRelaxNGNodeMatchesList
+	* test/relaxng/testsuite.xml: augmented the test suite
+	* result/relaxng/spec1* result/relaxng/tutor12_1*: this fixes
+	  some schemas validation tests in the presence of foreign 
+	  namespaces.
+
+Fri Mar 21 02:23:34 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: added another interleave speedup.
+
+Thu Mar 20 17:22:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: added integer and fixed one of the
+	  IDREFS regression tests pbm
+	* result/relaxng/docbook_0.err: updated
+
+Wed Mar 19 21:58:47 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c xmlschemastypes.c: attempt to cope with ID/IDREF(S)
+	  declared both in the DTD and in the Schemas <grin/>
+	* relaxng.c: more debug, added a big optimization for <mixed>
+	* test/relaxng/testsuite.xml: augmented the testsuite
+	* test/relaxng/ result/relaxng: added the RelaxNG spec and a 
+	  DocBook example to the regression tests
+
+Wed Mar 19 11:34:10 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xsddata-test-suite.py: cosmetic change for output
+	* relaxng.c: try to minimize calls to malloc/free for states.
+
+Tue Mar 18 17:50:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: removed a warning
+	* xmlschemastypes.c: more cleanup, added ENTITY and ENTITIES
+	  support
+	* check-relaxng-test-suite.py check-xsddata-test-suite.py:
+	  cleanup/improvements of the regression tests batch
+	* test/relaxng/testsuite.xml: augmented libxml2 own testsuite
+
+Tue Mar 18 12:36:22 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed error msg cleanup deallocation
+	* xmlschemastypes.c: added a function to handle lists of
+	  atomic types, added support for IDREFS
+
+Tue Mar 18 01:28:15 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c valid.c xmlschemastypes.c: added Datatype ID
+	  and IDREF, usable from RelaxNG now
+	* include/libxml/xmlschemastypes.h: need to add a new interface
+	  because the validation modifies the infoset
+	* test/relaxng/testsuite.xml: extended the testsuite
+
+Mon Mar 17 16:34:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed the last core RelaxNG bug known #107083,
+	  shemas datatype ID/IDREF support still missing though.
+	* xmlreader.c: fix a crashing bug with prefix raised by
+	  Merijn Broeren
+	* test/relaxng/testsuite.xml: augmented the testsuite with
+	  complex inheritance tests
+
+Sun Mar 16 18:45:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: switched back to the previous Relax-NG code base,
+	  the derivation algorithm need severe constraining code to avoid
+	  combinatorial explosion. Fixed the problem with Sebastian Rahtz
+	  TEI based example and other bugs
+	* result/relaxng/*err: updated the results
+	* test/relaxng/testsuite.xml: started a new test suite 
+
+Sat Mar 15 22:26:46 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c include/libxml/relaxng.h: After coming to the conclusion
+	  that the original RelaxNG validation code was un-fixeable, it got
+	  rewritten to use the derivation algorithm from James Clark and
+	  redebugged it (nearly) from scratch:
+	  found 373 test schemas: 372 success 1 failures
+	  found 529 test instances: 529 success 0 failures
+
+Tue Mar 11 12:08:23 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c parser.c: fix some recursion problems introduced in the
+	  last release.
+	* relaxng.c: more debugging of the RNG validation engine, still
+	  problems though.
+
+Mon Mar 10 14:10:47 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: stop generating wrong result file with * in name
+	* relaxng.c: fixing the include bug raised by Sebastian Rahtz
+	* result/relaxng/demo* test/relaxng/demo: added the tests from
+	  Sebastian reproducing the problem.
+
+Sun Mar  9 18:02:31 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.1: regenerating man page from xmllint.xml to pick
+	  up Aleksey's change
+
+Sun Mar  9 13:53:16 2003  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* xmllint.c doc/xmllint.xml: use $XMLLINT_INDENT environment
+	variable to control the indentation for the xmllint "--format" 
+	option
+
+Sat Mar  8 14:27:43 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* encoding.c: applied Gennady's patch against buffer overrun
+
+Fri Mar  7 19:29:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* test/xsdtest/xsdtest.xml uri.c: after and exchange with James
+	  Clark it appeared I had bug in URI parsing code ...
+	* relaxng.c include/libxml/relaxng.h: completely revamped error
+	  reporting to not loose message from optional parts.
+	* xmllint.c: added timing for RNG validation steps
+	* result/relaxng/*: updated the result, all error messages changed
+
+Fri Mar  7 15:18:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fix bug #107804, the algorithm used for document order
+	  computation was failing on attributes.
+
+Thu Mar  6 22:35:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fix bug #107764 , possibility of buffer overflow
+	  in xmlValidDebug()
+
+Wed Mar  5 17:41:37 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c include/libxml/nanoftp.h: adding xmlNanoFTPDele()
+	  from Philipp Dunkel
+
+Wed Mar  5 10:57:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastype.c: made powten array static it should not be exported
+	* HTMLparser.c: fix bug #107361 by reusing the code from the XML 
+	  parser function.
+	* testHTML.c: get rid of valgrind messages on the HTML SAX tests
+
+Fri Feb 28 00:23:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed a node dump crash on attributes
+	* test/xsdtest/xsdtest.xml test/xsdtest/xsdtest.xsl: fixed
+	  an URI test bug and get better output.
+
+Thu Feb 27 22:28:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xsddata-test-suite.py: give more infos
+	* relaxng.c: fix a bug reported by Sebastian Rahtz and
+	  REF->DEF in attribute values.
+
+Thu Feb 27 21:09:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xsddata-test-suite.py test/xsdtest/xsdtest.xml
+	  test/xsdtest/xsdtest.xsl: import of the XSD Datatype
+	  regression tests from James Clark.
+
+Thu Feb 27 18:40:04 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlschemas.c xmlschemastypes.c
+	  include/libxml/xmlschemastypes.h: added param support for relaxng
+	  type checking, started to increment the pool of simple types
+	  registered, still much work to be done on simple types and
+	  facets checkings.
+
+Wed Feb 26 16:45:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: fixes again one of the problem raised by
+	  James Clark in #106788
+
+Wed Feb 26 15:46:48 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: Fixed a couple of problem raised by James Clark
+	  in bug #107083, the support for ID/IDREF/IDREFS at the WXS
+	  datatype level still not fixed though.
+
+Mon Feb 24 21:09:19 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing release 2.5.4
+	* doc/*: updated and rebuilt the docs
+	* relaxng.c: removed warnings
+	* result/relaxng/*: updated the results
+
+Mon Feb 24 20:53:17 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixes a DTD regexp generation problem.
+
+Mon Feb 24 20:12:57 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixes bug #105998 about false detection of
+	  attribute consumption loop.
+
+Mon Feb 24 19:14:57 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: Fixes bug #106931 in XInclude entities merging.
+
+Mon Feb 24 18:50:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixed bug #105992
+
+Mon Feb 24 18:14:16 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed xmlSetProp and al. when the node passed is not an
+	  element.
+	* relaxng.c: fixed bugs 7.3 (though not complete) and memory leaks
+	  found 373 test schemas: 369 success 4 failures
+	  found 529 test instances: 525 success 4 failures
+	* check-relaxng-test-suite.py: added memory debug reporting
+
+Mon Feb 24 12:41:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c parser.c: some warning removal on Igor's patch
+	* tree.c: seems I messed up with #106788 fix
+	* python/libxml.c: fixed some base problems when Python provides
+	  the resolver.
+	* relaxng.c: fixed the interleave algorithm 
+	  found 373 test schemas: 364 success 9 failures
+	  found 529 test instances: 525 success 4 failures
+	  the resulting failures are bug in the algorithm from 7.3 and
+	  lack of support for params
+
+Sun Feb 23 14:49:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: another fix for nodeinfo in entities problem
+	* tree.c entities.c: fixed bug #106788 from James Clark
+	  some spaces need to be serialized as character references.
+
+Sat Feb 22 18:28:16 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* parser.c uri.c: fixed the bug I introduced in the path
+	  handling, reported by Sebastian Bergmann
+
+Sat Feb 22 00:19:48 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing some nodeinfo in entities problem raised
+	  by Glenn W. Bach
+	* relaxng.c: implemented the first section 7.3 check
+	* result/relaxng/*: updated the results
+
+Fri Feb 21 18:12:19 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: fixed some problems in the previous commit
+	  and finished implementing 4.16 rules checking
+	  found 373 test schemas: 353 success 20 failures
+	  found 529 test instances: 519 success 6 failures
+	* result/relaxng/*: updated the results
+
+Fri Feb 21 16:37:39 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: implemented checks from section 7.2
+
+Thu Feb 20 16:00:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: implemented the checks from section 7.1, fixed
+	  some of the 4.20 and 4.21 problems.
+	  found 373 test schemas: 338 success 35 failures
+	  found 529 test instances: 519 success 6 failures
+	* result/relaxng/*: updated the results
+
+Thu Feb 20 01:09:24 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: implemented the 4.20 and 4.21 simplification rules.
+	* result/relaxng/*: updated the results
+
+Wed Feb 19 18:30:30 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more bugfixes
+	* result/relaxng/*: updated the results
+
+Wed Feb 19 15:39:56 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* DOCBparser.c: obsoleted xmlNormalizeWindowsPath
+	* HTMLparser.c: obsoleted xmlNormalizeWindowsPath
+	* SAX.c: ensured xmlDoc.URL is always canonic
+	* parser.c: obsoleted xmlNormalizeWindowsPath
+	* uri.c include/libxml/uri.h: introduced xmlCanonicPath
+	* xmlIO.c include/libxml/xmlIO.h: obsoleted xmlNormalizeWindowsPath
+	* win32/libxml2.def.src: added few exports
+
+Wed Feb 19 14:26:51 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in: patched to have shared libraries
+	  for Python regression tests and static binaries for gdb debug
+	  in my development environment
+	* relaxng.c: more bugfixes 
+	  found 373 test schemas: 296 success 77 failures
+	  found 529 test instances: 516 success 8 failures
+	* result/relaxng/*: updated the results
+
+Wed Feb 19 01:17:48 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: guess what ! Relax-NG bugfixing, what a surprize...
+
+Tue Feb 18 22:09:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: float/double check bugfix
+	* tree.c include/libxml/tree.h: exported a function for NMTOKEN
+	  validation
+	* xmlreader.c: add a TODO for Jody
+	* relaxng.c: bugfix bugfix bugfix
+	  found 373 test schemas: 300 success 73 failures
+	  found 529 test instances: 507 success 10 failures
+	* result/relaxng/*: updated the results
+
+Tue Feb 18 00:33:17 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c check-relaxng-test-suite.py: more RelaxNG bug hunting
+
+Mon Feb 17 18:23:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c check-relaxng-test-suite.py: more work on the
+	  RelaxNG implementation conformance testing.
+	  found 373 test schemas: 284 success 89 failures
+	  found 529 test instances: 448 success 47 failures
+	* result/relaxng/*: updated the results
+
+Sun Feb 16 16:48:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* ChangeLog tree.c doc/libxml-doc.el doc/libxml2-api.xml: applied
+	  a patch from Kjartan Maraas to fix some typos
+
+Sun Feb 16 16:40:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more bug-hunting
+	* testRelax.c include/libxml/relaxng.h: added --tree to dump the
+	  intermediate rng tree
+	* python/generator.py: patch from Stéphane Bidoul to fix the generator
+	  on python < 2.2
+
+Fri Feb 14 17:49:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-relaxng-test-suite.py relaxng.c: more testing on the
+	  Relax-NG front, cleaning up the regression tests failures
+	  current state and I forgot support for "mixed":
+	  found 373 test schemas: 280 success 93 failures
+	  found 529 test instances: 401 success 68 failures
+	* tree.c include/libxml/tree.h xmlschemastypes.c: finished and
+	  moved the Name, NCName and QName validation routine in tree.c
+	* uri.c: fixed handling of URI ending up with #, i.e. having
+	  an empty fragment ID.
+	* result/relaxng/*: updated the results
+
+Thu Feb 13 16:49:24 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xinclude-test-suite.py: improved the script accordingly
+	  to the XInclude regression tests updates
+	* xpointer.c: Implemented XPointer element() Scheme W3C PR of 13
+	  November 2002
+	* result/XPath/xptr/chapterschildseq result/XPath/xptr/vidchildseq
+	  test/XPath/xptr/chapterschildseq test/XPath/xptr/vidchildseq:
+	  augmented the Xpointer testsuite for the element() scheme
+
+Thu Feb 13 12:00:30 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: added TODO for the DTD compatibility spec
+	* xinclude.c: more bug fixes driven by the testsuite 
+
+Tue Feb 11 19:01:02 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* check-xinclude-test-suite.py xinclude.c: Work on the W3C/NIST
+	  regression tests for XInclude, improved the script, improving
+	  XInclude error reporting mechanism
+
+Mon Feb 10 17:19:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/* configure.in: preparing release 2.5.3
+
+Mon Feb 10 17:11:22 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: trying to fix #104934 about some XHTML1 serialization
+	  issues.
+
+Mon Feb 10 16:41:13 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c xmlIO.c: fixing bug #104646 about iconv based
+	  encoding conversion when the input buffer stops in the
+	  middle of a multibyte char
+
+Mon Feb 10 15:24:47 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* test/relaxng/OASIS/spectest.xml: OASIS RelaxNG testsuite
+	* check-relaxng-test-suite.py: python script to run regression
+	  against OASIS RelaxNG testsuite
+	* relaxng.c: some cleanup tweaks
+	* HTMLparser.c globals.c: cleanups in comments
+	* doc/libxml2-api.xml: updated the API
+	* result/relaxng/*: errors moved files, so large diffs but
+	  no changes at the semantic level.
+
+Mon Feb 10 01:00:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixing #105678 problem when dumping a namespace node.
+
+Mon Feb 10 00:30:01 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed doc comment problems
+	* python/generator.py python/libxml_wrap.h python/types.c: adding
+	  RelaxNG wrappers
+	* python/tests/Makefile.am python/tests/relaxng.py: added a specific
+	  test of those early Python RelaxNG bindings
+
+Sun Feb  9 15:18:43 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: fixes a libtool problem on AMD 64bits builds
+	* relaxng.c: found the validation problem I had with interleave
+	  when not covering all remaining siblings
+	* Makefile.am test.relaxng/* result/relaxng/*: augmented the
+	  testsuite and check the RNG schemas against the RNG schemas
+	  given in appendix A
+
+Sat Feb  8 18:55:43 CET 2003 Igor Zlatkovic <igor@zlatkovic.com>
+
+	* win32/Makefile.msvc: updates for RelaxNG
+	* win32/Makefile.mingw: updates for RelaxNG
+	* win32/libxml2.def.src: added RelaxNG exports
+
+Fri Feb  7 14:00:53 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: applied another bug fix from Sean Chittenden
+
+Fri Feb  7 13:34:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xmllint.c: I f...ed up the default configuration
+	  of schemas and --relaxng option display in xmllint, pointed by
+	  Morus Walter.
+	* xlink.c: Sean Chittenden pointed a couple of errors in the XLink
+	  detection module, fixes bug #105374.
+
+Fri Feb  7 01:43:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: added the boolean base type.
+
+Thu Feb  6 10:23:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: started implementing some of the missing
+	  default simple types
+	* result/relaxng/*: updated the results
+
+Wed Feb  5 15:28:04 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/*: updated the docs, ready for 2.5.2 release
+
+Wed Feb  5 14:15:59 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c tree.c xmlIO.c: comments cleanups
+	* Makefile.am: use xmllint for doing the RelaxNG tests
+	* configure.in: preparing 2.5.2 made schemas support default to
+	  on instead of off
+	* relaxng.c: removed the verbosity
+	* xmllint.c: added --relaxng option
+	* python/generator.py python/libxml_wrap.h: prepared the integration
+	  of the new RelaxNG module and schemas
+	* result/relaxng/*: less verbose output
+
+Wed Feb  5 12:00:36 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: do not run content model validation if the
+	  content is not determinist
+
+Wed Feb  5 11:43:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: added the redefinition of namespaced attribute
+	  check that was missing as Fabrice Desré pointed out.
+
+Wed Feb  5 11:09:29 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c include/libxml/HTMLparser.h: applied HTML
+	  improvements from Nick Kew, allowing to do more checking
+	  to HTML elements and attributes.
+
+Tue Feb  4 23:47:06 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fixing bug #105137 about entities declaration
+	  needing to be copied to the including document.
+
+Tue Feb  4 20:26:22 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixed bug #104817 with delegateURI
+	* xpath.c: fixing bugs #104123 and #104125
+
+Tue Feb  4 17:12:56 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in valid.c xmlreader.c python/libxml_wrap.h 
+	  python/types.c: fixing #104096 to compile without regexps
+
+Tue Feb  4 16:31:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixing bug #103969 forgot to add an epsilon transition
+	  when building the automata for elem*
+
+Tue Feb  4 16:21:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: applied patch from Arne de Bruijn fixing 
+	  bug #103827
+
+Tue Feb  4 16:17:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: updating a comment, fixing #103776
+
+Tue Feb  4 16:05:53 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing bug 105049 for validity checking of content
+	  within recursive entities.
+
+Tue Feb  4 15:40:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: try to fix # 105049
+	* relaxng.c xmlschemastypes.c: a couple of changes and extensions
+	* tree.c: updated a function comment
+
+Tue Feb  4 00:20:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: more work on grammars and refs/defs
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Mon Feb  3 14:16:59 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: more work on name classes, except support
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Mon Feb  3 11:56:05 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: more work on name classes, the "validate all" schemas
+	  seems to work now.
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Mon Feb  3 09:50:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: removed an unprotedted debug message Aleksi Suhonen
+	* parser.c: put a guard against infinite document depth, basically
+	  trying to avoid another kind of DoS attack.
+	* relaxng.c: some code w.r.t. nameClasses
+
+Sun Feb  2 17:01:43 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* test/relaxng/* result/relaxng/*: check all the namespace support
+	  was actually correct based on tutorial section 10.
+
+Sun Feb  2 15:33:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: include seems to work okay now
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Sat Feb  1 19:44:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: a bit of work done in the train back.
+	* test/relaxng/*: added one of the include tests
+
+Thu Jan 30 14:06:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: more work done in the train
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Wed Jan 29 23:44:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: debugging of externalRef
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
+Wed Jan 29 22:06:04 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG, implementing externalRef
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+	* Makefile.am: cleanup to Relaxtests target
+
+Wed Jan 29 00:08:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG, implementing interleave
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+
+Tue Jan 28 21:56:49 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG, implementing interleave
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+
+Mon Jan 27 07:35:29 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/customfo.xsl
+	* doc/tutorial/customhtml.xsl
+	adding stylesheet customizations used to generate fo
+	for pdf and html
+
+Mon Jan 27 13:29:43 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+	* xmlschemastypes.c: added a number of base type definition but not
+	  the associated checks, those are still TODOs
+
+Sun Jan 26 17:37:06 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	in docs/tutorial:
+	* apa.html
+	* apb.html
+	* apc.html
+	* apd.html
+	* ape.html
+	* apf.html
+	* apg.html
+	* ar01s02.html
+	* ar01s03.html
+	* ar01s04.html
+	* ar01s05.html
+	* ar01s06.html
+	* ar01s07.html
+	* ar01s08.html
+	* index.html
+	* xmltutorial.pdf
+	* xmltutorial.xml
+	add index to tutorial
+
+Sun Jan 26 17:02:29 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog.1
+	* doc/xmlcatalog_man.html
+	* doc/xmlcatalog_man.xml
+	belatedly fixing bug #93622 (adds rewriteURI type to
+	"--add" option in xmlcatalog man page
+
+Sun Jan 26 20:47:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c xmllint.c: applied patch for NetBSD by
+	  Julio Merino, closing #104475
+
+Sun Jan 26 20:38:43 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+
+Sun Jan 26 01:49:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+
+Sat Jan 25 18:59:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* README: updated the policy on private mail answers
+	* relaxng.c: more work on Relax-NG
+	* test/relaxng/* result/relaxng/*: augmented/updated the 
+	  regression tests
+
+Fri Jan 24 15:12:44 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c parser.c tree.c: applied a documentation patch from
+	  Stefan Kost
+
+Fri Jan 24 02:00:50 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more work on Relax-NG
+	* doc/*: regenerated the docs
+	* test/relaxng/* result/relaxng/*: updated and augmented the
+	  Relax-NG regression tests and results
+
+Thu Jan 23 19:26:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in relaxng.c include/libxml/relaxng.h:
+	  First commit of the new Relax-NG validation code, not generally
+	  useful yet.
+	* test/relaxng/* result/relaxng/*: current state of the regression
+	  tests
+
+Thu Jan 23 19:22:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: minimized the memory allocated for GetContent
+	  and a bit of cleanup.
+
+Thu Jan 23 17:41:37 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: seems there is no good reasons to
+	  not generate bindings for XPointer
+
+Tue Jan 21 13:19:35 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c doc/apibuild.py: applied a new patch from
+	  Stéphane Bidoul for cleanups
+	* doc/libxml2-api.xml: rebuilt the API description with
+	  new entry points
+
+Mon Jan 20 23:25:00 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/drv_libxml2.py python/generator.py
+	  python/libxml.c python/libxml.py python/libxml_wrap.h
+	  python/types.c: patch from Stéphane Bidoul for better per
+	  context error message APIs
+	* python/tests/ctxterror.py python/tests/readererr.py:
+	  update of the tests
+
+Sun Jan 19 17:09:28 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/guidelines.html
+	grammar and spelling cleanup
+
+Fri Jan 17 00:31:30 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h python/generator.py
+	  python/libxml.c python/libxml.py win32/libxml2.def.src: applied
+	  a patch from Stéphane Bidoul to allow per XMLtextReader error
+	  and warning handling
+	* python/tests/Makefile.am python/tests/readererr.py: adding the
+	  specific regression test
+
+Tue Jan 14 17:00:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: Alexey Efimov pointed out that concat('a', 'b', )
+	  should raise a syntax error
+
+Tue Jan 14 15:39:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: cleanup patch from Stéphane Bidoul
+
+Tue Jan 14 14:41:18 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fixing bug #103100 with a dummy UTF8ToUTF8 copy
+
+Tue Jan 14 12:40:29 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml.py
+	  python/libxml_wrap.h python/types.c: applied and fixed a patch
+	  from Stéphane Bidoul to provide per parser error handlers at the
+	  Python level.
+	* python/tests/Makefile.am python/tests/ctxterror.py: added a
+	  regression test for it.
+
+Tue Jan 14 01:15:04 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: fixed the streaming property of the reader,
+	  it was generating tree faster than consuming it. Pointed out
+	  by Nate Myers
+	* tree.c: fixed a bug in xmlSaveFormatFileEnc if passed a NULL doc
+
+Sun Jan 12 22:18:02 CET 2003 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: added more xmlreader and other exports
+
+Fri Jan 10 18:04:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fix to the XPath implementation for parent and
+	  ancestors axis when operating on a Result Value Tree.
+	  Fixes bug #100271
+
+Fri Jan 10 17:07:01 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c xmlIO.c: patch from Stefano Zacchiroli
+	  to fix some URI/file escaping problems
+
+Fri Jan 10 16:20:34 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: fixed a bug raised by Raymond Wiker, 
+	  docSetRootElement() should not raise an exception if the
+	  return is None
+
+Fri Jan 10 14:13:03 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py python/libxml.c python/libxml2-python-api.xml:
+	  fixed bug #102181 by applying the suggested change and fixing
+	  the generation/registration problem.
+
+Fri Jan 10 13:47:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed bug #102960 by reusing the XML name parsing
+	  routines.
+
+Fri Jan 10 00:16:49 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: one more IsEmptyElement crazyness, that time in
+	  external parsed entities if substitution is asked.
+	* python/tests/reader3.py: added a specific test.
+
+Thu Jan  9 22:35:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/drv_libxml2.py: update from Stéphane Bidoul: python 2.1
+	  support and improved error handler registration
+
+Thu Jan  9 14:16:38 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c tree.c: fixes #102920 about namespace handling in
+	  HTML output and section 16.2 "HTML Output Method" of XSLT-1.0
+	* README: fixed a link
+
+Wed Jan  8 18:32:25 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in doc/* NEWS: preparing 2.5.1 release
+	* SAX.c parser.c: fixing XmlTextReader bug
+
+Wed Jan  8 00:13:01 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fuck, I introduced a memory leak on external parsed
+	  entities in 2.5.0 :-(
+
+Tue Jan  7 12:12:45 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: another fix needed as pointed by Christophe Merlet
+	  for --stream --debug if compiled without debug support.
+
+Mon Jan  6 20:53:08 MST 2003 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml
+	* doc/xmllint.1:
+	update man page with --stream and --chkregister
+
+Tue Jan  7 01:17:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: fixed --with-threads compile
+	* xmllint.c: fixed --without-debug compile
+	* include/libxml/globals.h: cleanup
+	* include/libxml/schemasInternals.h: add a missing include
+
+Mon Jan  6 14:06:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in NEWS: preparing 2.5.0 release
+	* SAX.c: only warn in pedantic mode about namespace name 
+	  brokeness
+	* globals.c: fix a doc generation problem
+	* uri.c: fix #101520
+	* doc/*: updated and rebuilt the doc for the release, includuding
+	  stylesheet update
+	* python/Makefile.am: fix a filename bug
+
+Mon Jan  6 12:05:12 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/tutorial/* : fixed #101894 if doc == NULL xmlFreeDoc 
+	  should not be called.
+
+Mon Jan  6 11:59:09 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml-2.0.pc.in: applied the patch to fix #101894
+
+Sun Jan  5 23:35:47 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c : applied patch from Lukas Schroeder for register callbacks
+	* valid.c: modified patch from Lukas Schroeder to test
+	  register callbacks with --chkregister
+
+Sun Jan  5 02:23:20 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: seriously changed the way data are pushed to
+	  the underlying parser, go by block of 512 bytes instead of
+	  tryng to detect tag boundaries at that level. Changed the
+	  way empty element are detected and tagged.
+	* python/tests/reader.py python/tests/reader2.py
+	  python/tests/reader3.py: small changes mostly due to context
+	  reporting being different and DTD node being reported. Some
+	  errors previously undetected are now caught and fixed.
+	* doc/xmlreader.html: flagged last section as TODO
+
+Sat Jan  4 20:40:28 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: integrated the Python 2.2 optimizations
+	  from Hannu Krosing, while maintaining compatibility with 
+	  1.5 and 2.1
+
+Sat Jan  4 17:33:17 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: a bit of cleanup
+	* xmlreader.c: small fix
+	* doc/xmlreader.html: more work on the XmlTextReader tutorial
+	* python/libxml.py: a few fixes pointed out by Hannu Krosing
+
+Sat Jan  4 13:46:14 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* python/setup.py.in: patch from Stéphane Bidoul to include
+	  drv_libxml2.py in setup.py
+
+Sat Jan  4 01:43:06 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmlreader.html: starting documenting the new XmlTextReader
+	  interface.
+
+Fri Jan  3 17:18:32 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added the --stream flag to use the TextReader API
+	* xmlreader.c: small performance tweak
+
+Fri Jan  3 13:50:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader2py: okay the DTD validation
+	  code on top of the XMLTextParser API should be solid now.
+
+Fri Jan  3 02:17:18 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader2py: Fixing some more mess
+	  with validation and recursive entities while using the
+	  reader interface, it's getting a bit messy...
+
+Thu Jan  2 15:15:26 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: another couple of problem
+	  related to IsEmptyElement reported by Stéphane Bidoul needed 
+	  some fixes.
+
+Thu Jan  2 13:57:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in python/Makefile.am python/drv_libxml2.py:
+	  integrated drv_libxml2.py Python xml.sax driver from Stéphane Bidoul
+	  based on the python XmlTextReader interface.
+
+Wed Jan  1 22:05:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: backing out one change in the last patch which broke the
+	  regression tests
+
+Wed Jan  1 21:57:28 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* global.data globals.c tree.c include/libxml/globals.h: applied
+	  an old patch from Lukas Schroeder to track node creation and
+	  destruction. Probably missing a lot of references at the moment
+	  and not usable reliably.
+
+Wed Jan  1 20:12:07 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS doc/Makefile.am doc/news.xsl: generate the NEWS file
+	  from doc/news.html and a stylesheet
+
+Wed Jan  1 16:09:57 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: fixed another couple of
+	  xmlreader bugs reported by Stéphane Bidoul and added tests.
+
+Wed Jan  1 15:42:54 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader2.py: fixed another validity
+	  checking in external parsed entities raised by Stéphane Bidoul
+	  and added a specific regression test.
+	* python/tests/reader3.py: cleanup
+
+Tue Dec 31 15:44:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader2.py: fixed a problem with
+	  validation within entities pointed by Stéphane Bidoul, augmented
+	  the tests to catch those.
+
+Tue Dec 31 12:15:37 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: modified the generator to allow keeping
+	  class references when creating new classes, needed to fix a bug
+	  pointed by Stéphane Bidoul where the input buffer of the
+	  xmlTextReader instance gets destroyed if the python wrapper for
+	  the input is not referenced anymore.
+
+Mon Dec 30 19:39:36 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: fixed another pair of problem
+	  pointed by Stéphane Bidoul: depth start at 0 and a parse problem.
+
+Mon Dec 30 13:36:50 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: fixed another problem
+	  pointed by Stéphane Bidoul
+
+Mon Dec 30 12:39:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: fixed a limit case problem
+	  with "<a/>"
+
+Mon Dec 30 11:53:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: warn on xmlns:prefix="foo"
+	* xmlreader.c python/tests/reader.py: fixed a couple of problem
+	  for namespace attributes handling.
+
+Mon Dec 30 00:59:07 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c parser.c tree.c include/libxml/entities.h: Fixed
+	  a really nasty problem raised by a DocBook XSLT transform
+	  provided by Sebastian Bergmann
+
+Sun Dec 29 12:13:18 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader.py: fixed a bug pointed out
+	  by Stéphane Bidoul and integrated it into the tests
+
+Sat Dec 28 23:49:12 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml:
+	  extended the XmlTextReader API a bit, addding accessors for
+	  the current doc and node, and an entity substitution mode for
+	  the parser.
+	* python/libxml.py python/libxml2class.txt: related updates
+	* python/tests/Makefile.am python/tests/reader.py 
+	  python/tests/reader2.py python/tests/reader3.py: updated a bit
+	  the old tests and added a new one to test the entities handling
+
+Sat Dec 28 22:11:57 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml2class.txt 
+	  python/tests/reader.py python/tests/reader2.py: changed the
+	  generator to provide casing for the XmlTextReader similar to
+	  C# so that examples and documentation are more directly transposable.
+	  Fixed the couple of tests in the suite.
+
+Sat Dec 28 15:55:32 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/guidelines.html: added a document on guildeline for
+	  publishing and deploying XML
+
+Fri Dec 27 20:35:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c xmlreader.c: final touch running DTD validation
+	  on the XmlTextReader
+	* python/tests/Makefile.am python/tests/reader2.py: added a
+	  specific run based on the examples from test/valid/*.xml
+
+Fri Dec 27 15:17:20 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.py: added a few predefined xmlTextReader parser
+	  configuration values.
+
+Fri Dec 27 12:57:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml_wrap.h: trying to fix #102037
+
+Fri Dec 27 12:18:14 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixing bug #95296, when the predefined entities
+	  are redefined in the DTD the default one must be used
+	  instead anyway.
+
+Wed Dec 25 19:22:06 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml
+	* doc/xmllint.1
+	Add discussion of XML_DEBUG_CATALOG to xmllint man
+	page - bug #100907
+
+Mon Dec 23 16:54:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c: Fixed the empty node detection to avoid reporting
+	  an inexistant close tag.
+
+Mon Dec 23 15:42:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/setup.py.in: patch from Stéphane Bidoul
+	  for Python 2.1
+
+Sun Dec 22 11:24:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* testC14N.c vms/config.vms: applied Craig A. Berry patches for VMS
+
+Fri Dec 20 11:27:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/libxml2-api.xml python/tests/reader.py: one really need
+	  to provide the base URI information when creating a reader parser
+	  from an input stream. Updated the API and the example using it.
+
+Fri Dec 20 01:11:30 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* testReader.c xmlreader.c valid.c include/libxml/tree.h
+	  include/libxml/valid.h include/libxml/xmlreader.h: working on
+	  DTD validation on top of xml reader interfaces. Allows to
+	  validate arbitrary large instances. This required some extensions
+	  to the valid module interface and augmenting the size of xmlID
+	  and xmlRef structs a bit.
+	* uri.c xmlregexp.c: simple cleanup.
+
+Wed Dec 18 15:51:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: more
+	  work on the xml reader interfaces.
+	* AUTHORS MAINTAINERS doc/* win32/*: updated Igor's mail and the
+	  Web page for the Windows binaries.
+
+Tue Dec 17 19:31:07 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied a patch for VMS following the report by
+	  Nigel Hall
+
+Tue Dec 17 11:29:41 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: the parseStartTag bug fix wasn't complete.
+
+Mon Dec 16 23:00:05 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Vyacheslav Pindyura managed to trigger a bug in
+	  parseStartTag, fixing it.
+	* test/att4 result/att4 result/noent/att4: adding the test
+	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: added
+	  more methods to XmlTextReader.
+
+Mon Dec 16 19:31:16 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: added more xml reader exports
+	* win32/Makefile.msvc win32/Makefile.mingw: added xml reader interface
+	  to the build
+
+Mon Dec 16 06:36:54 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml
+	plus generated html and pdf
+	Updating tutorial again based on further comments from Niraj
+	Tolia on the last iteration
+
+Sun Dec 15 21:27:30 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml
+	* doc/tutorial/includekeyword.c
+	* doc/tutorial/includegetattribute.c
+	plus generated html and pdf
+	Adding fix from Niraj Tolia to tutorial to properly free memory.
+
+Mon Dec 16 00:34:25 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: added
+	  more methods of XmlTextReader.
+	* python/libxml2class.txt python/tests/reader.py: this increased the
+	  methods in the bndings, augmented the test to check those new
+	  functions.
+
+Sat Dec 14 23:57:39 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c doc/libxml2-api.xml: added the close and getattribute
+	  methods of XmlTextReader.
+	* python/generator.py python/libxml_wrap.h python/types.c 
+	  python/libxml2class.txt: added the reader to the Python bindings
+	* python/tests/Makefile.am python/tests/reader.py: added a specific
+	  test for the Python bindings of the Reader APIs
+	* parser.c: small cleanup.
+
+Fri Dec 13 11:39:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: fallback was only copying the first child not the
+	  full child list of the fallback element, closes #89684 as reopened
+	  by Bernd Kuemmerlen
+
+Thu Dec 12 13:34:59 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: exported htmlNodeDumpOutput
+
+Thu Dec 12 10:59:11 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing release of 2.4.30
+	* doc/apibuild.py doc/libxml2-api.xml: fixups to the api builder,
+	  gives enum values, fix functype return type, put back fields in
+	  structs 
+	* doc/*: updated the docs rebuilt
+
+Thu Dec 12 01:09:34 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c include/libxml/HTMLtree.h: patch from Mark Vakoc
+	  about htmlNodeDumpOutput location.
+	* xpath.c: removed an undefined function signature
+	* doc/apibuild.py doc/libxml2-api.xml: the script was exporting
+	  too many symbols in the API breaking the python bindings.
+	  Updated with the libxslt/libexslt changes.
+
+Wed Dec 11 20:26:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing release of 2.4.29
+	* doc/*: rebuilt the docs and API
+	* xmlreader.c: a few more fixes for the XmlTextReader API
+
+Wed Dec 11 18:01:15 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* include/win32config.h: applied mingw patch from Magnus Henoch
+
+Wed Dec 11 16:58:48 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c doc/libxml2-api.xml: a bit more cleanup
+
+Wed Dec 11 14:54:47 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/apibuild.py doc/libxml2-api.xml doc/Makefile.am: new API
+	  building Python script, does the C parsing directly, generates
+	  a better API description including structure fieds defs and
+	  enums. Still a couple of bugs, but good enough for the python
+	  wrappers now.
+	* DOCBparser.c SAX.c nanohttp.c parser.c parserInternals.c tree.c
+	  valid.c xmlIO.c xmlmemory.c xmlreader.c xmlregexp.c xmlschemas.c
+	  include/libxml/schemasInternals.h include/libxml/tree.h: more
+	  cleanup based on the python analysis script reports.
+	* libxml.spec.in: make sure the API XML description is part of the
+	  devel package.
+
+Tue Dec 10 16:16:34 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c HTMLparser.c c14n.c debugXML.c encoding.c hash.c
+	  nanoftp.c nanohttp.c parser.c parserInternals.c testC14N.c
+	  testDocbook.c threads.c tree.c valid.c xmlIO.c xmllint.c xmlmemory.c
+	  xmlreader.c xmlregexp.c xmlschemas.c xmlschemastypes.c xpath.c:
+	  code cleanup, especially the function comments.
+	* tree.c: fixed a small bug when freeing nodes which are XInclude ones.
+
+Mon Dec  9 15:08:17 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am xmlreader.c include/libxml/Makefile.am
+	  include/libxml/xmlreader.h:  Adding a new set of APIs based on
+	  the C# TextXmlReader API but converted to C. Allow to parse
+	  in constant memory usage, far simpler to program and explain
+	  than the SAX like APIs, unfinished but working.
+	* testReader.c: test program
+
+Sun Dec  8 18:36:01 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: applied YALDSP from Mark Vakoc
+
+Wed Dec  4 16:08:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Chip turner indicated that XHTML1 serialization
+	  rule for style actually break on both IE and Mozilla, 
+	  try to avoid the rule if escaping ain't necessary
+
+Wed Dec  4 12:43:28 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* nanhttp.c: handle HTTP URL escaping, problem reported by
+	  Glen Nakamura and Stefano Zacchiroli
+
+Sat Nov 30 12:19:17 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c HTMLparser.c parser.c valid.c xpath.c: code cleanup
+
+Thu Nov 28 12:53:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: Johann Richard pointed out some XPointer problems for
+	  URN based URI references in XInclude. Modified the URI parsing
+	  and saving routines to allow correct parsing and saving of 
+	  XPointers, especially when attached to "opaque" scheme accordingly
+	  to RFC 2396
+
+Wed Nov 27 20:36:08 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c include/libxml/HTMLtree.h: applied the same kind
+	  of refactoring to the HTML saving code.
+	* doc/libxml2-*.xml doc/API*.html: slight API changes got reflected
+	  in the doc.
+
+Wed Nov 27 12:40:16 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c include/libxml/tree.h: refactored the XML dump of a node
+	  to a buffer API to reuse the generic dump to an OutputIO layer,
+	  this reduces code, fixes xmlNodeDump() for XHTML, also made
+	  xmlNodeDump() now return the number of byte written.
+
+Wed Nov 27 09:00:00 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/setup.py.in: another patch from Stéphane Bidoul for 
+	  Python bindings on Windows
+	* doc/parsedecl.py: small cleanup
+
+Mon Nov 25 17:28:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in configure.in: add a line in %changelog for releases
+
+Mon Nov 25 14:18:27 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: patch from Marcus Clarke fixing a problem in entities
+	  parsing that was detected in KDe documentations environment.
+
+Mon Nov 24 14:13:21 CET 2002 ERDI Gergo <cactus@cactus.rulez.org>
+
+	* python/libxml.c (libxml_prev): Return the previous as opposed to
+	the next node (I guess this is the result of some cut & paste programming:)
+
+Sat Nov 23 17:22:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am: Jan Rafaj pointed a bug in the Makefile.
+
+Sat Nov 23 12:21:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/setup.py.in: trying
+	  to fix the Python bindings build on Windows (Stéphane Bidoul)
+
+Fri Nov 22 22:41:34 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/configure.js: added option for python bindings
+	* win32/libxml2.def.src: added more exports
+
+Fri Nov 22 18:50:34 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/Makefile.mingw: fixed unresolved symbols when linking with
+	  pthreads
+	* win32/wince/*: applied updates to Windows CE port from Javier
+
+Fri Nov 22 15:51:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.28
+	* libxml.spec.in doc/Makefile.am: some cleanup
+	* doc/*: updated the news and regenerated.
+
+Fri Nov 22 14:15:14 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: final touch at closing #87235 </p> end tags
+	  need to be generated.
+	* result/HTML/cf_128.html result/HTML/test2.html result/HTML/test3.html:
+	  this change slightly the output of a few tests
+	* doc/*: regenerated
+
+Fri Nov 22 13:26:19 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fixing bug #99190 when UTF8 document are
+	  parsed using the progressive parser and the end of the chunk
+	  is in the middle of an UTF8 multibyte character.
+
+Fri Nov 22 13:13:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
+
+	* threads.c: fixed initialization problem in xmlNewGlobalState
+	  which was causing crash.
+	* globals.c: removed duplicate call to initxmlDefaultSAXHandler
+	  in xmlInitializeGlobalState.
+	* parserInternals.c: cleaned up ctxt->sax initialisation.
+
+Thu Nov 21 15:05:45 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c include/libxml/tree.h: modified the existing APIs
+	  to handle XHTML1 serialization rules automatically, also add
+	  xmlIsXHTML() to libxml2 API. Some tweaking to make sure
+	  libxslt serialization uses it when needed without changing
+	  the library API.
+	* test/xhtml1 result/noent/xhtml1 result/valid/xhtml1.xhtml
+	  result/xhtml1: added a new test specifically for xhtml1 output
+	  and updated the result of one XHTML1 test
+
+Wed Nov 20 14:24:56 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c parserInternals.c encoding.c: fixed #99082
+	  for xi:include encoding="..." support on text includes.
+	* result/XInclude/tstencoding.xml test/XInclude/docs/tstencoding.xml
+	  test/XInclude/ents/isolatin.txt : added a specific regression test
+	* python/generator.py python/libxml2class.txt: fixed the generator
+	  the new set of comments generated for doc/libxml2-api.xml were
+	  breaking the python generation.
+
+Tue Nov 19 23:25:47 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am: repair some problem if gtk-doc fail or such
+	* configure.in: patch for Solaris on new autoconf closes #98880 
+	* doc/parsedecl.py: repair the frigging API building script,
+	  did I say that python xmllib sucks ?
+	* doc/libxml2-api.xml doc/libxml2-refs.xml: regenerated, reordering
+	  and some comment are no more truncated.
+
+Tue Nov 19 09:09:04 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Martin Stoilov pointed out a potential leak in
+	  xmlCreateMemoryParserCtxt
+
+Mon Nov 18 16:05:51 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed bug #98879 a corner case when 0 is
+	  included in HTML documents and using the push parser.
+
+Mon Nov 18 00:11:24 CET 2002 ERDI Gergo <cactus@cactus.rulez.org>
+
+	* configure.in (PYTHON_SITE_PACKAGES): If --with-python is
+	  specified, look for the Python interpreter not just in the
+	  specified root but also in the specified location. Fixes #98825
+
+Sun Nov 17 23:36:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: fixing bug #98792 , node may have no doc
+	  and dereferencing without checking ain't good ...
+
+Sun Nov 17 10:25:43 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing release 2.4.27
+	* doc/* : updated and rebuilt the docs
+	* doc/Makefile.am libxml.spec.in: try to make sure the tutorial
+	  and all the docs are actually packaged and in the final RPMs
+	* parser.c parserInternals.c include/libxml/parser.h: restore
+	  xmllint --recover feature.
+
+Sat Nov 16 16:30:25 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c xpath.c: fixing #96925 wich was also dependent on the
+	  processing of parsed entities, and XPath computation on sustitued
+	  entities.
+	* testXPath.c: make sure entities are substitued.
+
+Fri Nov 15 16:22:54 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed #96594, which was totally dependent on the 
+	  processing of internal parsed entities, which had to be changed.
+
+Fri Nov 15 12:16:07 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am python/Makefile.am python/tests/Makefile.am:
+	  trying to fix bug #98517 about building outside the source tree
+	* doc/xml.html doc/FAQ.html: fixed the link to libiconv #94585
+
+Thu Nov 14 18:41:55 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* include/win32config.h: cleanup
+	* win32/Makefile.mingw: integrated mingw in JScript configure
+	* win32/Makefile.msvc: modified to allow mingw coexistence
+	* win32/configure.js: integrated mingw
+	* win32/Readme.txt: cleanup
+
+Tue Nov 12 22:06:45 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: strengthen the guard in the Pop macros,
+	  like in the XML parser, closes bug #97315
+
+Tue Nov 12 21:56:39 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h: fixed bug #98338 , fatalError SAX
+	  callback is never used.
+
+Tue Nov 12 13:32:50 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: fixed the initialization of the SAX structure
+	  which was breaking xsltproc
+	* xpath.c: patch from Petr Pajas for CDATA nodes
+	* tree.c: patch from Petr Pajas improving xmlGetNodePath()
+	* parser.c include/libxml/parser.h: patch from Peter Jones
+	  removing a leak in xmlSAXParseMemory() and adding the
+	  function xmlSAXParseMemoryWithData()
+
+Mon Nov 11 20:47:03 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	adding pdf of tutorial, changing web page to link to it
+	* doc/tutorial/xmltutorial.pdf
+	* doc/xml.html
+	* doc/docs.html
+
+Sun Nov 10 20:48:57 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/ar01s08.html
+	adding file what I forgot for tutorial
+
+Sun Nov 10 20:33:13 MST 2002 John Fleck  <jfleck@inkstain.net>
+
+	Adding encoding discussion to tutorial
+	Added:
+	* doc/tutorial/images/*.png: DocBook admonition image files
+	* doc/tutorial/apf.html, apg.html: new generated html
+	* doc/tutorial/includeconvert.c: conversion code entity file
+	changed:
+	* doc/tutorial/xmltutorial.xml: DocBook original
+	* doc/tutorial/*.html: generated html
+
+Fri Nov  8 17:59:32 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* include/libxml/*.h: retired xmlwin32version.h
+	* doc/Makefile.am: retired xmlwin32version.h
+	* win32/configure.js: retired xmlwin32version.h
+
+Fri Nov  8 16:55:47 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: exported additional symbols
+	* include/libxml/xmlmemory.h: exported the rest of the xmlMem* 
+	  sisterhood
+
+Fri Nov  8 16:08:13 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: fixed a typo pointed out by Igor
+	* xpath.c: try to speed up node compare using line numbers
+	  if available.
+
+Thu Nov  7 15:16:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: make xmlFreeNode() handle attributes correctly.
+
+Wed Nov  6 23:51:11 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* catalog.c: completed the #96963 fix, as reported by Karl
+	  Eichwalder
+
+Wed Nov  6 16:48:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpointer.c: tried to fix bug #97852 reported by Nicolas Noffke
+
+Sun Nov  3 10:43:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: switched the order of a couple of includes
+	  to fix bugs #97100
+
+Thu Oct 31 17:11:46 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* catalog.c: fixed bug #96963, reverted to the old behaviour of
+	  xmlLoadCatalogs that used to separate directories with a ':'.
+
+Thu Oct 31 16:55:21 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* threads.c: improvements to the Windows-side of thread handling
+	* testThreads.c: conditionally excluded unistd.h
+	* testThradsWin32.c: broke overlong lines
+	* include/win32config.h: adapted thread-related macros to the new
+	  scheme and for pthreads on Windows
+	* win32/Makefile.msvc: introduced a more flexible thread build, 
+	  added testThreads[Win32].c to the build
+	* win32/configure.js: introduced a more flexible thread config
+
+2002-10-31  John Fleck  <jfleck@inkstain.net>
+
+	* doc/xml.html (and, by implication, FAQ.html)
+	added UTF-8 conversaion FAQ from Marcus Labib Iskander
+
+Tue Oct 29 18:32:33 CET 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* configure.in: removed xmlwin32version.h
+	* include/libxml/Makefile.am: removed xmlwin32version.h
+
+Mon Oct 28 14:01:29 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch from Brian Stafford to fix a bug
+	  in xmlReconciliateNs()
+
+Mon Oct 28 13:51:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch from Christian Glahn to allow
+	  xmlNewChild() on document fragment nodes
+
+Sat Oct 26 15:27:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Christian Glahn found a problem with a recent
+	  patch to xmlParseBalancedChunkMemoryRecover()
+	* xmlschemas.c: Charles Bozeman fixed some Schemas validation
+	  problems
+	* result/schemas/elem* result/schemas/seq* test/schemas.elem*
+	  test/schemas/seq*: added the test cases from Charles
+
+Wed Oct 23 16:42:29 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am config.h.in libxml.spec.in doc/Makefile.am:
+	  serious cleanup of the spec file and associated changes
+	  in the Makefiles.
+	* valid.c: try to remove some warnings on x86_64
+
+Wed Oct 23 10:53:42 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/Makefile.am: added winsockcompat.h to EXTRA_DIST to
+	  fix bug #96586
+
+Tue Oct 22 21:13:06 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: Mikhail Sogrine pointed out a bug in HTML
+	  parsing, applied his patch
+	* result/HTML/attrents.html result/HTML/attrents.html.err
+	  result/HTML/attrents.html.sax test/HTML/attrents.html:
+	  added the test and result case provided by Mikhail Sogrine
+
+Tue Oct 22 19:33:20 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* vms/build_libxml.com vms/config.vms vms/readme.vms
+	  include/libxml/parser.h include/libxml/parserInternals.h
+	  include/libxml/tree.h include/libxml/xmlIO.h
+	  HTMLparser.c catalog.c debugXML.c parser.c parserInternals.c
+	  tree.c triodef.h trionan.c uri.c xmlIO.c xpath.c:
+	  Applied the VMS update patch from Craig A. Berry
+	* doc/*.html: update
+
+Tue Oct 22 16:27:31 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/encoding.h encoding.c: made xmlGetUTF8Char public
+
+Tue Oct 22 16:25:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: adding a grep command to --shell in xmllint
+	  for T.V. Raman
+
+Tue Oct 22 16:23:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c: tried to fix some of the problem with --sgml
+
+Mon Oct 21 09:57:10 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: tried to fix bug #91500 where doc->children may
+	  be overriden by a call to xmlParseBalancedChunkMemory()
+
+Mon Oct 21 09:04:32 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: tried to fix bug #90945 w.r.t. parsing of system
+	  identifiers in SGML catalogs containing '&'
+
+Sun Oct 20 23:31:47 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c: fixed bugs when passing result value tree
+	  to Python functions.
+
+Fri Oct 18 13:18:53 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing the release of 2.4.26
+	* doc/*: updated and rebuilt the documentation
+
+Wed Oct 16 20:01:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a XML Namespace compliance bug reported by
+	  Alexander Grimalovsky
+
+Wed Oct 16 17:18:42 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixed serialization of script and style when
+	  they are not lowercase (i.e. added using the API to the tree).
+
+Wed Oct 16 16:31:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: make xmlValidateDocument emit a warning msg if there
+	  is no DTD, pointed by Christian Glahn
+
+Wed Oct 16 16:05:38 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c: fixed the validation of sequences
+	  content model when some of the blocks have min or max, and a couple
+	  of bugs found in the process.
+	* result/schemas/list0* test/schemas/list0*: added some specific
+	  regression tests
+
+Tue Oct 15 12:41:01 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* README: updated the contact informations
+
+Tue Oct 15 10:35:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: use test -f instead of test -e since Solaris /bin/sh
+	  misses it, reported by Peter Bray.
+
+Mon Oct 14 17:37:32 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: investigating xmlNodeGetContent() on namespace nodes
+	  and removed a few warnings
+
+Mon Oct 14 13:12:55 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Christian Glahn found a small bug in the push parser.
+	* xmlIO.c include/libxml/xmlIO.h: cleaned up and made xmlCheckFilename
+	  public
+
+Wed Oct  9 23:11:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: added
+	  xmlSchemaNewMemParserCtxt to parse a schemas from a memory area
+	* testSchemas.c: added --memory to test the new interface
+
+Wed Oct  9 16:22:54 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/index.py doc/search.php: integrated the XSLT indexing,
+	  a few fixed in the indexer, added a scope selection at the
+	  search level.
+
+Wed Oct  9 12:18:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: Joe Marcus Clarke reported a segfault on FBsd 
+	  this was due to uninitialized parts of the validation context
+
+Tue Oct  8 23:24:20 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: applied patch from Mark Vakoc except the API
+	  change, preserved it.
+	* doc/*: updated the docs to point to the search engine for
+	  information lookup or before bug/help reports.
+
+Tue Oct  8 18:53:31 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/index.py doc/search.php: added mailing-list archives
+	  indexing and lookup
+
+Tue Oct  8 10:25:07 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: patch from Mark Vakoc to fix xmlNodeGetPath()
+
+Mon Oct  7 13:12:03 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/index.py: improved HTML indexing
+	* doc/search.php: make the queries also lookup the HTML based indexes
+
+Sun Oct  6 23:50:29 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/index.py: added HTML page indexing 
+
+Fri Oct  4 15:33:55 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* xmlIO.c: extended Windows path normalisation to fix the base
+	  problem in libxslt.
+	* catalog.c: fixed list handling in XML_CATALOG_FILES
+
+Fri Oct  4 13:43:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: typo/bug found by Christian Glahn
+
+Sun Sep 29 19:44:10 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* xmlIO.c: applied Windows CE patch from Javier.
+	* win32/wince: new directory, contains support for the PocketPC
+	  with Windows CE from Javier.
+	* include/win32config.h: reorganised, removed duplicate 
+	  definitions and applied WinCE patch from Javier.
+	* include/wsockcompat.h: new file, now contains WinSock
+	  compatibility macros.
+	* win32/Makefile.msvc: introduced double-run compilation.
+
+Thu Sep 26 19:48:06 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing release
+	  of 2.4.25
+	* doc/*: updated and regenerated teh docs and web pages.
+
+Thu Sep 26 17:33:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c valid.c include/libxml/valid.h: fixed bug #92518 validation
+	  error were not covering namespace declarations.
+	* result/valid/dia.xml test/valid/dia.xml: the test wasn't valid,
+	  it was missing the attribute declaration for the namespace
+	* result/VC/NS3: the fix now report breakages in that test
+
+Thu Sep 26 14:39:07 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixing bug #94241 on HTML boolean attributes
+
+Thu Sep 26 14:25:33 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*: added the 3 new modules xmlregexp xmlautomata and xmlunicode
+	  and regenerated the docs and web site
+
+Thu Sep 26 11:45:42 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c xmlschemas.c xmlschemastypes.c xpath.c: make sure
+	  ATTRIBUTE_UNUSED is always put after the attribute declaration,
+	  not before
+
+Thu Sep 26 11:33:28 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml2class.txt: fixed a stupid error
+	  breaking the python API
+
+Thu Sep 26 00:31:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* trio.c trio.h triodef.h trionan.c trionan.h triop.h
+	  triostr.c triostr.h: applied a trio update patch from 
+	  Bjorn Reese which should work with MinGW
+
+Thu Sep 26 00:21:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: improving some documentation comments
+	* xmlregexp.c: found and fixed a mem leak with python regression tests
+	* doc/*: rebuilt the doc and the API XML file including the 
+	  xmlregexp.h xmlautomata.h and xmlunicode.h headers
+	* python/generator.py python/libxml2class.txt python/libxml_wrap.h
+	  python/types.c: added access to the XML Schemas regexps from
+	  python
+	* python/tests/Makefile.am python/tests/regexp.py: added a 
+	  simple regexp bindings test
+
+Tue Sep 24 08:10:48 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/xml.html:
+	  fixing ftp links - thanks to Vitaly Ostanin
+
+Tue Sep 24 16:08:17 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: fixed the data callback on transition functionality
+	  which was broken when using the compact form
+	* result/schemas/*: updated the results, less verbose, all tests
+	  pass like before
+	* DOCBparser.c testAutomata.c testC14N.c testSchemas.c testThreads.c
+	  testXPath.c valid.c xinclude.c xmllint.c xmlregexp.c xmlschemas.c
+	  xmlschemastypes.c xpath.c python/libxml.c: removed a bunch of
+	  annoying warnings
+	* xpath.c: try to provide better error report when possible
+
+Sat Sep 21 14:56:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: fixed a breakage raised by Jacob
+
+Fri Sep 20 20:08:18 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* include/win32config.h: added HAVE_ERRNO_H definition for parts
+	  which don't use sockets
+
+Fri Sep 20 18:40:50 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/Makefile.msvc: applied zlib patch from Daniel Gehriger
+	* win32/configure.js: applied zlib patch from Daniel Gehriger
+
+Fri Sep 20 15:40:14 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/configure.js: applied the patch from Mark Vakoc for 
+	  regexp support
+	* win32/libxml2.def.src: applied the patch from Mark Vakoc
+	  for regexp support
+
+Fri Sep 20 15:35:33 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: as pointed by Igor Float and Double
+	  parsing ain't finished yet
+
+Fri Sep 20 14:00:16 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in: trying to fix #88412 by bypassing
+	  all the python subdir if python ain't detected
+
+Thu Sep 19 21:46:53 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in include/libxml/xmlversion.h.in:
+	  made configuring with regexps/automata/unicode the default
+	  but without schemas ATM
+	* testRegexp.c valid.c xmlregexp.c include/libxml/xmlregexp.h:
+	  fixed the regexp based DTD validation performance and memory
+	  problem by switching to a compact form for determinist regexps
+	  and detecting the determinism property in the process. Seems
+	  as fast as the old DTD validation specific engine :-) despite
+	  the regexp built and compaction process.
+
+Wed Sep 18 18:27:26 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: determinism is debugged, new DTD checking code now works
+	  but xmlFAComputesDeterminism takes far too much CPU and the whole
+	  set usues too much memory to be really usable as-is
+
+Wed Sep 18 00:54:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed another stupid bug in xmlGetNodePath()
+	* xmllint.c: --version now report the options compiled in
+
+Tue Sep 17 23:48:07 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: small cleanup
+	* valid.c xmlregexp.c: switched DTD validation to use only regexp
+	  when configured with them. A bit of debugging around the determinism
+	  checks is still needed
+
+Tue Sep 17 21:22:25 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml_wrap.h: stupid bug found by mattam@netcourrier.com
+
+Tue Sep 17 19:58:26 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: small portability glitch fixed.
+
+Mon Sep 17 12:38:08 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: incomplete steps for real/double support
+	* testAutomata.c include/libxml/xmlautomata.h
+	  include/libxml/xmlregexp.h: avoiding a compilation problem
+	* valid.c include/libxml/valid.h: starting the work toward using
+	  the regexps for actual DTD validation
+
+Fri Sep 13 16:46:14 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* hash.c: cosmetic cleanup
+	* valid.c include/libxml/tree.h include/libxml/valid.h: started 
+	  integrating a DTD validation layer based on the regexps
+
+Thu Sep 12 18:01:29 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c: fixed a bug reported by Jeff Goff,
+	  the determinism was tested before eliminating the epsilon
+	  transitions :-(
+
+Thu Sep 12 16:57:45 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml.py
+	  python/libxml2-python-api.xml python/libxml2class.txt
+	  python/libxml_wrap.h python/types.c: updated the python
+	  bindings, added code for easier File I/O, and the ability to
+	  define a resolver from Python fixing bug #91635
+	* python/tests/Makefile.am python/tests/inbuf.py
+	  python/tests/outbuf.py python/tests/pushSAXhtml.py
+	  python/tests/resolver.py python/tests/serialize.py: updated
+	  and augmented the set of Python tests.
+
+Tue Sep 10 21:05:28 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/configure.js: added more readme info for the binary
+	  package.
+
+Tue Sep 10 14:15:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fixed a stupid out of bound array error
+
+Tue Sep 10 13:09:14 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlIO.h xmlIO.c parser.c HTMLparser.c DOCBparser.c:
+	  messing around with support for Windows path, cleanups,
+	  trying to identify and fix the various code path to the
+	  filename access. Added xmlNormalizeWindowsPath()
+
+Thu Sep  5 16:19:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* error.c valid.c: working on better error reporting of validity
+	  errors, especially providing an accurate context.
+	* result/valid/xlink.xml.err result/valid/rss.xml.err: better
+	  error reports in those cases.
+
+Thu Sep  5 13:29:47 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c HTMLparser.c c14n.c entities.c list.c
+	  parser.c parserInternals.c xmlIO.c: get rid of all the 
+	  perror() calls made in the library execution paths. This
+	  should fix both #92059 and #92385
+
+Thu Sep  5 13:13:17 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: memory leak reporting was broken after a change
+	  of the preprocessor symbol used to activate it.
+
+Thu Sep  5 13:10:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: try to make the copy function work for node of
+	  type XML_DOCUMENT_FRAG_NODE, they are only created by the
+	  DOM layers though, not libxml2 itself.
+
+Thu Sep  5 12:57:38 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: try to provide file and line informations, not all
+	  messages are covered, but it's a (good) start
+
+Thu Sep  5 12:49:35 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: reimplemented a large part of the XInclude
+	  processor, trying to minimize resources used, James Henstridge
+	  provided a huge test case which was exhibiting severe memory
+	  consumption problems.
+
+Thu Sep  5 10:07:13 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: applied patch from Christophe Merlet to
+	  reestablish DESTDIR
+
+Wed Sep  4 14:13:34 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: fixes libary path for x86_64 AMD
+
+Tue Sep  3 21:14:19 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/includekeyword.c
+	* doc/tutorial/xmltutorial.xml:
+	(plus resulting generated html files)
+	fixing one spot I missed in the tutorial where I hadn't freed
+	memory properly
+
+Sat Aug 31 19:31:17 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/includeaddattribute.c
+	* doc/tutorial/includeaddkeyword.c
+	* doc/tutorial/includegetattribute.c
+	* doc/tutorial/includekeyword.c
+	* doc/tutorial/xmltutorial.xml
+	* doc/tutorial/*.html:
+	update tutorial to properly free memory (thanks to Christopher
+	R. Harris for pointing out that this needs to be done)
+	* doc/tutorial/images/callouts/*.png:
+	added image files so the callouts are graphical, making it
+	easier to read ( use "--param callout.graphics 1" to generate
+	html with graphical callouts)
+
+Wed Aug 28 13:44:54 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Libxml2-Logo-180x168.gif doc/Libxml2-Logo-90x34.gif:
+	  nice logos generated by Marc Liyanage
+	* doc/site.xsl *.html: changed the stylesheet to show the new
+	  logo and regenerated the pages
+
+Sun Aug 25 16:38:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: handle Windows sepecific file://localhost/ semantic ...
+
+Thu Aug 22 22:03:19 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: possible mem leak patch from Jason Adams
+
+Thu Aug 22 17:27:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: integrated xf:escape-uri() from Wesley Terpstra
+	  in the XQuery namespace
+	* configure.in: preparing 2.4.24
+	* doc/*.html: updated the web pages
+
+Thu Aug 22 16:19:42 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: closing bug #85258 by generating conditional
+	  compile check to avoid linking to routines not configured in.
+
+2002-08-22  Havoc Pennington  <hp@pobox.com>
+
+	* autogen.sh: update error message for missing automake
+
+Thu Aug 22 11:45:50 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: typo in target name resulted in libxml2.py
+	  to not be rebuilt. fixed DESTDIR similary to the libxslt one.
+
+Thu Aug 22 09:15:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* win32/win32/Makefile.mingw: updated with version from 
+	  Elizabeth Barham at http://soggytrousers.net/repository/
+
+Tue Aug 20 16:40:48 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/Makefile.msvc: added the prefix location to the include
+	and lib search path.
+
+2002-08-18  Havoc Pennington  <hp@pobox.com>
+
+	* autogen.sh: hardcode aclocal-1.4/automake-1.4 so that users with
+	both automake 1.6 and 1.4 installed get the right automake. Means
+	compilation from CVS will now require the latest automake 1.4
+	release, or manually creating symlinks called "automake-1.4" and
+	"aclocal-1.4"
+
+Wed Aug 14 18:54:19 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in python/Makefile.am: more AMD 64 induced changes from
+	  Frederic Crozat
+
+Wed Aug 14 16:43:53 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: oops I was missing the xml:base fixup too
+	* result/XInclude/*.xml: this adds xml:base attributes to most
+	  results of the tests
+
+Wed Aug 14 16:05:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xinclude.c: quick but apparently working implementation of
+	  xi:fallback, should close bug #89684
+	* Makefile.am test/XInclude/docs/fallback.xml 
+	  result/XInclude/fallback.xml: added a basic test for fallback,
+	  and run with --nowarning to avoid a spurious warning
+	* configure.in: applied patch from Frederic Crozat for python
+	  bindings on AMD 64bits machines.
+
+Wed Aug 14 10:47:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: xmlSAXUserParseMemory() really ought to fail if
+	  the caller don't pass a SAX callback block.
+
+Wed Aug 14 10:29:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied the same fix for the XML-1.0 namespace to
+	  xmlSearchNsByHref() as was done for xmlSearchNs()
+
+Mon Aug 12 16:52:08 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.3: small cleanup of the man page
+	* HTMLtree.c: fixed a potential problem raised by Petr Vandrovec
+	  when serializing HREF attributes generated by XSLT.
+
+Mon Aug 12 15:24:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c include/libxml/HTMLtree.h: integrated a cleaned up
+	  version of Marc Liyanage' patch for boolean attributes in HTML
+	  output
+
+Mon Aug 12 14:11:59 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/tests/serialize.py: fixed the test results, indenting
+	  behaviour changed slightly
+
+Thu Aug  8 11:00:26 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* win32/dsp/libxml2.def.src win32/libxml2.def.src: added
+	new c14n function to Windows def files
+
+Fri Aug  2 16:46:46 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* c14n.c: fixed a memory leak in c14n code
+
+Sat Aug  3 00:15:06 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parser.h: adding a new API for Christian
+	  Glahn: xmlParseBalancedChunkMemoryRecover
+	* valid.c: patch from Rick Jones for some grammar cleanup in
+	  validation messages
+	* result/VC/* result/valid/*: this slightly change some of the
+	  regression tests outputs
+
+Thu Aug  1 14:50:28 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: trying to fix a problem in namespaced attribute handling
+	  raised by Christian Glahn
+
+Thu Aug  1 12:17:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c include/libxml/encoding.h: Opening the interface
+	  xmlNewCharEncodingHandler as requested in #89415
+	* python/generator.py python/setup.py.in: applied cleanup
+	  patches from Marc-Andre Lemburg
+	* tree.c: fixing bug #89332 on a specific case of loosing 
+	  the XML-1.0 namespace on xml:xxx attributes
+
+Wed Jul 31 23:27:42 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* c14n.c include/libxml/c14n.h: fixed one more c14n + namespaces
+	corner case from new Merlin's test suite and added a callback
+	that will be used to improve xmlsec performance
+
+Mon Jul 29 18:22:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: trying to fix the <style> escaping problem in
+	  HTML serialization bug #89342
+
+Thu Jul 25 01:33:47 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/*.html: applied syntax patch from Rick Jones
+	  and rebuilt the web site.
+
+Mon Jul 22 11:04:48 PDT 2002  Aleksey Sanin <aleksey@aleksey.com>
+
+	* include/libxml/tree.h: added _private member to xmlNs struct
+
+Sun Jul 21 17:48:47 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixing bug #84876 based on the xml working
+	  code.
+
+Sun Jul 21 19:15:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
+
+	* python/Makefile.am: enhanced to fix bug 72012 (errors
+	  when using '-jX' make parameter)
+
+Fri Jul 19 16:35:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: small additional enhancement for booleans
+	  compared to nodesets
+
+Wed Jul 17 19:48:14 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: changed the order of the encoding declaration
+	  attributes in the meta tags due to a bug in IE/Mac
+
+Fri Jul 12 08:45:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: enhanced handling of booleans (especially '='
+	  and '!=' for nodesets) - fixes bug 85256.  Added new
+	  routine xmlXPathNotEqualValues for more proper handling
+	  of '!=' when nodesets are involved.
+
+Thu Jul 11 21:45:52 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am: fixing Red Hat bug #68614 by adding the
+	  doc/xmlcatalog_man.xml to the source distribution
+
+Wed Jul 10 21:26:13 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/Makefile.msvc: Added a copy *.pdb to install, few have
+	  asked for this.
+
+Sat Jul  6 21:55:59 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.23
+	* doc/*: rebuilt the docs
+
+Sat Jul  6 21:11:20 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixing bug #84169 by fixing the
+	  comment of xmlCreatePushParserCtxt to describe the 
+	  encoding detection parameters better.
+
+Sat Jul  6 19:44:56 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixing bug #79331 in one path the lookup for
+	  ID attributes on a namespaced node wasn't handled correctly :-\
+
+Fri Jul  5 20:07:43 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: trying to fix 87235 about discarded white
+	  spaces in the HTML parser.
+	* result/HTML/*: this changes the output of a number of HTML
+	  regression tests
+
+Mon Jul  1 23:23:41 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied patch from Richard Jinks for the namespace
+	  axis + fixed a memory error.
+	* parser.c parserInternals.c: applied patches from Peter Jacobi
+	  removing ctxt->token for good.
+	* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
+	  popped out by the regression tests.
+	* Makefile.am: patch for threads makefile from Gary Pennington
+
+Fri Jun 28 19:38:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: enhanced behaviour of position() after usage of
+	  expressions involving preceding-sibling (et al).
+
+Tue Jun 18 09:58:48 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* hash.c: applied a patch from Peter Jacobi to solve a problem
+	  when compiling with the Watcom C on Win32 
+	* result/schemas/*.err: the change of hashing algo generated
+	  permutations in the output
+
+Mon Jun 17 19:02:49 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* hash.c: applied patch from Sander Vesik improving the quality of
+	  the hash function.
+
+2002-06-14  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* DOCBparser.c HTMLparser.c debugXML.c encoding.c
+	nanoftp.c nanohttp.c parser.c tree.c uri.c xmlIO.c
+	xmllint.c xpath.c: replaced sprintf() with snprintf()
+	to prevent possible buffer overflow (the bug was pointed
+	out by Anju Premachandran) 
+
+Thu Jun 13 17:30:25 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: removed an uninitialized data error popped by valgrind
+	  on PE references
+
+Wed Jun 12 21:38:46 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/xml.html
+	adding tutorial reference to the web page
+
+Wed Jun 12 21:26:08 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/tutorial/xmltutorial.xml
+	* doc/tutorial/ar01s07.html
+	* doc/tutorial/ape.html
+	* doc/tutorial/includegetattribute.c
+	adding section to tutorial about retrieving an attribute
+	value
+
+Tue Jun 11 12:07:04 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: applied a couple of patches from Peter Jacobi to start
+	  to get rid of ctxt->token, with a possible significant speed
+	  improvement to be gained once done. Better compliance with PE
+	  references constructs in DTDs too.
+	* test/valid/t[0-9]* result/valid/t[0-9]*: added a set of tests
+	  from Peter too
+
+Tue Jun 11 09:25:12 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Babak Vahedipour-Kunze reported that openTag in 
+	  xmlParseElement was likely to have been deallocated at the
+	  time of the report, possibly leading to segfault. Just report
+	  the tag name now.
+
+Mon Jun 10 18:00:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: patch from Richard Jinks for XPath substring() function
+	* result/XPath/expr/strings test/XPath/expr/strings: new set of tests
+
+2002-06-06  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* xmlIO.c: patch from Rachel Hestilow to fix bug #84340
+
+Wed Jun  5 19:14:49 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	*doc/FAQ.html
+	fixing typos in FAQ, thanks to Robert Funnell for the
+	editing help
+
+Wed Jun  5 14:50:24 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* NEWS: got complaints from rpmlint that it was empty
+
+Tue Jun  4 09:09:18 MDT 2002 John Fleck <jfleck@inkstain.net>
+
+	* added doc/tutorial, including:
+	apa.html
+	apb.html
+	apc.html
+	apd.html
+	ar01s02.html
+	ar01s03.html
+	ar01s04.html
+	ar01s05.html
+	ar01s06.html
+	includeaddattribute.c
+	includeaddkeyword.c
+	includekeyword.c
+	includestory.xml
+	index.html
+	xmltutorial.xml
+	libxml tutorial, including generated html
+
+Mon Jun  3 21:21:26 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* result/c14n/exc-without-comments/merlin-c14n-two-*
+	  result/c14n/without-comments/merlin-c14n-two-*
+	  test/c14n/exc-without-comments/merlin-c14n-two-*
+	  test/c14n/without-comments/merlin-c14n-two-*
+	  testC14N.c Makefile.am: added merlin-c14n-two.tar.gz tests for 
+	c14n/exc-c14n and slightly modified test script to handle
+	these test cases
+	* c14n.c: fixed bugs for complicated nodes set (namespace
+	without node and others from merlin-c14n-two.tar.gz)
+	* include/libxml/xpathInternals.h win32/dsp/libxml2.def.src
+	win32/libxml2.def.src: "opened" xmlXPathNodeSetFreeNs() function
+	for xmlsec performance patch
+	* xpath.c: fixed self::node() for namespaces and attributes
+
+Mon Jun 03 00:04:21 2002 Chema Celorio <chema@ximian.com>
+
+	* tree.h: added xmlDocFormatDump which is just as xmlDocDump
+	  but with the format parameter
+	* tree.c: made xmlDocDump a wrapper arround xmlDocFormatDump
+
+Fri May 31 12:16:48 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* Makefile.am: updated c14n tests suite
+	* c14n.c: performance improvement for previous c14n patch
+
+Fri May 31 11:47:12 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: another peroformance patch from Peter Jacobi, that
+	  time on parsing attribute values.
+
+Thu May 30 23:34:27 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* Makefile.am result/c14n/* test/c14n/*: C14N tests integrated
+	into LibXML2 test suite
+
+Thu May 30 21:23:06 2002  Aleksey Sanin  <aleksey@aleksey.com>
+
+	* c14n.c: propagating xpath ancesstors node fix to c14n
+	plus small performance improvement to reduce number of
+	mallocs
+	* xpath.c: fixed ancestors axis processing for namespace nodes
+
+Wed May 29 10:21:39 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c parser.c tree.c include/libxml/tree.h: performance patch from
+	  Peter Jacobi
+
+Mon May 27 23:18:33 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.22
+
+Mon May 27 16:44:04 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c win32/libxml2.def.src win32/dsp/libxml2.def.src
+	  include/libxml/HTMLparser.h: fixing #79334 making htmlParseDocument
+	  a public entry point.
+	* doc/*: rebuilt the API and docs
+
+Mon May 27 14:16:28 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: patch from Richard Jinks to fix a problem introduced
+	  in the previous patch and pointed by Norm
+
+Fri May 24 13:10:22 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: fixing bug #81112
+
+Fri May 24 13:03:24 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: fixing bug #82848
+
+Fri May 24 09:54:49 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* result/catalogs/mycatalog.full: Aleksey's commit changed the
+	  output of one catalog test
+
+Fri 24 May 2002 12:17:45 AM PDT Aleksey Sanin <aleksey@aleksey.com>
+
+	* global.data globals.c tree.c include/libxml/globals.h 
+	win32/libxml2.def.src win32/dsp/libxml2.def.src: changed
+	default value for global parameter xmlIndentTreeOutput to 1 and
+	introduced new global parameter xmlTreeIndentString (the string
+	used to do one-level indent) with default value "  " (as it was
+	in tree.c)
+
+Thu May 23 13:55:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: Merijn Broeren pointed out a problem when compiling
+	  with trio and schemas.
+
+Wed May 22 11:57:49 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: patch from Richard Jinks to fix the problem raised in
+	  http://mail.gnome.org/archives/xml/2002-April/msg00246.htm
+
+Wed May 22 08:38:19 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: a bit of work on import.
+	* xmlschemastypes.c: Charles Bozeman provided a compare function
+	  for date/time types so min/max facet restrictions should work,
+	  indeterminate comparisons return an error instead of equal.
+	* test/schemas/date_0* result/schemas/date_0_0: specific test
+	  from Charles Bozeman too
+
+Sat May 18 09:54:12 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.3 doc/buildDocBookCatalog: apply a couple of patches
+	  from Christian Cornelssen fixing the man pages and the Catalog
+	  building script.
+	* xmlschemas.c include/libxml/schemasInternals.h: nothing new yet
+	  next step is <xs:import> I now have a reasonable understanding
+	  of how it works.
+
+Thu May 16 10:43:26 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: applied a small buffer performance patch from Gary Pennington
+
+Wed May 15 00:25:34 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/libxml2.def.src: exported xmlXPathNodeSetAddNs()
+
+Tue May 14 13:00:48 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixing an XPath function evalutation bug pointed out
+	  by Alexey Efimov where the context was lost when evaluating
+	  the function arguments
+
+Mon 13 May 2002 11:37:39 PM PDT Aleksey Sanin <aleksey@aleksey.com>
+
+	* xpath.c include/libxml/xpathInternals.h: maked xmlXPathNodeSetAddNs() 
+	  function public for XMLSec performance optimizations
+
+Mon May 13 12:32:22 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml2class.txt : fixed a problem
+	  with the HTML parser pointed by Gary Benson
+	* python/tests/Makefile.am python/tests/pushSAXhtml.py: sdding the
+	  example
+
+Thu 09 May 2002 11:19:00 AM PDT Aleksey Sanin <aleksey@aleksey.com>
+	* parser.c: fixed bug #81159 (memory growth in SAX)
+
+Tue 07 May 2002 09:20:21 AM PDT Aleksey Sanin <aleksey@aleksey.com>
+	* xpath.c: fixed bug #78858 (the real fix)
+
+Sat 04 May 2002 11:56:31 PM PDT Aleksey Sanin <aleksey@aleksey.com>
+	* xpath.c: fixed bug #78858 (quick and durty fix to hide the problem)
+
+Sun May  5 08:57:08 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: modified xmlNodeSetBase to allow changing the
+	  base of a document.
+
+Fri May  3 09:20:41 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemastypes.c: patch Charles Bozeman for validation of
+	  all the date, time, and duration types
+	* test/schemas/dur_0* result/schemas/dur_0*: associated tests
+	* configure.in: fixed an error pointed by an user
+	* xml2-config.in: fixed an error pointed by an user
+
+Wed 01 May 2002 11:29:27 AM PDT Aleksey Sanin <aleksey@aleksey.com>
+
+	* include/libxml/xmlIO.h win32/dsp/libxml2.def.src
+	win32/libxml2.def.src xmlIO.c: exported default
+	'file:', 'http:' and 'ftp:' protocols input handlers 
+	and maked protocols comparisson case insensitive
+
+Tue Apr 30 16:29:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: Neven Has detected a typo
+
+Tue Apr 30 08:48:11 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* AUTHORS HACKING: added Aleksey Sanin <aleksey@aleksey.com>
+	  as one of the persons allowed to commit directly to the
+	  module.
+
+Mon Apr 29 17:48:26 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing 2.4.21
+	* valid.c: raised a too low limit
+	* doc/*: rebuilt the docs 
+
+Wed Apr 24 13:41:03 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* test/XPath/expr/floats test/XPath/expr/functions
+	  result/XPath/expr/floats result/XPath/expr/functions
+	  xpath.c: another XPath conformance patch from Richard Jinks
+
+Tue Apr 23 19:50:40 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: fixed validation of attribute groups.
+	* test/schemas result/schemas: added an example from the primer
+
+Tue Apr 23 09:11:37 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am xmlschemas.c xmlschemastypes.c: more work on Schemas
+	* test/schemas result/schemas: updated the test list
+
+Mon Apr 22 17:59:14 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* TODO: updated a bit
+	* parser.c: made a comment more specific
+	* xmlregexp.c xmlschemas.c xmlschemastypes.c: more work on the
+	  Schemas conformance.
+	* test/schemas result/schemas: updated the test list
+
+Sat Apr 20 19:36:39 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c include/libxml/xmlautomata.h:
+	  implementing xs:all with minOccurs = 0
+	* tes/schemas/* result/schemas/*: added more tests covering
+	  xs:all
+
+Sat Apr 20 09:22:50 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c: first implementation of the all particle, this
+	  may need to be revisited for case where not all transitions
+	  must be crossed.
+
+Fri Apr 19 18:26:04 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: another entity processing update from Markus Henke
+
+Fri Apr 19 17:14:24 CEST 2002 Bjorn Reese <breese@users.sourceforge.net>
+
+	* trionan.c: fixed crash on OSF/1
+
+Fri Apr 19 09:00:56 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c: more Schemas work
+	* test/schemas/* result/schemas/*: added more tests coming
+	  from the spec.
+
+Thu Apr 18 23:00:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: patch from Aleksey Sanin reflecting a change in the
+	  ExcC14N specification
+
+Thu Apr 18 18:38:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: patch from Markus Henke, fix for recursive entities.
+
+Thu Apr 18 17:49:24 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fix a problem with string() on a document node.
+
+Thu Apr 18 16:40:42 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am xmlschemas.c: more Schemas work
+	* test/schemas/* result/schemas/*: added more tests coming
+	  from the spec.
+
+Thu Apr 18 13:52:52 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixed & serialization bug introduced in 2.4.20
+	* result/HTML/*: this changes a few things in the results
+
+Wed Apr 17 20:34:37 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* include/libxml/tree.h: eliminated 'declaration different than
+	 prototype' warning
+	* include/win32config.h: "resolved" conflicts with errno.h
+
+Wed Apr 17 18:26:07 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlregexp.c xmlschemas.c include/libxml/xmlautomata.h: more work
+	  on the automata interfaces and debug of counted choices
+	* test/schemas/* result/schemas/*: added a number of tests
+
+Wed Apr 17 11:03:03 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c xmlschemastypes.c include/libxml/xmlschemas.h:
+	  a bit of work on Schemas
+	* testSchemas.c: try to make it more useful
+	* test/schemas/* result/schemas/* Makefile.am: changed the
+	  Schemas regression test procedure, started adding a few samples
+
+Tue Apr 16 19:52:01 CEST 2002 Igor Zlatkovic <izlatkovic@stud.fh-frankfurt.de>
+
+	* include/libxml/encoding.h: Patch for the Borland C++ builder
+	* include/libxml/tree.h: Patch for the Borland C++ builder
+	* threads.c: Patch for the Borland C++ builder
+	* win32/bcb5: New directory for the Borland C++ builder
+	 project files       
+
+Tue Apr 16 19:46:55 CEST 2002 Igor Zlatkovic <izlatkovic@stud.fh-frankfurt.de>
+
+	* win32/Makefile.msvc: Update for XML Schema support
+	* win32/configure.js: Update for XML Schema support
+	* win32/libxml2.def.src: Update for XML Schema support
+
+Tue Apr 16 17:46:43 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am TODO_SCHEMAS configure.in genUnicode.py testAutomata.c
+	 testRegexp.c testSchemas.c xmlregexp.c xmlschemas.c xmlschemastypes.c
+	 xmlunicode.c include/libxml/Makefile.am
+	 include/libxml/schemasInternals.h include/libxml/xmlautomata.h
+	 include/libxml/xmlregexp.h include/libxml/xmlschemas.h
+	 include/libxml/xmlschemastypes.h include/libxml/xmlunicode.h
+	 include/libxml/xmlversion.h.in : merged the current state of
+	 XML Schemas implementation, it is not configured in by default,
+	 a specific --schemas configure option has been added.
+	* test/automata test/regexp test/schemas Makefile.am
+	  result/automata result/regexp result/schemas:
+	  merged automata/regexp/schemas regression tests
+
+Tue Apr 16 09:48:44 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: Gary found a compile time problem, fixes #78823
+
+Mon Apr 15 19:11:36 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: release of 2.4.20
+	* doc/*: updated and rebuilt the docs
+
+Mon Apr 15 14:55:53 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: patch from Cristian Gafton to build on
+	  Red Hat 6.2, should also fix #75779
+
+Mon Apr 15 12:14:49 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: first part of fixing #78729
+
+Sun Apr 14 23:44:58 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c uri.c: fixing bug #78662 i.e. add proper
+	  escaping of URI when saving HTML files.
+	* result/HTML/*: this impacted some tests
+
+Sun Apr 14 14:55:15 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: trying to fix #77441
+
+Fri Apr 12 23:02:16 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlIO.h: Hallski complained it could not be
+	  included by itself.
+
+Thu Apr 11 10:23:36 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: applied an IEEE flag patch for OSF/1 #77825
+
+Wed Apr 10 23:31:34 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+	* win32/configure.js: patch from Nilo for the c14n option
+	* win32/Makefile.msvc: fixed libxml2.def generation with threads
+
+Wed Apr 10 21:24:16 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c include/libxml/xmlwin32version.h.in: Silvan Minghetti
+	  pointed erroneous use of LIBXML_THREADS_ENABLED instead of
+	   LIBXML_THREAD_ENABLED
+
+Wed Apr 10 18:12:52 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: another patch from Richard Jinks for substring conformance
+	* test/XPath/expr/floats test/XPath/expr/strings
+	  result/XPath/expr/floats result/XPath/expr/strings: update of the
+	  test suite to check those.
+
+Wed Apr 10 13:29:49 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: patch from Richard Jinks for .x float parsing.
+
+Tue Apr  9 18:09:31 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: patch from Markus Henke when an encoding ain't recognized
+
+Tue Apr  9 15:47:14 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.m4: got a report that #include <string.h> was needed
+
+Tue Apr  9 11:51:25 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: applied a fix from Anthony Jones for -o /--output
+
+Tue Apr  2 20:27:11 MST 2002 John Fleck <jfleck@inkstain.net>
+
+	* doc/example.html: fixing typo
+
+Mon Apr  1 10:02:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed a bug in the nodeset to boolean comparison code
+	  pointed out by Melvyn Sopacua.
+
+Fri Mar 29 23:41:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.m4: Frédéric Crozat gave a patch related to the change
+	  of Include paths breaking the libxml.m4
+
+Fri Mar 29 18:25:54 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: Fix bug #76927 forgot to save some context
+	  when evaluating binary expressions
+
+Thu Mar 28 19:22:48 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: fixed configure for MPE/iX from Markus Henke
+	* xmlmemory.c: fixed initialization problems
+	* xpath.c: another set of patches from Richard Jinks this
+	  fixes "make XPathtests" on linux
+
+Wed Mar 27 17:09:43 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* trionan.c trionan.h xpath.c: more patches from Richard Jinks
+	* test/XPath/expr/compare test/XPath/expr/equality
+	  test/XPath/expr/floats test/XPath/expr/functions
+	  test/XPath/expr/strings result/XPath/expr/compare
+	  result/XPath/expr/equality result/XPath/expr/floats
+	  result/XPath/expr/functions result/XPath/expr/strings: Updated
+	  tests though they show a divergence on Linux
+
+Wed Mar 27 10:06:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c trionan.c: previous commit also included patches
+	  from Richard Jinks on some IEEE support corner case
+
+Wed Mar 27 10:03:11 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* AUTHORS HACKING: Added Igor Zlatkovic as official maintainer
+	* python/Makefile.am python/tests/Makefile.am: Albert Chin pointed
+	  that $(datadir) should be used for docs
+
+Tue Mar 26 13:43:16 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: Thomas Steinborn pointed out #76404 that libxml2
+	  could leak filedescriptors
+
+Tue Mar 26 08:55:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in nanohttp.c: applied patch from Allan Clark for
+	  UnixWare/OpenServer
+
+Mon Mar 25 17:45:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.19
+	* doc/*: rebuilt the docs
+
+Mon Mar 25 17:34:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* nanohttp.c: fixing #76043, got fed up with non-portability
+	  of that piece of code.
+
+Mon Mar 25 13:08:21 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c SAX.c: Never commit without running "make tests" :-(
+	  fix a couple of stupidities in the previous commit
+	* result/*: a few changes in some attribute order result of previous
+	  commit.
+
+Mon Mar 25 11:46:05 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c SAX.c: fixed bug #76168, attribute redeclared in
+	  the internal subset should not raise duplicate ID errors,
+	  also there was a small bug in conjunction to namespace
+	  declarations defaulted and xml:xxx attributes DTD definitions.
+
+Fri Mar 22 15:13:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: Richard Jinks also raised some rounding problems
+	  this tries to fix them
+
+Fri Mar 22 13:22:09 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: Richard Jinks spotted an incoherent memory allocation
+	  behaviour in xmlXPathCastToString()
+
+Thu Mar 21 14:25:29 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: fixed a bug in the ISO-Latin 1 to UTF8 encoder
+	  raised by Morus Walter
+
+Thu Mar 21 14:07:13 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c include/libxml/xmlversion.h.in: applied 2 fixups
+	  from Igor
+
+Thu Mar 21 13:30:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixing #75619, related to a problem when trying
+	  to evaluate condition when the current node set resulting
+	  from that sub-step evaluation is empty. Also fixes 2 potential
+	  problem with previous-sibling and next-siblings axis.
+
+Thu Mar 21 09:03:59 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: patch from Mark Vakoc to build C14N if DocBook and
+	  HTML support is not configured in.
+
+Wed Mar 20 22:42:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c error.c parser.c parserInternals.c tree.c xmlIO.c
+	  include/libxml/tree.h: dohh I really didn't intended to commit
+	  this test version :-(
+
+Wed Mar 20 20:20:57 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* testSAX.c: I wanted to see the real speed at the SAX interface
+	  after a little too many Ximianer started complaining about the
+	  parser speed.
+	  added a --quiet option:
+	  paphio:~/XML -> ls -l db100000.xml 
+	  -rw-rw-r--    1 veillard www      20182040 Mar 20 10:30 db100000.xml
+	  paphio:~/XML -> time ./testSAX --quiet db100000.xml 
+	  3200006 callbacks generated
+	  real	0m1.270s
+	  Which means 16MBytes/s and 3Mcallback/s
+
+Tue Mar 19 19:33:57 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: valgrind spotted another error that time when running
+	  on libxslt regression tests
+
+Tue Mar 19 15:24:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: adding "make valgrind" running the full regression
+	  tests (except python ones) under Valgrind (using valgrind -q
+	  which was kindly added by the author).
+	* valid.c: stupid bug pinpointed by Valgrind, the regression tests
+	  passes cleanly now except an obcure floating point initialization
+	  raised in log10() in one XPath regression test ???
+	* tree.c: edited some comments to close #75244
+
+Tue Mar 19 12:15:20 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: pretty insane thing, the xmlXPathFormatNumber()
+	  was not serializing 1 as "1" if LC_ALL=sv_SE :-( and in the
+	  context of ScrollKeeper, made sure that if the number is
+	  an integer, the serialization follows the description at
+	  http://www.w3.org/TR/xpath#section-String-Functions
+
+Mon Mar 18 19:18:13 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.18
+	* doc/*: updated and rebuilt the web site
+	* *.c libxml.h: implement the new IN_LIBXML scheme discussed with
+	  the Windows and Cygwin maintainers.
+	* parser.c: humm, changed the way the SAX parser work when
+	  xmlSubstituteEntitiesDefault(1) is set, it will then 
+	  do the entity registration and loading by itself in case the
+	  user provided SAX getEntity() returns NULL.
+	* testSAX.c: added --noent to test the behaviour.
+
+Mon Mar 18 12:44:23 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Wilfried Teiken provided a hackish but working
+	  way to get context reported back on entities when parsing
+	  with SAX and without breaking the DOM build.
+
+Sun Mar 17 11:31:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: applied a new patch from Aleksey Sanin
+	* doc/site.xsl doc/xml.html doc/*.html: updated the documentation
+	  to reference Aleksey implementation of XML digital Signatures
+
+Sat Mar 16 23:01:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: small fix to avoid potential problem due to
+	  ordering of freeing data
+	* python/Makefile.am: people were complaining about 
+	  the generated file in python dir not being built
+
+Fri Mar 15 23:21:40 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in python/Makefile.am python/tests/Makefile.am
+	  python/generator.py python/libxml.c python/types.c: Cleanup
+	  of the python Makefiles based on Jacob and James feedback,
+	  fixed the spec file accordingly, fixed the number of warning
+	  that passing my pedantic CFLAGS was generating. Conclusion
+	  is that Python includes are real crap.
+
+Fri Mar 15 19:41:25 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure,in: it was reported quite a few times that
+	  xml2-config --cflags should not output
+	  -I$includeprefix/libxml2/libxml because libxml2 header names
+	  clashes with existing names like list.h from C++ stl.
+	  Includes should be #include<libxml/xxx.h> so ...
+
+Fri Mar 15 10:41:50 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: another patch from Aleksey Sanin
+
+Fri Mar 15 08:55:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: applied patch from Aleksey Sanin fixing a problem in the
+	  canonicalization algorithm
+	* doc/xml.html doc/index.html: added the C14N references on the 
+	  index page.
+
+2002-03-13  jacob berkman  <jacob@ximian.com>
+
+	* python/Makefile.am: remove LDADD and CFLAGS as this is broken
+	usage, redundant, and gcc specific
+
+Wed Mar 13 11:00:59 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: speedup some node selection operations, this can
+	  have a significant impact on DocBook Norm's stylesheets
+	* nanohttp.c: someone reported that SOCKLEN_T may not be defined
+	  make sure it's always the case
+	* debugXML.c: distinguish CDATA and comments in ls operations
+
+Tue Mar 12 19:45:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/*.h: Heiko W. Rupp fixed a lot of comments
+	  to generate better API descriptions etc...
+
+Mon Mar 11 10:10:30 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: Fixing #74186, made sure all boolean expressions
+	  get fully parenthesized, ran indent on the output
+	* configure.in HTMLtree.c SAX.c c14n.c debugXML.c tree.c xpointer.c
+	  include/libxml/tree.h: also #74186 related, removed the
+	  --with-buffers option, and all the preprocessor conditional
+	  sections that were resulting from it.
+
+Sun Mar 10 17:47:58 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: applied patch from Dodji Seketeli fixing an
+	  uninitailized variable in xmlValidGetValidElements()
+
+Sat Mar  9 15:10:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* c14n.c: fixed a few comments
+	* doc/*.html doc/*/*.html: regenerated the docs and added
+	  the C14N API
+	* doc/api.xsl doc/gnome-xml.sgml: fixups and added IDs
+
+Sat Mar  9 11:16:11 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: fix to adapt varaiations in the
+	  bindings
+	* configure.in python/setup.py python/setup.py.in: fixed to
+	  have the version of the python scripts automatically updated
+
+Fri Mar  8 16:45:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed a bug newly introduced and pointed by Uwe Fechner
+	  in xmlCopyProp()
+
+Fri Mar  8 15:49:10 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.17 release
+	* doc/*: updated and rebuilt the docs
+	* xpath.c: fixed a comment
+	* python/libxml.c: fixed a possible reentrancy problem
+
+Thu Mar  7 23:19:28 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c python/tests/Makefile.am python/tests/attribs.py:
+	  fixed xmlHasNsProp() bugs for defaulted from DTD attribs,
+	  added a specific regression test
+	* python/generator.py: xmlHasNsProp() and xmlHasProp() shall
+	  not raise exceptions when failing to find the attribute.
+
+Thu Mar  7 16:11:35 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xmllint.c: owen pointed out a problem with the
+	  ftme fix, gettimeofday() was not detected by configure and
+	  the ftime header wasn't included, dohhh
+
+Thu Mar  7 12:19:36 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in xmllint.c: trying to fix #71457 for timing
+	  precision when gettimeofday() is not availble but ftime() is
+
+Thu Mar  7 11:24:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in doc/Makefile.am: Fixed #73408 missing images
+	  are now copied on install and part of the -devel RPM
+
+Thu Mar  7 09:34:16 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: trying to avoid bug #72150 which was apparently
+	  caused by a gcc bug (or a processor problem) as detailed
+	  at http://veillard.com/gcc.bug
+
+Thu Mar  7 01:02:37 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c python/tests/Makefile.am python/tests/cutnpaste.py:
+	  fixed xmlReconciliateNs(), added a Python test/example for
+	  inter-document cut'n paste
+	* python/libxml.py: fixed node.doc on document nodes and added
+	  xpathEval() onto node objects
+
+Wed Mar  6 22:38:03 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c: fixed some htmlSetMetaEncoding() problems
+	* python/libxml.c python/tests/Makefile.am python/tests/serialize.py:
+	  fixup and integrated tests for the serialization stuff
+
+Wed Mar  6 19:40:57 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am libxml.3 libxml.4 libxml.spec.in: Fixed bug #72570
+	  moved the libxml man page to section 3
+
+Wed Mar  6 18:34:07 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fix bug #72490
+	* python/libxml.c python/libxml.py: added methods serialize()
+	  and saveTo() to all node elements.
+
+Tue Mar  5 21:27:03 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: closed #73430, don't read from an input source
+	  which indicated an end-of-file or an error.
+
+Tue Mar  5 16:33:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: make sure SAX endDocument is always called as
+	  this could result in a Python memory leak otherwise (it's
+	  used to decrement ref-counting)
+	* python/generator.py python/libxml.c python/libxml.py
+	  python/libxml2-python-api.xml python/libxml2class.txt
+	  python/tests/error.py python/tests/xpath.py: implemented
+	  the suggestions made by Gary Benson and extended the tests
+	  to match it.
+
+Tue Mar  5 10:35:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py: applied patch fixing #73450
+
+Mon Mar  4 17:59:29 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixing #61290 "namespace nodes have no parent"
+	  long standing divergence from the XPath REC. NodeSets
+	  simply hold a copy of namespace nodes and those node ->next
+	  points to the parent (which may not be the node carrying the
+	  definition).
+	* include/libxml/xpath.h: flagged but didn't added a possible
+	  speedup
+	* DOCBparser.c HTMLparser.c: removed some warnings from push
+	  parser due to new state being added.
+	* tree.c: new fix from Boris Erdmann
+	* configure.in c14n.c include/libxml/c14n.h testC14N.c: added
+	  the XML Canonalization support from Aleksey Sanin
+
+Sun Mar  3 15:12:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: patch from Boris Erdmann fixing some namespace odities
+	  with xmlCopyNode()
+
+Sat Mar  2 10:33:04 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: fix bug #72706 when loading a NULL entity
+
+Fri Mar  1 17:14:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: Fixed #72346, about handling of xmlns:foo="", this could
+	  actually change in a future XML Namespace revision.
+
+Fri Mar  1 17:12:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/types.c python/tests/Makefile.am python/tests/xpathret.py:
+	  added the possibility of returning nodesets from XPath extension
+	  functions written in Python
+
+Fri Mar  1 13:56:12 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/*: commiting some Python bindings work done while travelling
+
+Fri Mar  1 10:11:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: close #72663 and #72658, don't memdump unless compiled
+	  explicitely with memory debugging switched on
+
+Sat Feb 23 11:08:09 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt python/libxml_wrap.h python/types.c:
+	  Added wrapper for the xmlURIPtr type, provided accessors, fixed
+	  the accessor generator for strings
+	* python/tests/Makefile.am python/tests/tstURI.py: added a specific
+	  regression test.
+
+Fri Feb 22 23:44:57 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/README python/generator.py python/libxml.c python/setup.py:
+	  added the 'usual' setup.py to allow building a libxml2-python
+	  module based on the same code. The initialization is however
+	  different the 2 .so files fo libxml2 and libxslt are identical and
+	  they entry point initialize both libraries. this is done to avoid
+	  some possible nasty problem since the Python don't merge the maps
+	  of all shared modules.
+
+Wed Feb 20 23:16:08 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed a push/encoding bug reported by Michael
+	  on librsvg
+
+Wed Feb 20 19:54:05 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parserInternals.h: fixes a misplaced #endif
+
+Wed Feb 20 17:47:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c valid.c: found and fixed a couple of allocation bugs
+
+Wed Feb 20 15:36:03 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xml.html doc/python.html doc/*: added a Python and binding
+	  page describing the current state of the Python bindings and 
+	  giving pointers to the other languages wrappers.
+
+Wed Feb 20 11:16:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing 2.4.16
+	* doc/* python/libxml2class.txt: updated and rebuilt the docs,
+	  rebuilt the API and web site
+	* xpath.c: fixed #71978 portability bugs
+
+Tue Feb 19 22:49:36 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: oops broke automatic defaulting of namespaces attributes.
+
+Tue Feb 19 22:01:35 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parserInternals.h parser.c: had to change
+	  2 internal parsing API when processing document content
+	  to check the start and end of element content are defined
+	  in the same entity
+	* valid.c include/libxml/valid.h: attribute normalization can
+	  generate a validity error added xmlValidCtxtNormalizeAttributeValue()
+	  with the context to report it.
+	* SAX.c: fixed the last known bugs, crazy validation constraints
+	  when a document is standalone seems correctly handled. There
+	  is a couple of open issues left which need consideration especially
+	  PE93 on external unparsed entities and standalone status. 
+	  Ran 1819 tests: 1817 suceeded, 2 failed and 0 generated an error in 8.26 s.
+	  The 2 tests left failing are actually in error. Cleanup done.
+
+Tue Feb 19 15:17:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: implemented E59 spaces in CDATA does not match the
+	  nonterminal S
+
+Tue Feb 19 14:44:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c parser.c valid.c: more validation test fixups
+	* check-xml-test-suite.py: added duration info for the tests
+
+Mon Feb 18 23:25:08 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c valid.c: a couple of errors were reported but not
+	  saved back as such in the parsing context. Down to 1% failure rate
+	  Ran 1819 tests: 1801 suceeded, 18 failed and 0 generated an error
+
+Mon Feb 18 20:16:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlInternald.c: isExtender was missing a char 
+	* parser.c include/libxml/parser.h: % are acceptable in the
+	  internal subset if within a PUBLIC ID
+
+Mon Feb 18 19:27:32 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c parserInternals.c valid.c: more work on the conformance
+	  suite. Took the step to finally block documents with encoding
+	  errors. It's a fatal error per the spec, people should have fixed
+	  their documents by now.
+
+Mon Feb 18 15:30:14 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: fixed the test script after some discussion
+	  on the semantic of TYPE="error"
+	* Makefile.am: added the script to the distrib
+
+Mon Feb 18 12:17:41 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c entities.c: fixed a couple of conformances issues deep
+	  into the validation code (standalone and undeclared Notations)
+
+Mon Feb 18 00:17:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed #71741 supid typo an a bug about encoding parsing
+	  stayed there for years !
+
+Mon Feb 18 00:06:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c SAX.c: fixed #71740 NotationDecl with a required field
+	  missing
+
+Sun Feb 17 23:45:40 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: improved the behaviour a bit as
+	  well as the logs
+	* parser.c valid.c SAX.c: fixed a few more bugs 
+	  "Ran 1819 tests: 1778 suceeded, 41 failed, and 0 generated an error"
+
+Sun Feb 17 20:41:37 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* check-xml-test-suite.py: python script to run regression tests
+	  against the XML Test suite of W3C/OASis
+	* SAX.c: fixed a validation bug
+	* parser.c: fixed 3 errors pointed by the test suite
+	* doc/buildDocBookCatalog: fixed a typo pointed by drake
+	* python/Makefile.am: fixed a dependendy
+
+Fri Feb 15 21:47:13 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: avoid a warning bug #71594
+
+Wed Feb 13 22:13:33 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: Jesse Perry provided a patch to remove a few
+	  warning on alpha/Tru64
+
+Wed Feb 13 14:30:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/entities.h: fixing a comment
+	* valid.c: fixing some troubles with validity check on namespaces
+	* result/VC/NS3 test/VC/NS3: added a specific regression test
+
+Wed Feb 13 14:05:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Fixing #71342 serializing '\n' in attribute values
+	* result/noent/att3 result/att3 test/att3: added a specific
+	  test.
+
+Tue Feb 12 14:45:32 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c: couple of bug fixes
+
+Mon Feb 11 19:41:29 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/*.py: removed tabs and used spaces.
+
+Mon Feb 11 19:25:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing 2.4.15
+	* doc/news.html doc/xml.html doc/xmlio.html: rebuilt some docs
+
+Mon Feb 11 14:53:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmlcatalog_man.xml: trying to close Red Hat bug #58707
+	  https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=58707
+
+Mon Feb 11 09:53:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/encoding.h include/libxml/entities.h
+	  include/libxml/globals.h include/libxml/parser.h
+	  include/libxml/threads.h include/libxml/tree.h
+	  include/libxml/xmlmemory.h: trying to fix the include mess
+
+Mon Feb 11 08:53:33 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlmemory.h: reverted part of the previous
+	  attempt to provide #69655, this was breaking the build.
+
+Sun Feb 10 14:13:34 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c Makefile.am build_glob.py configure.in debugXML.c
+	  globals.c parser.c threads.c tree.c valid.c xmlmemory.c
+	  xpath.c xpointer.c include/libxml/globals.h include/libxml/parser.h
+	  include/libxml/parserInternals.h include/libxml/tree.h
+	  include/libxml/xmlmemory.h include/libxml/xpathInternals.h:
+	  Tentatively fixed #69655 , make compiling with -Wredundant-decls
+	  clean.
+	* python/libxml.c: fixed a warning.
+
+Sun Feb 10 12:02:59 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c valid.c xinclude.c: fix #68882, cleanup the XInclude
+	  copying of node, merge back IDs in the target document.
+	* result/XInclude/docids.xml test/XInclude/docs/docids.xml
+	  test/XInclude/ents/ids.xml: test case
+	* result/VC/ElementValid4: output changed due to a typo fix
+
+Sat Feb  9 23:15:04 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: seems some version of automake didn't
+	  generate the dependencies right as Jacob found out. Add
+	  an extra dependency rule.
+
+Sat Feb  9 18:59:23 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c valid.c: Justin Fletcher found some parts
+	  of the code needing cleanup
+	* libxml.spec.in python/Makefile.am python/generator.py
+	  python/libxml.c python/libxml.py: Fixed the python Makefiles
+	  corrected a bug showing up on ia64, changed the name of the
+	  python internal module too
+
+Fri Feb  8 15:19:28 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: applied patch from Andris Pavenis for binary
+	  name suffixes
+
+Fri Feb  8 14:43:17 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c win32/win32config.h: fixing #68748
+
+Fri Feb  8 14:37:05 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixing #70166
+
+Fri Feb  8 14:31:24 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixing #70077
+
+Fri Feb  8 14:24:02 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Copyright Makefile.am README configure.in libxml.spec.in:
+	  Changed to the MIT Licence
+	* doc/FAQ.html doc/catalog.html doc/intro.html doc/xml.html
+	  doc/xmlio.html: updated the doc accordingly
+	* include/libxml/xmlwin32version.h configure.in: preparing
+	  2.4.14 release
+	* python/generator.py python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt python/libxml_wrap.h python/types.c:
+	  fixed the const xmlChar * wrapper and generator, XPath extension
+	  functions now use the context as first argument
+	* python/tests/tstxpath.py python/tests/xpath.py
+	  python/tests/xpathext.py: Updated the tests accordingly
+	* tree.c: fixed bug #70067
+
+Thu Feb  7 17:33:58 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: cleanup
+	* debugXML.c: always use stdout if output is NULL
+	* xmlIO.c: don't close filedescriptors passed to outputBuffers
+	* python/Makefile.am python/generator.py python/libxml2class.txt
+	  python/libxml_wrap.h python/types.c: augmented the number of bindings
+	  handling FILE * and XPath contexts
+	* python/tests/Makefile.am: avoid a stupid problem due to the
+	  use of TEST.
+
+Wed Feb  6 23:37:07 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: fixed stupid bug #70738 found by alfons hoogervorst
+
+Wed Feb  6 17:04:51 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/TODO python/libxml.c: cleanup the extension function lookup
+	* xmlmemory.c include/libxml/xmlmemory.h: always compile the list
+
+Tue Feb  5 17:33:30 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in python/Makefile.am: do not install outside
+	  of prefix
+
+Mon Feb  4 15:05:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/TODO python/libxml.c: started adding SAX interfaces
+	* python/tests/Makefile.am python/tests/pushSAX.py: added a basic
+	  SAX test
+
+Mon Feb  4 01:12:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: hardened the addChild function
+	* python/generator.py python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt python/libxml_wrap.h python/TODO:
+	  added accessors needed for xmlNode, a bit more testing and
+	  extension of interfaces
+	* python/tests/Makefile.am python/tests/build.py: added a test
+	  build from scratch/save/load/check
+
+Sun Feb  3 21:10:39 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: change a small bit in the way valididy
+	  error messages get initialized
+	* python/TODO python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt python/libxml_wrap.h python/types.c:
+	  added some memory debugging to track leaks at the libxml2 level
+	* python/tests/*.py: changed all tests to check for leaks,
+	  there is just one left in XPath extension registrations.
+
+Sun Feb  3 17:50:46 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/TODO python/generator.py python/libxml2-python-api.xml
+	  python/libxml2class.txt: more accessor classes for the parser
+	  context, allow to switch on and check validity
+	* python/tests/Makefile.am python/tests/error.py
+	  python/tests/invalid.xml python/tests/valid.xml
+	  python/tests/validate.py: attded more test and and added error.py
+	  which I forgot to commit in the last step
+
+Sun Feb  3 16:03:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/types.c: cleanup
+	* python/libxml.c python/libxml.py python/libxml_wrap.h
+	  python/generator.py python/libxml2-python-api.xml 
+	  python/libxml2class.txt: added class for parser context, added
+	  first cut for push mode support. Added a framework to generate
+	  accessors functions.
+	* python/tests/Makefile.am python/tests/push.py: added a push
+	  test
+
+Sun Feb  3 00:17:26 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/TODO python/libxml.py: fixed a small
+	  bug a bit of cleanup.
+
+Sat Feb  2 22:47:10 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt: adding error redirections and preformat
+	  to a python handler
+	* python/tests/Makefile.am python/tests/*.py: cleanup made all
+	  tests self checking
+
+Sat Feb  2 13:18:54 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/libxml.c python/libxml.py: fixed a stupid bug when renaming
+	  a function
+
+Sat Feb  2 11:25:51 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in python/Makefile.am python/TODO python/generator.py
+	  python/libxml.c python/libxml2-python-api.xml
+	  python/libxml2class.txt: Progressing through the TODOs, class
+	  description output, extra XML API, RPM now builds the wrappers
+	  for all python installed versions
+
+Sat Feb  2 10:13:52 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in libxml.spec.in python/Makefile.am python/TODO
+	  python/generator.py python/libxml2class.txt: added more informations
+	  in the libxml2-python package including docs. Slightly changed
+	  the class hierarchy
+	* python/tests/*: added basic regression tests infrastructure too
+
+Fri Feb  1 23:11:58 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in libxml.spec.in example/Makefile.am python/Makefile.am:
+	  added libxml2-python as part of the packages installed
+
+Fri Feb  1 18:48:19 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/generator.py python/libxml.c
+	  python/libxml.py: more work, now able to extend the
+	  XPath interpreter with functions written in python.
+
+Fri Feb  1 10:28:51 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am: Jacob sent a patch to allow building from
+	  tarfile.
+
+Fri Feb  1 00:40:48 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/Makefile.am python/libxml.c configure.in Makefile.am:
+	  inserted the python wrappers build, I hope this won't be too
+	  unportable
+
+Thu Jan 31 21:27:37 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: minor optimization
+	* python/generator.py python/libxml.c python/libxml.py
+	  python/libxml_wrap.h: more work on the python bindings,
+	  they now support XPath and there is no evident leak
+
+Thu Jan 31 00:48:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml.py:
+	  more work on the python bindings generator.
+
+Wed Jan 30 21:51:26 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml_wrap.h:
+	  more work on the python bindings.
+
+Wed Jan 30 17:35:33 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.c python/libxml.py
+	  python/libxml_wrap.h: commited early version of a python binding
+	  for private use only ATM
+
+Sat Jan 26 22:41:13 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c tree.c include/libxml/entities.h: applied patch
+	  from Anthony Jones to implement copy of DTD subtree too. Had
+	  just to keep 2 function private which really ought to become
+	  public ones.
+
+Fri Jan 25 15:14:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: added pointers to the web pages in the usage()
+
+Thu Jan 24 17:04:04 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: more fixes from Petr Kozelka for attribute handling
+	  in the tree API to align the semantic with DOM.
+
+Thu Jan 24 16:00:53 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c tree.c entities.c: another set of patches from
+	  Anthony Jones for copy operations cleanup and robustness
+
+Wed Jan 23 18:53:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/APIchunk*.html doc/parsedecl.py doc/api.xsl: generated
+	  an alphabetic index based on comments content
+	* doc/*: rebuilt the web site with the new references
+
+Wed Jan 23 15:14:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.h: Greg Sjaardema suggested to use an
+	  eponential buffer groth policy in xmlParserAddNodeInfo()
+
+Wed Jan 23 13:32:40 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/api.xsl doc/APIconstructors.html doc/APIfiles.html
+	  doc/APIfunctions.html doc/APIsymbols.html doc/libxml2-refs.xml
+	  doc/parsedecl.py doc/Makefile.am: updated the python extractor
+	  to generate cross-references, and added/updated the stylesheets
+	  to generate and link API indexes. The generic keyword index
+	  is not done yet.
+	* doc/*.html: regenerated all the usual docs too
+
+Tue Jan 22 23:11:26 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: added an xpath function to the shell for T. V. Raman
+
+Tue Jan 22 22:42:23 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: patch from Anthony Jones to catch NULL nodes in
+	  debug routines.
+
+Tue Jan 22 22:38:42 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: apply an patch from Petr Kozelka for unlink and replace 
+	  support of attribute nodes
+
+Tue Jan 22 19:12:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/libxml2-api.xml doc/parsedecl.py: Build a new version
+	  hopefully near complete and fully documented of the API in XML
+	* HTMLtree.c SAX.c debugXML.c error.c globals.c parser.c tree.c
+	 xmlIO.c xmlmemory.c include/libxml/catalog.h include/libxml/hash.h
+	 include/libxml/list.h include/libxml/parser.h include/libxml/tree.h
+	 include/libxml/parserInternals.h include/libxml/valid.hi
+	 include/libxml/xmlIO.h include/libxml/xmlerror.hi
+	 include/libxml/xmlmemory.h include/libxml/xmlversion.h.ini
+	 include/libxml/xpath.h include/libxml/xpathInternals.h:
+	  Cleaned up the doc comments a lot in the process, the interface
+	  coverage is now 100%
+
+Tue Jan 22 00:12:58 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/libxml2-api.xml doc/parsedecl.py: improved the script to
+	  extracts comments from the gtk-doc DocBook output (a bit
+	  convoluted but seems to work).
+
+Mon Jan 21 18:29:19 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am doc/Makefile.am doc/libxml2-api.xml doc/parsedecl.py:
+	  added an XML description of the API, moved the script generating
+	  it here. Added a "make api" target
+
+Mon Jan 21 14:34:37 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Adam Lounds pointed out a bug in xmlSearchNs()
+
+Mon Jan 21 09:55:21 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c include/libxml/xpathInternals.h: the change made to
+	  xmlXPathFuncLookupFunc was incompatible roll it back
+
+Sun Jan 20 23:03:41 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: cleanup patch from Anthony Jones
+	* doc/Makefile.am: fix the headers to avoid in make scan
+	* parserInternals.c xpath.c include/libxml/*.h: cleanup of the
+	  includes, * vs Ptr and general cleanup
+	* parsedecl.py: first version of a script to extract the
+	  module interfaces, the goal will be to provide .decl or XML
+	  specification of the interfaces to build wrappers.
+
+Sun Jan 20 13:38:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/xmlcatalog_man.xml xmlcatalog.c: Fixed bug #68830, xmlcatalog
+	  now provides return codes in case of errors
+
+Sat Jan 19 16:36:21 CET 2002 Bjorn Reese <breese@users.sourceforge.net>
+
+	* trio.h trio.c triodef.h triop.h trionan.h trionan.c Makefile.am:
+	  Upgraded to trio baseline 1.6
+	* strio.h strio.c: Replaced by triostr.h and triostr.c
+
+Fri Jan 18 17:22:50 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c xmlIO.c xmlcatalog.c: removed the last occurences
+	  of strdup usage in the code
+
+Fri Jan 18 12:47:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c error.c: Keith Isdale complained rightly that 
+	  xmlInitParser() did not preserve value set by xmlSetGenericErrorFunc
+
+Thu Jan 17 09:44:44 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed the funxtion to set the xml: attributes
+	* debugXML.c: added "setbase" to test it.
+
+Wed Jan 16 16:36:08 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: update xmlNodeSetContent() and xmlNodeSetContentLen()
+	  to allow updating an attribute content
+
+Tue Jan 15 18:09:23 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h: try to avoid problems when compiling on Windows
+
+Mon Jan 14 18:56:25 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* hash.c: patch from Anthony Jones for hash.c allocation size
+	* Makefile.am: trying to work around Yet Another Libtool Madness
+	  and build the 2.4.13 release finally ...
+
+Mon Jan 14 18:27:19 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: updated to 2.4.13
+	* doc/* : update of the documentation
+
+Mon Jan 14 17:53:41 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c tree.c: some cleanup after an unsuccessful attempt
+	  at fixing #61290 :-(
+
+Sun Jan 13 21:30:54 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed xmlSaveFormatFileEnc() when encoding == NULL
+	  Fixes bug #67229
+
+Sun Jan 13 17:14:06 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: trying to avoid troubles when a subtree is copied
+	  and coalesced in part with the target tree. Should fix 
+	  bug #67407
+
+Sun Jan 13 16:37:15 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed validation of attributes content of type
+	  NAME NAMES NMTOKEN and NMTOKENS to accept internationalized
+	  values, very old bug. Fixes #67671
+
+Sun Jan 13 15:07:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parserInternals.h tree.c: integrated
+	  a couple of fixes and a new API function xmlSetEntityReferenceFunc()
+	  from Keith Isdale and dedicated to xsldbg the XSLT debugger.
+
+Sun Jan 13 14:23:21 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: applied Serguei Narojnyi's patch to add native
+	  thread support on the Win32 platform
+	* testThreadsWin32.c Makefile.am: added the test program also
+	  from Serguei, Win32 specific
+	* include/win32config.h include/libxml/xmlwin32version.h.in:
+	  added patch from Igor for the Windows thread specific defines.
+
+Wed Jan  9 12:50:39 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: Anthony Jones pointed a bug in xmlCopyEntity()
+
+Tue Jan  8 14:23:22 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*.html doc/site.xsl doc/Makefile: renamed XML.html
+	  output page into XMLinfo.html. Close bug #66951 and
+	  raised by Robert Collins too.
+
+Tue Jan  8 14:13:18 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c: Paul Keogh pointed out a possibility of segfault
+	  on repeted xmlAddEncodingAlias() / xmlCleanupEncodingAlias().
+	  Closes bug # 68238
+
+Tue Jan  8 12:48:27 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/*.html: updated the Gdome2 links
+
+Tue Jan  8 11:32:30 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h: Applied following patches from Robert Collins
+	  and make sure IN_LIBXML is defined when compiling it
+	-------
+	* include/libxml/xmlversion.h.in (LIBXML_DLL_IMPORT): Use on Cygwin
+	  as well as Visual C.
+	* parser.c (XML_DIR_SEP): Don't use '\\' for Cygwin.
+	* parserInternals.c (XML_DIR_SEP): Don't use '\\' for Cygwin.
+	* strio.c (PLATFORM_UNIX): Define for Cygwin.
+	* triodef.h (TRIO_PLATFORM_UNIX): Define for Cygwin.
+	* xmlIO.c (xmlFileOpen): Use unix behaviour for Cygwin.
+	  Use binary mode opens for Cygwin (xmlFileOpenW xmlParserGetDirectory
+	  xmlSysIDExists xmlNoNetExists).
+	* xmllint.c: Don't include winsock2.h for Cygwin.
+
+Mon Jan  7 17:52:48 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Jirka Kosek pointer out a bug in xmlParseTextDecl()
+	  when the version info is not present.
+
+Mon Jan  7 00:03:58 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Anthony Jones  pointed out a problem in
+	  xmlStringGetNodeList() and provided a fix for it
+
+Sun Jan  6 13:45:49 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: patch from Frank J Franklin to remove a bug in
+	  xmlCreatePushParserCtxt() when the initial buffer passed
+	  is large.
+
+Sat Jan  5 19:24:23 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* win32/*: big cleanup of the Windows/MSVC project files
+	  from Igor Zlatkovic
+
+Wed Jan  2 14:11:35 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* doc/Makefile.am: should fix #67674 and avoid troubles if 
+	  xsltproc is not available or fails in the prefix provided
+
+Tue Jan  1 17:48:56 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlmemory.c: one more doc patch from Charlie Bozeman.
+
+Mon Dec 31 17:35:40 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c parser.c valid.c include/libxml/parserInternals.h
+	  include/libxml/xmlerror.h include/libxml/xpathInternals.h:
+	  Fixed a few other problems raised by Charlie Bozeman.
+	* result/VC/ElementValid[5-7]: fixed the output
+
+Mon Dec 31 17:13:34 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* *.c include/libxml/*.h doc/html/*: applied 42 documentation
+	  patches from Charlie Bozeman. Regenerated the HTML docs.
+
+Thu Dec 20 14:59:52 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/debugXML.h win32/dsp/libxml2.def.src: fixes
+	  for Windows from Igor
+
+Tue Dec 18 12:13:33 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: applied Justin Fletcher patch for --output or -o
+
+Tue Dec 18 08:52:32 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/libxml2/libxml2.def.src: close #67019
+
+Tue Dec 18 08:08:51 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: applied Justin Fletcher generic timing patch
+	  similar to the one already applied to xsltproc.
+
+Mon Dec 17 16:29:08 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h tree.c: applied documentation patches
+	  from Charlie Bozeman
+
+Thu Dec 13 21:24:16 MST 2001 John Fleck <jfleck@inkstain.net>
+
+	*doc/xmllint.xml, xmllint.1 - document --dropdtd
+
+Thu Dec 13 23:19:50 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fix the xmlStrdup() used in the previous patch.
+	* valid.c: added --dropdtd
+	* tree.c: fixed xmlUnlinkNode so it also removes the references
+	  from the document if the node is a DTD
+
+Thu Dec 13 15:54:35 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c valid.c: cleanup some static declarations
+
+Thu Dec 13 15:23:04 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: removed another strdup()
+	* doc/FAQ: removed the HP/UX entry
+
+Thu Dec 13 09:44:58 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fix bug #66816 when validating.
+	* xmllint.c: don't use sys/time.h if configure did not found it
+
+Mon Dec 10 21:39:55 MST 2001 John Fleck <jfleck@inkstain.net>
+
+	* docs/xmllint.1, xmllint.xml, xmlcatalog.1, xmlcatalog_man.html,
+	xmlcatalog_man.xml
+
+Mon Dec 10 22:06:16 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlmemory.h: Hietaniemi Jarkko pointed out that
+	  xmlInitMemory() was declared twice
+
+Sun Dec  9 14:59:23 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: do not reference strdup() !
+	* configure.in libxml-2.0.pc.in: trying to fix the libs
+	  of the various config extraction modules
+
+Fri Dec  7 15:21:33 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in : preparing 2.4.12
+	* doc/* : updated and rebuilt the docs
+
+Fri Dec  7 12:32:00 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: closed bug #66159
+	* testURI.c: added --escape option
+	* configure.in: some cleanup for xml2-config --cflags
+
+Thu Dec  6 15:31:30 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c testThreads.c: removed some misplaced includes
+	  of xmlversion.h
+
+Thu Dec  6 09:06:08 EST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* threads.c: patch from Gary Pennington fixing a possible
+	  problem at initialization time.
+
+Wed Dec  5 13:01:37 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in libxml.h parser.c testThreads.c macos/: integrated
+	  Eric Lavigne contribution to build libxml2 on MacOS using
+	  CodeWarrior.
+
+Tue Dec  4 14:13:44 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: applied Geert Kloosterman's patch to fix
+	  --repeat --timing output
+
+Thu Nov 29 17:10:22 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Robin Berjon <robin@knowscape.com> found a case
+	  where non-wellformed XML declaractions were not detected.
+
+Wed Nov 28 15:41:40 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpointer.c: fixed a compilation bug pointed by Danny Jamshy
+
+Wed Nov 28 10:09:51 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: as robert pointed again, xmlInputCallbackInitialized
+	  gets reset by xmlCleanupInputCallbacks() and this makes the
+	  function useless. Same for output.
+
+Tue Nov 27 17:22:36 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: robert pointed out a loop error in callback cleanups
+
+Mon Nov 26 16:56:00 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c debugXML.c include/libxml/tree.h include/libxml/debugXML.h:
+	  moved xmlGetLineNo() and xmlGetNodePath() into the main tree module,
+	  they are not really tied to debugging
+
+Mon Nov 26 11:31:36 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing 2.4.11
+	* xmllint.c: better --catalogs description
+
+Sun Nov 25 11:34:24 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: fixed a couple of problems in xmlSetProp()
+
+Thu Nov 22 19:19:10 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c tree.c xmlIO.c xmlmemory.c: some cleanups when chasing
+	  unappropriate stdout output.
+
+Thu Nov 22 13:58:14 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h: Fixed a couple of macro errors pointed out
+	  by Denis Beurive, closes #65111
+
+Tue Nov 20 10:34:01 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: in case of content model validity error, don't
+	  print it if validity warnings were not requested.
+
+Tue Nov 20 09:30:02 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: applied a couple of patches from Brian D Ripley.
+	* parserInternals.c: removed the last exit() call. Print an
+	  unmaskable error on stderr instead (library mismatch detection)
+
+Sat Nov 17 17:16:51 MST 2001 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmllint.xml, doc/xmllint.1 - update xmllint man page with
+	shell instructions from Heiko Rupp
+
+Thu Nov 15 14:53:42 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: use the URL notation file:// for default catalog paths
+
+Wed Nov 14 16:03:02 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/tree.h: better comments for _private fields
+	* tree.c: removed a problem when copying an entity reference.
+
+Tue Nov 13 16:23:04 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* vms/*: updated instructions and diffs from John A Fotheringham
+
+Mon Nov 12 23:43:22 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlerror.h: avoid an include problem if
+	  #include <libxml/xmlerror.h> happens first in code
+	  seems to be the case in KDE libs
+
+Mon Nov 12 22:32:41 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/* include/libxml/xmlwin32version.h.in: update
+	  from Igor for Windows
+
+Mon Nov 12 10:19:41 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: Gary Pennington pointed out a missing prefix
+
+Sat Nov 10 12:55:42 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: preparing 2.4.10
+	* doc/*: upgraded and rebuilt the docs
+
+Sat Nov 10 12:33:38 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fix comment in scripts element parsing.
+	* result/HTML/doc3*: updated the results.
+
+Sat Nov 10 11:18:18 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: another URI bug fix #63336, using Joel Young patch.
+
+Sat Nov 10 11:07:26 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/debugXML.h: add xmlGetNodePath()
+	  a cleaned up version of the Pwd shell string generation.
+
+Fri Nov  9 00:34:13 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c include/libxml/tree.h: trying to fix namespaces +
+	  validation problems for good, closing #63619 in the process
+	* result/valid/dia.xml test/valid/dia.xml: the Dia test was
+	  wrong in this respect, fixed it.
+
+Thu Nov  8 18:31:40 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: Morus Walter patch to allow --format and --encode
+
+Thu Nov  8 14:52:18 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: Stefan Kost provided an help command for the shell
+
+Wed Nov  7 14:32:55 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: Heiko Rupp pointed that the shell would crash
+	  on empty nodesets returns.
+
+Wed Nov  7 13:52:36 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: Weiqi Gao pointed out that xmlcatalog
+	  migh need the history libraries
+
+Tue Nov  6 23:49:09 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c test/HTML/lt.html result/HTML/lt.html*:
+	  handle the case of < in quoted attributes, Bastian Kleineidam
+
+Tue Nov  6 16:21:33 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in include/libxml/xmlwin32version.h: releasing 2.4.9
+	  fixing catalog breakages
+	* Makefile.am catalog.c result/catalogs/catal 
+	  result/catalogs/mycatalog.* test/catalogs/catal*:
+	  fixed more problems in catalog support, added more regression tests
+	  for both XML and SGML catalog handling
+
+Mon Nov  5 20:26:41 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c: applied an improvement to xmlGetLineNo() from
+	  Keith Isdale
+
+Mon Nov  5 15:20:16 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: dohhhh XML catalog add and remove ops were broken too.
+	  Side effect of the progressive catalog loading
+
+Mon Nov  5 12:40:54 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: confexecdir and confexec_DATA were defined twice
+	  pointed out by Karl Eichwalder
+
+Sun Nov  4 23:18:34 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmlcatalog.c: avoid unlink() and use remove() instead.
+
+Sun Nov  4 23:12:38 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.spec.in: cleanup
+	* include/libxml/xmlwin32version.h: updated with 2.4.8
+
+Sun Nov  4 21:17:24 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c global.data globals.c testThreads.c: fix bug #63752
+	  of compiling libxml with a non standard set of options
+
+Sun Nov  4 13:11:41 MST 2001 John Fleck <jfleck@inkstain.net
+
+	* doc/xmllint.xml, xmllint.1 - updating xmllint man page to
+	document --sgml option, fixing gnome bugzilla #63382
+
+Sun Nov  4 20:56:53 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h catalog.c: Fixed SGML catalogs
+	  breakage of 2.4.7, added a couple of really needed APIs
+	  like xmlCatalogIsEmpty() and xmlNewCatalog()
+	* xmlcatalog.c: updated --sgml --noout to be a suitable replacement
+	  for install-catalog
+	* configure.in: preparing 2.4.8
+
+Thu Nov  1 15:29:31 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c tree.c include/libxml/HTMLtree.h
+	  include/libxml/tree.h include/libxml/xmlIO.h: more include
+	  cleanups, export cleanly one html output + format function.
+
+Thu Nov  1 14:12:12 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: removed initGenericErrorDefaultFunc call from
+	  xmlInitParser() since it could destroy previous calls to
+	  xsltSetGenericErrorFunc() effects
+
+Thu Nov  1 09:37:13 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* debugXML.c include/libxml/debugXML.h: bool can be a reserved
+	  keyword.
+
+Wed Oct 31 18:50:08 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: cleanup
+	* threads.c: cleanup too
+	* xmlIO.c include/libxml/xmlIO.h: added xmlNoNetExternalEntityLoader()
+	  from xsltproc
+	* include/libxml/tree.h include/libxml/parser.h: trying to break a
+	  dependency loop.
+
+Tue Oct 30 18:38:53 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: Justin Fletcher pointed out that xmlParseXMLCatalog
+	  was not used anymore !
+
+Tue Oct 30 13:33:13 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.7
+	* Makefile.am doc/Makefile.am: switched to the latest xmllint
+	  manual page from John
+	* doc/*: updated the doc and rebuilt the generated pages
+
+Tue Oct 30 11:31:19 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: closing bug #62711, the library should never
+	  close stdin or stdout.
+
+Tue Oct 30 10:46:12 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: second pass at fixing #63336, using Joel Young
+	  final patch. looks okay.
+
+Tue Oct 30 00:56:05 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c include/libxml/uri.h: trying to clear #63336
+	  allowing the escaping routine to parse unconformant
+	  URI-References.
+
+Mon Oct 29 19:09:46 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* vms/readme.vms vms/build_libxml.com nanoftp.c 
+	  include/libxml/xmlversion.h.in: a few VMS updates from
+	  John A Fotheringham
+	* include/libxml/xmlIO.h xmlIO.c: added xmlCleanupInputCallbacks()
+	  and xmlCleanupOutputCallbacks() for the Perl binding people.
+
+Mon Oct 29 12:44:17 CET 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c globals.c DOCBparser.c HTMLparser.c error.c:
+	  apply fixes to close #63271 and avoid segfaults when
+	  the error routine gets callbed before xmlInitParser()
+	  get called.
+	* nanoftp.c error.c: Applied patches from Justin Fletcher
+	  correcting some xmlGenericError misuses.
+
+Sat Oct 27 14:04:45 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	*doc/xmllint.xml, doc/xmllint.1
+	New and improved man page for xmllint - .xml is the original, .1
+	is the generated man page
+
+Wed Oct 24 14:34:25 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* doc/site.xsl doc/*.html doc/Makefile.am: now autogenerate
+	  the web site from the main HTML document.
+
+Tue Oct 23 14:32:04 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: fixed an erroneous validation bug when PE refs
+	  occurs in external parsed entities referenced from the
+	  internals subset
+	* test/valid/index.xml test/valid/dtds/nitf-2-5.dtd
+	  test/valid/dtds/NewsMLv1.0.dtd result/valid/index.xml*:
+	  added the associated testcase, it's a nice one.
+	* HTMLparser.c: generate the DTD node as HTML still ...
+	* HTMLtree.c: fixed errors in Set/GetMetaEncoding 
+
+Mon Oct 22 14:20:17 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: fixed a bug in htmlNewDoc()
+
+Mon Oct 22 11:32:36 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* test/threads/*: added entities testing to the Thread test
+	* testThreads.c: make the test reasonable
+	* DOCBparser.c: fix the DTD public and system ID
+	* xmllint.c: added --sgml for SGML DocBook importing
+	* Makefile.am: added Docbtests target
+
+Fri Oct 19 11:47:13 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c: use only "anonymous@" string for anonymous passwds
+	* testThreads.c: removed bogus include
+
+Thu Oct 18 16:56:23 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c valid.c result/valid/rss.xml result/valid/rss.xml.err:
+	  fixed a very serious (looping) validation bug
+
+Wed Oct 17 11:56:25 EDT 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/globals.h include/libxml/threads.h threads.c
+	  testThreads.c: far more testing, cleaning up bugs
+	* *.c : make sure globals.h is always included.
+
+Wed Oct 17 17:41:41 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c: try to get rid of parser loops for good.
+
+Wed Oct 17 13:29:02 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: fixed some bugs in CFLAGS passing.
+	* test/threads Makefile.am testThreads.c: added a specific
+	  threaded test case (really nasty, guaranteed).
+
+Tue Oct 16 23:01:49 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: serious cleanup on the management of the
+	  XML catalog tree, more tests done, especially with
+	  the catalog PI.
+
+Tue Oct 16 08:43:43 EDT 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: avoid a problem in catalog cleanup on SMP if
+	  catalogs were not initialized.
+
+Tue Oct 16 14:33:19 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c xpath.c: trying to cleanup the not thread safe
+	  parts of the library.
+
+Mon Oct 15 14:30:11 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/globals.h configure.in global.data: make
+	  the allocation be per-thread a configure option
+	* encoding.c include/libxml/parser.h: fixed compilation
+	  errors
+
+Mon Oct 15 12:45:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/parser.h: Norm reported that a few lines
+	  added were breaking libxslt compile, removed them for now
+
+Sun Oct 14 05:55:01 EDT 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c parserInternals.c threads.c: debugged and fixed
+	  initialization problems which were giving troubles on SMP
+	  boxes.
+
+Sat Oct 13 16:17:13 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/Makefile.am: missing globals.h
+
+Sat Oct 13 14:15:00 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* globals.c: added a couple of standard includes.
+
+Sat Oct 13 11:08:20 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/SAX.h include/libxml/globals.h include/libxml/parser.h
+	  include/libxml/parserInternals.h include/libxml/tree.h
+	  include/libxml/xmlerror.h HTMLparser.c SAX.c error.c globals.c
+	  nanoftp.c nanohttp.c parser.c parserInternals.c testDocbook.c
+	  testHTML.c testSAX.c tree.c uri.c xlink.c xmlmemory.c:
+	  Applied the last patches from Gary, cleanup, activated threading
+	  all user accessible global variables are now handled in globals.[ch]
+	  Still a bit rought but make tests passes with either 
+	  --with-threads defined at configure time or not.
+	* Makefile.am example/Makefile.am: added globals.[ch] and threads
+	  linking options
+
+Fri Oct 12 19:25:55 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am include/libxml/Makefile.am
+	  include/libxml/globals.h globals.c  include/libxml/threads.h
+	  threads.c build_glob.py global.data xmlcatalog.c acconfig.h
+	  configure.in: started integrating the core of the thread support
+	  not activated yet but half integrated. The code should still
+	  compile and work anyway.
+
+Fri Oct 12 00:53:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLtree.c catalog.c debugXML.c entities.c nanoftp.c
+	  parser.c valid.c xmlmemory.c xpath.c xpointer.c: started
+	  integrating the non-controversial parts of Gary Pennington
+	  multithread patches
+	* catalog.c: corrected a small bug introduced
+
+Thu Oct 11 20:58:15 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c include/libxml/catalog.h: very serious cleanup,
+	  isolating unportable code and as much as possible the accesses
+	  to the global shared catalog. May need more testing !
+
+Thu Oct 11 11:10:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/debugXML.h debugXML.c tree.c: integrating
+	  Keith Isdale patches for the XSLT debugger interfaces. Some
+	  cleanup
+
+Thu Oct 11 08:44:01 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/Makefile.mingw: update from Tobias Peters for 2.4.5
+	* DOCBparser.c: generate line nubers in elements
+
+Wed Oct 10 11:35:45 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing 2.4.6 release
+	* doc/xml.html doc/html/*: updated and rebuilt the docs
+	* include/libxml/*.h *.c: fixed a number of teh/the widht/width typos
+
+Mon Oct  8 20:38:27 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog_man.xml, xmlcatalog.1, xmlcatalog_man.html
+	adding documentation for DV's supercatalog support
+
+Mon Oct  8 17:00:16 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h catalog.c xmlcatalog.c: adding SGML
+	  super catalog support adding one API and one flag --sgml to
+	  xmlcatalog
+
+Sun Oct  7 16:43:57 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog_man.xml, xmlcatalog.1
+	One more crack at
+	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=54392 
+
+Sun Oct  7 18:47:02 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* xpath.c: implemented xmlXPathObjectCopy for external objects
+	* include/libxml/xpathInternals.h: added xmlXPathStackIsExternal
+
+Sat Oct  6 16:25:52 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	*doc/xmlcatalog_man.xml, xmlcatalog_man.html, xmlcatalog.1
+	finishing up fix to
+	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=54392, making
+	the xmlcatalog man page display more elegantly
+
+Sat Oct  6 15:27:12 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: closing bug #61832
+	* HTMLparser.c: removed a warning
+
+Sat Oct  6 15:07:14 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixing #61673 part I, do not loose doc information
+	  when copying result value trees.
+
+Sat Oct  6 11:58:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: trying to harden the XPath interpreter
+
+Fri Oct  5 20:37:51 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog.1 updated using a new stylesheet to address, in
+	part, https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=54392
+
+Fri Oct  5 23:35:00 HKT 2001 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser: repaired another loop problem
+
+Fri Oct  5 11:16:21 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* uri.c: applied fix from Mathias Hasselmann about a bug in URI
+	  parsing.
+	* xpath.c: fix bug #61291 the default XML namespace node is
+	  missing from the namespace axis.
+	* tree.c: refuse to create namespaces nodes with prefix "xml"
+
+Thu Oct  4 16:47:44 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: ouch a non-defined namespace could lead to a crash,
+	  fixed #61215
+
+Thu Oct  4 16:24:26 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: closed bug #61054
+
+Wed Oct  3 15:19:04 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/Makefile.am: closing #60708
+
+Tue Oct  2 15:52:05 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/libxml2.def.src include/libxml/parser.h parser.c:
+	  adding xmlSAXParseFileWithData following Marco Stipek suggestion
+
+Tue Oct  2 11:27:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: close bug #61550 when xml: wasn't considered a namespace
+
+Tue Oct  2 11:18:32 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/libxml2.def.src: Igor Zlatkovic patches
+	* DOCBparser.c HTMLparser.c parser.c: fixed typos
+
+Mon Oct  1 09:34:51 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: Justin Fletcher provided cleaup code in case
+	  HAVE_STAT is not defined
+	* include/win32config.h: Igor Zlatkovic suggested to have
+	  HAVE_STAT defined there
+
+Sat Sep 29 00:15:00 HKT 2001 William Brack <wbrack@mmm.com.hk>
+
+	* catalog.c - fixed typing error reported by M. Barros
+
+Sun Sep 23 21:02:39 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	* xmllint.c - fixing typo
+
+Sat Sep 22 10:00:00 HKT 2001 William Brack <wbrack@mmm.com.hk>
+
+	* HTMLparser.c: small enhancement to prevent loop on
+	  unrecognizable data
+
+Fri Sep 21 11:45:53 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parserInternals.c: applying patch from bug #60757 this
+	  should close it
+
+Thu Sep 20 15:54:29 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c xmlcatalog.c: removed a couple of warning
+	* xpath.c: try to solve the linking problem on platforms
+	  needing trio to compile
+
+Wed Sep 19 10:01:37 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am libxml.spec.in: backing up non-documented changes
+	  commited without review or aproval by Jens Finke <jens@gnome.org>
+	* HACKING: made 100% clear that no commit should be done directly
+
+Mon Sep 17 18:52:37 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: Joe Orton provided a patch fixing a problem
+	  when iconv is specified to be in a non-standard directory
+	  but wasn't exported in xml2-config --cflags
+
+Fri Sep 14 19:32:43 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: let's ship 2.4.5 before getting too much
+	  troubles with 2.4.4 errors.
+
+Fri Sep 14 12:26:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* encoding.c entities.c: do not output hexadecimal charrefs
+	  when serializing HTML since some version of Netscape can't
+	  grok it, generate decimal ones.
+	* result/HTML/doc3.htm: output changed due to previous test
+	* parserInternals.c: repair xmlKeepBlanksDefault() broken in 2.4.4
+
+Thu Sep 13 13:34:27 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* libxml-2.0.pc.in: dohh generated the wrong include path :-(
+	* doc/Makefile.am libxml.spec.in: re-dohh forgot the new manpage :-(
+
+Wed Sep 12 22:14:55 CEST 2001 Daniel Veillard <daniel@veillard.com>
+	Released 2.4.4
+
+	* config.h.in configure.in libxml.spec.in include/libxml/Makefile.am
+	  libxml-2.0.pc.in: moved includes to includedir/libxml2/libxml,
+	  updated the configuration scripts systems accordingly
+
+Wed Sep 12 20:49:32 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* configure.in: preparing for 2.4.4
+	* doc/xml.html doc/html/*: updated and rebuilt the docs
+
+Wed Sep 12 16:58:16 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/libxml2.def.src: tried to incorporate comments
+	  from bug #59220
+
+Tue Sep 11 11:25:36 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c result/noent/wml.xml: fixed bug #59981 related
+	  to handling of '&' in attributes when entities are substitued
+
+Mon Sep 10 22:14:42 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.h include/libxml/xmlversion.h.in
+	  include/libxml/xmlwin32version.h include/libxml/xmlwin32version.h.in:
+	  Tried to close bug #60131
+
+Mon Sep 10 20:46:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixed a bug in the HTML parser introduced Sep  9
+
+Mon Sep 10 20:13:09 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: fixing bug #59946 on xmlns=""
+
+Mon Sep 10 16:39:42 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/xmlerror.h SAX.c: fixing bug 59732, simple
+	  but allocates a new error code.
+
+Sun Sep  9 10:33:15 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: John Fleck fixed typos in the options output
+	* parser.c SAX.c: fix ignorable white space SAX selection
+
+Sat Sep  8 11:43:53 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* entities.c: Steve Underwood found the possibility of an
+	  ininite loop in case of error.
+
+Fri Sep  7 11:35:00 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am: Need $(ICONV_LIBS) in libxml2_la_LIBADD
+
+Wed Sep  5 17:47:43 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: warn if version is not 1.0 but it's not
+	  strictly speaking an error after analyzing the spec
+
+Mon Sep  3 10:07:03 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	*doc/catalog.html - add link to the html version of the
+	man page, other linguistic cleanups
+
+Mon Sep  3 09:10:08 MDT 2001 John Fleck <jfleck@inkstain.net>
+
+	* doc/xmlcatalog_man.xml, xmlcatalog_man.html, xmlcatalog.1
+	adding documentation for xmlcatalog. Note: xmlcatalog.1, the man
+	file, has not yet been included in the build.
+
+Sat Sep  1 18:17:47 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: removed a duplicate affectation Justin Fletcher
+
+Fri Aug 31 22:02:10 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: Armin Sander pointed a possible text coalescing 
+	  problem, completed his patch.
+
+Fri Aug 31 18:30:28 CEST 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* trionan.c: Fixed const and volatile re-definition problem
+
+Fri Aug 31 16:51:28 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.4 parser.c: doc updates from Heiko Rupp
+	* parserInternals.c: 2 sanity checks from Heiko Rupp
+
+Tue Aug 28 22:38:45 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* tree.c: applied patch from Armin Sander to make some pointers
+	  const in xmlCopyNode()
+	* include/libxml/tree.h: added fix to the header
+
+Mon Aug 27 16:24:47 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: hum, restrict the integer usage gcc bug workaround
+	  to only gcc compilers so that other architecture don't get
+	  penalized by this limitation.
+	* include/libxml/xpath.h: small typo fix from Heiko W. Rupp
+
+Sun Aug 26 20:45:04 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* valid.c: fixed a Windows compiler warning (Chris Poblete)
+	* xpath.c: fix for mod when dividend is 0 (Chris Poblete)
+
+Sat Aug 25 15:30:17 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h catalog.c xmlcatalog.c: added a 
+	  --convert option to xmlcatalog to convert SGML ones to
+	  the XML syntax.
+	* xmllint.c: small cleanup for $SGML_CATALOG_FILES support.
+
+	2.4.3 got released at that point
+Thu Aug 23 23:16:32 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c xmlIO.c: started some serious testing and fixed
+	  a few bug and optmization needs.
+
+Thu Aug 23 17:26:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am configure.in include/libxml/xmlwin32version.h:
+	  preparing for a 2.4.3 release even if it may not be ready yet
+	* catalog.c parser.c xmlIO.c include/libxml/catalog.h: redirected
+	  all file parsing lookup to go through the entity resolver, add
+	  to add an API to bypass it (needed to load catalogs themselves),
+	  some cleanup on the catalog code too.
+	* nanoftp.c: small cleanup
+	* doc/catalog.html: small update
+
+Thu Aug 23 12:22:26 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixed bugi #59406 in SGML catalog parsing reported by
+	  Jun Kuriyama
+
+Thu Aug 23 02:51:29 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* doc/catalog.html: finished the catalog documentation
+
+Thu Aug 23 01:38:42 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* doc/catalog.html doc/xml.html: added documentation about
+	  Catalog support, misses an API description 
+	* doc/html/*: reextracted the API pages
+
+Wed Aug 22 18:27:47 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h catalog.c xmlIO.c HTMLparser.c:
+	  Added the part about section 7.2 on URI resolution,
+	  fixed a side effect in the HTML parser, look complete
+	  and ready to rock except the URI/SystemID part!
+
+Wed Aug 22 16:27:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/catalog.h include/libxml/parser.h
+	  include/libxml/xmlerror.h catalog.c parser.c parserInternals.c
+	  xmlIO.c: added support and APIs needed for the catalog PI
+	* include/libxml/xmlIO.h: cleanup
+
+Wed Aug 22 02:03:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c parser.c xmlIO.c xmlcatalog.c xmllint.c 
+	  include/libxml/catalog.h: starts to look okay, really
+	  plugged the new framework, cleaned a lot of stuff,
+	  added some APIs, except the PI's support missing this
+	  should be mostly complete
+	* result/catalogs/* test/catalogs/*: added new test, enriched
+	  the existing one with URN ID tests
+
+Tue Aug 21 14:56:18 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* catalog.c: fixed nextCatalog
+	* result/catalogs/docbook test/catalogs/*: started adding
+	  a small regression test
+
+Tue Aug 21 12:52:38 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am catalog.c xmlcatalog.c include/libxml/catalog.h:
+	  more work on the XML catalog support.
+	* parser.c include/libxml/parser.h: small cleanup seems using
+	  list as a public parameter name can give portability troubles
+	* trionan.c trionan.h xpath.c include/libxml/trionan.h
+	  include/libxml/xpath.h include/libxml/Makefile.am: removed
+	  trionan from the libxml API, added xmlXPathIsInf and xmlXPathIsNaN
+	  wrappers
+
+Tue Aug 21 11:18:45 CEST 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* Makefile.am trio.c triodef.h trionan.c xpath.c
+	  include/libxml/Makefile.am include/libxml/trionan.h:
+	  Re-worked Not-A-Number and Infinity support.
+	* xmlcatalog.c: added readline include files
+
+Mon Aug 20 02:04:13 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* Makefile.am xmlcatalog.c libxml.spec.in: renaming 
+	  testCatalog as xmlcatalog, making it an installed app
+	  adding a shell, and preparing it to be a /etc/xml/catalog
+	  management tool, though not ready yet
+	* catalog.c include/libxml/catalog.h: adding support for
+	  XML Catalogs http://www.oasis-open.org/committees/entity/
+	  not finished, there is some interesting tradeoffs and a
+	  few open questions left.
+
+Sun Aug 19 14:59:56 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: fixed a line formatting problem
+
+Fri Aug 17 11:35:31 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: removed a couple of unused variable (Albert Chin)
+
+Fri Aug 17 01:25:21 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HTMLparser.c HTMLtree.c include/libxml/HTMLparser.h:
+	  trying to fix some troubles w.r.t. function returning
+	  const xxxPtr.
+
+Thu Aug 16 21:33:20 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/libxml2.def.src: another set of symbols conditionally
+	  defined
+
+Thu Aug 16 21:31:14 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpointer.c: removed unused var
+
+Thu Aug 16 18:26:40 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* testXPath.c: another small cleanup closing bug #59110
+
+Thu Aug 16 17:59:18 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* win32/dsp/libxml2.def.src: small cleanup closing bug
+	  #59108
+
+Wed Aug 15 22:46:01 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* example/gjobread.c: add xmlCleanupParser() before leaving
+
+Wed Aug 15 14:57:08 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* config.h.in configure.in include/libxml/xmlwin32version.h:
+	  released 2.4.2
+
+Wed Aug 15 13:56:22 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/valid.h debugXML.c valid.c: deprecate
+	  the non-boundchecking Sprintf functions, add Snprintf
+	  this should close bug #57984
+
+Wed Aug 15 10:46:07 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmlIO.c: xmlOutputBufferCreateFilename() didn't unescaped
+	  URIs before doing the lookups (pointed by Mark Vakoc)
+
+Tue Aug 14 18:37:23 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: serious changes on Result Value Trees and NodeSets
+	  w.r.t. deallocation and collect operations. Probably not
+	  100% clean (merge of allocated trees smells like a problem).
+	  Seems sufficient to close #58943
+
+Tue Aug 14 16:12:00 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xmllint.c: adding a --format option
+
+Tue Aug 14 14:16:24 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: count() was broken on Result Value Tree
+	* xmlIO.c: fixed file:/// accesses on _WIN32
+
+Mon Aug 13 13:22:53 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* libxml.m4: s/LIBXML_VERSION_NUMBER/LIBXML_VERSION/ seems the
+	  macro was renamed, this should close bug #58683
+
+Mon Aug 13 12:33:40 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: small fix fixing bug #58539 reported by coolo, in
+	  entity substitution mode text at the end of the entity might
+	  be added due to text coalescing.
+	* nanoftp.c parser.c: small cleanup
+
+Wed Aug  8 22:57:05 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* HACKING: added John Fleck right to commit in the doc subdir
+
+Tue Aug  7 03:05:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c testXPath.c valid.c xmllint.c include/libxml/valid.h:
+	  allow to inherit attributes from the DTD directly in the
+	  tree, this is needed for XPath and can be a useful feature.
+	  Inherited namespaces are always provided at the tree level now
+	* test/defattr* result/defattr* result/noent/defattr*: added a couple
+	  of tests for this feature (XSLT being the prime user).
+
+Fri Aug  3 14:02:20 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* DOCBparser.c Makefile.am nanohttp.c parser.c testHTML.c
+	  testSAX.c xmlIO.c xmllint.c include/win32config.h
+	  include/libxml/xmlversion.h.in include/libxml/xmlwin32version.h
+	  include/libxml/xmlwin32version.h.in win32/README.MSDev
+	  win32/dsp/*: applied Win32 Facelift No.2 patches from 
+	  Igor Zlatkovic for Windows/MSC
+
+Wed Aug  1 23:21:06 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* SAX.c: unparsedEntityDecl() the URI computation of the
+	  entity wasn't done breaking XSLT unparsed-entity-uri()
+
+Wed Aug  1 17:44:57 CEST 2001 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: fixed a bug when walking the descendants and
+	  the current node has no children
+	* debugXML.c: show up when a text node is supposed to not be escaped
+
+Wed Aug  1 01:33:35 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* xpath.c: fixed a bug in xmlXPathNodeTrailingSorted (for now it
+	  worked like the set:leading() function)
+	* include/libxml/xpathInternals.h: added xmlXPathNodeSetContains
+
+Tue Jul 31 18:24:34 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* nanohttp.c: protected an use of EAGAIN, Brian Stafford
+
+Tue Jul 31 17:48:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/xmlIO.h: apply change to close #58141 
+	* win32/libxml2/*: update of the MSC projects from Igor  Zlatkovic
+
+Tue Jul 31 17:09:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: when the internal subset uses a PE, then the
+	  included entity can use conditional sections.
+
+Mon Jul 30 12:58:39 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c include/libxml/xpath.h: fixed a serious memory problen
+	  when walking the namespace axis showing up in
+	  libxst/tests/general/bug-12
+	* xmlmemory.c: added the possibility to trace a given block
+	  defined by its address
+
+Sun Jul 29 07:18:53 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: don't override existing encoding specified before
+	  starting xmlParseDocument()
+
+Sat Jul 28 13:33:10 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/xmlwin32version.h: reinserted, needed for
+	  Windows users of CVS
+
+2001-07-27  Darin Adler  <darin@bentspoon.com>
+
+	* encoding.c: (xmlIconvWrapper): Add cast to fix warning.
+	* testCatalog.c: Add include of <libxml/parser.h>.
+
+2001-07-27  Darin Adler  <darin@bentspoon.com>
+
+	* include/libxml/.cvsignore:
+	* include/libxml/xmlwin32version.h:
+	Remove this file from CVS because it's generated.
+
+Fri Jul 27 10:03:56 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c include/libxml/parser.h: applied const patches from
+	  Tom Moog #58002
+
+Thu Jul 26 18:55:52 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* xpath.c include/libxml/xpath{,Internals}.h: added a function
+	  lookup framework
+
+Fri Jul 27 01:50:20 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed xmlCopyNode() for documents
+
+Thu Jul 26 12:40:35 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed bugs #58073 reported by Greg Shtilman
+
+Thu Jul 26 11:38:37 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixes bug #57652 reported by Morus Walter
+
+Thu Jul 26 10:24:34 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* nanohttp.c: John Kroll provided a small fix to xmlNanoHTTPSave
+
+Thu Jul 26 07:16:04 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c parserInternals.c: fixed the xmlLineNumbersDefault()
+	  errors, lesson don't add new functions at 1am before a release
+	* xpath.c: integrated fix from Bjorn to avoid divide by zero
+	  from XPath initialization when possible.
+
+Tue Jul 24 15:39:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* result/scripts/base*: removing history/readline changed
+	  this slightly
+	* include/libxml/parser.h SAX.c parser.c parserInternals.c
+	  xmllint.c: make element content line number generation
+	  optionnal to avoid breaking old apps added interface to switch
+
+Tue Jul 24 15:06:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: get rid of the readline and libhistory
+	  dependencies by default, release 2.4.1 with IA64 fix
+	* nanohttp.c tree.c xmlIO.c include/libxml/nanohttp.h
+	  include/libxml/tree.h include/libxml/xmlIO.h: incorporated
+	  John Kroll fixes to allow saving to HTTP via PUT (or
+	  POST of needed).
+	* doc/html/*.html: regenerated the docs
+
+Sun Jul 22 05:56:16 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* hash.c include/libxml/hash.h: added xmlHashScannerFull,
+	  xmlHashScanFull and xmlHashScannFull3 to get passed the
+	  three keys as arguments to the callback function
+
+Thu Jul 19 15:29:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in Makefile.am: removed libxml softlink for good
+	* include/libxml/*.h *.c doc/Makefile.am: cleanup to get
+	  100% coverage by gtk-doc
+
+Tue Jul 17 17:36:46 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlmemory.c include/libxml/xmlmemory.h: debugging on IA64,
+	  fixed serious troubles due to size_t vs. int mismatch
+
+Tue Jul 17 16:04:36 EDT 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c xmlIO.c: cleaned up some warning on the Alpha
+
+Mon Jul 16 06:32:44 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* include/libxml/xpath{,Internals}.h xpath.c: added a more
+	  convenient extension API for value and context managing
+	  Now handles external objects through xmlXPathPopExternal,
+	  xmlXPathWrapExternal and xmlXPathReturnExternal.
+	  Added functions for sets operations (intersection, etc.)
+
+Mon Jul 16 20:05:27 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/parserInternals.h include/libxml/HTMLparser.h
+	  xmlIO.c tree.c parserInternals.c entities.c encoding.c
+	  HTMLparser.c: cleanup of global variables, marking some
+	  const or private.
+
+Mon Jul 16 00:17:15 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+	* include/libxml/xpath.h: exported xmlXPath{NAN,PINF,NINF}
+	  fixed xmlXPathNodeSetItem when passing index=0
+
+Sun Jul 15 17:58:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/xmlwin32version.h.in: added xmlCheckVersion()
+
+Sat Jul 14 19:31:21 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmllint.c: fixed compilation under Cygwin #57503
+	* TODO: update
+
+2001-07-13  Peter Williams  <peterw@ximian.com>
+
+	* config.h.in: add #undef HAVE_DLFCN_H
+
+	* example/Makefile.am (INCLUDES): Compile fix when srcdir !=
+	builddir.
+
+Fri Jul 13 11:09:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* win32/libxml2/libxml2.def.src: added a couple of exported entries
+	  raised by #57348 and #57381
+
+Thu Jul 12 21:20:17 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c HTMLparser.c HTMLtree.c SAX.c debugXML.c parser.c
+	  tree.c xpointer.c: store the line numbder in element->content,
+	  may break some software, need a configuration mechanism
+
+2001-07-10  Darin Adler  <darin@bentspoon.com>
+
+	* .cvsignore:
+	* example/.cvsignore:
+	* include/.cvsignore:
+	* include/libxml/.cvsignore:
+	Various things that are generated and should be ignored.
+
+Tue Jul 10 17:47:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in include/libxml/xmlwin32version.h: release of 2.4.0
+	* doc/xml.html doc/html/*:  updated the docs
+
+Mon Jul  9 22:06:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: fixed "Internal: MIXED struct bad" when #CDATA elements
+	  validation occured on content with element child
+
+Mon Jul  9 17:59:08 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed XML Base computation which was broken
+	* debugXML.c: added a base function to the shell
+	* Makefile.am result/scripts/* test/scripts/*: added scripts
+	  based regression tests, and adding 2 XML Base tests
+
+Mon Jul  9 12:31:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: set properties doc and call xmlSetListDoc for properties
+	  content when grafting them in a different tree.
+	* aclocal.m4: remove from CVS
+
+Sun Jul  8 23:09:07 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* win32/libxml2/libxml2.def.src: added some missing entry point
+	  for XPath (Mark Vakoc)
+
+Sun Jul  8 20:34:35 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: fixed an old bug raised by Bernhard Zwisch, the I/O
+	  layer should URI-Unescape before trying to open resources.
+
+Sun Jul  8 16:26:00 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fix the name() bug for elements in the default 
+	  namespace reported by Charlie Bozeman
+
+Sun Jul  8 15:11:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c parser.c testXPath.c xpath.c: trying to fix #56948, this
+	  led to an XPath fix, improvements of SAX initialization, and
+	  an added option --nocdata to testXPath
+
+Sat Jul  7 21:09:55 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/libxml-doc.el: Felix Natter provided anew version working
+	  with XEmacs too
+
+Sat Jul  7 02:16:00 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/xpath.h: small cleanup
+	* doc/xml.html: update
+
+Fri Jul  6 01:40:23 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am configure.in include/libxml/xmlwin32version.h:
+	  released 2.3.14
+
+Fri Jul  6 00:47:41 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/html/*: rebuilt the docs for the release
+	* doc/xml.html: added 2.3.14 release.
+
+Thu Jul  5 22:01:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: a bug reported by Stephan Kulow empty nodesets
+	  were not equal to empty strings
+
+Thu Jul  5 00:52:25 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c: fixed a URI-Reference computation problem when validating
+	* xmlIO.c: small cleanup
+
+Thu Jul  5 00:04:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: improved the description of a couple of interfaces
+	  upon Larry Stamper suggestion
+
+Wed Jul  4 21:42:24 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c entities.c parser.c: changed completely the way entities
+	  are handled when running the parser in entity substitution mode.
+	  This fixes a bug reported by Stephan Kulow and nearly divides
+	  by 3 the amount of memory required by libxslt to load and process
+	  DocBook TDG.
+
+Wed Jul  4 18:02:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: fixing a too early root closing problem raised
+	  byt Prashanth Naidu
+
+Wed Jul  4 01:42:01 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed a missing copy in xmlXPathVariableLookupNS() 
+	  raised by Mark Vakoc.
+
+Tue Jul  3 18:35:48 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* example/Makefile.am: fixed the include path to add srcdir/include
+	* Makefile.am configure.in: fix from Albert Chin for iconv detection
+	  and some cleanup
+
+Tue Jul  3 10:12:03 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c include/libxml/xpath.h include/libxml/xpathInternals.h:
+	  lot of optimization work, results in significant improvements
+	  when handling really complex XPath queries. Add a small optimizer
+	  for unions, improve [n] and [last()], avoid some costly ops.
+
+Fri Jun 29 23:26:54 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/parser.h parser.c: xmlStrstr args are both const
+	* xpath.c: small cleanup
+	* xmlGetNsList: reformated, fixed problems if used on Entities
+
+Thu Jun 28 18:19:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: added 1.8.14 and 2.3.13 releases
+
+Thu Jun 28 18:16:28 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in include/libxml/xmlwin32version.h: released 2.3.13
+	* Makefile.am example/Makefile.am: workaround automake generating
+	  erroneous deps
+
+Thu Jun 28 15:08:22 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/win32config.h: bug #56801 Yon Derek provided a patch
+	  to the windows config file.
+
+Thu Jun 28 14:51:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpointer.c include/win32config.h win32/libxml2/libxml2.def.src
+	  libxml.h : Yon Derek provided a set of changes to compile from
+	  CVS on Windows/MSC
+
+Thu Jun 28 14:11:28 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed UTF8 BOM support in push mode
+	* test/utf8bom.xml result/utf8bom.xml result/noent/utf8bom.xml:
+	  added a specific testcase
+
+Wed Jun 27 18:33:13 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: added --push regression tests
+	* parserInternals.c: the XML parser segfaulted in --push mode
+
+Wed Jun 27 13:09:51 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: moved the symlinks detection within a CVS
+	  check, this is not portable and will be removed soon.
+	* xpath.c: small cleanup/speedup
+
+Tue Jun 26 18:05:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in doc/xml.html include/libxml/xmlwin32version.h:
+	  release of 2.3.12
+	* parser.c: make an error message if unknow entities in all cases
+
+Tue Jun 26 09:46:29 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* uri.c: fixed 2 uri normalization bugs on '//' reduction
+
+Mon Jun 25 18:06:23 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/libxml/Makefile.am: Laszlo Peter pointed out that
+	  includes were installed in the wrong dir
+
+Mon Jun 25 17:07:37 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/html.xml: warn against sending code to exhibit bugs.
+
+Sun Jun 24 23:31:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: patch to xmlXPathFormatNumber for the optimizer on
+	  Tru64 from Thomas Leitner
+
+Sun Jun 24 14:05:54 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* AUTHORS: added William and Bjorn
+	* include/libxml/*.h *.c README doc/*.html etc.: changed old email to
+	  daniel@veillard.com hopefully I won't have to do this again
+	* doc/Makefile.am doc/html/*.html: cleanup makefile, checked that
+	  docs can be rebuilt cleanly now
+	* include/libxml/xml*version.h*: removed include/libxml/xmlversion.h
+	  from CVs it's generated, added include/libxml/xmlwin32version.h
+	  also generated but which should change far less frequently.
+	* catalog.c nanoftp.c: made sure to include libxml.h not
+	  libxml/xmlversion.h directly
+	* include/libxml/*.h: include xmlwin32version.h instead of xmlversion.h
+	  when compiling on WIN32 and MSC
+
+Sat Jun 23 23:54:12 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/Makefile.am include/libxml/Makefile.am configure.in:
+	  fixed make distcheck and rebuilding the rpms
+
+Sat Jun 23 20:50:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: should finish the migration of exported includes
+	  into a real include/libxml in CVS, at least for CVS users.
+	* removed the exported headers, added in include/libxml (as well
+	  as xmlversion.h.in).
+
+Sat Jun 23 20:37:19 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: fixed the way to detect symlink
+
+Sat Jun 23 20:30:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: updated, include/libxml is now a real CVS dir
+
+Sat Jun 23 19:36:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/libxml-doc.el: a new version of libxml-doc.el. This new
+	  version works with both libxml1 and libxml2 (it autodetects
+	  the prefix of the html-files) from Felix Natter.
+	* doc/xml.html: updated doc accordingly
+
+Sat Jun 23 18:30:28 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed the bug generating a template loop in libxslt
+	  when using docbook-xsl-1.4, * should filter out document nodes
+	* HACKING: added William
+	* TODO: updated
+
+Fri Jun 22 18:02:37 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/FAQ.html: added a warning about gcc-3.0
+	* doc/xml.html: added reference to gdome2 and removed a confusing
+	  sentence
+
+Fri Jun 22 17:02:16 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlversion.h: okay this is a generated file, but Windows
+	  users need it and they can't generate it, and I want CVS
+	  Windows users ...
+	* win32/libxml2/libxml2_so.dsp: Windows project file for 
+	  the shared lib version of libxml2
+	* win32/libxml2/libxml2.def.src: bug #56527 set of exported
+	  resources needed for libxslt/xsltproc by Yon Derek
+
+Fri Jun 22 16:39:36 CEST 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* trio.c: MSVC fix (provided by Igor Zlatkovic)
+
+Fri Jun 22 12:42:16 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/win32config.h: another small fix for ATTRIBUTE_UNUSED
+
+Fri Jun 22 12:42:16 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* include/win32config.h: Yon Derek provided a first fix
+	  to be able to compile libxslt/xsltproc on Windows
+
+Fri Jun 22 00:04:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: attempt to work around what seemed a gcc optimizer
+	  bug when handling floats on i386 http://veillard.com/gcc.bug
+	* tree.c entities.c encoding.c: doing some cleanups while
+	  chasing it
+
+Thu Jun 21 13:13:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: cleanup when --without-debug is specified
+	* xinclude.c xpath.c xpathInternals.h xpointer.c: cleanup
+	  w.r.t. --without-debug and other include points
+	* catalog.h testCatalog.c: a bit of cleanup and prepare for XML
+	  Catalogs
+	* configure.in entities.h tree.h HTMLparser.c: removed
+	  --without-corba, made the _private field mandatory
+
+Wed Jun 20 19:37:25 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c parserInternals.c encoding.c: Since Notepad on Win2k
+	  outputs a BOM in UTF8, an errata has been issued to avoid the
+	  problem, that was the most reasonable solution... Add support
+	  for a leading UTF8 BOM in entities.
+
+Wed Jun 20 15:38:59 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: fixed a bug found when post validating an entity ref
+	* xmllint.c: added --loaddtd and sligly changed --postvalid to
+	  activate it too
+
+Tue Jun 19 20:03:40 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c xinclude.c xpointer.c: bug #56402 exposed a number of
+	  weakness in the node copy the XPointer and the XInclude
+	  implementations. Serious cleanup.
+
+Tue Jun 19 14:50:18 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: Kjartan Maraas provided a small patch to
+	  add xml2-config.in to EXTRA_DIST
+
+Tue Jun 19 13:04:10 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c tree.c parserInternals.c parser.c: Stephan Kulow
+	  provided another failing case found in KDE, the way the
+	  ctxt->vctxt.nodeTab was allocated and freed changed over
+	  time but it wasn't completely cleaned up. This should fix it.
+
+Sun Jun 17 19:56:33 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: Stephan Kulow also raised the fact that line number
+	  could get miscounted making debug harder, fixed the problem
+	  in xmlParseCharData()
+
+Sun Jun 17 19:17:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: Stephan Kulow pointed out a problem when validating
+	  and using an empty entity, forgot a 'break' in a case.
+
+Sun Jun 17 16:47:40 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed xmlHasNsProp() accordingly to bug #55683
+	* doc/xml.html: updated with 2.3.11
+
+Sun Jun 17 12:24:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* TODO: updated adding cleanup of generated doc
+	* configure.in: prepared to release 2.3.11
+	* xmllint.c: added --version for bug reporting
+	* doc/html/*.html: rebuilt the doc
+
+Sat Jun 16 23:23:33 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: first part of the work on selecting namespace to
+	  fix bug #56115 
+
+Sat Jun 16 00:20:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am example/Makefile.am: Laszlo PETER provided a fix
+	  when using -liconv
+	* TODO: updated
+
+Fri Jun 15 07:08:57 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.[ch]: more work on the HTML serialization routnes,
+	  cleanup, encoding support.
+
+Thu Jun 14 10:31:17 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: Thomas Broyer suggested a better patch for the / arg
+
+Thu Jun 14 01:01:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: bug detected by Ankh when / is used as a function arg
+
+Wed Jun 13 23:08:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.[ch] HTMLtree.c: stored the inline/block property
+	  of element and use it to avoid outputting formatting spaces at
+	  the wrong place. Implemented the format parameter for HTML save.
+	* result/HTML/doc2.htm result/HTML/doc3.htm result/HTML/fp40.htm
+	  result/HTML/script.html result/HTML/test2.html result/HTML/test3.html
+	  result/HTML/wired.html: of course this impact the result of a
+	  number of HTML tests
+
+Thu Jun 14 09:49:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.[ch]: started augmenting the HTML save API with
+	  encoding and formatting parameters
+
+Wed Jun 13 09:44:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.h: cleanup and started evaluating the work needed on
+	  revamping the HTML output code
+
+Mon Jun 11 19:29:40 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c: handling of PIs and <?sgml-declaration in entities.
+
+Tue Jun 12 08:46:28 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: fixed bug #56049, forgot one check in the
+	  validation routine
+
+Tue Jun 12 08:09:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch]: grrr ... namespace is a C++ reserved keyword
+
+Tue Jun 12 06:29:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* libxml.h: fixed an error in last commit
+	* doc/FAQ.html: added an entry for compilation from CVS
+
+Mon Jun 11 10:07:29 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlversion.h.in libxml.h: Cygwin patches
+	* tree.c: xmlFreeNodeList patch similar to xmlFreeNode one
+	* tree.h: cleanup
+
+Sat Jun  9 19:16:00 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: patched xmlFreeNode() to avoid freeing() a static
+	  memory block in a strange case where libxml is linked twice
+	  in the binary.
+
+Sat Jun  9 18:39:03 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: (a? , b? , c? , ... , z?) was storing/restauring
+	  state far too often, simple fix used to avoid it.
+
+Sat Jun  9 16:10:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xinclude.c: Raphael Hertzog had a trouble with DTD nodes
+	  being processed, applied his patch
+	* tree.c: fixed a bug raised in xmlStaticCopyNodeList()
+
+Sat Jun  9 15:50:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* nanoftp.c nanohttp.c uri.c include/win32config.h: Igor  Zlatkovic
+	  provided fixes to compile on MSCC again
+	* win32/libxml2/libxml2.def.src win32/libxml2/libxml2*.dsp: he
+	  also provided an update for the project files.
+
+Thu Jun  7 21:52:10 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: applied Steve Tinney patch to xmlNewNsProp to fix
+	  bug #55810
+
+Thu Jun  7 21:29:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed xmlGetNsProp() to close bug #55683
+	  Note this requires libxslt to use it's own function instead.
+
+Thu Jun  7 18:06:34 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: when in a pre element no formatting space should
+	  be added.
+	* test/HTML/pre.html result/HTML/pre.html*: added a regression test
+
+Thu Jun  7 17:29:38 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: added tests for signal() and signal.h
+
+Fri Jun  8 10:17:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: robert pointed out xmlXPathNINF was not initialized
+
+Fri Jun  8 10:01:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/libxml-doc.el: Felix Natter provided a new version for
+	  libxml2
+
+Fri Jun  8 07:20:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: when in a pre element no formatting space should
+	  be added.
+
+Wed Jun  6 18:07:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: add -mieee to CFLAGS when compiling on Linux/alpha
+
+Thu Jun  7 06:44:01 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c: implemented the <?sgml-declaration encoding="xxx"?>
+	  hack
+	* tree.[ch]: added xmlHasNsProp as suggested in bug report #55653 
+	* uri.c: fixed a warning
+
+Tue Jun  5 22:54:21 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: trying to close bug #55772 escaping in script
+	  elements
+	* doc/xml.html: suggest to send mail to the list
+
+Tue Jun  5 19:11:02 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* error.c: attempt to fix the xmlGetVarStr breakage once and for
+	  good. Use a macro and based on the solution provided in 
+	  vsnprintf manual page from GNU.
+
+Tue Jun  5 14:46:10 CEST 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* error.c: Workaround for non-preserving variadic list.
+	* trio.c trio.h triop.h strio.c strio.h: Upgraded to trio baseline 1.4
+
+Sat Jun  2 06:12:33 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: added 2.3.10 release
+
+Fri Jun  1 11:27:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: releasing 2.3.10
+
+Thu May 31 20:42:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: Gary Pennington spotted a few troubles with file:///
+
+Thu May 31 20:18:59 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* encoding.c: Robert Collins provided a patch to add the
+	  "US-ASCII" encoding alias
+
+Wed May 30 21:12:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c encoding.[ch]: William M. Brack provided a set of UTF8
+	  string oriented functions and started cleaning the related areas
+	  in xpath.c which needed fixing in this respect
+
+Wed May 30 20:30:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: applied patch from Jaroslaw Kolakowski to close bug
+	  #55380
+	* tree.c: patch to xmlNodeGetContent() to get CDATA section content
+
+Mon May 28 12:56:29 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* TODO: updated
+	* nanohttp.[ch] : started adding APIs to get the redirected URL
+	  when this occurs (needed for further base computation
+	* tree.h: cleanup
+	* encoding.c: cleanup
+	* SAX.c: minor change around ctxt->loadsubset
+
+Fri May 25 09:36:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am include/Makefile.am: small change to have
+	  include/libxml rebuilt if working from CVS.
+	* uri.c: applied another patch from Carl Douglas for URI escaping,
+	  this should close bug #51876
+
+Wed May 23 15:40:27 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xinclude.c: fixed XInclude recursive behaviour bug #54678
+	* result/XInclude/recursive.xml test/XInclude/docs/recursive.xml
+	  test/XInclude/ents/inc.txt test/XInclude/ents/sub-inc.ent:
+	  added specific regression test
+	* parser.h: preparing for the XSLT mode where DTD inherited
+	  attributes are added to the tree.
+
+Wed May 23 13:59:19 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xinclude.[ch]: Updated the namespace for the Last Call version
+	* result/XInclude/include test/XInclude/include: updated the
+	  testsuite accordingly
+
+Wed May 23 12:27:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* uri.[ch]: applied a patch from Carl Douglas for URI escaping,
+	  related to bug #51876
+
+Tue May 22 18:46:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed a gross mistake in base computation, xml:base is
+	  not completely correct yet (need cascade).
+	* xpath.[ch]: added the few things needed to find a function name
+	  and URI from the XPath context when it is called.
+
+Tue May 22 17:00:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* catalog.[ch]: fixes and add xmlLoadCatalogs()
+	* DOCBparser.c: small cleanup
+	* xmllint.c: added a --catalogs option to load catalogs from
+	  $SGML_CATALOG_FILES
+	* tree.c: cleanup
+	* configure.in: iconv library fixup, ICONV_LIBS 
+
+Mon May 21 16:05:22 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* catalog.c: handling of CATALOG entries. detection of recursion,
+	  and a few bugfixes
+	* xpath.c: fixing bug #54951 QNAME with no prefix should not match
+	  against the default namespace
+
+Mon May 21 10:14:07 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: Joe Orton reported a bug found with IRIx compiler.
+
+Sun May 20 15:15:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed propagation context info when parsing an
+	  external entity.
+	* doc/html/*.html: regenerated a couple of docs
+
+Sat May 19 17:11:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: update with 2.3.9 informations
+
+Sat May 19 16:50:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.h debugXML.h parserInternals.h tree.h valid.c
+	  xmlversion.h.in xpathInternals.h xpath.h: some cleanup for gtk-doc
+	* doc/html/* : rebuilt the docs
+	* valid.c: small patch which may improve some case when
+	  validating.
+
+Sat May 19 15:20:03 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: Closed bug #54891
+	* result/HTML/cf_128.html* test/HTML/cf_128.html: added the test
+	  to the suite
+
+Thu May 17 14:15:07 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* encoding.h hash.c nanoftp.h parser.h tree.h uri.h xlink.h xpointer.c:
+	  applied a documentation patch from LotR and filled in a few missing
+	  descriptions
+
+Wed May 16 23:02:41 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c tree.c parser.c: speed optimizations at the parser level
+	  document tree freeing and xpath evaluation
+
+Wed May 16 12:55:48 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c parser.h parserInternals.h: fixed a couple of
+	  interfaces for handling memory buffer input to const char *
+	  upon suggestion of JamesH.
+
+Tue May 15 17:22:27 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: LoTR sent a patch fixing the previous commit 
+
+Tue May 15 14:40:04 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: trying to deal again with the stoopid -R linking
+	  flag of Solaris
+
+Tue May 15 12:49:50 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.h: two nodeset access macros from Thomas Broyer
+
+Tue May 15 11:42:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c xpath.h xpathInternals.h: apply an XPath API cleanup
+	  patch from Thomas Broyer
+
+Tue May 15 10:52:19 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c test/VCM/v2[34].xml: Fixed bug #54631 added specific test
+	  case
+	* INSTALL: was empty added stuff from the FAQ
+
+Fri May 11 19:37:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch]: fixing bug #54446, by cleaning some bugs in the
+	  attributes handling and #54433 by adding xmlUnsetProp()
+	  and xmlUnsetNsProp()
+
+Fri May 11 16:07:13 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: Patch from Jonas Borgström
+	(htmlGetEndPriority): New function, returns 
+	the priority of a certain element.
+	(htmlAutoCloseOnClose): Only close inline elements if they 
+	all have lower or equal priority.
+	* result/HTML: this of course changed a number of tests results.
+
+Thu May 10 17:30:22 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c catalog.c: plugged in the default catalog resolution
+	* doc/gnome-xml.sgml: linked in the Docbook parser and catalog
+	  documentations
+	* doc/html/libxml-*.html: rebuild added the missing ones to CVS
+
+Thu May 10 16:14:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am xmlversion.h.in configure.in include/Makefile.am:
+	  integrating catalogs
+	* catalog.[ch] testCatalog.c: adding a small catalo API
+	  (only SGML catalog support).
+	* parser.c: restaured xmlKeepBlanksDefault(0) API
+
+Wed May  9 12:50:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: zb@bisp.com reported an error in xmlNodeGetLang()
+
+Tue May  8 12:31:40 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: added xmlParseExternalEntityPrivate() to allow
+	  propagation of ctxt->_private when parsing external entities
+
+Tue May  8 10:26:22 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: fixed the bug reported by Bjorn in htmlNodeDump
+
+Tue May  8 09:30:12 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: fixed a small portability problem with AM_CONDITIONAL
+
+Mon May  7 22:44:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: warn when indeterminist content model is detected
+	* result/VC/ElementValid8: this adds a message
+	* Makefile.am: add --novalid for VCM tests
+	* parserInternals.c: added a call to Init memory 
+
+Fri May  4 19:51:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: fixed htmlNewDoc SYSTEM and PUBLIC ID inversion
+	  when both parameters are NULL.
+
+Fri May  4 17:19:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: applied small patch from Gary Pennington, reindented
+	  some part of the code.
+
+Thu May  3 13:10:43 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in doc/xml.html doc/html/*: preparing for 2.3.8
+	  release, updated and regenerated the docs
+
+Thu May  3 12:47:46 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c result/XPath/expr/floats : clarified and cleanup
+	  printing of abnormal floats in tests.
+
+Thu May  3 10:25:19 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: trying to fix the problem reported by Jonas Borgström
+	* results/HTML/ : a few changes in the output of the HTML tests as
+	  a result.
+	* configure.in: tying to fix -liconv where needed
+
+Wed May  2 19:10:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: fixed a stupid error
+
+Wed May  2 18:39:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in Makefile.am: make the inclusion of the trio
+	  modules in the library conditional
+
+Wed May  2 14:39:57 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c: patche from  László Kovács, fixed entities refs
+	  in attributes handling
+
+Wed May  2 12:56:04 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: Bjorn Reese provided a fix for a problem on buffer
+	 flushing
+
+Mon Apr 30 22:29:34 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fix of an XSLT namespace bug reported on the list
+	  general/bug-8-
+
+Mon Apr 30 19:42:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* strio.h trio.c: Dan McNichol suggested a couple of small
+	  fixes for AIX 4.3.3 using Visual Age 5.0.2 compiler
+
+Mon Apr 30 13:44:48 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c parser.c encoding.c: spent a bit more time looking
+	  at the parsing speed and DOM handling. Added a few more
+	  speedups.
+
+Sun Apr 29 21:53:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: small but effective parsing speed improvement
+
+Sun Apr 29 19:02:13 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: default on the DocBook parser inclusion (for Gnome)
+	* DOCBparser.h: fixed a header reference
+
+Sat Apr 28 19:00:39 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in xpath.c: applied Bjorn patches for FPE on the
+	  alpha
+
+Sat Apr 28 18:54:28 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch] xmlIO.h: applied patch from Joe McAlerney to add
+	  xmlSaveFormatFileTo()
+
+Sat Apr 28 16:33:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: simple and efficient optimization, XPath functions
+	  aways bind to the same code, cache this
+	* TODO: updated (by saying some is obsolete)
+
+Sat Apr 28 14:23:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: more cleanup work on XPath name parsing routines
+
+Fri Apr 27 19:06:13 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parserInternals.c xpath.[ch]: some UTF8 cleanup on
+	  xmlXPathParseName
+	* xpath.c: Igor Zlatkovic suggested a change for NAN and MSC
+	* debugXML.c: avoid compilation problems if compiling without
+	  HTML support, Igor Zlatkovic
+	* win32/libxml2/libxml2.def.src: being able to compile without
+	  XPath on Windows
+
+Thu Apr 26 22:53:03 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* libxml.m4: yet another patch from Toshio Kuratomi
+
+Thu Apr 26 21:27:43 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* libxml.m4 libxml2-spec.in: new patches from Toshio Kuratomi
+
+Thu Apr 26 20:53:48 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch]: added xmlSaveFormatFile interface for saving
+	  and indenting a file.
+
+Thu Apr 26 16:35:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed bug #53689 related to processing-instruction()
+
+Thu Apr 26 12:57:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c: patche from  László Kovács
+
+Thu Apr 26 11:31:54 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: applied fixes from Christian Glahn bug report #53391
+
+Thu Apr 26 11:14:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* error.c: Jean François Lecomte provided a complete description
+	  and a fix to bug #53537
+
+Thu Apr 26 09:42:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* libxml.m4: added AM_PATH_XML2 provided by Toshio Kuratomi
+
+Wed Apr 25 21:05:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c SAX.c: a bit more work on entities processing.
+	  Still Need to cleanup XML output and references in attributes
+
+Wed Apr 25 17:52:27 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c include/Makefile.am: two patches from László Kovács
+
+Wed Apr 25 14:56:26 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: trying to fix #53574, not completely complete,
+	  I would like xmllint --copy --debug test/ent1 and
+	  xmllint --debug test/ent1 to show the same result.
+	* xpath.c: fix a bug when trying to sort namespace nodes
+
+Wed Apr 25 12:28:57 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: real fix for  #53402
+
+Tue Apr 24 17:36:35 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c HTMLtree.h : closing #53402 i.e. output of
+	  PIs when using xsl:output
+	* valid.c: closing #53537 some case generate segfaults if there
+	  is validity errors
+
+Tue Apr 24 15:19:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c testDocbook.c DOCBparser.c: more work on the support
+	  of external parsed entities, added --noent to testDocbook
+	* valid.c: Garry Pennington found an uninitialized variable
+	  access in xmlValidateElementContent()
+
+Tue Apr 24 14:41:25 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c : HTML parsing still sucks ... trying to deal
+	  with madness
+	* result/HTML/ : this modified the result of the regression tests
+	  a lot.
+
+Tue Apr 24 14:10:38 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* entities.c: xmlEncodeEntitiesReentrant fixed a few accesses
+	  to doc where it wasn't checked against NULL reported by
+	  Jens Laas
+
+Tue Apr 24 13:21:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: Jonas Borgström patch, the <td>, and <th> elements
+	  now means the end of any open <span>,<font>,<a>,<b>,<i>,<u>.
+
+Mon Apr 23 15:40:04 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* DOCBparser.c DOCBparser.h testDocbook.c configure.in Makefile.am
+	  xmlversion.h.in: started (re)integrating the DocBook SGML parser.
+	* SAX.[ch]: cleanup and updates for DocBook
+	* debugXML.c parser.h tree.[ch] valid.c xpath.c: small macro or
+	  ex SGML identifier changes
+	* valid.c: removed a static unused function.
+
+Mon Apr 23 11:05:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLtree.c: applied change for Paul Sponagl on script saving
+	* Makefile.am: the warning about entity title.xml are normal.
+
+Sun Apr 22 22:09:35 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: release of 2.3.7
+	* Makefile.am: fixing make distcheck
+
+Sun Apr 22 21:29:52 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/html/* doc/xml.html: updated and regenerated the docs
+
+Sun Apr 22 21:11:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed the XPointer problem introduced in 2.3.6
+
+Sun Apr 22 14:11:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed #53388 with the provided patch
+
+Sun Apr 22 12:34:41 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: Bjorn detected an invalid memory access. Fixed
+	  vstateVPush()
+
+Sun Apr 22 10:49:23 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed xmlXPathCompile to detected unproperly ended expr
+
+Sat Apr 21 18:27:51 CEST 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* libxml.h: new header used only for the compilation of libxml
+	* HTMLparser.c HTMLtree.c SAX.c debugXML.c encoding.c entities.c
+	  error.c hash.c list.c nanoftp.c nanohttp.c parser.c
+	  parserInternals.c testHTML.c testSAX.c testURI.c testXPath.c
+	  tree.c uri.c valid.c xinclude.c xlink.c xmlIO.c xmllint.c
+	  xmlmemory.c xpath.c xpointer.c: libxml.h integration
+	* trio.[ch] triop.h strio.[ch]: upgraded to the latest trio
+	  baseline (version 1.2 plus a single patch).
+	* xpath.c result/XPath/expr/floats test/XPath/expr/floats: parses
+	  scientific notation for numbers. Tests added.
+	* xpath.c: formatting of numbers changed to use sprintf
+	  (contribution from William Brack)
+
+Sat Apr 21 16:12:59 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: cleanup, more useful debugging
+	* parserInternals.c: cleanup vctxt.nodeTab (de)allocation
+	* xmlIO.c: entity loading is printed as an error when validating
+
+Sat Apr 21 12:25:49 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: fixed to validate within entities
+	* test/VCM/v22.xml: added a specific testcase
+
+Fri Apr 20 17:45:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: forgot an epsilon transition in for ()+
+	* test/VCM/v21.xml : added a specific test case
+
+Fri Apr 20 15:46:04 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: removed a state explosion exhibited by RSS
+	* test/valid/rss.xml result/valid/rss.xml*: added the testcase
+	  from bug #51872
+
+Fri Apr 20 14:52:44 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.[ch] tree.h: worked *hard* to get non-determinist content
+	  validation without using an ugly NFA -> DFA algo in the source.
+	  Made a specific algorithm easier to maintain, using a single
+	  stack and without recursion.
+	* Makefile.am test/VCM/*.xml: added more tests to "make Validtests"
+	* hash.c: made the growing routine static
+	* tree.h parser.c: added the parent information to an
+	  xmlElementContent node.
+
+Wed Apr 18 23:33:11 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c parser.c xpath.c: generating IDs when not validating
+	  from an external parsed entity was poisoning the ID has table
+	  with removed values. This was killing XSLT on the KDE help
+	  browser.
+
+Wed Apr 18 17:09:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* entities.h: andrew@ugh.net.au detected a double declaration
+
+Wed Apr 18 15:06:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* debugXML.c hash.c tree.h valid.c : some changes related to
+	  the validation suport to improve speed with DocBook
+	* result/VC/OneID2 result/VC/OneID3 : this slightly changes
+	  the way validation errors get reported
+
+Wed Apr 18 11:42:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c HTMLtree.c: applied part of the patches provided
+	  by P C Chow and William M. Brack for XSLT HTML output
+
+Mon Apr 16 19:44:36 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlversion.h.in win32config.h win32/libxml2/*: applied 
+	  Igor Zlatkovic patches for MSC compilation and added his
+	  updates
+
+Tue Apr 17 10:08:19 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed xmlXPathNodeCollectAndTest() to do proper
+	  prefix lookup.
+	* parserInternals.c: fixed the bug reported by Morus Walter
+	  due to an off by one typo in xmlStringCurrentChar()
+
+Thu Apr 12 17:41:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c result/HTML/*: revamped the way the HTML
+	  parser handles end of tags or end of input
+
+Thu Apr 12 10:50:34 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch] : added xmlDocCopyNode for gdome2 support
+
+Wed Apr 11 16:37:50 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.h: include xmlmemory.h this seems to havoid a nasty glibc
+	  bug where the linktime verions of free() won't work ...
+
+Wed Apr 11 14:21:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* config.h.in configure.in xmlversion.h.in: added ansidecl.h test
+
+Wed Apr 11 13:50:42 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: added 2.3.6 release
+
+Wed Apr 11 13:26:34 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed xmlStringGetNodeList() to handle charrefs
+	* result/wml.xml: resulted in a small output change
+
+Wed Apr 11 09:47:55 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: xmlNewDoc was missing the charset initialization
+	* xmllint.c: added --auto to autogenerate a doc, allow to
+	  reproduce the problem fixed on xmlNewDoc
+
+Tue Apr 10 18:13:10 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: trying to get 52979 solved
+	* tree.c result/ result/noent/: trying to get 52712 solved, this
+	  also made me clean up the fact that XML output in general should
+	  not add formating blanks by default, this changed the output of
+	  a few tests
+
+Tue Apr 10 16:30:20 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: Bill Brack pointer an error in detecting a null nodeset
+
+Sun Apr  8 15:07:16 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: finally released 2.3.6
+
+Sun Apr  8 11:39:21 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: checking for null pointer generated by new code
+
+Fri Apr  6 12:53:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed a [] evaluation problem reported
+	* test/XPath/tests/simpleaddr: extended test
+	* result/XPath/simpleaddr: updated result
+
+Wed Apr  4 02:07:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmllint.c: Dan Timis reported a portability problem
+	  on Macs without mmap, fixed it.
+
+Tue Apr  3 20:20:51 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* testXPath.c : added a --tree option allowing to display the
+	  tree dump of the XPath expression
+
+Mon Apr  2 17:13:51 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed a memleak when comparing nodesets
+	* HTMLtree.c: don't invent the HTML doctype if not available (XSLT)
+	* tree.c: added a TODO
+
+Tue Mar 27 14:32:06 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in Makefile.am config.h.in xmlversion.h.in: detect if
+	  we need string functions
+	* trio.[ch] strio.[ch]: embedded the Trio-0.23 string functions
+	  to be able to use them where needed. Applied some changes
+	  to reduce name linking pollution and compile in only what's
+	  needed.
+	* HTMLtree.c debugXML.c entities.c error.c nanoftp.c valid.c
+	  xlink.c xmlversion.h.in xpath.c: got rid of the #ifdef 
+	  for the string manipulation functions
+	* xmlmemory.[ch]: removed DEBUG_MEMORY_FREED and added it automatically
+	  to the free() function of xmlmemory.c
+	* entities.c HTMLtree.c parserInternals.c tree.c uri.c valid.c
+	  xinclude.c xmlIO.c xpath.c xpointer.c: removed the MEM_CLEANUP
+	  usage.
+
+Tue Mar 27 02:30:23 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* error.c: applied the context output patch of the error
+	  handling submitted by Chuck Griffith
+	* error/VC/*: this slightly change some error logs
+
+Tue Mar 27 00:51:27 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed line number reporting on error
+
+Mon Mar 26 23:21:41 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: Sullivan and Darin found a parser bug,
+	  applied the patch.
+
+Mon Mar 26 18:24:52 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c HTMLtree.c SAX.c debugXML.c error.c parserInternals.c
+	  testHTML.c testSAX.c tree.c valid.c xmlIO.c xmlmemory.c
+	  xmlversion.h.in xpointer.c: of course the way I defined
+	  UNUSED breaks on old gcc version. Try to be smart and
+	  also define it directly in xmlversion.h
+	* configure.in: removed -ansi flag from the pedantic set
+
+Sat Mar 24 17:45:36 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+	Huge cleanup, I switched to compile with
+	-Wall -g -O -ansi -pedantic -W -Wunused -Wimplicit
+	-Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat
+	-Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow
+	-Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return
+	-Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline
+	* HTMLparser.[ch] HTMLtree.c SAX.c debugXML.c encoding.[ch]
+	  encoding.h entities.c error.c list.[ch] nanoftp.c
+	  nanohttp.c parser.[ch] parserInternals.[ch] testHTML.c
+	  testSAX.c testURI.c testXPath.c tree.[ch] uri.c
+	  valid.[ch] xinclude.c xmlIO.[ch] xmllint.c xmlmemory.c
+	  xpath.c xpathInternals.h xpointer.[ch] example/gjobread.c:
+	  Cleanup, staticfied a number of non-exported functions,
+	  detected and cleaned up a dozen of problem found this way,
+	  avoided a lot of public function name/typedef/system names clashes
+	* doc/xml.html: updated
+	* configure.in: switched private flags to the really pedantic ones.
+
+Thu Mar 22 22:44:15 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: 2.3.5
+	* doc/html/*: rebuilt the docs
+
+Thu Mar 22 15:36:45 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed a reported bug in NOTATION parsing
+	* uri.c: accepted but not fixed bug 51876, added TODO 
+	* Makefile.am: fixed bug 51876
+
+Thu Mar 22 13:41:22 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* config.h.in configure.in error.c: fix a compilation problem
+	  on platforms without vsnprintf (xml@thewrittenword.com)
+
+Wed Mar 21 19:04:34 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed a function name header typo
+	* SAX.c: notations can also occur in external subset.
+
+Tue Mar 20 14:21:28 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* error.c: removed a C++ like comment
+
+Tue Mar 20 12:22:36 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixing bug 52299 strange condition leading
+	  to a parser crash due to a buffer overflow
+	* result/noent/attrib.xml result/attrib.xml test/attrib.xml:
+	  added the specific test case
+
+Mon Mar 19 16:50:52 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.[ch]: still a lot of cleanup based on XSLT, added
+	  xmlXPathConvert{String,Number,Boolean} to be able to make
+	  type casts without a context stack, fixed some implementation
+	  problems related to the absence of context at parse-time,
+	  added xmlXPathEvalPredicate() and xmlXPathFreeCompExpr()
+	  in the public API too
+	* xpointer.c xpathInternals.h: we need to know at parse time
+	  whether we are compiling an XPointer
+
+Mon Mar 19 11:54:31 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.[ch] xpointer.c: restaured the Binary and API compatibility
+	  cleaned up the parser internals, refactored XPath code, added
+	  new compilation based APIs and cleanly separated public and
+	  private APIs.
+
+Mon Mar 19 00:59:25 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.h: the comp field must be added at the end to avoid
+	  killing binary compat.
+
+Mon Mar 19 00:11:18 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: detect XPath memleaks in regreson tests
+	* error.c: fixed and error w.r.t. error reporting still using
+	  stderr
+	* hash.c: added new line at end of file
+	* tree.h: minor cleanup
+	* xpath.[ch] xpointer.[ch]: Major changes ! Separated XPath
+	  expression parsing from evaluation, resulted in a number of
+	  changes internally, and in XPointer. Likely to break stuff
+	  using xpathInternals.h but should remain binary compatible,
+	  new interfaces will be added.
+
+Wed Mar 14 20:34:02 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: fixed a couple of problems reported by 
+	  okiddle@yahoo.co.uk and allanc@chickenandporn.com when compiling
+	  without gcc on non linux platforms.
+
+Wed Mar 14 20:13:54 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/Makefile.am configure.in: yearke@eng.buffalo.edu suggested
+	  a fix for --with-html-dir= configure support. I hope it won't
+	  break rpm generation
+
+Wed Mar 14 17:28:49 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: one function comment cleanup.
+
+Wed Mar 14 14:55:46 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* SAX.c: external subset notations were improperly registered
+	  in the internal subset.
+
+Tue Mar 13 10:28:49 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* README.cvs-commits: added, pointing to HACKING
+	* HACKING: updated
+
+Mon Mar 12 22:09:40 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: and Matt Sergeant found one in the XML push
+	  parser (erroneous check I forgot to remove when I fixed the
+	  main parser).
+
+Mon Mar 12 19:19:04 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: ptittom found a small bug in UnaryExpr
+
+Sat Mar 10 13:09:53 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: bumped to 2.3.4
+	* error.c: fixed bug #51860
+	* tree.c: fixed bug #51861
+	* valid.c: cleanup, more debug, failed to fix one bug crap ...
+	* tree.[ch] : added xmlDefaultBufferSize
+	* nanoftp.c: typo in function name header block
+	* doc/xml.html : updated, added link to XML::LibXSLT
+	* doc/html/* : rebuilt the docs
+
+Wed Mar  7 20:43:47 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c SAX.c: the new content parsing code raised an
+	  ugly bug in the characters() SAX callback. Found it
+	  just because of strangeness in XSLT XML Rec ouptut :-(
+
+Wed Mar  7 16:50:22 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: Martin Baulig suggested to add -lm
+	* tree.c: found another bug in xmlNodeGetContent()
+
+Tue Mar  6 09:21:30 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: Bjorn found the error related to strictness of comparison.
+
+Mon Mar  5 21:47:31 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: trying to fix the Dtd parsing problem reported
+	  by Gary, side effect of last week speed optimizations.
+
+Sat Mar  3 19:45:59 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xml2Conf.sh.in: fixes pointed out by Fredrik Hallenberg
+	* parserInternals.c: removed unneeded test raised by Stric
+
+Sat Mar  3 13:04:37 CET 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* xpath.c: Fixed xmlXPathNodeCollectAndTest (problem reported
+	  and fixed by William Brack). Added xmlXPathFormatNumber.
+	  Changed the sorting slightly.
+	* configure.in Makefile.am example/Makefile.am: Added -lm.
+	  Please note that applications linking with libxml2, must
+	  also like with the math library from now on.
+
+Sat Mar  3 07:38:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: fixed loop reported by Marc Sanfacon
+
+Sat Mar  3 02:10:24 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: one must report spaces even if the Dtd element
+	  content proves that this is not part of the element content.
+	* result/valid/*.xml: this changed the ouptu slightly
+
+Thu Mar  1 17:53:39 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: bumped to 2.3.3
+	* doc/xml.html: updated
+
+Wed Feb 28 00:43:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: minor doc fix
+	* xpath.c: deallocation issues when a result tree has been
+	  converted to a node-set
+
+Mon Feb 26 22:09:45 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: oops corrected dates s/2000/2001
+
+Mon Feb 26 12:48:35 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: new patch from Gary Pennington
+
+Mon Feb 26 09:30:23 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: applied patch from Ankh
+
+Mon Feb 26 03:34:43 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xinclude.c: fixed a problem building on Mac
+
+Sun Feb 25 21:52:30 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: more work on increasing parsing ferformances
+
+Sun Feb 25 18:03:42 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlmemory.h HTMLparser.c HTMLtree.c entities.c parser.c
+	  xpath.c xpointer.c tree.c uri.c valid.c xinclude.c xmlIO.c:
+	  avoiding memcpy in production builds MEM_CLEANUP macro use
+	* parser.[ch] parserInternals.c: optimizations of the tightest
+	  internal loops inside the parser. Better checking of I/O
+	  flushing/loading conditions
+	* xmllint.c : added --timing
+
+Sun Feb 25 05:48:51 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: bumped to 2.3.2
+	* doc/xml.html: updated for release
+
+Sat Feb 24 14:07:52 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: found a memleak and fixed a nasty bug
+
+Sat Feb 24 03:35:48 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmllint.[c1] : added return code errors for xmllint
+	* xpath.c: specific debug dump function for result value trees
+
+Thu Feb 22 07:52:27 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: finally implemented xmlXPathCompareNodeSets
+	* test/XPath/expr/floats results/XPath/expr/floats: added 
+	  a test for float expressions
+
+Tue Feb 20 18:57:54 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed xmlNodeGetContent, it was not recursing on child
+	* parserInternals.[ch]: trying to speed up parsing
+	* xpath.c : speeded up node set equality op
+
+Mon Feb 19 19:01:57 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am valid.c list.[ch]: Gary Pennington provided a
+	  better handling of ID/IDREF and the list modules associated
+	* configure.in: small CFLAGS cleanup
+
+Mon Feb 19 16:13:22 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: fixed iconv detection on AIX (stric)
+
+Mon Feb 19 10:59:41 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed "*" (unbelievable !) and a couple of warnings
+
+Sun Feb 18 17:52:37 MET 2001 Bjorn Reese <breese@users.sourceforge.net>
+
+	* xpath.c: fixed whitespace handling in xmlXPathStringEvalNumber,
+	  and optimized xmlXPathNodeSetSort
+
+Sat Feb 17 14:18:42 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: bug fix when context size is 0
+	* parser.c: I like Norm's Dtd because they still manage to break
+	  the parser occasionally
+
+Fri Feb 16 14:20:35 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: xmlXPathEqualNodeSetFloat the arg is really a double now
+
+Fri Feb 16 01:10:06 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.[ch] parser.c xpath.c: fixed the problem of addressing
+	  attributes within the XML-1.0 namespace
+
+Thu Feb 15 16:53:20 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpathInternals.h: exported a few axis functions
+	* doc/xml.html: updated the doc
+
+Thu Feb 15 15:57:14 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: applied patch from Daniel van Balen for OpenBSD
+	  and bumped version to 2.3.1
+	* HTMLtree.c result/HTML/doc3.htm result/HTML/wired.html: the
+	  attempt to find autoclosing was simply broken, removed it,
+	  updated the examples, this is better
+
+Wed Feb 14 11:35:39 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* hash.[ch]: added Paolo Casarini patch to provide Delete from
+	  hash functionnalities.
+	* doc/html/* : rebuild the doc
+
+Tue Feb 13 18:01:48 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c result/XPath/tests/chaptersprefol: bugfixes on order and
+	  on predicate
+	* HTMLparser.[ch] HTMLtree.c result/HTML/doc3.htm.err
+	  result/HTML/doc3.htm.sax result/HTML/wired.html: sometimes one
+	  really want to have tags closed on output even if we accept
+	  unclosed ones on input
+
+Mon Feb 12 18:33:20 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: ouch don't free NULL, rare case fixed
+	* tree.c: don't coalesce text nodes if they don't have the
+	  same behaviour wrt escaping on output
+
+Sun Feb 11 21:15:41 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: small fixup
+	* SAX.c: don't warn on empty namespaces.
+
+Thu Feb  8 11:28:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* README: a bit of cleanup
+	* configure.in: preparing for 2.3.0 release
+
+Thu Feb  8 10:37:00 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* hash.[ch]: added a first version of xmlHashSize()
+	* valid.c: another bug fix from Gary Pennington
+
+Wed Feb  7 19:22:37 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* valid.c: couple of bug fixes pointed by Gary Pennington
+	* HTMLtree.c: #if 0 cleanup
+
+Tue Feb  6 14:02:56 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: started profiling XSLT, added xmlXPathNodeSetAddUnique()
+	  which removes a time consuming check of xmlXPathNodeSetAdd()
+	  and use it in places where we are sure to not break unicity
+
+Mon Feb  5 18:51:36 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: bug fixes found from XSLT
+	* tree.c: preserve node->name special values when copying nodes.
+	* parserInternals.[ch] parser.[ch] SAX.c : added a mode where
+	  external subset are fetched when available but without full
+	  validation. Added xmlLoadExtDtdDefaultValue, need a function.
+	* HTMLtree.c: add support for xmlStringTextNoenc for XSLt HTML
+	  output with encoding disabled.
+
+Sat Feb  3 09:50:29 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmliO.c: Harry Blundell pointed out that xmlCheckFilename
+	  xmlCheckFilename should not be called from xmlFileOpenW
+	  and xmlGzfileOpenW
+
+Fri Feb  2 18:04:35 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* uri.c: rewrite of xmlNormalizeURIPath from Paul D. Smith
+	* test/URI/smith.uri result/URI/smith.uri Makefile.am:
+	  added the new tests for URI normalization
+	* testURI.c: fixed stoopid bugs
+	* result/VC/OneID3 result/VC/UniqueElementTypeDeclaration:
+	  the URI in the error messages are now properly normalized
+
+Fri Feb  2 09:18:53 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* uri.c: applied Marc Sanfacon's patch for xmlNormalizeURIPath
+
+Thu Feb  1 05:28:55 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed a number of problems in XPATH_XSLT_TREE processing
+
+Wed Jan 31 21:45:37 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed mod operator
+
+Wed Jan 31 16:50:42 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c: fixed xmlStrcat doc
+	* tree.c: 2 fixes form Anders Carlson for copying nodes and
+	  trees.
+
+Wed Jan 31 14:19:16 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c result/XPath/tests/chaptersbase
+	  result/XPath/tests/simplebase: fixed XPath node() 
+	* tree.c: small fix in xmlNewNs()
+	* Makefile.am: removed extraneous xml2Conf.sh rule
+
+Sun Jan 28 08:37:03 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am configure.in libxml.spec.in example/Makefile.am:
+	  Changed the library name, in order to get libxml-devel and
+	  libxml2-devel to coexist on a single system
+	* xml-config.1 xml-config.in xmlConf.sh.in: renamed
+	* xml2-config.1 xml2-config.in xml2Conf.sh.in: new files
+
+Sat Jan 27 19:58:22 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am configure.in libxml-2.0.pc.in: started working on getting
+	  libxml2-devel installable in // as libxml-devel.
+
+Sat Jan 27 18:49:02 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/Makefile.am: fixed make rebuild in doc
+	* doc/html/*.html: rebuilt the docs
+
+Fri Jan 26 10:30:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: patch from Bjorn Reese on xmlBufferCCat
+
+Thu Jan 25 19:22:25 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am doc/Makefile.am libxml.spec.in: painful work to get
+	  the HTML doc to go into the -devel RPM ...
+	* aclocal.m4 config.h.in: some updates due to auto* magic
+
+Thu Jan 25 19:11:49 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.h: added a hook in the context structure allowing to
+	  link to extra support, needed for XSLT
+
+Thu Jan 25 13:34:11 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.[ch] xpointer.c: added xmlXPathCmpNodes, changed
+	  xmlXPtrCmpPoints to use it.
+	* propagated the following patch from Alejandro Forero
+	* include/win32config.h xmlIO.c: applied further suggestions
+	  from Igor Zlatkovic <igorz@dialup.nacamar.de> and cleanup
+	* example/gjobread.c: fixed warnings, now that it builds
+
+Wed Jan 24 20:27:28 COT 2001 Alejandro Forero <bachue@bachue.com>
+
+	* xmlIO.c (xmlFileOpen, xmlFileOpenW): Removed unnecesary checks.
+
+	* xmlIO.c (xmlCheckFilename): Function added to know whether a given
+	  filename points to a valid file (not a directory).
+	* xmlIO.c (xmlFileOpen, xmlFileOpenW, xmlGzfileOpen, xmlGzfileOpenW):
+	  Added calls to xmlCheckFilenameDir.
+
+	* xmlIO.c (xmlGzfileOpen, xmlGzfileOpenW, xmlFdOpen, xmlFdOpenW): Pass
+	  `path' (rather than `filename') as the parameter to gzopen and open.
+
+Tue Jan 23 16:26:30 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: fixed a problem with EXTRA_DIST
+
+Mon Jan 22 23:42:17 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am example/Makefile.am: finally found the trick
+	  to build the example, i.e. add "." in SUBDIRS before example
+	  in the list <grin/>
+
+Mon Jan 22 16:30:37 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* doc/xml.html: updated with an XSLT section, removed pointer to
+	  W3C CVS base.
+
+Mon Jan 22 11:43:21 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: when copying a XSLT tree object teh tree need to be copied
+	  too, and deallocation need to occur the same way.
+
+Mon Jan 22 10:35:40 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpathInternals.h xpath.[ch] debugXML.c: added the XPATH_XSLT_TREE
+	  type correponding to an XSLT result tree fragment. Share most
+	  of the data format with node set, as well as operators.
+	* HTMLtree.c: added a newline at the end of the doctype output
+	  whe this one is not present initially.
+	* tree.c: make sure taht the parent and doc pointers are properly
+	  set when copying attributes (lists).
+
+Sun Jan 21 10:47:38 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* htmlTree.[ch] xmlIO.h: exported htmlDocContentDumpOutput
+
+Fri Jan 19 18:15:50 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: seems I finally killed that ugly path evaluation
+	  context bug (tagged 9999 in case is is wrong)
+
+Fri Jan 19 06:30:38 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.[ch] xpathInternals.h: added xmlXPathRegisterVariableLookup()
+	  for XSLT
+
+Thu Jan 18 16:19:47 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: Gary Pennington <Gary.Pennington@uk.sun.com> fix
+	  for xmlGzfileOpen() bug
+
+Thu Jan 18 13:11:50 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: removed an error found by XSLT usage
+	* tree.c parserInternals.h: use a predefined static string
+	  for text and comment nodes, avoid freeing them in xmlFreeNode,
+	  exported the string name in parserInternals.h and added
+	  another value to disable encoding at output (for XSLT),
+	  gain memory, time.
+
+Wed Jan 17 09:15:16 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* win32/README.MSDev win32/libxml2/libxml2_a.dsp
+	  win32/libxml2/libxml2_so.dsp: new makefiles and update
+	  provided by Igor Zlatkovic <igor@stud.fh-frankfurt.de>
+
+Tue Jan 16 18:24:46 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c : xmlSaveFile, xmlSaveFileEnc, applied patch from 
+	  Gary Pennington
+
+Mon Jan 15 20:24:18 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xpath.c: fixed the comaprision of values and nodelists,
+	  need to compare nodelist still ...
+	* debugXML.c: avoided a possible core dump
+	* HTMLparser.c: cleanup
+	* nanohttp.c: contributed fix.
+	* tree.c: fixes in properties handling added xmlSetNsProp
+	  needed by libxslt
+	* xpathInternals.h: exported xmlXPathBooleanFunction, added a 
+	  comment
+	* TODO: updated
+
+Sat Jan  6 22:05:09 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* parser.c parserInternals.c: applied Bjorn Reese optimization
+	  patch
+
+Sat Jan  6 19:13:27 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* Makefile.am: applied patch fro make check from Martin Vidner
+
+Thu Jan  4 19:07:49 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* configure.in: preparing 2.2.11
+	* doc/html/*: rebuild the HTML files
+	* doc/xml.html : updated
+
+Thu Jan  4 14:09:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c: fixed a stupid bug
+	* valid.c: applied "Paul D. Smith" <pausmith@nortelnetworks.com>
+	  patches related to validation of an XInclude processing result
+	* TODO: updated
+
+Thu Jan  4 11:46:40 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* encoding.c xmlIO.c: Fixing the problem reported by Marc Sanfacon
+	  on large files
+
+Wed Jan  3 21:51:13 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlIO.c: fixed xmlParserInputBufferCreateMem doc
+
+Wed Jan  3 18:56:00 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* HTMLparser.c: htmlCheckParagraph to check htmlOmittedDefaultValue,
+	  reported by Jonas Borgström
+	* nanohttp.c: Applied Bjorn Reese' IPV6 first patch
+
+Wed Jan  3 16:19:39 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* testXPath.c xpath.c: fixing the XPath union expressions problem
+	  reported by  Martin Vidner <martin@artax.karlin.mff.cuni.cz>
+
+Wed Jan  3 14:22:33 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmllint.c: Made is so if the file name is "-" is will read form
+	  standard input. Sven Heinicke  <sven@zen.org>
+	* tree.c: fixed a problem when growing buffer
+	* tree.h: fixed the comment of the node types following andersca
+	  comment
+	* TODO: updated
+
+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
+	  on a non-updated tree :-(, made a 2.2.10 release to correct the
+	  situation
+
+Sat Nov 25 10:41:37 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.c parser.[ch] tree.[ch] xmlIO.[ch] xmllint.c xpath.c
+	  parserInternals.h vms/build_libxml.com vms/config.vms Makefile.am:
+	  integrated a set of OpenVMS changes from Howard Taylor
+	  <Howard.Taylor@pacoast.com>
+
+Sat Nov 25 01:21:01 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] xmlIO.c: added xmlDocDumpMemoryEnc() from John Kroll
+	* error.c: applied fix suggested by "Leo Davidson" <leo@ox.compsoc.net>
+
+Sat Nov 25 00:24:49 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: some fixes on auto-open of html/head/body
+	* encoding.c: fixed a compilation error on some gcc env
+	* xpath.c xpointer.[ch] xpathInternals.h: improved the
+	  XPointer implementation
+	* test/XPath/xptr/strpoint test/XPath/xptr/strrange3: added
+	  related XPointer tests and associated results
+
+Fri Nov 24 14:01:44 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xmldtd.html doc/xml.html: following a short step by step
+	  guidance on IRC to help maciej with DTDs I started a small
+	  page on the subject.
+
+Fri Nov 17 17:28:06 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: fixed handling of broken charrefs
+	* xmlmemory.h libxml2.dsp include/win32config.h: reporting Windows
+	  patches
+
+Mon Nov 13 19:17:20 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html doc/html/* : rebuilt the docs after adding
+	  xinclude and updated page for 2.2.7 and 2.2.8
+	* configure.in: releasing 2.2.8
+
+Mon Nov 13 12:39:38 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch] parserInternals.c: applied the conditional
+	  section processing fix from Jonathan P Springer
+	  <jonathan.springer2@gte.net>
+	* xmlversion.h.in win32/libxml2/libxml2.dsp : Updated MS
+	  project file, fixed iconv default non support
+	* xpath.c: fixed the problem of evaluating relative expressions
+	  when a node context is provided.
+
+Sun Nov 12 16:31:19 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c: fixed gcc 2.95 new warnings
+	* SAX.c: fixed a stupid bug
+	* tree.c: fixed a formatting problem when round-tripping
+	  from/to memory
+	* xinclude.c: chased memleak, fixed a base problem
+	* xpointer.c: added xmlXPtrBuildRangeNodeList(), finished ? 
+	  xmlXPtrBuildNodeList()
+	* TODO: updated
+	* Makefile.am test/XInclude/docs test/XInclude/ents result/XInclude:
+	  adding a first small set of regression tests for XInclude
+
+Tue Nov  7 15:11:34 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.[ch]: applied Wayne Davison patches to access
+	  the WWW-Authorization header.
+	* parser.c: Closed Bug#30847: Problems when switching encoding
+	  in short files by applying Simon Berg's patch.
+	* valid.c: fixed a validation problem
+	* hash.c parser.h parserInternals.h testHTML.c testSAX.c tree.h
+	  xmlerror.h xmlmemory.h xmlversion.h.in: applied a DLL patch from
+	  Wayne Davison
+	* xpointer.[ch]: added first version of xmlXPtrBuildNodeList()
+	  need to be extended to non full nodes selections.
+	* xinclude.c: starts to work decently
+
+Mon Nov  6 17:22:46 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] xinclude.[ch] xmllint.c configure.in valid.c
+	  debugXML.c xmlversion.h.in: Started adding XInclude support,
+	  this is a new xmllint option
+	* tree.c xpath.c: applied TOM patches for XPath
+	* xpointer.c: fixed a couple of errors.
+	* uri.c: added an escaping function needed for xinclude
+	* testXPath.c hash.c HTMLtree.c: minor cleanups raised by
+	  new warning from RH70 gcc's version
+
+Tue Oct 31 14:14:13 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: fixed loop on invalid char in scripts
+	* parser.c: update to description of xmlIOParseDTD()
+	* libxml.m4 xmlversion.h.in: changes contributed by
+	  Michael Schmeing <m.schmeing@internet-factory.de>
+	* configure.in: preparing for 2.2.7
+	* Makefile.am: trying to avoid  config.h and acconfig.h
+	  being included in the distrib
+	* configure.in: released 2.2.7
+
+Mon Oct 30 17:08:10 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] debugXML.c parserInternals.c xpath.c: Deprecated Pi's
+	  like namespaces for good. Unified xmlNs and xmlNode somewhat.
+
+Mon Oct 30 16:26:49 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch]: added xmlIOParseDTD()
+	* xpointer.c: added support for the 2 extra parameters of
+	  string-range, fixed a stoopid error when '0' was present
+	  in XPointer expressions
+	* test/XPath/xptr/strrange2 result/XPath/xptr/strrange2: added
+	  testsuite for the above
+
+Mon Oct 30 10:26:43 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* libxml.spec.in: improved package descriptions
+
+Sun Oct 29 19:03:11 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c xpathInternals.h: applied a large cleaning patch
+	  from TOM <ptittom@free.fr>, it also add namespace support
+	  for function and variables registration.
+
+Sun Oct 29 18:51:46 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c: Wayne Davison's patch fixing xmlBuildURI()
+	* Makefile.mingw: Wayne Davison's update adding hash.c
+
+Sun Oct 29 18:38:12 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c: fixed the root evaluation problems
+	* HTMLparser.c result/HTML/doc3.htm: fixed the problem of non
+	  ignorable spaces with <b> <bold> <em>
+	* tree.c: fixed a loop in xmlSearchNsByHref()
+
+Fri Oct 27 18:57:32 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c: applied another XPath patch from TOM 
+	* xpath.c include/makefile.am: applied another patch from 
+	  china@thewrittenword.com (cleanup on IRIX).
+
+Fri Oct 27 13:45:28 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xml-config.1: received a fixed version from Fredrik Hallenberg
+	  <hallon@lysator.liu.se>
+
+Thu Oct 26 16:05:25 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c textXPath.c xpathInternals.h: applied TOM <ptittom@free.fr>
+	  cleanup patch for XPath
+
+Wed Oct 25 21:31:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* patched to redirrect all "out of context" error messages to
+	  a reconfigurable routine. The changes are:
+	* xmlerror.h : added the export of an error context type (void *)
+	  an error handler type xmlGenericErrorFunc there is an interface
+	  xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler);
+	  to reset the error handling routine and its argument
+	  (by default it's equivalent to respectively fprintf and stderr.
+	* all the c files: all wild accesses to stderr or stdout within
+	  the library have been replaced to calls to the handler.
+
+Wed Oct 25 15:27:19 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: release 2.2.6
+	* xpath.[ch] xpointer.c xpathInternals.h: added xpathInternals.h
+	  exporting the inner functions of xpath for extension modules
+	* doc/*: updated and rebuilt the doc
+
+Wed Oct 25 12:48:55 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.c : applied Wayne HTTP cleanup patch
+	* tree.[ch]: applied TOM <ptittom@free.fr> for xmlNodeSetBase()
+	  and xmlNodeSetSpacePreserve()
+
+Wed Oct 25 12:11:03 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c: closing bug #29260
+
+Tue Oct 24 18:49:34 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* hash.[ch] debugXML.c: expanded/enhanced the API, added
+	  multikey tuples, made hash structure opaque
+	* valid.[ch]: moved elements, attributes, notations decalarations
+	  as well as ID and refs to hash tables.
+	* entities.c: hash cleanup
+	* xmlmemory.c: fixed a dump problem in debug mode
+	* include/Makefile.am: problem passing in DESTDIR= values patch
+	  from Marc Christensen <marc@calderasystems.com>
+	* nanohttp.c: removed debugging remains
+	* HTMLparser.c: the bogus tag should be ignored (Wayne)
+	* HTMLparser.c parser.c: fixing a number of problems with the
+	  macros in the *parser.c files (Wayne).
+	* HTMLparser.c: close the previous option when opening a new one
+	  (Marc Sanfacon).
+	* result/HTML/*: updated the HTML results accordingly
+
+Sun Oct 22 18:39:19 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* entities.[ch] xpath.[ch] hash.[ch] debugXML.c tree.h: added/hacked
+	  hash tables from Bjorn Reese <breese@mail1.stofanet.dk>. Switched
+	  XPath functions and XML entities table to them. More to come...
+	* xmlIO.c: fixed libxml closing FILEs it didn't open.
+
+Sun Oct 22 13:59:50 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: coalesce adjacent text nodes
+	* valid.c: handling of blank nodes in DTd validation (raised
+	  by problems with a posteriori validation).
+	* nanohttp.c: changing behaviour on HTTP write stuff.
+	* HTMLtree.c: forced body and html to be explicitely closed.
+	* xpath.h: exported more XPath functions.
+
+Sun Oct 15 22:28:32 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Release of 2.2.5
+	* xpointer.c: range() range-inside and other helper functions
+	* parserInternals.c: fixed perf problem raised by rolf@pointsman.de
+
+Sun Oct 15 16:21:27 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.c: HTML attributes need normalization too (Bjorn Reese)
+	* HTMLparser.[ch]: addded htmlIsScriptAttribute()
+
+Sun Oct 15 13:18:36 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/*: rebuilt docs preparing for 2.2.5 release, added URI
+	  and XPointer modules
+
+Sun Oct 15 12:13:30 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.h: closed #25107
+
+Sun Oct 15 12:06:16 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* testSAX.c: fixed problem with cdata reporting
+	* SAXresult/* : updated
+
+Sun Oct 15 12:00:24 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c test/wap.xml result/noent/wap.xml result/wap.xml:
+	  Closed bug #27499, added to regression tests
+	* TODO: updated
+
+Sun Oct 15 01:34:37 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c HTMLtree.[ch] SAX.c testHTML.c tree.c: fixed HTML
+	  support for SCRIPT and STYLE with help from Bjorn Reese
+	* test/HTML/* result/HTML/*: added simple testcase and updated
+	  the existing ones.
+
+Fri Oct 13 18:24:31 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c xpointer.c: XPointer reorder of ranges start/end and
+	  string-range for empty strings
+	* test/XPath/docs/str test/XPath/xptr/chaptersrange
+	  test/XPath/xptr/strrange: augmented the XPointer testsuite
+
+Fri Oct 13 12:21:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html doc/xmlmem.html: added a module describing memory
+	  interfaces and use, updated the main page.
+
+Fri Oct 13 01:23:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c nanohttp.c xmlIO.c: Wayne Davison Win32 patch
+	  nanoftp code work on Windows too now
+
+Fri Oct 13 00:54:37 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* testXPath.c xpath.[ch]: moved some debug functions to xpath core
+	* xpointer.c: implemented string-range() at least a good first version
+	* test/XPath/docs/str test/XPath/xptr/strrange
+	  result/XPath/xptr/strrange: the string-range() tests
+
+Thu Oct 12 10:02:59 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am include/Makefile.am include/win32config.h
+	  win32/Makefile.mingw: fixed problems reported by Wayne Davison
+	  and make distcheck
+
+Thu Oct 12 01:44:08 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.c: added xmlNanoHTTPTimeout(int delay), removed a bug
+	  xmlNanoHTTPMethod on input MimeType Tony Lam <Tony.Lam@eng.sun.com>
+	* xpointer.c: slight extension of xmlXPtrLocationSetMerge
+
+Thu Oct 12 01:37:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* config.h.in configure.in nanoftp.c nanohttp.c xmlversion.h.in :
+	  patch for socklen_t detection by
+	  Albert Chin-A-Young <china@thewrittenword.com>
+
+Wed Oct 11 17:53:57 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c valid.c xmllint.c: Fixed a few postvalidation bugs
+	  and added a --dtdvalid option to xmllint used to test it
+
+Wed Oct 11 15:01:29 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xml-config.1 Makefile.am libxml.spec.in: adding a man page for
+	  xml-config by Fredrik Hallenberg <hallon@lysator.liu.se>
+
+Wed Oct 11 12:41:30 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.[ch] xpointer.[ch]: worked on XPath functions and variable
+	  handlings (registration, lookup, cleanup)
+
+Wed Oct 11 01:46:44 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in Makefile.am include/makefile.am: adding XPointer
+	  and XPtrtests target
+	* xpointer.[ch] : new files for XPointer support
+	* test/XPath/xptr result/XPath/xptr: added XPointer testsuite and
+	  more XPath tests
+
+Wed Oct 11 01:23:25 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: fixed, very broken, make distcheck works again
+
+Wed Oct 11 02:53:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* More work toward 2.2.5, integrated a number of patches
+	* configure.in Makefile.am win32config.h.in: trying to cleanup
+	  make distcheck .... huh ...
+	* include/Makefile.am include/win32config.h: new directory
+	  for includes
+	* win32/Makefile.mingw win32/README.MSDev win32/libxml2/libxml2.dsp
+	  updated teh makefiles and instructions for WIN32
+	* xpath.c: small fixes
+	* test/XPath/ results/XPath: updated the testcases and results
+	* HTMLparser.c nanohttp.c testXPath.c: incorporated provided or
+	  suggested patches
+	* valid.c: fixed an ID bug
+
+Mon Oct  9 14:28:56 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* moved xml-error.h to xmlerror.h: seems this allowed to bypass
+	  the automake bug where wrong dependencies were generated.
+	* xpath.[ch]: worked on XPointer
+
+Fri Oct  6 12:58:04 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in Makefile.am: 2.2.5, ship the include in an
+	  include/libxml subdirectory, use symlinks when using CVS
+	* testSAX.c: fixed small bug
+	* testXPath.c: changed the way testfiles are parsed
+	* debugXML.c: same kind of cleanup when parsing an argument expression
+	  XPath/XPointers can have blanks embedded
+	* xpath.[ch]: more cleanup, reorgs for XPointer work
+	* parserInternals.c parser.c HTMLparser.c: fixed wrong include
+	* win32/README.MSDev win32/libxml2/libxml2.dsp: Windows stuff
+
+Thu Oct  5 18:13:15 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* debugXML.c testXPath.c xpath.[ch]: got pissed by some nastyness
+	  in the XPath engine, rewrote large parts of it, now it's far
+	  cleaner and in sync with the REC not an old WD. Fixed a parsing
+	  problem in the interactive XML shell found when testing XPath.
+
+Wed Oct  4 15:25:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer,
+	  incorporated "(TOM)" <ptittom@free.fr> patches rebuilt the XPath
+	  examples with the extra test
+
+Wed Oct  4 14:39:01 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c xmlIO.c xmlIO.h: fixed bug 26650, and improved
+	  the global init function.
+
+Tue Oct  3 11:28:52 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: Doohhh, attribute name parsing was still case
+	  sensitive ! Fixed this ...
+	* result/HTML/* : updated the tests results accordingly
+
+Mon Oct  2 23:47:32 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.[ch] debugXML.c testXPath.c: fixed the XPath evaluation
+	  engine, should be far more stable, incorporated a new version of
+	  preceding/following axis, need testing
+	* uri.c: fixed file:///c:/a/b/c problem
+	* test/XPath/tests/idsimple: augmented the XPath tests
+
+Sun Oct  1 22:33:00 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/* rebuilding docs for 2.2.4 release
+
+Sun Oct  1 22:16:33 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: releasing 2.2.4
+	* parser.[ch]: added xmlStrEqual()
+	* HTMLparser.c HTMLtree.c SAX.c debugXML.c entities.c parser.c
+	  tree.c valid.c xlink.c xpath.c: converted all !xmlStrcmp to
+	  use xmlStrEqual instead
+	* TODO: updated
+	* added an XPath test
+
+Sun Oct  1 20:19:39 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: fixed htmlStartCloseIndexinitialized init
+	* entities.h: exported xmlInitializePredefinedEntities
+	* parser.[ch] : added xmlInitParser()
+	* parserInternals.h : had to export htmlInitAutoClose()
+
+Sun Oct  1 16:28:22 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.[ch] : fixed some serious XPath Predicate evaluation
+	  problems
+	* Makefile.am : added XPath regression tests to normal tests
+	* uri.c: fixed a problem with local paths, cleanup
+	* parser.c: fixed a problem with large CData sections
+
+Sat Sep 30 16:35:54 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in xml-config.in: patch from "Ben Taylor"
+	  <sol7x86@hotmail.com> for solaris shared libs lookup
+
+2000-09-30  Martin Baulig  <baulig@suse.de>
+
+	* libxml-2.0.pc.in: Provide pkg-config script.
+
+	* configure.in: Create the libxml-2.0.pc script from the
+	libxml-2.0.pc.in templates.
+	* Makefile.am (pkgconfig_DATA): Install the libxml-2.0.pc
+	script in `$(libdir)/pkgconfig'.
+
+Mon Sep 25 16:23:41 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c parser.c tree.c tree.h: Avoiding a few warning
+	  when compiling with MSC
+
+Sun Sep 24 20:32:52 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c: patch for normalize-string() substring-before(),
+	  substring-after() and translate() functions from Bjorn Reese
+	  <breese@mail1.stofanet.dk>
+	* libxml.m4 Makefile.am: added libxml.m4 from Debian ?
+	  Fredrik Hallenberg <hallon@lysator.liu.se>
+	* TODO: updated
+
+Sun Sep 24 10:00:49 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlversion.h.in nanoftp.c nanohttp.c: traying to work out the
+	  problem of socklen_t being undefined on a number of platforms
+	* debugXML.c: fixed a compilation problem when without snprintf
+
+Sat Sep 23 12:19:45 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c uri.c: Another patch from Wayne Davison, correcting
+	  an URI bug and a fix for the control-character-induced infinite loop
+	* nanohttp.c: preventive fix for compiling on WIN32
+
+Fri Sep 22 18:06:08 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlint.c: closing bug #25000
+
+Fri Sep 22 14:17:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlIO.h tree.h: made xmlNodeDump() and xmlNodeDumpOutput() public
+	* parser.[ch] nanohttp.c HTMLtree.c HTMLparser.c tree.c: applied and
+	  modified slightly Wayne Davison patch adding xmlStrcasecmp and
+	  related function, fixing xmlStrncmp(), and associated cleanup
+	* result/HTML/entities.html.sax: updating result
+
+Tue Sep 19 14:20:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c: applied patch for URI escaping from Wayne Davison
+	  <wayned@blorf.net>
+	* tree.c parserInternals.c HTMLparser.c: memset checks patches
+	  from Denis Barbier <barbier@imacs.polytechnique.fr>
+	* HTMLparser.c: UTF8 characters in HTML tag-attribute values
+	  patch from Wayne Davison
+
+Sun Sep 17 18:37:03 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html : updated with new releases, adding "how to help"
+
+Sun Sep 17 17:58:37 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.c debugXML.c parser.c parserInternals.c tree.c valid.c xpath.c:
+	  removed a few warnings in pedantic mode ...
+	* parserInternals.c parser.c: moved encoding switching function
+	  to parserInternals.c
+	* configure.in, doc/Makefile.am libxml.spec.in: released 2.2.3
+
+Sat Sep 16 20:12:41 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c parser.c: set ctxt->errNo before calling the
+	  error or warning handlers
+
+Wed Sep 13 22:03:18 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parserInternals.c parserInternals.h parser.c Makefile.am:
+	  created a new module parserInternals.c, moved most of the
+	  code shared by the various parsers there, as well as
+	  deprecated  code from parser.c. More cleanup of parser.c
+	* uri.c: fixed a problem when URI is NULL
+	* valid.c: speedup when looking for an attribute declaration
+
+Sun Sep 10 17:53:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c tree.c SAX.c parser.c entities.c debugXML.c: finished
+	  the cleanup of the computation of URI references when seeking
+	  external entities. The URI reference string and the resulting
+	  URI are both stored now.
+	* parser.c HTMLparser.c valid.c nanoftp.c nanohttp.c xpath.c:
+	  large s(n)printf checks and cleanup from Denis Barbier
+	  <barbier@imacs.polytechnique.fr>
+	* xmlversion.h.in tree.h: couple of SGML declarations for a
+	  possible docbook module.
+	* result/VC/ : a couple of test output changed due to the change
+	  of the entities URI
+
+Sun Sep 10 15:59:58 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.h: added a _private field for linking user's data
+
+Sun Sep 10 15:14:43 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c parserInternals.h: demacroified most of the IS_XXX
+	  the gain in size is significant so ...
+
+Fri Sep  8 20:48:29 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* entities.c: cases where looking up entities with doc==NULL
+	  covered
+
+Tue Sep  5 12:41:15 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c: applied Wayne Davison patch
+	* Makefile.in test/URI/uri.data result/URI/uri.data: updated URI tests
+
+Mon Sep  4 13:01:45 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c testUri.c: applied Wayne Davison patches
+	* test/URI/uri.data result/URI/uri.data: first set of tests/results
+	* Makefile.in: added URItest and included thenin "make tests"
+
+Sun Sep  3 19:19:29 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlversion.h.in: closed bug 22941
+
+Thu Aug 31 16:55:55 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xmlio.html: added doc and example for entity loader
+	  redefinition.
+
+Thu Aug 31 14:59:28 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xmlio.html doc/xml.html: added a doc on the I/O mechanism
+	  used by libxml
+
+Tue Aug 29 20:22:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: Fixed bug on invalid ontent characters and when using
+	  push.
+	* xmllint.c: fixed xmllint endling of errors in push mode
+
+Tue Aug 29 11:24:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c testHTML.c: applied two new patches from
+	  Wayne Davison <wayned@users.sourceforge.net>
+	* result/HTML/*.sax: regenerated HTML SAX output
+	* parser.c: more cleanup.
+
+Mon Aug 28 11:58:12 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.[ch] testHTML.c: applied the second set of
+	  patches from Wayne Davison <wayned@users.sourceforge.net>,
+	  adding htmlEncodeEntities()
+	* HTMLparser.c: fixed an ignorable white space detection bug
+	  occuring when parsing with SAX only
+	* result/HTML/*.sax: updated since the output is now HTML
+	  encoded...
+
+Mon Aug 28 00:38:31 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.[ch]: applied some of Wayne Davison
+	  <wayned@users.sourceforge.net> patches
+
+Sun Aug 27 22:14:01 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.c tree.c debugXML.c: fixed bogus behaviour when an
+	  undeclared namespace prefix was used, added a warning.
+	  Cleaned up support w.r.t. entities, spilling out a warning
+	  and being pedantic on lookups.
+	* test/warning/ent9 : added testcase for previous example.
+	* TODO: updated
+	* parserInternals.h parser.c: changed the way names are parsed
+	  now allow infinite size and decrease penalty for normal use
+	* parser.c: Started a big cleanup/check of the parser code,
+	  fixed some of the most tortuous entity code, spotted code
+	  unused anymore
+	* test/*: added tests for very long names and related nasty
+	  things.
+
+Sat Aug 26 23:31:04 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/encoding.html: added encoding aliases doc
+	* doc/xml.html: updates
+	* encoding.[ch]: added EncodingAliases functions
+	* entities.[ch] valid.[ch] debugXML.c: removed two serious
+	  bottleneck affecting large DTDs like Docbook
+	* parser.[ch] xmllint.c: added a pedantic option, will be
+	  useful
+	* SAX.c: redefinition of entities is reported in pedantic mode
+	* testHTML.c: uninitialized warning from gcc
+	* uri.c: fixed a couple of bugs
+	* TODO: added issue raised by Michael
+
+Wed Aug 23 01:50:51 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/encoding.html: propagated Martin Duerst suggestions
+
+Wed Aug 23 00:23:41 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: Fixed Bug#21552: libxml fails to decode &amp;
+	* uri.c testUri.c patches, by Marc Sanfacon (1 left)
+	* parser.c HTMLparser.c: HTML/encoding push problems reportedi
+	  by Wayne Davison
+
+Sun Aug 20 17:03:38 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c nanohttp.c: small cleanup
+	* TODO: updated
+
+Sat Aug 19 22:57:02 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* added an old VC testcase and updated title.xml entity
+
+Sat Aug 19 21:02:08 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c SAX.c tree.c HTMLtree.h result/HTML/*: work
+	  done on auto-opening of <p> tags and cleanup of SAX output
+
+Sat Aug 19 18:45:40 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* libxml.4  xmllint.1 Makefile.am libxml.spec.in: added man pages
+
+Sat Aug 19 18:38:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html libxml.* structure.*: updated the doc a bit
+
+Thu Aug 17 15:50:00 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* testSAX.c testHTML.c result/HTML/: cleanup of the output
+	  of SAX tests
+
+Mon Aug 14 13:56:33 EDT 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Patch from Albert Chin-A-Young <china@thewrittenword.com>:
+	* xmllint.c: workaround a MAP_FAILEd definition bug in DU-4.0
+
+Mon Aug 14 11:10:20 EDT 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Patch from Dave Yearke <yearke@eng.buffalo.edu>:
+	* testHTML.c: fix core dump on Solaris 2.x systems
+	* HTMLparser.c: fix segfault if ctxt->sax->characters() is NULL
+	* result/HTML/*.sax: previous bug fix lead to new results
+
+Mon Aug 14 10:26:09 EDT 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Patch from Albert Chin-A-Young <china@thewrittenword.com>:
+	* configure.in: added --with-readline=DIR to accept alternate
+	  path for readline include/library
+	* configure.in: added AM_C_PROTOTYPES to add -Aa -D_HPUX_SOURCE
+	  for ANSI under HP-UX
+	* config.in: Removed @LIBS@ from xml-config because @XML_LIBS@
+	  includes @LIBS@
+
+Sat Aug 12 23:19:42 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/* : rebuilt the docs
+	* getting ready for 2.2.2 release
+
+Sat Aug 12 16:42:37 EDT 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch]: added xmlGetFeaturesList() xmlGetFeature()
+	  and xmlAddFeature()
+	* tree.[ch]: added xmlAddChildList()
+	* xmllint.c: MAP_FAILED macro test
+	* parser.h: added xmlParseCtxtExternalEntity()
+	* valid.c: applied bug fixes removed warning
+	* tree.c: added CDATA block to elements content
+	* testSAX.c: cleanup of output
+	* testHTML.c: added SAX testing
+	* encoding.c: better error recovery
+	* SAX.c, parser.c: fixed one of the external entity processing
+	  of the OASis testsuite
+	* Makefile.am: added HTML SAX regression tests
+	* configure.in: bumped to 2.2.2
+	* test/HTML/ result/HTML: added a few of HTML tests, and added the
+	  SAX results
+
+Fri Aug  4 11:21:50 PDT 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: patch for HP compiler
+
+2000-08-04  Sven Heinicke  <sven@zen.org>
+
+	* xmllint.c: Was coredumping sometimes when the file given didn't
+	exist.
+
+Sat Jul 22 05:59:05 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c xmlIO.[ch]: fixed the problem of encoding support
+
+	  when using in memory parsing. Need some cleanup.
+	* xmllint.c configure.in: added a --memory flag to test memory
+	  parsing
+
+Fri Jul 21 17:09:57 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.c: fixed socklen_t replacement to unsigned int
+	* parser.c: fixed a space handdling missing at the end of
+	  production 28 DOCTYPE.
+	* xmlmemory.c: fixed a stupid bug on the routine to override
+	  allocation functions
+	* TODO: updated
+
+Fri Jul 14 17:01:14 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/ regenerated the docs
+
+Fri Jul 14 16:12:20 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/encoding.html doc/xml.html: added I18N doc
+	* encoding.[ch] HTMLtree.[ch] parser.c HTMLparser.c: I18N encoding
+	  improvements, both parser and filters, added ASCII & HTML,
+	  fixed the ISO-Latin-1 one
+	* xmllint.c testHTML.c: added/made visible --encode
+	* debugXML.c : cleanup
+	* most .c files: applied patches due to warning on Windows and
+	  when using Sun Pro cc compiler
+	* xpath.c : cleanup memleaks
+	* nanoftp.c : added a TESTING preprocessor flag for standalong
+	  compile so that people can report bugs more easilly
+	* nanohttp.c : ditched socklen_t which was a portability mess
+	  and replaced it with unsigned int.
+	* tree.[ch]: added xmlHasProp()
+	* TODO: updated
+	* test/ : added more test for entities, NS, encoding, HTML, wap
+	* configure.in: preparing for 2.2.0 release
+
+Mon Jul 10 16:17:18 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c: fixed the way the control connection is handled
+	* libxml.spec.in: fixed the dependencies and cleanup
+
+Mon Jul  3 14:37:07 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html: changed the xmlsoft.org structure, updated the
+	  examples w.r.t. root and childs
+
+Sun Jul  2 20:51:43 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* libxml.spec.in: fixed bug #7419, dependencies fouled for libxml-devel
+
+Sun Jul  2 09:52:45 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: Work on character encoding support for the HTML parser
+	* HTMLparser.c: Fixed some autoopen/autoclose probs for the HTML parser
+	* encoding.c: Fixed a potential memleak in the encoding stuff
+
+Sat Jul  1 13:44:22 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/FAQ.html doc/Makefile.am : added a FAQ
+
+Fri Jun 30 20:29:08 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c HTMLtree.c SAX.c valid.c tree.h : more cleanup
+	  of the HTML parser to force it to not bypass SAX
+
+Fri Jun 30 11:19:59 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* win32config.h.in: updated
+	* xmlversion.h.in: crap forgot to update this, this mean 2.1.0
+	  lacks iconv support :-( need to release 2.1.1
+	* configure.in: release 2.1.1
+	* HTMLparser: fixed bug #14784
+	* xpath.c HTMLparser.c encoding.c parser.c: fix warning raised
+	  by Windows compiler
+	* HTMLparser.c SAX.c HTMLtree.h tree.h: create HTML document in
+	  the SAX startDocument() callback.
+	* TODO: updated
+
+Thu Jun 29 12:06:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* added xmlStopParser()
+
+Wed Jun 28 23:10:26 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: 2.1.0 prerelease
+	* Large resync between W3C and Gnome tree
+	* nanoftp, nanohttp.c: fixed stalled connections probs
+	* HTMLtree.c SAX.c : support for attribute without values in
+	  HTML for andersca
+	* valid.c: Fixed most validation + namespace problems
+	* HTMLparser.c: start document callback for andersca
+	* debugXML.c xpath.c: lots of XPath fixups from Picdar Technology
+	* parser.h, SAX.c: serious speed improvement for large
+	  CDATA blocks
+	* encoding.[ch] xmlIO.[ch]: Improved seriously saving to
+	  different encoding
+	* example/Makefile.am example/gjobread.c tree.h: work on 
+	  libxml1 libxml2 convergence.
+	* config.h.in parser.c xmllint.c: added xmlCheckVersion()
+	  and the LIBXML_TEST_VERSION macro
+
+Fri Jun 23 22:26:07 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html: various patches and improvements typo fixed by
+	  Felix Natter
+	* doc/libxml-doc.el: Emacs module to lookup the libxml documentation
+	  from Felix Natter <fnatter@gmx.net>
+
+Sat May  6 10:09:45 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/upgrade.html: updated with instructions for support of both
+	  libxml-1.x and libxml-2.x
+	* doc/gjobread.c : applied Todd Dukes <tdukes@ibmoto.com> patch
+	  for 2.x support and also fixed includes
+
+Wed May  3 14:21:25 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
+	  the encoding support, added iconv support, so now libxml if
+	  compiled with iconv automatically support japanese encodings
+	  among others. Work based on initial patch from Yuan-Chen Cheng
+	  I may have broken binary compat in the encoding handler
+	  registration scheme, but that was so utterly broken I don't
+	  expect anybody to have used this feature until now.
+	* parserInternals.h: fixup on the CHAR range macro
+	* xml-error.h, parser.c: catch URL/URI errors using the uri.c
+	  code.
+	* tree.[ch]: added xmlBufferGrow(), was needed for iconv
+	* uri.c: added xmlParseURI() I can't believe I forgot to
+	  implement this one in 2.0 !!!
+	* SAX.c: moved doc->encoding update in the endDocument() call.
+	* TODO: updated.
+
+Mon Apr 24 13:30:13 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.h: removed extraneous xmlRemoveProp definition
+	* TODO: added item about --disable-corba configure switch
+	* tree.c parser.c: fixed problems for xmlCopyDoc and postvalidation
+	* nanoftp.c: fixed include problems giving troubles on AIX and 
+	  slowlaris
+	* xmlIO.[ch] valid.h tree.[ch] xlink.c xmlmemory.c uri.c 
+	  parser.c nanoftp.c nanohttp.c SAX.c testSAX.c :
+	  comment and headers changes to lower gtk-doc number of warnings
+	* doc/html/*: rebuilt docs
+
+Sun Apr 16 11:23:29 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HACKING: documented the tag for 1.x and instructions
+
+Wed Apr 12 15:47:22 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlIO.[ch] parser.[ch]: More interfaces for new I/O functions
+	  xmlNewIOInputStream, xmlParserInputBufferCreateIO,
+	  xmlCreateIOParserCtxt
+	* parser.c parserInternals.h: speedup of IS_CHAR like macros,
+	  significant overall improvement
+	* xmllint.c: added I/O test to xmllint
+	* testSAX.c: added a speed test
+	* doc/* : updated/regenerated
+
+Sat Apr  8 14:54:54 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.c uri.h parserInternals.h: cosmetic changes from
+	  "Timur I. Bakeyev" <timur@bat.ru>, including making 
+	  xmlCreateURI() public
+
+Fri Apr  7 18:35:02 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlIO.[ch] parser.c: cleane up the xmlParserInputBuffer mess
+	  and the code at the same time. Added a clean mechanism for
+	  overload or added input methods: xmlRegisterInputCallbacks()
+	* tree.c: fixed xmlPrevSibling and xmlNextSibling per 
+	  Christophe Le Gal (Christophe.Le-Gal@imag.fr) input
+	* TODO: updated
+	* doc/* : updated/regenerated
+	* doc/Makefile.am: tweaks to avoid problem with libxml link in the
+	  source dir
+
+Wed Apr  5 21:11:35 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* testURI.c: yet another forgotten commit, I should get some sleep !
+
+Wed Apr  5 20:36:46 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmllint.c: forgot to commit this too ?
+
+Wed Apr  5 16:22:44 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlversion.h.in : forgot to commit this previously
+
+Mon Apr  3 21:47:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: preparing libxml-2.0.0 version looks Ok so far
+	* README TODO: updated for release
+	* uri.c uri.h: added authority parsing/saving
+	* uri.c testURI.c Makefile.am: moved the testing code to testURI.c
+	* xmlversion.h.in configure.in nanoftp.[ch] nanohttp.[ch] encoding.h
+	  debugXML.[ch] xpath.[ch] xmlIO.c tester.c testXPath.c testHTML.c
+	  tree.c HTMLtree.c HTMLparser.c tree.c tree.h parser.c
+	  Makefile.am : added compile-time customization of libxml
+	  --with-ftp --with-http --with-html --with-xpath --with-debug
+	  --with-mem-debug
+	* *.[ch] autoconf.sh : moved to an absolute adressing of includes : 
+	  #include <libxml/xxx.h> I hope it won't break too much stuff
+	  and will be manageable in the future...
+	* xmllint.c Makefile.am libxml.spec.in : renamed tester.c to xmllint.c
+	  and added xmllint to the installed programs
+	* uri.h: added xmlFreeURI()
+
+Fri Mar 24 14:35:21 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c uri.h: finished the escaping handling, the base support
+	  and the URI path normalization. Looks good just lacks the
+	  authority content parsing code.
+	* Makefile.am: added instructions to generate testURI
+	* TODO: updated
+	* doc/xml.html, doc/smallfootonly.gif doc/w3c.png: updated,
+	  added links and icons for W3C and Gnome
+
+Mon Mar 20 14:05:26 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlmemory.[ch] : seems I forgot to actually update the files in
+	  the last commit :-)
+	* doc/xml.html doc/html/* : updated and uploaded the docs
+
+Mon Mar 20 12:33:51 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* test/valid/dtds/xhtml*: removed RCS infos (pain with CVS)
+	* TODO: updated
+	* xmlmemory.[ch] : added xmlMemSetup() and xmlMemGet() to override
+	  libxml default allocation function with another set (like gmalloc/
+	  gfree).
+	* Makefile.am, uri.c, uri.h: added a set of functions to do
+	  exact (litteraly copied from the RFC 2396 productions) parsing
+	  and handling of URI. Will be needed for XLink, one XML WFC, 
+	  XML Base and reused in the nano[ftp/http] modules. Still work
+	  to be done.
+
+Tue Mar 14 20:52:35 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, libxml.spec.in : libxml2
+	* doc/* : updated the doc page, rebuilt the docs
+
+Tue Mar 14 19:11:29 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* all: tagged LIB_XML_1_X
+	* *.c *.h : updated from W3C CVS tree
+	* configure.in : 2.0.0-beta
+	* libxml.spec.in : libxml2 package nam
+	* result/* : new version of the tests output
+
+Mon Mar  6 09:34:52 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html, doc/update.html: updated docs, 1.8.7
+
+Sat Mar  4 16:14:42 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/* : rebuilt the docs
+	* parser.c: final patch on #6766
+	* valid.c: small patch on validity checks.
+
+Sat Mar  4 12:38:41 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/upgrade.html: instruction on how to upgrade from 1.x to 2.x
+	  added
+	* parser.c: adding xmlKeepBlanksDefault() as a way to manage
+	  compatibility w.r.t. XML spec and existing code.
+
+Thu Mar  2 04:45:15 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: seems a better solution to <a>   </a> exists,
+	  will try it for a while
+
+Thu Mar  2 02:26:13 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: tried to remove the <a>   </a> generating <a/>
+	  this is hard. Left a flag for that purpose. Fixed bug #6766
+	* configure.in: prepared 1.8.7 not released, due to previous
+	  problem
+
+Thu Mar  2 03:03:50 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html : applied second patch from Paul DuBois
+
+Tue Feb 29 23:55:13 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html : applied patch from Paul DuBois
+
+Thu Feb  3 16:36:39 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c HTMLparser.c: do a bit of bufferization in push mode.
+
+Thu Feb  3 15:59:37 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c nanohttp.c tree.c HTMLtree.[ch] debugXML.c xpath.c: Fixed
+	  compilation warnings on various platforms.
+	* parser.c: Fixed #5281 validity error callbacks are now desactived
+	  by default if not validating.
+
+Thu Feb  3 13:46:14 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c, win32config.h.in: patches to compile on WIN32
+
+Wed Feb  2 22:51:16 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c: snprintf/sprintf patch courtesy George Katsirelos
+	  <gkatsi@cs.toronto.edu>
+
+Mon Jan 31 18:58:21 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.c nanohttp.c: Fixed '#' and '?' stripping when
+	  processing URLs
+
+Mon Jan 31 14:25:57 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.[ch]: cleanup, bug fixes, integration in rpmfind, added
+	  xmlNanoFTPUpdateURL for persistent control connections.
+	* configure.in: 1.8.6
+
+Thu Jan 27 17:52:29 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.[ch], nanoftp.[ch]: cleanup, added proxy support
+	* tree.[ch] : added xmlSaveNoEmptyTags
+
+2000-01-29  James Henstridge <james@daa.com.au>
+
+	* nanoftp.c: include <netinet/in.h> for IPPROTO_TCP.
+
+	* Makefile.am: added nanoftp.[ch] to the build.
+
+Wed Jan 26 18:14:55 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.[ch]: cleanup, comments, API
+	* debugXML.c : fixed a bug in the cat command
+	* doc/*: regenerated the docs
+
+Wed Jan 26 16:52:50 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanoftp.[ch] parser.c xmlIO.[ch]: added a Nano FTP implementation
+	* debugXML.c : fixed a bug in the cat command
+	* valid.c: fixing some small probs
+	* libxml.spec.in: get rid of the SNAP suffix
+	* doc/xml.html: updated the status
+
+Mon Jan 24 14:31:09 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xml-config.in: xml-config --version to just return the
+	  version number
+	* xpath.c: some cleanup w.r.t. axis when the current node is
+	  an attribute.
+	* TODO: updated
+
+Tue Jan 18 18:46:06 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: prepared for libxml-1.8.5
+	* doc/* recompiled the documentation
+
+2000-01-17  Jody Goldberg <jgoldberg@home.com>
+
+	* configure.in : WARNING autoconf subtlety alert :
+	  Use AC_CHECK_HEADERS rather than AC_CHECK_HEADER
+	  when looking for zlib.h so that HAVE_ZLIB_H is defined.
+	* config.h.in : Have a #undef for HAVE_ZLIB_H so that it will
+	  get defined by AC_CHECK_HEADERS.
+
+Mon Jan 17 17:04:12 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: fixed a hideous bug in xmlGetProp() thanks to
+	  Rune.Djurhuus@fast.no
+
+Sat Jan 15 15:09:06 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* TODO: updated
+	* tree.c, parser.c: made sure that only memory alloc problems
+	  and internal parser errors are allowed to write to stdout or
+	  stderr.
+
+Thu Jan 13 11:49:11 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c : restored xmlNewGlobalNs since this seems used by
+	  a lot of existing code :-(, fixed a bug in xmlNewNs
+	* nanohttp.c: fixed a problem with INCLUDE_WINSOCK
+	* HTMLparser.c, parser.c, entities.c, valid.c : removed all calls
+	  to exit() from the library code.
+	* xpath.c, parser.c: removed bugs or unused code detected by 
+	  Windows compilers
+	* parser.c: started adding interfaces for parsing well balanced
+	  XML fragments
+	* configure.in: releasing 1.8.4
+	* doc/* : rebuilt the docs
+
+Sun Jan  9 23:03:20 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] : added xmlNewDocFragment() for DOM
+	* testHTML.c: uninitialized variable.
+
+Wed Jan  5 17:29:17 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/* : rebuild the docs
+
+Wed Jan  5 17:08:43 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* acconfig.h: readline and history patch
+	* valid.[ch]: added xmlRemoveID() and xmlRemoveRef()
+	* tree.c: added check and handling when possibly removing an ID
+	* tree.c, HTMLparser.h, HTMLtree.h: fixed entities parsing
+	     and saving.
+	* test/HTML/entities.html result/HTML/entities.html* : test for
+	     various entities reference cases
+	* result/HTML/* : as a result output of some testcase have
+	     changed
+	* HTMLparser.c, parser.c: fixed a bug in the push mode triggered
+	     by previous example. added xmlParseTryOrFinish().
+	* xpath.h tree.h parser.h valid.h xmlIO.h xlink.h encoding.h
+	  entities.h debugXML.h HTMLparser.h: changed the way struct are 
+	  declared to allow gtk-doc to expose those
+	* parser.c: closed bug #4960  
+	* Makefile.am configure.in: Applied patch from 
+	  Albert Chin-A-Young <china@thewrittenword.com> for better zlib
+	  and math/socket libs detection
+
+Mon Jan  3 18:29:43 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, Makefile.am: link tester against readline
+	* doc/xml.html doc/*/*: updated and rebuilt the documentation pages
+
+Mon Jan  3 11:58:05 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch]: added xmlRemoveProp
+	* win32config.h.in nanohttp.c: avoid including the Windows
+	    socket stuff in every C files
+	* parser.c: removed an indetermination xmLDecl/PI(xml...) in
+	    the XmL parser(s)
+	* test/ns4 result/ns4 etc...: added test case for previous prob    
+	* tree.c: xmlNewNs wasn't checking for double definition
+	* Makefile.in: fixed a problem with dist-hook duplicates
+	* parser.[hc], xmlIO.c: fixed the loading of external entities
+	    APIs, now xmlLoadExternalEntity() is used everywhere and
+	    setting up an app specific front-end using the 
+	* SAX.c parser.c: some fixes, now the xhtml spec validates
+	    with the xhtml DTD.
+	* error.c: fixed crashes in case of no input stream    
+	* test/valid/[dtds/]/xhtml* : added the xhtml spec and dtds
+	    to the validation tests and results
+
+Wed Dec 29 15:29:52 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.[ch] testHTML.c: added push mode for the HTML parser
+	  too htmlCreatePushParserCtxt() and htmlParseChunk()
+	* parser.c: a bit of cleanup.
+	* SAX.c, HTMLparser.c: some attributes may not have values (contrary
+	  to XML) removed the last mem leak known
+	* HTMLtree.c: output message cleanup
+	* xmlmemory.c: display content info about memory blocks
+	* result/HTML/wired.* : missing att value warning change
+
+Tue Dec 28 17:42:41 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/* : rebuilt the documentation
+
+Tue Dec 28 18:44:22 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch] parserInternals.h: Push parser for XML,
+	     seems to work fine now
+	* tester.c debugXML.[ch]: Added an XML shell debug facility and
+	     --push for push testing
+	* xpath.[ch] : cleaned up for Shell usage, added missing APIs
+	* testSAX.c: added --push
+	* HTMLtree.[ch] tree.[ch]: new functions for dumping parts of the
+	     subtree
+	* xmlIO.[ch] : enriched API + fixes for push mode     
+	* entities.[ch]: added the entity content length to the struct.
+	* xmlmemory.[ch]: new API to show the last entries for the shell
+	* valid.c: added required attribute testing
+	* SAX.c: the cdata callback now merge contiguous fragments
+	* HTMLparser.c: cleanup of some macros
+
+Wed Dec 22 12:20:53 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: fix for PIs name starting with xml
+	* tree.c: fixed a potential problem with || and && ops
+	* *.c, configure.in win32config.h.in : generate win32config.h for
+	  those on the Other Side !
+
+Tue Dec 21 17:22:17 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: fixed a stupid = vs. == bug :-(
+	* doc/gnome-xml.sgml: s/glade/xml/
+
+Tue Dec 21 14:29:34 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, doc/xml.html : bug fix release 1.8.2
+	* debugXML.h nanohttp.h xml-error.h xmlmemory.h xpath.h : 
+	  Hopefully the end of that silly C++ include problem
+	* tree.[ch]: Added a few functions: xmlReplaceNode, xmlAddPrevSibling,
+	      xmlAddNextSibling, xmlNodeSetName and xmlDocSetRootElement
+	* HTMLparser.c HTMLparser.h HTMLtree.c: When saving HTML try to avoid 
+	      troubles with autoclosed elements when the stree shape doesn't
+	      follow the DtD specs. Added htmlIsAutoClosed() and
+	      htmlAutoCloseTag()
+	* result/HTML/*.htm*: Updated the HTML examples regression tests output
+	* SAX.c tree.c: fixed bug on defaulting namespaces on attributes
+	* debugXML.c: fixed a bug on printing default namespaces.
+	* HTMLtree.c: fixed a problem when outputing XML parsed docs as HTML
+
+Mon Dec 20 16:20:55 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* result/HTML/*.htm[l] : updated the HTML regression tests according
+	  to the new output
+	* xpath.h xml-error.h valid.h tree.h parser.h entities.h SAX.h
+	  HTMLtree.h tree.c entities.c: headers tweakings to avoid a nasty
+	  problem due to intermix of extern "C" { ... } declarations for C++
+	  and recursive includes in the headers
+
+1999-12-20  Chris Lahey  <clahey@umich.edu>
+
+	* HTMLtree.c: Made it so that html nodes with a single child do
+	not insert a carriage return before or after the child node.
+
+Sat Dec 18 16:07:03 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, doc/xml.html : bug fix release 1.8.1
+	* parser.c: fixed bug #4344
+	* xpath.h xml-error.h xlink.h nanohttp.h debugXML.h SAX.h HTMLparser.h
+	  added the glue to avoid C++ problems
+	* doc/* : regenerated the documentation
+
+Thu Dec 16 16:19:29 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: fixed a bug introduced in 1.8.0 and breaking default
+	  namespace recognition, and Dia as a resul :-(
+	* encoding.c: closed bug #3950
+
+Wed Dec 15 19:22:23 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* valid.c: debugging a posteriori validation, except URI expansion
+	  stuff this should be fixed now
+	* parserInternals.h: fixed a bug in IS_BASECHAR reported by
+	  Carl Nygard <cnygard@bellatlantic.net>
+	* tester.c: added --postvalid, cleaning of the code
+	* tree.[ch]: added xmlDocGetRootElement()
+
+Tue Dec 14 20:30:34 PST 1999 Ramiro Estrugo <ramiro@eazel.com>
+
+	* SAX.h, tree.h : changed 'namespace' to 'nameSpace' to workaround
+	c++ losage.
+
+Sun Dec 12 13:08:15 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, doc/xml.html : bumped to 1.8.0
+	* xlink.[ch], Makefile.am : added framework for link detection
+	* parser.h: added nbChars to parser context, needed for cleanup.
+	* xmlmemory.c: removed a nasty bug when out of mem
+	* valid.[ch]: adding namespace support for attribute decl
+	* tester.c: added --debugent option
+	* debugXML.[ch]: added xmlDebugDumpEntities()
+	* parser.c: cleanup, avoiding use of CUR_PTR like plague, using
+	  buffers instead, this was really needed, validation was breaking
+	  in strange ways due to that. Added xmlParseStringPEReference()
+	  and other parsing from strings functions. Entities processing
+	  modified again, but PERef are still not handled correcly but
+	  unless you're Eve Maller you won't notice :-)
+	* HTMLparser.c: large changes toward reliability, and switched to
+	  lowercase internal tags, XHTML is lowercase, so it will help
+	  that output is closer to next version.
+	* doc/* : regenerated the documentation, it is now hosted at
+	  http://xmlsoft.org/ (same bits I just bought the domain :-)
+
+Fri Dec  3 13:46:32 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.h, SAX.c, makefile.am: added SAX.h mostly useful for the
+	         doc generation
+	* parser.c: fixed bugs #3908 and #3937 and a memory leak
+	         in the SAX API
+	* doc/*: rebuilt the doc making sure everything appears in the
+	         HTML files
+
+Wed Dec  1 10:27:47 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] HTMLtree.c, debugXML.c, configure.in, xml-config.in:
+	     added the patch from Carl Nygard <cnygard@bellatlantic.net>
+	     which allow impressive speed improvement on dataset with
+	     large text pieces, but at the cost of broken binary
+	     compatibility and slightly bigger memory usage.
+	     Configure with --with-buffers to activate them, they
+	     are protected with XML_USE_BUFFER_CONTENT define.
+	* entities.[ch], parser.c: added xmlCleanupPredefinedEntities(),
+	     goal is 0 memory left allocated once parser is no more used
+	* testDAV.c, testHTML.c, testSAX.c, testXPath.c: make sure we
+	     call xmlCleanupParser() and xmlMemoryDump()
+
+Wed Nov 24 19:00:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch] xmlIO.[ch] parser.c valid.c: code cleanup with -pedantic
+	* parser.[ch] encoding.[ch]: added memory cleanup routines
+	* parser.c: closing bug #3788
+	* doc/*: rebuilt the doc
+
+Tue Nov 23 11:23:55 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch]: closing bug 3748, added xmlNewDocRawNode(), 
+	             xmlNewTextChild() and xmlSetCompressMode() behaviour.
+	* tester.c: added --compress option
+	* doc/*: rebuilt the documentation
+
+Fri Nov 19 18:41:28 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: bugfixing, the damn thing MUST not crash even
+	                if given /proc/kcore as input !
+	* doc/xml.html doc/*: updated and rebuilt the documentation
+
+Thu Nov 18 14:57:18 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: Fixed some wrongly space collapsing code due to
+	            a misreading of the spec.
+	* result/*: fixed the output accordingly	    
+
+Wed Nov 17 18:28:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* encoding.c: bug fix and typos
+	* xmlIO.[ch] parser.c: first bits toward real progressive parsing
+	* parser.c: added attribute normalization closing bug #3597
+	* test/att* result/att* SAXresult/att*: testcase for attribute
+	    normalization
+
+Mon Nov 15 18:50:56 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: closing bug #3163 by adding extra flags for the
+	                cc compiler on HP-UX
+
+Fri Nov 12 17:41:20 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* valid.[ch] : removed a typo and an enumerated type bug in the
+	               xmlAddElementDecl() function
+	* tree.c : I changed xmlSetProp() and xmlNewProp() to do the
+	    call to xmlEncodeEntitiesReentrant() so that the functions 
+	    New, Set and Get are at the same level.
+	* parser.c HTMLparser.c: extra memory allocation bug for
+	    attributes detected by someone using libxml in embedded systems :-)
+
+Thu Oct 28 17:49:26 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlmemory.h: turned off mem debug :-\
+
+Mon Oct 25 12:13:25 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: closed bug #2784 a one line fix, but worth pushing
+	            a new release out
+	* HTMLparser.c: fixed auto-close bugs on list items, zeroing
+	            some structures, comments before and after the
+		    main element, and other nastyness
+	* HTMLtree.c tree.c: accomodate the extended HTML supported	    
+	* configure.in: pushing 1.7.4
+	* test/ent8 and related outputs : added a new test for bug #2784
+	* test/HTML/wired.html and related output: a nasty HTML example
+	* Makefile.am: improved the test scripts
+	* docs/* : reran the documentation extractor, updated xml.html
+
+Thu Oct 14 10:29:56 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c, HTMLtree.c, tree.h: completely revamped the
+	     HTMLparser and debugged the HTML related code. HTML documents
+	     now have their own type
+	* entities.c: do not dump &apos; for HTML output
+	* xmlmemory.c: improvement, breakpoint mechanism
+	* testHTML.c: added --sax --repeat ...
+	* Makefile.am: improved the HTML tests
+	* valid.[ch]: added xmlValidGetValidElements and
+	              xmlValidGetPotentialChildren
+	* tester.c: added --insert to test the 2 new functions
+	* test//* result//* SAXresult//* : regression test cleanup
+	               and extension.
+	* doc/html : added doc for new modules gnome-xml-xmlmemory.html and
+	             gnome-xml-nanohttp.html
+
+Mon Oct 11 14:31:58 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: fixed problems with some autoclose tags
+	* tree.c: fixed XML output problems. 
+	* result/* SAXresult/*: update of the tests output
+
+Sat Oct  9 11:02:57 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am: Arturo patch for xmlConf.sh version info
+	* parser.c: Tim Josling patch for single quoted items
+	* tester.c: Tim Josling patch for tester options usage
+	* tree.h: indent cleanup
+
+Fri Oct  8 16:35:37 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c parser.h : Fixed problems with HTML parsing
+	    reported by Kristian Hogsberg Kristensen <hogsberg@daimi.au.dk>
+
+Fri Oct  8 11:37:11 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c : Raph patch for initialization of CORBA fields
+	* parser.c, xpath.c, ...: modification of doc comments
+	* xpath.c : allow spaces in xpath expressions
+
+Mon Sep 27 10:16:43 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlmemory.h: turning off memory debug :-(
+
+Sun Sep 26 13:16:54 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch] : added xmlSAXUserParseFile() and xmlSAXUserParseMemory()
+	                better SAX interfaces.
+	* testSAX.c: uses the new SAX routine, avoid fetching any remote
+	             entity.
+	* configure.in: 1.7.2
+
+Fri Sep 24 16:01:01 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* libxml.spec.in: fixed the URL
+	* doc/xml.html: improved the documentation front-end
+
+Fri Sep 24 01:06:36 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* nanohttp.c: conditionned references to snprintf with HAVE_SNPRINTF
+
+Fri Sep 24 00:15:58 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* libxml.spec.in: fixed the alpha compile problem
+	* parser.[ch]: changed errno to errNo in the parser context :-(
+	* *.[ch]: changed CHAR to xmlChar to avoid problem on WIN32
+	* doc/xml.html: changed CHAR to xmlChar
+	* doc/html/*: recompiled the documentation
+	* configure.in: 1.7.1
+
+Wed Sep 22 11:40:31 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.h: modified the parser context struct to regain 1.4.0
+	            binary compatibility
+	* parser.c, xml-error.h: added errno ot teh context and defined
+	            a set of errors values with update of errno
+	* nanohttp.[ch]: minimalist HTTP front-end for fetching remote
+	            DTDs and entities
+	* *.h, *.c: complete cleanup of the use of config.h and include
+	            protection depending on the current setup.
+	* overalll debugging, maintenance and bug-fixing on all modules
+	* updated the documentation
+	* ready for 1.7.0
+
+Wed Sep  8 22:46:14 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c : cleanup
+	* SAX.c valid.c valid.h: added ID/IDREF checking
+	* tree.c tree.h: extended doc structure for refs
+	* configure.in: 1.6.2
+	* parser.c: patched bug in SAX user arg call
+	* parserInternals.h: patched missing close in C++ wrapping
+	* testXPath.c xpath.c xpath.h: prepared for extensibility,
+	  especially upcoming XPointer implementation.
+	* doc/xml.html: augmented, typo
+
+Sat Sep  4 22:48:05 CEST 1999 Timur Bakeyev <mc@bat.ru>
+
+	* doc/Makefile.am: replaced "install -d " with "mkinstalldirs" -
+	not all invocations of install understand -d.
+
+Sat Sep  4 22:20:07 CEST 1999 Timur Bakeyev <mc@bat.ru>
+
+	* Makefile.am: prepend all the test* calls with $(top_builddir) -
+	to make 'check' works, when builddir != srcdir.
+
+Sat Sep  4 20:25:46 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* doc/xml.html : updated the documentation
+
+Fri Sep  3 00:01:08 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xmlmemory.[ch] Makefile.am  :added a memory wrapper to chase
+	      not deallocated memory blocks
+	* *.c : replaces all calls to malloc() free() and realloc() to
+	      the wrapper functions/macros
+	* tree.c : removed memory leaks dues to calling xmlFreeNode()
+	      instead of xmlFreeNodeList()
+
+Wed Sep  1 14:15:09 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c: corrected a stupid bug leading to core dump at
+	                tree deallocation. Removed warnings indicated by
+			Stephane.Conversy@lri.fr
+	* entities.c: Fixes Yet Another Stupid Bug, entities were not
+	              looked for in the external subset
+
+Mon Aug 30 13:22:26 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c valid.[ch] xpath.c: patched compilation warnings reported
+	  on SGI by Stephane.Conversy@lri.fr
+
+Sun Aug 29 22:27:29 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* all .h : changed the prototype declaration indent as in gtk
+	* most .c : working on reducing the TODOs in the code
+	* most .c : cleanup though -pedantic and Insure++
+	* improvements on validation ID checkings.
+	* tree.[ch] SAX.c: added support for namespace on attributes #2022
+	* xml-config.in: closed #1810
+
+Mon Aug 16 03:27:38 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.h, valid.c, valid.h: more work on validity, IDs
+	* xpath.c: added/fixed comparidon and equlity, added a new isinf
+	  definition for AIX
+
+Sun Aug 15 21:15:17 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am libxml.spec.in: corrected missing xmlConf.sh in
+	  the distribution due to a cut'n paste error at last commit
+
+Tue Aug 10 20:28:09 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: upgraded to version 1.4.0
+	* valid.[ch], SAX.c, parser.[ch] parserInternals.h ...
+	  Big update, added a large part of the validation process,
+	  it should be usable, but some parts are missing
+	* xpath.c: improved the implementation w.r.t. root.
+	* Makefile.am: added more tests
+	* test and result trees: added a lot of tests
+	* libxml.spec.in: export libxml.so.0 and libxml.so.1
+
+Tue Aug 10 11:33:41 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Added an HACKING file
+
+Tue Jul 27 21:43:00 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xpath.[ch] : improvements and debug of the XPath implementation
+	* parser.c, HTMLparser.c : modified the parsers to be progressive
+	* tree.[ch] : extended the Buffer promitives
+	* xmlIO.[ch] : added basic I/O routines providing progressive
+	  parsing and ready for I18N conversion plugins
+	* SAXresult/* : the SAX callback sequence maybe slightly different
+	  now
+	* test*.c : improved/updated the tests programs
+	* doc/* : recompiled the docs.
+
+1999-07-26  Michael Meeks  <michael@edenproject.org>
+
+	* tree.h: Add const to 'content' in xmlNewDocNode, xmlNewChild
+
+	* tree.c: Ditto.
+
+Thu Jul 15 16:17:16 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: upgraded to version 1.4.0
+	* xpath.c, xpath.h, testXPath.c, makefile.am: added code for the XPath
+	  draft from W3C. Will be used by XPointer, Xlink, XSL, and possibly
+	  XML query language, see http://www.w3.org/TR/xpath for more details.
+	* parser.c, parser.h: added CHAR* related string functions for XPath
+	* HTMLparser.[ch], HTMLtree.c: a bit of cleanup on entities.
+	* doc/gnome-xml.sgml, doc/html/* : added XPath and HTML documentation,
+	  rebuild the docs.
+	* Makefile.am, test/XPath/*, result/XPath/*: added an XPathtests target
+	  and regression testing capabilities for XPath.
+
+Mon Jul 12 12:36:39 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, HTMLparser.c: applied patch from John Ellson <ellson@lucent.com>
+	  closing bug #1646
+
+Mon Jul 12 11:04:44 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am, example/Makefile.am: closed bug #1683
+
+Sun Jul 11 18:16:34 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* example/Makefile.am, configure.in: added the makefile for the
+	  gjobread example
+
+Sat Jul 10 14:19:11 CEST 1999 Tomasz KÅ‚oczko  <kloczek@pld.org.pl>
+
+	* doc/Makefile.am:
+	- fix which allow "make install DESTDIR=</install/prefix>".
+
+Fri Jul  9 12:10:24 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.c parser.c: applied patch from John Ellson <ellson@lucent.com>
+	  which fixed a problem on the file reading-code.
+
+Wed Jul  7 09:28:43 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.[ch], HTMLtree.[ch]: more work for HTML parsing and
+	  output.
+	* Makefile.am, test/HTML/*, result/HTML/*: added HTMLtests targetestHTMLt
+
+Wed Jul  7 00:25:42 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.h : Oops removed the binary compatibility problem
+	* HTMLparser.[ch], HTMLtree.h : More work on the HTML parse/dump
+	* parser.c, HTMLparser.c: applied patches for reading from stdin
+
+Mon Jul  5 18:45:31 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, entities.c, valid.c: cleanup bug #1591
+	* configure.in: cleanup bug #1592
+	* HTMLparser.[ch], testHTML.c: started adding an HTML parser using
+	  the same tree back-end. Hence gdome will be available for it.
+	* doc/Makefile.am: close bug #617
+
+Sat Jun 26 23:36:38 EDT 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: alloctate a per parser context SAX interface block
+
+Tue Jun 22 23:46:32 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* released 1.3.0 with xmlEncodeEntities restoring old behaviour
+	  and xmlEncodeEntitiesReentrant with the correct one :-\
+
+Mon Jun 21 14:07:53 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* commit of my internal XML base changes, quite a lot of
+	  changes, cleanups, better entities support, framework for
+	  new I/O and charset detection and handling
+	* Fixed the configure/Makefile stuff to generate shared libs
+	  with the proper version info, so we jumped on rev from
+	  0.0.0 to 1.2.0 ! The binary interfaces have been broken,
+	  xmlEncodeEntities() result need to be freed now, and a string
+	  xmlParserVersion provide the current library version.
+
+Tue Jun 15 14:24:19 1999  Raph Levien  <raph@acm.org>
+
+	* parser.c: fixed a buffer overrun for when you have a very long
+	attribute with no entities in it.
+
+Mon Jun 14 00:17:50 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* added example directory
+	* added example/gjobs.xml gjobread.c, still need a Makefile.in
+
+Wed Jun  2 19:40:58 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Release of libxml-1.1, nearly everything has been touched for
+	  this.
+	* Added more regression tests
+	* Updated the documentation
+
+Sat May 29 13:34:42 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch]: unified the XML_NO_CORBA defines.
+	* parser.c encoding.[ch]: started plugging in char encoding detection
+
+Fri May 28 22:58:42 EDT 1999 Manish Vachharajani <mvachhar@vger.rutgers.edu>
+
+	* tree.c: (xmlSaveFile) - removed double call of xmlContentDump.  
+	  Also freed allocated buffer.
+
+Wed Apr 21 22:07:35 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+	* parser.[ch] tree.[ch] entities.[ch] valid.[ch] : removed the main
+	  reentrancy problem at printing. One is left in entities.c, to
+	  remove ASAP
+	* testSAX.c : added a test example showing the use of the SAX 
+	  interface if one doesn't want to build the DOM tree.
+	* html/gnome-xml-*.html html/index.sgml: regenerated the documentation
+
+Mon Apr  5 14:14:40 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch] tree.[ch] SAX.c, parserInternals.h valid.[ch]:
+	  large revamping of the parser to use SAX callbacks
+	  http://www.megginson.com/SAX/ (or at least a C like interface
+	  a la Expat). It's now possible to set up your own callbacks
+	  and the parser will not build a DOM tree.
+	* test/* result/*: updated the test suite, I finally removed
+	  the old Namespace draft support (PI based).
+
+Fri Apr  2 17:57:32 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am: added test result to EXTRA_DIST for make tests
+
+Wed Mar 24 21:37:02 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, parserInternals.h: moved the chars macro definitions
+	  to parserInternals.h
+	* parser.c, error.c: applied patches from "Knut Åkesson"
+	  <ka@s2.chalmers.se> for clean compilation under MSVC 6 :-o
+
+Tue Mar 23 11:10:15 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xml-config.in : applied patch to make --version work
+
+1999-03-05  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* Makefile.am (check-local): Alias for `tests' target.  This will
+	cause `make check' to do the right thing.
+	(tests): Don't run tests in srcdir.  Also, replaced calls to
+	basename with a `sed' "equivalent".
+
+Fri Mar  5 07:23:53 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Renamed error.h to xml-error.h, corrected Makefile.am to list
+	  it in the header and not the sources, updated the doc.
+	  Thanks to Tim Mooney <mooney@dogbert.cc.ndsu.nodak.edu> for
+	  pointing this out.
+
+Mon Mar  1 13:27:17 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, parser.h, parserInternals.h: memory leak hunting,
+	  exported the inputStream routines.
+	* doc/html/* : updated accordingly
+
+Sun Feb 28 22:51:33 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, parser.h, parserInternals.h: added a few extra
+	  internal calls to allocate and free parser contexts ...
+	* doc/html/* : updated accordingly
+
+Thu Feb 25 11:52:24 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in, Makefile.am, doc/makefile.am : General changes for
+	  1.0.0 release and including the generated HTML documentation.
+
+Thu Feb 25 09:44:52 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* makefile.am : added parserInternals.h, oops.
+
+Mon Feb 22 11:24:56 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parserInternals.h: added this header giving access to the parser
+	  internal functions.
+	* doc/Makefile.am : added a rebuild target which rebuilds the full
+	  set of documentations
+	* parser.[ch] tree.[ch] valid.[ch]: serious updates w.r.t. parsing
+	  the internal subset. 
+	* *.c *.h: modifications needed to generate the documentation using
+	  gtk-doc, cleanup of functions blocks, reorganisation of struct
+	  declarations.
+
+Tue Feb 16 17:27:29 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* Makefile.am, spec, doc/Makefile.am : upgrading to 0.99.8, fixing
+	  the tar and spec file to include the beginning of the doc.
+
+1999-02-13  Nuno Ferreira  <nmrf@rnl.ist.utl.pt>
+
+	* doc/.cvsignore: Added this file.
+
+Mon Feb  8 19:27:56 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: fixed xmlGetProp to return "" when the attribute
+	  exists, even if the node-list is NULL.
+
+Mon Feb  8 16:10:15 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: patched an error outputting empty attribute values.
+	* Makefile.am and doc/makefile.am: have been updated during the
+	  week-end. Sorry for an empty CVS log, I got a shell problem.
+
+Mon Feb  1 12:10:13 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.h: cleaned up using enums instead of defines
+	* parser.c, valid.[ch]: more work on parsing/output of element
+	  declarations
+
+Sun Jan 31 22:06:48 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* valid.[ch], tree.c, parser.c : more work toward full parsing
+	  of XML DTDs.
+	* README: added informations about mailing-list and on-line
+	  documentation
+
+1999-01-27  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* configure.in (XML_INCLUDEDIR): Use -I not -L for includes.
+
+Sun Jan 17 20:06:36 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, tree.[ch] : more work toward conformance testing,
+	  added a last element to accelerate parsing of very flat structures
+	  started working on internal subset Element content declaration.
+	* valid.[ch] : first cut at adding code toward validation.
+	* previous changes had also small impact on most files, especially
+	  the conformance testing using James Clark test suite.
+
+Sun Jan 17 14:45:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* test/* : updated the examples, most of them were not well
+	           formed (humm), and added rdf2.
+	* result/* : resulting changes in the output.
+
+Sun Dec  6 13:06:58 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: changed the behaviour of xmlGetProp on NULL values.
+
+Sat Dec  5 12:25:09 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: patched a bug in the generation of empty attributes
+
+Fri Nov 27 01:36:54 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* entities.[ch], tree.[ch], tester.c: added copy interfaces
+	  for node/trees/documents/... Biggest problem is namespace
+	  support when copying subtrees.
+
+Sun Nov 15 19:59:47 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, entities.c: improve entities and char ref encoding,
+	  and cleanups of error messages.
+
+Fri Nov 13 13:03:10 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c, entities.c: simple bug hunting done during rpm2html and
+	  rpmfind integration.
+
+Sun Nov  8 13:11:07 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch]: Added interfaces allowing to specify a SAX
+	  handler before parsing.
+
+Sun Nov  8 09:39:17 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: redirrect all errors reporting through the SAX
+	  error function
+
+Wed Nov  4 14:21:54 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* entities.c: rather use HAVE_SNPRINTF and not depend on glib
+	* libtool, tlmain ...: update of the libtool files
+
+1998-11-04  Miguel de Icaza  <miguel@nuclecu.unam.mx>
+
+	* entities.c: Use g_snprintf insteda of snprintf.
+
+Sun Nov  1 14:31:06 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* entities.c, parser.c: debug and cleanup of CharRef handling/saving.
+	  added ent5 test for this purpose.
+	* parser.c, parser.h: formatting, comments and UTF-8 planning.
+
+Fri Oct 30 01:36:52 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: fixed? a strange error due to compression on a GWP
+	  document.
+
+Thu Oct 29 00:48:45 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch]: bug fixing
+	* entities.[ch]: defined a specific type for predefined entities
+	* doc/xml.html: more documentation on the library, how to use it,
+	  overview of the interfaces.
+
+Wed Oct 28 17:56:35 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.[ch]: more cleanup on the API, made the tree mor conformant.
+
+Tue Oct 27 17:54:00 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c: corrected a small bug
+	* doc/xml.html: continuing writing documentation.
+
+Tue Oct 27 17:54:00 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* debugXML.h debugXML.c: added debugging utilities.
+	* tester.c: added --debug switch.
+	* tree.c: patched an incorrect node->type assignment.
+	* parser.c: formatting, ensure that node->doc != NULL in attributes
+
+Tue Oct 27 01:15:39 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.[ch] SAX.c tree.[ch]: large amount of changes to improve
+	  entity support and provide an internal representation close to
+	  DOM one (entity ref nodes, and attribute value as tree). I tried
+	  to preserve the interface but this will surely break some apps
+	  (I have to change rpm2html/rpmfind for example). I had to change
+	  two interfaces, and the generated tree is somewhat different.
+	* doc/* : started documenting the XML library, the tree and
+	  DOM/Corba. This is a first step.
+
+Sat Oct 24 14:23:51 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: Set up the fonctions comment block, boring but useful.
+	* parser.h, SAX.c, parser.c: now attributes are processed through
+	  the SAX interface. The problem is that my SAX interface diverged
+	  quite a bit from the original one, well this is not an official
+	  spec, and translating it from Java to C is hairy anyway...
+
+Tue Oct 20 02:11:21 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* SAX.c, entities.c, tree.c, encoding.c, error.c: Set up the
+	  fonctions comment block, boring but useful.
+
+Sun Oct 18 20:40:58 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* encoding.[ch], Makefile.am: Added the UTF-8, UTF-16 and ISO Latin 1
+	  conversion routines. However they are not yet used to convert the
+	  inputs. The core will run with UTF-8.
+
+Sun Oct 18 15:08:19 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c : make sure that the type id is properly set-up when
+	  a new object is allocated, needed for DOM.
+
+Sat Oct 17 02:43:21 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.h, tree.c: Ok, the main objects in the tree will be native
+	  corba objects, it costs 8 bytes per Node, Attribute and Document
+	  but it simplifies the Corba integration a lot (no extra interface
+	  objects to allocate/free).
+
+Tue Oct 13 21:46:57 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.h, tree.c, parser.c: added prev and doc pointers to Node,
+	  and changed NODEs contants for conformity with DOM Level 1
+
+Wed Oct  7 23:42:46 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* added hooks to keep track of servants when creating objects
+	  xmlDoc and xmlNode (for Corba export).
+
+Sun Oct  4 03:18:09 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* added xml-config script.
+
+Thu Oct  1 16:22:37 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* autogen.sh : applied patch from Frederic Devernay <devernay@istar.fr>
+	  to autoupdate libtool and automake conf files.
+
+1998-09-30  Miguel de Icaza  <miguel@nuclecu.unam.mx>
+
+	* Makefile.am: Use '?' to separate the sed
+	commands as ',' is used when people pass -Wl,something.
+
+Thu Sep 24 15:13:29 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* tree.c, tree.h: added a per-document compression interface.
+
+Tue Sep 22 20:47:38 EDT 1998
+
+	* tree.c, tree.h: added saving with compression and added interfaces
+	  to control the compression level (xmlGetCompressMode,
+	  xmlSetCompressMode) and a new save to filename function (xmlSaveFile).
+
+Mon Sep 21 20:11:13 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* parser.c: corrected a loop for files of size 0
+
+1998-08-20  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* error.h: New file.  Contains prototyes from `error.c'.
+
+Thu Aug 13 19:02:34 1998  Tom Tromey  <tromey@cygnus.com>
+
+	* Makefile.am (xmlincdir): New macro.
+	(xmlinc_HEADERS): Renamed from include_HEADERS.
+
+Thu Aug 13 00:40:14 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* applied small patch on numeric entities from
+	  Christopher Blizzard <blizzard@appliedtheory.com>
+
+Wed Aug 12 23:12:58 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* New release 0.2, removed the old xml_* files so that it's
+	    coherent with the other CVS base (W3C), far better conformance
+	    to standard, new namespaces, decent entities support, beginning
+	    of a SAX-like interface. Nearly nothing left intact, even the
+	    test examples ...
+
+1998-07-30  Christopher Blizzard  <blizzard@appliedtheory.com>
+
+	* .cvsignore: Add .deps dir
+
+Sun Jul 26 17:29:52 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* xml_tree: changed the memory allocation scheme for name in xmlNewNode
+
+Sun Jul 26 00:17:51 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: added test for CPP
+	* AUTHORS, Changelog: the original ones didn't get commited but the
+	    glib ones instead, fixed.
+	* Makefile.am: corrected an error in library naming
+
+Fri Jul 24 16:47:14 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* integrated code developped at W3C
+	* changed the original Copyright
+	* migrated to automake
+	* prefixed the filenames by xml_ to avoid filename clashes
+
+#
+# vim: set enc=utf-8
+#
diff --git a/src/Copyright b/src/Copyright
new file mode 100644
index 0000000..417e955
--- /dev/null
+++ b/src/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/src/DOCBparser.c b/src/DOCBparser.c
new file mode 100644
index 0000000..3573743
--- /dev/null
+++ b/src/DOCBparser.c
@@ -0,0 +1,305 @@
+/*
+ * DOCBparser.c : an attempt to parse SGML Docbook documents
+ *
+ * This is deprecated !!!
+ * Code removed with release 2.6.0 it was broken.
+ * The doc are expect to be migrated to XML DocBook
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+#ifdef LIBXML_DOCB_ENABLED
+
+#include <libxml/xmlerror.h>
+#include <libxml/DOCBparser.h>
+
+/**
+ * docbEncodeEntities:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ * @quoteChar: the quote character to escape (' or ") or zero.
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
+ * plus SGML entities block of chars out.
+ *
+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * 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 octets consumed.
+ */
+int
+docbEncodeEntities(unsigned char *out ATTRIBUTE_UNUSED,
+                   int *outlen ATTRIBUTE_UNUSED,
+                   const unsigned char *in ATTRIBUTE_UNUSED,
+                   int *inlen ATTRIBUTE_UNUSED,
+                   int quoteChar ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbEncodeEntities() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return(-1);
+}
+
+/**
+ * docbParseDocument:
+ * @ctxt:  an SGML parser context
+ * 
+ * parse an SGML document (and build a tree if using the standard SAX
+ * interface).
+ *
+ * Returns 0, -1 in case of error. the parser context is augmented
+ *                as a result of the parsing.
+ */
+
+int
+docbParseDocument(docbParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseDocument() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (xmlParseDocument(ctxt));
+}
+
+/**
+ * docbFreeParserCtxt:
+ * @ctxt:  an SGML parser context
+ *
+ * Free all the memory used by a parser context. However the parsed
+ * document in ctxt->myDoc is not freed.
+ */
+
+void
+docbFreeParserCtxt(docbParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbFreeParserCtxt() deprecated function reached\n");
+        deprecated = 1;
+    }
+    xmlFreeParserCtxt(ctxt);
+}
+
+/**
+ * docbParseChunk:
+ * @ctxt:  an XML parser context
+ * @chunk:  an char array
+ * @size:  the size in byte of the chunk
+ * @terminate:  last chunk indicator
+ *
+ * Parse a Chunk of memory
+ *
+ * Returns zero if no error, the xmlParserErrors otherwise.
+ */
+int
+docbParseChunk(docbParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+               const char *chunk ATTRIBUTE_UNUSED,
+	       int size ATTRIBUTE_UNUSED,
+               int terminate ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseChunk() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlParseChunk(ctxt, chunk, size, terminate));
+}
+
+/**
+ * docbCreatePushParserCtxt:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @chunk:  a pointer to an array of chars
+ * @size:  number of chars in the array
+ * @filename:  an optional file name or URI
+ * @enc:  an optional encoding
+ *
+ * Create a parser context for using the DocBook SGML parser in push mode
+ * To allow content encoding detection, @size should be >= 4
+ * The value of @filename is used for fetching external entities
+ * and error/warning reports.
+ *
+ * Returns the new parser context or NULL
+ */
+docbParserCtxtPtr
+docbCreatePushParserCtxt(docbSAXHandlerPtr sax ATTRIBUTE_UNUSED,
+                         void *user_data ATTRIBUTE_UNUSED,
+                         const char *chunk ATTRIBUTE_UNUSED,
+			 int size ATTRIBUTE_UNUSED,
+			 const char *filename ATTRIBUTE_UNUSED,
+                         xmlCharEncoding enc ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseChunk() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return(xmlCreatePushParserCtxt(sax, user_data, chunk, size, filename));
+}
+
+/**
+ * docbSAXParseDoc:
+ * @cur:  a pointer to an array of xmlChar
+ * @encoding:  a free form C string describing the SGML document encoding, or NULL
+ * @sax:  the SAX handler block
+ * @userData: if using SAX, this pointer will be provided on callbacks. 
+ *
+ * parse an SGML in-memory document and build a tree.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ * 
+ * Returns the resulting document tree
+ */
+
+docbDocPtr
+docbSAXParseDoc(xmlChar * cur ATTRIBUTE_UNUSED,
+                const char *encoding ATTRIBUTE_UNUSED,
+		docbSAXHandlerPtr sax ATTRIBUTE_UNUSED,
+                void *userData ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseChunk() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlSAXParseMemoryWithData(sax, (const char *)cur,
+			  xmlStrlen((const xmlChar *) cur), 0,  userData));
+}
+
+/**
+ * docbParseDoc:
+ * @cur:  a pointer to an array of xmlChar
+ * @encoding:  a free form C string describing the SGML document encoding, or NULL
+ *
+ * parse an SGML in-memory document and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+
+docbDocPtr
+docbParseDoc(xmlChar * cur ATTRIBUTE_UNUSED,
+             const char *encoding ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseChunk() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlParseDoc(cur));
+}
+
+
+/**
+ * docbCreateFileParserCtxt:
+ * @filename:  the filename
+ * @encoding:  the SGML document encoding, or NULL
+ *
+ * Create a parser context for a file content. 
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+docbParserCtxtPtr
+docbCreateFileParserCtxt(const char *filename ATTRIBUTE_UNUSED,
+                         const char *encoding ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbCreateFileParserCtxt() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlCreateFileParserCtxt(filename));
+}
+
+/**
+ * docbSAXParseFile:
+ * @filename:  the filename
+ * @encoding:  a free form C string describing the SGML document encoding, or NULL
+ * @sax:  the SAX handler block
+ * @userData: if using SAX, this pointer will be provided on callbacks. 
+ *
+ * parse an SGML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ *
+ * Returns the resulting document tree
+ */
+
+docbDocPtr
+docbSAXParseFile(const char *filename ATTRIBUTE_UNUSED,
+                 const char *encoding ATTRIBUTE_UNUSED,
+                 docbSAXHandlerPtr sax ATTRIBUTE_UNUSED,
+		 void *userData ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbSAXParseFile() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlSAXParseFileWithData(sax, filename, 0, userData));
+}
+
+/**
+ * docbParseFile:
+ * @filename:  the filename
+ * @encoding:  a free form C string describing document encoding, or NULL
+ *
+ * parse a Docbook SGML file and build a tree. Automatic support for
+ * ZLIB/Compress compressed document is provided by default if found
+ * at compile-time.
+ *
+ * Returns the resulting document tree
+ */
+
+docbDocPtr
+docbParseFile(const char *filename ATTRIBUTE_UNUSED,
+              const char *encoding ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "docbParseFile() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return (xmlParseFile(filename));
+}
+#define bottom_DOCBparser
+#include "elfgcchack.h"
+#endif /* LIBXML_DOCB_ENABLED */
diff --git a/src/HTMLparser.c b/src/HTMLparser.c
new file mode 100644
index 0000000..42dc776
--- /dev/null
+++ b/src/HTMLparser.c
@@ -0,0 +1,6939 @@
+/*
+ * HTMLparser.c : an HTML 4.0 non-verifying parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+#ifdef LIBXML_HTML_ENABLED
+
+#include <string.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/entities.h>
+#include <libxml/encoding.h>
+#include <libxml/valid.h>
+#include <libxml/xmlIO.h>
+#include <libxml/globals.h>
+#include <libxml/uri.h>
+
+#define HTML_MAX_NAMELEN 1000
+#define HTML_PARSER_BIG_BUFFER_SIZE 1000
+#define HTML_PARSER_BUFFER_SIZE 100
+
+/* #define DEBUG */
+/* #define DEBUG_PUSH */
+
+static int htmlOmittedDefaultValue = 1;
+
+xmlChar * htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
+			     xmlChar end, xmlChar  end2, xmlChar end3);
+static void htmlParseComment(htmlParserCtxtPtr ctxt);
+
+/************************************************************************
+ *									*
+ *		Some factorized error routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlErrMemory:
+ * @ctxt:  an HTML parser context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+htmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL) {
+        ctxt->errNo = XML_ERR_NO_MEMORY;
+        ctxt->instate = XML_PARSER_EOF;
+        ctxt->disableSAX = 1;
+    }
+    if (extra)
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+                        NULL, NULL, 0, 0,
+                        "Memory allocation failed : %s\n", extra);
+    else
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
+                        NULL, NULL, 0, 0, "Memory allocation failed\n");
+}
+
+/**
+ * htmlParseErr:
+ * @ctxt:  an HTML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  string infor
+ * @str2:  string infor
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+             const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    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_HTML, error,
+                    XML_ERR_ERROR, NULL, 0,
+		    (const char *) str1, (const char *) str2,
+		    NULL, 0, 0,
+		    msg, str1, str2);
+    if (ctxt != NULL)
+	ctxt->wellFormed = 0;
+}
+
+/**
+ * htmlParseErrInt:
+ * @ctxt:  an HTML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  integer info
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+             const char *msg, int val)
+{
+    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_HTML, error,
+                    XML_ERR_ERROR, NULL, 0, NULL, NULL,
+		    NULL, val, 0, msg, val);
+    if (ctxt != NULL)
+	ctxt->wellFormed = 0;
+}
+
+/************************************************************************
+ *									*
+ *	Parser stacks related functions and macros		*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlnamePush:
+ * @ctxt:  an HTML parser context
+ * @value:  the element name
+ *
+ * Pushes a new element name on top of the name stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+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 * *)
+                         xmlRealloc((xmlChar * *)ctxt->nameTab,
+                                    ctxt->nameMax *
+                                    sizeof(ctxt->nameTab[0]));
+        if (ctxt->nameTab == NULL) {
+            htmlErrMemory(ctxt, NULL);
+            return (0);
+        }
+    }
+    ctxt->nameTab[ctxt->nameNr] = value;
+    ctxt->name = value;
+    return (ctxt->nameNr++);
+}
+/**
+ * htmlnamePop:
+ * @ctxt: an HTML parser context
+ *
+ * Pops the top element name from the name stack
+ *
+ * Returns the name just removed
+ */
+static const xmlChar *
+htmlnamePop(htmlParserCtxtPtr ctxt)
+{
+    const xmlChar *ret;
+
+    if (ctxt->nameNr <= 0)
+        return (NULL);
+    ctxt->nameNr--;
+    if (ctxt->nameNr < 0)
+        return (NULL);
+    if (ctxt->nameNr > 0)
+        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
+    else
+        ctxt->name = NULL;
+    ret = ctxt->nameTab[ctxt->nameNr];
+    ctxt->nameTab[ctxt->nameNr] = NULL;
+    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.
+ *
+ * Dirty macros, i.e. one need to make assumption on the context to use them
+ *
+ *   CUR_PTR return the current pointer to the xmlChar to be parsed.
+ *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
+ *           in ISO-Latin or UTF-8, and the current 16 bit value if compiled
+ *           in UNICODE mode. This should be used internally by the parser
+ *           only to compare to ASCII values otherwise it would break when
+ *           running with UTF-8 encoding.
+ *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
+ *           to compare on ASCII based substring.
+ *   UPP(n)  returns the n'th next xmlChar converted to uppercase. Same as CUR
+ *           it should be used only to compare on ASCII based substring.
+ *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
+ *           strings without newlines within the parser.
+ *
+ * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
+ *
+ *   CURRENT Returns the current char value, with the full decoding of
+ *           UTF-8 if we are using this mode. It returns an int.
+ *   NEXT    Skip to the next character, this does the proper decoding
+ *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
+ *   NEXTL(l) Skip the current unicode character of l xmlChars long.
+ *   COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
+ */
+
+#define UPPER (toupper(*ctxt->input->cur))
+
+#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val)
+
+#define NXT(val) ctxt->input->cur[(val)]
+
+#define UPP(val) (toupper(ctxt->input->cur[(val)]))
+
+#define CUR_PTR ctxt->input->cur
+
+#define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
+		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
+	xmlParserInputShrink(ctxt->input)
+
+#define GROW if ((ctxt->progressive == 0) &&				\
+		 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))	\
+	xmlParserInputGrow(ctxt->input, INPUT_CHUNK)
+
+#define CURRENT ((int) (*ctxt->input->cur))
+
+#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
+
+/* Inported from XML */
+
+/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
+#define CUR ((int) (*ctxt->input->cur))
+#define NEXT xmlNextChar(ctxt)
+
+#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
+
+
+#define NEXTL(l) do {							\
+    if (*(ctxt->input->cur) == '\n') {					\
+	ctxt->input->line++; ctxt->input->col = 1;			\
+    } else ctxt->input->col++;						\
+    ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++;		\
+  } while (0)
+
+/************
+    \
+    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
+    if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
+ ************/
+
+#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
+
+#define COPY_BUF(l,b,i,v)						\
+    if (l == 1) b[i++] = (xmlChar) v;					\
+    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
+ *
+ * The current char value, if using UTF-8 this may actually span multiple
+ * bytes in the input buffer. Implement the end of line normalization:
+ * 2.11 End-of-Line Handling
+ * If the encoding is unspecified, in the case we find an ISO-Latin-1
+ * char, then the encoding converter is plugged in automatically.
+ *
+ * Returns the current char value and its length
+ */
+
+static int
+htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(0);
+
+    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
+	 * From rfc2044: encoding of the Unicode values on UTF-8:
+	 *
+	 * 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
+	 *
+	 * Check for the 0x110000 limit too
+	 */
+	const unsigned char *cur = ctxt->input->cur;
+	unsigned char c;
+	unsigned int val;
+
+	c = *cur;
+	if (c & 0x80) {
+	    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) {
+		    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) {
+			xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                        cur = ctxt->input->cur;
+                    }
+		    if (((c & 0xf8) != 0xf0) ||
+			((cur[3] & 0xc0) != 0x80))
+			goto encoding_error;
+		    /* 4-byte code */
+		    *len = 4;
+		    val = (cur[0] & 0x7) << 18;
+		    val |= (cur[1] & 0x3f) << 12;
+		    val |= (cur[2] & 0x3f) << 6;
+		    val |= cur[3] & 0x3f;
+		} else {
+		  /* 3-byte code */
+		    *len = 3;
+		    val = (cur[0] & 0xf) << 12;
+		    val |= (cur[1] & 0x3f) << 6;
+		    val |= cur[2] & 0x3f;
+		}
+	    } else {
+	      /* 2-byte code */
+		*len = 2;
+		val = (cur[0] & 0x1f) << 6;
+		val |= cur[1] & 0x3f;
+	    }
+	    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);
+	}
+    }
+    /*
+     * Assume it's a fixed length encoding (1) with
+     * a compatible encoding for the ASCII set, since
+     * XML constructs only use < 128 chars
+     */
+    *len = 1;
+    if ((int) *ctxt->input->cur < 0x80)
+	return((int) *ctxt->input->cur);
+
+    /*
+     * Humm this is bad, do an automatic flow conversion
+     */
+    {
+        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:
+    /*
+     * If we detect an UTF8 error that probably mean that the
+     * input encoding didn't get properly advertized in the
+     * declaration header. Report the error and switch the encoding
+     * to ISO-Latin-1 (if you don't like this policy, just declare the
+     * encoding !)
+     */
+    {
+        char buffer[150];
+
+	if (ctxt->input->end - ctxt->input->cur >= 4) {
+	    snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			    ctxt->input->cur[0], ctxt->input->cur[1],
+			    ctxt->input->cur[2], ctxt->input->cur[3]);
+	} else {
+	    snprintf(buffer, 149, "Bytes: 0x%02X\n", ctxt->input->cur[0]);
+	}
+	htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+		     "Input is not proper UTF-8, indicate encoding !\n",
+		     BAD_CAST buffer, NULL);
+    }
+
+    ctxt->charset = XML_CHAR_ENCODING_8859_1;
+    *len = 1;
+    return((int) *ctxt->input->cur);
+}
+
+/**
+ * htmlSkipBlankChars:
+ * @ctxt:  the HTML parser context
+ *
+ * skip all blanks character found at that point in the input streams.
+ *
+ * Returns the number of space chars skipped
+ */
+
+static int
+htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
+    int res = 0;
+
+    while (IS_BLANK_CH(*(ctxt->input->cur))) {
+	if ((*ctxt->input->cur == 0) &&
+	    (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
+		xmlPopInput(ctxt);
+	} else {
+	    if (*(ctxt->input->cur) == '\n') {
+		ctxt->input->line++; ctxt->input->col = 1;
+	    } else ctxt->input->col++;
+	    ctxt->input->cur++;
+	    ctxt->nbChars++;
+	    if (*ctxt->input->cur == 0)
+		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+	}
+	res++;
+    }
+    return(res);
+}
+
+
+
+/************************************************************************
+ *									*
+ *	The list of HTML elements and their properties		*
+ *									*
+ ************************************************************************/
+
+/*
+ *  Start Tag: 1 means the start tag can be ommited
+ *  End Tag:   1 means the end tag can be ommited
+ *             2 means it's forbidden (empty elements)
+ *             3 means the tag is stylistic and should be closed easily
+ *  Depr:      this element is deprecated
+ *  DTD:       1 means that this element is valid only in the Loose DTD
+ *             2 means that this element is valid only in the Frameset DTD
+ *
+ * Name,Start Tag,End Tag,Save End,Empty,Deprecated,DTD,inline,Description
+	, subElements , impliedsubelt , Attributes, userdata
+ */
+
+/* Definitions and a couple of vars for HTML Elements */
+
+#define FONTSTYLE "tt", "i", "b", "u", "s", "strike", "big", "small"
+#define NB_FONTSTYLE 8
+#define PHRASE "em", "strong", "dfn", "code", "samp", "kbd", "var", "cite", "abbr", "acronym"
+#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 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 NB_BLOCK NB_HEADING + NB_LIST + 14
+#define FORMCTRL "input", "select", "textarea", "label", "button"
+#define NB_FORMCTRL 5
+#define PCDATA
+#define NB_PCDATA 0
+#define HEADING "h1", "h2", "h3", "h4", "h5", "h6"
+#define NB_HEADING 6
+#define LIST "ul", "ol", "dir", "menu"
+#define NB_LIST 4
+#define MODIFIER
+#define NB_MODIFIER 0
+#define FLOW BLOCK,INLINE
+#define NB_FLOW NB_BLOCK + NB_INLINE
+#define EMPTY NULL
+
+
+static const char* const html_flow[] = { FLOW, NULL } ;
+static const char* const html_inline[] = { INLINE, NULL } ;
+
+/* placeholders: elts with content but no subelements */
+static const char* const html_pcdata[] = { NULL } ;
+#define html_cdata html_pcdata
+
+
+/* ... and for HTML Attributes */
+
+#define COREATTRS "id", "class", "style", "title"
+#define NB_COREATTRS 4
+#define I18N "lang", "dir"
+#define NB_I18N 2
+#define EVENTS "onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover", "onmouseout", "onkeypress", "onkeydown", "onkeyup"
+#define NB_EVENTS 9
+#define ATTRS COREATTRS,I18N,EVENTS
+#define NB_ATTRS NB_NB_COREATTRS + NB_I18N + NB_EVENTS
+#define CELLHALIGN "align", "char", "charoff"
+#define NB_CELLHALIGN 3
+#define CELLVALIGN "valign"
+#define NB_CELLVALIGN 1
+
+static const char* const html_attrs[] = { ATTRS, NULL } ;
+static const char* const core_i18n_attrs[] = { COREATTRS, I18N, NULL } ;
+static const char* const core_attrs[] = { COREATTRS, NULL } ;
+static const char* const i18n_attrs[] = { I18N, NULL } ;
+
+
+/* Other declarations that should go inline ... */
+static const char* const a_attrs[] = { ATTRS, "charset", "type", "name",
+	"href", "hreflang", "rel", "rev", "accesskey", "shape", "coords",
+	"tabindex", "onfocus", "onblur", NULL } ;
+static const char* const target_attr[] = { "target", NULL } ;
+static const char* const rows_cols_attr[] = { "rows", "cols", NULL } ;
+static const char* const alt_attr[] = { "alt", NULL } ;
+static const char* const src_alt_attrs[] = { "src", "alt", NULL } ;
+static const char* const href_attrs[] = { "href", NULL } ;
+static const char* const clear_attrs[] = { "clear", NULL } ;
+static const char* const inline_p[] = { INLINE, "p", NULL } ;
+
+static const char* const flow_param[] = { FLOW, "param", NULL } ;
+static const char* const applet_attrs[] = { COREATTRS , "codebase",
+		"archive", "alt", "name", "height", "width", "align",
+		"hspace", "vspace", NULL } ;
+static const char* const area_attrs[] = { "shape", "coords", "href", "nohref",
+	"tabindex", "accesskey", "onfocus", "onblur", NULL } ;
+static const char* const basefont_attrs[] =
+	{ "id", "size", "color", "face", NULL } ;
+static const char* const quote_attrs[] = { ATTRS, "cite", NULL } ;
+static const char* const body_contents[] = { FLOW, "ins", "del", NULL } ;
+static const char* const body_attrs[] = { ATTRS, "onload", "onunload", NULL } ;
+static const char* const body_depr[] = { "background", "bgcolor", "text",
+	"link", "vlink", "alink", NULL } ;
+static const char* const button_attrs[] = { ATTRS, "name", "value", "type",
+	"disabled", "tabindex", "accesskey", "onfocus", "onblur", NULL } ;
+
+
+static const char* const col_attrs[] = { ATTRS, "span", "width", CELLHALIGN, CELLVALIGN, NULL } ;
+static const char* const col_elt[] = { "col", NULL } ;
+static const char* const edit_attrs[] = { ATTRS, "datetime", "cite", NULL } ;
+static const char* const compact_attrs[] = { ATTRS, "compact", NULL } ;
+static const char* const dl_contents[] = { "dt", "dd", NULL } ;
+static const char* const compact_attr[] = { "compact", NULL } ;
+static const char* const label_attr[] = { "label", NULL } ;
+static const char* const fieldset_contents[] = { FLOW, "legend" } ;
+static const char* const font_attrs[] = { COREATTRS, I18N, "size", "color", "face" , NULL } ;
+static const char* const form_contents[] = { HEADING, LIST, INLINE, "pre", "p", "div", "center", "noscript", "noframes", "blockquote", "isindex", "hr", "table", "fieldset", "address", NULL } ;
+static const char* const form_attrs[] = { ATTRS, "method", "enctype", "accept", "name", "onsubmit", "onreset", "accept-charset", NULL } ;
+static const char* const frame_attrs[] = { COREATTRS, "longdesc", "name", "src", "frameborder", "marginwidth", "marginheight", "noresize", "scrolling" , NULL } ;
+static const char* const frameset_attrs[] = { COREATTRS, "rows", "cols", "onload", "onunload", NULL } ;
+static const char* const frameset_contents[] = { "frameset", "frame", "noframes", NULL } ;
+static const char* const head_attrs[] = { I18N, "profile", NULL } ;
+static const char* const head_contents[] = { "title", "isindex", "base", "script", "style", "meta", "link", "object", NULL } ;
+static const char* const hr_depr[] = { "align", "noshade", "size", "width", NULL } ;
+static const char* const version_attr[] = { "version", NULL } ;
+static const char* const html_content[] = { "head", "body", "frameset", NULL } ;
+static const char* const iframe_attrs[] = { COREATTRS, "longdesc", "name", "src", "frameborder", "marginwidth", "marginheight", "scrolling", "align", "height", "width", NULL } ;
+static const char* const img_attrs[] = { ATTRS, "longdesc", "name", "height", "width", "usemap", "ismap", NULL } ;
+static const char* const embed_attrs[] = { COREATTRS, "align", "alt", "border", "code", "codebase", "frameborder", "height", "hidden", "hspace", "name", "palette", "pluginspace", "pluginurl", "src", "type", "units", "vspace", "width", NULL } ;
+static const char* const input_attrs[] = { ATTRS, "type", "name", "value", "checked", "disabled", "readonly", "size", "maxlength", "src", "alt", "usemap", "ismap", "tabindex", "accesskey", "onfocus", "onblur", "onselect", "onchange", "accept", NULL } ;
+static const char* const prompt_attrs[] = { COREATTRS, I18N, "prompt", NULL } ;
+static const char* const label_attrs[] = { ATTRS, "for", "accesskey", "onfocus", "onblur", NULL } ;
+static const char* const legend_attrs[] = { ATTRS, "accesskey", NULL } ;
+static const char* const align_attr[] = { "align", NULL } ;
+static const char* const link_attrs[] = { ATTRS, "charset", "href", "hreflang", "type", "rel", "rev", "media", NULL } ;
+static const char* const map_contents[] = { BLOCK, "area", NULL } ;
+static const char* const name_attr[] = { "name", NULL } ;
+static const char* const action_attr[] = { "action", NULL } ;
+static const char* const blockli_elt[] = { BLOCK, "li", NULL } ;
+static const char* const meta_attrs[] = { I18N, "http-equiv", "name", "scheme", NULL } ;
+static const char* const content_attr[] = { "content", NULL } ;
+static const char* const type_attr[] = { "type", NULL } ;
+static const char* const noframes_content[] = { "body", FLOW MODIFIER, NULL } ;
+static const char* const object_contents[] = { FLOW, "param", NULL } ;
+static const char* const object_attrs[] = { ATTRS, "declare", "classid", "codebase", "data", "type", "codetype", "archive", "standby", "height", "width", "usemap", "name", "tabindex", NULL } ;
+static const char* const object_depr[] = { "align", "border", "hspace", "vspace", NULL } ;
+static const char* const ol_attrs[] = { "type", "compact", "start", NULL} ;
+static const char* const option_elt[] = { "option", NULL } ;
+static const char* const optgroup_attrs[] = { ATTRS, "disabled", NULL } ;
+static const char* const option_attrs[] = { ATTRS, "disabled", "label", "selected", "value", NULL } ;
+static const char* const param_attrs[] = { "id", "value", "valuetype", "type", NULL } ;
+static const char* const width_attr[] = { "width", NULL } ;
+static const char* const pre_content[] = { PHRASE, "tt", "i", "b", "u", "s", "strike", "a", "br", "script", "map", "q", "span", "bdo", "iframe", NULL } ;
+static const char* const script_attrs[] = { "charset", "src", "defer", "event", "for", NULL } ;
+static const char* const language_attr[] = { "language", NULL } ;
+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_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 } ;
+static const char* const talign_attrs[] = { ATTRS, CELLHALIGN, CELLVALIGN, NULL} ;
+static const char* const th_td_depr[] = { "nowrap", "bgcolor", "width", "height", NULL } ;
+static const char* const th_td_attr[] = { ATTRS, "abbr", "axis", "headers", "scope", "rowspan", "colspan", CELLHALIGN, CELLVALIGN, NULL } ;
+static const char* const textarea_attrs[] = { ATTRS, "name", "disabled", "readonly", "tabindex", "accesskey", "onfocus", "onblur", "onselect", "onchange", NULL } ;
+static const char* const tr_contents[] = { "th", "td", NULL } ;
+static const char* const bgcolor_attr[] = { "bgcolor", NULL } ;
+static const char* const li_elt[] = { "li", NULL } ;
+static const char* const ul_depr[] = { "type", "compact", NULL} ;
+static const char* const dir_attr[] = { "dir", NULL} ;
+
+#define DECL (const char**)
+
+static const htmlElemDesc
+html40ElementTable[] = {
+{ "a",		0, 0, 0, 0, 0, 0, 1, "anchor ",
+	DECL html_inline , NULL , DECL a_attrs , DECL target_attr, NULL
+},
+{ "abbr",	0, 0, 0, 0, 0, 0, 1, "abbreviated form",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "acronym",	0, 0, 0, 0, 0, 0, 1, "",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "address",	0, 0, 0, 0, 0, 0, 0, "information on author ",
+	DECL inline_p  , NULL , DECL html_attrs, NULL, NULL
+},
+{ "applet",	0, 0, 0, 0, 1, 1, 2, "java applet ",
+	DECL flow_param , NULL , NULL , DECL applet_attrs, NULL
+},
+{ "area",	0, 2, 2, 1, 0, 0, 0, "client-side image map area ",
+	EMPTY ,  NULL , DECL area_attrs , DECL target_attr, DECL alt_attr
+},
+{ "b",		0, 3, 0, 0, 0, 0, 1, "bold text style",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "base",	0, 2, 2, 1, 0, 0, 0, "document base uri ",
+	EMPTY , NULL , NULL , DECL target_attr, DECL href_attrs
+},
+{ "basefont",	0, 2, 2, 1, 1, 1, 1, "base font size " ,
+	EMPTY , NULL , NULL, DECL basefont_attrs, NULL
+},
+{ "bdo",	0, 0, 0, 0, 0, 0, 1, "i18n bidi over-ride ",
+	DECL html_inline , NULL , DECL core_i18n_attrs, NULL, DECL dir_attr
+},
+{ "big",	0, 3, 0, 0, 0, 0, 1, "large text style",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "blockquote",	0, 0, 0, 0, 0, 0, 0, "long quotation ",
+	DECL html_flow , NULL , DECL quote_attrs , NULL, NULL
+},
+{ "body",	1, 1, 0, 0, 0, 0, 0, "document body ",
+	DECL body_contents , "div" , DECL body_attrs, DECL body_depr, NULL
+},
+{ "br",		0, 2, 2, 1, 0, 0, 1, "forced line break ",
+	EMPTY , NULL , DECL core_attrs, DECL clear_attrs , NULL
+},
+{ "button",	0, 0, 0, 0, 0, 0, 2, "push button ",
+	DECL html_flow MODIFIER , NULL , DECL button_attrs, NULL, NULL
+},
+{ "caption",	0, 0, 0, 0, 0, 0, 0, "table caption ",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "center",	0, 3, 0, 0, 1, 1, 0, "shorthand for div align=center ",
+	DECL html_flow , NULL , NULL, DECL html_attrs, NULL
+},
+{ "cite",	0, 0, 0, 0, 0, 0, 1, "citation",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "code",	0, 0, 0, 0, 0, 0, 1, "computer code fragment",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "col",	0, 2, 2, 1, 0, 0, 0, "table column ",
+	EMPTY , NULL , DECL col_attrs , NULL, NULL
+},
+{ "colgroup",	0, 1, 0, 0, 0, 0, 0, "table column group ",
+	DECL col_elt , "col" , DECL col_attrs , NULL, NULL
+},
+{ "dd",		0, 1, 0, 0, 0, 0, 0, "definition description ",
+	DECL html_flow , NULL , DECL html_attrs, NULL, NULL
+},
+{ "del",	0, 0, 0, 0, 0, 0, 2, "deleted text ",
+	DECL html_flow , NULL , DECL edit_attrs , NULL, NULL
+},
+{ "dfn",	0, 0, 0, 0, 0, 0, 1, "instance definition",
+	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
+},
+{ "dir",	0, 0, 0, 0, 1, 1, 0, "directory list",
+	DECL blockli_elt, "li" , NULL, DECL compact_attrs, NULL
+},
+{ "div",	0, 0, 0, 0, 0, 0, 0, "generic language/style container",
+	DECL html_flow, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "dl",		0, 0, 0, 0, 0, 0, 0, "definition list ",
+	DECL dl_contents , "dd" , DECL html_attrs, DECL compact_attr, NULL
+},
+{ "dt",		0, 1, 0, 0, 0, 0, 0, "definition term ",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "em",		0, 3, 0, 0, 0, 0, 1, "emphasis",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "embed",	0, 1, 0, 0, 1, 1, 1, "generic embedded object ",
+	EMPTY, NULL, DECL embed_attrs, NULL, NULL
+},
+{ "fieldset",	0, 0, 0, 0, 0, 0, 0, "form control group ",
+	DECL fieldset_contents , NULL, DECL html_attrs, NULL, NULL
+},
+{ "font",	0, 3, 0, 0, 1, 1, 1, "local change to font ",
+	DECL html_inline, NULL, NULL, DECL font_attrs, NULL
+},
+{ "form",	0, 0, 0, 0, 0, 0, 0, "interactive form ",
+	DECL form_contents, "fieldset", DECL form_attrs , DECL target_attr, DECL action_attr
+},
+{ "frame",	0, 2, 2, 1, 0, 2, 0, "subwindow " ,
+	EMPTY, NULL, NULL, DECL frame_attrs, NULL
+},
+{ "frameset",	0, 0, 0, 0, 0, 2, 0, "window subdivision" ,
+	DECL frameset_contents, "noframes" , NULL , DECL frameset_attrs, NULL
+},
+{ "h1",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "h2",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "h3",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "h4",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "h5",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "h6",		0, 0, 0, 0, 0, 0, 0, "heading ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "head",	1, 1, 0, 0, 0, 0, 0, "document head ",
+	DECL head_contents, NULL, DECL head_attrs, NULL, NULL
+},
+{ "hr",		0, 2, 2, 1, 0, 0, 0, "horizontal rule " ,
+	EMPTY, NULL, DECL html_attrs, DECL hr_depr, NULL
+},
+{ "html",	1, 1, 0, 0, 0, 0, 0, "document root element ",
+	DECL html_content , NULL , DECL i18n_attrs, DECL version_attr, NULL
+},
+{ "i",		0, 3, 0, 0, 0, 0, 1, "italic text style",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "iframe",	0, 0, 0, 0, 0, 1, 2, "inline subwindow ",
+	DECL html_flow, NULL, NULL, DECL iframe_attrs, NULL
+},
+{ "img",	0, 2, 2, 1, 0, 0, 1, "embedded image ",
+	EMPTY, NULL, DECL img_attrs, DECL align_attr, DECL src_alt_attrs
+},
+{ "input",	0, 2, 2, 1, 0, 0, 1, "form control ",
+	EMPTY, NULL, DECL input_attrs , DECL align_attr, NULL
+},
+{ "ins",	0, 0, 0, 0, 0, 0, 2, "inserted text",
+	DECL html_flow, NULL, DECL edit_attrs, NULL, NULL
+},
+{ "isindex",	0, 2, 2, 1, 1, 1, 0, "single line prompt ",
+	EMPTY, NULL, NULL, DECL prompt_attrs, NULL
+},
+{ "kbd",	0, 0, 0, 0, 0, 0, 1, "text to be entered by the user",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "label",	0, 0, 0, 0, 0, 0, 1, "form field label text ",
+	DECL html_inline MODIFIER, NULL, DECL label_attrs , NULL, NULL
+},
+{ "legend",	0, 0, 0, 0, 0, 0, 0, "fieldset legend ",
+	DECL html_inline, NULL, DECL legend_attrs , DECL align_attr, NULL
+},
+{ "li",		0, 1, 1, 0, 0, 0, 0, "list item ",
+	DECL html_flow, NULL, DECL html_attrs, NULL, NULL
+},
+{ "link",	0, 2, 2, 1, 0, 0, 0, "a media-independent link ",
+	EMPTY, NULL, DECL link_attrs, DECL target_attr, NULL
+},
+{ "map",	0, 0, 0, 0, 0, 0, 2, "client-side image map ",
+	DECL map_contents , NULL, DECL html_attrs , NULL, DECL name_attr
+},
+{ "menu",	0, 0, 0, 0, 1, 1, 0, "menu list ",
+	DECL blockli_elt , NULL, NULL, DECL compact_attrs, NULL
+},
+{ "meta",	0, 2, 2, 1, 0, 0, 0, "generic metainformation ",
+	EMPTY, NULL, DECL meta_attrs , NULL , DECL content_attr
+},
+{ "noframes",	0, 0, 0, 0, 0, 2, 0, "alternate content container for non frame-based rendering ",
+	DECL noframes_content, "body" , DECL html_attrs, NULL, NULL
+},
+{ "noscript",	0, 0, 0, 0, 0, 0, 0, "alternate content container for non script-based rendering ",
+	DECL html_flow, "div", DECL html_attrs, NULL, NULL
+},
+{ "object",	0, 0, 0, 0, 0, 0, 2, "generic embedded object ",
+	DECL object_contents , "div" , DECL object_attrs, DECL object_depr, NULL
+},
+{ "ol",		0, 0, 0, 0, 0, 0, 0, "ordered list ",
+	DECL li_elt , "li" , DECL html_attrs, DECL ol_attrs, NULL
+},
+{ "optgroup",	0, 0, 0, 0, 0, 0, 0, "option group ",
+	DECL option_elt , "option", DECL optgroup_attrs, NULL, DECL label_attr
+},
+{ "option",	0, 1, 0, 0, 0, 0, 0, "selectable choice " ,
+	DECL html_pcdata, NULL, DECL option_attrs, NULL, NULL
+},
+{ "p",		0, 1, 0, 0, 0, 0, 0, "paragraph ",
+	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
+},
+{ "param",	0, 2, 2, 1, 0, 0, 0, "named property value ",
+	EMPTY, NULL, DECL param_attrs, NULL, DECL name_attr
+},
+{ "pre",	0, 0, 0, 0, 0, 0, 0, "preformatted text ",
+	DECL pre_content, NULL, DECL html_attrs, DECL width_attr, NULL
+},
+{ "q",		0, 0, 0, 0, 0, 0, 1, "short inline quotation ",
+	DECL html_inline, NULL, DECL quote_attrs, NULL, NULL
+},
+{ "s",		0, 3, 0, 0, 1, 1, 1, "strike-through text style",
+	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
+},
+{ "samp",	0, 0, 0, 0, 0, 0, 1, "sample program output, scripts, etc.",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "script",	0, 0, 0, 0, 0, 0, 2, "script statements ",
+	DECL html_cdata, NULL, DECL script_attrs, DECL language_attr, DECL type_attr
+},
+{ "select",	0, 0, 0, 0, 0, 0, 1, "option selector ",
+	DECL select_content, NULL, DECL select_attrs, NULL, NULL
+},
+{ "small",	0, 3, 0, 0, 0, 0, 1, "small text style",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "span",	0, 0, 0, 0, 0, 0, 1, "generic language/style container ",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "strike",	0, 3, 0, 0, 1, 1, 1, "strike-through text",
+	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
+},
+{ "strong",	0, 3, 0, 0, 0, 0, 1, "strong emphasis",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "style",	0, 0, 0, 0, 0, 0, 0, "style info ",
+	DECL html_cdata, NULL, DECL style_attrs, NULL, DECL type_attr
+},
+{ "sub",	0, 3, 0, 0, 0, 0, 1, "subscript",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "sup",	0, 3, 0, 0, 0, 0, 1, "superscript ",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "table",	0, 0, 0, 0, 0, 0, 0, "",
+	DECL table_contents , "tr" , DECL table_attrs , DECL table_depr, NULL
+},
+{ "tbody",	1, 0, 0, 0, 0, 0, 0, "table body ",
+	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
+},
+{ "td",		0, 0, 0, 0, 0, 0, 0, "table data cell",
+	DECL html_flow, NULL, DECL th_td_attr, DECL th_td_depr, NULL
+},
+{ "textarea",	0, 0, 0, 0, 0, 0, 1, "multi-line text field ",
+	DECL html_pcdata, NULL, DECL textarea_attrs, NULL, DECL rows_cols_attr
+},
+{ "tfoot",	0, 1, 0, 0, 0, 0, 0, "table footer ",
+	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
+},
+{ "th",		0, 1, 0, 0, 0, 0, 0, "table header cell",
+	DECL html_flow, NULL, DECL th_td_attr, DECL th_td_depr, NULL
+},
+{ "thead",	0, 1, 0, 0, 0, 0, 0, "table header ",
+	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
+},
+{ "title",	0, 0, 0, 0, 0, 0, 0, "document title ",
+	DECL html_pcdata, NULL, DECL i18n_attrs, NULL, NULL
+},
+{ "tr",		0, 0, 0, 0, 0, 0, 0, "table row ",
+	DECL tr_contents , "td" , DECL talign_attrs, DECL bgcolor_attr, NULL
+},
+{ "tt",		0, 3, 0, 0, 0, 0, 1, "teletype or monospaced text style",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "u",		0, 3, 0, 0, 1, 1, 1, "underlined text style",
+	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
+},
+{ "ul",		0, 0, 0, 0, 0, 0, 0, "unordered list ",
+	DECL li_elt , "li" , DECL html_attrs, DECL ul_depr, NULL
+},
+{ "var",	0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument",
+	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+}
+};
+
+/*
+ * start tags that imply the end of current element
+ */
+static const char * const htmlStartClose[] = {
+"form",		"form", "p", "hr", "h1", "h2", "h3", "h4", "h5", "h6",
+		"dl", "ul", "ol", "menu", "dir", "address", "pre",
+		"listing", "xmp", "head", NULL,
+"head",		"p", NULL,
+"title",	"p", NULL,
+"body",		"head", "style", "link", "title", "p", NULL,
+"frameset",	"head", "style", "link", "title", "p", NULL,
+"li",		"p", "h1", "h2", "h3", "h4", "h5", "h6", "dl", "address",
+		"pre", "listing", "xmp", "head", "li", NULL,
+"hr",		"p", "head", NULL,
+"h1",		"p", "head", NULL,
+"h2",		"p", "head", NULL,
+"h3",		"p", "head", NULL,
+"h4",		"p", "head", NULL,
+"h5",		"p", "head", NULL,
+"h6",		"p", "head", NULL,
+"dir",		"p", "head", NULL,
+"address",	"p", "head", "ul", NULL,
+"pre",		"p", "head", "ul", NULL,
+"listing",	"p", "head", NULL,
+"xmp",		"p", "head", NULL,
+"blockquote",	"p", "head", NULL,
+"dl",		"p", "dt", "menu", "dir", "address", "pre", "listing",
+		"xmp", "head", NULL,
+"dt",		"p", "menu", "dir", "address", "pre", "listing", "xmp",
+                "head", "dd", NULL,
+"dd",		"p", "menu", "dir", "address", "pre", "listing", "xmp",
+                "head", "dt", NULL,
+"ul",		"p", "head", "ol", "menu", "dir", "address", "pre",
+		"listing", "xmp", NULL,
+"ol",		"p", "head", "ul", NULL,
+"menu",		"p", "head", "ul", 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,
+"a",		"a", NULL,
+"caption",	"p", NULL,
+"colgroup",	"caption", "colgroup", "col", "p", NULL,
+"col",		"caption", "col", "p", NULL,
+"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,
+"tr",		"th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
+"thead",	"caption", "col", "colgroup", NULL,
+"tfoot",	"th", "td", "tr", "caption", "col", "colgroup", "thead",
+		"tbody", "p", NULL,
+"tbody",	"th", "td", "tr", "caption", "col", "colgroup", "thead",
+		"tfoot", "tbody", "p", NULL,
+"optgroup",	"option", NULL,
+"option",	"option", NULL,
+"fieldset",	"legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6",
+		"pre", "listing", "xmp", "a", NULL,
+NULL
+};
+
+/*
+ * The list of HTML elements which are supposed not to have
+ * CDATA content and where a p element will be implied
+ *
+ * TODO: extend that list by reading the HTML SGML DTD on
+ *       implied paragraph
+ */
+static const char *const htmlNoContentElements[] = {
+    "html",
+    "head",
+    NULL
+};
+
+/*
+ * The list of HTML attributes which are of content %Script;
+ * NOTE: when adding ones, check htmlIsScriptAttribute() since
+ *       it assumes the name starts with 'on'
+ */
+static const char *const htmlScriptAttributes[] = {
+    "onclick",
+    "ondblclick",
+    "onmousedown",
+    "onmouseup",
+    "onmouseover",
+    "onmousemove",
+    "onmouseout",
+    "onkeypress",
+    "onkeydown",
+    "onkeyup",
+    "onload",
+    "onunload",
+    "onfocus",
+    "onblur",
+    "onsubmit",
+    "onrest",
+    "onchange",
+    "onselect"
+};
+
+/*
+ * This table is used by the htmlparser to know what to do with
+ * broken html pages. By assigning different priorities to different
+ * 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;
+    int priority;
+} elementPriority;
+
+static const elementPriority htmlEndPriority[] = {
+    {"div",   150},
+    {"td",    160},
+    {"th",    160},
+    {"tr",    170},
+    {"thead", 180},
+    {"tbody", 180},
+    {"tfoot", 180},
+    {"table", 190},
+    {"head",  200},
+    {"body",  200},
+    {"html",  220},
+    {NULL,    100} /* Default priority */
+};
+
+static const char** htmlStartCloseIndex[100];
+static int htmlStartCloseIndexinitialized = 0;
+
+/************************************************************************
+ *									*
+ *	functions to handle HTML specific data			*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlInitAutoClose:
+ *
+ * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
+ * This is not reentrant. Call xmlInitParser() once before processing in
+ * case of use in multithreaded programs.
+ */
+void
+htmlInitAutoClose(void) {
+    int indx, i = 0;
+
+    if (htmlStartCloseIndexinitialized) return;
+
+    for (indx = 0;indx < 100;indx ++) htmlStartCloseIndex[indx] = NULL;
+    indx = 0;
+    while ((htmlStartClose[i] != NULL) && (indx < 100 - 1)) {
+        htmlStartCloseIndex[indx++] = (const char**) &htmlStartClose[i];
+	while (htmlStartClose[i] != NULL) i++;
+	i++;
+    }
+    htmlStartCloseIndexinitialized = 1;
+}
+
+/**
+ * htmlTagLookup:
+ * @tag:  The tag name in lowercase
+ *
+ * Lookup the HTML tag in the ElementTable
+ *
+ * Returns the related htmlElemDescPtr or NULL if not found.
+ */
+const htmlElemDesc *
+htmlTagLookup(const xmlChar *tag) {
+    unsigned int i;
+
+    for (i = 0; i < (sizeof(html40ElementTable) /
+                     sizeof(html40ElementTable[0]));i++) {
+        if (!xmlStrcasecmp(tag, BAD_CAST html40ElementTable[i].name))
+	    return((htmlElemDescPtr) &html40ElementTable[i]);
+    }
+    return(NULL);
+}
+
+/**
+ * htmlGetEndPriority:
+ * @name: The name of the element to look up the priority for.
+ *
+ * Return value: The "endtag" priority.
+ **/
+static int
+htmlGetEndPriority (const xmlChar *name) {
+    int i = 0;
+
+    while ((htmlEndPriority[i].name != NULL) &&
+	   (!xmlStrEqual((const xmlChar *)htmlEndPriority[i].name, name)))
+	i++;
+
+    return(htmlEndPriority[i].priority);
+}
+
+
+/**
+ * htmlCheckAutoClose:
+ * @newtag:  The new tag name
+ * @oldtag:  The old tag name
+ *
+ * Checks whether the new tag is one of the registered valid tags for
+ * closing old.
+ * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
+ *
+ * Returns 0 if no, 1 if yes.
+ */
+static int
+htmlCheckAutoClose(const xmlChar * newtag, const xmlChar * oldtag)
+{
+    int i, indx;
+    const char **closed = NULL;
+
+    if (htmlStartCloseIndexinitialized == 0)
+        htmlInitAutoClose();
+
+    /* inefficient, but not a big deal */
+    for (indx = 0; indx < 100; indx++) {
+        closed = htmlStartCloseIndex[indx];
+        if (closed == NULL)
+            return (0);
+        if (xmlStrEqual(BAD_CAST * closed, newtag))
+            break;
+    }
+
+    i = closed - htmlStartClose;
+    i++;
+    while (htmlStartClose[i] != NULL) {
+        if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) {
+            return (1);
+        }
+        i++;
+    }
+    return (0);
+}
+
+/**
+ * htmlAutoCloseOnClose:
+ * @ctxt:  an HTML parser context
+ * @newtag:  The new tag name
+ * @force:  force the tag closure
+ *
+ * The HTML DTD allows an ending tag to implicitly close other tags.
+ */
+static void
+htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
+{
+    const htmlElemDesc *info;
+    int i, priority;
+
+    priority = htmlGetEndPriority(newtag);
+
+    for (i = (ctxt->nameNr - 1); i >= 0; i--) {
+
+        if (xmlStrEqual(newtag, ctxt->nameTab[i]))
+            break;
+        /*
+         * 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
+         */
+        if (htmlGetEndPriority(ctxt->nameTab[i]) > priority)
+            return;
+    }
+    if (i < 0)
+        return;
+
+    while (!xmlStrEqual(newtag, ctxt->name)) {
+        info = htmlTagLookup(ctxt->name);
+        if ((info != NULL) && (info->endTag == 3)) {
+            htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+	                 "Opening and ending tag mismatch: %s and %s\n",
+			 newtag, ctxt->name);
+        }
+        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+            ctxt->sax->endElement(ctxt->userData, ctxt->name);
+	htmlnamePop(ctxt);
+    }
+}
+
+/**
+ * htmlAutoCloseOnEnd:
+ * @ctxt:  an HTML parser context
+ *
+ * Close all remaining tags at the end of the stream
+ */
+static void
+htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt)
+{
+    int i;
+
+    if (ctxt->nameNr == 0)
+        return;
+    for (i = (ctxt->nameNr - 1); i >= 0; i--) {
+        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+            ctxt->sax->endElement(ctxt->userData, ctxt->name);
+	htmlnamePop(ctxt);
+    }
+}
+
+/**
+ * htmlAutoClose:
+ * @ctxt:  an HTML parser context
+ * @newtag:  The new tag name or NULL
+ *
+ * The HTML DTD allows a tag to implicitly close other tags.
+ * The list is kept in htmlStartClose array. This function is
+ * 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
+ */
+static void
+htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
+{
+    while ((newtag != NULL) && (ctxt->name != NULL) &&
+           (htmlCheckAutoClose(newtag, ctxt->name))) {
+        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+            ctxt->sax->endElement(ctxt->userData, ctxt->name);
+	htmlnamePop(ctxt);
+    }
+    if (newtag == NULL) {
+        htmlAutoCloseOnEnd(ctxt);
+        return;
+    }
+    while ((newtag == NULL) && (ctxt->name != NULL) &&
+           ((xmlStrEqual(ctxt->name, BAD_CAST "head")) ||
+            (xmlStrEqual(ctxt->name, BAD_CAST "body")) ||
+            (xmlStrEqual(ctxt->name, BAD_CAST "html")))) {
+        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+            ctxt->sax->endElement(ctxt->userData, ctxt->name);
+	htmlnamePop(ctxt);
+    }
+}
+
+/**
+ * htmlAutoCloseTag:
+ * @doc:  the HTML document
+ * @name:  The tag name
+ * @elem:  the HTML element
+ *
+ * The HTML DTD allows a tag to implicitly close other tags.
+ * The list is kept in htmlStartClose array. This function checks
+ * if the element or one of it's children would autoclose the
+ * given tag.
+ *
+ * Returns 1 if autoclose, 0 otherwise
+ */
+int
+htmlAutoCloseTag(htmlDocPtr doc, const xmlChar *name, htmlNodePtr elem) {
+    htmlNodePtr child;
+
+    if (elem == NULL) return(1);
+    if (xmlStrEqual(name, elem->name)) return(0);
+    if (htmlCheckAutoClose(elem->name, name)) return(1);
+    child = elem->children;
+    while (child != NULL) {
+        if (htmlAutoCloseTag(doc, name, child)) return(1);
+	child = child->next;
+    }
+    return(0);
+}
+
+/**
+ * htmlIsAutoClosed:
+ * @doc:  the HTML document
+ * @elem:  the HTML element
+ *
+ * The HTML DTD allows a tag to implicitly close other tags.
+ * The list is kept in htmlStartClose array. This function checks
+ * if a tag is autoclosed by one of it's child
+ *
+ * Returns 1 if autoclosed, 0 otherwise
+ */
+int
+htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
+    htmlNodePtr child;
+
+    if (elem == NULL) return(1);
+    child = elem->children;
+    while (child != NULL) {
+	if (htmlAutoCloseTag(doc, elem->name, child)) return(1);
+	child = child->next;
+    }
+    return(0);
+}
+
+/**
+ * htmlCheckImplied:
+ * @ctxt:  an HTML parser context
+ * @newtag:  The new tag name
+ *
+ * The HTML DTD allows a tag to exists only implicitly
+ * called when a new tag has been detected and generates the
+ * appropriates implicit tags if missing
+ */
+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"))
+	return;
+    if (ctxt->nameNr <= 0) {
+	htmlnamePush(ctxt, BAD_CAST"html");
+	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
+    }
+    if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
+        return;
+    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")))) {
+        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"))) {
+        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;
+	    }
+	    if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
+		return;
+	    }
+	}
+
+	htmlnamePush(ctxt, BAD_CAST"body");
+	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
+    }
+}
+
+/**
+ * htmlCheckParagraph
+ * @ctxt:  an HTML parser context
+ *
+ * Check whether a p element need to be implied before inserting
+ * characters in the current element.
+ *
+ * Returns 1 if a paragraph has been inserted, 0 if not and -1
+ *         in case of error.
+ */
+
+static int
+htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
+    const xmlChar *tag;
+    int i;
+
+    if (ctxt == NULL)
+	return(-1);
+    tag = ctxt->name;
+    if (tag == NULL) {
+	htmlAutoClose(ctxt, BAD_CAST"p");
+	htmlCheckImplied(ctxt, BAD_CAST"p");
+	htmlnamePush(ctxt, BAD_CAST"p");
+	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
+	return(1);
+    }
+    if (!htmlOmittedDefaultValue)
+	return(0);
+    for (i = 0; htmlNoContentElements[i] != NULL; i++) {
+	if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
+	    htmlAutoClose(ctxt, BAD_CAST"p");
+	    htmlCheckImplied(ctxt, BAD_CAST"p");
+	    htmlnamePush(ctxt, BAD_CAST"p");
+	    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+		ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
+	    return(1);
+	}
+    }
+    return(0);
+}
+
+/**
+ * htmlIsScriptAttribute:
+ * @name:  an attribute name
+ *
+ * Check if an attribute is of content type Script
+ *
+ * Returns 1 is the attribute is a script 0 otherwise
+ */
+int
+htmlIsScriptAttribute(const xmlChar *name) {
+    unsigned int i;
+
+    if (name == NULL)
+      return(0);
+    /*
+     * all script attributes start with 'on'
+     */
+    if ((name[0] != 'o') || (name[1] != 'n'))
+      return(0);
+    for (i = 0;
+	 i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
+	 i++) {
+	if (xmlStrEqual(name, (const xmlChar *) htmlScriptAttributes[i]))
+	    return(1);
+    }
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *	The list of HTML predefined entities			*
+ *									*
+ ************************************************************************/
+
+
+static const htmlEntityDesc  html40EntitiesTable[] = {
+/*
+ * the 4 absolute ones, plus apostrophe.
+ */
+{ 34,	"quot",	"quotation mark = APL quote, U+0022 ISOnum" },
+{ 38,	"amp",	"ampersand, U+0026 ISOnum" },
+{ 39,	"apos",	"single quote" },
+{ 60,	"lt",	"less-than sign, U+003C ISOnum" },
+{ 62,	"gt",	"greater-than sign, U+003E ISOnum" },
+
+/*
+ * A bunch still in the 128-255 range
+ * Replacing them depend really on the charset used.
+ */
+{ 160,	"nbsp",	"no-break space = non-breaking space, U+00A0 ISOnum" },
+{ 161,	"iexcl","inverted exclamation mark, U+00A1 ISOnum" },
+{ 162,	"cent",	"cent sign, U+00A2 ISOnum" },
+{ 163,	"pound","pound sign, U+00A3 ISOnum" },
+{ 164,	"curren","currency sign, U+00A4 ISOnum" },
+{ 165,	"yen",	"yen sign = yuan sign, U+00A5 ISOnum" },
+{ 166,	"brvbar","broken bar = broken vertical bar, U+00A6 ISOnum" },
+{ 167,	"sect",	"section sign, U+00A7 ISOnum" },
+{ 168,	"uml",	"diaeresis = spacing diaeresis, U+00A8 ISOdia" },
+{ 169,	"copy",	"copyright sign, U+00A9 ISOnum" },
+{ 170,	"ordf",	"feminine ordinal indicator, U+00AA ISOnum" },
+{ 171,	"laquo","left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum" },
+{ 172,	"not",	"not sign, U+00AC ISOnum" },
+{ 173,	"shy",	"soft hyphen = discretionary hyphen, U+00AD ISOnum" },
+{ 174,	"reg",	"registered sign = registered trade mark sign, U+00AE ISOnum" },
+{ 175,	"macr",	"macron = spacing macron = overline = APL overbar, U+00AF ISOdia" },
+{ 176,	"deg",	"degree sign, U+00B0 ISOnum" },
+{ 177,	"plusmn","plus-minus sign = plus-or-minus sign, U+00B1 ISOnum" },
+{ 178,	"sup2",	"superscript two = superscript digit two = squared, U+00B2 ISOnum" },
+{ 179,	"sup3",	"superscript three = superscript digit three = cubed, U+00B3 ISOnum" },
+{ 180,	"acute","acute accent = spacing acute, U+00B4 ISOdia" },
+{ 181,	"micro","micro sign, U+00B5 ISOnum" },
+{ 182,	"para",	"pilcrow sign = paragraph sign, U+00B6 ISOnum" },
+{ 183,	"middot","middle dot = Georgian comma Greek middle dot, U+00B7 ISOnum" },
+{ 184,	"cedil","cedilla = spacing cedilla, U+00B8 ISOdia" },
+{ 185,	"sup1",	"superscript one = superscript digit one, U+00B9 ISOnum" },
+{ 186,	"ordm",	"masculine ordinal indicator, U+00BA ISOnum" },
+{ 187,	"raquo","right-pointing double angle quotation mark right pointing guillemet, U+00BB ISOnum" },
+{ 188,	"frac14","vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum" },
+{ 189,	"frac12","vulgar fraction one half = fraction one half, U+00BD ISOnum" },
+{ 190,	"frac34","vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum" },
+{ 191,	"iquest","inverted question mark = turned question mark, U+00BF ISOnum" },
+{ 192,	"Agrave","latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1" },
+{ 193,	"Aacute","latin capital letter A with acute, U+00C1 ISOlat1" },
+{ 194,	"Acirc","latin capital letter A with circumflex, U+00C2 ISOlat1" },
+{ 195,	"Atilde","latin capital letter A with tilde, U+00C3 ISOlat1" },
+{ 196,	"Auml",	"latin capital letter A with diaeresis, U+00C4 ISOlat1" },
+{ 197,	"Aring","latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1" },
+{ 198,	"AElig","latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1" },
+{ 199,	"Ccedil","latin capital letter C with cedilla, U+00C7 ISOlat1" },
+{ 200,	"Egrave","latin capital letter E with grave, U+00C8 ISOlat1" },
+{ 201,	"Eacute","latin capital letter E with acute, U+00C9 ISOlat1" },
+{ 202,	"Ecirc","latin capital letter E with circumflex, U+00CA ISOlat1" },
+{ 203,	"Euml",	"latin capital letter E with diaeresis, U+00CB ISOlat1" },
+{ 204,	"Igrave","latin capital letter I with grave, U+00CC ISOlat1" },
+{ 205,	"Iacute","latin capital letter I with acute, U+00CD ISOlat1" },
+{ 206,	"Icirc","latin capital letter I with circumflex, U+00CE ISOlat1" },
+{ 207,	"Iuml",	"latin capital letter I with diaeresis, U+00CF ISOlat1" },
+{ 208,	"ETH",	"latin capital letter ETH, U+00D0 ISOlat1" },
+{ 209,	"Ntilde","latin capital letter N with tilde, U+00D1 ISOlat1" },
+{ 210,	"Ograve","latin capital letter O with grave, U+00D2 ISOlat1" },
+{ 211,	"Oacute","latin capital letter O with acute, U+00D3 ISOlat1" },
+{ 212,	"Ocirc","latin capital letter O with circumflex, U+00D4 ISOlat1" },
+{ 213,	"Otilde","latin capital letter O with tilde, U+00D5 ISOlat1" },
+{ 214,	"Ouml",	"latin capital letter O with diaeresis, U+00D6 ISOlat1" },
+{ 215,	"times","multiplication sign, U+00D7 ISOnum" },
+{ 216,	"Oslash","latin capital letter O with stroke latin capital letter O slash, U+00D8 ISOlat1" },
+{ 217,	"Ugrave","latin capital letter U with grave, U+00D9 ISOlat1" },
+{ 218,	"Uacute","latin capital letter U with acute, U+00DA ISOlat1" },
+{ 219,	"Ucirc","latin capital letter U with circumflex, U+00DB ISOlat1" },
+{ 220,	"Uuml",	"latin capital letter U with diaeresis, U+00DC ISOlat1" },
+{ 221,	"Yacute","latin capital letter Y with acute, U+00DD ISOlat1" },
+{ 222,	"THORN","latin capital letter THORN, U+00DE ISOlat1" },
+{ 223,	"szlig","latin small letter sharp s = ess-zed, U+00DF ISOlat1" },
+{ 224,	"agrave","latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1" },
+{ 225,	"aacute","latin small letter a with acute, U+00E1 ISOlat1" },
+{ 226,	"acirc","latin small letter a with circumflex, U+00E2 ISOlat1" },
+{ 227,	"atilde","latin small letter a with tilde, U+00E3 ISOlat1" },
+{ 228,	"auml",	"latin small letter a with diaeresis, U+00E4 ISOlat1" },
+{ 229,	"aring","latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1" },
+{ 230,	"aelig","latin small letter ae = latin small ligature ae, U+00E6 ISOlat1" },
+{ 231,	"ccedil","latin small letter c with cedilla, U+00E7 ISOlat1" },
+{ 232,	"egrave","latin small letter e with grave, U+00E8 ISOlat1" },
+{ 233,	"eacute","latin small letter e with acute, U+00E9 ISOlat1" },
+{ 234,	"ecirc","latin small letter e with circumflex, U+00EA ISOlat1" },
+{ 235,	"euml",	"latin small letter e with diaeresis, U+00EB ISOlat1" },
+{ 236,	"igrave","latin small letter i with grave, U+00EC ISOlat1" },
+{ 237,	"iacute","latin small letter i with acute, U+00ED ISOlat1" },
+{ 238,	"icirc","latin small letter i with circumflex, U+00EE ISOlat1" },
+{ 239,	"iuml",	"latin small letter i with diaeresis, U+00EF ISOlat1" },
+{ 240,	"eth",	"latin small letter eth, U+00F0 ISOlat1" },
+{ 241,	"ntilde","latin small letter n with tilde, U+00F1 ISOlat1" },
+{ 242,	"ograve","latin small letter o with grave, U+00F2 ISOlat1" },
+{ 243,	"oacute","latin small letter o with acute, U+00F3 ISOlat1" },
+{ 244,	"ocirc","latin small letter o with circumflex, U+00F4 ISOlat1" },
+{ 245,	"otilde","latin small letter o with tilde, U+00F5 ISOlat1" },
+{ 246,	"ouml",	"latin small letter o with diaeresis, U+00F6 ISOlat1" },
+{ 247,	"divide","division sign, U+00F7 ISOnum" },
+{ 248,	"oslash","latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1" },
+{ 249,	"ugrave","latin small letter u with grave, U+00F9 ISOlat1" },
+{ 250,	"uacute","latin small letter u with acute, U+00FA ISOlat1" },
+{ 251,	"ucirc","latin small letter u with circumflex, U+00FB ISOlat1" },
+{ 252,	"uuml",	"latin small letter u with diaeresis, U+00FC ISOlat1" },
+{ 253,	"yacute","latin small letter y with acute, U+00FD ISOlat1" },
+{ 254,	"thorn","latin small letter thorn with, U+00FE ISOlat1" },
+{ 255,	"yuml",	"latin small letter y with diaeresis, U+00FF ISOlat1" },
+
+{ 338,	"OElig","latin capital ligature OE, U+0152 ISOlat2" },
+{ 339,	"oelig","latin small ligature oe, U+0153 ISOlat2" },
+{ 352,	"Scaron","latin capital letter S with caron, U+0160 ISOlat2" },
+{ 353,	"scaron","latin small letter s with caron, U+0161 ISOlat2" },
+{ 376,	"Yuml",	"latin capital letter Y with diaeresis, U+0178 ISOlat2" },
+
+/*
+ * Anything below should really be kept as entities references
+ */
+{ 402,	"fnof",	"latin small f with hook = function = florin, U+0192 ISOtech" },
+
+{ 710,	"circ",	"modifier letter circumflex accent, U+02C6 ISOpub" },
+{ 732,	"tilde","small tilde, U+02DC ISOdia" },
+
+{ 913,	"Alpha","greek capital letter alpha, U+0391" },
+{ 914,	"Beta",	"greek capital letter beta, U+0392" },
+{ 915,	"Gamma","greek capital letter gamma, U+0393 ISOgrk3" },
+{ 916,	"Delta","greek capital letter delta, U+0394 ISOgrk3" },
+{ 917,	"Epsilon","greek capital letter epsilon, U+0395" },
+{ 918,	"Zeta",	"greek capital letter zeta, U+0396" },
+{ 919,	"Eta",	"greek capital letter eta, U+0397" },
+{ 920,	"Theta","greek capital letter theta, U+0398 ISOgrk3" },
+{ 921,	"Iota",	"greek capital letter iota, U+0399" },
+{ 922,	"Kappa","greek capital letter kappa, U+039A" },
+{ 923,	"Lambda", "greek capital letter lambda, U+039B ISOgrk3" },
+{ 924,	"Mu",	"greek capital letter mu, U+039C" },
+{ 925,	"Nu",	"greek capital letter nu, U+039D" },
+{ 926,	"Xi",	"greek capital letter xi, U+039E ISOgrk3" },
+{ 927,	"Omicron","greek capital letter omicron, U+039F" },
+{ 928,	"Pi",	"greek capital letter pi, U+03A0 ISOgrk3" },
+{ 929,	"Rho",	"greek capital letter rho, U+03A1" },
+{ 931,	"Sigma","greek capital letter sigma, U+03A3 ISOgrk3" },
+{ 932,	"Tau",	"greek capital letter tau, U+03A4" },
+{ 933,	"Upsilon","greek capital letter upsilon, U+03A5 ISOgrk3" },
+{ 934,	"Phi",	"greek capital letter phi, U+03A6 ISOgrk3" },
+{ 935,	"Chi",	"greek capital letter chi, U+03A7" },
+{ 936,	"Psi",	"greek capital letter psi, U+03A8 ISOgrk3" },
+{ 937,	"Omega","greek capital letter omega, U+03A9 ISOgrk3" },
+
+{ 945,	"alpha","greek small letter alpha, U+03B1 ISOgrk3" },
+{ 946,	"beta",	"greek small letter beta, U+03B2 ISOgrk3" },
+{ 947,	"gamma","greek small letter gamma, U+03B3 ISOgrk3" },
+{ 948,	"delta","greek small letter delta, U+03B4 ISOgrk3" },
+{ 949,	"epsilon","greek small letter epsilon, U+03B5 ISOgrk3" },
+{ 950,	"zeta",	"greek small letter zeta, U+03B6 ISOgrk3" },
+{ 951,	"eta",	"greek small letter eta, U+03B7 ISOgrk3" },
+{ 952,	"theta","greek small letter theta, U+03B8 ISOgrk3" },
+{ 953,	"iota",	"greek small letter iota, U+03B9 ISOgrk3" },
+{ 954,	"kappa","greek small letter kappa, U+03BA ISOgrk3" },
+{ 955,	"lambda","greek small letter lambda, U+03BB ISOgrk3" },
+{ 956,	"mu",	"greek small letter mu, U+03BC ISOgrk3" },
+{ 957,	"nu",	"greek small letter nu, U+03BD ISOgrk3" },
+{ 958,	"xi",	"greek small letter xi, U+03BE ISOgrk3" },
+{ 959,	"omicron","greek small letter omicron, U+03BF NEW" },
+{ 960,	"pi",	"greek small letter pi, U+03C0 ISOgrk3" },
+{ 961,	"rho",	"greek small letter rho, U+03C1 ISOgrk3" },
+{ 962,	"sigmaf","greek small letter final sigma, U+03C2 ISOgrk3" },
+{ 963,	"sigma","greek small letter sigma, U+03C3 ISOgrk3" },
+{ 964,	"tau",	"greek small letter tau, U+03C4 ISOgrk3" },
+{ 965,	"upsilon","greek small letter upsilon, U+03C5 ISOgrk3" },
+{ 966,	"phi",	"greek small letter phi, U+03C6 ISOgrk3" },
+{ 967,	"chi",	"greek small letter chi, U+03C7 ISOgrk3" },
+{ 968,	"psi",	"greek small letter psi, U+03C8 ISOgrk3" },
+{ 969,	"omega","greek small letter omega, U+03C9 ISOgrk3" },
+{ 977,	"thetasym","greek small letter theta symbol, U+03D1 NEW" },
+{ 978,	"upsih","greek upsilon with hook symbol, U+03D2 NEW" },
+{ 982,	"piv",	"greek pi symbol, U+03D6 ISOgrk3" },
+
+{ 8194,	"ensp",	"en space, U+2002 ISOpub" },
+{ 8195,	"emsp",	"em space, U+2003 ISOpub" },
+{ 8201,	"thinsp","thin space, U+2009 ISOpub" },
+{ 8204,	"zwnj",	"zero width non-joiner, U+200C NEW RFC 2070" },
+{ 8205,	"zwj",	"zero width joiner, U+200D NEW RFC 2070" },
+{ 8206,	"lrm",	"left-to-right mark, U+200E NEW RFC 2070" },
+{ 8207,	"rlm",	"right-to-left mark, U+200F NEW RFC 2070" },
+{ 8211,	"ndash","en dash, U+2013 ISOpub" },
+{ 8212,	"mdash","em dash, U+2014 ISOpub" },
+{ 8216,	"lsquo","left single quotation mark, U+2018 ISOnum" },
+{ 8217,	"rsquo","right single quotation mark, U+2019 ISOnum" },
+{ 8218,	"sbquo","single low-9 quotation mark, U+201A NEW" },
+{ 8220,	"ldquo","left double quotation mark, U+201C ISOnum" },
+{ 8221,	"rdquo","right double quotation mark, U+201D ISOnum" },
+{ 8222,	"bdquo","double low-9 quotation mark, U+201E NEW" },
+{ 8224,	"dagger","dagger, U+2020 ISOpub" },
+{ 8225,	"Dagger","double dagger, U+2021 ISOpub" },
+
+{ 8226,	"bull",	"bullet = black small circle, U+2022 ISOpub" },
+{ 8230,	"hellip","horizontal ellipsis = three dot leader, U+2026 ISOpub" },
+
+{ 8240,	"permil","per mille sign, U+2030 ISOtech" },
+
+{ 8242,	"prime","prime = minutes = feet, U+2032 ISOtech" },
+{ 8243,	"Prime","double prime = seconds = inches, U+2033 ISOtech" },
+
+{ 8249,	"lsaquo","single left-pointing angle quotation mark, U+2039 ISO proposed" },
+{ 8250,	"rsaquo","single right-pointing angle quotation mark, U+203A ISO proposed" },
+
+{ 8254,	"oline","overline = spacing overscore, U+203E NEW" },
+{ 8260,	"frasl","fraction slash, U+2044 NEW" },
+
+{ 8364,	"euro",	"euro sign, U+20AC NEW" },
+
+{ 8465,	"image","blackletter capital I = imaginary part, U+2111 ISOamso" },
+{ 8472,	"weierp","script capital P = power set = Weierstrass p, U+2118 ISOamso" },
+{ 8476,	"real",	"blackletter capital R = real part symbol, U+211C ISOamso" },
+{ 8482,	"trade","trade mark sign, U+2122 ISOnum" },
+{ 8501,	"alefsym","alef symbol = first transfinite cardinal, U+2135 NEW" },
+{ 8592,	"larr",	"leftwards arrow, U+2190 ISOnum" },
+{ 8593,	"uarr",	"upwards arrow, U+2191 ISOnum" },
+{ 8594,	"rarr",	"rightwards arrow, U+2192 ISOnum" },
+{ 8595,	"darr",	"downwards arrow, U+2193 ISOnum" },
+{ 8596,	"harr",	"left right arrow, U+2194 ISOamsa" },
+{ 8629,	"crarr","downwards arrow with corner leftwards = carriage return, U+21B5 NEW" },
+{ 8656,	"lArr",	"leftwards double arrow, U+21D0 ISOtech" },
+{ 8657,	"uArr",	"upwards double arrow, U+21D1 ISOamsa" },
+{ 8658,	"rArr",	"rightwards double arrow, U+21D2 ISOtech" },
+{ 8659,	"dArr",	"downwards double arrow, U+21D3 ISOamsa" },
+{ 8660,	"hArr",	"left right double arrow, U+21D4 ISOamsa" },
+
+{ 8704,	"forall","for all, U+2200 ISOtech" },
+{ 8706,	"part",	"partial differential, U+2202 ISOtech" },
+{ 8707,	"exist","there exists, U+2203 ISOtech" },
+{ 8709,	"empty","empty set = null set = diameter, U+2205 ISOamso" },
+{ 8711,	"nabla","nabla = backward difference, U+2207 ISOtech" },
+{ 8712,	"isin",	"element of, U+2208 ISOtech" },
+{ 8713,	"notin","not an element of, U+2209 ISOtech" },
+{ 8715,	"ni",	"contains as member, U+220B ISOtech" },
+{ 8719,	"prod",	"n-ary product = product sign, U+220F ISOamsb" },
+{ 8721,	"sum",	"n-ary summation, U+2211 ISOamsb" },
+{ 8722,	"minus","minus sign, U+2212 ISOtech" },
+{ 8727,	"lowast","asterisk operator, U+2217 ISOtech" },
+{ 8730,	"radic","square root = radical sign, U+221A ISOtech" },
+{ 8733,	"prop",	"proportional to, U+221D ISOtech" },
+{ 8734,	"infin","infinity, U+221E ISOtech" },
+{ 8736,	"ang",	"angle, U+2220 ISOamso" },
+{ 8743,	"and",	"logical and = wedge, U+2227 ISOtech" },
+{ 8744,	"or",	"logical or = vee, U+2228 ISOtech" },
+{ 8745,	"cap",	"intersection = cap, U+2229 ISOtech" },
+{ 8746,	"cup",	"union = cup, U+222A ISOtech" },
+{ 8747,	"int",	"integral, U+222B ISOtech" },
+{ 8756,	"there4","therefore, U+2234 ISOtech" },
+{ 8764,	"sim",	"tilde operator = varies with = similar to, U+223C ISOtech" },
+{ 8773,	"cong",	"approximately equal to, U+2245 ISOtech" },
+{ 8776,	"asymp","almost equal to = asymptotic to, U+2248 ISOamsr" },
+{ 8800,	"ne",	"not equal to, U+2260 ISOtech" },
+{ 8801,	"equiv","identical to, U+2261 ISOtech" },
+{ 8804,	"le",	"less-than or equal to, U+2264 ISOtech" },
+{ 8805,	"ge",	"greater-than or equal to, U+2265 ISOtech" },
+{ 8834,	"sub",	"subset of, U+2282 ISOtech" },
+{ 8835,	"sup",	"superset of, U+2283 ISOtech" },
+{ 8836,	"nsub",	"not a subset of, U+2284 ISOamsn" },
+{ 8838,	"sube",	"subset of or equal to, U+2286 ISOtech" },
+{ 8839,	"supe",	"superset of or equal to, U+2287 ISOtech" },
+{ 8853,	"oplus","circled plus = direct sum, U+2295 ISOamsb" },
+{ 8855,	"otimes","circled times = vector product, U+2297 ISOamsb" },
+{ 8869,	"perp",	"up tack = orthogonal to = perpendicular, U+22A5 ISOtech" },
+{ 8901,	"sdot",	"dot operator, U+22C5 ISOamsb" },
+{ 8968,	"lceil","left ceiling = apl upstile, U+2308 ISOamsc" },
+{ 8969,	"rceil","right ceiling, U+2309 ISOamsc" },
+{ 8970,	"lfloor","left floor = apl downstile, U+230A ISOamsc" },
+{ 8971,	"rfloor","right floor, U+230B ISOamsc" },
+{ 9001,	"lang",	"left-pointing angle bracket = bra, U+2329 ISOtech" },
+{ 9002,	"rang",	"right-pointing angle bracket = ket, U+232A ISOtech" },
+{ 9674,	"loz",	"lozenge, U+25CA ISOpub" },
+
+{ 9824,	"spades","black spade suit, U+2660 ISOpub" },
+{ 9827,	"clubs","black club suit = shamrock, U+2663 ISOpub" },
+{ 9829,	"hearts","black heart suit = valentine, U+2665 ISOpub" },
+{ 9830,	"diams","black diamond suit, U+2666 ISOpub" },
+
+};
+
+/************************************************************************
+ *									*
+ *		Commodity functions to handle entities			*
+ *									*
+ ************************************************************************/
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define growBuffer(buffer) {						\
+    xmlChar *tmp;							\
+    buffer##_size *= 2;							\
+    tmp = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
+    if (tmp == NULL) {						\
+	htmlErrMemory(ctxt, "growing buffer\n");			\
+	xmlFree(buffer);						\
+	return(NULL);							\
+    }									\
+    buffer = tmp;							\
+}
+
+/**
+ * htmlEntityLookup:
+ * @name: the entity name
+ *
+ * Lookup the given entity in EntitiesTable
+ *
+ * TODO: the linear scan is really ugly, an hash table is really needed.
+ *
+ * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
+ */
+const htmlEntityDesc *
+htmlEntityLookup(const xmlChar *name) {
+    unsigned int i;
+
+    for (i = 0;i < (sizeof(html40EntitiesTable)/
+                    sizeof(html40EntitiesTable[0]));i++) {
+        if (xmlStrEqual(name, BAD_CAST html40EntitiesTable[i].name)) {
+            return((htmlEntityDescPtr) &html40EntitiesTable[i]);
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * htmlEntityValueLookup:
+ * @value: the entity's unicode value
+ *
+ * Lookup the given entity in EntitiesTable
+ *
+ * TODO: the linear scan is really ugly, an hash table is really needed.
+ *
+ * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
+ */
+const htmlEntityDesc *
+htmlEntityValueLookup(unsigned int value) {
+    unsigned int i;
+
+    for (i = 0;i < (sizeof(html40EntitiesTable)/
+                    sizeof(html40EntitiesTable[0]));i++) {
+        if (html40EntitiesTable[i].value >= value) {
+	    if (html40EntitiesTable[i].value > value)
+		break;
+            return((htmlEntityDescPtr) &html40EntitiesTable[i]);
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * UTF8ToHtml:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
+ * plus HTML entities block of chars out.
+ *
+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * 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 octets consumed.
+ */
+int
+UTF8ToHtml(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen) {
+    const unsigned char* processed = in;
+    const unsigned char* outend;
+    const unsigned char* outstart = out;
+    const unsigned char* instart = in;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if (in == NULL) {
+        /*
+	 * initialization nothing to do
+	 */
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    inend = in + (*inlen);
+    outend = out + (*outlen);
+    while (in < inend) {
+	d = *in++;
+	if      (d < 0x80)  { c= d; trailing= 0; }
+	else if (d < 0xC0) {
+	    /* trailing byte in leading position */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+        } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+        else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+        else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+	else {
+	    /* no chance for this in Ascii */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+
+	if (inend - in < trailing) {
+	    break;
+	}
+
+	for ( ; trailing; trailing--) {
+	    if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
+		break;
+	    c <<= 6;
+	    c |= d & 0x3F;
+	}
+
+	/* assertion: c is a single UTF-4 value */
+	if (c < 0x80) {
+	    if (out + 1 >= outend)
+		break;
+	    *out++ = c;
+	} else {
+	    int len;
+	    const htmlEntityDesc * ent;
+	    const char *cp;
+	    char nbuf[16];
+
+	    /*
+	     * Try to lookup a predefined HTML entity for it
+	     */
+
+	    ent = htmlEntityValueLookup(c);
+	    if (ent == NULL) {
+	      snprintf(nbuf, sizeof(nbuf), "#%u", c);
+	      cp = nbuf;
+	    }
+	    else
+	      cp = ent->name;
+	    len = strlen(cp);
+	    if (out + 2 + len >= outend)
+		break;
+	    *out++ = '&';
+	    memcpy(out, cp, len);
+	    out += len;
+	    *out++ = ';';
+	}
+	processed = in;
+    }
+    *outlen = out - outstart;
+    *inlen = processed - instart;
+    return(0);
+}
+
+/**
+ * htmlEncodeEntities:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ * @quoteChar: the quote character to escape (' or ") or zero.
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
+ * plus HTML entities block of chars out.
+ *
+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * 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 octets consumed.
+ */
+int
+htmlEncodeEntities(unsigned char* out, int *outlen,
+		   const unsigned char* in, int *inlen, int quoteChar) {
+    const unsigned char* processed = in;
+    const unsigned char* outend;
+    const unsigned char* outstart = out;
+    const unsigned char* instart = in;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL))
+        return(-1);
+    outend = out + (*outlen);
+    inend = in + (*inlen);
+    while (in < inend) {
+	d = *in++;
+	if      (d < 0x80)  { c= d; trailing= 0; }
+	else if (d < 0xC0) {
+	    /* trailing byte in leading position */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+        } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+        else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+        else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+	else {
+	    /* no chance for this in Ascii */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+
+	if (inend - in < trailing)
+	    break;
+
+	while (trailing--) {
+	    if (((d= *in++) & 0xC0) != 0x80) {
+		*outlen = out - outstart;
+		*inlen = processed - instart;
+		return(-2);
+	    }
+	    c <<= 6;
+	    c |= d & 0x3F;
+	}
+
+	/* assertion: c is a single UTF-4 value */
+	if ((c < 0x80) && (c != (unsigned int) quoteChar) &&
+	    (c != '&') && (c != '<') && (c != '>')) {
+	    if (out >= outend)
+		break;
+	    *out++ = c;
+	} else {
+	    const htmlEntityDesc * ent;
+	    const char *cp;
+	    char nbuf[16];
+	    int len;
+
+	    /*
+	     * Try to lookup a predefined HTML entity for it
+	     */
+	    ent = htmlEntityValueLookup(c);
+	    if (ent == NULL) {
+		snprintf(nbuf, sizeof(nbuf), "#%u", c);
+		cp = nbuf;
+	    }
+	    else
+		cp = ent->name;
+	    len = strlen(cp);
+	    if (out + 2 + len > outend)
+		break;
+	    *out++ = '&';
+	    memcpy(out, cp, len);
+	    out += len;
+	    *out++ = ';';
+	}
+	processed = in;
+    }
+    *outlen = out - outstart;
+    *inlen = processed - instart;
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions to handle streams			*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlNewInputStream:
+ * @ctxt:  an HTML parser context
+ *
+ * Create a new input stream structure
+ * Returns the new input stream or NULL
+ */
+static htmlParserInputPtr
+htmlNewInputStream(htmlParserCtxtPtr ctxt) {
+    htmlParserInputPtr input;
+
+    input = (xmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
+    if (input == NULL) {
+        htmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
+	return(NULL);
+    }
+    memset(input, 0, sizeof(htmlParserInput));
+    input->filename = NULL;
+    input->directory = NULL;
+    input->base = NULL;
+    input->cur = NULL;
+    input->buf = NULL;
+    input->line = 1;
+    input->col = 1;
+    input->buf = NULL;
+    input->free = NULL;
+    input->version = NULL;
+    input->consumed = 0;
+    input->length = 0;
+    return(input);
+}
+
+
+/************************************************************************
+ *									*
+ *		Commodity functions, cleanup needed ?			*
+ *									*
+ ************************************************************************/
+/*
+ * 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
+ */
+static const char *allowPCData[] = {
+    "a", "abbr", "acronym", "address", "applet", "b", "bdo", "big",
+    "blockquote", "body", "button", "caption", "center", "cite", "code",
+    "dd", "del", "dfn", "div", "dt", "em", "font", "form", "h1", "h2",
+    "h3", "h4", "h5", "h6", "i", "iframe", "ins", "kbd", "label", "legend",
+    "li", "noframes", "noscript", "object", "p", "pre", "q", "s", "samp",
+    "small", "span", "strike", "strong", "td", "th", "tt", "u", "var"
+};
+
+/**
+ * areBlanks:
+ * @ctxt:  an HTML parser context
+ * @str:  a xmlChar *
+ * @len:  the size of @str
+ *
+ * Is this a sequence of blank chars that one can ignore ?
+ *
+ * Returns 1 if ignorable 0 otherwise.
+ */
+
+static int areBlanks(htmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
+    unsigned int i;
+    int j;
+    xmlNodePtr lastChild;
+    xmlDtdPtr dtd;
+
+    for (j = 0;j < len;j++)
+        if (!(IS_BLANK_CH(str[j]))) return(0);
+
+    if (CUR == 0) return(1);
+    if (CUR != '<') return(0);
+    if (ctxt->name == NULL)
+	return(1);
+    if (xmlStrEqual(ctxt->name, BAD_CAST"html"))
+	return(1);
+    if (xmlStrEqual(ctxt->name, BAD_CAST"head"))
+	return(1);
+
+    /* Only strip CDATA children of the body tag for strict HTML DTDs */
+    if (xmlStrEqual(ctxt->name, BAD_CAST "body") && ctxt->myDoc != NULL) {
+        dtd = xmlGetIntSubset(ctxt->myDoc);
+        if (dtd != NULL && dtd->ExternalID != NULL) {
+            if (!xmlStrcasecmp(dtd->ExternalID, BAD_CAST "-//W3C//DTD HTML 4.01//EN") ||
+                    !xmlStrcasecmp(dtd->ExternalID, BAD_CAST "-//W3C//DTD HTML 4//EN"))
+                return(1);
+        }
+    }
+
+    if (ctxt->node == NULL) return(0);
+    lastChild = xmlGetLastChild(ctxt->node);
+    while ((lastChild) && (lastChild->type == XML_COMMENT_NODE))
+	lastChild = lastChild->prev;
+    if (lastChild == NULL) {
+        if ((ctxt->node->type != XML_ELEMENT_NODE) &&
+            (ctxt->node->content != NULL)) return(0);
+	/* 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]) ) {
+		return(0);
+	    }
+	}
+    } else if (xmlNodeIsText(lastChild)) {
+        return(0);
+    } else {
+	/* 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]) ) {
+		return(0);
+	    }
+	}
+    }
+    return(1);
+}
+
+/**
+ * htmlNewDocNoDtD:
+ * @URI:  URI for the dtd, or NULL
+ * @ExternalID:  the external ID of the DTD, or NULL
+ *
+ * Creates a new HTML document without a DTD node if @URI and @ExternalID
+ * are NULL
+ *
+ * Returns a new document, do not initialize the DTD if not provided
+ */
+htmlDocPtr
+htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
+    xmlDocPtr cur;
+
+    /*
+     * Allocate a new document and fill the fields.
+     */
+    cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
+    if (cur == NULL) {
+	htmlErrMemory(NULL, "HTML document creation failed\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlDoc));
+
+    cur->type = XML_HTML_DOCUMENT_NODE;
+    cur->version = NULL;
+    cur->intSubset = NULL;
+    cur->doc = cur;
+    cur->name = NULL;
+    cur->children = NULL;
+    cur->extSubset = NULL;
+    cur->oldNs = NULL;
+    cur->encoding = NULL;
+    cur->standalone = 1;
+    cur->compression = 0;
+    cur->ids = NULL;
+    cur->refs = NULL;
+    cur->_private = NULL;
+    cur->charset = XML_CHAR_ENCODING_UTF8;
+    cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
+    if ((ExternalID != NULL) ||
+	(URI != NULL))
+	xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
+    return(cur);
+}
+
+/**
+ * htmlNewDoc:
+ * @URI:  URI for the dtd, or NULL
+ * @ExternalID:  the external ID of the DTD, or NULL
+ *
+ * Creates a new HTML document
+ *
+ * Returns a new document
+ */
+htmlDocPtr
+htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
+    if ((URI == NULL) && (ExternalID == NULL))
+	return(htmlNewDocNoDtD(
+		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd",
+		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN"));
+
+    return(htmlNewDocNoDtD(URI, ExternalID));
+}
+
+
+/************************************************************************
+ *									*
+ *			The parser itself				*
+ *	Relates to http://www.w3.org/TR/html40				*
+ *									*
+ ************************************************************************/
+
+/************************************************************************
+ *									*
+ *			The parser itself				*
+ *									*
+ ************************************************************************/
+
+static const xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
+
+/**
+ * htmlParseHTMLName:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML tag or attribute name, note that we convert it to lowercase
+ * since HTML names are not case-sensitive.
+ *
+ * Returns the Tag Name parsed or NULL
+ */
+
+static const xmlChar *
+htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
+    int i = 0;
+    xmlChar loc[HTML_PARSER_BUFFER_SIZE];
+
+    if (!IS_ASCII_LETTER(CUR) && (CUR != '_') &&
+        (CUR != ':') && (CUR != '.')) return(NULL);
+
+    while ((i < HTML_PARSER_BUFFER_SIZE) &&
+           ((IS_ASCII_LETTER(CUR)) || (IS_ASCII_DIGIT(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));
+}
+
+
+/**
+ * htmlParseHTMLName_nonInvasive:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML tag or attribute name, note that we convert it to lowercase
+ * since HTML names are not case-sensitive, this doesn't consume the data
+ * from the stream, it's a look-ahead
+ *
+ * Returns the Tag Name parsed or NULL
+ */
+
+static const xmlChar *
+htmlParseHTMLName_nonInvasive(htmlParserCtxtPtr ctxt) {
+    int i = 0;
+    xmlChar loc[HTML_PARSER_BUFFER_SIZE];
+
+    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) == '_'))) {
+	if ((NXT(1+i) >= 'A') && (NXT(1+i) <= 'Z')) loc[i] = NXT(1+i) + 0x20;
+        else loc[i] = NXT(1+i);
+	i++;
+    }
+
+    return(xmlDictLookup(ctxt->dict, loc, i));
+}
+
+
+/**
+ * htmlParseName:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML name, this routine is case sensitive.
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static const xmlChar *
+htmlParseName(htmlParserCtxtPtr ctxt) {
+    const xmlChar *in;
+    const xmlChar *ret;
+    int count = 0;
+
+    GROW;
+
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->input->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_') || (*in == ':')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == '-') ||
+	       (*in == ':') || (*in == '.'))
+	    in++;
+	if ((*in > 0) && (*in < 0x80)) {
+	    count = in - ctxt->input->cur;
+	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+	    ctxt->input->cur = in;
+	    ctxt->nbChars += count;
+	    ctxt->input->col += count;
+	    return(ret);
+	}
+    }
+    return(htmlParseNameComplex(ctxt));
+}
+
+static const xmlChar *
+htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+    int len = 0, l;
+    int c;
+    int count = 0;
+
+    /*
+     * Handler for more complex cases
+     */
+    GROW;
+    c = CUR_CHAR(l);
+    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+	(!IS_LETTER(c) && (c != '_') &&
+         (c != ':'))) {
+	return(NULL);
+    }
+
+    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || (c == ':') ||
+	    (IS_COMBINING(c)) ||
+	    (IS_EXTENDER(c)))) {
+	if (count++ > 100) {
+	    count = 0;
+	    GROW;
+	}
+	len += l;
+	NEXTL(l);
+	c = CUR_CHAR(l);
+    }
+    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+}
+
+
+/**
+ * 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
+ *
+ * Returns the attribute parsed or NULL
+ */
+
+static xmlChar *
+htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
+    xmlChar *buffer = NULL;
+    int buffer_size = 0;
+    xmlChar *out = NULL;
+    const xmlChar *name = NULL;
+    const xmlChar *cur = NULL;
+    const htmlEntityDesc * ent;
+
+    /*
+     * allocate a translation buffer.
+     */
+    buffer_size = HTML_PARSER_BUFFER_SIZE;
+    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) {
+	htmlErrMemory(ctxt, "buffer allocation failed\n");
+	return(NULL);
+    }
+    out = buffer;
+
+    /*
+     * Ok loop until we reach one of the ending chars
+     */
+    while ((CUR != 0) && (CUR != stop)) {
+	if ((stop == 0) && (CUR == '>')) break;
+	if ((stop == 0) && (IS_BLANK_CH(CUR))) break;
+        if (CUR == '&') {
+	    if (NXT(1) == '#') {
+		unsigned int c;
+		int bits;
+
+		c = htmlParseCharRef(ctxt);
+		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) {
+		    *out++  = ((c >> bits) & 0x3F) | 0x80;
+		}
+
+		if (out - buffer > buffer_size - 100) {
+			int indx = out - buffer;
+
+			growBuffer(buffer);
+			out = &buffer[indx];
+		}
+	    } else {
+		ent = htmlParseEntityRef(ctxt, &name);
+		if (name == NULL) {
+		    *out++ = '&';
+		    if (out - buffer > buffer_size - 100) {
+			int indx = out - buffer;
+
+			growBuffer(buffer);
+			out = &buffer[indx];
+		    }
+		} else if (ent == NULL) {
+		    *out++ = '&';
+		    cur = name;
+		    while (*cur != 0) {
+			if (out - buffer > buffer_size - 100) {
+			    int indx = out - buffer;
+
+			    growBuffer(buffer);
+			    out = &buffer[indx];
+			}
+			*out++ = *cur++;
+		    }
+		} else {
+		    unsigned int c;
+		    int bits;
+
+		    if (out - buffer > buffer_size - 100) {
+			int indx = out - buffer;
+
+			growBuffer(buffer);
+			out = &buffer[indx];
+		    }
+		    c = ent->value;
+		    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) {
+			*out++  = ((c >> bits) & 0x3F) | 0x80;
+		    }
+		}
+	    }
+	} else {
+	    unsigned int c;
+	    int bits, l;
+
+	    if (out - buffer > buffer_size - 100) {
+		int indx = out - buffer;
+
+		growBuffer(buffer);
+		out = &buffer[indx];
+	    }
+	    c = CUR_CHAR(l);
+	    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) {
+		*out++  = ((c >> bits) & 0x3F) | 0x80;
+	    }
+	    NEXT;
+	}
+    }
+    *out = 0;
+    return(buffer);
+}
+
+/**
+ * htmlParseEntityRef:
+ * @ctxt:  an HTML parser context
+ * @str:  location to store the entity name
+ *
+ * parse an HTML ENTITY references
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ *
+ * Returns the associated htmlEntityDescPtr if found, or NULL otherwise,
+ *         if non-NULL *str will have to be freed by the caller.
+ */
+const htmlEntityDesc *
+htmlParseEntityRef(htmlParserCtxtPtr ctxt, const xmlChar **str) {
+    const xmlChar *name;
+    const htmlEntityDesc * ent = NULL;
+
+    if (str != NULL) *str = NULL;
+    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
+
+    if (CUR == '&') {
+        NEXT;
+        name = htmlParseName(ctxt);
+	if (name == NULL) {
+	    htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
+	                 "htmlParseEntityRef: no name\n", NULL, NULL);
+	} else {
+	    GROW;
+	    if (CUR == ';') {
+	        if (str != NULL)
+		    *str = name;
+
+		/*
+		 * Lookup the entity in the table.
+		 */
+		ent = htmlEntityLookup(name);
+		if (ent != NULL) /* OK that's ugly !!! */
+		    NEXT;
+	    } else {
+		htmlParseErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING,
+		             "htmlParseEntityRef: expecting ';'\n",
+			     NULL, NULL);
+	        if (str != NULL)
+		    *str = name;
+	    }
+	}
+    }
+    return(ent);
+}
+
+/**
+ * htmlParseAttValue:
+ * @ctxt:  an HTML parser context
+ *
+ * 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
+ *
+ * Returns the AttValue parsed or NULL.
+ */
+
+static xmlChar *
+htmlParseAttValue(htmlParserCtxtPtr ctxt) {
+    xmlChar *ret = NULL;
+
+    if (CUR == '"') {
+        NEXT;
+	ret = htmlParseHTMLAttribute(ctxt, '"');
+        if (CUR != '"') {
+	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+	                 "AttValue: \" expected\n", NULL, NULL);
+	} else
+	    NEXT;
+    } else if (CUR == '\'') {
+        NEXT;
+	ret = htmlParseHTMLAttribute(ctxt, '\'');
+        if (CUR != '\'') {
+	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+	                 "AttValue: ' expected\n", NULL, NULL);
+	} else
+	    NEXT;
+    } else {
+        /*
+	 * That's an HTMLism, the attribute value may not be quoted
+	 */
+	ret = htmlParseHTMLAttribute(ctxt, 0);
+	if (ret == NULL) {
+	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
+	                 "AttValue: no value found\n", NULL, NULL);
+	}
+    }
+    return(ret);
+}
+
+/**
+ * htmlParseSystemLiteral:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML Literal
+ *
+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
+ *
+ * Returns the SystemLiteral parsed or NULL
+ */
+
+static xmlChar *
+htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
+    const xmlChar *q;
+    xmlChar *ret = NULL;
+
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
+			 "Unfinished SystemLiteral\n", NULL, NULL);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
+			 "Unfinished SystemLiteral\n", NULL, NULL);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
+	             " or ' expected\n", NULL, NULL);
+    }
+
+    return(ret);
+}
+
+/**
+ * htmlParsePubidLiteral:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML public literal
+ *
+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
+ *
+ * Returns the PubidLiteral parsed or NULL.
+ */
+
+static xmlChar *
+htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
+    const xmlChar *q;
+    xmlChar *ret = NULL;
+    /*
+     * Name ::= (Letter | '_') (NameChar)*
+     */
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while (IS_PUBIDCHAR_CH(CUR)) NEXT;
+	if (CUR != '"') {
+	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
+	                 "Unfinished PubidLiteral\n", NULL, NULL);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (CUR != '\'') {
+	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
+	                 "Unfinished PubidLiteral\n", NULL, NULL);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    } else {
+	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
+	             "PubidLiteral \" or ' expected\n", NULL, NULL);
+    }
+
+    return(ret);
+}
+
+/**
+ * htmlParseScript:
+ * @ctxt:  an HTML parser context
+ *
+ * parse the content of an HTML SCRIPT or STYLE element
+ * http://www.w3.org/TR/html4/sgml/dtd.html#Script
+ * http://www.w3.org/TR/html4/sgml/dtd.html#StyleSheet
+ * http://www.w3.org/TR/html4/types.html#type-script
+ * http://www.w3.org/TR/html4/types.html#h-6.15
+ * http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1
+ *
+ * Script data ( %Script; in the DTD) can be the content of the SCRIPT
+ * element and the value of intrinsic event attributes. User agents must
+ * not evaluate script data as HTML markup but instead must pass it on as
+ * data to a script engine.
+ * NOTES:
+ * - The content is passed like CDATA
+ * - the attributes for style and scripting "onXXX" are also described
+ *   as CDATA but SGML allows entities references in attributes so their
+ *   processing is identical as other attributes
+ */
+static void
+htmlParseScript(htmlParserCtxtPtr ctxt) {
+    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
+    int nbchar = 0;
+    int cur,l;
+
+    SHRINK;
+    cur = CUR_CHAR(l);
+    while (IS_CHAR_CH(cur)) {
+	if ((cur == '<') && (NXT(1) == '/')) {
+            /*
+             * One should break here, the specification is clear:
+             * Authors should therefore escape "</" within the content.
+             * Escape mechanisms are specific to each scripting or
+             * style sheet language.
+             *
+             * In recovery mode, only break if end tag match the
+             * current tag, effectively ignoring all tags inside the
+             * script/style block and treating the entire block as
+             * CDATA.
+             */
+            if (ctxt->recovery) {
+                if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
+				   xmlStrlen(ctxt->name)) == 0)
+                {
+                    break; /* while */
+                } else {
+		    htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+				 "Element %s embeds close tag\n",
+		                 ctxt->name, NULL);
+		}
+            } else {
+                if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
+                    ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
+                {
+                    break; /* while */
+                }
+            }
+	}
+	COPY_BUF(l,buf,nbchar,cur);
+	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
+	    if (ctxt->sax->cdataBlock!= NULL) {
+		/*
+		 * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
+		 */
+		ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
+	    } else if (ctxt->sax->characters != NULL) {
+		ctxt->sax->characters(ctxt->userData, buf, nbchar);
+	    }
+	    nbchar = 0;
+	}
+	GROW;
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+    }
+
+    if ((!(IS_CHAR_CH(cur))) && (!((cur == 0) && (ctxt->progressive)))) {
+	htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+	                "Invalid char in CDATA 0x%X\n", cur);
+	NEXT;
+    }
+
+    if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+	if (ctxt->sax->cdataBlock!= NULL) {
+	    /*
+	     * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
+	     */
+	    ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
+	} else if (ctxt->sax->characters != NULL) {
+	    ctxt->sax->characters(ctxt->userData, buf, nbchar);
+	}
+    }
+}
+
+
+/**
+ * htmlParseCharData:
+ * @ctxt:  an HTML parser context
+ *
+ * parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+static void
+htmlParseCharData(htmlParserCtxtPtr ctxt) {
+    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
+    int nbchar = 0;
+    int cur, l;
+    int chunk = 0;
+
+    SHRINK;
+    cur = CUR_CHAR(l);
+    while (((cur != '<') || (ctxt->token == '<')) &&
+           ((cur != '&') || (ctxt->token == '&')) &&
+	   (cur != 0)) {
+	if (!(IS_CHAR(cur))) {
+	    htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+	                "Invalid char in CDATA 0x%X\n", cur);
+	} else {
+	    COPY_BUF(l,buf,nbchar,cur);
+	}
+	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
+	    /*
+	     * Ok the segment is to be consumed as chars.
+	     */
+	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+		if (areBlanks(ctxt, buf, nbchar)) {
+		    if (ctxt->sax->ignorableWhitespace != NULL)
+			ctxt->sax->ignorableWhitespace(ctxt->userData,
+			                               buf, nbchar);
+		} else {
+		    htmlCheckParagraph(ctxt);
+		    if (ctxt->sax->characters != NULL)
+			ctxt->sax->characters(ctxt->userData, buf, nbchar);
+		}
+	    }
+	    nbchar = 0;
+	}
+	NEXTL(l);
+        chunk++;
+        if (chunk > HTML_PARSER_BUFFER_SIZE) {
+            chunk = 0;
+            SHRINK;
+            GROW;
+        }
+	cur = CUR_CHAR(l);
+	if (cur == 0) {
+	    SHRINK;
+	    GROW;
+	    cur = CUR_CHAR(l);
+	}
+    }
+    if (nbchar != 0) {
+        buf[nbchar] = 0;
+
+	/*
+	 * Ok the segment is to be consumed as chars.
+	 */
+	if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+	    if (areBlanks(ctxt, buf, nbchar)) {
+		if (ctxt->sax->ignorableWhitespace != NULL)
+		    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
+	    } else {
+		htmlCheckParagraph(ctxt);
+		if (ctxt->sax->characters != NULL)
+		    ctxt->sax->characters(ctxt->userData, buf, nbchar);
+	    }
+	}
+    } else {
+	/*
+	 * Loop detection
+	 */
+	if (cur == 0)
+	    ctxt->instate = XML_PARSER_EOF;
+    }
+}
+
+/**
+ * htmlParseExternalID:
+ * @ctxt:  an HTML parser context
+ * @publicID:  a xmlChar** receiving PubidLiteral
+ *
+ * Parse an External ID or a Public ID
+ *
+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
+ *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
+ *
+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
+ *
+ * Returns the function returns SystemLiteral and in the second
+ *                case publicID receives PubidLiteral, is strict is off
+ *                it is possible to return NULL and have publicID set.
+ */
+
+static xmlChar *
+htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID) {
+    xmlChar *URI = NULL;
+
+    if ((UPPER == 'S') && (UPP(1) == 'Y') &&
+         (UPP(2) == 'S') && (UPP(3) == 'T') &&
+	 (UPP(4) == 'E') && (UPP(5) == 'M')) {
+        SKIP(6);
+	if (!IS_BLANK_CH(CUR)) {
+	    htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
+	                 "Space required after 'SYSTEM'\n", NULL, NULL);
+	}
+        SKIP_BLANKS;
+	URI = htmlParseSystemLiteral(ctxt);
+	if (URI == NULL) {
+	    htmlParseErr(ctxt, XML_ERR_URI_REQUIRED,
+	                 "htmlParseExternalID: SYSTEM, no URI\n", NULL, NULL);
+        }
+    } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
+	       (UPP(2) == 'B') && (UPP(3) == 'L') &&
+	       (UPP(4) == 'I') && (UPP(5) == 'C')) {
+        SKIP(6);
+	if (!IS_BLANK_CH(CUR)) {
+	    htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
+	                 "Space required after 'PUBLIC'\n", NULL, NULL);
+	}
+        SKIP_BLANKS;
+	*publicID = htmlParsePubidLiteral(ctxt);
+	if (*publicID == NULL) {
+	    htmlParseErr(ctxt, XML_ERR_PUBID_REQUIRED,
+	                 "htmlParseExternalID: PUBLIC, no Public Identifier\n",
+			 NULL, NULL);
+	}
+        SKIP_BLANKS;
+        if ((CUR == '"') || (CUR == '\'')) {
+	    URI = htmlParseSystemLiteral(ctxt);
+	}
+    }
+    return(URI);
+}
+
+/**
+ * xmlParsePI:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML Processing Instruction.
+ *
+ * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ */
+static void
+htmlParsePI(htmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = HTML_PARSER_BUFFER_SIZE;
+    int cur, l;
+    const xmlChar *target;
+    xmlParserInputState state;
+    int count = 0;
+
+    if ((RAW == '<') && (NXT(1) == '?')) {
+	state = ctxt->instate;
+        ctxt->instate = XML_PARSER_PI;
+	/*
+	 * this is a Processing Instruction.
+	 */
+	SKIP(2);
+	SHRINK;
+
+	/*
+	 * Parse the target name and check for special support like
+	 * namespace.
+	 */
+        target = htmlParseName(ctxt);
+	if (target != NULL) {
+	    if (RAW == '>') {
+		SKIP(1);
+
+		/*
+		 * SAX: PI detected.
+		 */
+		if ((ctxt->sax) && (!ctxt->disableSAX) &&
+		    (ctxt->sax->processingInstruction != NULL))
+		    ctxt->sax->processingInstruction(ctxt->userData,
+		                                     target, NULL);
+		ctxt->instate = state;
+		return;
+	    }
+	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+	    if (buf == NULL) {
+		htmlErrMemory(ctxt, NULL);
+		ctxt->instate = state;
+		return;
+	    }
+	    cur = CUR;
+	    if (!IS_BLANK(cur)) {
+		htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
+			  "ParsePI: PI %s space expected\n", target, NULL);
+	    }
+            SKIP_BLANKS;
+	    cur = CUR_CHAR(l);
+	    while (IS_CHAR(cur) && (cur != '>')) {
+		if (len + 5 >= size) {
+		    xmlChar *tmp;
+
+		    size *= 2;
+		    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+		    if (tmp == NULL) {
+			htmlErrMemory(ctxt, NULL);
+			xmlFree(buf);
+			ctxt->instate = state;
+			return;
+		    }
+		    buf = tmp;
+		}
+		count++;
+		if (count > 50) {
+		    GROW;
+		    count = 0;
+		}
+		COPY_BUF(l,buf,len,cur);
+		NEXTL(l);
+		cur = CUR_CHAR(l);
+		if (cur == 0) {
+		    SHRINK;
+		    GROW;
+		    cur = CUR_CHAR(l);
+		}
+	    }
+	    buf[len] = 0;
+	    if (cur != '>') {
+		htmlParseErr(ctxt, XML_ERR_PI_NOT_FINISHED,
+		      "ParsePI: PI %s never end ...\n", target, NULL);
+	    } else {
+		SKIP(1);
+
+		/*
+		 * SAX: PI detected.
+		 */
+		if ((ctxt->sax) && (!ctxt->disableSAX) &&
+		    (ctxt->sax->processingInstruction != NULL))
+		    ctxt->sax->processingInstruction(ctxt->userData,
+		                                     target, buf);
+	    }
+	    xmlFree(buf);
+	} else {
+	    htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
+                         "PI is not started correctly", NULL, NULL);
+	}
+	ctxt->instate = state;
+    }
+}
+
+/**
+ * htmlParseComment:
+ * @ctxt:  an HTML parser context
+ *
+ * Parse an XML (SGML) comment <!-- .... -->
+ *
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ */
+static void
+htmlParseComment(htmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len;
+    int size = HTML_PARSER_BUFFER_SIZE;
+    int q, ql;
+    int r, rl;
+    int cur, l;
+    xmlParserInputState state;
+
+    /*
+     * Check that there is a comment right here.
+     */
+    if ((RAW != '<') || (NXT(1) != '!') ||
+        (NXT(2) != '-') || (NXT(3) != '-')) return;
+
+    state = ctxt->instate;
+    ctxt->instate = XML_PARSER_COMMENT;
+    SHRINK;
+    SKIP(4);
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+        htmlErrMemory(ctxt, "buffer allocation failed\n");
+	ctxt->instate = state;
+	return;
+    }
+    q = CUR_CHAR(ql);
+    NEXTL(ql);
+    r = CUR_CHAR(rl);
+    NEXTL(rl);
+    cur = CUR_CHAR(l);
+    len = 0;
+    while (IS_CHAR(cur) &&
+           ((cur != '>') ||
+	    (r != '-') || (q != '-'))) {
+	if (len + 5 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+	        xmlFree(buf);
+	        htmlErrMemory(ctxt, "growing buffer failed\n");
+		ctxt->instate = state;
+		return;
+	    }
+	    buf = tmp;
+	}
+	COPY_BUF(ql,buf,len,q);
+	q = r;
+	ql = rl;
+	r = cur;
+	rl = l;
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+	if (cur == 0) {
+	    SHRINK;
+	    GROW;
+	    cur = CUR_CHAR(l);
+	}
+    }
+    buf[len] = 0;
+    if (!IS_CHAR(cur)) {
+	htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+	             "Comment not terminated \n<!--%.50s\n", buf, NULL);
+	xmlFree(buf);
+    } else {
+        NEXT;
+	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
+	    (!ctxt->disableSAX))
+	    ctxt->sax->comment(ctxt->userData, buf);
+	xmlFree(buf);
+    }
+    ctxt->instate = state;
+}
+
+/**
+ * htmlParseCharRef:
+ * @ctxt:  an HTML parser context
+ *
+ * parse Reference declarations
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ *                  '&#x' [0-9a-fA-F]+ ';'
+ *
+ * Returns the value parsed (as an int)
+ */
+int
+htmlParseCharRef(htmlParserCtxtPtr ctxt) {
+    int val = 0;
+
+    if ((ctxt == NULL) || (ctxt->input == NULL)) {
+	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		     "htmlParseCharRef: context error\n",
+		     NULL, NULL);
+        return(0);
+    }
+    if ((CUR == '&') && (NXT(1) == '#') &&
+        ((NXT(2) == 'x') || NXT(2) == 'X')) {
+	SKIP(3);
+	while (CUR != ';') {
+	    if ((CUR >= '0') && (CUR <= '9'))
+	        val = val * 16 + (CUR - '0');
+	    else if ((CUR >= 'a') && (CUR <= 'f'))
+	        val = val * 16 + (CUR - 'a') + 10;
+	    else if ((CUR >= 'A') && (CUR <= 'F'))
+	        val = val * 16 + (CUR - 'A') + 10;
+	    else {
+	        htmlParseErr(ctxt, XML_ERR_INVALID_HEX_CHARREF,
+		             "htmlParseCharRef: missing semicolumn\n",
+			     NULL, NULL);
+		break;
+	    }
+	    NEXT;
+	}
+	if (CUR == ';')
+	    NEXT;
+    } else if  ((CUR == '&') && (NXT(1) == '#')) {
+	SKIP(2);
+	while (CUR != ';') {
+	    if ((CUR >= '0') && (CUR <= '9'))
+	        val = val * 10 + (CUR - '0');
+	    else {
+	        htmlParseErr(ctxt, XML_ERR_INVALID_DEC_CHARREF,
+		             "htmlParseCharRef: missing semicolumn\n",
+			     NULL, NULL);
+		break;
+	    }
+	    NEXT;
+	}
+	if (CUR == ';')
+	    NEXT;
+    } else {
+	htmlParseErr(ctxt, XML_ERR_INVALID_CHARREF,
+	             "htmlParseCharRef: invalid value\n", NULL, NULL);
+    }
+    /*
+     * Check the value IS_CHAR ...
+     */
+    if (IS_CHAR(val)) {
+        return(val);
+    } else {
+	htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+			"htmlParseCharRef: invalid xmlChar value %d\n",
+			val);
+    }
+    return(0);
+}
+
+
+/**
+ * htmlParseDocTypeDecl:
+ * @ctxt:  an HTML parser context
+ *
+ * parse a DOCTYPE declaration
+ *
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
+ *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ */
+
+static void
+htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlChar *ExternalID = NULL;
+    xmlChar *URI = NULL;
+
+    /*
+     * We know that '<!DOCTYPE' has been detected.
+     */
+    SKIP(9);
+
+    SKIP_BLANKS;
+
+    /*
+     * Parse the DOCTYPE name.
+     */
+    name = htmlParseName(ctxt);
+    if (name == NULL) {
+	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
+	             "htmlParseDocTypeDecl : no DOCTYPE name !\n",
+		     NULL, NULL);
+    }
+    /*
+     * Check that upper(name) == "HTML" !!!!!!!!!!!!!
+     */
+
+    SKIP_BLANKS;
+
+    /*
+     * Check for SystemID and ExternalID
+     */
+    URI = htmlParseExternalID(ctxt, &ExternalID);
+    SKIP_BLANKS;
+
+    /*
+     * We should be at the end of the DOCTYPE declaration.
+     */
+    if (CUR != '>') {
+	htmlParseErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED,
+	             "DOCTYPE improperly terminated\n", NULL, NULL);
+        /* We shouldn't try to resynchronize ... */
+    }
+    NEXT;
+
+    /*
+     * Create or update the document accordingly to the DOCTYPE
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
+	(!ctxt->disableSAX))
+	ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
+
+    /*
+     * Cleanup, since we don't use all those identifiers
+     */
+    if (URI != NULL) xmlFree(URI);
+    if (ExternalID != NULL) xmlFree(ExternalID);
+}
+
+/**
+ * htmlParseAttribute:
+ * @ctxt:  an HTML parser context
+ * @value:  a xmlChar ** used to store the value of the attribute
+ *
+ * parse an attribute
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ *
+ * [25] Eq ::= S? '=' S?
+ *
+ * With namespace:
+ *
+ * [NS 11] Attribute ::= QName Eq AttValue
+ *
+ * Also the case QName == xmlns:??? is handled independently as a namespace
+ * definition.
+ *
+ * Returns the attribute name, and the value in *value.
+ */
+
+static const xmlChar *
+htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
+    const xmlChar *name;
+    xmlChar *val = NULL;
+
+    *value = NULL;
+    name = htmlParseHTMLName(ctxt);
+    if (name == NULL) {
+	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
+	             "error parsing attribute name\n", NULL, NULL);
+        return(NULL);
+    }
+
+    /*
+     * read the value
+     */
+    SKIP_BLANKS;
+    if (CUR == '=') {
+        NEXT;
+	SKIP_BLANKS;
+	val = htmlParseAttValue(ctxt);
+    }
+
+    *value = val;
+    return(name);
+}
+
+/**
+ * htmlCheckEncoding:
+ * @ctxt:  an HTML parser context
+ * @attvalue: the attribute value
+ *
+ * Checks an http-equiv attribute from a Meta tag to detect
+ * the encoding
+ * If a new encoding is detected the parser is switched to decode
+ * it and pass UTF8
+ */
+static void
+htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
+    const xmlChar *encoding;
+
+    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;
+    } else {
+	encoding = xmlStrcasestr(attvalue, BAD_CAST"charset =");
+	if (encoding != NULL)
+	    encoding += 9;
+    }
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+	xmlCharEncodingHandlerPtr handler;
+
+	while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
+
+	if (ctxt->input->encoding != NULL)
+	    xmlFree((xmlChar *) ctxt->input->encoding);
+	ctxt->input->encoding = xmlStrdup(encoding);
+
+	enc = xmlParseCharEncoding((const char *) encoding);
+	/*
+	 * registered set of known encodings
+	 */
+	if (enc != XML_CHAR_ENCODING_ERROR) {
+	    if (((enc == XML_CHAR_ENCODING_UTF16LE) ||
+	         (enc == XML_CHAR_ENCODING_UTF16BE) ||
+		 (enc == XML_CHAR_ENCODING_UCS4LE) ||
+		 (enc == XML_CHAR_ENCODING_UCS4BE)) &&
+		(ctxt->input->buf != NULL) &&
+		(ctxt->input->buf->encoder == NULL)) {
+		htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+		             "htmlCheckEncoding: wrong encoding meta\n",
+			     NULL, NULL);
+	    } else {
+		xmlSwitchEncoding(ctxt, enc);
+	    }
+	    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+	} else {
+	    /*
+	     * fallback for unknown encodings
+	     */
+	    handler = xmlFindCharEncodingHandler((const char *) encoding);
+	    if (handler != NULL) {
+		xmlSwitchToEncoding(ctxt, handler);
+		ctxt->charset = XML_CHAR_ENCODING_UTF8;
+	    } else {
+		ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+	    }
+	}
+
+	if ((ctxt->input->buf != NULL) &&
+	    (ctxt->input->buf->encoder != NULL) &&
+	    (ctxt->input->buf->raw != NULL) &&
+	    (ctxt->input->buf->buffer != NULL)) {
+	    int nbchars;
+	    int processed;
+
+	    /*
+	     * convert as much as possible to the parser reading buffer.
+	     */
+	    processed = ctxt->input->cur - ctxt->input->base;
+	    xmlBufferShrink(ctxt->input->buf->buffer, processed);
+	    nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
+		                       ctxt->input->buf->buffer,
+				       ctxt->input->buf->raw);
+	    if (nbchars < 0) {
+		htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+		             "htmlCheckEncoding: encoder error\n",
+			     NULL, NULL);
+	    }
+	    ctxt->input->base =
+	    ctxt->input->cur = ctxt->input->buf->buffer->content;
+            ctxt->input->end =
+                          &ctxt->input->base[ctxt->input->buf->buffer->use];
+	}
+    }
+}
+
+/**
+ * htmlCheckMeta:
+ * @ctxt:  an HTML parser context
+ * @atts:  the attributes values
+ *
+ * Checks an attributes from a Meta tag
+ */
+static void
+htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
+    int i;
+    const xmlChar *att, *value;
+    int http = 0;
+    const xmlChar *content = NULL;
+
+    if ((ctxt == NULL) || (atts == NULL))
+	return;
+
+    i = 0;
+    att = atts[i++];
+    while (att != NULL) {
+	value = atts[i++];
+	if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"http-equiv"))
+	 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
+	    http = 1;
+	else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
+	    content = value;
+	att = atts[i++];
+    }
+    if ((http) && (content != NULL))
+	htmlCheckEncoding(ctxt, content);
+
+}
+
+/**
+ * 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.
+ *
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ *
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ *
+ * With namespace:
+ *
+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
+ *
+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
+ *
+ * Returns 0 in case of success, -1 in case of error and 1 if discarded
+ */
+
+static int
+htmlParseStartTag(htmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    const xmlChar *attname;
+    xmlChar *attvalue;
+    const xmlChar **atts;
+    int nbatts = 0;
+    int maxatts;
+    int meta = 0;
+    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);
+	return -1;
+    }
+    if (CUR != '<') return -1;
+    NEXT;
+
+    atts = ctxt->atts;
+    maxatts = ctxt->maxatts;
+
+    GROW;
+    name = htmlParseHTMLName(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 != '>') &&
+               (ctxt->instate != XML_PARSER_EOF))
+	    NEXT;
+        return -1;
+    }
+    if (xmlStrEqual(name, BAD_CAST"meta"))
+	meta = 1;
+
+    /*
+     * Check for auto-closure of HTML elements.
+     */
+    htmlAutoClose(ctxt, name);
+
+    /*
+     * Check for implied HTML elements.
+     */
+    htmlCheckImplied(ctxt, name);
+
+    /*
+     * Avoid html at any level > 0, head at any level != 1
+     * or any attempt to recurse body
+     */
+    if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
+	htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+	             "htmlParseStartTag: misplaced <html> tag\n",
+		     name, NULL);
+	discardtag = 1;
+	ctxt->depth++;
+    }
+    if ((ctxt->nameNr != 1) &&
+	(xmlStrEqual(name, BAD_CAST"head"))) {
+	htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+	             "htmlParseStartTag: misplaced <head> tag\n",
+		     name, NULL);
+	discardtag = 1;
+	ctxt->depth++;
+    }
+    if (xmlStrEqual(name, BAD_CAST"body")) {
+	int indx;
+	for (indx = 0;indx < ctxt->nameNr;indx++) {
+	    if (xmlStrEqual(ctxt->nameTab[indx], BAD_CAST"body")) {
+		htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+		             "htmlParseStartTag: misplaced <body> tag\n",
+			     name, NULL);
+		discardtag = 1;
+		ctxt->depth++;
+	    }
+	}
+    }
+
+    /*
+     * Now parse the attributes, it ends up with the ending
+     *
+     * (S Attribute)* S?
+     */
+    SKIP_BLANKS;
+    while ((IS_CHAR_CH(CUR)) &&
+           (CUR != '>') &&
+	   ((CUR != '/') || (NXT(1) != '>'))) {
+	long cons = ctxt->nbChars;
+
+	GROW;
+	attname = htmlParseAttribute(ctxt, &attvalue);
+        if (attname != NULL) {
+
+	    /*
+	     * Well formedness requires at most one declaration of an attribute
+	     */
+	    for (i = 0; i < nbatts;i += 2) {
+	        if (xmlStrEqual(atts[i], attname)) {
+		    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
+		                 "Attribute %s redefined\n", attname, NULL);
+		    if (attvalue != NULL)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+	    }
+
+	    /*
+	     * Add the pair to atts
+	     */
+	    if (atts == NULL) {
+	        maxatts = 22; /* allow for 10 attrs by default */
+	        atts = (const xmlChar **)
+		       xmlMalloc(maxatts * sizeof(xmlChar *));
+		if (atts == NULL) {
+		    htmlErrMemory(ctxt, NULL);
+		    if (attvalue != NULL)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+		ctxt->atts = atts;
+		ctxt->maxatts = maxatts;
+	    } else if (nbatts + 4 > maxatts) {
+	        const xmlChar **n;
+
+	        maxatts *= 2;
+	        n = (const xmlChar **) xmlRealloc((void *) atts,
+					     maxatts * sizeof(const xmlChar *));
+		if (n == NULL) {
+		    htmlErrMemory(ctxt, NULL);
+		    if (attvalue != NULL)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+		atts = n;
+		ctxt->atts = atts;
+		ctxt->maxatts = maxatts;
+	    }
+	    atts[nbatts++] = attname;
+	    atts[nbatts++] = attvalue;
+	    atts[nbatts] = NULL;
+	    atts[nbatts + 1] = NULL;
+	}
+	else {
+	    if (attvalue != NULL)
+	        xmlFree(attvalue);
+	    /* Dump the bogus attribute string up to the next blank or
+	     * the end of the tag. */
+	    while ((IS_CHAR_CH(CUR)) &&
+	           !(IS_BLANK_CH(CUR)) && (CUR != '>') &&
+		   ((CUR != '/') || (NXT(1) != '>')))
+		NEXT;
+	}
+
+failed:
+	SKIP_BLANKS;
+        if (cons == ctxt->nbChars) {
+	    htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	                 "htmlParseStartTag: problem parsing attributes\n",
+			 NULL, NULL);
+	    break;
+	}
+    }
+
+    /*
+     * Handle specific association to the META tag
+     */
+    if (meta && (nbatts != 0))
+	htmlCheckMeta(ctxt, atts);
+
+    /*
+     * SAX: Start of Element !
+     */
+    if (!discardtag) {
+	htmlnamePush(ctxt, name);
+	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL)) {
+	    if (nbatts != 0)
+		ctxt->sax->startElement(ctxt->userData, name, atts);
+	    else
+		ctxt->sax->startElement(ctxt->userData, name, NULL);
+	}
+    }
+
+    if (atts != NULL) {
+        for (i = 1;i < nbatts;i += 2) {
+	    if (atts[i] != NULL)
+		xmlFree((xmlChar *) atts[i]);
+	}
+    }
+
+    return(discardtag);
+}
+
+/**
+ * htmlParseEndTag:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [NS 9] ETag ::= '</' QName S? '>'
+ *
+ * Returns 1 if the current level should be closed.
+ */
+
+static int
+htmlParseEndTag(htmlParserCtxtPtr ctxt)
+{
+    const xmlChar *name;
+    const xmlChar *oldname;
+    int i, ret;
+
+    if ((CUR != '<') || (NXT(1) != '/')) {
+        htmlParseErr(ctxt, XML_ERR_LTSLASH_REQUIRED,
+	             "htmlParseEndTag: '</' not found\n", NULL, NULL);
+        return (0);
+    }
+    SKIP(2);
+
+    name = htmlParseHTMLName(ctxt);
+    if (name == NULL)
+        return (0);
+    /*
+     * We should definitely be at the ending "S? '>'" part
+     */
+    SKIP_BLANKS;
+    if ((!IS_CHAR_CH(CUR)) || (CUR != '>')) {
+        htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
+	             "End tag : expected '>'\n", NULL, NULL);
+	if (ctxt->recovery) {
+	    /*
+	     * We're not at the ending > !!
+	     * Error, unless in recover mode where we search forwards
+	     * until we find a >
+	     */
+	    while (CUR != '\0' && CUR != '>') NEXT;
+	    NEXT;
+	}
+    } else
+        NEXT;
+
+    /*
+     * if we ignored misplaced tags in htmlParseStartTag don't pop them
+     * out now.
+     */
+    if ((ctxt->depth > 0) &&
+        (xmlStrEqual(name, BAD_CAST "html") ||
+         xmlStrEqual(name, BAD_CAST "body") ||
+	 xmlStrEqual(name, BAD_CAST "head"))) {
+	ctxt->depth--;
+	return (0);
+    }
+
+    /*
+     * If the name read is not one of the element in the parsing stack
+     * then return, it's just an error.
+     */
+    for (i = (ctxt->nameNr - 1); i >= 0; i--) {
+        if (xmlStrEqual(name, ctxt->nameTab[i]))
+            break;
+    }
+    if (i < 0) {
+        htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+	             "Unexpected end tag : %s\n", name, NULL);
+        return (0);
+    }
+
+
+    /*
+     * Check for auto-closure of HTML elements.
+     */
+
+    htmlAutoCloseOnClose(ctxt, name);
+
+    /*
+     * Well formedness constraints, opening and closing must match.
+     * With the exception that the autoclose may have popped stuff out
+     * of the stack.
+     */
+    if (!xmlStrEqual(name, ctxt->name)) {
+        if ((ctxt->name != NULL) && (!xmlStrEqual(ctxt->name, name))) {
+            htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+	                 "Opening and ending tag mismatch: %s and %s\n",
+			 name, ctxt->name);
+        }
+    }
+
+    /*
+     * SAX: End of Tag
+     */
+    oldname = ctxt->name;
+    if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
+        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+            ctxt->sax->endElement(ctxt->userData, name);
+        htmlnamePop(ctxt);
+        ret = 1;
+    } else {
+        ret = 0;
+    }
+
+    return (ret);
+}
+
+
+/**
+ * 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.
+ */
+static void
+htmlParseReference(htmlParserCtxtPtr ctxt) {
+    const htmlEntityDesc * ent;
+    xmlChar out[6];
+    const xmlChar *name;
+    if (CUR != '&') return;
+
+    if (NXT(1) == '#') {
+	unsigned int c;
+	int bits, i = 0;
+
+	c = htmlParseCharRef(ctxt);
+	if (c == 0)
+	    return;
+
+        if      (c <    0x80) { out[i++]= c;                bits= -6; }
+        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;
+        }
+	out[i] = 0;
+
+	htmlCheckParagraph(ctxt);
+	if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+	    ctxt->sax->characters(ctxt->userData, out, i);
+    } else {
+	ent = htmlParseEntityRef(ctxt, &name);
+	if (name == NULL) {
+	    htmlCheckParagraph(ctxt);
+	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+	        ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
+	    return;
+	}
+	if ((ent == NULL) || !(ent->value > 0)) {
+	    htmlCheckParagraph(ctxt);
+	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
+		ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
+		ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
+		/* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
+	    }
+	} else {
+	    unsigned int c;
+	    int bits, i = 0;
+
+	    c = ent->value;
+	    if      (c <    0x80)
+	            { out[i++]= c;                bits= -6; }
+	    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;
+	    }
+	    out[i] = 0;
+
+	    htmlCheckParagraph(ctxt);
+	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+		ctxt->sax->characters(ctxt->userData, out, i);
+	}
+    }
+}
+
+/**
+ * htmlParseContent:
+ * @ctxt:  an HTML parser context
+ *
+ * Parse a content: comment, sub-element, reference or text.
+ * Kept for compatibility with old code
+ */
+
+static void
+htmlParseContent(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);
+		return;
+	    }
+	    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;
+
+	        if (currentNode != NULL)
+	            xmlFree(currentNode);
+	        return;
+	    }
+
+	    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)))
+	     {
+	    if (currentNode != NULL) xmlFree(currentNode);
+	    return;
+	}
+
+	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 == '<') {
+		htmlParseElement(ctxt);
+	    }
+
+	    /*
+	     * 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);
+}
+
+/**
+ * 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
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ */
+
+void
+htmlParseElement(htmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlChar *currentNode = NULL;
+    const htmlElemDesc * info;
+    htmlParserNodeInfo node_info;
+    int failed;
+    int depth;
+    const xmlChar *oldptr;
+
+    if ((ctxt == NULL) || (ctxt->input == NULL)) {
+	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		     "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 +
+                          (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);
+	}
+
+	/*
+	 * Capture end position and add node
+	 */
+	if (ctxt->record_info) {
+	   node_info.end_pos = ctxt->input->consumed +
+			      (CUR_PTR - ctxt->input->base);
+	   node_info.end_line = ctxt->input->line;
+	   node_info.node = ctxt->node;
+	   xmlParserAddNodeInfo(ctxt, &node_info);
+	}
+	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;
+    }
+
+    /*
+     * Parse the content of the element:
+     */
+    currentNode = xmlStrdup(ctxt->name);
+    depth = ctxt->nameNr;
+    while (IS_CHAR_CH(CUR)) {
+	oldptr = ctxt->input->cur;
+	htmlParseContent(ctxt);
+	if (oldptr==ctxt->input->cur) break;
+	if (ctxt->nameNr < depth) break;
+    }
+
+    /*
+     * Capture end position and add node
+     */
+    if ( currentNode != NULL && ctxt->record_info ) {
+       node_info.end_pos = ctxt->input->consumed +
+                          (CUR_PTR - ctxt->input->base);
+       node_info.end_line = ctxt->input->line;
+       node_info.node = ctxt->node;
+       xmlParserAddNodeInfo(ctxt, &node_info);
+    }
+    if (!IS_CHAR_CH(CUR)) {
+	htmlAutoCloseOnEnd(ctxt);
+    }
+
+    if (currentNode != NULL)
+	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).
+ *
+ * Returns 0, -1 in case of error. the parser context is augmented
+ *                as a result of the parsing.
+ */
+
+int
+htmlParseDocument(htmlParserCtxtPtr ctxt) {
+    xmlChar start[4];
+    xmlCharEncoding enc;
+    xmlDtdPtr dtd;
+
+    xmlInitParser();
+
+    htmlDefaultSAXHandlerInit();
+
+    if ((ctxt == NULL) || (ctxt->input == NULL)) {
+	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		     "htmlParseDocument: context error\n", NULL, NULL);
+	return(XML_ERR_INTERNAL_ERROR);
+    }
+    ctxt->html = 1;
+    ctxt->linenumbers = 1;
+    GROW;
+    /*
+     * SAX: beginning of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
+
+    if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
+	/*
+	 * Get the 4 first bytes and decode the charset
+	 * if enc != XML_CHAR_ENCODING_NONE
+	 * plug some encoding conversion routines.
+	 */
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(&start[0], 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+    /*
+     * Wipe out everything which is before the first '<'
+     */
+    SKIP_BLANKS;
+    if (CUR == 0) {
+	htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY,
+	             "Document is empty\n", NULL, NULL);
+    }
+
+    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
+	ctxt->sax->startDocument(ctxt->userData);
+
+
+    /*
+     * Parse possible comments and PIs before any content
+     */
+    while (((CUR == '<') && (NXT(1) == '!') &&
+            (NXT(2) == '-') && (NXT(3) == '-')) ||
+	   ((CUR == '<') && (NXT(1) == '?'))) {
+        htmlParseComment(ctxt);
+        htmlParsePI(ctxt);
+	SKIP_BLANKS;
+    }
+
+
+    /*
+     * Then possibly doc type declaration(s) and more Misc
+     * (doctypedecl Misc*)?
+     */
+    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')) {
+	htmlParseDocTypeDecl(ctxt);
+    }
+    SKIP_BLANKS;
+
+    /*
+     * Parse possible comments and PIs before any content
+     */
+    while (((CUR == '<') && (NXT(1) == '!') &&
+            (NXT(2) == '-') && (NXT(3) == '-')) ||
+	   ((CUR == '<') && (NXT(1) == '?'))) {
+        htmlParseComment(ctxt);
+        htmlParsePI(ctxt);
+	SKIP_BLANKS;
+    }
+
+    /*
+     * Time to start parsing the tree itself
+     */
+    htmlParseContentInternal(ctxt);
+
+    /*
+     * autoclose
+     */
+    if (CUR == 0)
+	htmlAutoCloseOnEnd(ctxt);
+
+
+    /*
+     * SAX: end of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+        ctxt->sax->endDocument(ctxt->userData);
+
+    if (ctxt->myDoc != NULL) {
+	dtd = xmlGetIntSubset(ctxt->myDoc);
+	if (dtd == NULL)
+	    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");
+    }
+    if (! ctxt->wellFormed) return(-1);
+    return(0);
+}
+
+
+/************************************************************************
+ *									*
+ *			Parser contexts handling			*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlInitParserCtxt:
+ * @ctxt:  an HTML parser context
+ *
+ * Initialize a parser context
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+
+static int
+htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
+{
+    htmlSAXHandler *sax;
+
+    if (ctxt == NULL) return(-1);
+    memset(ctxt, 0, sizeof(htmlParserCtxt));
+
+    ctxt->dict = xmlDictCreate();
+    if (ctxt->dict == NULL) {
+        htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+	return(-1);
+    }
+    sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
+    if (sax == NULL) {
+        htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+	return(-1);
+    }
+    else
+        memset(sax, 0, sizeof(htmlSAXHandler));
+
+    /* Allocate the Input stack */
+    ctxt->inputTab = (htmlParserInputPtr *)
+                      xmlMalloc(5 * sizeof(htmlParserInputPtr));
+    if (ctxt->inputTab == NULL) {
+        htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return(-1);
+    }
+    ctxt->inputNr = 0;
+    ctxt->inputMax = 5;
+    ctxt->input = NULL;
+    ctxt->version = NULL;
+    ctxt->encoding = NULL;
+    ctxt->standalone = -1;
+    ctxt->instate = XML_PARSER_START;
+
+    /* Allocate the Node stack */
+    ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
+    if (ctxt->nodeTab == NULL) {
+        htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return(-1);
+    }
+    ctxt->nodeNr = 0;
+    ctxt->nodeMax = 10;
+    ctxt->node = NULL;
+
+    /* Allocate the Name stack */
+    ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
+    if (ctxt->nameTab == NULL) {
+        htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 0;
+	ctxt->name = NULL;
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return(-1);
+    }
+    ctxt->nameNr = 0;
+    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;
+	memcpy(sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1));
+    }
+    ctxt->userData = ctxt;
+    ctxt->myDoc = NULL;
+    ctxt->wellFormed = 1;
+    ctxt->replaceEntities = 0;
+    ctxt->linenumbers = xmlLineNumbersDefaultValue;
+    ctxt->html = 1;
+    ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
+    ctxt->vctxt.userData = ctxt;
+    ctxt->vctxt.error = xmlParserValidityError;
+    ctxt->vctxt.warning = xmlParserValidityWarning;
+    ctxt->record_info = 0;
+    ctxt->validate = 0;
+    ctxt->nbChars = 0;
+    ctxt->checkIndex = 0;
+    ctxt->catalogs = NULL;
+    xmlInitNodeInfoSeq(&ctxt->node_seq);
+    return(0);
+}
+
+/**
+ * htmlFreeParserCtxt:
+ * @ctxt:  an HTML parser context
+ *
+ * Free all the memory used by a parser context. However the parsed
+ * document in ctxt->myDoc is not freed.
+ */
+
+void
+htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
+{
+    xmlFreeParserCtxt(ctxt);
+}
+
+/**
+ * htmlNewParserCtxt:
+ *
+ * Allocate and initialize a new parser context.
+ *
+ * Returns the htmlParserCtxtPtr or NULL in case of allocation error
+ */
+
+htmlParserCtxtPtr
+htmlNewParserCtxt(void)
+{
+    xmlParserCtxtPtr ctxt;
+
+    ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
+    if (ctxt == NULL) {
+        htmlErrMemory(NULL, "NewParserCtxt: out of memory\n");
+	return(NULL);
+    }
+    memset(ctxt, 0, sizeof(xmlParserCtxt));
+    if (htmlInitParserCtxt(ctxt) < 0) {
+        htmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    return(ctxt);
+}
+
+/**
+ * htmlCreateMemoryParserCtxt:
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ *
+ * Create a parser context for an HTML in-memory document.
+ *
+ * Returns the new parser context or NULL
+ */
+htmlParserCtxtPtr
+htmlCreateMemoryParserCtxt(const char *buffer, int size) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+    xmlParserInputBufferPtr buf;
+
+    if (buffer == NULL)
+	return(NULL);
+    if (size <= 0)
+	return(NULL);
+
+    ctxt = htmlNewParserCtxt();
+    if (ctxt == NULL)
+	return(NULL);
+
+    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) return(NULL);
+
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    input->filename = NULL;
+    input->buf = buf;
+    input->base = input->buf->buffer->content;
+    input->cur = input->buf->buffer->content;
+    input->end = &input->buf->buffer->content[input->buf->buffer->use];
+
+    inputPush(ctxt, input);
+    return(ctxt);
+}
+
+/**
+ * htmlCreateDocParserCtxt:
+ * @cur:  a pointer to an array of xmlChar
+ * @encoding:  a free form C string describing the HTML document encoding, or NULL
+ *
+ * Create a parser context for an HTML document.
+ *
+ * TODO: check the need to add encoding handling there
+ *
+ * Returns the new parser context or NULL
+ */
+static htmlParserCtxtPtr
+htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) {
+    int len;
+    htmlParserCtxtPtr ctxt;
+
+    if (cur == NULL)
+	return(NULL);
+    len = xmlStrlen(cur);
+    ctxt = htmlCreateMemoryParserCtxt((char *)cur, len);
+    if (ctxt == NULL)
+	return(NULL);
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+	xmlCharEncodingHandlerPtr handler;
+
+	if (ctxt->input->encoding != NULL)
+	    xmlFree((xmlChar *) ctxt->input->encoding);
+	ctxt->input->encoding = xmlStrdup((const xmlChar *) encoding);
+
+	enc = xmlParseCharEncoding(encoding);
+	/*
+	 * registered set of known encodings
+	 */
+	if (enc != XML_CHAR_ENCODING_ERROR) {
+	    xmlSwitchEncoding(ctxt, enc);
+	    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+		htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+		             "Unsupported encoding %s\n",
+			     (const xmlChar *) encoding, NULL);
+	    }
+	} else {
+	    /*
+	     * fallback for unknown encodings
+	     */
+	    handler = xmlFindCharEncodingHandler((const char *) encoding);
+	    if (handler != NULL) {
+		xmlSwitchToEncoding(ctxt, handler);
+	    } else {
+		htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+		             "Unsupported encoding %s\n",
+			     (const xmlChar *) encoding, NULL);
+	    }
+	}
+    }
+    return(ctxt);
+}
+
+#ifdef LIBXML_PUSH_ENABLED
+/************************************************************************
+ *									*
+ *	Progressive parsing interfaces				*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlParseLookupSequence:
+ * @ctxt:  an HTML parser context
+ * @first:  the first char to lookup
+ * @next:  the next char to lookup or zero
+ * @third:  the next char to lookup or zero
+ * @comment: flag to force checking inside comments
+ *
+ * Try to find if a sequence (first, next, third) or  just (first next) or
+ * (first) 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.
+ * This is basically similar to xmlParseLookupSequence()
+ *
+ * Returns the index to the current parsing point if the full sequence
+ *      is available, -1 otherwise.
+ */
+static int
+htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
+                        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);
+
+    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;
+    }
+
+    /* 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 (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;
+#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);
+#endif
+            return (base - (in->cur - in->base));
+        }
+    }
+    if ((!incomment) && (!invalue))
+        ctxt->checkIndex = base;
+#ifdef DEBUG_PUSH
+    if (next == 0)
+        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);
+#endif
+    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);
+}
+
+/**
+ * htmlParseTryOrFinish:
+ * @ctxt:  an HTML parser context
+ * @terminate:  last chunk indicator
+ *
+ * Try to progress on parsing
+ *
+ * Returns zero if no parsing was possible
+ */
+static int
+htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
+    int ret = 0;
+    htmlParserInputPtr in;
+    int avail = 0;
+    xmlChar cur, next;
+
+#ifdef DEBUG_PUSH
+    switch (ctxt->instate) {
+	case XML_PARSER_EOF:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try EOF\n"); break;
+	case XML_PARSER_START:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try START\n"); break;
+	case XML_PARSER_MISC:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try MISC\n");break;
+	case XML_PARSER_COMMENT:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try COMMENT\n");break;
+	case XML_PARSER_PROLOG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try PROLOG\n");break;
+	case XML_PARSER_START_TAG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try START_TAG\n");break;
+	case XML_PARSER_CONTENT:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try CONTENT\n");break;
+	case XML_PARSER_CDATA_SECTION:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try CDATA_SECTION\n");break;
+	case XML_PARSER_END_TAG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try END_TAG\n");break;
+	case XML_PARSER_ENTITY_DECL:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try ENTITY_DECL\n");break;
+	case XML_PARSER_ENTITY_VALUE:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try ENTITY_VALUE\n");break;
+	case XML_PARSER_ATTRIBUTE_VALUE:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try ATTRIBUTE_VALUE\n");break;
+	case XML_PARSER_DTD:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try DTD\n");break;
+	case XML_PARSER_EPILOG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try EPILOG\n");break;
+	case XML_PARSER_PI:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try PI\n");break;
+	case XML_PARSER_SYSTEM_LITERAL:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "HPP: try SYSTEM_LITERAL\n");break;
+    }
+#endif
+
+    while (1) {
+
+	in = ctxt->input;
+	if (in == NULL) break;
+	if (in->buf == NULL)
+	    avail = in->length - (in->cur - in->base);
+	else
+	    avail = in->buf->buffer->use - (in->cur - in->base);
+	if ((avail == 0) && (terminate)) {
+	    htmlAutoCloseOnEnd(ctxt);
+	    if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
+		/*
+		 * SAX: end of the document processing.
+		 */
+		ctxt->instate = XML_PARSER_EOF;
+		if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+		    ctxt->sax->endDocument(ctxt->userData);
+	    }
+	}
+        if (avail < 1)
+	    goto done;
+	cur = in->cur[0];
+	if (cur == 0) {
+	    SKIP(1);
+	    continue;
+	}
+
+        switch (ctxt->instate) {
+            case XML_PARSER_EOF:
+	        /*
+		 * Document parsing is done !
+		 */
+	        goto done;
+            case XML_PARSER_START:
+	        /*
+		 * Very first chars read from the document flow.
+		 */
+		cur = in->cur[0];
+		if (IS_BLANK_CH(cur)) {
+		    SKIP_BLANKS;
+		    if (in->buf == NULL)
+			avail = in->length - (in->cur - in->base);
+		    else
+			avail = in->buf->buffer->use - (in->cur - in->base);
+		}
+		if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+		    ctxt->sax->setDocumentLocator(ctxt->userData,
+						  &xmlDefaultSAXLocator);
+		if ((ctxt->sax) && (ctxt->sax->startDocument) &&
+	            (!ctxt->disableSAX))
+		    ctxt->sax->startDocument(ctxt->userData);
+
+		cur = in->cur[0];
+		next = in->cur[1];
+		if ((cur == '<') && (next == '!') &&
+		    (UPP(2) == 'D') && (UPP(3) == 'O') &&
+		    (UPP(4) == 'C') && (UPP(5) == 'T') &&
+		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
+		    (UPP(8) == 'E')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing internal subset\n");
+#endif
+		    htmlParseDocTypeDecl(ctxt);
+		    ctxt->instate = XML_PARSER_PROLOG;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering PROLOG\n");
+#endif
+                } else {
+		    ctxt->instate = XML_PARSER_MISC;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering MISC\n");
+#endif
+		}
+		break;
+            case XML_PARSER_MISC:
+		SKIP_BLANKS;
+		if (in->buf == NULL)
+		    avail = in->length - (in->cur - in->base);
+		else
+		    avail = in->buf->buffer->use - (in->cur - in->base);
+		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, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing Comment\n");
+#endif
+		    htmlParseComment(ctxt);
+		    ctxt->instate = XML_PARSER_MISC;
+	        } else if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing PI\n");
+#endif
+		    htmlParsePI(ctxt);
+		    ctxt->instate = XML_PARSER_MISC;
+		} else if ((cur == '<') && (next == '!') &&
+		    (UPP(2) == 'D') && (UPP(3) == 'O') &&
+		    (UPP(4) == 'C') && (UPP(5) == 'T') &&
+		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
+		    (UPP(8) == 'E')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing internal subset\n");
+#endif
+		    htmlParseDocTypeDecl(ctxt);
+		    ctxt->instate = XML_PARSER_PROLOG;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering PROLOG\n");
+#endif
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 9)) {
+		    goto done;
+		} else {
+		    ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering START_TAG\n");
+#endif
+		}
+		break;
+            case XML_PARSER_PROLOG:
+		SKIP_BLANKS;
+		if (in->buf == NULL)
+		    avail = in->length - (in->cur - in->base);
+		else
+		    avail = in->buf->buffer->use - (in->cur - in->base);
+		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, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing Comment\n");
+#endif
+		    htmlParseComment(ctxt);
+		    ctxt->instate = XML_PARSER_PROLOG;
+	        } else if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing PI\n");
+#endif
+		    htmlParsePI(ctxt);
+		    ctxt->instate = XML_PARSER_PROLOG;
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 4)) {
+		    goto done;
+		} else {
+		    ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering START_TAG\n");
+#endif
+		}
+		break;
+            case XML_PARSER_EPILOG:
+		if (in->buf == NULL)
+		    avail = in->length - (in->cur - in->base);
+		else
+		    avail = in->buf->buffer->use - (in->cur - in->base);
+		if (avail < 1)
+		    goto done;
+		cur = in->cur[0];
+		if (IS_BLANK_CH(cur)) {
+		    htmlParseCharData(ctxt);
+		    goto done;
+		}
+		if (avail < 2)
+		    goto done;
+		next = in->cur[1];
+	        if ((cur == '<') && (next == '!') &&
+		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing Comment\n");
+#endif
+		    htmlParseComment(ctxt);
+		    ctxt->instate = XML_PARSER_EPILOG;
+	        } else if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: Parsing PI\n");
+#endif
+		    htmlParsePI(ctxt);
+		    ctxt->instate = XML_PARSER_EPILOG;
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 4)) {
+		    goto done;
+		} else {
+		    ctxt->errNo = XML_ERR_DOCUMENT_END;
+		    ctxt->wellFormed = 0;
+		    ctxt->instate = XML_PARSER_EOF;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering EOF\n");
+#endif
+		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+			ctxt->sax->endDocument(ctxt->userData);
+		    goto done;
+		}
+		break;
+            case XML_PARSER_START_TAG: {
+	        const xmlChar *name;
+		int failed;
+		const htmlElemDesc * info;
+
+		if (avail < 2)
+		    goto done;
+		cur = in->cur[0];
+	        if (cur != '<') {
+		    ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering CONTENT\n");
+#endif
+		    break;
+		}
+		if (in->cur[1] == '/') {
+		    ctxt->instate = XML_PARSER_END_TAG;
+		    ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering END_TAG\n");
+#endif
+		    break;
+		}
+		if ((!terminate) &&
+		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+		    goto done;
+
+		failed = htmlParseStartTag(ctxt);
+		name = ctxt->name;
+		if ((failed == -1) ||
+		    (name == NULL)) {
+		    if (CUR == '>')
+			NEXT;
+		    break;
+		}
+
+		/*
+		 * 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);
+		    ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering CONTENT\n");
+#endif
+		    break;
+		}
+
+		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);
+		    }
+
+		    ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "HPP: entering CONTENT\n");
+#endif
+		    break;
+		}
+
+		/*
+		 * 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);
+		}
+		ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+                break;
+	    }
+            case XML_PARSER_CONTENT: {
+		long cons;
+                /*
+		 * Handle preparsed entities and charRef
+		 */
+		if (ctxt->token != 0) {
+		    xmlChar chr[2] = { 0 , 0 } ;
+
+		    chr[0] = (xmlChar) ctxt->token;
+		    htmlCheckParagraph(ctxt);
+		    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+			ctxt->sax->characters(ctxt->userData, chr, 1);
+		    ctxt->token = 0;
+		    ctxt->checkIndex = 0;
+		}
+		if ((avail == 1) && (terminate)) {
+		    cur = in->cur[0];
+		    if ((cur != '<') && (cur != '&')) {
+			if (ctxt->sax != NULL) {
+			    if (IS_BLANK_CH(cur)) {
+				if (ctxt->sax->ignorableWhitespace != NULL)
+				    ctxt->sax->ignorableWhitespace(
+					    ctxt->userData, &cur, 1);
+			    } else {
+				htmlCheckParagraph(ctxt);
+				if (ctxt->sax->characters != NULL)
+				    ctxt->sax->characters(
+					    ctxt->userData, &cur, 1);
+			    }
+			}
+			ctxt->token = 0;
+			ctxt->checkIndex = 0;
+			in->cur++;
+			break;
+		    }
+		}
+		if (avail < 2)
+		    goto done;
+		cur = in->cur[0];
+		next = in->cur[1];
+		cons = ctxt->nbChars;
+		if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) ||
+		    (xmlStrEqual(ctxt->name, BAD_CAST"style"))) {
+		    /*
+		     * Handle SCRIPT/STYLE separately
+		     */
+		    if (!terminate) {
+		        int idx;
+			xmlChar val;
+
+			idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0, 1);
+			if (idx < 0)
+			    goto done;
+		        val = in->cur[idx + 2];
+			if (val == 0) /* bad cut of input */
+			    goto done;
+		    }
+		    htmlParseScript(ctxt);
+		    if ((cur == '<') && (next == '/')) {
+			ctxt->instate = XML_PARSER_END_TAG;
+			ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: entering END_TAG\n");
+#endif
+			break;
+		    }
+		} else {
+		    /*
+		     * Sometimes DOCTYPE arrives in the middle of the document
+		     */
+		    if ((cur == '<') && (next == '!') &&
+			(UPP(2) == 'D') && (UPP(3) == 'O') &&
+			(UPP(4) == 'C') && (UPP(5) == 'T') &&
+			(UPP(6) == 'Y') && (UPP(7) == 'P') &&
+			(UPP(8) == 'E')) {
+			if ((!terminate) &&
+			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			    goto done;
+			htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+			             "Misplaced DOCTYPE declaration\n",
+				     BAD_CAST "DOCTYPE" , NULL);
+			htmlParseDocTypeDecl(ctxt);
+		    } else if ((cur == '<') && (next == '!') &&
+			(in->cur[2] == '-') && (in->cur[3] == '-')) {
+			if ((!terminate) &&
+			    (htmlParseLookupSequence(
+				ctxt, '-', '-', '>', 1, 1) < 0))
+			    goto done;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: Parsing Comment\n");
+#endif
+			htmlParseComment(ctxt);
+			ctxt->instate = XML_PARSER_CONTENT;
+		    } else if ((cur == '<') && (next == '?')) {
+			if ((!terminate) &&
+			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+			    goto done;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: Parsing PI\n");
+#endif
+			htmlParsePI(ctxt);
+			ctxt->instate = XML_PARSER_CONTENT;
+		    } else if ((cur == '<') && (next == '!') && (avail < 4)) {
+			goto done;
+		    } else if ((cur == '<') && (next == '/')) {
+			ctxt->instate = XML_PARSER_END_TAG;
+			ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: entering END_TAG\n");
+#endif
+			break;
+		    } else if (cur == '<') {
+			ctxt->instate = XML_PARSER_START_TAG;
+			ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: entering START_TAG\n");
+#endif
+			break;
+		    } else if (cur == '&') {
+			if ((!terminate) &&
+			    (htmlParseLookupChars(ctxt,
+                                                  BAD_CAST "; >/", 4) < 0))
+			    goto done;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: Parsing Reference\n");
+#endif
+			/* TODO: check generation of subtrees if noent !!! */
+			htmlParseReference(ctxt);
+		    } else {
+		        /*
+			 * check that the text sequence is complete
+			 * before handing out the data to the parser
+			 * to avoid problems with erroneous end of
+			 * data detection.
+			 */
+			if ((!terminate) &&
+                            (htmlParseLookupChars(ctxt, BAD_CAST "<&", 2) < 0))
+			    goto done;
+			ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"HPP: Parsing char data\n");
+#endif
+			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);
+		    }
+		    NEXT;
+		    break;
+		}
+
+		break;
+	    }
+            case XML_PARSER_END_TAG:
+		if (avail < 2)
+		    goto done;
+		if ((!terminate) &&
+		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
+		    goto done;
+		htmlParseEndTag(ctxt);
+		if (ctxt->nameNr == 0) {
+		    ctxt->instate = XML_PARSER_EPILOG;
+		} else {
+		    ctxt->instate = XML_PARSER_CONTENT;
+		}
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+	        break;
+            case XML_PARSER_CDATA_SECTION:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == CDATA\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_DTD:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == DTD\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_COMMENT:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == COMMENT\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_PI:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == PI\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_ENTITY_DECL:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == ENTITY_DECL\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_ENTITY_VALUE:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == ENTITY_VALUE\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering DTD\n");
+#endif
+		break;
+            case XML_PARSER_ATTRIBUTE_VALUE:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == ATTRIBUTE_VALUE\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_START_TAG;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering START_TAG\n");
+#endif
+		break;
+	    case XML_PARSER_SYSTEM_LITERAL:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		    "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+	    case XML_PARSER_IGNORE:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == XML_PARSER_IGNORE\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+	    case XML_PARSER_PUBLIC_LITERAL:
+		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+			"HPP: internal error, state == XML_PARSER_LITERAL\n",
+			     NULL, NULL);
+		ctxt->instate = XML_PARSER_CONTENT;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"HPP: entering CONTENT\n");
+#endif
+		break;
+
+	}
+    }
+done:
+    if ((avail == 0) && (terminate)) {
+	htmlAutoCloseOnEnd(ctxt);
+	if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
+	    /*
+	     * SAX: end of the document processing.
+	     */
+	    ctxt->instate = XML_PARSER_EOF;
+	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+		ctxt->sax->endDocument(ctxt->userData);
+	}
+    }
+    if ((ctxt->myDoc != NULL) &&
+	((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
+	 (ctxt->instate == XML_PARSER_EPILOG))) {
+	xmlDtdPtr dtd;
+	dtd = xmlGetIntSubset(ctxt->myDoc);
+	if (dtd == NULL)
+	    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");
+    }
+#ifdef DEBUG_PUSH
+    xmlGenericError(xmlGenericErrorContext, "HPP: done %d\n", ret);
+#endif
+    return(ret);
+}
+
+/**
+ * htmlParseChunk:
+ * @ctxt:  an HTML parser context
+ * @chunk:  an char array
+ * @size:  the size in byte of the chunk
+ * @terminate:  last chunk indicator
+ *
+ * Parse a Chunk of memory
+ *
+ * Returns zero if no error, the xmlParserErrors otherwise.
+ */
+int
+htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
+              int terminate) {
+    if ((ctxt == NULL) || (ctxt->input == NULL)) {
+	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		     "htmlParseChunk: context error\n", NULL, NULL);
+	return(XML_ERR_INTERNAL_ERROR);
+    }
+    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;
+
+	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+	if (res < 0) {
+	    ctxt->errNo = XML_PARSER_EOF;
+	    ctxt->disableSAX = 1;
+	    return (XML_PARSER_EOF);
+	}
+	ctxt->input->base = ctxt->input->buf->buffer->content + base;
+	ctxt->input->cur = ctxt->input->base + cur;
+	ctxt->input->end =
+	  &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
+#ifdef DEBUG_PUSH
+	xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
+#endif
+
+#if 0
+	if ((terminate) || (ctxt->input->buf->buffer->use > 80))
+	    htmlParseTryOrFinish(ctxt, terminate);
+#endif
+    } 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) {
+		    htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+			         "encoder error\n", NULL, NULL);
+		    return(XML_ERR_INVALID_ENCODING);
+		}
+	    }
+	}
+    }
+    htmlParseTryOrFinish(ctxt, terminate);
+    if (terminate) {
+	if ((ctxt->instate != XML_PARSER_EOF) &&
+	    (ctxt->instate != XML_PARSER_EPILOG) &&
+	    (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);
+}
+
+/************************************************************************
+ *									*
+ *			User entry points				*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlCreatePushParserCtxt:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @chunk:  a pointer to an array of chars
+ * @size:  number of chars in the array
+ * @filename:  an optional file name or URI
+ * @enc:  an optional encoding
+ *
+ * Create a parser context for using the HTML parser in push mode
+ * The value of @filename is used for fetching external entities
+ * and error/warning reports.
+ *
+ * Returns the new parser context or NULL
+ */
+htmlParserCtxtPtr
+htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
+                         const char *chunk, int size, const char *filename,
+			 xmlCharEncoding enc) {
+    htmlParserCtxtPtr ctxt;
+    htmlParserInputPtr inputStream;
+    xmlParserInputBufferPtr buf;
+
+    xmlInitParser();
+
+    buf = xmlAllocParserInputBuffer(enc);
+    if (buf == NULL) return(NULL);
+
+    ctxt = htmlNewParserCtxt();
+    if (ctxt == NULL) {
+	xmlFreeParserInputBuffer(buf);
+	return(NULL);
+    }
+    if(enc==XML_CHAR_ENCODING_UTF8 || buf->encoder)
+	ctxt->charset=XML_CHAR_ENCODING_UTF8;
+    if (sax != NULL) {
+	if (ctxt->sax != (xmlSAXHandlerPtr) &htmlDefaultSAXHandler)
+	    xmlFree(ctxt->sax);
+	ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler));
+	if (ctxt->sax == NULL) {
+	    xmlFree(buf);
+	    xmlFree(ctxt);
+	    return(NULL);
+	}
+	memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
+	if (user_data != NULL)
+	    ctxt->userData = user_data;
+    }
+    if (filename == NULL) {
+	ctxt->directory = NULL;
+    } else {
+        ctxt->directory = xmlParserGetDirectory(filename);
+    }
+
+    inputStream = htmlNewInputStream(ctxt);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	xmlFree(buf);
+	return(NULL);
+    }
+
+    if (filename == NULL)
+	inputStream->filename = NULL;
+    else
+	inputStream->filename = (char *)
+	    xmlCanonicPath((const xmlChar *) filename);
+    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];
+
+    inputPush(ctxt, inputStream);
+
+    if ((size > 0) && (chunk != NULL) && (ctxt->input != 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);
+
+	ctxt->input->base = ctxt->input->buf->buffer->content + base;
+	ctxt->input->cur = ctxt->input->base + cur;
+	ctxt->input->end =
+	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
+#ifdef DEBUG_PUSH
+	xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
+#endif
+    }
+    ctxt->progressive = 1;
+
+    return(ctxt);
+}
+#endif /* LIBXML_PUSH_ENABLED */
+
+/**
+ * htmlSAXParseDoc:
+ * @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.
+ *
+ * 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.
+ */
+
+htmlDocPtr
+htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) {
+    htmlDocPtr ret;
+    htmlParserCtxtPtr ctxt;
+
+    xmlInitParser();
+
+    if (cur == NULL) return(NULL);
+
+
+    ctxt = htmlCreateDocParserCtxt(cur, encoding);
+    if (ctxt == NULL) return(NULL);
+    if (sax != NULL) {
+        if (ctxt->sax != NULL) xmlFree (ctxt->sax);
+        ctxt->sax = sax;
+        ctxt->userData = userData;
+    }
+
+    htmlParseDocument(ctxt);
+    ret = ctxt->myDoc;
+    if (sax != NULL) {
+	ctxt->sax = NULL;
+	ctxt->userData = NULL;
+    }
+    htmlFreeParserCtxt(ctxt);
+
+    return(ret);
+}
+
+/**
+ * htmlParseDoc:
+ * @cur:  a pointer to an array of xmlChar
+ * @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
+ */
+
+htmlDocPtr
+htmlParseDoc(xmlChar *cur, const char *encoding) {
+    return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
+}
+
+
+/**
+ * htmlCreateFileParserCtxt:
+ * @filename:  the filename
+ * @encoding:  a free form C string describing the HTML document encoding, or NULL
+ *
+ * Create a parser context for a file content.
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+htmlParserCtxtPtr
+htmlCreateFileParserCtxt(const char *filename, const char *encoding)
+{
+    htmlParserCtxtPtr ctxt;
+    htmlParserInputPtr inputStream;
+    char *canonicFilename;
+    /* htmlCharEncoding enc; */
+    xmlChar *content, *content_line = (xmlChar *) "charset=";
+
+    if (filename == NULL)
+        return(NULL);
+
+    ctxt = htmlNewParserCtxt();
+    if (ctxt == NULL) {
+	return(NULL);
+    }
+    canonicFilename = (char *) xmlCanonicPath((const xmlChar *) filename);
+    if (canonicFilename == NULL) {
+#ifdef LIBXML_SAX1_ENABLED
+	if (xmlDefaultSAXHandler.error != NULL) {
+	    xmlDefaultSAXHandler.error(NULL, "out of memory\n");
+	}
+#endif
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    inputStream = xmlLoadExternalEntity(canonicFilename, NULL, ctxt);
+    xmlFree(canonicFilename);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    inputPush(ctxt, inputStream);
+
+    /* set encoding */
+    if (encoding) {
+        content = xmlMallocAtomic (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);
+}
+
+/**
+ * htmlSAXParseFile:
+ * @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.
+ *
+ * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ *
+ * Returns the resulting document tree unless SAX is NULL or the document is
+ *     not well formed.
+ */
+
+htmlDocPtr
+htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
+                 void *userData) {
+    htmlDocPtr ret;
+    htmlParserCtxtPtr ctxt;
+    htmlSAXHandlerPtr oldsax = NULL;
+
+    xmlInitParser();
+
+    ctxt = htmlCreateFileParserCtxt(filename, encoding);
+    if (ctxt == NULL) return(NULL);
+    if (sax != NULL) {
+	oldsax = ctxt->sax;
+        ctxt->sax = sax;
+        ctxt->userData = userData;
+    }
+
+    htmlParseDocument(ctxt);
+
+    ret = ctxt->myDoc;
+    if (sax != NULL) {
+        ctxt->sax = oldsax;
+        ctxt->userData = NULL;
+    }
+    htmlFreeParserCtxt(ctxt);
+
+    return(ret);
+}
+
+/**
+ * htmlParseFile:
+ * @filename:  the filename
+ * @encoding:  a free form C string describing the HTML document encoding, or NULL
+ *
+ * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ *
+ * Returns the resulting document tree
+ */
+
+htmlDocPtr
+htmlParseFile(const char *filename, const char *encoding) {
+    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);
+}
+
+/**
+ * htmlElementAllowedHere:
+ * @parent: HTML parent element
+ * @elt: HTML element
+ *
+ * Checks whether an HTML element may be a direct child of a parent element.
+ * Note - doesn't check for deprecated elements
+ *
+ * Returns 1 if allowed; 0 otherwise.
+ */
+int
+htmlElementAllowedHere(const htmlElemDesc* parent, const xmlChar* elt) {
+  const char** p ;
+
+  if ( ! elt || ! parent || ! parent->subelts )
+	return 0 ;
+
+  for ( p = parent->subelts; *p; ++p )
+    if ( !xmlStrcmp((const xmlChar *)*p, elt) )
+      return 1 ;
+
+  return 0 ;
+}
+/**
+ * htmlElementStatusHere:
+ * @parent: HTML parent element
+ * @elt: HTML element
+ *
+ * Checks whether an HTML element may be a direct child of a parent element.
+ * and if so whether it is valid or deprecated.
+ *
+ * Returns one of HTML_VALID, HTML_DEPRECATED, HTML_INVALID
+ */
+htmlStatus
+htmlElementStatusHere(const htmlElemDesc* parent, const htmlElemDesc* elt) {
+  if ( ! parent || ! elt )
+    return HTML_INVALID ;
+  if ( ! htmlElementAllowedHere(parent, (const xmlChar*) elt->name ) )
+    return HTML_INVALID ;
+
+  return ( elt->dtd == 0 ) ? HTML_VALID : HTML_DEPRECATED ;
+}
+/**
+ * htmlAttrAllowed:
+ * @elt: HTML element
+ * @attr: HTML attribute
+ * @legacy: whether to allow deprecated attributes
+ *
+ * Checks whether an attribute is valid for an element
+ * Has full knowledge of Required and Deprecated attributes
+ *
+ * Returns one of HTML_REQUIRED, HTML_VALID, HTML_DEPRECATED, HTML_INVALID
+ */
+htmlStatus
+htmlAttrAllowed(const htmlElemDesc* elt, const xmlChar* attr, int legacy) {
+  const char** p ;
+
+  if ( !elt || ! attr )
+	return HTML_INVALID ;
+
+  if ( elt->attrs_req )
+    for ( p = elt->attrs_req; *p; ++p)
+      if ( !xmlStrcmp((const xmlChar*)*p, attr) )
+        return HTML_REQUIRED ;
+
+  if ( elt->attrs_opt )
+    for ( p = elt->attrs_opt; *p; ++p)
+      if ( !xmlStrcmp((const xmlChar*)*p, attr) )
+        return HTML_VALID ;
+
+  if ( legacy && elt->attrs_depr )
+    for ( p = elt->attrs_depr; *p; ++p)
+      if ( !xmlStrcmp((const xmlChar*)*p, attr) )
+        return HTML_DEPRECATED ;
+
+  return HTML_INVALID ;
+}
+/**
+ * htmlNodeStatus:
+ * @node: an htmlNodePtr in a tree
+ * @legacy: whether to allow deprecated elements (YES is faster here
+ *	for Element nodes)
+ *
+ * Checks whether the tree node is valid.  Experimental (the author
+ *     only uses the HTML enhancements in a SAX parser)
+ *
+ * Return: for Element nodes, a return from htmlElementAllowedHere (if
+ *	legacy allowed) or htmlElementStatusHere (otherwise).
+ *	for Attribute nodes, a return from htmlAttrAllowed
+ *	for other nodes, HTML_NA (no checks performed)
+ */
+htmlStatus
+htmlNodeStatus(const htmlNodePtr node, int legacy) {
+  if ( ! node )
+    return HTML_INVALID ;
+
+  switch ( node->type ) {
+    case XML_ELEMENT_NODE:
+      return legacy
+	? ( htmlElementAllowedHere (
+		htmlTagLookup(node->parent->name) , node->name
+		) ? HTML_VALID : HTML_INVALID )
+	: htmlElementStatusHere(
+		htmlTagLookup(node->parent->name) ,
+		htmlTagLookup(node->name) )
+	;
+    case XML_ATTRIBUTE_NODE:
+      return htmlAttrAllowed(
+	htmlTagLookup(node->parent->name) , node->name, legacy) ;
+    default: return HTML_NA ;
+  }
+}
+/************************************************************************
+ *									*
+ *	New set (2.6.0) of simpler and more flexible APIs		*
+ *									*
+ ************************************************************************/
+/**
+ * DICT_FREE:
+ * @str:  a string
+ *
+ * Free a string if it is not owned by the "dict" dictionnary in the
+ * current scope
+ */
+#define DICT_FREE(str)						\
+	if ((str) && ((!dict) ||				\
+	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
+	    xmlFree((char *)(str));
+
+/**
+ * htmlCtxtReset:
+ * @ctxt: an HTML parser context
+ *
+ * Reset a parser context
+ */
+void
+htmlCtxtReset(htmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr input;
+    xmlDictPtr dict;
+
+    if (ctxt == NULL)
+        return;
+
+    xmlInitParser();
+    dict = ctxt->dict;
+
+    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
+        xmlFreeInputStream(input);
+    }
+    ctxt->inputNr = 0;
+    ctxt->input = NULL;
+
+    ctxt->spaceNr = 0;
+    if (ctxt->spaceTab != NULL) {
+	ctxt->spaceTab[0] = -1;
+	ctxt->space = &ctxt->spaceTab[0];
+    } else {
+	ctxt->space = NULL;
+    }
+
+
+    ctxt->nodeNr = 0;
+    ctxt->node = NULL;
+
+    ctxt->nameNr = 0;
+    ctxt->name = NULL;
+
+    DICT_FREE(ctxt->version);
+    ctxt->version = NULL;
+    DICT_FREE(ctxt->encoding);
+    ctxt->encoding = NULL;
+    DICT_FREE(ctxt->directory);
+    ctxt->directory = NULL;
+    DICT_FREE(ctxt->extSubURI);
+    ctxt->extSubURI = NULL;
+    DICT_FREE(ctxt->extSubSystem);
+    ctxt->extSubSystem = NULL;
+    if (ctxt->myDoc != NULL)
+        xmlFreeDoc(ctxt->myDoc);
+    ctxt->myDoc = NULL;
+
+    ctxt->standalone = -1;
+    ctxt->hasExternalSubset = 0;
+    ctxt->hasPErefs = 0;
+    ctxt->html = 1;
+    ctxt->external = 0;
+    ctxt->instate = XML_PARSER_START;
+    ctxt->token = 0;
+
+    ctxt->wellFormed = 1;
+    ctxt->nsWellFormed = 1;
+    ctxt->valid = 1;
+    ctxt->vctxt.userData = ctxt;
+    ctxt->vctxt.error = xmlParserValidityError;
+    ctxt->vctxt.warning = xmlParserValidityWarning;
+    ctxt->record_info = 0;
+    ctxt->nbChars = 0;
+    ctxt->checkIndex = 0;
+    ctxt->inSubset = 0;
+    ctxt->errNo = XML_ERR_OK;
+    ctxt->depth = 0;
+    ctxt->charset = XML_CHAR_ENCODING_NONE;
+    ctxt->catalogs = NULL;
+    xmlInitNodeInfoSeq(&ctxt->node_seq);
+
+    if (ctxt->attsDefault != NULL) {
+        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
+        ctxt->attsDefault = NULL;
+    }
+    if (ctxt->attsSpecial != NULL) {
+        xmlHashFree(ctxt->attsSpecial, NULL);
+        ctxt->attsSpecial = NULL;
+    }
+}
+
+/**
+ * htmlCtxtUseOptions:
+ * @ctxt: an HTML parser context
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * Applies the options to the parser context
+ *
+ * Returns 0 in case of success, the set of unknown or unimplemented options
+ *         in case of error.
+ */
+int
+htmlCtxtUseOptions(htmlParserCtxtPtr ctxt, int options)
+{
+    if (ctxt == NULL)
+        return(-1);
+
+    if (options & HTML_PARSE_NOWARNING) {
+        ctxt->sax->warning = NULL;
+        ctxt->vctxt.warning = NULL;
+        options -= XML_PARSE_NOWARNING;
+	ctxt->options |= XML_PARSE_NOWARNING;
+    }
+    if (options & HTML_PARSE_NOERROR) {
+        ctxt->sax->error = NULL;
+        ctxt->vctxt.error = NULL;
+        ctxt->sax->fatalError = NULL;
+        options -= XML_PARSE_NOERROR;
+	ctxt->options |= XML_PARSE_NOERROR;
+    }
+    if (options & HTML_PARSE_PEDANTIC) {
+        ctxt->pedantic = 1;
+        options -= XML_PARSE_PEDANTIC;
+	ctxt->options |= XML_PARSE_PEDANTIC;
+    } else
+        ctxt->pedantic = 0;
+    if (options & XML_PARSE_NOBLANKS) {
+        ctxt->keepBlanks = 0;
+        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+        options -= XML_PARSE_NOBLANKS;
+	ctxt->options |= XML_PARSE_NOBLANKS;
+    } else
+        ctxt->keepBlanks = 1;
+    if (options & HTML_PARSE_RECOVER) {
+        ctxt->recovery = 1;
+	options -= HTML_PARSE_RECOVER;
+    } else
+        ctxt->recovery = 0;
+    if (options & HTML_PARSE_COMPACT) {
+	ctxt->options |= HTML_PARSE_COMPACT;
+        options -= HTML_PARSE_COMPACT;
+    }
+    if (options & XML_PARSE_HUGE) {
+	ctxt->options |= XML_PARSE_HUGE;
+        options -= XML_PARSE_HUGE;
+    }
+    ctxt->dictNames = 0;
+    return (options);
+}
+
+/**
+ * htmlDoRead:
+ * @ctxt:  an HTML parser context
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ * @reuse:  keep the context for reuse
+ *
+ * Common front-end for the htmlRead functions
+ *
+ * Returns the resulting document tree or NULL
+ */
+static htmlDocPtr
+htmlDoRead(htmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
+          int options, int reuse)
+{
+    htmlDocPtr ret;
+
+    htmlCtxtUseOptions(ctxt, options);
+    ctxt->html = 1;
+    if (encoding != NULL) {
+        xmlCharEncodingHandlerPtr hdlr;
+
+	hdlr = xmlFindCharEncodingHandler(encoding);
+	if (hdlr != NULL) {
+	    xmlSwitchToEncoding(ctxt, hdlr);
+	    if (ctxt->input->encoding != NULL)
+	      xmlFree((xmlChar *) ctxt->input->encoding);
+            ctxt->input->encoding = xmlStrdup((xmlChar *)encoding);
+        }
+    }
+    if ((URL != NULL) && (ctxt->input != NULL) &&
+        (ctxt->input->filename == NULL))
+        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
+    htmlParseDocument(ctxt);
+    ret = ctxt->myDoc;
+    ctxt->myDoc = NULL;
+    if (!reuse) {
+        if ((ctxt->dictNames) &&
+	    (ret != NULL) &&
+	    (ret->dict == ctxt->dict))
+	    ctxt->dict = NULL;
+	xmlFreeParserCtxt(ctxt);
+    }
+    return (ret);
+}
+
+/**
+ * htmlReadDoc:
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML in-memory document and build a tree.
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
+{
+    htmlParserCtxtPtr ctxt;
+
+    if (cur == NULL)
+        return (NULL);
+
+    xmlInitParser();
+    ctxt = htmlCreateDocParserCtxt(cur, NULL);
+    if (ctxt == NULL)
+        return (NULL);
+    return (htmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * htmlReadFile:
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML file from the filesystem or the network.
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlReadFile(const char *filename, const char *encoding, int options)
+{
+    htmlParserCtxtPtr ctxt;
+
+    xmlInitParser();
+    ctxt = htmlCreateFileParserCtxt(filename, encoding);
+    if (ctxt == NULL)
+        return (NULL);
+    return (htmlDoRead(ctxt, NULL, NULL, options, 0));
+}
+
+/**
+ * htmlReadMemory:
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML in-memory document and build a tree.
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
+{
+    htmlParserCtxtPtr ctxt;
+
+    xmlInitParser();
+    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
+    if (ctxt == NULL)
+        return (NULL);
+    htmlDefaultSAXHandlerInit();
+    if (ctxt->sax != NULL)
+        memcpy(ctxt->sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1));
+    return (htmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * htmlReadFd:
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML from a file descriptor and build a tree.
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlReadFd(int fd, const char *URL, const char *encoding, int options)
+{
+    htmlParserCtxtPtr ctxt;
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (fd < 0)
+        return (NULL);
+
+    xmlInitParser();
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+	xmlFreeParserCtxt(ctxt);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * htmlReadIO:
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @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
+htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
+          void *ioctx, const char *URL, const char *encoding, int options)
+{
+    htmlParserCtxtPtr ctxt;
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ioread == NULL)
+        return (NULL);
+    xmlInitParser();
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    ctxt = htmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+	xmlFreeParserCtxt(ctxt);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * htmlCtxtReadDoc:
+ * @ctxt:  an HTML parser context
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML in-memory document and build a tree.
+ * This reuses the existing @ctxt parser context
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar * cur,
+               const char *URL, const char *encoding, int options)
+{
+    xmlParserInputPtr stream;
+
+    if (cur == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    htmlCtxtReset(ctxt);
+
+    stream = xmlNewStringInputStream(ctxt, cur);
+    if (stream == NULL) {
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * htmlCtxtReadFile:
+ * @ctxt:  an HTML parser context
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML file from the filesystem or the network.
+ * This reuses the existing @ctxt parser context
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlCtxtReadFile(htmlParserCtxtPtr ctxt, const char *filename,
+                const char *encoding, int options)
+{
+    xmlParserInputPtr stream;
+
+    if (filename == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    htmlCtxtReset(ctxt);
+
+    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
+    if (stream == NULL) {
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, NULL, encoding, options, 1));
+}
+
+/**
+ * htmlCtxtReadMemory:
+ * @ctxt:  an HTML parser context
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML in-memory document and build a tree.
+ * This reuses the existing @ctxt parser context
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size,
+                  const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ctxt == NULL)
+        return (NULL);
+    if (buffer == NULL)
+        return (NULL);
+
+    htmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+    if (input == NULL) {
+	return(NULL);
+    }
+
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+	xmlFreeParserInputBuffer(input);
+	return(NULL);
+    }
+
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * htmlCtxtReadFd:
+ * @ctxt:  an HTML parser context
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * parse an XML from a file descriptor and build a tree.
+ * This reuses the existing @ctxt parser context
+ *
+ * Returns the resulting document tree
+ */
+htmlDocPtr
+htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd,
+              const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (fd < 0)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    htmlCtxtReset(ctxt);
+
+
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * htmlCtxtReadIO:
+ * @ctxt:  an HTML parser context
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of htmlParserOption(s)
+ *
+ * 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
+htmlCtxtReadIO(htmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
+              xmlInputCloseCallback ioclose, void *ioctx,
+	      const char *URL,
+              const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ioread == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    htmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+#define bottom_HTMLparser
+#include "elfgcchack.h"
+#endif /* LIBXML_HTML_ENABLED */
diff --git a/src/HTMLtree.c b/src/HTMLtree.c
new file mode 100644
index 0000000..b508583
--- /dev/null
+++ b/src/HTMLtree.c
@@ -0,0 +1,1231 @@
+/*
+ * HTMLtree.c : implementation of access function for an HTML tree.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+
+#define IN_LIBXML
+#include "libxml.h"
+#ifdef LIBXML_HTML_ENABLED
+
+#include <string.h> /* for memset() only ! */
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/entities.h>
+#include <libxml/valid.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parserInternals.h>
+#include <libxml/globals.h>
+#include <libxml/uri.h>
+
+/************************************************************************
+ *									*
+ *   		Getting/Setting encoding meta tags			*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlGetMetaEncoding:
+ * @doc:  the document
+ * 
+ * Encoding definition lookup in the Meta tags
+ *
+ * Returns the current encoding as flagged in the HTML source
+ */
+const xmlChar *
+htmlGetMetaEncoding(htmlDocPtr doc) {
+    htmlNodePtr cur;
+    const xmlChar *content;
+    const xmlChar *encoding;
+
+    if (doc == NULL)
+	return(NULL);
+    cur = doc->children;
+
+    /*
+     * Search the html
+     */
+    while (cur != NULL) {
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
+	    if (xmlStrEqual(cur->name, BAD_CAST"html"))
+		break;
+	    if (xmlStrEqual(cur->name, BAD_CAST"head"))
+		goto found_head;
+	    if (xmlStrEqual(cur->name, BAD_CAST"meta"))
+		goto found_meta;
+	}
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return(NULL);
+    cur = cur->children;
+
+    /*
+     * Search the head
+     */
+    while (cur != NULL) {
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
+	    if (xmlStrEqual(cur->name, BAD_CAST"head"))
+		break;
+	    if (xmlStrEqual(cur->name, BAD_CAST"meta"))
+		goto found_meta;
+	}
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return(NULL);
+found_head:
+    cur = cur->children;
+
+    /*
+     * Search the meta elements
+     */
+found_meta:
+    while (cur != NULL) {
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
+	    if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
+		xmlAttrPtr attr = cur->properties;
+		int http;
+		const xmlChar *value;
+
+		content = NULL;
+		http = 0;
+		while (attr != NULL) {
+		    if ((attr->children != NULL) &&
+		        (attr->children->type == XML_TEXT_NODE) &&
+		        (attr->children->next == NULL)) {
+			value = attr->children->content;
+			if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
+			 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
+			    http = 1;
+			else if ((value != NULL)
+			 && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
+			    content = value;
+			if ((http != 0) && (content != NULL))
+			    goto found_content;
+		    }
+		    attr = attr->next;
+		}
+	    }
+	}
+	cur = cur->next;
+    }
+    return(NULL);
+
+found_content:
+    encoding = xmlStrstr(content, BAD_CAST"charset=");
+    if (encoding == NULL) 
+	encoding = xmlStrstr(content, BAD_CAST"Charset=");
+    if (encoding == NULL) 
+	encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
+    if (encoding != NULL) {
+	encoding += 8;
+    } else {
+	encoding = xmlStrstr(content, BAD_CAST"charset =");
+	if (encoding == NULL) 
+	    encoding = xmlStrstr(content, BAD_CAST"Charset =");
+	if (encoding == NULL) 
+	    encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
+	if (encoding != NULL)
+	    encoding += 9;
+    }
+    if (encoding != NULL) {
+	while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
+    }
+    return(encoding);
+}
+
+/**
+ * htmlSetMetaEncoding:
+ * @doc:  the document
+ * @encoding:  the encoding string
+ * 
+ * Sets the current encoding in the Meta tags
+ * NOTE: this will not change the document content encoding, just
+ * the META flag associated.
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+int
+htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
+    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);
+	newcontent[sizeof(newcontent) - 1] = 0;
+    }
+
+    cur = doc->children;
+
+    /*
+     * Search the html
+     */
+    while (cur != NULL) {
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
+	    if (xmlStrcasecmp(cur->name, BAD_CAST"html") == 0)
+		break;
+	    if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
+		goto found_head;
+	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
+		goto found_meta;
+	}
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return(-1);
+    cur = cur->children;
+
+    /*
+     * Search the head
+     */
+    while (cur != NULL) {
+	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) {
+                head = cur->parent;
+		goto found_meta;
+            }
+	}
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return(-1);
+found_head:
+    head = cur;
+    if (cur->children == NULL)
+        goto create;
+    cur = cur->children;
+
+found_meta:
+    /*
+     * Search and update all the remaining the meta elements carrying
+     * encoding informations
+     */
+    while (cur != NULL) {
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
+	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
+		xmlAttrPtr attr = cur->properties;
+		int http;
+		const xmlChar *value;
+
+		content = NULL;
+		http = 0;
+		while (attr != NULL) {
+		    if ((attr->children != NULL) &&
+		        (attr->children->type == XML_TEXT_NODE) &&
+		        (attr->children->next == NULL)) {
+			value = attr->children->content;
+			if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
+			 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
+			    http = 1;
+			else
+                        {
+                           if ((value != NULL) && 
+                               (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
+			       content = value;
+                        }
+		        if ((http != 0) && (content != NULL))
+			    break;
+		    }
+		    attr = attr->next;
+		}
+		if ((http != 0) && (content != NULL)) {
+		    meta = cur;
+		    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);
+}
+
+/**
+ * booleanHTMLAttrs:
+ *
+ * These are the HTML attributes which will be output
+ * in minimized form, i.e. <option selected="selected"> will be
+ * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method"
+ *
+ */
+static const char* htmlBooleanAttrs[] = {
+  "checked", "compact", "declare", "defer", "disabled", "ismap",
+  "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
+  "selected", NULL
+};
+
+
+/**
+ * htmlIsBooleanAttr:
+ * @name:  the name of the attribute to check
+ *
+ * Determine if a given attribute is a boolean attribute.
+ * 
+ * returns: false if the attribute is not boolean, true otherwise.
+ */
+int
+htmlIsBooleanAttr(const xmlChar *name)
+{
+    int i = 0;
+
+    while (htmlBooleanAttrs[i] != NULL) {
+        if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0)
+            return 1;
+        i++;
+    }
+    return 0;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * private routine exported from xmlIO.c
+ */
+xmlOutputBufferPtr
+xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
+/************************************************************************
+ *									*
+ * 			Output error handlers				*
+ *									*
+ ************************************************************************/
+/**
+ * htmlSaveErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+htmlSaveErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * htmlSaveErr:
+ * @code:  the error number
+ * @node:  the location of the error.
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+htmlSaveErr(int code, xmlNodePtr node, const char *extra)
+{
+    const char *msg = NULL;
+
+    switch(code) {
+        case XML_SAVE_NOT_UTF8:
+	    msg = "string is not in UTF-8\n";
+	    break;
+	case XML_SAVE_CHAR_INVALID:
+	    msg = "invalid character value\n";
+	    break;
+	case XML_SAVE_UNKNOWN_ENCODING:
+	    msg = "unknown encoding %s\n";
+	    break;
+	case XML_SAVE_NO_DOCTYPE:
+	    msg = "HTML has no DOCTYPE\n";
+	    break;
+	default:
+	    msg = "unexpected error number\n";
+    }
+    __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
+}
+
+/************************************************************************
+ *									*
+ *   		Dumping HTML tree content to a simple buffer		*
+ *									*
+ ************************************************************************/
+
+static int
+htmlNodeDumpFormat(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+	           int format);
+
+/**
+ * htmlNodeDumpFormat:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too.
+ *
+ * Returns the number of byte written or -1 in case of error
+ */
+static int
+htmlNodeDumpFormat(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+	           int format) {
+    unsigned int use;
+    int ret;
+    xmlOutputBufferPtr outbuf;
+
+    if (cur == NULL) {
+	return (-1);
+    }
+    if (buf == NULL) {
+	return (-1);
+    }
+    outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
+    if (outbuf == NULL) {
+        htmlSaveErrMemory("allocating HTML output buffer");
+	return (-1);
+    }
+    memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
+    outbuf->buffer = buf;
+    outbuf->encoder = NULL;
+    outbuf->writecallback = NULL;
+    outbuf->closecallback = NULL;
+    outbuf->context = NULL;
+    outbuf->written = 0;
+
+    use = buf->use;
+    htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
+    xmlFree(outbuf);
+    ret = buf->use - use;
+    return (ret);
+}
+
+/**
+ * htmlNodeDump:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too,
+ * and formatting returns are added.
+ *
+ * Returns the number of byte written or -1 in case of error
+ */
+int
+htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
+    xmlInitParser();
+
+    return(htmlNodeDumpFormat(buf, doc, cur, 1));
+}
+
+/**
+ * htmlNodeDumpFileFormat:
+ * @out:  the FILE pointer
+ * @doc:  the document
+ * @cur:  the current node
+ * @encoding: the document encoding
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too.
+ *
+ * TODO: if encoding == NULL try to save in the doc encoding
+ *
+ * returns: the number of byte written or -1 in case of failure.
+ */
+int
+htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
+	               xmlNodePtr cur, const char *encoding, int format) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int ret;
+
+    xmlInitParser();
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != XML_CHAR_ENCODING_UTF8) {
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+	}
+    }
+
+    /*
+     * Fallback to HTML or ASCII when the encoding is unspecified
+     */
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("HTML");
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("ascii");
+
+    /* 
+     * save the content to a temp buffer.
+     */
+    buf = xmlOutputBufferCreateFile(out, handler);
+    if (buf == NULL) return(0);
+
+    htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * htmlNodeDumpFile:
+ * @out:  the FILE pointer
+ * @doc:  the document
+ * @cur:  the current node
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too,
+ * and formatting returns are added.
+ */
+void
+htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
+    htmlNodeDumpFileFormat(out, doc, cur, NULL, 1);
+}
+
+/**
+ * htmlDocDumpMemoryFormat:
+ * @cur:  the document
+ * @mem:  OUT: the memory pointer
+ * @size:  OUT: the memory length
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML document in memory and return the xmlChar * and it's size.
+ * It's up to the caller to free the memory.
+ */
+void
+htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    const char *encoding;
+
+    xmlInitParser();
+
+    if ((mem == NULL) || (size == NULL))
+        return;
+    if (cur == NULL) {
+	*mem = NULL;
+	*size = 0;
+	return;
+    }
+
+    encoding = (const char *) htmlGetMetaEncoding(cur);
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != cur->charset) {
+	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+		/*
+		 * Not supported yet
+		 */
+		*mem = NULL;
+		*size = 0;
+		return;
+	    }
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL) {
+		*mem = NULL;
+		*size = 0;
+		return;
+	    }
+	} else {
+	    handler = xmlFindCharEncodingHandler(encoding);
+	}
+    }
+
+    /*
+     * Fallback to HTML or ASCII when the encoding is unspecified
+     */
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("HTML");
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("ascii");
+
+    buf = xmlAllocOutputBufferInternal(handler);
+    if (buf == NULL) {
+	*mem = NULL;
+	*size = 0;
+	return;
+    }
+
+	htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
+
+    xmlOutputBufferFlush(buf);
+    if (buf->conv != NULL) {
+	*size = buf->conv->use;
+	*mem = xmlStrndup(buf->conv->content, *size);
+    } else {
+	*size = buf->buffer->use;
+	*mem = xmlStrndup(buf->buffer->content, *size);
+    }
+    (void)xmlOutputBufferClose(buf);
+}
+
+/**
+ * htmlDocDumpMemory:
+ * @cur:  the document
+ * @mem:  OUT: the memory pointer
+ * @size:  OUT: the memory length
+ *
+ * Dump an HTML document in memory and return the xmlChar * and it's size.
+ * It's up to the caller to free the memory.
+ */
+void
+htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
+	htmlDocDumpMemoryFormat(cur, mem, size, 1);
+}
+
+
+/************************************************************************
+ *									*
+ *   		Dumping HTML tree content to an I/O output buffer	*
+ *									*
+ ************************************************************************/
+
+void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
+
+/**
+ * htmlDtdDumpOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @encoding:  the encoding string
+ * 
+ * TODO: check whether encoding is needed
+ *
+ * Dump the HTML document DTD, if any.
+ */
+static void
+htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+	          const char *encoding ATTRIBUTE_UNUSED) {
+    xmlDtdPtr cur = doc->intSubset;
+
+    if (cur == NULL) {
+	htmlSaveErr(XML_SAVE_NO_DOCTYPE, (xmlNodePtr) doc, NULL);
+	return;
+    }
+    xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (cur->ExternalID != NULL) {
+	xmlOutputBufferWriteString(buf, " PUBLIC ");
+	xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
+	if (cur->SystemID != NULL) {
+	    xmlOutputBufferWriteString(buf, " ");
+	    xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
+	} 
+    }  else if (cur->SystemID != NULL) {
+	xmlOutputBufferWriteString(buf, " SYSTEM ");
+	xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
+    }
+    xmlOutputBufferWriteString(buf, ">\n");
+}
+
+/**
+ * htmlAttrDumpOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the attribute pointer
+ * @encoding:  the encoding string
+ *
+ * Dump an HTML attribute
+ */
+static void
+htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
+	           const char *encoding ATTRIBUTE_UNUSED) {
+    xmlChar *value;
+
+    /*
+     * TODO: The html output method should not escape a & character
+     *       occurring in an attribute value immediately followed by
+     *       a { character (see Section B.7.1 of the HTML 4.0 Recommendation).
+     */
+
+    if (cur == NULL) {
+	return;
+    }
+    xmlOutputBufferWriteString(buf, " ");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if ((cur->children != NULL) && (!htmlIsBooleanAttr(cur->name))) {
+	value = xmlNodeListGetString(doc, cur->children, 0);
+	if (value) {
+	    xmlOutputBufferWriteString(buf, "=");
+	    if ((cur->ns == NULL) && (cur->parent != NULL) &&
+		(cur->parent->ns == NULL) &&
+		((!xmlStrcasecmp(cur->name, BAD_CAST "href")) ||
+	         (!xmlStrcasecmp(cur->name, BAD_CAST "action")) ||
+		 (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
+		 ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
+		  (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
+		xmlChar *escaped;
+		xmlChar *tmp = value;
+
+		while (IS_BLANK_CH(*tmp)) tmp++;
+
+		escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
+		if (escaped != NULL) {
+		    xmlBufferWriteQuotedString(buf->buffer, escaped);
+		    xmlFree(escaped);
+		} else {
+		    xmlBufferWriteQuotedString(buf->buffer, value);
+		}
+	    } else {
+		xmlBufferWriteQuotedString(buf->buffer, value);
+	    }
+	    xmlFree(value);
+	} else  {
+	    xmlOutputBufferWriteString(buf, "=\"\"");
+	}
+    }
+}
+
+/**
+ * htmlAttrListDumpOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the first attribute pointer
+ * @encoding:  the encoding string
+ *
+ * Dump a list of HTML attributes
+ */
+static void
+htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
+    if (cur == NULL) {
+	return;
+    }
+    while (cur != NULL) {
+        htmlAttrDumpOutput(buf, doc, cur, encoding);
+	cur = cur->next;
+    }
+}
+
+
+
+/**
+ * htmlNodeListDumpOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the first node
+ * @encoding:  the encoding string
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML node list, recursive behaviour,children are printed too.
+ */
+static void
+htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+	               xmlNodePtr cur, const char *encoding, int format) {
+    if (cur == NULL) {
+	return;
+    }
+    while (cur != NULL) {
+        htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
+	cur = cur->next;
+    }
+}
+
+/**
+ * htmlNodeDumpFormatOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @encoding:  the encoding string
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too.
+ */
+void
+htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+	                 xmlNodePtr cur, const char *encoding, int format) {
+    const htmlElemDesc * info;
+
+    xmlInitParser();
+
+    if ((cur == NULL) || (buf == NULL)) {
+	return;
+    }
+    /*
+     * Special cases.
+     */
+    if (cur->type == XML_DTD_NODE)
+	return;
+    if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
+        (cur->type == XML_DOCUMENT_NODE)){
+	htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding);
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+        htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur, encoding);
+	return;
+    }
+    if (cur->type == HTML_TEXT_NODE) {
+	if (cur->content != NULL) {
+	    if (((cur->name == (const xmlChar *)xmlStringText) ||
+		 (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
+		((cur->parent == NULL) ||
+		 ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
+		  (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
+		xmlChar *buffer;
+
+		buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
+		if (buffer != NULL) {
+		    xmlOutputBufferWriteString(buf, (const char *)buffer);
+		    xmlFree(buffer);
+		}
+	    } else {
+		xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    }
+	}
+	return;
+    }
+    if (cur->type == HTML_COMMENT_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWriteString(buf, "<!--");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    xmlOutputBufferWriteString(buf, "-->");
+	}
+	return;
+    }
+    if (cur->type == HTML_PI_NODE) {
+	if (cur->name == NULL)
+	    return;
+	xmlOutputBufferWriteString(buf, "<?");
+	xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	if (cur->content != NULL) {
+	    xmlOutputBufferWriteString(buf, " ");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	}
+	xmlOutputBufferWriteString(buf, ">");
+	return;
+    }
+    if (cur->type == HTML_ENTITY_REF_NODE) {
+        xmlOutputBufferWriteString(buf, "&");
+	xmlOutputBufferWriteString(buf, (const char *)cur->name);
+        xmlOutputBufferWriteString(buf, ";");
+	return;
+    }
+    if (cur->type == HTML_PRESERVE_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	}
+	return;
+    }
+
+    /*
+     * Get specific HTML info for that node.
+     */
+    if (cur->ns == NULL)
+	info = htmlTagLookup(cur->name);
+    else
+	info = NULL;
+
+    xmlOutputBufferWriteString(buf, "<");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (cur->nsDef)
+	xmlNsListDumpOutput(buf, cur->nsDef);
+    if (cur->properties != NULL)
+        htmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
+
+    if ((info != NULL) && (info->empty)) {
+        xmlOutputBufferWriteString(buf, ">");
+	if ((format) && (!info->isinline) && (cur->next != NULL)) {
+	    if ((cur->next->type != HTML_TEXT_NODE) &&
+		(cur->next->type != HTML_ENTITY_REF_NODE) &&
+		(cur->parent != NULL) &&
+		(cur->parent->name != NULL) &&
+		(cur->parent->name[0] != 'p')) /* p, pre, param */
+		xmlOutputBufferWriteString(buf, "\n");
+	}
+	return;
+    }
+    if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
+	(cur->children == NULL)) {
+        if ((info != NULL) && (info->saveEndTag != 0) &&
+	    (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) &&
+	    (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) {
+	    xmlOutputBufferWriteString(buf, ">");
+	} else {
+	    xmlOutputBufferWriteString(buf, "></");
+            if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+                xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+                xmlOutputBufferWriteString(buf, ":");
+            }
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    xmlOutputBufferWriteString(buf, ">");
+	}
+	if ((format) && (cur->next != NULL) &&
+            (info != NULL) && (!info->isinline)) {
+	    if ((cur->next->type != HTML_TEXT_NODE) &&
+		(cur->next->type != HTML_ENTITY_REF_NODE) &&
+		(cur->parent != NULL) &&
+		(cur->parent->name != NULL) &&
+		(cur->parent->name[0] != 'p')) /* p, pre, param */
+		xmlOutputBufferWriteString(buf, "\n");
+	}
+	return;
+    }
+    xmlOutputBufferWriteString(buf, ">");
+    if ((cur->type != XML_ELEMENT_NODE) &&
+	(cur->content != NULL)) {
+	    /*
+	     * Uses the OutputBuffer property to automatically convert
+	     * invalids to charrefs
+	     */
+
+            xmlOutputBufferWriteString(buf, (const char *) cur->content);
+    }
+    if (cur->children != NULL) {
+        if ((format) && (info != NULL) && (!info->isinline) &&
+	    (cur->children->type != HTML_TEXT_NODE) &&
+	    (cur->children->type != HTML_ENTITY_REF_NODE) &&
+	    (cur->children != cur->last) &&
+	    (cur->name != NULL) &&
+	    (cur->name[0] != 'p')) /* p, pre, param */
+	    xmlOutputBufferWriteString(buf, "\n");
+	htmlNodeListDumpOutput(buf, doc, cur->children, encoding, format);
+        if ((format) && (info != NULL) && (!info->isinline) &&
+	    (cur->last->type != HTML_TEXT_NODE) &&
+	    (cur->last->type != HTML_ENTITY_REF_NODE) &&
+	    (cur->children != cur->last) &&
+	    (cur->name != NULL) &&
+	    (cur->name[0] != 'p')) /* p, pre, param */
+	    xmlOutputBufferWriteString(buf, "\n");
+    }
+    xmlOutputBufferWriteString(buf, "</");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    xmlOutputBufferWriteString(buf, ">");
+    if ((format) && (info != NULL) && (!info->isinline) &&
+	(cur->next != NULL)) {
+        if ((cur->next->type != HTML_TEXT_NODE) &&
+	    (cur->next->type != HTML_ENTITY_REF_NODE) &&
+	    (cur->parent != NULL) &&
+	    (cur->parent->name != NULL) &&
+	    (cur->parent->name[0] != 'p')) /* p, pre, param */
+	    xmlOutputBufferWriteString(buf, "\n");
+    }
+}
+
+/**
+ * htmlNodeDumpOutput:
+ * @buf:  the HTML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @encoding:  the encoding string
+ *
+ * Dump an HTML node, recursive behaviour,children are printed too,
+ * and formatting returns/spaces are added.
+ */
+void
+htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+	           xmlNodePtr cur, const char *encoding) {
+    htmlNodeDumpFormatOutput(buf, doc, cur, encoding, 1);
+}
+
+/**
+ * htmlDocContentDumpFormatOutput:
+ * @buf:  the HTML buffer output
+ * @cur:  the document
+ * @encoding:  the encoding string
+ * @format:  should formatting spaces been added
+ *
+ * Dump an HTML document.
+ */
+void
+htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
+	                       const char *encoding, int format) {
+    int type;
+
+    xmlInitParser();
+
+    if ((buf == NULL) || (cur == NULL))
+        return;
+
+    /*
+     * force to output the stuff as HTML, especially for entities
+     */
+    type = cur->type;
+    cur->type = XML_HTML_DOCUMENT_NODE;
+    if (cur->intSubset != NULL) {
+        htmlDtdDumpOutput(buf, cur, NULL);
+    }
+    if (cur->children != NULL) {
+        htmlNodeListDumpOutput(buf, cur, cur->children, encoding, format);
+    }
+    xmlOutputBufferWriteString(buf, "\n");
+    cur->type = (xmlElementType) type;
+}
+
+/**
+ * htmlDocContentDumpOutput:
+ * @buf:  the HTML buffer output
+ * @cur:  the document
+ * @encoding:  the encoding string
+ *
+ * Dump an HTML document. Formating return/spaces are added.
+ */
+void
+htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
+	                 const char *encoding) {
+    htmlDocContentDumpFormatOutput(buf, cur, encoding, 1);
+}
+
+/************************************************************************
+ *									*
+ *		Saving functions front-ends				*
+ *									*
+ ************************************************************************/
+
+/**
+ * htmlDocDump:
+ * @f:  the FILE*
+ * @cur:  the document
+ *
+ * Dump an HTML document to an open FILE.
+ *
+ * returns: the number of byte written or -1 in case of failure.
+ */
+int
+htmlDocDump(FILE *f, xmlDocPtr cur) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    const char *encoding;
+    int ret;
+
+    xmlInitParser();
+
+    if ((cur == NULL) || (f == NULL)) {
+	return(-1);
+    }
+
+    encoding = (const char *) htmlGetMetaEncoding(cur);
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != cur->charset) {
+	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+		/*
+		 * Not supported yet
+		 */
+		return(-1);
+	    }
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+	} else {
+	    handler = xmlFindCharEncodingHandler(encoding);
+	}
+    }
+
+    /*
+     * Fallback to HTML or ASCII when the encoding is unspecified
+     */
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("HTML");
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("ascii");
+
+    buf = xmlOutputBufferCreateFile(f, handler);
+    if (buf == NULL) return(-1);
+    htmlDocContentDumpOutput(buf, cur, NULL);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * htmlSaveFile:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ *
+ * Dump an HTML document to a file. If @filename is "-" the stdout file is
+ * used.
+ * returns: the number of byte written or -1 in case of failure.
+ */
+int
+htmlSaveFile(const char *filename, xmlDocPtr cur) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    const char *encoding;
+    int ret;
+
+    if ((cur == NULL) || (filename == NULL))
+        return(-1);
+       
+    xmlInitParser();
+
+    encoding = (const char *) htmlGetMetaEncoding(cur);
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != cur->charset) {
+	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+		/*
+		 * Not supported yet
+		 */
+		return(-1);
+	    }
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+	}
+    }
+
+    /*
+     * Fallback to HTML or ASCII when the encoding is unspecified
+     */
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("HTML");
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("ascii");
+
+    /* 
+     * save the content to a temp buffer.
+     */
+    buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
+    if (buf == NULL) return(0);
+
+    htmlDocContentDumpOutput(buf, cur, NULL);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * htmlSaveFileFormat:
+ * @filename:  the filename
+ * @cur:  the document
+ * @format:  should formatting spaces been added
+ * @encoding: the document encoding
+ *
+ * Dump an HTML document to a file using a given encoding.
+ * 
+ * returns: the number of byte written or -1 in case of failure.
+ */
+int
+htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
+	           const char *encoding, int format) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int ret;
+
+    if ((cur == NULL) || (filename == NULL))
+        return(-1);
+
+    xmlInitParser();
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != cur->charset) {
+	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+		/*
+		 * Not supported yet
+		 */
+		return(-1);
+	    }
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+	}
+        htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
+    } else {
+	htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
+    }
+
+    /*
+     * Fallback to HTML or ASCII when the encoding is unspecified
+     */
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("HTML");
+    if (handler == NULL)
+	handler = xmlFindCharEncodingHandler("ascii");
+
+    /* 
+     * save the content to a temp buffer.
+     */
+    buf = xmlOutputBufferCreateFilename(filename, handler, 0);
+    if (buf == NULL) return(0);
+
+    htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * htmlSaveFileEnc:
+ * @filename:  the filename
+ * @cur:  the document
+ * @encoding: the document encoding
+ *
+ * Dump an HTML document to a file using a given encoding
+ * and formatting returns/spaces are added.
+ * 
+ * returns: the number of byte written or -1 in case of failure.
+ */
+int
+htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
+    return(htmlSaveFileFormat(filename, cur, encoding, 1));
+}
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#define bottom_HTMLtree
+#include "elfgcchack.h"
+#endif /* LIBXML_HTML_ENABLED */
diff --git a/src/INSTALL b/src/INSTALL
new file mode 100644
index 0000000..7d1c323
--- /dev/null
+++ b/src/INSTALL
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
+
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/src/NEWS b/src/NEWS
new file mode 100644
index 0000000..cdfdda6
--- /dev/null
+++ b/src/NEWS
@@ -0,0 +1,2006 @@
+
+        NEWS file for libxml2
+
+  Note that this is automatically generated from the news webpage at:
+       http://xmlsoft.org/news.html
+
+Items not finished and worked on, get in touch with the list if you want
+to help those   - More testing on RelaxNG
+   - Finishing up XML
+  Schemas
+
+The change log at 
+ChangeLog.html
+ describes the recents commits
+to the SVN at 
+http://svn.gnome.org/viewvc/libxml2/trunk/
+ code base.Here is the list of public releases:
+2.7.6: Oct  6 2009:
+   -  Bug Fixes:
+     Restore thread support in default configuration (Andrew W. Nosenko),
+     URI with no path parsing problem (Daniel Veillard),
+     Minor patch for conditional defines in threads.c (Eric Zurcher)
+  
+
+
+2.7.5: Sep 24 2009:
+   -  Bug Fixes:
+    Restore behavior of --with-threads without argument (Andrew W. Nosenko),
+    Fix memory leak when doc is NULL (Rob Richards),
+    595792 fixing a RelaxNG bug introduced in 2.7.4 (Daniel Veillard),
+    Fix a Relaxng bug raised by libvirt test suite (Daniel Veillard),
+    Fix a parsing problem with little data at startup (Daniel Veillard),
+    link python module with python library (Frederic Crozat),
+    594874 Forgot an fclose in xmllint (Daniel Veillard)
+  
+   -  Cleanup:
+    Adding symbols.xml to EXTRA_DIST (Daniel Veillard)
+  
+
+
+2.7.4: Sep 10 2009:
+   - Improvements:
+    Switch to GIT (GNOME),
+    Add symbol versioning to libxml2 shared libs (Daniel Veillard)
+  
+   - Portability:
+    593857 try to work around thread pbm MinGW 4.4 (Daniel Veillard),
+    594250 rename ATTRIBUTE_ALLOC_SIZE to avoid clashes (Daniel Veillard),
+    Fix Windows build * relaxng.c: fix windows build (Rob Richards),
+    Fix the globals.h to use XMLPUBFUN (Paul Smith),
+    Problem with extern extern in header (Daniel Veillard),
+    Add -lnetwork for compiling on Haiku (Scott McCreary),
+    Runtest portability patch for Solaris (Tim Rice),
+    Small patch to accomodate the Haiku OS (Scott McCreary),
+    584605 package VxWorks folder in the distribution (Daniel Veillard),
+    574017 Realloc too expensive on most platform (Daniel Veillard),
+    Fix windows build (Rob Richards),
+    545579 doesn't compile without schema support (Daniel Veillard),
+    xmllint use xmlGetNodePath when not compiled in (Daniel Veillard),
+    Try to avoid __imp__xmlFree link trouble on msys (Daniel Veillard),
+    Allow to select the threading system on Windows (LRN),
+    Fix Solaris binary links, cleanups (Daniel Veillard),
+    Bug 571059 – MSVC doesn't work with the bakefile (Intron),
+    fix ATTRIBUTE_PRINTF header clash (Belgabor and Mike Hommey),
+    fixes for Borland/CodeGear/Embarcadero compilers (Eric Zurcher)
+  
+   - Documentation:
+    544910 typo: "renciliateNs" (Leonid Evdokimov),
+    Add VxWorks to list of OSes (Daniel Veillard),
+    Regenerate the documentation and update for git (Daniel Veillard),
+    560524 ¿ xmlTextReaderLocalName description (Daniel Veillard),
+    Added sponsoring by AOE media for the server (Daniel Veillard),
+    updated URLs for GNOME (Vincent Lefevre),
+    more warnings about xmlCleanupThreads and xmlCleanupParser (Daniel Veillard)
+  
+   - Bug fixes:
+    594514 memory leaks - duplicate initialization (MOD),
+    Wrong block opening in htmlNodeDumpOutputInternal (Daniel Veillard),
+    492317 Fix  Relax-NG validation problems (Daniel Veillard),
+    558452 fight with reg test and error report (Daniel Veillard),
+    558452 RNG compilation of optional multiple child (Daniel Veillard),
+    579746 XSD validation not correct / nilable groups (Daniel Veillard),
+    502960 provide namespace stack when parsing entity (Daniel Veillard),
+    566012 part 2 fix regresion tests and push mode (Daniel Veillard),
+    566012 autodetected encoding and encoding conflict (Daniel Veillard),
+    584220 xpointer(/) and xinclude problems (Daniel Veillard),
+    587663 Incorrect Attribute-Value Normalization (Daniel Veillard),
+    444994 HTML chunked failure for attribute with <> (Daniel Veillard),
+    Fix end of buffer char being split in XML parser (Daniel Veillard),
+    Non ASCII character may be split at buffer end (Adiel Mittmann),
+    440226 Add xmlXIncludeProcessTreeFlagsData API (Stefan Behnel),
+    572129 speed up parsing of large HTML text nodes (Markus Kull),
+    Fix HTML parsing with 0 character in CDATA (Daniel Veillard),
+    Fix SetGenericErrorFunc and SetStructured clash (Wang Lam),
+    566012  Incomplete EBCDIC parsing support (Martin Kogler),
+    541335 HTML avoid creating 2 head or 2 body element (Daniel Veillard),
+    541237 error correcting missing end tags in HTML (Daniel Veillard),
+    583439 missing line numbers in push mode (Daniel Veillard),
+    587867 xmllint --html --xmlout serializing as HTML (Daniel Veillard),
+    559501 avoid select and use poll for nanohttp (Raphael Prevost),
+    559410 -  Regexp bug on (...)? constructs (Daniel Veillard),
+    Fix a small problem on previous HTML parser patch (Daniel Veillard),
+    592430 -  HTML parser runs into endless loop (Daniel Veillard),
+    447899 potential double free in xmlFreeTextReader (Daniel Veillard),
+    446613 small validation bug mixed content with NS (Daniel Veillard),
+    Fix the problem of revalidating a doc with RNG (Daniel Veillard),
+    Fix xmlKeepBlanksDefault to not break indent (Nick Wellnhofer),
+    512131 refs from externalRef part need to be added (Daniel Veillard),
+    512131 crash in xmlRelaxNGValidateFullElement (Daniel Veillard),
+    588441 allow '.' in HTML Names even if invalid (Daniel Veillard),
+    582913 Fix htmlSetMetaEncoding() to be nicer (Daniel Veillard),
+    579317 Try to find the HTML encoding information (Daniel Veillard),
+    575875 don't output charset=html (Daniel Veillard),
+    571271 fix semantic of xsd:all with minOccurs=0 (Daniel Veillard),
+    570702 fix a bug in regexp determinism checking (Daniel Veillard),
+    567619 xmlValidateNotationUse missing param test (Daniel Veillard),
+    574393 ¿ utf-8 filename magic for compressed files (Hans Breuer),
+    Fix a couple of problems in the parser (Daniel Veillard),
+    585505 ¿ Document ids and refs populated by XSD (Wayne Jensen),
+    582906 XSD validating multiple imports of the same schema (Jason Childs),
+    Bug 582887 ¿ problems validating complex schemas (Jason Childs),
+    Bug 579729 ¿ fix XSD schemas parsing crash (Miroslav Bajtos),
+    576368 ¿ htmlChunkParser with special attributes (Jiri Netolicky),
+    Bug 565747 ¿ relax anyURI data character checking (Vincent Lefevre),
+    Preserve attributes of include start on tree copy (Petr Pajas),
+    Skip silently unrecognized XPointer schemes (Jakub Wilk),
+    Fix leak on SAX1, xmllint --sax1 option and debug (Daniel Veillard),
+    potential NULL dereference on non-glibc (Jim Meyering),
+    Fix an XSD validation crash (Daniel Veillard),
+    Fix a regression in streaming entities support (Daniel Veillard),
+    Fix a couple of ABI issues with C14N 1.1 (Aleksey Sanin),
+    Aleksey Sanin support for c14n 1.1 (Aleksey Sanin),
+    reader bug fix with entities (Daniel Veillard),
+    use options from current parser ctxt for external entities (Rob Richards),
+    581612 use %s to printf strings (Christian Persch),
+    584605 change the threading initialization sequence (Igor Novoseltsev),
+    580705 keep line numbers in HTML parser (Aaron Patterson),
+    581803 broken HTML table attributes init (Roland Steiner),
+    do not set error code in xmlNsWarn (Rob Richards),
+    564217 fix structured error handling problems,
+    reuse options from current parser for entities (Rob Richards),
+    xmlXPathRegisterNs should not allow enpty prefixes (Daniel Veillard),
+    add a missing check in xmlAddSibling (Kris Breuker),
+    avoid leaks on errors (Jinmei Tatuya)
+  
+   - Cleanup:
+    Chasing dead assignments reported by clang-scan (Daniel Veillard),
+    A few more safety cleanup raised by scan (Daniel Veillard),
+    Fixing assorted potential problems raised by scan (Daniel Veillard),
+    Potential uninitialized arguments raised by scan (Daniel Veillard),
+    Fix a bunch of scan 'dead increments' and cleanup (Daniel Veillard),
+    Remove a pedantic warning (Daniel Veillard),
+    555833 always use rm -f in uninstall-local (Daniel Veillard),
+    542394 xmlRegisterOutputCallbacks MAX_INPUT_CALLBACK (Daniel Veillard),
+    Autoregenerate libxml2.syms automated checkings (Daniel Veillard),
+    Make xmlRecoverDoc const (Martin Trappel) (Daniel Veillard),
+    Both args of xmlStrcasestr are const (Daniel Veillard),
+    hide the nbParse* variables used for debugging (Mike Hommey),
+    570806 changed include of config.h (William M. Brack),
+    cleanups and error reports when xmlTextWriterVSprintf fails (Jinmei Tatuya)
+  
+
+
+2.7.3: Jan 18 2009:
+   - Build fix: fix build when HTML support is not included.
+   - Bug fixes: avoid memory overflow in gigantic text nodes,
+      indentation problem on the writed (Rob Richards),
+      xmlAddChildList pointer problem (Rob Richards and Kevin Milburn),
+      xmlAddChild problem with attribute (Rob Richards and Kris Breuker),
+      avoid a memory leak in an edge case (Daniel Zimmermann),
+      deallocate some pthread data (Alex Ott).
+   - Improvements: configure option to avoid rebuilding docs (Adrian Bunk),
+      limit text nodes to 10MB max by default, add element traversal
+      APIs, add a parser option to enable pre 2.7 SAX behavior (Rob Richards),
+      add gcc malloc checking (Marcus Meissner), add gcc printf like functions
+      parameters checking (Marcus Meissner).
+
+
+2.7.2: Oct 3 2008:
+   - Portability fix: fix solaris compilation problem, fix compilation
+        if XPath is not configured in
+   - Bug fixes: nasty entity bug introduced in 2.7.0, restore old behaviour
+        when saving an HTML doc with an xml dump function, HTML UTF-8 parsing
+        bug, fix reader custom error handlers (Riccardo Scussat)
+    
+   - Improvement: xmlSave options for more flexibility to save as
+        XML/HTML/XHTML, handle leading BOM in HTML documents
+
+
+2.7.1: Sep 1 2008:
+   - Portability fix: Borland C fix (Moritz Both)
+   - Bug fixes: python serialization wrappers, XPath QName corner
+        case handking and leaks (Martin)
+   - Improvement: extend the xmlSave to handle HTML documents and trees
+   - Cleanup: python serialization wrappers
+
+
+2.7.0: Aug 30 2008:
+   - Documentation: switch ChangeLog to UTF-8, improve mutithreads and
+      xmlParserCleanup docs
+   - Portability fixes: Older Win32 platforms (Rob Richards), MSVC
+      porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg),
+      non GNUCC builds (Rob Richards), compilation on Haiku (Andreas Färber)
+      
+   - Bug fixes: various realloc problems (Ashwin), potential double-free
+      (Ashwin), regexp crash, icrash with invalid whitespace facets (Rob
+      Richards), pattern fix when streaming (William Brack), various XML
+      parsing and validation fixes based on the W3C regression tests, reader
+      tree skipping function fix (Ashwin), Schemas regexps escaping fix
+      (Volker Grabsch), handling of entity push errors (Ashwin), fix a slowdown
+      when encoder cant serialize characters on output
+   - Code cleanup: compilation fix without the reader, without the output
+      (Robert Schwebel), python whitespace (Martin), many space/tabs cleanups,
+      serious cleanup of the entity handling code
+   - Improvement: switch parser to XML-1.0 5th edition, add parsing flags
+      for old versions, switch URI parsing to RFC 3986,
+      add xmlSchemaValidCtxtGetParserCtxt (Holger Kaelberer),
+      new hashing functions for dictionnaries (based on Stefan Behnel work),
+      improve handling of misplaced html/head/body in HTML parser, better
+      regression test tools and code coverage display, better algorithms
+      to detect various versions of the billion laughts attacks, make
+      arbitrary parser limits avoidable as a parser option
+
+
+2.6.32: Apr 8 2008:
+   - Documentation: returning heap memory to kernel (Wolfram Sang),
+      trying to clarify xmlCleanupParser() use, xmlXPathContext improvement
+      (Jack Jansen), improve the *Recover* functions documentation,
+      XmlNodeType doc link fix (Martijn Arts)
+   - Bug fixes: internal subset memory leak (Ashwin), avoid problem with
+      paths starting with // (Petr Sumbera), streaming XSD validation callback
+      patches (Ashwin), fix redirection on port other than 80 (William Brack),
+      SAX2 leak (Ashwin), XInclude fragment of own document (Chris Ryan),
+      regexp bug with '.' (Andrew Tosh), flush the writer at the end of the
+      document (Alfred Mickautsch), output I/O bug fix (William Brack),
+      writer CDATA output after a text node (Alex Khesin), UTF-16 encoding
+      detection (William Brack), fix handling of empty CDATA nodes for Safari
+      team, python binding problem with namespace nodes, improve HTML parsing
+      (Arnold Hendriks), regexp automata build bug, memory leak fix (Vasily
+      Chekalkin), XSD test crash, weird system parameter entity parsing problem,
+      allow save to file:///X:/ windows paths, various attribute normalisation
+      problems, externalSubsetSplit fix (Ashwin), attribute redefinition in
+      the DTD (Ashwin), fix in char ref parsing check (Alex Khesin), many
+      out of memory handling fixes (Ashwin), XPath out of memory handling fixes
+      (Alvaro Herrera), various realloc problems (Ashwin), UCS4 encoding
+      conversion buffer size (Christian Fruth), problems with EatName
+      functions on memory errors, BOM handling in external parsed entities
+      (Mark Rowe)
+   - Code cleanup: fix build under VS 2008 (David Wimsey), remove useless
+      mutex in xmlDict (Florent Guilian), Mingw32 compilation fix (Carlo
+      Bramini), Win and MacOS EOL cleanups (Florent Guiliani), iconv need
+      a const detection (Roumen Petrov), simplify xmlSetProp (Julien Charbon),
+      cross compilation fixes for Mingw (Roumen Petrov), SCO Openserver build
+      fix (Florent Guiliani), iconv uses const on Win32 (Rob Richards),
+      duplicate code removal (Ashwin), missing malloc test and error reports
+      (Ashwin), VMS makefile fix (Tycho Hilhorst)
+   - improvements: better plug of schematron in the normal error handling
+      (Tobias Minich)
+
+
+2.6.31: Jan 11 2008:
+   - Security fix: missing of checks in UTF-8 parsing
+   - Bug fixes: regexp bug, dump attribute from XHTML document, fix
+      xmlFree(NULL) to not crash in debug mode, Schematron parsing crash
+      (Rob Richards), global lock free on Windows (Marc-Antoine Ruel),
+      XSD crash due to double free (Rob Richards), indentation fix in
+      xmlTextWriterFullEndElement (Felipe Pena), error in attribute type
+      parsing if attribute redeclared, avoid crash in hash list scanner if
+      deleting elements, column counter bug fix (Christian Schmidt),
+      HTML embed element saving fix (Stefan Behnel), avoid -L/usr/lib
+      output from xml2-config (Fred Crozat), avoid an xmllint crash 
+      (Stefan Kost), don't stop HTML parsing on out of range chars.
+      
+   - Code cleanup: fix open() call third argument, regexp cut'n paste
+      copy error, unused variable in __xmlGlobalInitMutexLock (Hannes Eder),
+      some make distcheck realted fixes (John Carr)
+   - Improvements: HTTP Header: includes port number (William Brack),
+      testURI --debug option, 
+
+
+2.6.30: Aug 23 2007:
+   - Portability: Solaris crash on error handling, windows path fixes
+      (Roland Schwarz and Rob Richards), mingw build (Roland Schwarz)
+   - Bugfixes: xmlXPathNodeSetSort problem (William Brack), leak when
+      reusing a writer for a new document (Dodji Seketeli), Schemas
+      xsi:nil handling patch (Frank Gross), relative URI build problem
+      (Patrik Fimml), crash in xmlDocFormatDump, invalid char in comment
+      detection bug, fix disparity with xmlSAXUserParseMemory, automata
+      generation for complex regexp counts problems, Schemas IDC import
+      problems (Frank Gross), xpath predicate evailation error handling
+      (William Brack)
+
+
+2.6.29: Jun 12 2007:
+   - Portability: patches from Andreas Stricke for WinCEi,
+      fix compilation warnings (William Brack), avoid warnings on Apple OS/X
+      (Wendy Doyle and Mark Rowe), Windows compilation and threading
+      improvements (Rob Richards), compilation against old Python versions,
+      new GNU tar changes (Ryan Hill)
+   - Documentation: xmlURIUnescapeString comment, 
+   - Bugfixes: xmlBufferAdd problem (Richard Jones), 'make valgrind'
+      flag fix (Richard Jones), regexp interpretation of \,
+      htmlCreateDocParserCtxt (Jean-Daniel Dupas), configure.in
+      typo (Bjorn Reese), entity content failure, xmlListAppend() fix
+      (Georges-André Silber), XPath number serialization (William Brack),
+      nanohttp gzipped stream fix (William Brack and Alex Cornejo),
+      xmlCharEncFirstLine typo (Mark Rowe), uri bug (François Delyon),
+      XPath string value of PI nodes (William Brack), XPath node set
+      sorting bugs (William Brack), avoid outputting namespace decl
+      dups in the writer (Rob Richards), xmlCtxtReset bug, UTF-8 encoding
+      error handling, recustion on next in catalogs, fix a Relax-NG crash,
+      workaround wrong file: URIs, htmlNodeDumpFormatOutput on attributes,
+      invalid character in attribute detection bug, big comments before 
+      internal subset streaming bug, HTML parsing of attributes with : in
+      the name, IDness of name in HTML (Dagfinn I. Mannsåker) 
+   - Improvement: keep URI query parts in raw form (Richard Jones),
+      embed tag support in HTML (Michael Day) 
+
+
+2.6.28: Apr 17 2007:
+   - Documentation: comment fixes (Markus Keim), xpath comments fixes too
+      (James Dennett)
+   - Bug fixes: XPath bug (William Brack), HTML parser autoclose stack usage
+      (Usamah Malik), various regexp bug fixes (DV and William), path conversion
+      on Windows (Igor Zlatkovic), htmlCtxtReset fix (Michael Day), XPath
+      principal node of axis bug, HTML serialization of some codepoint
+      (Steven Rainwater), user data propagation in XInclude (Michael Day),
+      standalone and XML decl detection (Michael Day), Python id ouptut
+      for some id, fix the big python string memory leak, URI parsing fixes
+      (Stéphane Bidoul and William), long comments parsing bug (William),
+      concurrent threads initialization (Ted Phelps), invalid char
+      in text XInclude (William), XPath memory leak (William), tab in
+      python problems (Andreas Hanke), XPath node comparison error
+      (Oleg Paraschenko), cleanup patch for reader (Julien Reichel),
+      XML Schemas attribute group (William), HTML parsing problem (William),
+      fix char 0x2d in regexps (William), regexp quantifier range with
+      min occurs of 0 (William), HTML script/style parsing (Mike Day)
+   - Improvement: make xmlTextReaderSetup() public
+   - Compilation and postability: fix a missing include problem (William),
+      __ss_familly on AIX again (Björn Wiberg), compilation without zlib
+      (Michael Day), catalog patch for Win32 (Christian Ehrlicher),
+      Windows CE fixes (Andreas Stricke)
+   - Various CVS to SVN infrastructure changes
+
+
+2.6.27: Oct 25 2006:
+   - Portability fixes: file names on windows (Roland Schwingel, 
+      Emelyanov Alexey), windows compile fixup (Rob Richards), 
+      AIX iconv() is apparently case sensitive
+   - improvements: Python XPath types mapping (Nic Ferrier), XPath optimization
+      (Kasimier), add xmlXPathCompiledEvalToBoolean (Kasimier), Python node
+      equality and comparison (Andreas Pakulat), xmlXPathCollectAndTest
+      improvememt (Kasimier), expose if library was compiled with zlib 
+      support (Andrew Nosenko), cache for xmlSchemaIDCMatcher structs
+      (Kasimier), xmlTextConcat should work with comments and PIs (Rob
+      Richards), export htmlNewParserCtxt needed by Michael Day, refactoring
+      of catalog entity loaders (Michael Day), add XPointer support to 
+      python bindings (Ross Reedstrom, Brian West and Stefan Anca), 
+      try to sort out most file path to URI conversions and xmlPathToUri,
+      add --html --memory case to xmllint
+   - building fix: fix --with-minimum (Felipe Contreras), VMS fix, 
+      const'ification of HTML parser structures (Matthias Clasen),
+      portability fix (Emelyanov Alexey), wget autodetection (Peter
+      Breitenlohner),  remove the build path recorded in the python
+      shared module, separate library flags for shared and static builds
+      (Mikhail Zabaluev), fix --with-minimum --with-sax1 builds, fix
+      --with-minimum --with-schemas builds
+   - bug fix: xmlGetNodePath fix (Kasimier), xmlDOMWrapAdoptNode and
+      attribute (Kasimier), crash when using the recover mode, 
+      xmlXPathEvalExpr problem (Kasimier), xmlXPathCompExprAdd bug (Kasimier),
+      missing destry in xmlFreeRMutex (Andrew Nosenko), XML Schemas fixes
+      (Kasimier), warning on entities processing, XHTML script and style
+      serialization (Kasimier), python generator for long types, bug in
+      xmlSchemaClearValidCtxt (Bertrand Fritsch), xmlSchemaXPathEvaluate
+      allocation bug (Marton Illes), error message end of line (Rob Richards),
+      fix attribute serialization in writer (Rob Richards), PHP4 DTD validation
+      crasher, parser safety patch (Ben Darnell), _private context propagation
+      when parsing entities (with Michael Day), fix entities behaviour when 
+      using SAX, URI to file path fix (Mikhail Zabaluev), disapearing validity
+      context, arg error in SAX callback (Mike Hommey), fix mixed-content
+      autodetect when using --noblanks, fix xmlIOParseDTD error handling,
+      fix bug in xmlSplitQName on special Names, fix Relax-NG element content
+      validation bug, fix xmlReconciliateNs bug, fix potential attribute 
+      XML parsing bug, fix line/column accounting in XML parser, chunking bug
+      in the HTML parser on script, try to detect obviously buggy HTML
+      meta encoding indications, bugs with encoding BOM and xmlSaveDoc, 
+      HTML entities in attributes parsing, HTML minimized attribute values,
+      htmlReadDoc and htmlReadIO were broken, error handling bug in
+      xmlXPathEvalExpression (Olaf Walkowiak), fix a problem in
+      htmlCtxtUseOptions, xmlNewInputFromFile could leak (Marius Konitzer),
+      bug on misformed SSD regexps (Christopher Boumenot)
+      
+   - documentation: warning about XML_PARSE_COMPACT (Kasimier Buchcik),
+      fix xmlXPathCastToString documentation, improve man pages for
+      xmllitn and xmlcatalog (Daniel Leidert), fixed comments of a few
+      functions
+
+
+2.6.26: Jun 6 2006:
+   - portability fixes: Python detection (Joseph Sacco), compilation
+    error(William Brack and Graham Bennett), LynxOS patch (Olli Savia)
+   - bug fixes: encoding buffer problem, mix of code and data in
+    xmlIO.c(Kjartan Maraas), entities in XSD validation (Kasimier Buchcik),
+    variousXSD validation fixes (Kasimier), memory leak in pattern (Rob
+    Richards andKasimier), attribute with colon in name (Rob Richards), XPath
+    leak inerror reporting (Aleksey Sanin), XInclude text include of
+    selfdocument.
+   - improvements: Xpath optimizations (Kasimier), XPath object
+    cache(Kasimier)
+
+
+2.6.25: Jun 6 2006::
+Do not use or package 2.6.25
+2.6.24: Apr 28 2006:
+   - Portability fixes: configure on Windows, testapi compile on windows
+      (Kasimier Buchcik, venkat naidu), Borland C++ 6 compile (Eric Zurcher),
+      HP-UX compiler workaround (Rick Jones), xml2-config bugfix, gcc-4.1
+      cleanups, Python detection scheme (Joseph Sacco), UTF-8 file paths on
+      Windows (Roland Schwingel).
+      
+   - Improvements: xmlDOMWrapReconcileNamespaces xmlDOMWrapCloneNode (Kasimier
+      Buchcik), XML catalog debugging (Rick Jones), update to Unicode 4.01.
+   - Bug fixes: xmlParseChunk() problem in 2.6.23, xmlParseInNodeContext()
+      on HTML docs, URI behaviour on Windows (Rob Richards), comment streaming
+      bug, xmlParseComment (with William Brack), regexp bug fixes (DV &
+      Youri Golovanov), xmlGetNodePath on text/CDATA (Kasimier),
+      one Relax-NG interleave bug, xmllint --path and --valid,
+      XSD bugfixes (Kasimier), remove debug
+      left in Python bindings (Nic Ferrier), xmlCatalogAdd bug (Martin Cole),
+      xmlSetProp fixes (Rob Richards), HTML IDness (Rob Richards), a large
+      number of cleanups and small fixes based on Coverity reports, bug
+      in character ranges, Unicode tables const (Aivars Kalvans), schemas
+      fix (Stefan Kost), xmlRelaxNGParse error deallocation, 
+      xmlSchemaAddSchemaDoc error deallocation, error handling on unallowed
+      code point, ixmllint --nonet to never reach the net (Gary Coady),
+      line break in writer after end PI (Jason Viers). 
+   - Documentation: man pages updates and cleanups (Daniel Leidert).
+   - New features: Relax NG structure error handlers.
+
+
+2.6.23: Jan 5 2006:
+   - portability fixes: Windows (Rob Richards), getaddrinfo on Windows
+    (Kolja Nowak, Rob Richards), icc warnings (Kjartan Maraas),
+    --with-minimum compilation fixes (William Brack), error case handling fix
+    on Solaris (Albert Chin), don't use 'list' as parameter name reported by
+    Samuel Diaz Garcia, more old Unices portability fixes (Albert Chin),
+    MinGW compilation (Mark Junker), HP-UX compiler warnings (Rick
+  Jones),
+   - code cleanup: xmlReportError (Adrian Mouat), remove xmlBufferClose
+    (Geert Jansen), unreachable code (Oleksandr Kononenko), refactoring
+    parsing code (Bjorn Reese)
+   - bug fixes: xmlBuildRelativeURI and empty path (William Brack),
+    combinatory explosion and performances in regexp code, leak in
+    xmlTextReaderReadString(), xmlStringLenDecodeEntities problem (Massimo
+    Morara), Identity Constraints bugs and a segfault (Kasimier Buchcik),
+    XPath pattern based evaluation bugs (DV & Kasimier),
+    xmlSchemaContentModelDump() memory leak (Kasimier), potential leak in
+    xmlSchemaCheckCSelectorXPath(), xmlTextWriterVSprintf() misuse of
+    vsnprintf (William Brack), XHTML serialization fix (Rob Richards), CRLF
+    split problem (William), issues with non-namespaced attributes in
+    xmlAddChild() xmlAddNextSibling() and xmlAddPrevSibling() (Rob Richards),
+    HTML parsing of script, Python must not output to stdout (Nic Ferrier),
+    exclusive C14N namespace visibility (Aleksey Sanin), XSD dataype
+    totalDigits bug (Kasimier Buchcik), error handling when writing to an
+    xmlBuffer (Rob Richards), runtest schemas error not reported (Hisashi
+    Fujinaka), signed/unsigned problem in date/time code (Albert Chin), fix
+    XSI driven XSD validation (Kasimier), parsing of xs:decimal (Kasimier),
+    fix DTD writer output (Rob Richards), leak in xmlTextReaderReadInnerXml
+    (Gary Coady), regexp bug affecting schemas (Kasimier), configuration of
+    runtime debugging (Kasimier), xmlNodeBufGetContent bug on entity refs
+    (Oleksandr Kononenko), xmlRegExecPushString2 bug (Sreeni Nair),
+    compilation and build fixes (Michael Day), removed dependancies on
+    xmlSchemaValidError (Kasimier), bug with <xml:foo/>, more XPath
+    pattern based evaluation fixes (Kasimier)
+   - improvements: XSD Schemas redefinitions/restrictions (Kasimier
+    Buchcik), node copy checks and fix for attribute (Rob Richards), counted
+    transition bug in regexps, ctxt->standalone = -2 to indicate no
+    standalone attribute was found, add xmlSchemaSetParserStructuredErrors()
+    (Kasimier Buchcik), add xmlTextReaderSchemaValidateCtxt() to API
+    (Kasimier), handle gzipped HTTP resources (Gary Coady), add
+    htmlDocDumpMemoryFormat. (Rob Richards),
+   - documentation: typo (Michael Day), libxml man page (Albert Chin), save
+    function to XML buffer (Geert Jansen), small doc fix (Aron Stansvik),
+
+
+2.6.22: Sep 12 2005:
+   - build fixes: compile without schematron (Stéphane Bidoul)
+   - bug fixes: xmlDebugDumpNode on namespace node (Oleg Paraschenko)i,
+    CDATA push parser bug, xmlElemDump problem with XHTML1 doc,
+    XML_FEATURE_xxx clash with expat headers renamed XML_WITH_xxx, fix some
+    output formatting for meta element (Rob Richards), script and style
+    XHTML1 serialization (David Madore), Attribute derivation fixups in XSD
+    (Kasimier Buchcik), better IDC error reports (Kasimier Buchcik)
+   - improvements: add XML_SAVE_NO_EMPTY xmlSaveOption (Rob Richards), add
+    XML_SAVE_NO_XHTML xmlSaveOption, XML Schemas improvements preparing for
+    derive (Kasimier Buchcik).
+   - documentation: generation of gtk-doc like docs, integration with
+    devhelp.
+
+
+2.6.21: Sep 4 2005:
+   - build fixes: Cygwin portability fixes (Gerrit P. Haase), calling
+    convention problems on Windows (Marcus Boerger), cleanups based on Linus'
+    sparse tool, update of win32/configure.js (Rob Richards), remove warnings
+    on Windows(Marcus Boerger), compilation without SAX1, detection of the
+    Python binary, use $GCC inestad of $CC = 'gcc' (Andrew W. Nosenko),
+    compilation/link with threads and old gcc, compile problem by C370 on
+    Z/OS,
+   - bug fixes: http_proxy environments (Peter Breitenlohner), HTML UTF-8
+    bug (Jiri Netolicky), XPath NaN compare bug (William Brack),
+    htmlParseScript potential bug, Schemas regexp handling of spaces, Base64
+    Schemas comparisons NIST passes, automata build error xsd:all,
+    xmlGetNodePath for namespaced attributes (Alexander Pohoyda), xmlSchemas
+    foreign namespaces handling, XML Schemas facet comparison (Kupriyanov
+    Anatolij), xmlSchemaPSimpleTypeErr error report (Kasimier Buchcik), xml:
+    namespace ahndling in Schemas (Kasimier), empty model group in Schemas
+    (Kasimier), wilcard in Schemas (Kasimier), URI composition (William),
+    xs:anyType in Schemas (Kasimier), Python resolver emmitting error
+    messages directly, Python xmlAttr.parent (Jakub Piotr Clapa), trying to
+    fix the file path/URI conversion, xmlTextReaderGetAttribute fix (Rob
+    Richards), xmlSchemaFreeAnnot memleak (Kasimier), HTML UTF-8
+    serialization, streaming XPath, Schemas determinism detection problem,
+    XInclude bug, Schemas context type (Dean Hill), validation fix (Derek
+    Poon), xmlTextReaderGetAttribute[Ns] namespaces (Rob Richards), Schemas
+    type fix (Kuba Nowakowski), UTF-8 parser bug, error in encoding handling,
+    xmlGetLineNo fixes, bug on entities handling, entity name extraction in
+    error handling with XInclude, text nodes in HTML body tags (Gary Coady),
+    xml:id and IDness at the treee level fixes, XPath streaming patterns
+  bugs.
+   - improvements: structured interfaces for schemas and RNG error reports
+    (Marcus Boerger), optimization of the char data inner loop parsing
+    (thanks to Behdad Esfahbod for the idea), schematron validation though
+    not finished yet, xmlSaveOption to omit XML declaration, keyref match
+    error reports (Kasimier), formal expression handling code not plugged
+    yet, more lax mode for the HTML parser, parser XML_PARSE_COMPACT option
+    for text nodes allocation.
+   - documentation: xmllint man page had --nonet duplicated
+
+
+2.6.20: Jul 10 2005:
+   - build fixes: Windows build (Rob Richards), Mingw compilation (Igor
+    Zlatkovic), Windows Makefile (Igor), gcc warnings (Kasimier and
+    andriy@google.com), use gcc weak references to pthread to avoid the
+    pthread dependancy on Linux, compilation problem (Steve Nairn), compiling
+    of subset (Morten Welinder), IPv6/ss_family compilation (William Brack),
+    compilation when disabling parts of the library, standalone test
+    distribution.
+   - bug fixes: bug in lang(), memory cleanup on errors (William Brack),
+    HTTP query strings (Aron Stansvik), memory leak in DTD (William), integer
+    overflow in XPath (William), nanoftp buffer size, pattern "." apth fixup
+    (Kasimier), leak in tree reported by Malcolm Rowe, replaceNode patch
+    (Brent Hendricks), CDATA with NULL content (Mark Vakoc), xml:base fixup
+    on XInclude (William), pattern fixes (William), attribute bug in
+    exclusive c14n (Aleksey Sanin), xml:space and xml:lang with SAX2 (Rob
+    Richards), namespace trouble in complex parsing (Malcolm Rowe), XSD type
+    QNames fixes (Kasimier), XPath streaming fixups (William), RelaxNG bug
+    (Rob Richards), Schemas for Schemas fixes (Kasimier), removal of ID (Rob
+    Richards), a small RelaxNG leak, HTML parsing in push mode bug (James
+    Bursa), failure to detect UTF-8 parsing bugs in CDATA sections,
+    areBlanks() heuristic failure, duplicate attributes in DTD bug
+  (William).
+   - improvements: lot of work on Schemas by Kasimier Buchcik both on
+    conformance and streaming, Schemas validation messages (Kasimier Buchcik,
+    Matthew Burgess), namespace removal at the python level (Brent
+    Hendricks), Update to new Schemas regression tests from W3C/Nist
+    (Kasimier), xmlSchemaValidateFile() (Kasimier), implementation of
+    xmlTextReaderReadInnerXml and xmlTextReaderReadOuterXml (James Wert),
+    standalone test framework and programs, new DOM import APIs
+    xmlDOMWrapReconcileNamespaces() xmlDOMWrapAdoptNode() and
+    xmlDOMWrapRemoveNode(), extension of xmllint capabilities for SAX and
+    Schemas regression tests, xmlStopParser() available in pull mode too,
+    ienhancement to xmllint --shell namespaces support, Windows port of the
+    standalone testing tools (Kasimier and William),
+    xmlSchemaValidateStream() xmlSchemaSAXPlug() and xmlSchemaSAXUnplug() SAX
+    Schemas APIs, Schemas xmlReader support.
+
+
+2.6.19: Apr 02 2005:
+   - build fixes: drop .la from RPMs, --with-minimum build fix (William
+    Brack), use XML_SOCKLEN_T instead of SOCKLEN_T because it breaks with AIX
+    5.3 compiler, fixed elfgcchack.h generation and PLT reduction code on
+    Linux/ELF/gcc4
+   - bug fixes: schemas type decimal fixups (William Brack), xmmlint return
+    code (Gerry Murphy), small schemas fixes (Matthew Burgess and GUY
+    Fabrice), workaround "DAV:" namespace brokeness in c14n (Aleksey Sanin),
+    segfault in Schemas (Kasimier Buchcik), Schemas attribute validation
+    (Kasimier), Prop related functions and xmlNewNodeEatName (Rob Richards),
+    HTML serialization of name attribute on a elements, Python error handlers
+    leaks and improvement (Brent Hendricks), uninitialized variable in
+    encoding code, Relax-NG validation bug, potential crash if
+    gnorableWhitespace is NULL, xmlSAXParseDoc and xmlParseDoc signatures,
+    switched back to assuming UTF-8 in case no encoding is given at
+    serialization time
+   - improvements: lot of work on Schemas by Kasimier Buchcik on facets
+    checking and also mixed handling.
+   - 
+
+
+2.6.18: Mar 13 2005:
+   - build fixes: warnings (Peter Breitenlohner), testapi.c generation,
+    Bakefile support (Francesco Montorsi), Windows compilation (Joel Reed),
+    some gcc4 fixes, HP-UX portability fixes (Rick Jones).
+   - bug fixes: xmlSchemaElementDump namespace (Kasimier Buchcik), push and
+    xmlreader stopping on non-fatal errors, thread support for dictionnaries
+    reference counting (Gary Coady), internal subset and push problem, URL
+    saved in xmlCopyDoc, various schemas bug fixes (Kasimier), Python paths
+    fixup (Stephane Bidoul), xmlGetNodePath and namespaces, xmlSetNsProp fix
+    (Mike Hommey), warning should not count as error (William Brack),
+    xmlCreatePushParser empty chunk, XInclude parser flags (William), cleanup
+    FTP and HTTP code to reuse the uri parsing and IPv6 (William),
+    xmlTextWriterStartAttributeNS fix (Rob Richards), XMLLINT_INDENT being
+    empty (William), xmlWriter bugs (Rob Richards), multithreading on Windows
+    (Rich Salz), xmlSearchNsByHref fix (Kasimier), Python binding leak (Brent
+    Hendricks), aliasing bug exposed by gcc4 on s390, xmlTextReaderNext bug
+    (Rob Richards), Schemas decimal type fixes (William Brack),
+    xmlByteConsumed static buffer (Ben Maurer).
+   - improvement: speedup parsing comments and DTDs, dictionnary support for
+    hash tables, Schemas Identity constraints (Kasimier), streaming XPath
+    subset, xmlTextReaderReadString added (Bjorn Reese), Schemas canonical
+    values handling (Kasimier), add xmlTextReaderByteConsumed (Aron
+  Stansvik),
+   - Documentation: Wiki support (Joel Reed)
+
+
+2.6.17: Jan 16 2005:
+   - build fixes: Windows, warnings removal (William Brack),
+    maintainer-clean dependency(William), build in a different directory
+    (William), fixing --with-minimum configure build (William), BeOS build
+    (Marcin Konicki), Python-2.4 detection (William), compilation on AIX (Dan
+    McNichol)
+   - bug fixes: xmlTextReaderHasAttributes (Rob Richards), xmlCtxtReadFile()
+    to use the catalog(s), loop on output (William Brack), XPath memory leak,
+    ID deallocation problem (Steve Shepard), debugDumpNode crash (William),
+    warning not using error callback (William), xmlStopParser bug (William),
+    UTF-16 with BOM on DTDs (William), namespace bug on empty elements in
+    push mode (Rob Richards), line and col computations fixups (Aleksey
+    Sanin), xmlURIEscape fix (William), xmlXPathErr on bad range (William),
+    patterns with too many steps, bug in RNG choice optimization, line number
+    sometimes missing.
+   - improvements: XSD Schemas (Kasimier Buchcik), python generator
+    (William), xmlUTF8Strpos speedup (William), unicode Python strings
+    (William), XSD error reports (Kasimier Buchcik), Python __str__ call
+    serialize().
+   - new APIs: added xmlDictExists(), GetLineNumber and GetColumnNumber for
+    the xmlReader (Aleksey Sanin), Dynamic Shared Libraries APIs (mostly Joel
+    Reed), error extraction API from regexps, new XMLSave option for format
+    (Phil Shafer)
+   - documentation: site improvement (John Fleck), FAQ entries
+  (William).
+
+
+2.6.16: Nov 10 2004:
+   - general hardening and bug fixing crossing all the API based on new
+    automated regression testing
+   - build fix: IPv6 build and test on AIX (Dodji Seketeli)
+   - bug fixes: problem with XML::Libxml reported by Petr Pajas,  encoding
+    conversion functions return values, UTF-8 bug affecting XPath reported by
+    Markus Bertheau, catalog problem with NULL entries (William Brack)
+   - documentation: fix to xmllint man page, some API function descritpion
+    were updated.
+   - improvements: DTD validation APIs provided at the Python level (Brent
+    Hendricks)
+
+
+2.6.15: Oct 27 2004:
+   - security fixes on the nanoftp and nanohttp modules
+   - build fixes: xmllint detection bug in configure, building outside the
+    source tree (Thomas Fitzsimmons)
+   - bug fixes: HTML parser on broken ASCII chars in names (William), Python
+    paths (Malcolm Tredinnick), xmlHasNsProp and default namespace (William),
+    saving to python file objects (Malcolm Tredinnick), DTD lookup fix
+    (Malcolm), save back <group> in catalogs (William), tree build
+    fixes (DV and Rob Richards), Schemas memory bug, structured error handler
+    on Python 64bits, thread local memory deallocation, memory leak reported
+    by Volker Roth, xmlValidateDtd in the presence of an internal subset,
+    entities and _private problem (William), xmlBuildRelativeURI error
+    (William).
+   - improvements: better XInclude error reports (William), tree debugging
+    module and tests, convenience functions at the Reader API (Graham
+    Bennett), add support for PI in the HTML parser.
+
+
+2.6.14: Sep 29 2004:
+   - build fixes: configure paths for xmllint and xsltproc, compilation
+    without HTML parser, compilation warning cleanups (William Brack &
+    Malcolm Tredinnick), VMS makefile update (Craig Berry),
+   - bug fixes: xmlGetUTF8Char (William Brack), QName properties (Kasimier
+    Buchcik), XInclude testing, Notation serialization, UTF8ToISO8859x
+    transcoding (Mark Itzcovitz), lots of XML Schemas cleanup and fixes
+    (Kasimier), ChangeLog cleanup (Stepan Kasal), memory fixes (Mark Vakoc),
+    handling of failed realloc(), out of bound array adressing in Schemas
+    date handling, Python space/tabs cleanups (Malcolm Tredinnick), NMTOKENS
+    E20 validation fix (Malcolm),
+   - improvements: added W3C XML Schemas testsuite (Kasimier Buchcik), add
+    xmlSchemaValidateOneElement (Kasimier), Python exception hierearchy
+    (Malcolm Tredinnick), Python libxml2 driver improvement (Malcolm
+    Tredinnick), Schemas support for xsi:schemaLocation,
+    xsi:noNamespaceSchemaLocation, xsi:type (Kasimier Buchcik)
+
+
+2.6.13: Aug 31 2004:
+   - build fixes: Windows and zlib (Igor Zlatkovic), -O flag with gcc,
+    Solaris compiler warning, fixing RPM BuildRequires,
+   - fixes: DTD loading on Windows (Igor), Schemas error reports APIs
+    (Kasimier Buchcik), Schemas validation crash, xmlCheckUTF8 (William Brack
+    and Julius Mittenzwei), Schemas facet check (Kasimier), default namespace
+    problem (William), Schemas hexbinary empty values, encoding error could
+    genrate a serialization loop.
+   - Improvements: Schemas validity improvements (Kasimier), added --path
+    and --load-trace options to xmllint
+   - documentation: tutorial update (John Fleck)
+
+
+2.6.12: Aug 22 2004:
+   - build fixes: fix --with-minimum, elfgcchack.h fixes (Peter
+    Breitenlohner), perl path lookup (William), diff on Solaris (Albert
+    Chin), some 64bits cleanups.
+   - Python: avoid a warning with 2.3 (William Brack), tab and space mixes
+    (William), wrapper generator fixes (William), Cygwin support (Gerrit P.
+    Haase), node wrapper fix (Marc-Antoine Parent), XML Schemas support
+    (Torkel Lyng)
+   - Schemas: a lot of bug fixes and improvements from Kasimier Buchcik
+   - fixes: RVT fixes (William), XPath context resets bug (William), memory
+    debug (Steve Hay), catalog white space handling (Peter Breitenlohner),
+    xmlReader state after attribute reading (William), structured error
+    handler (William), XInclude generated xml:base fixup (William), Windows
+    memory reallocation problem (Steve Hay), Out of Memory conditions
+    handling (William and Olivier Andrieu), htmlNewDoc() charset bug,
+    htmlReadMemory init (William), a posteriori validation DTD base
+    (William), notations serialization missing, xmlGetNodePath (Dodji),
+    xmlCheckUTF8 (Diego Tartara), missing line numbers on entity
+  (William)
+   - improvements: DocBook catalog build scrip (William), xmlcatalog tool
+    (Albert Chin), xmllint --c14n option, no_proxy environment (Mike Hommey),
+    xmlParseInNodeContext() addition, extend xmllint --shell, allow XInclude
+    to not generate start/end nodes, extend xmllint --version to include CVS
+    tag (William)
+   - documentation: web pages fixes, validity API docs fixes (William)
+    schemas API fix (Eric Haszlakiewicz), xmllint man page (John Fleck)
+
+
+2.6.11: July 5 2004:
+   - Schemas: a lot of changes and improvements by Kasimier Buchcik for
+    attributes, namespaces and simple types.
+   - build fixes: --with-minimum (William Brack),  some gcc cleanup
+    (William), --with-thread-alloc (William)
+   - portability: Windows binary package change (Igor Zlatkovic), Catalog
+    path on Windows
+   - documentation: update to the tutorial (John Fleck), xmllint return code
+    (John Fleck), man pages (Ville Skytta),
+   - bug fixes: C14N bug serializing namespaces (Aleksey Sanin), testSAX
+    properly initialize the library (William), empty node set in XPath
+    (William), xmlSchemas errors (William), invalid charref problem pointed
+    by Morus Walter, XInclude xml:base generation (William), Relax-NG bug
+    with div processing (William), XPointer and xml:base problem(William),
+    Reader and entities, xmllint return code for schemas (William), reader
+    streaming problem (Steve Ball), DTD serialization problem (William),
+    libxml.m4 fixes (Mike Hommey), do not provide destructors as methods on
+    Python classes, xmlReader buffer bug, Python bindings memory interfaces
+    improvement (with Stéphane Bidoul), Fixed the push parser to be back to
+    synchronous behaviour.
+   - improvement: custom per-thread I/O enhancement (Rob Richards), register
+    namespace in debug shell (Stefano Debenedetti), Python based regression
+    test for non-Unix users (William), dynamically increase the number of
+    XPath extension functions in Python and fix a memory leak (Marc-Antoine
+    Parent and William)
+   - performance: hack done with Arjan van de Ven to reduce ELF footprint
+    and generated code on Linux, plus use gcc runtime profiling to optimize
+    the code generated in the RPM packages.
+
+
+2.6.10: May 17 2004:
+   - Web page generated for ChangeLog
+   - build fixes: --without-html problems, make check without make all
+   - portability: problem with xpath.c on Windows (MSC and Borland), memcmp
+    vs. strncmp on Solaris, XPath tests on Windows (Mark Vakoc), C++ do not
+    use "list" as parameter name, make tests work with Python 1.5 (Ed
+  Davis),
+   - improvements: made xmlTextReaderMode public, small buffers resizing
+    (Morten Welinder), add --maxmem option to xmllint, add
+    xmlPopInputCallback() for Matt Sergeant, refactoring of serialization
+    escaping, added escaping customization
+   - bugfixes: xsd:extension (Taihei Goi), assorted regexp bugs (William
+    Brack), xmlReader end of stream problem, node deregistration with reader,
+    URI escaping and filemanes,  XHTML1 formatting (Nick Wellnhofer), regexp
+    transition reduction (William), various XSD Schemas fixes (Kasimier
+    Buchcik), XInclude fallback problem (William), weird problems with DTD
+    (William), structured error handler callback context (William), reverse
+    xmlEncodeSpecialChars() behaviour back to escaping '"'
+
+
+2.6.9: Apr 18 2004:
+   - implement xml:id Working Draft, relaxed XPath id() checking
+   - bugfixes: xmlCtxtReset (Brent Hendricks), line number and CDATA (Dave
+    Beckett), Relax-NG compilation (William Brack), Regexp patches (with
+    William), xmlUriEscape (Mark Vakoc), a Relax-NG notAllowed problem (with
+    William), Relax-NG name classes compares (William), XInclude duplicate
+    fallback (William), external DTD encoding detection (William), a DTD
+    validation bug (William), xmlReader Close() fix, recusive extention
+    schemas
+   - improvements: use xmlRead* APIs in test tools (Mark Vakoc), indenting
+    save optimization, better handle IIS broken HTTP redirect  behaviour (Ian
+    Hummel), HTML parser frameset (James Bursa), libxml2-python RPM
+    dependancy, XML Schemas union support (Kasimier Buchcik), warning removal
+    clanup (William), keep ChangeLog compressed when installing from RPMs
+   - documentation: examples and xmlDocDumpMemory docs (John Fleck), new
+    example (load, xpath, modify, save), xmlCatalogDump() comments,
+   - Windows: Borland C++ builder (Eric Zurcher), work around Microsoft
+    compiler NaN handling bug (Mark Vakoc)
+
+
+2.6.8: Mar 23 2004:
+   - First step of the cleanup of the serialization code and APIs
+   - XML Schemas: mixed content (Adam Dickmeiss), QName handling fixes (Adam
+    Dickmeiss), anyURI for "" (John Belmonte)
+   - Python: Canonicalization C14N support added (Anthony Carrico)
+   - xmlDocCopyNode() extension (William)
+   - Relax-NG: fix when processing XInclude results (William), external
+    reference in interleave (William), missing error on <choice>
+    failure (William), memory leak in schemas datatype facets.
+   - xmlWriter: patch for better DTD support (Alfred Mickautsch)
+   - bug fixes: xmlXPathLangFunction memory leak (Mike Hommey and William
+    Brack), no ID errors if using HTML_PARSE_NOERROR, xmlcatalog fallbacks to
+    URI on SYSTEM lookup failure, XInclude parse flags inheritance (William),
+    XInclude and XPointer fixes for entities (William), XML parser bug
+    reported by Holger Rauch, nanohttp fd leak (William),  regexps char
+    groups '-' handling (William), dictionnary reference counting problems,
+    do not close stderr.
+   - performance patches from Petr Pajas
+   - Documentation fixes: XML_CATALOG_FILES in man pages (Mike Hommey)
+   - compilation and portability fixes: --without-valid, catalog cleanups
+    (Peter Breitenlohner), MingW patch (Roland Schwingel), cross-compilation
+    to Windows (Christophe de Vienne),  --with-html-dir fixup (Julio Merino
+    Vidal), Windows build (Eric Zurcher)
+
+
+2.6.7: Feb 23 2004:
+   - documentation: tutorial updates (John Fleck), benchmark results
+   - xmlWriter: updates and fixes (Alfred Mickautsch, Lucas Brasilino)
+   - XPath optimization (Petr Pajas)
+   - DTD ID handling optimization
+   - bugfixes: xpath number with  > 19 fractional (William Brack), push
+    mode with unescaped '>' characters, fix xmllint --stream --timing, fix
+    xmllint --memory --stream memory usage, xmlAttrSerializeTxtContent
+    handling NULL, trying to fix Relax-NG/Perl interface.
+   - python: 2.3 compatibility, whitespace fixes (Malcolm Tredinnick)
+   - Added relaxng option to xmllint --shell
+
+
+2.6.6: Feb 12 2004:
+   - nanohttp and nanoftp: buffer overflow error on URI parsing (Igor and
+    William) reported by Yuuichi Teranishi
+   - bugfixes: make test and path issues, xmlWriter attribute serialization
+    (William Brack), xmlWriter indentation (William), schemas validation
+    (Eric Haszlakiewicz), XInclude dictionnaries issues (William and Oleg
+    Paraschenko), XInclude empty fallback (William), HTML warnings (William),
+    XPointer in XInclude (William), Python namespace serialization,
+    isolat1ToUTF8 bound error (Alfred Mickautsch), output of parameter
+    entities in internal subset (William), internal subset bug in push mode,
+    <xs:all> fix (Alexey Sarytchev)
+   - Build: fix for automake-1.8 (Alexander Winston), warnings removal
+    (Philip Ludlam), SOCKLEN_T detection fixes (Daniel Richard), fix
+    --with-minimum configuration.
+   - XInclude: allow the 2001 namespace without warning.
+   - Documentation: missing example/index.html (John Fleck), version
+    dependancies (John Fleck)
+   - reader API: structured error reporting (Steve Ball)
+   - Windows compilation: mingw, msys (Mikhail Grushinskiy), function
+    prototype (Cameron Johnson), MSVC6 compiler warnings, _WINSOCKAPI_
+  patch
+   - Parsers: added xmlByteConsumed(ctxt) API to get the byte offest in
+    input.
+
+
+2.6.5: Jan 25 2004:
+   - Bugfixes: dictionnaries for schemas (William Brack), regexp segfault
+    (William), xs:all problem (William), a number of XPointer bugfixes
+    (William), xmllint error go to stderr, DTD validation problem with
+    namespace, memory leak (William), SAX1 cleanup and minimal options fixes
+    (Mark Vadoc), parser context reset on error (Shaun McCance), XPath union
+    evaluation problem (William) , xmlReallocLoc with NULL (Aleksey Sanin),
+    XML Schemas double free (Steve Ball), XInclude with no href, argument
+    callbacks order for XPath callbacks (Frederic Peters)
+   - Documentation: python scripts (William Brack), xslt stylesheets (John
+    Fleck), doc (Sven Zimmerman), I/O example.
+   - Python bindings: fixes (William), enum support (Stéphane Bidoul),
+    structured error reporting (Stéphane Bidoul)
+   - XInclude: various fixes for conformance, problem related to dictionnary
+    references (William & me), recursion (William)
+   - xmlWriter: indentation (Lucas Brasilino), memory leaks (Alfred
+    Mickautsch),
+   - xmlSchemas: normalizedString datatype (John Belmonte)
+   - code cleanup for strings functions (William)
+   - Windows: compiler patches (Mark Vakoc)
+   - Parser optimizations, a few new XPath and dictionnary APIs for future
+    XSLT optimizations.
+
+
+2.6.4: Dec 24 2003:
+   - Windows build fixes (Igor Zlatkovic)
+   - Some serious XInclude problems reported by Oleg Paraschenko and
+   - Unix and Makefile packaging fixes (me, William Brack,
+   - Documentation improvements (John Fleck, William Brack), example fix
+    (Lucas Brasilino)
+   - bugfixes: xmlTextReaderExpand() with xmlReaderWalker, XPath handling of
+    NULL strings (William Brack) , API building reader or parser from
+    filedescriptor should not close it, changed XPath sorting to be stable
+    again (William Brack), xmlGetNodePath() generating '(null)' (William
+    Brack), DTD validation and namespace bug (William Brack), XML Schemas
+    double inclusion behaviour
+
+
+2.6.3: Dec 10 2003:
+   - documentation updates and cleanup (DV, William Brack, John Fleck)
+   - added a repository of examples, examples from Aleksey Sanin, Dodji
+    Seketeli, Alfred Mickautsch
+   - Windows updates: Mark Vakoc, Igor Zlatkovic, Eric Zurcher, Mingw
+    (Kenneth Haley)
+   - Unicode range checking (William Brack)
+   - code cleanup (William Brack)
+   - Python bindings: doc (John Fleck),  bug fixes
+   - UTF-16 cleanup and BOM issues (William Brack)
+   - bug fixes: ID and xmlReader validation, XPath (William Brack),
+    xmlWriter (Alfred Mickautsch), hash.h inclusion problem, HTML parser
+    (James Bursa), attribute defaulting and validation, some serialization
+    cleanups, XML_GET_LINE macro, memory debug when using threads (William
+    Brack), serialization of attributes and entities content, xmlWriter
+    (Daniel Schulman)
+   - XInclude bugfix, new APIs and update to the last version including the
+    namespace change.
+   - XML Schemas improvements: include (Robert Stepanek), import and
+    namespace handling, fixed the regression tests troubles, added examples
+    based on Eric van der Vlist book, regexp fixes
+   - preliminary pattern support for streaming (needed for schemas
+    constraints), added xmlTextReaderPreservePattern() to collect subdocument
+    when streaming.
+   - various fixes in the structured error handling
+
+
+2.6.2: Nov 4 2003:
+   - XPath context unregistration fixes
+   - text node coalescing fixes (Mark Lilback)
+   - API to screate a W3C Schemas from an existing document (Steve Ball)
+   - BeOS patches (Marcin 'Shard' Konicki)
+   - xmlStrVPrintf function added (Aleksey Sanin)
+   - compilation fixes (Mark Vakoc)
+   - stdin parsing fix (William Brack)
+   - a posteriori DTD validation fixes
+   - xmlReader bug fixes: Walker fixes, python bindings
+   - fixed xmlStopParser() to really stop the parser and errors
+   - always generate line numbers when using the new xmlReadxxx
+  functions
+   - added XInclude support to the xmlReader interface
+   - implemented XML_PARSE_NONET parser option
+   - DocBook XSLT processing bug fixed
+   - HTML serialization for <p> elements (William Brack and me)
+   - XPointer failure in XInclude are now handled as resource errors
+   - fixed xmllint --html to use the HTML serializer on output (added
+    --xmlout to implement the previous behaviour of saving it using the XML
+    serializer)
+
+
+2.6.1: Oct 28 2003:
+   - Mostly bugfixes after the big 2.6.0 changes
+   - Unix compilation patches: libxml.m4 (Patrick Welche), warnings cleanup
+    (William Brack)
+   - Windows compilation patches (Joachim Bauch, Stephane Bidoul, Igor
+    Zlatkovic)
+   - xmlWriter bugfix (Alfred Mickautsch)
+   - chvalid.[ch]: couple of fixes from Stephane Bidoul
+   - context reset: error state reset, push parser reset (Graham
+  Bennett)
+   - context reuse: generate errors if file is not readable
+   - defaulted attributes for element coming from internal entities
+    (Stephane Bidoul)
+   - Python: tab and spaces mix (William Brack)
+   - Error handler could crash in DTD validation in 2.6.0
+   - xmlReader: do not use the document or element _private field
+   - testSAX.c: avoid a problem with some PIs (Massimo Morara)
+   - general bug fixes: mandatory encoding in text decl, serializing
+    Document Fragment nodes, xmlSearchNs 2.6.0 problem (Kasimier Buchcik),
+    XPath errors not reported,  slow HTML parsing of large documents.
+
+
+2.6.0: Oct 20 2003:
+   - Major revision release: should be API and ABI compatible but got a lot
+    of change
+   - Increased the library modularity, far more options can be stripped out,
+    a --with-minimum configuration will weight around 160KBytes
+   - Use per parser and per document dictionnary, allocate names and small
+    text nodes from the dictionnary
+   - Switch to a SAX2 like parser rewrote most of the XML parser core,
+    provides namespace resolution and defaulted attributes, minimize memory
+    allocations and copies, namespace checking and specific error handling,
+    immutable buffers, make predefined entities static structures, etc...
+   - rewrote all the error handling in the library, all errors can be
+    intercepted at a structured level, with precise information
+  available.
+   - New simpler and more generic XML and HTML parser APIs, allowing to
+    easilly modify the parsing options and reuse parser context for multiple
+    consecutive documents.
+   - Similar new APIs for the xmlReader, for options and reuse, provided new
+    functions to access content as const strings, use them for Python
+  bindings
+   - a  lot of other smaller API improvements: xmlStrPrintf (Aleksey Sanin),
+    Walker i.e. reader on a document tree based on Alfred Mickautsch code,
+    make room in nodes for line numbers, reference counting and future PSVI
+    extensions, generation of character ranges to be checked with faster
+    algorithm (William),  xmlParserMaxDepth (Crutcher Dunnavant), buffer
+    access
+   - New xmlWriter API provided by Alfred Mickautsch
+   - Schemas: base64 support by Anthony Carrico
+   - Parser<->HTTP integration fix, proper processing of the Mime-Type
+    and charset information if available.
+   - Relax-NG: bug fixes including the one reported by Martijn Faassen and
+    zeroOrMore, better error reporting.
+   - Python bindings (Stéphane Bidoul), never use stdout for errors
+  output
+   - Portability: all the headers have macros for export and calling
+    convention definitions (Igor Zlatkovic), VMS update (Craig A. Berry),
+    Windows: threads (Jesse Pelton), Borland compiler (Eric Zurcher,  Igor),
+    Mingw (Igor), typos (Mark Vakoc),  beta version (Stephane Bidoul),
+    warning cleanups on AIX and MIPS compilers (William Brack), BeOS (Marcin
+    'Shard' Konicki)
+   - Documentation fixes and README (William Brack), search fix (William),
+    tutorial updates (John Fleck), namespace docs (Stefan Kost)
+   - Bug fixes: xmlCleanupParser (Dave Beckett), threading uninitialized
+    mutexes, HTML doctype lowercase,  SAX/IO (William), compression detection
+    and restore (William), attribute declaration in DTDs (William), namespace
+    on attribute in HTML output (William), input filename (Rob Richards),
+    namespace DTD validation, xmlReplaceNode (Chris Ryland), I/O callbacks
+    (Markus Keim), CDATA serialization (Shaun McCance), xmlReader (Peter
+    Derr), high codepoint charref like &#x10FFFF;, buffer access in push
+    mode (Justin Fletcher), TLS threads on Windows (Jesse Pelton), XPath bug
+    (William), xmlCleanupParser (Marc Liyanage), CDATA output (William), HTTP
+    error handling.
+   - xmllint options: --dtdvalidfpi for Tobias Reif, --sax1 for compat
+    testing,  --nodict for building without tree dictionnary, --nocdata to
+    replace CDATA by text, --nsclean to remove surperfluous  namespace
+    declarations
+   - added xml2-config --libtool-libs option from Kevin P. Fleming
+   - a lot of profiling and tuning of the code, speedup patch for
+    xmlSearchNs() by Luca Padovani. The xmlReader should do far less
+    allocation and it speed should get closer to SAX. Chris Anderson worked
+    on speeding and cleaning up repetitive checking code.
+   - cleanup of "make tests"
+   - libxml-2.0-uninstalled.pc from Malcolm Tredinnick
+   - deactivated the broken docBook SGML parser code and plugged the XML
+    parser instead.
+
+
+2.5.11: Sep 9 2003:
+A bugfix only release:   - risk of crash in Relax-NG
+   - risk of crash when using multithreaded programs
+
+
+2.5.10: Aug 15 2003:
+A bugfixes only release   - Windows Makefiles (William Brack)
+   - UTF-16 support fixes (Mark Itzcovitz)
+   - Makefile and portability (William Brack) automake, Linux alpha, Mingw
+    on Windows (Mikhail Grushinskiy)
+   - HTML parser (Oliver Stoeneberg)
+   - XInclude performance problem reported by Kevin Ruscoe
+   - XML parser performance problem reported by Grant Goodale
+   - xmlSAXParseDTD() bug fix from Malcolm Tredinnick
+   - and a couple other cleanup
+
+
+2.5.9: Aug 9 2003:
+   - bugfixes: IPv6 portability, xmlHasNsProp (Markus Keim), Windows build
+    (Wiliam Brake, Jesse Pelton, Igor), Schemas (Peter Sobisch), threading
+    (Rob Richards), hexBinary type (), UTF-16 BOM (Dodji Seketeli),
+    xmlReader, Relax-NG schemas compilation, namespace handling,  EXSLT (Sean
+    Griffin), HTML parsing problem (William Brack), DTD validation for mixed
+    content + namespaces, HTML serialization, library initialization,
+    progressive HTML parser
+   - better interfaces for Relax-NG error handling (Joachim Bauch, )
+   - adding xmlXIncludeProcessTree() for XInclud'ing in a subtree
+   - doc fixes and improvements (John Fleck)
+   - configure flag for -with-fexceptions when embedding in C++
+   - couple of new UTF-8 helper functions (William Brack)
+   - general encoding cleanup + ISO-8859-x without iconv (Peter Jacobi)
+   - xmlTextReader cleanup + enum for node types (Bjorn Reese)
+   - general compilation/warning cleanup Solaris/HP-UX/... (William
+  Brack)
+
+
+2.5.8: Jul 6 2003:
+   - bugfixes: XPath, XInclude, file/URI mapping, UTF-16 save (Mark
+    Itzcovitz), UTF-8 checking, URI saving, error printing (William Brack),
+    PI related memleak, compilation without schemas or without xpath (Joerg
+    Schmitz-Linneweber/Garry Pennington), xmlUnlinkNode problem with DTDs,
+    rpm problem on , i86_64, removed a few compilation problems from 2.5.7,
+    xmlIOParseDTD, and xmlSAXParseDTD (Malcolm Tredinnick)
+   - portability: DJGPP (MsDos) , OpenVMS (Craig A. Berry)
+   - William Brack fixed multithreading lock problems
+   - IPv6 patch for FTP and HTTP accesses (Archana Shah/Wipro)
+   - Windows fixes (Igor Zlatkovic,  Eric Zurcher), threading (Stéphane
+    Bidoul)
+   - A few W3C Schemas Structure improvements
+   - W3C Schemas Datatype improvements (Charlie Bozeman)
+   - Python bindings for thread globals (Stéphane Bidoul), and method/class
+    generator
+   - added --nonet option to xmllint
+   - documentation improvements (John Fleck)
+
+
+2.5.7: Apr 25 2003:
+   - Relax-NG: Compiling to regexp and streaming validation on top of the
+    xmlReader interface, added to xmllint --stream
+   - xmlReader: Expand(), Next() and DOM access glue, bug fixes
+   - Support for large files: RGN validated a 4.5GB instance
+   - Thread support is now configured in by default
+   - Fixes: update of the Trio code (Bjorn), WXS Date and Duration fixes
+    (Charles Bozeman), DTD and namespaces (Brent Hendricks), HTML push parser
+    and zero bytes handling, some missing Windows file path conversions,
+    behaviour of the parser and validator in the presence of "out of memory"
+    error conditions
+   - extended the API to be able to plug a garbage collecting memory
+    allocator, added xmlMallocAtomic() and modified the allocations
+    accordingly.
+   - Performances: removed excessive malloc() calls, speedup of the push and
+    xmlReader interfaces, removed excessive thread locking
+   - Documentation: man page (John Fleck), xmlReader documentation
+   - Python: adding binding for xmlCatalogAddLocal (Brent M Hendricks)
+
+
+2.5.6: Apr 1 2003:
+   - Fixed W3C XML Schemas datatype, should be compliant now except for
+    binHex and base64 which are not supported yet.
+   - bug fixes: non-ASCII IDs, HTML output, XInclude on large docs and
+    XInclude entities handling, encoding detection on external subsets, XML
+    Schemas bugs and memory leaks, HTML parser (James Bursa)
+   - portability: python/trio (Albert Chin), Sun compiler warnings
+   - documentation: added --relaxng option to xmllint man page (John)
+   - improved error reporting: xml:space, start/end tag mismatches, Relax NG
+    errors
+
+
+2.5.5: Mar 24 2003:
+   - Lot of fixes on the Relax NG implementation. More testing including
+    DocBook and TEI examples.
+   - Increased the support for W3C XML Schemas datatype
+   - Several bug fixes in the URI handling layer
+   - Bug fixes: HTML parser, xmlReader, DTD validation, XPath, encoding
+    conversion, line counting in the parser.
+   - Added support for $XMLLINT_INDENT environment variable, FTP delete
+   - Fixed the RPM spec file name
+
+
+2.5.4: Feb 20 2003:
+   - Conformance testing and lot of fixes on Relax NG and XInclude
+    implementation
+   - Implementation of XPointer element() scheme
+   - Bug fixes: XML parser, XInclude entities merge, validity checking on
+    namespaces,
+    2 serialization bugs, node info generation problems, a DTD regexp
+    generation problem.
+  
+   - Portability: windows updates and path canonicalization (Igor)
+   - A few typo fixes (Kjartan Maraas)
+   - Python bindings generator fixes (Stephane Bidoul)
+
+
+2.5.3: Feb 10 2003:
+   - RelaxNG and XML Schemas datatypes improvements, and added a first
+    version of RelaxNG Python bindings
+   - Fixes: XLink (Sean Chittenden), XInclude (Sean Chittenden), API fix for
+    serializing namespace nodes, encoding conversion bug, XHTML1
+  serialization
+   - Portability fixes: Windows (Igor), AMD 64bits RPM spec file
+
+
+2.5.2: Feb 5 2003:
+   - First implementation of RelaxNG, added --relaxng flag to xmllint
+   - Schemas support now compiled in by default.
+   - Bug fixes: DTD validation, namespace checking, XInclude and entities,
+    delegateURI in XML Catalogs, HTML parser, XML reader (Stéphane Bidoul),
+    XPath parser and evaluation,  UTF8ToUTF8 serialization, XML reader memory
+    consumption, HTML parser, HTML serialization in the presence of
+  namespaces
+   - added an HTML API to check elements and attributes.
+   - Documentation improvement, PDF for the tutorial (John Fleck), doc
+    patches (Stefan Kost)
+   - Portability fixes: NetBSD (Julio Merino), Windows (Igor Zlatkovic)
+   - Added python bindings for XPointer, contextual error reporting
+    (Stéphane Bidoul)
+   - URI/file escaping problems (Stefano Zacchiroli)
+
+
+2.5.1: Jan 8 2003:
+   - Fixes a memory leak and configuration/compilation problems in 2.5.0
+   - documentation updates (John)
+   - a couple of XmlTextReader fixes
+
+
+2.5.0: Jan 6 2003:
+   - New XmltextReader interface based on C#
+    API (with help of Stéphane Bidoul)
+   - Windows: more exports, including the new API (Igor)
+   - XInclude fallback fix
+   - Python: bindings for the new API, packaging (Stéphane Bidoul),
+    drv_libxml2.py Python xml.sax driver (Stéphane Bidoul), fixes, speedup
+    and iterators for Python-2.2 (Hannu Krosing)
+   - Tutorial fixes (john Fleck and Niraj Tolia) xmllint man update
+  (John)
+   - Fix an XML parser bug raised by Vyacheslav Pindyura
+   - Fix for VMS serialization (Nigel Hall) and config (Craig A. Berry)
+   - Entities handling fixes
+   - new API to optionally track node creation and deletion (Lukas
+  Schroeder)
+   - Added documentation for the XmltextReader interface and some XML guidelines
+
+
+2.4.30: Dec 12 2002:
+   - 2.4.29 broke the python bindings, rereleasing
+   - Improvement/fixes of the XML API generator, and couple of minor code
+    fixes.
+
+
+2.4.29: Dec 11 2002:
+   - Windows fixes (Igor): Windows CE port, pthread linking, python bindings
+    (Stéphane Bidoul), Mingw (Magnus Henoch), and export list updates
+   - Fix for prev in python bindings (ERDI Gergo)
+   - Fix for entities handling (Marcus Clarke)
+   - Refactored the XML and HTML dumps to a single code path, fixed XHTML1
+    dump
+   - Fix for URI parsing when handling URNs with fragment identifiers
+   - Fix for HTTP URL escaping problem
+   - added an TextXmlReader (C#) like API (work in progress)
+   - Rewrote the API in XML generation script, includes a C parser and saves
+    more information needed for C# bindings
+
+
+2.4.28: Nov 22 2002:
+   - a couple of python binding fixes
+   - 2 bug fixes in the XML push parser
+   - potential memory leak removed (Martin Stoilov)
+   - fix to the configure script for Unix (Dimitri Papadopoulos)
+   - added encoding support for XInclude parse="text"
+   - autodetection of XHTML1 and specific serialization rules added
+   - nasty threading bug fixed (William Brack)
+
+
+2.4.27: Nov 17 2002:
+   - fixes for the Python bindings
+   - a number of bug fixes: SGML catalogs, xmlParseBalancedChunkMemory(),
+    HTML parser,  Schemas (Charles Bozeman), document fragment support
+    (Christian Glahn), xmlReconciliateNs (Brian Stafford), XPointer,
+    xmlFreeNode(), xmlSAXParseMemory (Peter Jones), xmlGetNodePath (Petr
+    Pajas), entities processing
+   - added grep to xmllint --shell
+   - VMS update patch from Craig A. Berry
+   - cleanup of the Windows build with support for more compilers (Igor),
+    better thread support on Windows
+   - cleanup of Unix Makefiles and spec file
+   - Improvements to the documentation (John Fleck)
+
+
+2.4.26: Oct 18 2002:
+   - Patches for Windows CE port, improvements on Windows paths handling
+   - Fixes to the validation  code (DTD and Schemas), xmlNodeGetPath() ,
+    HTML serialization, Namespace compliance,  and a number of small
+  problems
+
+
+2.4.25: Sep 26 2002:
+   - A number of bug fixes: XPath, validation, Python bindings, DOM and
+    tree, xmlI/O,  Html
+   - Serious rewrite of XInclude
+   - Made XML Schemas regexp part of the default build and APIs, small fix
+    and improvement of the regexp core
+   - Changed the validation code to reuse XML Schemas regexp APIs
+   - Better handling of Windows file paths, improvement of Makefiles (Igor,
+    Daniel Gehriger, Mark Vakoc)
+   - Improved the python I/O bindings, the tests, added resolver and regexp
+    APIs
+   - New logos from Marc Liyanage
+   - Tutorial improvements: John Fleck, Christopher Harris
+   - Makefile: Fixes for AMD x86_64 (Mandrake), DESTDIR (Christophe
+  Merlet)
+   - removal of all stderr/perror use for error reporting
+   - Better error reporting: XPath and DTD validation
+   - update of the trio portability layer (Bjorn Reese)
+
+2.4.24: Aug 22 2002   - XPath fixes (William), xf:escape-uri() (Wesley Terpstra)
+   - Python binding fixes: makefiles (William), generator, rpm build, x86-64
+    (fcrozat)
+   - HTML <style> and boolean attributes serializer fixes
+   - C14N improvements by Aleksey
+   - doc cleanups: Rick Jones
+   - Windows compiler makefile updates: Igor and Elizabeth Barham
+   - XInclude: implementation of fallback and xml:base fixup added
+
+
+2.4.23: July 6 2002:
+   - performances patches: Peter Jacobi
+   - c14n fixes, testsuite and performances: Aleksey Sanin
+   - added xmlDocFormatDump: Chema Celorio
+   - new tutorial: John Fleck
+   - new hash functions and performances: Sander Vesik, portability fix from
+    Peter Jacobi
+   - a number of bug fixes: XPath (William Brack, Richard Jinks), XML and
+    HTML parsers, ID lookup function
+   - removal of all remaining sprintf: Aleksey Sanin
+
+
+2.4.22: May 27 2002:
+   - a number of bug fixes: configure scripts, base handling, parser, memory
+    usage, HTML parser, XPath, documentation (Christian Cornelssen),
+    indentation, URI parsing
+   - Optimizations for XMLSec, fixing and making public some of the network
+    protocol handlers (Aleksey)
+   - performance patch from Gary Pennington
+   - Charles Bozeman provided date and time support for XML Schemas
+  datatypes
+
+
+2.4.21: Apr 29 2002:
+This release is both a bug fix release and also contains the early XML
+Schemas structures at 
+http://www.w3.org/TR/xmlschema-1/
+ and datatypes at 
+http://www.w3.org/TR/xmlschema-2/
+ code, beware, all
+interfaces are likely to change, there is huge holes, it is clearly a work in
+progress and don't even think of putting this code in a production system,
+it's actually not compiled in by default. The real fixes are:   - a couple of bugs or limitations introduced in 2.4.20
+   - patches for Borland C++ and MSC by Igor
+   - some fixes on XPath strings and conformance patches by Richard
+  Jinks
+   - patch from Aleksey for the ExcC14N specification
+   - OSF/1 bug fix by Bjorn
+
+
+2.4.20: Apr 15 2002:
+   - bug fixes: file descriptor leak, XPath, HTML output, DTD validation
+   - XPath conformance testing by Richard Jinks
+   - Portability fixes: Solaris, MPE/iX, Windows, OSF/1, python bindings,
+    libxml.m4
+
+
+2.4.19: Mar 25 2002:
+   - bug fixes: half a dozen XPath bugs, Validation, ISO-Latin to UTF8
+    encoder
+   - portability fixes in the HTTP code
+   - memory allocation checks using valgrind, and profiling tests
+   - revamp of the Windows build and Makefiles
+
+
+2.4.18: Mar 18 2002:
+   - bug fixes: tree, SAX, canonicalization, validation, portability,
+  XPath
+   - removed the --with-buffer option it was becoming unmaintainable
+   - serious cleanup of the Python makefiles
+   - speedup patch to XPath very effective for DocBook stylesheets
+   - Fixes for Windows build, cleanup of the documentation
+
+
+2.4.17: Mar 8 2002:
+   - a lot of bug fixes, including "namespace nodes have no parents in
+  XPath"
+   - fixed/improved the Python wrappers, added more examples and more
+    regression tests, XPath extension functions can now return node-sets
+   - added the XML Canonicalization support from Aleksey Sanin
+
+
+2.4.16: Feb 20 2002:
+   - a lot of bug fixes, most of them were triggered by the XML Testsuite
+    from OASIS and W3C. Compliance has been significantly improved.
+   - a couple of portability fixes too.
+
+
+2.4.15: Feb 11 2002:
+   - Fixed the Makefiles, especially the python module ones
+   - A few bug fixes and cleanup
+   - Includes cleanup
+
+
+2.4.14: Feb 8 2002:
+   - Change of License to the MIT
+    License basically for integration in XFree86 codebase, and removing
+    confusion around the previous dual-licensing
+   - added Python bindings, beta software but should already be quite
+    complete
+   - a large number of fixes and cleanups, especially for all tree
+    manipulations
+   - cleanup of the headers, generation of a reference API definition in
+  XML
+
+
+2.4.13: Jan 14 2002:
+   - update of the documentation: John Fleck and Charlie Bozeman
+   - cleanup of timing code from Justin Fletcher
+   - fixes for Windows and initial thread support on Win32: Igor and Serguei
+    Narojnyi
+   - Cygwin patch from Robert Collins
+   - added xmlSetEntityReferenceFunc() for Keith Isdale work on xsldbg
+
+
+2.4.12: Dec 7 2001:
+   - a few bug fixes: thread (Gary Pennington), xmllint (Geert Kloosterman),
+    XML parser (Robin Berjon), XPointer (Danny Jamshy), I/O cleanups
+  (robert)
+   - Eric Lavigne contributed project files for MacOS
+   - some makefiles cleanups
+
+
+2.4.11: Nov 26 2001:
+   - fixed a couple of errors in the includes, fixed a few bugs, some code
+    cleanups
+   - xmllint man pages improvement by Heiko Rupp
+   - updated VMS build instructions from John A Fotheringham
+   - Windows Makefiles updates from Igor
+
+
+2.4.10: Nov 10 2001:
+   - URI escaping fix (Joel Young)
+   - added xmlGetNodePath() (for paths or XPointers generation)
+   - Fixes namespace handling problems when using DTD and validation
+   - improvements on xmllint: Morus Walter patches for --format and
+    --encode, Stefan Kost and Heiko Rupp improvements on the --shell
+   - fixes for xmlcatalog linking pointed by Weiqi Gao
+   - fixes to the HTML parser
+
+
+2.4.9: Nov 6 2001:
+   - fixes more catalog bugs
+   - avoid a compilation problem, improve xmlGetLineNo()
+
+
+2.4.8: Nov 4 2001:
+   - fixed SGML catalogs broken in previous release, updated xmlcatalog
+  tool
+   - fixed a compile errors and some includes troubles.
+
+
+2.4.7: Oct 30 2001:
+   - exported some debugging interfaces
+   - serious rewrite of the catalog code
+   - integrated Gary Pennington thread safety patch, added configure option
+    and regression tests
+   - removed an HTML parser bug
+   - fixed a couple of potentially serious validation bugs
+   - integrated the SGML DocBook support in xmllint
+   - changed the nanoftp anonymous login passwd
+   - some I/O cleanup and a couple of interfaces for Perl wrapper
+   - general bug fixes
+   - updated xmllint man page by John Fleck
+   - some VMS and Windows updates
+
+
+2.4.6: Oct 10 2001:
+   - added an updated man pages by John Fleck
+   - portability and configure fixes
+   - an infinite loop on the HTML parser was removed (William)
+   - Windows makefile patches from Igor
+   - fixed half a dozen bugs reported for libxml or libxslt
+   - updated xmlcatalog to be able to modify SGML super catalogs
+
+
+2.4.5: Sep 14 2001:
+   - Remove a few annoying bugs in 2.4.4
+   - forces the HTML serializer to output decimal charrefs since some
+    version of Netscape can't handle hexadecimal ones
+
+
+1.8.16: Sep 14 2001:
+   - maintenance release of the old libxml1 branch, couple of bug and
+    portability fixes
+
+
+2.4.4: Sep 12 2001:
+   - added --convert to xmlcatalog, bug fixes and cleanups of XML
+  Catalog
+   - a few bug fixes and some portability changes
+   - some documentation cleanups
+
+
+2.4.3:  Aug 23 2001:
+   - XML Catalog support see the doc
+   - New NaN/Infinity floating point code
+   - A few bug fixes
+
+
+2.4.2:  Aug 15 2001:
+   - adds xmlLineNumbersDefault() to control line number generation
+   - lot of bug fixes
+   - the Microsoft MSC projects files should now be up to date
+   - inheritance of namespaces from DTD defaulted attributes
+   - fixes a serious potential security bug
+   - added a --format option to xmllint
+
+
+2.4.1:  July 24 2001:
+   - possibility to keep line numbers in the tree
+   - some computation NaN fixes
+   - extension of the XPath API
+   - cleanup for alpha and ia64 targets
+   - patch to allow saving through HTTP PUT or POST
+
+
+2.4.0: July 10 2001:
+   - Fixed a few bugs in XPath, validation, and tree handling.
+   - Fixed XML Base implementation, added a couple of examples to the
+    regression tests
+   - A bit of cleanup
+
+
+2.3.14: July 5 2001:
+   - fixed some entities problems and reduce memory requirement when
+    substituting them
+   - lots of improvements in the XPath queries interpreter can be
+    substantially faster
+   - Makefiles and configure cleanups
+   - Fixes to XPath variable eval, and compare on empty node set
+   - HTML tag closing bug fixed
+   - Fixed an URI reference computation problem when validating
+
+
+2.3.13: June 28 2001:
+   - 2.3.12 configure.in was broken as well as the push mode XML parser
+   - a few more fixes for compilation on Windows MSC by Yon Derek
+
+
+1.8.14: June 28 2001:
+   - Zbigniew Chyla gave a patch to use the old XML parser in push mode
+   - Small Makefile fix
+
+
+2.3.12: June 26 2001:
+   - lots of cleanup
+   - a couple of validation fix
+   - fixed line number counting
+   - fixed serious problems in the XInclude processing
+   - added support for UTF8 BOM at beginning of entities
+   - fixed a strange gcc optimizer bugs in xpath handling of float, gcc-3.0
+    miscompile uri.c (William), Thomas Leitner provided a fix for the
+    optimizer on Tru64
+   - incorporated Yon Derek and Igor Zlatkovic  fixes and improvements for
+    compilation on Windows MSC
+   - update of libxml-doc.el (Felix Natter)
+   - fixed 2 bugs in URI normalization code
+
+
+2.3.11: June 17 2001:
+   - updates to trio, Makefiles and configure should fix some portability
+    problems (alpha)
+   - fixed some HTML serialization problems (pre, script, and block/inline
+    handling), added encoding aware APIs, cleanup of this code
+   - added xmlHasNsProp()
+   - implemented a specific PI for encoding support in the DocBook SGML
+    parser
+   - some XPath fixes (-Infinity, / as a function parameter and namespaces
+    node selection)
+   - fixed a performance problem and an error in the validation code
+   - fixed XInclude routine to implement the recursive behaviour
+   - fixed xmlFreeNode problem when libxml is included statically twice
+   - added --version to xmllint for bug reports
+
+
+2.3.10: June 1 2001:
+   - fixed the SGML catalog support
+   - a number of reported bugs got fixed, in XPath, iconv detection,
+    XInclude processing
+   - XPath string function should now handle unicode correctly
+
+
+2.3.9: May 19 2001:
+Lots of bugfixes, and added a basic SGML catalog support:   - HTML push bugfix #54891 and another patch from Jonas Borgström
+   - some serious speed optimization again
+   - some documentation cleanups
+   - trying to get better linking on Solaris (-R)
+   - XPath API cleanup from Thomas Broyer
+   - Validation bug fixed #54631, added a patch from Gary Pennington, fixed
+    xmlValidGetValidElements()
+   - Added an INSTALL file
+   - Attribute removal added to API: #54433
+   - added a basic support for SGML catalogs
+   - fixed xmlKeepBlanksDefault(0) API
+   - bugfix in xmlNodeGetLang()
+   - fixed a small configure portability problem
+   - fixed an inversion of SYSTEM and PUBLIC identifier in HTML document
+
+
+1.8.13: May 14 2001:
+   - bugfixes release of the old libxml1 branch used by Gnome
+
+
+2.3.8: May 3 2001:
+   - Integrated an SGML DocBook parser for the Gnome project
+   - Fixed a few things in the HTML parser
+   - Fixed some XPath bugs raised by XSLT use, tried to fix the floating
+    point portability issue
+   - Speed improvement (8M/s for SAX, 3M/s for DOM, 1.5M/s for
+    DOM+validation using the XML REC as input and a 700MHz celeron).
+   - incorporated more Windows cleanup
+   - added xmlSaveFormatFile()
+   - fixed problems in copying nodes with entities references (gdome)
+   - removed some troubles surrounding the new validation module
+
+
+2.3.7: April 22 2001:
+   - lots of small bug fixes, corrected XPointer
+   - Non deterministic content model validation support
+   - added xmlDocCopyNode for gdome2
+   - revamped the way the HTML parser handles end of tags
+   - XPath: corrections of namespaces support and number formatting
+   - Windows: Igor Zlatkovic patches for MSC compilation
+   - HTML output fixes from P C Chow and William M. Brack
+   - Improved validation speed sensible for DocBook
+   - fixed a big bug with ID declared in external parsed entities
+   - portability fixes, update of Trio from Bjorn Reese
+
+
+2.3.6: April 8 2001:
+   - Code cleanup using extreme gcc compiler warning options, found and
+    cleared half a dozen potential problem
+   - the Eazel team found an XML parser bug
+   - cleaned up the user of some of the string formatting function. used the
+    trio library code to provide the one needed when the platform is missing
+    them
+   - xpath: removed a memory leak and fixed the predicate evaluation
+    problem, extended the testsuite and cleaned up the result. XPointer seems
+    broken ...
+
+
+2.3.5: Mar 23 2001:
+   - Biggest change is separate parsing and evaluation of XPath expressions,
+    there is some new APIs for this too
+   - included a number of bug fixes(XML push parser, 51876, notations,
+  52299)
+   - Fixed some portability issues
+
+
+2.3.4: Mar 10 2001:
+   - Fixed bugs #51860 and #51861
+   - Added a global variable xmlDefaultBufferSize to allow default buffer
+    size to be application tunable.
+   - Some cleanup in the validation code, still a bug left and this part
+    should probably be rewritten to support ambiguous content model :-\
+   - Fix a couple of serious bugs introduced or raised by changes in 2.3.3
+    parser
+   - Fixed another bug in xmlNodeGetContent()
+   - Bjorn fixed XPath node collection and Number formatting
+   - Fixed a loop reported in the HTML parsing
+   - blank space are reported even if the Dtd content model proves that they
+    are formatting spaces, this is for XML conformance
+
+
+2.3.3: Mar 1 2001:
+   - small change in XPath for XSLT
+   - documentation cleanups
+   - fix in validation by Gary Pennington
+   - serious parsing performances improvements
+
+
+2.3.2: Feb 24 2001:
+   - chasing XPath bugs, found a bunch, completed some TODO
+   - fixed a Dtd parsing bug
+   - fixed a bug in xmlNodeGetContent
+   - ID/IDREF support partly rewritten by Gary Pennington
+
+
+2.3.1: Feb 15 2001:
+   - some XPath and HTML bug fixes for XSLT
+   - small extension of the hash table interfaces for DOM gdome2
+    implementation
+   - A few bug fixes
+
+
+2.3.0: Feb 8 2001 (2.2.12 was on 25 Jan but I didn't kept track):
+   - Lots of XPath bug fixes
+   - Add a mode with Dtd lookup but without validation error reporting for
+    XSLT
+   - Add support for text node without escaping (XSLT)
+   - bug fixes for xmlCheckFilename
+   - validation code bug fixes from Gary Pennington
+   - Patch from Paul D. Smith correcting URI path normalization
+   - Patch to allow simultaneous install of libxml-devel and
+  libxml2-devel
+   - the example Makefile is now fixed
+   - added HTML to the RPM packages
+   - tree copying bugfixes
+   - updates to Windows makefiles
+   - optimization patch from Bjorn Reese
+
+
+2.2.11: Jan 4 2001:
+   - bunch of bug fixes (memory I/O, xpath, ftp/http, ...)
+   - added htmlHandleOmittedElem()
+   - Applied Bjorn Reese's IPV6 first patch
+   - Applied Paul D. Smith patches for validation of XInclude results
+   - added XPointer xmlns() new scheme support
+
+
+2.2.10: Nov 25 2000:
+   - Fix the Windows problems of 2.2.8
+   - integrate OpenVMS patches
+   - better handling of some nasty HTML input
+   - Improved the XPointer implementation
+   - integrate a number of provided patches
+
+
+2.2.9: Nov 25 2000:
+   - erroneous release :-(
+
+
+2.2.8: Nov 13 2000:
+   - First version of XInclude
+    support
+   - Patch in conditional section handling
+   - updated MS compiler project
+   - fixed some XPath problems
+   - added an URI escaping function
+   - some other bug fixes
+
+
+2.2.7: Oct 31 2000:
+   - added message redirection
+   - XPath improvements (thanks TOM !)
+   - xmlIOParseDTD() added
+   - various small fixes in the HTML, URI, HTTP and XPointer support
+   - some cleanup of the Makefile, autoconf and the distribution content
+
+
+2.2.6: Oct 25 2000::
+   - Added an hash table module, migrated a number of internal structure to
+    those
+   - Fixed a posteriori validation problems
+   - HTTP module cleanups
+   - HTML parser improvements (tag errors, script/style handling, attribute
+    normalization)
+   - coalescing of adjacent text nodes
+   - couple of XPath bug fixes, exported the internal API
+
+
+2.2.5: Oct 15 2000::
+   - XPointer implementation and testsuite
+   - Lot of XPath fixes, added variable and functions registration, more
+    tests
+   - Portability fixes, lots of enhancements toward an easy Windows build
+    and release
+   - Late validation fixes
+   - Integrated a lot of contributed patches
+   - added memory management docs
+   - a performance problem when using large buffer seems fixed
+
+
+2.2.4: Oct 1 2000::
+   - main XPath problem fixed
+   - Integrated portability patches for Windows
+   - Serious bug fixes on the URI and HTML code
+
+
+2.2.3: Sep 17 2000:
+   - bug fixes
+   - cleanup of entity handling code
+   - overall review of all loops in the parsers, all sprintf usage has been
+    checked too
+   - Far better handling of larges Dtd. Validating against DocBook XML Dtd
+    works smoothly now.
+
+
+1.8.10: Sep 6 2000:
+   - bug fix release for some Gnome projects
+
+
+2.2.2: August 12 2000:
+   - mostly bug fixes
+   - started adding routines to access xml parser context options
+
+
+2.2.1: July 21 2000:
+   - a purely bug fixes release
+   - fixed an encoding support problem when parsing from a memory block
+   - fixed a DOCTYPE parsing problem
+   - removed a bug in the function allowing to override the memory
+    allocation routines
+
+
+2.2.0: July 14 2000:
+   - applied a lot of portability fixes
+   - better encoding support/cleanup and saving (content is now always
+    encoded in UTF-8)
+   - the HTML parser now correctly handles encodings
+   - added xmlHasProp()
+   - fixed a serious problem with &#38;
+   - propagated the fix to FTP client
+   - cleanup, bugfixes, etc ...
+   - Added a page about libxml Internationalization
+    support
+
+
+1.8.9:  July 9 2000:
+   - fixed the spec the RPMs should be better
+   - fixed a serious bug in the FTP implementation, released 1.8.9 to solve
+    rpmfind users problem
+
+
+2.1.1: July 1 2000:
+   - fixes a couple of bugs in the 2.1.0 packaging
+   - improvements on the HTML parser
+
+
+2.1.0 and 1.8.8: June 29 2000:
+   - 1.8.8 is mostly a commodity package for upgrading to libxml2 according
+    to new instructions. It fixes a nasty problem
+    about &#38; charref parsing
+   - 2.1.0 also ease the upgrade from libxml v1 to the recent version. it
+    also contains numerous fixes and enhancements:
+    added xmlStopParser() to stop parsing
+      improved a lot parsing speed when there is large CDATA blocs
+      includes XPath patches provided by Picdar Technology
+      tried to fix as much as possible DTD validation and namespace
+        related problems
+      output to a given encoding has been added/tested
+      lot of various fixes
+    
+   - added xmlStopParser() to stop parsing
+   - improved a lot parsing speed when there is large CDATA blocs
+   - includes XPath patches provided by Picdar Technology
+   - tried to fix as much as possible DTD validation and namespace
+        related problems
+   - output to a given encoding has been added/tested
+   - lot of various fixes
+
+
+2.0.0: Apr 12 2000:
+   - First public release of libxml2. If you are using libxml, it's a good
+    idea to check the 1.x to 2.x upgrade instructions. NOTE: while initially
+    scheduled for Apr 3 the release occurred only on Apr 12 due to massive
+    workload.
+   - The include are now located under $prefix/include/libxml (instead of
+    $prefix/include/gnome-xml), they also are referenced by
+    #include <libxml/xxx.h>
+    instead of
+    #include "xxx.h"
+  
+   - a new URI module for parsing URIs and following strictly RFC 2396
+   - the memory allocation routines used by libxml can now be overloaded
+    dynamically by using xmlMemSetup()
+   - The previously CVS only tool tester has been renamed
+    xmllint and is now installed as part of the libxml2
+    package
+   - The I/O interface has been revamped. There is now ways to plug in
+    specific I/O modules, either at the URI scheme detection level using
+    xmlRegisterInputCallbacks()  or by passing I/O functions when creating a
+    parser context using xmlCreateIOParserCtxt()
+   - there is a C preprocessor macro LIBXML_VERSION providing the version
+    number of the libxml module in use
+   - a number of optional features of libxml can now be excluded at
+    configure time (FTP/HTTP/HTML/XPath/Debug)
+
+
+2.0.0beta: Mar 14 2000:
+   - This is a first Beta release of libxml version 2
+   - It's available only fromxmlsoft.org
+    FTP, it's packaged as libxml2-2.0.0beta and available as tar and
+  RPMs
+   - This version is now the head in the Gnome CVS base, the old one is
+    available under the tag LIB_XML_1_X
+   - This includes a very large set of changes. From a  programmatic point
+    of view applications should not have to be modified too much, check the
+    upgrade page
+   - Some interfaces may changes (especially a bit about encoding).
+   - the updates includes:
+    fix I18N support. ISO-Latin-x/UTF-8/UTF-16 (nearly) seems correctly
+        handled now
+      Better handling of entities, especially well-formedness checking
+        and proper PEref extensions in external subsets
+      DTD conditional sections
+      Validation now correctly handle entities content
+      change
+        structures to accommodate DOM
+    
+   - fix I18N support. ISO-Latin-x/UTF-8/UTF-16 (nearly) seems correctly
+        handled now
+   - Better handling of entities, especially well-formedness checking
+        and proper PEref extensions in external subsets
+   - DTD conditional sections
+   - Validation now correctly handle entities content
+   - change
+        structures to accommodate DOM
+   - Serious progress were made toward compliance, here are the result of the test against the
+    OASIS testsuite (except the Japanese tests since I don't support that
+    encoding yet). This URL is rebuilt every couple of hours using the CVS
+    head version.
+
+
+1.8.7: Mar 6 2000:
+   - This is a bug fix release:
+   - It is possible to disable the ignorable blanks heuristic used by
+    libxml-1.x, a new function  xmlKeepBlanksDefault(0) will allow this. Note
+    that for adherence to XML spec, this behaviour will be disabled by
+    default in 2.x . The same function will allow to keep compatibility for
+    old code.
+   - Blanks in <a>  </a> constructs are not ignored anymore,
+    avoiding heuristic is really the Right Way :-\
+   - The unchecked use of snprintf which was breaking libxml-1.8.6
+    compilation on some platforms has been fixed
+   - nanoftp.c nanohttp.c: Fixed '#' and '?' stripping when processing
+  URIs
+
+
+1.8.6: Jan 31 2000:
+   - added a nanoFTP transport module, debugged until the new version of rpmfind can use
+    it without troubles
+
+
+1.8.5: Jan 21 2000:
+   - adding APIs to parse a well balanced chunk of XML (production [43] content of the
+    XML spec)
+   - fixed a hideous bug in xmlGetProp pointed by Rune.Djurhuus@fast.no
+   - Jody Goldberg <jgoldberg@home.com> provided another patch trying
+    to solve the zlib checks problems
+   - The current state in gnome CVS base is expected to ship as 1.8.5 with
+    gnumeric soon
+
+
+1.8.4: Jan 13 2000:
+   - bug fixes, reintroduced xmlNewGlobalNs(), fixed xmlNewNs()
+   - all exit() call should have been removed from libxml
+   - fixed a problem with INCLUDE_WINSOCK on WIN32 platform
+   - added newDocFragment()
+
+
+1.8.3: Jan 5 2000:
+   - a Push interface for the XML and HTML parsers
+   - a shell-like interface to the document tree (try tester --shell :-)
+   - lots of bug fixes and improvement added over XMas holidays
+   - fixed the DTD parsing code to work with the xhtml DTD
+   - added xmlRemoveProp(), xmlRemoveID() and xmlRemoveRef()
+   - Fixed bugs in xmlNewNs()
+   - External entity loading code has been revamped, now it uses
+    xmlLoadExternalEntity(), some fix on entities processing were added
+   - cleaned up WIN32 includes of socket stuff
+
+
+1.8.2: Dec 21 1999:
+   - I got another problem with includes and C++, I hope this issue is fixed
+    for good this time
+   - Added a few tree modification functions: xmlReplaceNode,
+    xmlAddPrevSibling, xmlAddNextSibling, xmlNodeSetName and
+    xmlDocSetRootElement
+   - Tried to improve the HTML output with help from Chris Lahey
+
+
+1.8.1: Dec 18 1999:
+   - various patches to avoid troubles when using libxml with C++ compilers
+    the "namespace" keyword and C escaping in include files
+   - a problem in one of the core macros IS_CHAR was corrected
+   - fixed a bug introduced in 1.8.0 breaking default namespace processing,
+    and more specifically the Dia application
+   - fixed a posteriori validation (validation after parsing, or by using a
+    Dtd not specified in the original document)
+   - fixed a bug in
+
+
+1.8.0: Dec 12 1999:
+   - cleanup, especially memory wise
+   - the parser should be more reliable, especially the HTML one, it should
+    not crash, whatever the input !
+   - Integrated various patches, especially a speedup improvement for large
+    dataset from Carl Nygard,
+    configure with --with-buffers to enable them.
+   - attribute normalization, oops should have been added long ago !
+   - attributes defaulted from DTDs should be available, xmlSetProp() now
+    does entities escaping by default.
+
+
+1.7.4: Oct 25 1999:
+   - Lots of HTML improvement
+   - Fixed some errors when saving both XML and HTML
+   - More examples, the regression tests should now look clean
+   - Fixed a bug with contiguous charref
+
+
+1.7.3: Sep 29 1999:
+   - portability problems fixed
+   - snprintf was used unconditionally, leading to link problems on system
+    were it's not available, fixed
+
+
+1.7.1: Sep 24 1999:
+   - The basic type for strings manipulated by libxml has been renamed in
+    1.7.1 from CHAR to xmlChar. The reason
+    is that CHAR was conflicting with a predefined type on Windows. However
+    on non WIN32 environment, compatibility is provided by the way of  a
+    #define .
+   - Changed another error : the use of a structure field called errno, and
+    leading to troubles on platforms where it's a macro
+
+
+1.7.0: Sep 23 1999:
+   - Added the ability to fetch remote DTD or parsed entities, see the nanohttp module.
+   - Added an errno to report errors by another mean than a simple printf
+    like callback
+   - Finished ID/IDREF support and checking when validation
+   - Serious memory leaks fixed (there is now a memory wrapper module)
+   - Improvement of XPath
+    implementation
+   - Added an HTML parser front-end
+
+Daniel Veillard at 
+bugs.html
diff --git a/src/README b/src/README
new file mode 100644
index 0000000..f1817aa
--- /dev/null
+++ b/src/README
@@ -0,0 +1,39 @@
+
+                  XML toolkit from the GNOME project
+
+Full documentation is available on-line at
+    http://xmlsoft.org/
+
+This code is released under the MIT Licence see the Copyright file.
+
+To build on an Unixised setup:
+   ./configure ; make ; make install
+To build on Windows:
+   see instructions on win32/Readme.txt
+
+To assert build quality:
+   on an Unixised setup:
+      run make tests
+   otherwise:
+       There is 3 standalone tools runtest.c runsuite.c testapi.c, which
+       should compile as part of the build or as any application would.
+       Launch them from this directory to get results, runtest checks 
+       the proper functionning of libxml2 main APIs while testapi does
+       a full coverage check. Report failures to the list.
+
+To report bugs, follow the instructions at: 
+  http://xmlsoft.org/bugs.html
+
+A mailing-list xml@gnome.org is available, to subscribe:
+    http://mail.gnome.org/mailman/listinfo/xml
+
+The list archive is at:
+    http://mail.gnome.org/archives/xml/
+
+All technical answers asked privately will be automatically answered on
+the list and archived for public access unless pricacy is explicitely
+required and justified.
+
+Daniel Veillard
+
+$Id$
diff --git a/src/README.tests b/src/README.tests
new file mode 100644
index 0000000..66522ab
--- /dev/null
+++ b/src/README.tests
@@ -0,0 +1,30 @@
+                       README.tests
+
+   Instructions for standalone test regressions of libxml2
+
+libxml2-tests-$version.tar.gz contains 3 standalone C programs as well
+as a large amount of tests and results coming from libxml2 itself and
+from W3C, NIST, Sun Microsystems, Microsoft and James Clark. Each C
+program has a different testing purpose:
+
+  runtest.c : runs libxml2 basic internal regression tests
+  runsuite.c: runs libxml2 against external regression tests
+  testapi.c : exercises the library public entry points
+  testchar.c: exercise the check of character ranges and UTF-8 validation
+
+The command:
+
+  make -f Makefile.tests check
+
+should be sufficient on an Unix system to build and exercise the tests
+for the version of the library installed on the system. Note however
+that there isn't backward compatibility provided so if the installed
+version is older to the testsuite one, failing to compile or run the tests
+is likely. In any event this won't work with an installed libxml2 older
+than 2.6.20.
+Building on other platfroms should be a matter of compiling the C files
+like any other program using libxml2, running the test should be done
+simply by launching the resulting executables.
+
+Daniel Veillard
+Thu Jul 24 2008
diff --git a/src/SAX.c b/src/SAX.c
new file mode 100644
index 0000000..8e5d460
--- /dev/null
+++ b/src/SAX.c
@@ -0,0 +1,180 @@
+/*
+ * SAX.c : Old SAX v1 handlers to build a tree.
+ *         Deprecated except for compatibility
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+
+#define IN_LIBXML
+#include "libxml.h"
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/valid.h>
+#include <libxml/entities.h>
+#include <libxml/xmlerror.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlIO.h>
+#include <libxml/SAX.h>
+#include <libxml/uri.h>
+#include <libxml/valid.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/globals.h>
+#include <libxml/SAX2.h>
+
+#ifdef LIBXML_LEGACY_ENABLED
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * initxmlDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ * @warning:  flag if non-zero sets the handler warning procedure
+ *
+ * Initialize the default XML SAX version 1 handler
+ * DEPRECATED: use xmlSAX2InitDefaultSAXHandler() for the new SAX2 blocks
+ */
+void
+initxmlDefaultSAXHandler(xmlSAXHandlerV1 *hdlr, int warning)
+{
+    
+    if(hdlr->initialized == 1)
+	return;
+
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = xmlSAX2ExternalSubset;
+    hdlr->isStandalone = xmlSAX2IsStandalone;
+    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
+    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
+    hdlr->resolveEntity = xmlSAX2ResolveEntity;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
+    hdlr->entityDecl = xmlSAX2EntityDecl;
+    hdlr->attributeDecl = xmlSAX2AttributeDecl;
+    hdlr->elementDecl = xmlSAX2ElementDecl;
+    hdlr->notationDecl = xmlSAX2NotationDecl;
+    hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+    hdlr->reference = xmlSAX2Reference;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = xmlSAX2CDataBlock;
+    hdlr->ignorableWhitespace = xmlSAX2Characters;
+    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
+    if (warning == 0)
+	hdlr->warning = NULL;
+    else
+	hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    hdlr->initialized = 1;
+}
+
+#ifdef LIBXML_HTML_ENABLED
+
+/**
+ * inithtmlDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ *
+ * Initialize the default HTML SAX version 1 handler
+ * DEPRECATED: use xmlSAX2InitHtmlDefaultSAXHandler() for the new SAX2 blocks
+ */
+void
+inithtmlDefaultSAXHandler(xmlSAXHandlerV1 *hdlr)
+{
+    if(hdlr->initialized == 1)
+	return;
+
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = NULL;
+    hdlr->isStandalone = NULL;
+    hdlr->hasInternalSubset = NULL;
+    hdlr->hasExternalSubset = NULL;
+    hdlr->resolveEntity = NULL;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = NULL;
+    hdlr->entityDecl = NULL;
+    hdlr->attributeDecl = NULL;
+    hdlr->elementDecl = NULL;
+    hdlr->notationDecl = NULL;
+    hdlr->unparsedEntityDecl = NULL;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+    hdlr->reference = NULL;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = xmlSAX2CDataBlock;
+    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
+    hdlr->comment = xmlSAX2Comment;
+    hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    hdlr->initialized = 1;
+}
+
+#endif /* LIBXML_HTML_ENABLED */
+
+#ifdef LIBXML_DOCB_ENABLED
+/**
+ * initdocbDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ *
+ * Initialize the default DocBook SAX version 1 handler
+ * DEPRECATED: use xmlSAX2InitDocbDefaultSAXHandler() for the new SAX2 blocks
+ */
+void
+initdocbDefaultSAXHandler(xmlSAXHandlerV1 *hdlr)
+{
+    if(hdlr->initialized == 1)
+	return;
+
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = NULL;
+    hdlr->isStandalone = xmlSAX2IsStandalone;
+    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
+    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
+    hdlr->resolveEntity = xmlSAX2ResolveEntity;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = NULL;
+    hdlr->entityDecl = xmlSAX2EntityDecl;
+    hdlr->attributeDecl = NULL;
+    hdlr->elementDecl = NULL;
+    hdlr->notationDecl = NULL;
+    hdlr->unparsedEntityDecl = NULL;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+    hdlr->reference = xmlSAX2Reference;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = NULL;
+    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+    hdlr->processingInstruction = NULL;
+    hdlr->comment = xmlSAX2Comment;
+    hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    hdlr->initialized = 1;
+}
+
+#endif /* LIBXML_DOCB_ENABLED */
+
+#endif /* LIBXML_SAX1_ENABLED */
+
+#define bottom_SAX
+#include "elfgcchack.h"
+#endif /* LIBXML_LEGACY_ENABLED */
diff --git a/src/SAX2.c b/src/SAX2.c
new file mode 100644
index 0000000..84c1f00
--- /dev/null
+++ b/src/SAX2.c
@@ -0,0 +1,2945 @@
+/*
+ * SAX2.c : Default SAX2 handler to build a tree.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+
+#define IN_LIBXML
+#include "libxml.h"
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/valid.h>
+#include <libxml/entities.h>
+#include <libxml/xmlerror.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlIO.h>
+#include <libxml/SAX.h>
+#include <libxml/uri.h>
+#include <libxml/valid.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/globals.h>
+
+/* Define SIZE_T_MAX unless defined through <limits.h>. */
+#ifndef SIZE_T_MAX
+# define SIZE_T_MAX     ((size_t)-1)
+#endif /* !SIZE_T_MAX */
+
+/* #define DEBUG_SAX2 */
+/* #define DEBUG_SAX2_TREE */
+
+/**
+ * TODO:
+ *
+ * macro to flag unimplemented blocks
+ * XML_CATALOG_PREFER user env to select between system/public prefered
+ * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
+ *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
+ *> values "system" and "public".  I have made the default be "system" to
+ *> match yours.
+ */
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+/*
+ * xmlSAX2ErrMemory:
+ * @ctxt:  an XML validation parser context
+ * @msg:   a string to accompany the error message
+ */
+static void
+xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
+    if (ctxt != NULL) {
+	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+	    ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg);
+	ctxt->errNo = XML_ERR_NO_MEMORY;
+	ctxt->instate = XML_PARSER_EOF;
+	ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlValidError:
+ * @ctxt:  an XML validation parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  extra data
+ * @str2:  extra data
+ *
+ * Handle a validation error
+ */
+static void
+xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+            const char *msg, const char *str1, const char *str2)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL) {
+	ctxt->errNo = error;
+	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
+	    schannel = ctxt->sax->serror;
+	__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);
+	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);
+    }
+}
+
+/**
+ * xmlFatalErrMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  an error string
+ * @str2:  an error string
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+               const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    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_PARSER, error,
+                    XML_ERR_FATAL, NULL, 0, 
+		    (const char *) str1, (const char *) str2,
+		    NULL, 0, 0, msg, str1, str2);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	ctxt->valid = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlWarnMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  an error string
+ * @str2:  an error string
+ *
+ * Handle a parser warning
+ */
+static void
+xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+               const char *msg, const xmlChar *str1)
+{
+    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_PARSER, error,
+                    XML_ERR_WARNING, NULL, 0, 
+		    (const char *) str1, NULL,
+		    NULL, 0, 0, msg, str1);
+}
+
+/**
+ * xmlNsErrMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  an error string
+ * @str2:  an error string
+ *
+ * Handle a namespace error
+ */
+static void
+xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+            const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    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_ERROR, NULL, 0, 
+		    (const char *) str1, (const char *) str2,
+		    NULL, 0, 0, msg, str1, str2);
+}
+
+/**
+ * xmlNsWarnMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  an error string
+ *
+ * Handle a namespace warning
+ */
+static void
+xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+             const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    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 *) str1, (const char *) str2,
+		    NULL, 0, 0, msg, str1, str2);
+}
+
+/**
+ * xmlSAX2GetPublicId:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
+ *
+ * Returns a xmlChar *
+ */
+const xmlChar *
+xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
+{
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+    return(NULL);
+}
+
+/**
+ * xmlSAX2GetSystemId:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provides the system ID, basically URL or filename e.g.
+ * http://www.sgmlsource.com/dtds/memo.dtd
+ *
+ * Returns a xmlChar *
+ */
+const xmlChar *
+xmlSAX2GetSystemId(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
+    return((const xmlChar *) ctxt->input->filename); 
+}
+
+/**
+ * xmlSAX2GetLineNumber:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provide the line number of the current parsing point.
+ *
+ * Returns an int
+ */
+int
+xmlSAX2GetLineNumber(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
+    return(ctxt->input->line);
+}
+
+/**
+ * xmlSAX2GetColumnNumber:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provide the column number of the current parsing point.
+ *
+ * Returns an int
+ */
+int
+xmlSAX2GetColumnNumber(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
+    return(ctxt->input->col);
+}
+
+/**
+ * xmlSAX2IsStandalone:
+ * @ctx: the user data (XML parser context)
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+int
+xmlSAX2IsStandalone(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
+    return(ctxt->myDoc->standalone == 1);
+}
+
+/**
+ * xmlSAX2HasInternalSubset:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+int
+xmlSAX2HasInternalSubset(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
+    return(ctxt->myDoc->intSubset != NULL);
+}
+
+/**
+ * xmlSAX2HasExternalSubset:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+int
+xmlSAX2HasExternalSubset(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
+    return(ctxt->myDoc->extSubset != NULL);
+}
+
+/**
+ * xmlSAX2InternalSubset:
+ * @ctx:  the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on internal subset declaration.
+ */
+void
+xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlDtdPtr dtd;
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
+            name, ExternalID, SystemID);
+#endif
+
+    if (ctxt->myDoc == NULL)
+	return;
+    dtd = xmlGetIntSubset(ctxt->myDoc);
+    if (dtd != NULL) {
+	if (ctxt->html)
+	    return;
+	xmlUnlinkNode((xmlNodePtr) dtd);
+	xmlFreeDtd(dtd);
+	ctxt->myDoc->intSubset = NULL;
+    }
+    ctxt->myDoc->intSubset = 
+	xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
+    if (ctxt->myDoc->intSubset == NULL)
+        xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
+}
+
+/**
+ * xmlSAX2ExternalSubset:
+ * @ctx: the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on external subset declaration.
+ */
+void
+xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
+            name, ExternalID, SystemID);
+#endif
+    if (((ExternalID != NULL) || (SystemID != NULL)) &&
+        (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
+	 (ctxt->wellFormed && ctxt->myDoc))) {
+	/*
+	 * Try to fetch and parse the external subset.
+	 */
+	xmlParserInputPtr oldinput;
+	int oldinputNr;
+	int oldinputMax;
+	xmlParserInputPtr *oldinputTab;
+	xmlParserInputPtr input = NULL;
+	xmlCharEncoding enc;
+	int oldcharset;
+
+	/*
+	 * Ask the Entity resolver to load the damn thing
+	 */
+	if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
+	    input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
+	                                        SystemID);
+	if (input == NULL) {
+	    return;
+	}
+
+	xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
+
+	/*
+	 * make sure we won't destroy the main document context
+	 */
+	oldinput = ctxt->input;
+	oldinputNr = ctxt->inputNr;
+	oldinputMax = ctxt->inputMax;
+	oldinputTab = ctxt->inputTab;
+	oldcharset = ctxt->charset;
+
+	ctxt->inputTab = (xmlParserInputPtr *)
+	                 xmlMalloc(5 * sizeof(xmlParserInputPtr));
+	if (ctxt->inputTab == NULL) {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
+	    ctxt->input = oldinput;
+	    ctxt->inputNr = oldinputNr;
+	    ctxt->inputMax = oldinputMax;
+	    ctxt->inputTab = oldinputTab;
+	    ctxt->charset = oldcharset;
+	    return;
+	}
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 5;
+	ctxt->input = NULL;
+	xmlPushInput(ctxt, input);
+
+	/*
+	 * On the fly encoding conversion if needed
+	 */
+	if (ctxt->input->length >= 4) {
+	    enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+
+	if (input->filename == NULL)
+	    input->filename = (char *) xmlCanonicPath(SystemID);
+	input->line = 1;
+	input->col = 1;
+	input->base = ctxt->input->cur;
+	input->cur = ctxt->input->cur;
+	input->free = NULL;
+
+	/*
+	 * let's parse that entity knowing it's an external subset.
+	 */
+	xmlParseExternalSubset(ctxt, ExternalID, SystemID);
+
+        /*
+	 * Free up the external entities
+	 */
+
+	while (ctxt->inputNr > 1)
+	    xmlPopInput(ctxt);
+	xmlFreeInputStream(ctxt->input);
+        xmlFree(ctxt->inputTab);
+
+	/*
+	 * Restore the parsing context of the main entity
+	 */
+	ctxt->input = oldinput;
+	ctxt->inputNr = oldinputNr;
+	ctxt->inputMax = oldinputMax;
+	ctxt->inputTab = oldinputTab;
+	ctxt->charset = oldcharset;
+	/* ctxt->wellFormed = oldwellFormed; */
+    }
+}
+
+/**
+ * xmlSAX2ResolveEntity:
+ * @ctx: the user data (XML parser context)
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * The entity loader, to control the loading of external entities,
+ * the application can either:
+ *    - override this xmlSAX2ResolveEntity() callback in the SAX block
+ *    - or better use the xmlSetExternalEntityLoader() function to
+ *      set up it's own entity resolution routine
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+xmlParserInputPtr
+xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr ret;
+    xmlChar *URI;
+    const char *base = NULL;
+
+    if (ctx == NULL) return(NULL);
+    if (ctxt->input != NULL)
+	base = ctxt->input->filename;
+    if (base == NULL)
+	base = ctxt->directory;
+
+    URI = xmlBuildURI(systemId, (const xmlChar *) base);
+
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
+#endif
+
+    ret = xmlLoadExternalEntity((const char *) URI,
+				(const char *) publicId, ctxt);
+    if (URI != NULL)
+	xmlFree(URI);
+    return(ret);
+}
+
+/**
+ * xmlSAX2GetEntity:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+xmlEntityPtr
+xmlSAX2GetEntity(void *ctx, const xmlChar *name)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlEntityPtr ret = NULL;
+
+    if (ctx == NULL) return(NULL);
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2GetEntity(%s)\n", name);
+#endif
+
+    if (ctxt->inSubset == 0) {
+	ret = xmlGetPredefinedEntity(name);
+	if (ret != NULL)
+	    return(ret);
+    }
+    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
+	if (ctxt->inSubset == 2) {
+	    ctxt->myDoc->standalone = 0;
+	    ret = xmlGetDocEntity(ctxt->myDoc, name);
+	    ctxt->myDoc->standalone = 1;
+	} else {
+	    ret = xmlGetDocEntity(ctxt->myDoc, name);
+	    if (ret == NULL) {
+		ctxt->myDoc->standalone = 0;
+		ret = xmlGetDocEntity(ctxt->myDoc, name);
+		if (ret != NULL) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
+	 "Entity(%s) document marked standalone but requires external subset\n",
+				   name, NULL);
+		}
+		ctxt->myDoc->standalone = 1;
+	    }
+	}
+    } else {
+	ret = xmlGetDocEntity(ctxt->myDoc, name);
+    }
+    if ((ret != NULL) &&
+	((ctxt->validate) || (ctxt->replaceEntities)) &&
+	(ret->children == NULL) &&
+	(ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
+	int val;
+
+	/*
+	 * for validation purposes we really need to fetch and
+	 * parse the external entity
+	 */
+	xmlNodePtr children;
+
+        val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
+		                         ret->ExternalID, &children);
+	if (val == 0) {
+	    xmlAddChildList((xmlNodePtr) ret, children);
+	} else {
+	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+		           "Failure to process entity %s\n", name, NULL);
+	    ctxt->validate = 0;
+	    return(NULL);
+	}
+	ret->owner = 1;
+	if (ret->checked == 0)
+	    ret->checked = 1;
+    }
+    return(ret);
+}
+
+/**
+ * xmlSAX2GetParameterEntity:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+xmlEntityPtr
+xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlEntityPtr ret;
+
+    if (ctx == NULL) return(NULL);
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
+#endif
+
+    ret = xmlGetParameterEntity(ctxt->myDoc, name);
+    return(ret);
+}
+
+
+/**
+ * xmlSAX2EntityDecl:
+ * @ctx: the user data (XML parser context)
+ * @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).
+ *
+ * An entity definition has been parsed
+ */
+void
+xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+    xmlEntityPtr ent;
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
+            name, type, publicId, systemId, content);
+#endif
+    if (ctxt->inSubset == 1) {
+	ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
+		              systemId, content);
+	if ((ent == NULL) && (ctxt->pedantic))
+	    xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
+	     "Entity(%s) already defined in the internal subset\n",
+	               name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    xmlChar *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
+	    ent->URI = URI;
+	}
+    } else if (ctxt->inSubset == 2) {
+	ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
+		              systemId, content);
+	if ((ent == NULL) && (ctxt->pedantic) &&
+	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+	    ctxt->sax->warning(ctxt->userData, 
+	     "Entity(%s) already defined in the external subset\n", name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    xmlChar *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
+	    ent->URI = URI;
+	}
+    } else {
+	xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+	               "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
+		       name, NULL);
+    }
+}
+
+/**
+ * xmlSAX2AttributeDecl:
+ * @ctx: the user data (XML parser context)
+ * @elem:  the name of the element
+ * @fullname:  the attribute name 
+ * @type:  the attribute type 
+ * @def:  the type of default value
+ * @defaultValue: the attribute default value
+ * @tree:  the tree of enumerated value set
+ *
+ * An attribute definition has been parsed
+ */
+void
+xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
+              int type, int def, const xmlChar *defaultValue,
+	      xmlEnumerationPtr tree)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlAttributePtr attr;
+    xmlChar *name = NULL, *prefix = NULL;
+
+    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
+        return;
+
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
+            elem, fullname, type, def, defaultValue);
+#endif
+    if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
+        (type != XML_ATTRIBUTE_ID)) {
+	/*
+	 * Raise the error but keep the validity flag
+	 */
+	int tmp = ctxt->valid;
+	xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
+	      "xml:id : attribute type should be ID\n", NULL, NULL);
+	ctxt->valid = tmp;
+    }
+    /* TODO: optimize name/prefix allocation */
+    name = xmlSplitQName(ctxt, fullname, &prefix);
+    ctxt->vctxt.valid = 1;
+    if (ctxt->inSubset == 1)
+	attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
+	       name, prefix, (xmlAttributeType) type,
+	       (xmlAttributeDefault) def, defaultValue, tree);
+    else if (ctxt->inSubset == 2)
+	attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
+	   name, prefix, (xmlAttributeType) type, 
+	   (xmlAttributeDefault) def, defaultValue, tree);
+    else {
+        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+	     "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
+	               name, NULL);
+	xmlFreeEnumeration(tree);
+	return;
+    }
+#ifdef LIBXML_VALID_ENABLED
+    if (ctxt->vctxt.valid == 0)
+	ctxt->valid = 0;
+    if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
+        (ctxt->myDoc->intSubset != NULL))
+	ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
+	                                        attr);
+#endif /* LIBXML_VALID_ENABLED */
+    if (prefix != NULL)
+	xmlFree(prefix);
+    if (name != NULL)
+	xmlFree(name);
+}
+
+/**
+ * xmlSAX2ElementDecl:
+ * @ctx: the user data (XML parser context)
+ * @name:  the element name 
+ * @type:  the element type 
+ * @content: the element value tree
+ *
+ * An element definition has been parsed
+ */
+void
+xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
+            xmlElementContentPtr content)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlElementPtr elem = NULL;
+
+    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
+        return;
+
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+                    "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
+#endif
+
+    if (ctxt->inSubset == 1)
+        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
+                                 name, (xmlElementTypeVal) type, content);
+    else if (ctxt->inSubset == 2)
+        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
+                                 name, (xmlElementTypeVal) type, content);
+    else {
+        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+	     "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
+	               name, NULL);
+        return;
+    }
+#ifdef LIBXML_VALID_ENABLED
+    if (elem == NULL)
+        ctxt->valid = 0;
+    if (ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset)
+        ctxt->valid &=
+            xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
+#endif /* LIBXML_VALID_ENABLED */
+}
+
+/**
+ * xmlSAX2NotationDecl:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+void
+xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNotationPtr nota = NULL;
+
+    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
+        return;
+
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
+#endif
+
+    if ((publicId == NULL) && (systemId == NULL)) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
+	     "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
+	               name, NULL);
+	return;
+    } else if (ctxt->inSubset == 1)
+	nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
+                              publicId, systemId);
+    else if (ctxt->inSubset == 2)
+	nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
+                              publicId, systemId);
+    else {
+	xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
+	     "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
+	               name, NULL);
+	return;
+    }
+#ifdef LIBXML_VALID_ENABLED
+    if (nota == NULL) ctxt->valid = 0;
+    if ((ctxt->validate) && (ctxt->wellFormed) &&
+        (ctxt->myDoc->intSubset != NULL))
+	ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
+	                                       nota);
+#endif /* LIBXML_VALID_ENABLED */
+}
+
+/**
+ * xmlSAX2UnparsedEntityDecl:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+void
+xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+    xmlEntityPtr ent;
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
+            name, publicId, systemId, notationName);
+#endif
+    if (ctxt->inSubset == 1) {
+	ent = xmlAddDocEntity(ctxt->myDoc, name,
+			XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+			publicId, systemId, notationName);
+	if ((ent == NULL) && (ctxt->pedantic) &&
+	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+	    ctxt->sax->warning(ctxt->userData, 
+	     "Entity(%s) already defined in the internal subset\n", name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    xmlChar *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
+	    ent->URI = URI;
+	}
+    } else if (ctxt->inSubset == 2) {
+	ent = xmlAddDtdEntity(ctxt->myDoc, name,
+			XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+			publicId, systemId, notationName);
+	if ((ent == NULL) && (ctxt->pedantic) &&
+	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+	    ctxt->sax->warning(ctxt->userData, 
+	     "Entity(%s) already defined in the external subset\n", name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    xmlChar *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
+	    ent->URI = URI;
+	}
+    } else {
+        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+	     "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
+	               name, NULL);
+    }
+}
+
+/**
+ * xmlSAX2SetDocumentLocator:
+ * @ctx: the user data (XML parser context)
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+void
+xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2SetDocumentLocator()\n");
+#endif
+}
+
+/**
+ * xmlSAX2StartDocument:
+ * @ctx: the user data (XML parser context)
+ *
+ * called when the document start being processed.
+ */
+void
+xmlSAX2StartDocument(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlDocPtr doc;
+
+    if (ctx == NULL) return;
+
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2StartDocument()\n");
+#endif
+    if (ctxt->html) {
+#ifdef LIBXML_HTML_ENABLED
+	if (ctxt->myDoc == NULL)
+	    ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
+	ctxt->myDoc->properties = XML_DOC_HTML;
+	ctxt->myDoc->parseFlags = ctxt->options;
+	if (ctxt->myDoc == NULL) {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+	    return;
+	}
+#else
+        xmlGenericError(xmlGenericErrorContext,
+		"libxml2 built without HTML support\n");
+	ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+	ctxt->instate = XML_PARSER_EOF;
+	ctxt->disableSAX = 1;
+	return;
+#endif
+    } else {
+	doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
+	if (doc != NULL) {
+	    doc->properties = 0;
+	    if (ctxt->options & XML_PARSE_OLD10)
+	        doc->properties |= XML_DOC_OLD10;
+	    doc->parseFlags = ctxt->options;
+	    if (ctxt->encoding != NULL)
+		doc->encoding = xmlStrdup(ctxt->encoding);
+	    else
+		doc->encoding = NULL;
+	    doc->standalone = ctxt->standalone;
+	} else {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+	    return;
+	}
+	if ((ctxt->dictNames) && (doc != NULL)) {
+	    doc->dict = ctxt->dict;
+	    xmlDictReference(doc->dict);
+	}
+    }
+    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
+	(ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
+	ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
+	if (ctxt->myDoc->URL == NULL)
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
+    }
+}
+
+/**
+ * xmlSAX2EndDocument:
+ * @ctx: the user data (XML parser context)
+ *
+ * called when the document end has been detected.
+ */
+void
+xmlSAX2EndDocument(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2EndDocument()\n");
+#endif
+    if (ctx == NULL) return;
+#ifdef LIBXML_VALID_ENABLED
+    if (ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset)
+	ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
+#endif /* LIBXML_VALID_ENABLED */
+
+    /*
+     * Grab the encoding if it was added on-the-fly
+     */
+    if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
+	(ctxt->myDoc->encoding == NULL)) {
+	ctxt->myDoc->encoding = ctxt->encoding;
+	ctxt->encoding = NULL;
+    }
+    if ((ctxt->inputTab != NULL) &&
+        (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
+        (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
+	(ctxt->myDoc->encoding == NULL)) {
+	ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
+    }
+    if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
+	(ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
+	ctxt->myDoc->charset = ctxt->charset;
+    }
+}
+
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+/**
+ * xmlSAX2AttributeInternal:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The attribute name, including namespace prefix
+ * @value:  The attribute value
+ * @prefix: the prefix on the element node
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ */
+static void
+xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
+             const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlAttrPtr ret;
+    xmlChar *name;
+    xmlChar *ns;
+    xmlChar *nval;
+    xmlNsPtr namespace;
+
+    if (ctxt->html) {
+	name = xmlStrdup(fullname);
+	ns = NULL;
+	namespace = NULL;
+    } else {
+	/*
+	 * Split the full name into a namespace prefix and the tag name
+	 */
+	name = xmlSplitQName(ctxt, fullname, &ns);
+	if ((name != NULL) && (name[0] == 0)) {
+	    if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
+		xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
+			    "invalid namespace declaration '%s'\n",
+			    fullname, NULL);
+	    } else {
+		xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
+			     "Avoid attribute ending with ':' like '%s'\n",
+			     fullname, NULL);
+	    }
+	    if (ns != NULL)
+		xmlFree(ns);
+	    ns = NULL;
+	    xmlFree(name);
+	    name = xmlStrdup(fullname);
+	}
+    }
+    if (name == NULL) {
+        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+	if (ns != NULL)
+	    xmlFree(ns);
+	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;
+#else
+        nval = NULL;
+#endif /* LIBXML_VALID_ENABLED */
+    }
+
+    /*
+     * Check whether it's a namespace definition
+     */
+    if ((!ctxt->html) && (ns == NULL) &&
+        (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
+        (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
+	xmlNsPtr nsret;
+	xmlChar *val;
+
+        if (!ctxt->replaceEntities) {
+	    ctxt->depth++;
+	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
+		                          0,0,0);
+	    ctxt->depth--;
+	} else {
+	    val = (xmlChar *) value;
+	}
+
+	if (val[0] != 0) {
+	    xmlURIPtr uri;
+
+	    uri = xmlParseURI((const char *)val);
+	    if (uri == NULL) {
+		if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+		    ctxt->sax->warning(ctxt->userData, 
+			 "xmlns: %s not a valid URI\n", val);
+	    } else {
+		if (uri->scheme == NULL) {
+		    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+			ctxt->sax->warning(ctxt->userData, 
+			     "xmlns: URI %s is not absolute\n", val);
+		}
+		xmlFreeURI(uri);
+	    }
+	}
+
+	/* a default namespace definition */
+	nsret = xmlNewNs(ctxt->node, val, NULL);
+
+#ifdef LIBXML_VALID_ENABLED
+	/*
+	 * Validate also for namespace decls, they are attributes from
+	 * an XML-1.0 perspective
+	 */
+        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
+	    ctxt->myDoc && ctxt->myDoc->intSubset)
+	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
+					   ctxt->node, prefix, nsret, val);
+#endif /* LIBXML_VALID_ENABLED */
+	if (name != NULL) 
+	    xmlFree(name);
+	if (nval != NULL)
+	    xmlFree(nval);
+	if (val != value)
+	    xmlFree(val);
+	return;
+    }
+    if ((!ctxt->html) &&
+	(ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
+        (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
+	xmlNsPtr nsret;
+	xmlChar *val;
+
+        if (!ctxt->replaceEntities) {
+	    ctxt->depth++;
+	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
+		                          0,0,0);
+	    ctxt->depth--;
+	    if (val == NULL) {
+	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+	        xmlFree(ns);
+		if (name != NULL) 
+		    xmlFree(name);
+		return;
+	    }
+	} else {
+	    val = (xmlChar *) value;
+	}
+
+	if (val[0] == 0) {
+	    xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
+		        "Empty namespace name for prefix %s\n", name, NULL);
+	}
+	if ((ctxt->pedantic != 0) && (val[0] != 0)) {
+	    xmlURIPtr uri;
+
+	    uri = xmlParseURI((const char *)val);
+	    if (uri == NULL) {
+	        xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
+			 "xmlns:%s: %s not a valid URI\n", name, value);
+	    } else {
+		if (uri->scheme == NULL) {
+		    xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
+			   "xmlns:%s: URI %s is not absolute\n", name, value);
+		}
+		xmlFreeURI(uri);
+	    }
+	}
+
+	/* a standard namespace definition */
+	nsret = xmlNewNs(ctxt->node, val, name);
+	xmlFree(ns);
+#ifdef LIBXML_VALID_ENABLED
+	/*
+	 * Validate also for namespace decls, they are attributes from
+	 * an XML-1.0 perspective
+	 */
+        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
+	    ctxt->myDoc && ctxt->myDoc->intSubset)
+	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
+					   ctxt->node, prefix, nsret, value);
+#endif /* LIBXML_VALID_ENABLED */
+	if (name != NULL) 
+	    xmlFree(name);
+	if (nval != NULL)
+	    xmlFree(nval);
+	if (val != value)
+	    xmlFree(val);
+	return;
+    }
+
+    if (ns != NULL) {
+	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;
+            }
+        }
+    } else {
+	namespace = NULL;
+    }
+
+    /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
+    ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
+
+    if (ret != NULL) {
+        if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
+	    xmlNodePtr tmp;
+
+	    ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
+	    tmp = ret->children;
+	    while (tmp != NULL) {
+		tmp->parent = (xmlNodePtr) ret;
+		if (tmp->next == NULL)
+		    ret->last = tmp;
+		tmp = tmp->next;
+	    }
+	} else if (value != NULL) {
+	    ret->children = xmlNewDocText(ctxt->myDoc, value);
+	    ret->last = ret->children;
+	    if (ret->children != NULL)
+		ret->children->parent = (xmlNodePtr) ret;
+	}
+    }
+
+#ifdef LIBXML_VALID_ENABLED
+    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset) {
+	
+	/*
+	 * If we don't substitute entities, the validation should be
+	 * done on a value with replaced entities anyway.
+	 */
+        if (!ctxt->replaceEntities) {
+	    xmlChar *val;
+
+	    ctxt->depth++;
+	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
+		                          0,0,0);
+	    ctxt->depth--;
+	    
+	    if (val == NULL)
+		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+				ctxt->myDoc, ctxt->node, ret, value);
+	    else {
+		xmlChar *nvalnorm;
+
+		/*
+		 * Do the last stage of the attribute normalization
+		 * It need to be done twice ... it's an extra burden related
+		 * to the ability to keep xmlSAX2References in attributes
+		 */
+		nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
+					    ctxt->node, fullname, val);
+		if (nvalnorm != NULL) {
+		    xmlFree(val);
+		    val = nvalnorm;
+		}
+
+		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+			        ctxt->myDoc, ctxt->node, ret, val);
+                xmlFree(val);
+	    }
+	} else {
+	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
+					       ctxt->node, ret, value);
+	}
+    } else
+#endif /* LIBXML_VALID_ENABLED */
+           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
+	       (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
+	        ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
+        /*
+	 * when validating, the ID registration is done at the attribute
+	 * validation level. Otherwise we have to do specific handling here.
+	 */
+	if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
+	    /*
+	     * Add the xml:id value
+	     *
+	     * Open issue: normalization of the value.
+	     */
+	    if (xmlValidateNCName(value, 1) != 0) {
+	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
+		      "xml:id : attribute value %s is not an NCName\n",
+			    (const char *) value, NULL);
+	    }
+	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
+	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
+	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
+	else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
+	    xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
+    }
+
+error:
+    if (nval != NULL)
+	xmlFree(nval);
+    if (ns != NULL) 
+	xmlFree(ns);
+}
+
+/*
+ * xmlCheckDefaultedAttributes:
+ *
+ * Check defaulted attributes from the DTD
+ */
+static void
+xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
+	const xmlChar *prefix, const xmlChar **atts) {
+    xmlElementPtr elemDecl;
+    const xmlChar *att;
+    int internal = 1;
+    int i;
+
+    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
+    if (elemDecl == NULL) {
+	elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
+	internal = 0;
+    }
+
+process_external_subset:
+
+    if (elemDecl != NULL) {
+	xmlAttributePtr attr = elemDecl->attributes;
+	/*
+	 * Check against defaulted attributes from the external subset
+	 * if the document is stamped as standalone
+	 */
+	if ((ctxt->myDoc->standalone == 1) &&
+	    (ctxt->myDoc->extSubset != NULL) &&
+	    (ctxt->validate)) {
+	    while (attr != NULL) {
+		if ((attr->defaultValue != NULL) &&
+		    (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
+					attr->elem, attr->name,
+					attr->prefix) == attr) &&
+		    (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
+					attr->elem, attr->name,
+					attr->prefix) == NULL)) {
+		    xmlChar *fulln;
+
+		    if (attr->prefix != NULL) {
+			fulln = xmlStrdup(attr->prefix);
+			fulln = xmlStrcat(fulln, BAD_CAST ":");
+			fulln = xmlStrcat(fulln, attr->name);
+		    } else {
+			fulln = xmlStrdup(attr->name);
+		    }
+                    if (fulln == NULL) {
+                        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+                        break;
+                    }
+
+		    /*
+		     * Check that the attribute is not declared in the
+		     * serialization
+		     */
+		    att = NULL;
+		    if (atts != NULL) {
+			i = 0;
+			att = atts[i];
+			while (att != NULL) {
+			    if (xmlStrEqual(att, fulln))
+				break;
+			    i += 2;
+			    att = atts[i];
+			}
+		    }
+		    if (att == NULL) {
+		        xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
+      "standalone: attribute %s on %s defaulted from external subset\n",
+				    (const char *)fulln,
+				    (const char *)attr->elem);
+		    }
+                    xmlFree(fulln);
+		}
+		attr = attr->nexth;
+	    }
+	}
+
+	/*
+	 * Actually insert defaulted values when needed
+	 */
+	attr = elemDecl->attributes;
+	while (attr != NULL) {
+	    /*
+	     * Make sure that attributes redefinition occuring in the
+	     * internal subset are not overriden by definitions in the
+	     * external subset.
+	     */
+	    if (attr->defaultValue != NULL) {
+		/*
+		 * the element should be instantiated in the tree if:
+		 *  - this is a namespace prefix
+		 *  - the user required for completion in the tree
+		 *    like XSLT
+		 *  - there isn't already an attribute definition 
+		 *    in the internal subset overriding it.
+		 */
+		if (((attr->prefix != NULL) &&
+		     (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
+		    ((attr->prefix == NULL) &&
+		     (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
+		    (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
+		    xmlAttributePtr tst;
+
+		    tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
+					     attr->elem, attr->name,
+					     attr->prefix);
+		    if ((tst == attr) || (tst == NULL)) {
+		        xmlChar fn[50];
+			xmlChar *fulln;
+
+                        fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
+			if (fulln == NULL) {
+			    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+			    return;
+			}
+
+			/*
+			 * Check that the attribute is not declared in the
+			 * serialization
+			 */
+			att = NULL;
+			if (atts != NULL) {
+			    i = 0;
+			    att = atts[i];
+			    while (att != NULL) {
+				if (xmlStrEqual(att, fulln))
+				    break;
+				i += 2;
+				att = atts[i];
+			    }
+			}
+			if (att == NULL) {
+			    xmlSAX2AttributeInternal(ctxt, fulln,
+						 attr->defaultValue, prefix);
+			}
+			if ((fulln != fn) && (fulln != attr->name))
+			    xmlFree(fulln);
+		    }
+		}
+	    }
+	    attr = attr->nexth;
+	}
+	if (internal == 1) {
+	    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
+		                             name, prefix);
+	    internal = 0;
+	    goto process_external_subset;
+	}
+    }
+}
+
+/**
+ * xmlSAX2StartElement:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The element name, including namespace prefix
+ * @atts:  An array of name/value attributes pairs, NULL terminated
+ *
+ * called when an opening tag has been processed.
+ */
+void
+xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret;
+    xmlNodePtr parent;
+    xmlNsPtr ns;
+    xmlChar *name;
+    xmlChar *prefix;
+    const xmlChar *att;
+    const xmlChar *value;
+    int i;
+
+    if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
+    parent = ctxt->node;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2StartElement(%s)\n", fullname);
+#endif
+
+    /*
+     * First check on validity:
+     */
+    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
+        ((ctxt->myDoc->intSubset == NULL) ||
+	 ((ctxt->myDoc->intSubset->notations == NULL) && 
+	  (ctxt->myDoc->intSubset->elements == NULL) &&
+	  (ctxt->myDoc->intSubset->attributes == NULL) && 
+	  (ctxt->myDoc->intSubset->entities == NULL)))) {
+	xmlErrValid(ctxt, XML_ERR_NO_DTD,
+	  "Validation failed: no DTD found !", NULL, NULL);
+	ctxt->validate = 0;
+    }
+       
+
+    /*
+     * Split the full name into a namespace prefix and the tag name
+     */
+    name = xmlSplitQName(ctxt, fullname, &prefix);
+
+
+    /*
+     * Note : the namespace resolution is deferred until the end of the
+     *        attributes parsing, since local namespace can be defined as
+     *        an attribute at this level.
+     */
+    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
+    if (ret == NULL) {
+        if (prefix != NULL)
+	    xmlFree(prefix);
+	xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+        return;
+    }
+    if (ctxt->myDoc->children == NULL) {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
+#endif
+        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
+    } else if (parent == NULL) {
+        parent = ctxt->myDoc->children;
+    }
+    ctxt->nodemem = -1;
+    if (ctxt->linenumbers) {
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->line < 65535)
+		ret->line = (short) ctxt->input->line;
+	    else
+	        ret->line = 65535;
+	}
+    }
+
+    /*
+     * We are parsing a new node.
+     */
+#ifdef DEBUG_SAX_TREE
+    xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
+#endif
+    nodePush(ctxt, ret);
+
+    /*
+     * Link the child element
+     */
+    if (parent != NULL) {
+        if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+	    xmlGenericError(xmlGenericErrorContext,
+		    "adding child %s to %s\n", name, parent->name);
+#endif
+	    xmlAddChild(parent, ret);
+	} else {
+#ifdef DEBUG_SAX_TREE
+	    xmlGenericError(xmlGenericErrorContext,
+		    "adding sibling %s to ", name);
+	    xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+	    xmlAddSibling(parent, ret);
+	}
+    }
+
+    /*
+     * Insert all the defaulted attributes from the DTD especially namespaces
+     */
+    if ((!ctxt->html) &&
+	((ctxt->myDoc->intSubset != NULL) ||
+	 (ctxt->myDoc->extSubset != NULL))) {
+	xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
+    }
+
+    /*
+     * process all the attributes whose name start with "xmlns"
+     */
+    if (atts != NULL) {
+        i = 0;
+	att = atts[i++];
+	value = atts[i++];
+	if (!ctxt->html) {
+	    while ((att != NULL) && (value != NULL)) {
+		if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
+		    (att[3] == 'n') && (att[4] == 's'))
+		    xmlSAX2AttributeInternal(ctxt, att, value, prefix);
+
+		att = atts[i++];
+		value = atts[i++];
+	    }
+	}
+    }
+
+    /*
+     * Search the namespace, note that since the attributes have been
+     * processed, the local namespaces are available.
+     */
+    ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
+    if ((ns == NULL) && (parent != NULL))
+	ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
+    if ((prefix != NULL) && (ns == NULL)) {
+	ns = xmlNewNs(ret, NULL, prefix);
+	xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+		     "Namespace prefix %s is not defined\n",
+		     prefix, NULL);
+    }
+
+    /*
+     * set the namespace node, making sure that if the default namspace
+     * is unbound on a parent we simply kee it NULL
+     */
+    if ((ns != NULL) && (ns->href != NULL) &&
+	((ns->href[0] != 0) || (ns->prefix != NULL)))
+	xmlSetNs(ret, ns);
+
+    /*
+     * process all the other attributes
+     */
+    if (atts != NULL) {
+        i = 0;
+	att = atts[i++];
+	value = atts[i++];
+	if (ctxt->html) {
+	    while (att != NULL) {
+		xmlSAX2AttributeInternal(ctxt, att, value, NULL);
+		att = atts[i++];
+		value = atts[i++];
+	    }
+	} else {
+	    while ((att != NULL) && (value != NULL)) {
+		if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
+		    (att[3] != 'n') || (att[4] != 's'))
+		    xmlSAX2AttributeInternal(ctxt, att, value, NULL);
+
+		/*
+		 * Next ones
+		 */
+		att = atts[i++];
+		value = atts[i++];
+	    }
+	}
+    }
+
+#ifdef LIBXML_VALID_ENABLED
+    /*
+     * If it's the Document root, finish the DTD validation and
+     * check the document root element for validity
+     */
+    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
+	int chk;
+
+	chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
+	if (chk <= 0)
+	    ctxt->valid = 0;
+	if (chk < 0)
+	    ctxt->wellFormed = 0;
+	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
+	ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
+    }
+#endif /* LIBXML_VALID_ENABLED */
+
+    if (prefix != NULL)
+	xmlFree(prefix);
+
+}
+
+/**
+ * xmlSAX2EndElement:
+ * @ctx: the user data (XML parser context)
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+void
+xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserNodeInfo node_info;
+    xmlNodePtr cur;
+
+    if (ctx == NULL) return;
+    cur = ctxt->node;
+#ifdef DEBUG_SAX
+    if (name == NULL)
+        xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
+    else
+	xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
+#endif
+    
+    /* Capture end position and add node */
+    if (cur != NULL && ctxt->record_info) {
+      node_info.end_pos = ctxt->input->cur - ctxt->input->base;
+      node_info.end_line = ctxt->input->line;
+      node_info.node = cur;
+      xmlParserAddNodeInfo(ctxt, &node_info);
+    }
+    ctxt->nodemem = -1;
+
+#ifdef LIBXML_VALID_ENABLED
+    if (ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset)
+        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
+					     cur);
+#endif /* LIBXML_VALID_ENABLED */
+
+    
+    /*
+     * end of parsing of this node.
+     */
+#ifdef DEBUG_SAX_TREE
+    xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
+#endif
+    nodePop(ctxt);
+}
+#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
+
+/*
+ * xmlSAX2TextNode:
+ * @ctxt:  the parser context
+ * @str:  the input string
+ * @len: the string length
+ * 
+ * Remove the entities from an attribute value
+ *
+ * Returns the newly allocated string or NULL if not needed or error
+ */
+static xmlNodePtr
+xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
+    xmlNodePtr ret;
+    const xmlChar *intern = NULL;
+
+    /*
+     * Allocate
+     */
+    if (ctxt->freeElems != NULL) {
+	ret = ctxt->freeElems;
+	ctxt->freeElems = ret->next;
+	ctxt->freeElemsNr--;
+    } else {
+	ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    }
+    if (ret == NULL) {
+        xmlErrMemory(ctxt, "xmlSAX2Characters");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlNode));
+    /*
+     * intern the formatting blanks found between tags, or the
+     * very short strings
+     */
+    if (ctxt->dictNames) {
+        xmlChar cur = str[len];
+
+	if ((len < (int) (2 * sizeof(void *))) &&
+	    (ctxt->options & XML_PARSE_COMPACT)) {
+	    /* store the string in the node overrithing properties and nsDef */
+	    xmlChar *tmp = (xmlChar *) &(ret->properties);
+	    memcpy(tmp, str, len);
+	    tmp[len] = 0;
+	    intern = tmp;
+	} else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
+	    ((cur == '<') && (str[len + 1] != '!')))) {
+	    intern = xmlDictLookup(ctxt->dict, str, len);
+	} else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
+	           (str[len + 1] != '!')) {
+	    int i;
+
+	    for (i = 1;i < len;i++) {
+		if (!IS_BLANK_CH(str[i])) goto skip;
+	    }
+	    intern = xmlDictLookup(ctxt->dict, str, len);
+	}
+    }
+skip:
+    ret->type = XML_TEXT_NODE;
+
+    ret->name = xmlStringText;
+    if (intern == NULL) {
+	ret->content = xmlStrndup(str, len);
+	if (ret->content == NULL) {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
+	    xmlFree(ret);
+	    return(NULL);
+	}
+    } else
+	ret->content = (xmlChar *) intern;
+
+    if (ctxt->input != NULL)
+        ret->line = ctxt->input->line;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(ret);
+    return(ret);
+}
+
+#ifdef LIBXML_VALID_ENABLED
+/*
+ * xmlSAX2DecodeAttrEntities:
+ * @ctxt:  the parser context
+ * @str:  the input string
+ * @len: the string length
+ * 
+ * Remove the entities from an attribute value
+ *
+ * Returns the newly allocated string or NULL if not needed or error
+ */
+static xmlChar *
+xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
+                          const xmlChar *end) {
+    const xmlChar *in;
+    xmlChar *ret;
+
+    in = str;
+    while (in < end)
+        if (*in++ == '&')
+	    goto decode;
+    return(NULL);
+decode:
+    ctxt->depth++;
+    ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
+				     XML_SUBSTITUTE_REF, 0,0,0);
+    ctxt->depth--;
+    return(ret);
+}
+#endif /* LIBXML_VALID_ENABLED */
+
+/**
+ * xmlSAX2AttributeNs:
+ * @ctx: the user data (XML parser context)
+ * @localname:  the local name of the attribute
+ * @prefix:  the attribute namespace prefix if available
+ * @URI:  the attribute namespace name if available
+ * @value:  Start of the attribute value
+ * @valueend: end of the attribute value
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ */
+static void
+xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
+                   const xmlChar * localname,
+                   const xmlChar * prefix,
+		   const xmlChar * value,
+		   const xmlChar * valueend)
+{
+    xmlAttrPtr ret;
+    xmlNsPtr namespace = NULL;
+    xmlChar *dup = NULL;
+
+    /*
+     * Note: if prefix == NULL, the attribute is not in the default namespace
+     */
+    if (prefix != NULL)
+	namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
+
+    /*
+     * allocate the node
+     */
+    if (ctxt->freeAttrs != NULL) {
+        ret = ctxt->freeAttrs;
+	ctxt->freeAttrs = ret->next;
+	ctxt->freeAttrsNr--;
+	memset(ret, 0, sizeof(xmlAttr));
+	ret->type = XML_ATTRIBUTE_NODE;
+
+	ret->parent = ctxt->node; 
+	ret->doc = ctxt->myDoc;
+	ret->ns = namespace;
+
+	if (ctxt->dictNames)
+	    ret->name = localname;
+	else
+	    ret->name = xmlStrdup(localname);
+
+        /* link at the end to preserv order, TODO speed up with a last */
+	if (ctxt->node->properties == NULL) {
+	    ctxt->node->properties = ret;
+	} else {
+	    xmlAttrPtr prev = ctxt->node->properties;
+
+	    while (prev->next != NULL) prev = prev->next;
+	    prev->next = ret;
+	    ret->prev = prev;
+	}
+
+	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	    xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
+    } else {
+	if (ctxt->dictNames)
+	    ret = xmlNewNsPropEatName(ctxt->node, namespace, 
+	                              (xmlChar *) localname, NULL);
+	else
+	    ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
+	if (ret == NULL) {
+	    xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
+	    return;
+	}
+    }
+
+    if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
+	xmlNodePtr tmp;
+
+	/*
+	 * We know that if there is an entity reference, then
+	 * the string has been dup'ed and terminates with 0
+	 * otherwise with ' or "
+	 */
+	if (*valueend != 0) {
+	    tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
+	    ret->children = tmp;
+	    ret->last = tmp;
+	    if (tmp != NULL) {
+		tmp->doc = ret->doc;
+		tmp->parent = (xmlNodePtr) ret;
+	    }
+	} else {
+	    ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
+						    valueend - value);
+	    tmp = ret->children;
+	    while (tmp != NULL) {
+	        tmp->doc = ret->doc;
+		tmp->parent = (xmlNodePtr) ret;
+		if (tmp->next == NULL)
+		    ret->last = tmp;
+		tmp = tmp->next;
+	    }
+	}
+    } else if (value != NULL) {
+	xmlNodePtr tmp;
+
+	tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
+	ret->children = tmp;
+	ret->last = tmp;
+	if (tmp != NULL) {
+	    tmp->doc = ret->doc;
+	    tmp->parent = (xmlNodePtr) ret;
+	}
+    }
+
+#ifdef LIBXML_VALID_ENABLED
+    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset) {
+	/*
+	 * If we don't substitute entities, the validation should be
+	 * done on a value with replaced entities anyway.
+	 */
+        if (!ctxt->replaceEntities) {
+	    dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
+	    if (dup == NULL) {
+	        if (*valueend == 0) {
+		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+				    ctxt->myDoc, ctxt->node, ret, value);
+		} else {
+		    /*
+		     * That should already be normalized.
+		     * cheaper to finally allocate here than duplicate
+		     * entry points in the full validation code
+		     */
+		    dup = xmlStrndup(value, valueend - value);
+
+		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+				    ctxt->myDoc, ctxt->node, ret, dup);
+		}
+	    } else {
+	        /*
+		 * dup now contains a string of the flattened attribute
+		 * content with entities substitued. Check if we need to
+		 * apply an extra layer of normalization.
+		 * It need to be done twice ... it's an extra burden related
+		 * to the ability to keep references in attributes
+		 */
+		if (ctxt->attsSpecial != NULL) {
+		    xmlChar *nvalnorm;
+		    xmlChar fn[50];
+		    xmlChar *fullname;
+		    
+		    fullname = xmlBuildQName(localname, prefix, fn, 50);
+		    if (fullname != NULL) {
+			ctxt->vctxt.valid = 1;
+		        nvalnorm = xmlValidCtxtNormalizeAttributeValue(
+			                 &ctxt->vctxt, ctxt->myDoc,
+					 ctxt->node, fullname, dup);
+			if (ctxt->vctxt.valid != 1)
+			    ctxt->valid = 0;
+
+			if ((fullname != fn) && (fullname != localname))
+			    xmlFree(fullname);
+			if (nvalnorm != NULL) {
+			    xmlFree(dup);
+			    dup = nvalnorm;
+			}
+		    }
+		}
+
+		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+			        ctxt->myDoc, ctxt->node, ret, dup);
+	    }
+	} else {
+	    /*
+	     * if entities already have been substitued, then
+	     * the attribute as passed is already normalized
+	     */
+	    dup = xmlStrndup(value, valueend - value);
+
+	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
+	                             ctxt->myDoc, ctxt->node, ret, dup);
+	}
+    } else
+#endif /* LIBXML_VALID_ENABLED */
+           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
+	       (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
+	        ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
+        /*
+	 * when validating, the ID registration is done at the attribute
+	 * validation level. Otherwise we have to do specific handling here.
+	 */
+        if ((prefix == ctxt->str_xml) &&
+	           (localname[0] == 'i') && (localname[1] == 'd') &&
+		   (localname[2] == 0)) {
+	    /*
+	     * Add the xml:id value
+	     *
+	     * Open issue: normalization of the value.
+	     */
+	    if (dup == NULL)
+	        dup = xmlStrndup(value, valueend - value);
+#ifdef LIBXML_VALID_ENABLED
+	    if (xmlValidateNCName(dup, 1) != 0) {
+	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
+		      "xml:id : attribute value %s is not an NCName\n",
+			    (const char *) dup, NULL);
+	    }
+#endif
+	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
+	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
+	    /* might be worth duplicate entry points and not copy */
+	    if (dup == NULL)
+	        dup = xmlStrndup(value, valueend - value);
+	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
+	} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
+	    if (dup == NULL)
+	        dup = xmlStrndup(value, valueend - value);
+	    xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
+	}
+    }
+    if (dup != NULL)
+	xmlFree(dup);
+}
+
+/**
+ * xmlSAX2StartElementNs:
+ * @ctx:  the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ * @nb_namespaces:  number of namespace definitions on that node
+ * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
+ * @nb_attributes:  the number of attributes on that node
+ * @nb_defaulted:  the number of defaulted attributes.
+ * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
+ *               attribute values.
+ *
+ * SAX2 callback when an element start has been detected by the parser.
+ * It provides the namespace informations for the element, as well as
+ * the new namespace declarations on the element.
+ */
+void
+xmlSAX2StartElementNs(void *ctx,
+                      const xmlChar *localname,
+		      const xmlChar *prefix,
+		      const xmlChar *URI,
+		      int nb_namespaces,
+		      const xmlChar **namespaces,
+		      int nb_attributes,
+		      int nb_defaulted,
+		      const xmlChar **attributes)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret;
+    xmlNodePtr parent;
+    xmlNsPtr last = NULL, ns;
+    const xmlChar *uri, *pref;
+    int i, j;
+
+    if (ctx == NULL) return;
+    parent = ctxt->node;
+    /*
+     * First check on validity:
+     */
+    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
+        ((ctxt->myDoc->intSubset == NULL) ||
+	 ((ctxt->myDoc->intSubset->notations == NULL) && 
+	  (ctxt->myDoc->intSubset->elements == NULL) &&
+	  (ctxt->myDoc->intSubset->attributes == NULL) && 
+	  (ctxt->myDoc->intSubset->entities == NULL)))) {
+	xmlErrValid(ctxt, XML_ERR_NO_DTD,
+	  "Validation failed: no DTD found !", NULL, NULL);
+	ctxt->validate = 0;
+    }
+
+    /*
+     * allocate the node
+     */
+    if (ctxt->freeElems != NULL) {
+        ret = ctxt->freeElems;
+	ctxt->freeElems = ret->next;
+	ctxt->freeElemsNr--;
+	memset(ret, 0, sizeof(xmlNode));
+	ret->type = XML_ELEMENT_NODE;
+
+	if (ctxt->dictNames)
+	    ret->name = localname;
+	else {
+	    ret->name = xmlStrdup(localname);
+	    if (ret->name == NULL) {
+	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+		return;
+	    }
+	}
+	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	    xmlRegisterNodeDefaultValue(ret);
+    } else {
+	if (ctxt->dictNames)
+	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 
+	                               (xmlChar *) localname, NULL);
+	else
+	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
+	if (ret == NULL) {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+	    return;
+	}
+    }
+    if (ctxt->linenumbers) {
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->line < 65535)
+		ret->line = (short) ctxt->input->line;
+	    else
+	        ret->line = 65535;
+	}
+    }
+
+    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
+        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
+    }
+    /*
+     * Build the namespace list
+     */
+    for (i = 0,j = 0;j < nb_namespaces;j++) {
+        pref = namespaces[i++];
+	uri = namespaces[i++];
+	ns = xmlNewNs(NULL, uri, pref);
+	if (ns != NULL) {
+	    if (last == NULL) {
+	        ret->nsDef = last = ns;
+	    } else {
+	        last->next = ns;
+		last = ns;
+	    }
+	    if ((URI != NULL) && (prefix == pref))
+		ret->ns = ns;
+	} else {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+	    return;
+	}
+#ifdef LIBXML_VALID_ENABLED
+	if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
+	    ctxt->myDoc && ctxt->myDoc->intSubset) {
+	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
+	                                           ret, prefix, ns, uri);
+	}
+#endif /* LIBXML_VALID_ENABLED */
+    }
+    ctxt->nodemem = -1;
+
+    /*
+     * We are parsing a new node.
+     */
+    nodePush(ctxt, ret);
+
+    /*
+     * Link the child element
+     */
+    if (parent != NULL) {
+        if (parent->type == XML_ELEMENT_NODE) {
+	    xmlAddChild(parent, ret);
+	} else {
+	    xmlAddSibling(parent, ret);
+	}
+    }
+
+    /*
+     * Insert the defaulted attributes from the DTD only if requested:
+     */
+    if ((nb_defaulted != 0) &&
+        ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
+	nb_attributes -= nb_defaulted;
+
+    /*
+     * Search the namespace if it wasn't already found
+     * Note that, if prefix is NULL, this searches for the default Ns
+     */
+    if ((URI != NULL) && (ret->ns == NULL)) {
+        ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
+	if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
+	    ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
+	}
+	if (ret->ns == NULL) {
+	    ns = xmlNewNs(ret, NULL, prefix);
+	    if (ns == NULL) {
+
+	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
+		return;
+	    }
+            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);
+	}
+    }
+
+    /*
+     * process all the other attributes
+     */
+    if (nb_attributes > 0) {
+        for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
+	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
+	                       attributes[j+3], attributes[j+4]);
+	}
+    }
+
+#ifdef LIBXML_VALID_ENABLED
+    /*
+     * If it's the Document root, finish the DTD validation and
+     * check the document root element for validity
+     */
+    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
+	int chk;
+
+	chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
+	if (chk <= 0)
+	    ctxt->valid = 0;
+	if (chk < 0)
+	    ctxt->wellFormed = 0;
+	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
+	ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
+    }
+#endif /* LIBXML_VALID_ENABLED */
+}
+
+/**
+ * xmlSAX2EndElementNs:
+ * @ctx:  the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ *
+ * SAX2 callback when an element end has been detected by the parser.
+ * It provides the namespace informations for the element.
+ */
+void
+xmlSAX2EndElementNs(void *ctx,
+                    const xmlChar * localname ATTRIBUTE_UNUSED,
+                    const xmlChar * prefix ATTRIBUTE_UNUSED,
+		    const xmlChar * URI ATTRIBUTE_UNUSED)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserNodeInfo node_info;
+    xmlNodePtr cur;
+
+    if (ctx == NULL) return;
+    cur = ctxt->node;
+    /* Capture end position and add node */
+    if ((ctxt->record_info) && (cur != NULL)) {
+        node_info.end_pos = ctxt->input->cur - ctxt->input->base;
+        node_info.end_line = ctxt->input->line;
+        node_info.node = cur;
+        xmlParserAddNodeInfo(ctxt, &node_info);
+    }
+    ctxt->nodemem = -1;
+
+#ifdef LIBXML_VALID_ENABLED
+    if (ctxt->validate && ctxt->wellFormed &&
+        ctxt->myDoc && ctxt->myDoc->intSubset)
+        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
+#endif /* LIBXML_VALID_ENABLED */
+
+    /*
+     * end of parsing of this node.
+     */
+    nodePop(ctxt);
+}
+
+/**
+ * xmlSAX2Reference:
+ * @ctx: the user data (XML parser context)
+ * @name:  The entity name
+ *
+ * called when an entity xmlSAX2Reference is detected. 
+ */
+void
+xmlSAX2Reference(void *ctx, const xmlChar *name)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret;
+
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2Reference(%s)\n", name);
+#endif
+    if (name[0] == '#')
+	ret = xmlNewCharRef(ctxt->myDoc, name);
+    else
+	ret = xmlNewReference(ctxt->myDoc, name);
+#ifdef DEBUG_SAX_TREE
+    xmlGenericError(xmlGenericErrorContext,
+	    "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
+#endif
+    if (xmlAddChild(ctxt->node, ret) == NULL) {
+        xmlFreeNode(ret);
+    }
+}
+
+/**
+ * xmlSAX2Characters:
+ * @ctx: the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ */
+void
+xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr lastChild;
+
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
+#endif
+    /*
+     * Handle the data if any. If there is no child
+     * add it as content, otherwise if the last child is text,
+     * concatenate it, else create a new node of type text.
+     */
+
+    if (ctxt->node == NULL) {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"add chars: ctxt->node == NULL !\n");
+#endif
+        return;
+    }
+    lastChild = ctxt->node->last;
+#ifdef DEBUG_SAX_TREE
+    xmlGenericError(xmlGenericErrorContext,
+	    "add chars to %s \n", ctxt->node->name);
+#endif
+
+    /*
+     * Here we needed an accelerator mechanism in case of very large
+     * elements. Use an attribute in the structure !!!
+     */
+    if (lastChild == NULL) {
+        lastChild = xmlSAX2TextNode(ctxt, ch, len);
+	if (lastChild != NULL) {
+	    ctxt->node->children = lastChild;
+	    ctxt->node->last = lastChild;
+	    lastChild->parent = ctxt->node;
+	    lastChild->doc = ctxt->node->doc;
+	    ctxt->nodelen = len;
+	    ctxt->nodemem = len + 1;
+	} else {
+	    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+	    return;
+	}
+    } else {
+	int coalesceText = (lastChild != NULL) &&
+	    (lastChild->type == XML_TEXT_NODE) &&
+	    (lastChild->name == xmlStringText);
+	if ((coalesceText) && (ctxt->nodemem != 0)) {
+	    /*
+	     * The whole point of maintaining nodelen and nodemem,
+	     * xmlTextConcat is too costly, i.e. compute length,
+	     * reallocate a new buffer, move data, append ch. Here
+	     * We try to minimaze realloc() uses and avoid copying
+	     * and recomputing length over and over.
+	     */
+	    if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
+		lastChild->content = xmlStrdup(lastChild->content);
+		lastChild->properties = NULL;
+	    } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
+	               (xmlDictOwns(ctxt->dict, lastChild->content))) {
+		lastChild->content = xmlStrdup(lastChild->content);
+	    }
+            if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
+                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+                xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
+                return;
+            }
+	    if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len || 
+	        (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
+                xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
+                return;
+	    }
+	    if (ctxt->nodelen + len >= ctxt->nodemem) {
+		xmlChar *newbuf;
+		size_t size;
+
+		size = ctxt->nodemem + len;
+		size *= 2;
+                newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
+		if (newbuf == NULL) {
+		    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+		    return;
+		}
+		ctxt->nodemem = size;
+		lastChild->content = newbuf;
+	    }
+	    memcpy(&lastChild->content[ctxt->nodelen], ch, len);
+	    ctxt->nodelen += len;
+	    lastChild->content[ctxt->nodelen] = 0;
+	} else if (coalesceText) {
+	    if (xmlTextConcat(lastChild, ch, len)) {
+		xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
+	    }
+	    if (ctxt->node->children != NULL) {
+		ctxt->nodelen = xmlStrlen(lastChild->content);
+		ctxt->nodemem = ctxt->nodelen + 1;
+	    }
+	} else {
+	    /* Mixed content, first time */
+	    lastChild = xmlSAX2TextNode(ctxt, ch, len);
+	    if (lastChild != NULL) {
+		xmlAddChild(ctxt->node, lastChild);
+		if (ctxt->node->children != NULL) {
+		    ctxt->nodelen = len;
+		    ctxt->nodemem = len + 1;
+		}
+	    }
+	}
+    }
+}
+
+/**
+ * xmlSAX2IgnorableWhitespace:
+ * @ctx: the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * UNUSED: by default the DOM building will use xmlSAX2Characters
+ */
+void
+xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
+{
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
+#endif
+}
+
+/**
+ * xmlSAX2ProcessingInstruction:
+ * @ctx: the user data (XML parser context)
+ * @target:  the target name
+ * @data: the PI data's
+ *
+ * A processing instruction has been parsed.
+ */
+void
+xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
+                      const xmlChar *data)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret;
+    xmlNodePtr parent;
+
+    if (ctx == NULL) return;
+    parent = ctxt->node;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
+#endif
+
+    ret = xmlNewDocPI(ctxt->myDoc, target, data);
+    if (ret == NULL) return;
+
+    if (ctxt->linenumbers) {
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->line < 65535)
+		ret->line = (short) ctxt->input->line;
+	    else
+	        ret->line = 65535;
+	}
+    }
+    if (ctxt->inSubset == 1) {
+	xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
+	return;
+    } else if (ctxt->inSubset == 2) {
+	xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
+	return;
+    }
+    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
+#ifdef DEBUG_SAX_TREE
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Setting PI %s as root\n", target);
+#endif
+        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
+	return;
+    }
+    if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"adding PI %s child to %s\n", target, parent->name);
+#endif
+	xmlAddChild(parent, ret);
+    } else {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"adding PI %s sibling to ", target);
+	xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+	xmlAddSibling(parent, ret);
+    }
+}
+
+/**
+ * xmlSAX2Comment:
+ * @ctx: the user data (XML parser context)
+ * @value:  the xmlSAX2Comment content
+ *
+ * A xmlSAX2Comment has been parsed.
+ */
+void
+xmlSAX2Comment(void *ctx, const xmlChar *value)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret;
+    xmlNodePtr parent;
+
+    if (ctx == NULL) return;
+    parent = ctxt->node;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
+#endif
+    ret = xmlNewDocComment(ctxt->myDoc, value);
+    if (ret == NULL) return;
+    if (ctxt->linenumbers) {
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->line < 65535)
+		ret->line = (short) ctxt->input->line;
+	    else
+	        ret->line = 65535;
+	}
+    }
+
+    if (ctxt->inSubset == 1) {
+	xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
+	return;
+    } else if (ctxt->inSubset == 2) {
+	xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
+	return;
+    }
+    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
+#ifdef DEBUG_SAX_TREE
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Setting xmlSAX2Comment as root\n");
+#endif
+        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
+	return;
+    }
+    if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"adding xmlSAX2Comment child to %s\n", parent->name);
+#endif
+	xmlAddChild(parent, ret);
+    } else {
+#ifdef DEBUG_SAX_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"adding xmlSAX2Comment sibling to ");
+	xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+	xmlAddSibling(parent, ret);
+    }
+}
+
+/**
+ * xmlSAX2CDataBlock:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+void
+xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlNodePtr ret, lastChild;
+
+    if (ctx == NULL) return;
+#ifdef DEBUG_SAX
+    xmlGenericError(xmlGenericErrorContext,
+	    "SAX.pcdata(%.10s, %d)\n", value, len);
+#endif
+    lastChild = xmlGetLastChild(ctxt->node);
+#ifdef DEBUG_SAX_TREE
+    xmlGenericError(xmlGenericErrorContext,
+	    "add chars to %s \n", ctxt->node->name);
+#endif
+    if ((lastChild != NULL) &&
+        (lastChild->type == XML_CDATA_SECTION_NODE)) {
+	xmlTextConcat(lastChild, value, len);
+    } else {
+	ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
+	xmlAddChild(ctxt->node, ret);
+    }
+}
+
+static int xmlSAX2DefaultVersionValue = 2;
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlSAXDefaultVersion:
+ * @version:  the version, 1 or 2
+ *
+ * Set the default version of SAX used globally by the library.
+ * By default, during initialization the default is set to 2.
+ * Note that it is generally a better coding style to use
+ * xmlSAXVersion() to set up the version explicitly for a given
+ * parsing context.
+ *
+ * Returns the previous value in case of success and -1 in case of error.
+ */
+int
+xmlSAXDefaultVersion(int version)
+{
+    int ret = xmlSAX2DefaultVersionValue;
+
+    if ((version != 1) && (version != 2))
+        return(-1);
+    xmlSAX2DefaultVersionValue = version;
+    return(ret);
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/**
+ * xmlSAXVersion:
+ * @hdlr:  the SAX handler
+ * @version:  the version, 1 or 2
+ *
+ * Initialize the default XML SAX handler according to the version
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xmlSAXVersion(xmlSAXHandler *hdlr, int version)
+{
+    if (hdlr == NULL) return(-1);
+    if (version == 2) {
+	hdlr->startElement = NULL;
+	hdlr->endElement = NULL;
+	hdlr->startElementNs = xmlSAX2StartElementNs;
+	hdlr->endElementNs = xmlSAX2EndElementNs;
+	hdlr->serror = NULL;
+	hdlr->initialized = XML_SAX2_MAGIC;
+#ifdef LIBXML_SAX1_ENABLED
+    } else if (version == 1) {
+	hdlr->startElement = xmlSAX2StartElement;
+	hdlr->endElement = xmlSAX2EndElement;
+	hdlr->initialized = 1;
+#endif /* LIBXML_SAX1_ENABLED */
+    } else
+        return(-1);
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = xmlSAX2ExternalSubset;
+    hdlr->isStandalone = xmlSAX2IsStandalone;
+    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
+    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
+    hdlr->resolveEntity = xmlSAX2ResolveEntity;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
+    hdlr->entityDecl = xmlSAX2EntityDecl;
+    hdlr->attributeDecl = xmlSAX2AttributeDecl;
+    hdlr->elementDecl = xmlSAX2ElementDecl;
+    hdlr->notationDecl = xmlSAX2NotationDecl;
+    hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->reference = xmlSAX2Reference;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = xmlSAX2CDataBlock;
+    hdlr->ignorableWhitespace = xmlSAX2Characters;
+    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
+    hdlr->comment = xmlSAX2Comment;
+    hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    return(0);
+}
+
+/**
+ * xmlSAX2InitDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ * @warning:  flag if non-zero sets the handler warning procedure
+ *
+ * Initialize the default XML SAX2 handler
+ */
+void
+xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
+{
+    if ((hdlr == NULL) || (hdlr->initialized != 0))
+	return;
+
+    xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
+    if (warning == 0)
+	hdlr->warning = NULL;
+    else
+	hdlr->warning = xmlParserWarning;
+}
+
+/**
+ * xmlDefaultSAXHandlerInit:
+ *
+ * Initialize the default SAX2 handler
+ */
+void
+xmlDefaultSAXHandlerInit(void)
+{
+#ifdef LIBXML_SAX1_ENABLED
+    xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
+#endif /* LIBXML_SAX1_ENABLED */
+}
+
+#ifdef LIBXML_HTML_ENABLED
+
+/**
+ * xmlSAX2InitHtmlDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ *
+ * Initialize the default HTML SAX2 handler
+ */
+void
+xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
+{
+    if ((hdlr == NULL) || (hdlr->initialized != 0))
+	return;
+
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = NULL;
+    hdlr->isStandalone = NULL;
+    hdlr->hasInternalSubset = NULL;
+    hdlr->hasExternalSubset = NULL;
+    hdlr->resolveEntity = NULL;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = NULL;
+    hdlr->entityDecl = NULL;
+    hdlr->attributeDecl = NULL;
+    hdlr->elementDecl = NULL;
+    hdlr->notationDecl = NULL;
+    hdlr->unparsedEntityDecl = NULL;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+    hdlr->reference = NULL;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = xmlSAX2CDataBlock;
+    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
+    hdlr->comment = xmlSAX2Comment;
+    hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    hdlr->initialized = 1;
+}
+
+/**
+ * htmlDefaultSAXHandlerInit:
+ *
+ * Initialize the default SAX handler
+ */
+void
+htmlDefaultSAXHandlerInit(void)
+{
+    xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
+}
+
+#endif /* LIBXML_HTML_ENABLED */
+
+#ifdef LIBXML_DOCB_ENABLED
+
+/**
+ * xmlSAX2InitDocbDefaultSAXHandler:
+ * @hdlr:  the SAX handler
+ *
+ * Initialize the default DocBook SAX2 handler
+ */
+void
+xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
+{
+    if ((hdlr == NULL) || (hdlr->initialized != 0))
+	return;
+
+    hdlr->internalSubset = xmlSAX2InternalSubset;
+    hdlr->externalSubset = NULL;
+    hdlr->isStandalone = xmlSAX2IsStandalone;
+    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
+    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
+    hdlr->resolveEntity = xmlSAX2ResolveEntity;
+    hdlr->getEntity = xmlSAX2GetEntity;
+    hdlr->getParameterEntity = NULL;
+    hdlr->entityDecl = xmlSAX2EntityDecl;
+    hdlr->attributeDecl = NULL;
+    hdlr->elementDecl = NULL;
+    hdlr->notationDecl = NULL;
+    hdlr->unparsedEntityDecl = NULL;
+    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
+    hdlr->startDocument = xmlSAX2StartDocument;
+    hdlr->endDocument = xmlSAX2EndDocument;
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+    hdlr->reference = xmlSAX2Reference;
+    hdlr->characters = xmlSAX2Characters;
+    hdlr->cdataBlock = NULL;
+    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+    hdlr->processingInstruction = NULL;
+    hdlr->comment = xmlSAX2Comment;
+    hdlr->warning = xmlParserWarning;
+    hdlr->error = xmlParserError;
+    hdlr->fatalError = xmlParserError;
+
+    hdlr->initialized = 1;
+}
+
+/**
+ * docbDefaultSAXHandlerInit:
+ *
+ * Initialize the default SAX handler
+ */
+void
+docbDefaultSAXHandlerInit(void)
+{
+    xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
+}
+
+#endif /* LIBXML_DOCB_ENABLED */
+#define bottom_SAX2
+#include "elfgcchack.h"
diff --git a/src/TODO b/src/TODO
new file mode 100644
index 0000000..9c32224
--- /dev/null
+++ b/src/TODO
@@ -0,0 +1,278 @@
+124907 HTML parse buffer problem when parsing larse in-memory docs
+124110 DTD validation && wrong namespace
+123564 xmllint --html --format
+
+           TODO for the XML parser and stuff:
+	   ==================================
+
+      $Id$
+
+    this tend to be outdated :-\ ...
+
+DOCS:
+=====
+
+- use case of using XInclude to load for example a description.
+  order document + product base -(XSLT)-> quote with XIncludes 
+                                                   |
+  HTML output with description of parts <---(XSLT)--
+
+TODO:
+=====
+- XInclude at the SAX level (libSRVG)
+- fix the C code prototype to bring back doc/libxml-undocumented.txt
+  to a reasonable level
+- Computation of base when HTTP redirect occurs, might affect HTTP
+  interfaces.
+- Computation of base in XInclude. Relativization of URIs.
+- listing all attributes in a node.
+- Better checking of external parsed entities TAG 1234
+- Go through erratas and do the cleanup.
+  http://www.w3.org/XML/xml-19980210-errata ... started ...
+- 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
+  + inversted SAX, initial patch in April 2002 archives.
+- htmlParseDoc has parameter encoding which is not used.
+  Function htmlCreateDocParserCtxt ignore it.
+- fix realloc() usage.
+- Stricten the UTF8 conformance (Martin Duerst):
+  http://www.w3.org/2001/06/utf-8-test/.
+  The bad files are in http://www.w3.org/2001/06/utf-8-wrong/.
+- xml:id normalized value
+
+TODO:
+=====
+
+- move all string manipulation functions (xmlStrdup, xmlStrlen, etc.) to
+  global.c. Bjorn noted that the following files depends on parser.o solely
+  because of these string functions: entities.o, global.o, hash.o, tree.o,
+  xmlIO.o, and xpath.o.
+
+- Optimization of tag strings allocation ?
+
+- maintain coherency of namespace when doing cut'n paste operations
+  => the functions are coded, but need testing
+
+- function to rebuild the ID table
+- functions to rebuild the DTD hash tables (after DTD changes).
+   
+
+EXTENSIONS:
+===========
+
+- Tools to produce man pages from the SGML docs.
+
+- Add Xpointer recognition/API
+
+- Add Xlink recognition/API
+  => started adding an xlink.[ch] with a unified API for XML and HTML.
+     it's crap :-(
+
+- Implement XSchemas
+  => Really need to be done <grin/>
+  - datatype are complete, but structure support is very limited.
+
+- extend the shell with:
+   - edit
+   - load/save
+   - mv (yum, yum, but it's harder because directories are ordered in
+     our case, mvup and mvdown would be required)
+
+
+Done:
+=====
+
+- Add HTML validation using the XHTML DTD
+  - problem: do we want to keep and maintain the code for handling
+    DTD/System ID cache directly in libxml ?
+  => not really done that way, but there are new APIs to check elements
+     or attributes. Otherwise XHTML validation directly ...
+
+- XML Schemas datatypes except Base64 and BinHex
+
+- Relax NG validation
+
+- XmlTextReader streaming API + validation
+
+- Add a DTD cache prefilled with xhtml DTDs and entities and a program to
+  manage them -> like the /usr/bin/install-catalog from SGML
+  right place seems $datadir/xmldtds
+  Maybe this is better left to user apps
+  => use a catalog instead , and xhtml1-dtd package
+
+- Add output to XHTML
+  => XML serializer automatically recognize the DTd and apply the specific
+     rules.
+
+- Fix output of <tst val="x&#xA;y"/>
+
+- compliance to XML-Namespace checking, see section 6 of
+  http://www.w3.org/TR/REC-xml-names/
+
+- Correct standalone checking/emitting (hard)
+  2.9 Standalone Document Declaration
+
+- Implement OASIS XML Catalog support
+  http://www.oasis-open.org/committees/entity/
+
+- Get OASIS testsuite to a more friendly result, check all the results
+  once stable. the check-xml-test-suite.py script does this
+
+- Implement XSLT
+  => libxslt
+
+- Finish XPath
+  => attributes addressing troubles
+  => defaulted attributes handling
+  => namespace axis ?
+  done as XSLT got debugged
+
+- bug reported by Michael Meallin on validation problems
+  => Actually means I need to add support (and warn) for non-deterministic
+     content model.
+- Handle undefined namespaces in entity contents better ... at least
+  issue a warning
+- DOM needs
+  int xmlPruneProp(xmlNodePtr node, xmlAtttrPtr attr);
+  => done it's actually xmlRemoveProp xmlUnsetProp xmlUnsetNsProp
+
+- HTML: handling of Script and style data elements, need special code in
+  the parser and saving functions (handling of < > " ' ...):
+  http://www.w3.org/TR/html4/types.html#type-script
+  Attributes are no problems since entities are accepted.
+- DOM needs
+  xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value)
+- problem when parsing hrefs with & with the HTML parser (IRC ac)
+- If the internal encoding is not UTF8 saving to a given encoding doesn't
+  work => fix to force UTF8 encoding ...
+  done, added documentation too
+- Add an ASCII I/O encoder (asciiToUTF8 and UTF8Toascii)
+- Issue warning when using non-absolute namespaces URI.
+- the html parser should add <head> and <body> if they don't exist
+  started, not finished.
+  Done, the automatic closing is added and 3 testcases were inserted
+- Command to force the parser to stop parsing and ignore the rest of the file.
+  xmlStopParser() should allow this, mostly untested
+- support for HTML empty attributes like <hr noshade>
+- plugged iconv() in for support of a large set of encodings.
+- xmlSwitchToEncoding() rewrite done
+- URI checkings (no fragments) rfc2396.txt
+- Added a clean mechanism for overload or added input methods:
+  xmlRegisterInputCallbacks()
+- dynamically adapt the alloc entry point to use g_alloc()/g_free()
+  if the programmer wants it: 
+    - use xmlMemSetup() to reset the routines used.
+- Check attribute normalization especially xmlGetProp()
+- Validity checking problems for NOTATIONS attributes
+- Validity checking problems for ENTITY ENTITIES attributes
+- Parsing of a well balanced chunk xmlParseBalancedChunkMemory()
+- URI module: validation, base, etc ... see uri.[ch]
+- turn tester into a generic program xmllint installed with libxml
+- extend validity checks to go through entities content instead of
+  just labelling them PCDATA
+- Save Dtds using the children list instead of dumping the tables,
+  order is preserved as well as comments and PIs
+- Wrote a notice of changes requires to go from 1.x to 2.x
+- make sure that all SAX callbacks are disabled if a WF error is detected
+- checking/handling of newline normalization
+  http://localhost/www.xml.com/axml/target.html#sec-line-ends
+- correct checking of '&' '%' on entities content.
+- checking of PE/Nesting on entities declaration
+- checking/handling of xml:space
+   - checking done.
+   - handling done, not well tested
+- Language identification code, productions [33] to [38]
+  => done, the check has been added and report WFness errors
+- Conditional sections in DTDs [61] to [65]
+  => should this crap be really implemented ???
+  => Yep OASIS testsuite uses them
+- Allow parsed entities defined in the internal subset to override
+  the ones defined in the external subset (DtD customization).
+  => This mean that the entity content should be computed only at
+     use time, i.e. keep the orig string only at parse time and expand
+     only when referenced from the external subset :-(
+     Needed for complete use of most DTD from Eve Maler
+- Add regression tests for all WFC errors
+  => did some in test/WFC
+  => added OASIS testsuite routines
+     http://xmlsoft.org/conf/result.html
+
+- I18N: http://wap.trondheim.com/vaer/index.phtml is not XML and accepted
+  by the XML parser, UTF-8 should be checked when there is no "encoding"
+  declared !
+- Support for UTF-8 and UTF-16 encoding
+  => added some convertion routines provided by Martin Durst
+     patched them, got fixes from @@@
+     I plan to keep everything internally as UTF-8 (or ISO-Latin-X)
+     this is slightly more costly but more compact, and recent processors
+     efficiency is cache related. The key for good performances is keeping
+     the data set small, so will I.
+  => the new progressive reading routines call the detection code
+     is enabled, tested the ISO->UTF-8 stuff
+- External entities loading: 
+   - allow override by client code
+   - make sure it is alled for all external entities referenced
+  Done, client code should use xmlSetExternalEntityLoader() to set
+  the default loading routine. It will be called each time an external
+  entity entity resolution is triggered.
+- maintain ID coherency when removing/changing attributes
+  The function used to deallocate attributes now check for it being an
+  ID and removes it from the table.
+- push mode parsing i.e. non-blocking state based parser
+  done, both for XML and HTML parsers. Use xmlCreatePushParserCtxt()
+  and xmlParseChunk() and html counterparts.
+  The tester program now has a --push option to select that parser 
+  front-end. Douplicated tests to use both and check results are similar.
+
+- Most of XPath, still see some troubles and occasionnal memleaks.
+- an XML shell, allowing to traverse/manipulate an XML document with
+  a shell like interface, and using XPath for the anming syntax
+  - use of readline and history added when available
+  - the shell interface has been cleanly separated and moved to debugXML.c
+- HTML parser, should be fairly stable now
+- API to search the lang of an attribute
+- Collect IDs at parsing and maintain a table. 
+   PBM: maintain the table coherency
+   PBM: how to detect ID types in absence of DtD !
+- Use it for XPath ID support
+- Add validity checking
+  Should be finished now !
+- Add regression tests with entity substitutions
+
+- External Parsed entities, either XML or external Subset [78] and [79]
+  parsing the xmllang DtD now works, so it should be sufficient for
+  most cases !
+
+- progressive reading. The entity support is a first step toward
+  asbtraction of an input stream. A large part of the context is still
+  located on the stack, moving to a state machine and putting everyting
+  in the parsing context should provide an adequate solution.
+  => Rather than progressive parsing, give more power to the SAX-like
+     interface. Currently the DOM-like representation is built but
+     => it should be possible to define that only as a set of SAX callbacks
+	and remove the tree creation from the parser code.
+	DONE
+
+- DOM support, instead of using a proprietary in memory
+  format for the document representation, the parser should
+  call a DOM API to actually build the resulting document.
+  Then the parser becomes independent of the in-memory
+  representation of the document. Even better using RPC's
+  the parser can actually build the document in another
+  program.
+  => Work started, now the internal representation is by default
+     very near a direct DOM implementation. The DOM glue is implemented
+     as a separate module. See the GNOME gdome module.
+
+- C++ support : John Ehresman <jehresma@dsg.harvard.edu>
+- Updated code to follow more recent specs, added compatibility flag
+- Better error handling, use a dedicated, overridable error
+  handling function.
+- Support for CDATA.
+- Keep track of line numbers for better error reporting.
+- Support for PI (SAX one).
+- Support for Comments (bad, should be in ASAP, they are parsed
+  but not stored), should be configurable.
+- Improve the support of entities on save (+SAX).
+
diff --git a/src/TODO_SCHEMAS b/src/TODO_SCHEMAS
new file mode 100644
index 0000000..145a4ed
--- /dev/null
+++ b/src/TODO_SCHEMAS
@@ -0,0 +1,31 @@
+- implement counted transitions at the automata level
+
+- Unicode:
+  + upgrade to 3.2
+  + improve the python script to generate better test
+    expressions to check the list of ranges.
+
+- Implement the interface at the SAX level
+
+- Implement the missing parts in the Structure part
+   + all content model
+   + enumerations
+   + countless others c.f. the TODO scattered in the code
+
+- Complete the Built-In datatype collections and Facets implementations
+
+- Regression tests based on
+  + the primer:
+    http://www.w3.org/TR/xmlschema-0/
+  + the Schemas Test Collection:
+    http://www.w3.org/2001/05/xmlschema-test-collection/
+  + archives of the schemas-dev list
+
+- Integrity constraints:
+  + what's that ? How need to read about it
+
+- "formal" checking, i.e. go through the full Structure spec and
+  bind code and associated parts of the Schemas spec
+
+- go though the erratas
+  http://www.w3.org/2001/05/xmlschema-errata
diff --git a/src/acconfig.h b/src/acconfig.h
new file mode 100644
index 0000000..dedcf1d
--- /dev/null
+++ b/src/acconfig.h
@@ -0,0 +1,16 @@
+#undef PACKAGE
+#undef VERSION
+#undef HAVE_LIBZ
+#undef HAVE_LIBM
+#undef HAVE_ISINF
+#undef 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
diff --git a/src/acinclude.m4 b/src/acinclude.m4
new file mode 100644
index 0000000..4ff672e
--- /dev/null
+++ b/src/acinclude.m4
@@ -0,0 +1,28 @@
+dnl Like AC_TRY_EVAL but also errors out if the compiler generates
+dnl _any_ output. Some compilers might issue warnings which we want
+dnl to catch.
+AC_DEFUN([AC_TRY_EVAL2],
+[{ (eval echo configure:__oline__: \"[$]$1\") 1>&AC_FD_CC; dnl
+(eval [$]$1) 2>&AC_FD_CC; _out=`eval [$]$1 2>&1` && test "x$_out" = x; }])
+
+dnl Like AC_TRY_COMPILE but calls AC_TRY_EVAL2 instead of AC_TRY_EVAL
+AC_DEFUN([AC_TRY_COMPILE2],
+[cat > conftest.$ac_ext <<EOF
+[#]line __oline__ "configure"
+#include "confdefs.h"
+[$1]
+int main(void) {
+[$2]
+; return 0; }
+EOF
+if AC_TRY_EVAL2(ac_compile); then
+  ifelse([$3], , :, [rm -rf conftest*
+  $3])
+else
+  echo "configure: failed program was:" >&AC_FD_CC
+  cat conftest.$ac_ext >&AC_FD_CC
+ifelse([$4], , , [  rm -rf conftest*
+  $4
+])dnl
+fi
+rm -f conftest*])
diff --git a/src/aclocal.m4 b/src/aclocal.m4
new file mode 100644
index 0000000..8b587f1
--- /dev/null
+++ b/src/aclocal.m4
@@ -0,0 +1,8956 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
+[m4_warning([this file was generated for autoconf 2.65.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+  ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+  lt_cl_success=:
+  test "$silent" = yes &&
+    lt_config_lt_args="$lt_config_lt_args --quiet"
+  exec AS_MESSAGE_LOG_FD>/dev/null
+  $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+  exec AS_MESSAGE_LOG_FD>>config.log
+  $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_XSI_SHELLFNS
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+[$]*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "[$]0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+    [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+       LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+       [shlibpath_overrides_runpath=yes])])
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC*)
+	    # IBM XL 8.0 on PPC
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  linux* | k*bsd*-gnu)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+  ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        AC_LINK_IFELSE(int foo(void) {},
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+        )
+        LDFLAGS="$save_LDFLAGS"
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+        _LT_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+    [[If ld is used when linking, flag to hardcode $libdir into a binary
+    during linking.  This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+    [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+        # as there is no search path for DLLs.
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+        _LT_TAGVAR(always_export_symbols, $1)=no
+        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    cp $export_symbols $output_objdir/$soname.def;
+          else
+	    echo EXPORTS > $output_objdir/$soname.def;
+	    cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          _LT_TAGVAR(ld_shlibs, $1)=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[[12]]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 will use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  xl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='echo'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=echo
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='echo'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${F77-"f77"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${FC-"f95"}
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]+=\$[2]"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+    ;;
+  esac
+])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
+
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
+
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3017 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6b])
+m4_define([LT_PACKAGE_REVISION], [1.3017])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6b'
+macro_revision='1.3017'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC],		[AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+AC_DEFUN([AM_C_PROTOTYPES],
+[AC_REQUIRE([AC_C_PROTOTYPES])
+if test "$ac_cv_prog_cc_stdc" != no; then
+  U= ANSI2KNR=
+else
+  U=_ ANSI2KNR=./ansi2knr
+fi
+# Ensure some checks needed by ansi2knr itself.
+AC_REQUIRE([AC_HEADER_STDC])
+AC_CHECK_HEADERS([string.h])
+AC_SUBST([U])dnl
+AC_SUBST([ANSI2KNR])dnl
+_AM_SUBST_NOTMAKE([ANSI2KNR])dnl
+])
+
+AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/src/c14n.c b/src/c14n.c
new file mode 100644
index 0000000..9c3cad2
--- /dev/null
+++ b/src/c14n.c
@@ -0,0 +1,2235 @@
+/*
+ * "Canonical XML" implementation 
+ * http://www.w3.org/TR/xml-c14n
+ * 
+ * "Exclusive XML Canonicalization" implementation
+ * http://www.w3.org/TR/xml-exc-c14n
+ *
+ * See Copyright for the status of this software.
+ * 
+ * Author: Aleksey Sanin <aleksey@aleksey.com>
+ */
+#define IN_LIBXML
+#include "libxml.h"
+#ifdef LIBXML_C14N_ENABLED
+#ifdef LIBXML_OUTPUT_ENABLED
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/uri.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/c14n.h>
+
+/************************************************************************
+ *									*
+ *		Some declaration better left private ATM		*
+ *									*
+ ************************************************************************/
+
+typedef enum {
+    XMLC14N_BEFORE_DOCUMENT_ELEMENT = 0,
+    XMLC14N_INSIDE_DOCUMENT_ELEMENT = 1,
+    XMLC14N_AFTER_DOCUMENT_ELEMENT = 2
+} xmlC14NPosition;
+
+typedef struct _xmlC14NVisibleNsStack {
+    int nsCurEnd;           /* number of nodes in the set */
+    int nsPrevStart;        /* the begginning of the stack for previous visible node */
+    int nsPrevEnd;          /* the end of the stack for previous visible node */
+    int nsMax;              /* size of the array as allocated */
+    xmlNsPtr 	*nsTab;	    /* array of ns in no particular order */	      
+    xmlNodePtr	*nodeTab;   /* array of nodes in no particular order */
+} xmlC14NVisibleNsStack, *xmlC14NVisibleNsStackPtr;
+
+typedef struct _xmlC14NCtx {
+    /* input parameters */
+    xmlDocPtr doc;
+    xmlC14NIsVisibleCallback is_visible_callback;
+    void* user_data;    
+    int with_comments;
+    xmlOutputBufferPtr buf;
+
+    /* position in the XML document */
+    xmlC14NPosition pos;
+    int parent_is_doc;
+    xmlC14NVisibleNsStackPtr ns_rendered;
+    
+    /* C14N mode */
+    xmlC14NMode mode;
+
+    /* exclusive canonicalization */
+    xmlChar **inclusive_ns_prefixes;
+
+    /* error number */
+    int error;
+} xmlC14NCtx, *xmlC14NCtxPtr;
+
+static xmlC14NVisibleNsStackPtr	xmlC14NVisibleNsStackCreate	(void);
+static void     xmlC14NVisibleNsStackDestroy	(xmlC14NVisibleNsStackPtr cur);
+static void     xmlC14NVisibleNsStackAdd	    (xmlC14NVisibleNsStackPtr cur, 
+                                                 xmlNsPtr ns,
+                                                 xmlNodePtr node);
+static void 			xmlC14NVisibleNsStackSave	(xmlC14NVisibleNsStackPtr cur,
+								 xmlC14NVisibleNsStackPtr state);
+static void 			xmlC14NVisibleNsStackRestore	(xmlC14NVisibleNsStackPtr cur,
+								 xmlC14NVisibleNsStackPtr state);
+static void 			xmlC14NVisibleNsStackShift	(xmlC14NVisibleNsStackPtr cur);
+static int			xmlC14NVisibleNsStackFind	(xmlC14NVisibleNsStackPtr cur, 
+								 xmlNsPtr ns);
+static int			xmlExcC14NVisibleNsStackFind	(xmlC14NVisibleNsStackPtr cur, 
+								 xmlNsPtr ns,
+								 xmlC14NCtxPtr ctx);
+
+static int			xmlC14NIsNodeInNodeset		(xmlNodeSetPtr nodes,
+								 xmlNodePtr node,
+								 xmlNodePtr parent);
+
+
+
+static int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur);
+static int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur);
+typedef enum {
+    XMLC14N_NORMALIZE_ATTR = 0,
+    XMLC14N_NORMALIZE_COMMENT = 1,
+    XMLC14N_NORMALIZE_PI = 2,
+    XMLC14N_NORMALIZE_TEXT = 3
+} xmlC14NNormalizationMode;
+
+static xmlChar *xmlC11NNormalizeString(const xmlChar * input,
+                                       xmlC14NNormalizationMode mode);
+
+#define 	xmlC11NNormalizeAttr( a ) \
+    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_ATTR)
+#define 	xmlC11NNormalizeComment( a ) \
+    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_COMMENT)
+#define 	xmlC11NNormalizePI( a )	\
+    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_PI)
+#define 	xmlC11NNormalizeText( a ) \
+    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_TEXT)
+
+#define 	xmlC14NIsVisible( ctx, node, parent ) \
+     (((ctx)->is_visible_callback != NULL) ? \
+	(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				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlC14NErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of memory error
+ */
+static void
+xmlC14NErrMemory(const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlC14NErrParam:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of param error
+ */
+static void
+xmlC14NErrParam(const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Invalid parameter : %s\n", extra);
+}
+
+/**
+ * xmlC14NErrInternal:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of internal error
+ */
+static void
+xmlC14NErrInternal(const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Internal error : %s\n", extra);
+}
+
+/**
+ * xmlC14NErrInvalidNode:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of invalid node error
+ */
+static void
+xmlC14NErrInvalidNode(const char *node_type, const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_C14N_INVALID_NODE, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Node %s is invalid here : %s\n", node_type, extra);
+}
+
+/**
+ * xmlC14NErrUnknownNode:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of unknown node error
+ */
+static void
+xmlC14NErrUnknownNode(int node_type, const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_C14N_UNKNOW_NODE, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Unknown node type %d found : %s\n", node_type, extra);
+}
+
+/**
+ * xmlC14NErrRelativeNamespace:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of relative namespace error
+ */
+static void
+xmlC14NErrRelativeNamespace(const char *ns_uri)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
+		    XML_C14N_RELATIVE_NAMESPACE, XML_ERR_ERROR, NULL, 0, NULL,
+		    NULL, NULL, 0, 0,
+		    "Relative namespace UR is invalid here : %s\n", ns_uri);
+}
+
+
+
+/**
+ * xmlC14NErr:
+ * @ctxt:  a C14N evaluation context
+ * @node:  the context node
+ * @error:  the erorr code
+ * @msg:  the message
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlC14NErr(xmlC14NCtxPtr ctxt, xmlNodePtr node, int error,
+           const char * msg)
+{
+    if (ctxt != NULL)
+        ctxt->error = error;
+    __xmlRaiseError(NULL, NULL, NULL,
+		    ctxt, node, XML_FROM_C14N, error,
+		    XML_ERR_ERROR, NULL, 0,
+		    NULL, NULL, NULL, 0, 0, "%s", msg);
+}
+
+/************************************************************************
+ *									*
+ *		The implementation internals				*
+ *									*
+ ************************************************************************/
+#define XML_NAMESPACES_DEFAULT		16
+
+static int			
+xmlC14NIsNodeInNodeset(xmlNodeSetPtr nodes, xmlNodePtr node, xmlNodePtr parent) {
+    if((nodes != NULL) && (node != NULL)) {
+	if(node->type != XML_NAMESPACE_DECL) {
+	    return(xmlXPathNodeSetContains(nodes, node));
+	} else {
+	    xmlNs ns;
+	    
+	    memcpy(&ns, node, sizeof(ns)); 
+	    
+	    /* this is a libxml hack! check xpath.c for details */
+	    if((parent != NULL) && (parent->type == XML_ATTRIBUTE_NODE)) {
+		ns.next = (xmlNsPtr)parent->parent;
+	    } else {
+		ns.next = (xmlNsPtr)parent; 
+	    }
+
+	    /* 
+	     * If the input is an XPath node-set, then the node-set must explicitly 
+	     * contain every node to be rendered to the canonical form.
+	     */
+	    return(xmlXPathNodeSetContains(nodes, (xmlNodePtr)&ns));
+	}
+    }
+    return(1);
+}
+
+static xmlC14NVisibleNsStackPtr
+xmlC14NVisibleNsStackCreate(void) {
+    xmlC14NVisibleNsStackPtr ret;
+
+    ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
+    if (ret == NULL) {
+        xmlC14NErrMemory("creating namespaces stack");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlC14NVisibleNsStack));
+    return(ret);
+}
+
+static void
+xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
+    if(cur == NULL) {
+        xmlC14NErrParam("destroying namespaces stack");
+        return;
+    }
+    if(cur->nsTab != NULL) {
+	memset(cur->nsTab, 0, cur->nsMax * sizeof(xmlNsPtr));
+	xmlFree(cur->nsTab);
+    }
+    if(cur->nodeTab != NULL) {
+	memset(cur->nodeTab, 0, cur->nsMax * sizeof(xmlNodePtr));
+	xmlFree(cur->nodeTab);
+    }
+    memset(cur, 0, sizeof(xmlC14NVisibleNsStack));
+    xmlFree(cur);
+    
+}
+
+static void 
+xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr node) {
+    if((cur == NULL) || 
+       ((cur->nsTab == NULL) && (cur->nodeTab != NULL)) ||
+       ((cur->nsTab != NULL) && (cur->nodeTab == NULL))) {
+        xmlC14NErrParam("adding namespace to stack");
+	return;
+    }
+
+    if ((cur->nsTab == NULL) && (cur->nodeTab == NULL)) {
+        cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
+        cur->nodeTab = (xmlNodePtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
+	if ((cur->nsTab == NULL) || (cur->nodeTab == NULL)) {
+	    xmlC14NErrMemory("adding node to stack");
+	    return;
+	}
+	memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
+	memset(cur->nodeTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
+        cur->nsMax = XML_NAMESPACES_DEFAULT;
+    } else if(cur->nsMax == cur->nsCurEnd) {
+	void *tmp;	
+	int tmpSize;
+	
+	tmpSize = 2 * cur->nsMax;
+	tmp = xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
+	if (tmp == NULL) {
+	    xmlC14NErrMemory("adding node to stack");
+	    return;
+	}
+	cur->nsTab = (xmlNsPtr*)tmp;
+
+	tmp = xmlRealloc(cur->nodeTab, tmpSize * sizeof(xmlNodePtr));
+	if (tmp == NULL) {
+	    xmlC14NErrMemory("adding node to stack");
+	    return;
+	}
+	cur->nodeTab = (xmlNodePtr*)tmp;
+
+	cur->nsMax = tmpSize;
+    }
+    cur->nsTab[cur->nsCurEnd] = ns;
+    cur->nodeTab[cur->nsCurEnd] = node;
+
+    ++cur->nsCurEnd;
+}
+
+static void
+xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
+    if((cur == NULL) || (state == NULL)) {
+        xmlC14NErrParam("saving namespaces stack");
+	return;
+    }
+    
+    state->nsCurEnd = cur->nsCurEnd;
+    state->nsPrevStart = cur->nsPrevStart;
+    state->nsPrevEnd = cur->nsPrevEnd;
+}
+
+static void
+xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
+    if((cur == NULL) || (state == NULL)) {
+        xmlC14NErrParam("restoring namespaces stack");
+	return;
+    }
+    cur->nsCurEnd = state->nsCurEnd;
+    cur->nsPrevStart = state->nsPrevStart;
+    cur->nsPrevEnd = state->nsPrevEnd;
+}
+
+static void 
+xmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
+    if(cur == NULL) {
+        xmlC14NErrParam("shifting namespaces stack");
+	return;
+    }
+    cur->nsPrevStart = cur->nsPrevEnd;
+    cur->nsPrevEnd = cur->nsCurEnd;
+}
+
+static int
+xmlC14NStrEqual(const xmlChar *str1, const xmlChar *str2) {
+    if (str1 == str2) return(1);
+    if (str1 == NULL) return((*str2) == '\0');
+    if (str2 == NULL) return((*str1) == '\0');
+    do {
+	if (*str1++ != *str2) return(0);
+    } while (*str2++);
+    return(1);
+}
+
+/**
+ * xmlC14NVisibleNsStackFind:
+ * @ctx:		the C14N context 
+ * @ns:			the namespace to check
+ *
+ * Checks whether the given namespace was already rendered or not
+ *
+ * Returns 1 if we already wrote this namespace or 0 otherwise
+ */
+static int
+xmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns)
+{
+    int i;
+    const xmlChar *prefix;
+    const xmlChar *href;
+    int has_empty_ns;
+        
+    if(cur == NULL) {
+        xmlC14NErrParam("searching namespaces stack (c14n)");
+        return (0);
+    }
+
+    /*
+     * if the default namespace xmlns="" is not defined yet then 
+     * we do not want to print it out
+     */
+    prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
+    href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
+    has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
+
+    if (cur->nsTab != NULL) {
+	int start = (has_empty_ns) ? 0 : cur->nsPrevStart;
+        for (i = cur->nsCurEnd - 1; i >= start; --i) {
+            xmlNsPtr ns1 = cur->nsTab[i];
+	    
+	    if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
+		return(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL));
+	    }
+        }
+    }
+    return(has_empty_ns);
+}
+
+static int			
+xmlExcC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NCtxPtr ctx) {
+    int i;
+    const xmlChar *prefix;
+    const xmlChar *href;
+    int has_empty_ns;
+        
+    if(cur == NULL) {
+        xmlC14NErrParam("searching namespaces stack (exc c14n)");
+        return (0);
+    }
+
+    /*
+     * if the default namespace xmlns="" is not defined yet then 
+     * we do not want to print it out
+     */
+    prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
+    href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
+    has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
+
+    if (cur->nsTab != NULL) {
+	int start = 0;
+        for (i = cur->nsCurEnd - 1; i >= start; --i) {
+            xmlNsPtr ns1 = cur->nsTab[i];
+	    
+	    if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
+		if(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL)) {
+	    	    return(xmlC14NIsVisible(ctx, ns1, cur->nodeTab[i]));
+		} else {
+		    return(0);
+		}
+	    }
+        }
+    }
+    return(has_empty_ns);
+}
+
+
+
+
+/**
+ * xmlC14NIsXmlNs:
+ * @ns: 		the namespace to check
+ *  		
+ * Checks whether the given namespace 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
+xmlC14NIsXmlNs(xmlNsPtr ns)
+{
+    return ((ns != NULL) &&
+            (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
+            (xmlStrEqual(ns->href, XML_XML_NAMESPACE)));
+}
+
+
+/**
+ * xmlC14NNsCompare:
+ * @ns1:		the pointer to first namespace
+ * @ns2: 		the pointer to second namespace
+ *
+ * Compares the namespaces by names (prefixes).
+ *
+ * Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2.
+ */
+static int
+xmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2)
+{
+    if (ns1 == ns2)
+        return (0);
+    if (ns1 == NULL)
+        return (-1);
+    if (ns2 == NULL)
+        return (1);
+
+    return (xmlStrcmp(ns1->prefix, ns2->prefix));
+}
+
+
+/**
+ * xmlC14NPrintNamespaces:
+ * @ns:			the pointer to namespace
+ * @ctx: 		the C14N context
+ *
+ * Prints the given namespace to the output buffer from C14N context.
+ *
+ * Returns 1 on success or 0 on fail.
+ */
+static int
+xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
+{
+
+    if ((ns == NULL) || (ctx == NULL)) {
+        xmlC14NErrParam("writing namespaces");
+        return 0;
+    }
+
+    if (ns->prefix != NULL) {
+        xmlOutputBufferWriteString(ctx->buf, " xmlns:");
+        xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
+        xmlOutputBufferWriteString(ctx->buf, "=\"");
+    } else {
+        xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");
+    }
+    if(ns->href != NULL) {
+	xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
+    }
+    xmlOutputBufferWriteString(ctx->buf, "\"");
+    return (1);
+}
+
+/**
+ * xmlC14NProcessNamespacesAxis:
+ * @ctx: 		the C14N context
+ * @node:		the current node
+ *
+ * Prints out canonical namespace axis of the current node to the
+ * buffer from C14N context as follows 
+ *
+ * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
+ *
+ * Namespace Axis
+ * Consider a list L containing only namespace nodes in the 
+ * axis and in the node-set in lexicographic order (ascending). To begin 
+ * processing L, if the first node is not the default namespace node (a node 
+ * with no namespace URI and no local name), then generate a space followed 
+ * by xmlns="" if and only if the following conditions are met:
+ *    - the element E that owns the axis is in the node-set
+ *    - The nearest ancestor element of E in the node-set has a default 
+ *	    namespace node in the node-set (default namespace nodes always 
+ *      have non-empty values in XPath)
+ * The latter condition eliminates unnecessary occurrences of xmlns="" in 
+ * the canonical form since an element only receives an xmlns="" if its 
+ * default namespace is empty and if it has an immediate parent in the 
+ * canonical form that has a non-empty default namespace. To finish 
+ * processing  L, simply process every namespace node in L, except omit 
+ * namespace node with local name xml, which defines the xml prefix, 
+ * if its string value is http://www.w3.org/XML/1998/namespace.
+ *
+ * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
+ * Canonical XML applied to a document subset requires the search of the 
+ * ancestor nodes of each orphan element node for attributes in the xml 
+ * namespace, such as xml:lang and xml:space. These are copied into the 
+ * element node except if a declaration of the same attribute is already 
+ * in the attribute axis of the element (whether or not it is included in 
+ * the document subset). This search and copying are omitted from the 
+ * Exclusive XML Canonicalization method.
+ *
+ * Returns 0 on success or -1 on fail.
+ */
+static int
+xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
+{
+    xmlNodePtr n;
+    xmlNsPtr ns, tmp;
+    xmlListPtr list;
+    int already_rendered;
+    int has_empty_ns = 0;
+    
+    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
+        xmlC14NErrParam("processing namespaces axis (c14n)");
+        return (-1);
+    }
+
+    /*
+     * Create a sorted list to store element namespaces
+     */
+    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
+    if (list == NULL) {
+        xmlC14NErrInternal("creating namespaces list (c14n)");
+        return (-1);
+    }
+
+    /* check all namespaces */
+    for(n = cur; n != NULL; n = n->parent) {
+	for(ns = n->nsDef; ns != NULL; ns = ns->next) {
+	    tmp = xmlSearchNs(cur->doc, cur, ns->prefix);
+	    
+	    if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
+		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
+		if(visible) {
+        	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
+		}
+		if(!already_rendered) {
+		    xmlListInsert(list, ns); 
+		}
+    		if(xmlStrlen(ns->prefix) == 0) {
+		    has_empty_ns = 1;
+		}
+	    }
+	}
+    }
+	
+    /**
+     * if the first node is not the default namespace node (a node with no 
+     * namespace URI and no local name), then generate a space followed by 
+     * xmlns="" if and only if the following conditions are met:
+     *  - the element E that owns the axis is in the node-set
+     *  - the nearest ancestor element of E in the node-set has a default 
+     *     namespace node in the node-set (default namespace nodes always 
+     *     have non-empty values in XPath)
+     */
+    if(visible && !has_empty_ns) {
+        static xmlNs ns_default;
+
+        memset(&ns_default, 0, sizeof(ns_default));
+        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
+    	    xmlC14NPrintNamespaces(&ns_default, ctx);
+	}
+    }
+	
+    
+    /* 
+     * print out all elements from list 
+     */
+    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
+
+    /* 
+     * Cleanup
+     */
+    xmlListDelete(list);
+    return (0);
+}
+
+
+/**
+ * xmlExcC14NProcessNamespacesAxis:
+ * @ctx: 		the C14N context
+ * @node:		the current node
+ *
+ * Prints out exclusive canonical namespace axis of the current node to the
+ * buffer from C14N context as follows 
+ *
+ * Exclusive XML Canonicalization
+ * http://www.w3.org/TR/xml-exc-c14n
+ *
+ * If the element node is in the XPath subset then output the node in 
+ * accordance with Canonical XML except for namespace nodes which are 
+ * rendered as follows:
+ *
+ * 1. Render each namespace node iff:
+ *    * it is visibly utilized by the immediate parent element or one of 
+ *      its attributes, or is present in InclusiveNamespaces PrefixList, and
+ *    * its prefix and value do not appear in ns_rendered. ns_rendered is 
+ *      obtained by popping the state stack in order to obtain a list of 
+ *      prefixes and their values which have already been rendered by 
+ *      an output ancestor of the namespace node's parent element.
+ * 2. Append the rendered namespace node to the list ns_rendered of namespace 
+ * nodes rendered by output ancestors. Push ns_rendered on state stack and 
+ * recurse.
+ * 3. After the recursion returns, pop thestate stack.
+ *
+ *
+ * Returns 0 on success or -1 on fail.
+ */
+static int
+xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
+{
+    xmlNsPtr ns;
+    xmlListPtr list;
+    xmlAttrPtr attr;
+    int already_rendered;
+    int has_empty_ns = 0;
+    int has_visibly_utilized_empty_ns = 0;
+    int has_empty_ns_in_inclusive_list = 0;
+        
+    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
+        xmlC14NErrParam("processing namespaces axis (exc c14n)");
+        return (-1);
+    }
+
+    if(!xmlC14NIsExclusive(ctx)) {
+        xmlC14NErrParam("processing namespaces axis (exc c14n)");
+        return (-1);
+
+    }
+
+    /*
+     * Create a sorted list to store element namespaces
+     */
+    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
+    if (list == NULL) {
+        xmlC14NErrInternal("creating namespaces list (exc c14n)");
+        return (-1);
+    }
+
+    /* 
+     * process inclusive namespaces:
+     * All namespace nodes appearing on inclusive ns list are 
+     * handled as provided in Canonical XML
+     */
+    if(ctx->inclusive_ns_prefixes != NULL) {
+	xmlChar *prefix; 
+	int i;
+	
+	for (i = 0; ctx->inclusive_ns_prefixes[i] != NULL; ++i) {
+	    prefix = ctx->inclusive_ns_prefixes[i];
+	    /*
+	     * Special values for namespace with empty prefix
+	     */
+            if (xmlStrEqual(prefix, BAD_CAST "#default")
+                || xmlStrEqual(prefix, BAD_CAST "")) {
+                prefix = NULL;
+		has_empty_ns_in_inclusive_list = 1;
+            }
+	
+	    ns = xmlSearchNs(cur->doc, cur, prefix);	    
+	    if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
+		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
+		if(visible) {
+    	    	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
+		}
+		if(!already_rendered) {
+	    	    xmlListInsert(list, ns); 
+		}
+    		if(xmlStrlen(ns->prefix) == 0) {
+		    has_empty_ns = 1;
+		}
+	    }
+	}
+    }
+    
+    /* add node namespace */
+    if(cur->ns != NULL) {
+	ns = cur->ns;
+    } else {
+        ns = xmlSearchNs(cur->doc, cur, NULL);
+	has_visibly_utilized_empty_ns = 1;
+    }
+    if((ns != NULL) && !xmlC14NIsXmlNs(ns)) {
+	if(visible && xmlC14NIsVisible(ctx, ns, cur)) { 
+	    if(!xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, ns, ctx)) {
+		xmlListInsert(list, ns);
+	    }
+	}
+	if(visible) {
+    	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur); 
+	}
+	if(xmlStrlen(ns->prefix) == 0) {
+	    has_empty_ns = 1;
+	}
+    }
+    
+        
+    /* add attributes */
+    for(attr = cur->properties; attr != NULL; attr = attr->next) {
+        /* 
+         * we need to check that attribute is visible and has non
+         * default namespace (XML Namespaces: "default namespaces 
+    	 * do not apply directly to attributes")	 
+         */
+	if((attr->ns != NULL) && !xmlC14NIsXmlNs(attr->ns) && xmlC14NIsVisible(ctx, attr, cur)) {
+	    already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);
+	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur); 
+	    if(!already_rendered && visible) {
+		xmlListInsert(list, attr->ns); 
+	    }
+	    if(xmlStrlen(attr->ns->prefix) == 0) {
+		has_empty_ns = 1;
+	    }
+	} else if((attr->ns != NULL) && (xmlStrlen(attr->ns->prefix) == 0) && (xmlStrlen(attr->ns->href) == 0)) {
+	    has_visibly_utilized_empty_ns = 1;
+	}
+    }
+
+    /*
+     * Process xmlns=""
+     */
+    if(visible && has_visibly_utilized_empty_ns && 
+	    !has_empty_ns && !has_empty_ns_in_inclusive_list) {
+        static xmlNs ns_default;
+
+        memset(&ns_default, 0, sizeof(ns_default));
+	
+        already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default, ctx);
+	if(!already_rendered) {
+    	    xmlC14NPrintNamespaces(&ns_default, ctx);
+	}
+    } else if(visible && !has_empty_ns && has_empty_ns_in_inclusive_list) {
+        static xmlNs ns_default;
+
+        memset(&ns_default, 0, sizeof(ns_default));
+        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
+    	    xmlC14NPrintNamespaces(&ns_default, ctx);
+	}
+    }
+
+    
+
+    /* 
+     * print out all elements from list 
+     */
+    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
+
+    /* 
+     * Cleanup
+     */
+    xmlListDelete(list);
+    return (0);
+}
+
+
+/**
+ * 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
+ *
+ * Prints the given attribute to the output buffer from C14N context.
+ *
+ * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2.
+ */
+static int
+xmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2)
+{
+    int ret = 0;
+
+    /*
+     * Simple cases
+     */
+    if (attr1 == attr2)
+        return (0);
+    if (attr1 == NULL)
+        return (-1);
+    if (attr2 == NULL)
+        return (1);
+    if (attr1->ns == attr2->ns) {
+        return (xmlStrcmp(attr1->name, attr2->name));
+    }
+
+    /* 
+     * Attributes in the default namespace are first
+     * because the default namespace is not applied to
+     * unqualified attributes
+     */
+    if (attr1->ns == NULL)
+        return (-1);
+    if (attr2->ns == NULL)
+        return (1);
+    if (attr1->ns->prefix == NULL)
+        return (-1);
+    if (attr2->ns->prefix == NULL)
+        return (1);
+
+    ret = xmlStrcmp(attr1->ns->href, attr2->ns->href);
+    if (ret == 0) {
+        ret = xmlStrcmp(attr1->name, attr2->name);
+    }
+    return (ret);
+}
+
+
+/**
+ * xmlC14NPrintAttrs:
+ * @attr:		the pointer to attr
+ * @ctx: 		the C14N context
+ *
+ * Prints out canonical attribute urrent node to the
+ * buffer from C14N context as follows 
+ *
+ * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
+ *
+ * Returns 1 on success or 0 on fail.
+ */
+static int
+xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
+{
+    xmlChar *value;
+    xmlChar *buffer;
+
+    if ((attr == NULL) || (ctx == NULL)) {
+        xmlC14NErrParam("writing attributes");
+        return (0);
+    }
+
+    xmlOutputBufferWriteString(ctx->buf, " ");
+    if (attr->ns != NULL && xmlStrlen(attr->ns->prefix) > 0) {
+        xmlOutputBufferWriteString(ctx->buf,
+                                   (const char *) attr->ns->prefix);
+        xmlOutputBufferWriteString(ctx->buf, ":");
+    }
+    xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
+    xmlOutputBufferWriteString(ctx->buf, "=\"");
+
+    value = xmlNodeListGetString(ctx->doc, attr->children, 1);
+    /* todo: should we log an error if value==NULL ? */
+    if (value != NULL) {
+        buffer = xmlC11NNormalizeAttr(value);
+        xmlFree(value);
+        if (buffer != NULL) {
+            xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);
+            xmlFree(buffer);
+        } else {
+            xmlC14NErrInternal("normalizing attributes axis");
+            return (0);
+        }
+    }
+    xmlOutputBufferWriteString(ctx->buf, "\"");
+    return (1);
+}
+
+/**
+ * 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 
+ *
+ * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
+ *
+ * Attribute Axis 
+ * In lexicographic order (ascending), process each node that 
+ * is in the element's attribute axis and in the node-set.
+ * 
+ * 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.
+ *
+ *
+ * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
+ *
+ * Canonical XML applied to a document subset requires the search of the 
+ * ancestor nodes of each orphan element node for attributes in the xml 
+ * namespace, such as xml:lang and xml:space. These are copied into the 
+ * element node except if a declaration of the same attribute is already 
+ * in the attribute axis of the element (whether or not it is included in 
+ * the document subset). This search and copying are omitted from the 
+ * Exclusive XML Canonicalization method.
+ *
+ * Returns 0 on success or -1 on fail.
+ */
+static int
+xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
+{
+    xmlAttrPtr attr;
+    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");
+        return (-1);
+    }
+
+    /*
+     * Create a sorted list to store element attributes
+     */
+    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NAttrsCompare);
+    if (list == NULL) {
+        xmlC14NErrInternal("creating attributes list");
+        return (-1);
+    }
+
+    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. 
+         */
+    
+        /* 
+         * 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;
+        }
+
+        /* 
+         * 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;
+    }
+
+    /* 
+     * print out all elements from list 
+     */
+    xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx);
+
+    /* 
+     * Cleanup
+     */
+    xmlFreePropList(attrs_to_delete);
+    xmlListDelete(list);
+    return (0);
+}
+
+/** 
+ * xmlC14NCheckForRelativeNamespaces:
+ * @ctx:		the C14N context
+ * @cur:		the current element node
+ *
+ * Checks that current element node has no relative namespaces defined
+ *
+ * Returns 0 if the node has no relative namespaces or -1 otherwise.
+ */
+static int
+xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+{
+    xmlNsPtr ns;
+
+    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
+        xmlC14NErrParam("checking for relative namespaces");
+        return (-1);
+    }
+
+    ns = cur->nsDef;
+    while (ns != NULL) {
+        if (xmlStrlen(ns->href) > 0) {
+            xmlURIPtr uri;
+
+            uri = xmlParseURI((const char *) ns->href);
+            if (uri == NULL) {
+                xmlC14NErrInternal("parsing namespace uri");
+                return (-1);
+            }
+            if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {
+                xmlC14NErrRelativeNamespace(uri->scheme);
+                xmlFreeURI(uri);
+                return (-1);
+            }
+            if ((xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "urn") != 0)
+                && (xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "dav") !=0)
+                && (xmlStrlen((const xmlChar *) uri->server) == 0)) {
+                xmlC14NErrRelativeNamespace(uri->scheme);
+                xmlFreeURI(uri);
+                return (-1);
+            }
+            xmlFreeURI(uri);
+        }
+        ns = ns->next;
+    }
+    return (0);
+}
+
+/**
+ * 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)
+ *
+ * Element Nodes
+ * If the element is not in the node-set, then the result is obtained 
+ * by processing the namespace axis, then the attribute axis, then 
+ * processing the child nodes of the element that are in the node-set 
+ * (in document order). If the element is in the node-set, then the result 
+ * is an open angle bracket (<), the element QName, the result of 
+ * processing the namespace axis, the result of processing the attribute 
+ * axis, a close angle bracket (>), the result of processing the child 
+ * nodes of the element that are in the node-set (in document order), an 
+ * open angle bracket, a forward slash (/), the element QName, and a close 
+ * angle bracket.
+ *
+ * Returns non-negative value on success or negative value on fail
+ */
+static int
+xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
+{
+    int ret;
+    xmlC14NVisibleNsStack state;
+    int parent_is_doc = 0;
+
+    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
+        xmlC14NErrParam("processing element node");
+        return (-1);
+    }
+
+    /* 
+     * Check relative relative namespaces:
+     * implementations of XML canonicalization MUST report an operation
+     * failure on documents containing relative namespace URIs.
+     */
+    if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {
+        xmlC14NErrInternal("checking for relative namespaces");
+        return (-1);
+    }
+
+
+    /* 
+     * Save ns_rendered stack position
+     */
+    memset(&state, 0, sizeof(state));
+    xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);
+
+    if (visible) {	
+        if (ctx->parent_is_doc) {
+	    /* save this flag into the stack */
+	    parent_is_doc = ctx->parent_is_doc;
+	    ctx->parent_is_doc = 0;
+            ctx->pos = XMLC14N_INSIDE_DOCUMENT_ELEMENT;
+        }
+        xmlOutputBufferWriteString(ctx->buf, "<");
+
+        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
+            xmlOutputBufferWriteString(ctx->buf,
+                                       (const char *) cur->ns->prefix);
+            xmlOutputBufferWriteString(ctx->buf, ":");
+        }
+        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
+    }
+
+    if (!xmlC14NIsExclusive(ctx)) {
+        ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
+    } else {
+        ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
+    }
+    if (ret < 0) {
+        xmlC14NErrInternal("processing namespaces axis");
+        return (-1);
+    }
+    /* todo: shouldn't this go to "visible only"? */
+    if(visible) {
+	xmlC14NVisibleNsStackShift(ctx->ns_rendered);
+    }
+    
+    ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);
+    if (ret < 0) {
+	xmlC14NErrInternal("processing attributes axis");
+    	return (-1);
+    }
+
+    if (visible) { 
+        xmlOutputBufferWriteString(ctx->buf, ">");
+    }
+    if (cur->children != NULL) {
+        ret = xmlC14NProcessNodeList(ctx, cur->children);
+        if (ret < 0) {
+            xmlC14NErrInternal("processing childrens list");
+            return (-1);
+        }
+    }
+    if (visible) {
+        xmlOutputBufferWriteString(ctx->buf, "</");
+        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
+            xmlOutputBufferWriteString(ctx->buf,
+                                       (const char *) cur->ns->prefix);
+            xmlOutputBufferWriteString(ctx->buf, ":");
+        }
+        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
+        xmlOutputBufferWriteString(ctx->buf, ">");
+        if (parent_is_doc) {
+	    /* restore this flag from the stack for next node */
+            ctx->parent_is_doc = parent_is_doc;
+	    ctx->pos = XMLC14N_AFTER_DOCUMENT_ELEMENT;
+        }
+    }
+
+    /* 
+     * Restore ns_rendered stack position
+     */
+    xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);
+    return (0);
+}
+
+/**
+ * xmlC14NProcessNode:
+ * @ctx: 		the pointer to C14N context object
+ * @cur:		the node to process
+ *  		
+ * Processes the given node
+ *
+ * Returns non-negative value on success or negative value on fail
+ */
+static int
+xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+{
+    int ret = 0;
+    int visible;
+
+    if ((ctx == NULL) || (cur == NULL)) {
+        xmlC14NErrParam("processing node");
+        return (-1);
+    }
+
+    visible = xmlC14NIsVisible(ctx, cur, cur->parent);
+    switch (cur->type) {
+        case XML_ELEMENT_NODE:
+            ret = xmlC14NProcessElementNode(ctx, cur, visible);
+            break;
+        case XML_CDATA_SECTION_NODE:
+        case XML_TEXT_NODE:
+            /*
+             * Text Nodes
+             * the string value, except all ampersands are replaced 
+             * by &amp;, all open angle brackets (<) are replaced by &lt;, all closing 
+             * angle brackets (>) are replaced by &gt;, and all #xD characters are 
+             * replaced by &#xD;.
+             */
+            /* cdata sections are processed as text nodes */
+            /* todo: verify that cdata sections are included in XPath nodes set */
+            if ((visible) && (cur->content != NULL)) {
+                xmlChar *buffer;
+
+                buffer = xmlC11NNormalizeText(cur->content);
+                if (buffer != NULL) {
+                    xmlOutputBufferWriteString(ctx->buf,
+                                               (const char *) buffer);
+                    xmlFree(buffer);
+                } else {
+                    xmlC14NErrInternal("normalizing text node");
+                    return (-1);
+                }
+            }
+            break;
+        case XML_PI_NODE:
+            /* 
+             * Processing Instruction (PI) Nodes- 
+             * The opening PI symbol (<?), the PI target name of the node, 
+             * a leading space and the string value if it is not empty, and 
+             * the closing PI symbol (?>). If the string value is empty, 
+             * then the leading space is not added. Also, a trailing #xA is 
+             * rendered after the closing PI symbol for PI children of the 
+             * root node with a lesser document order than the document 
+             * element, and a leading #xA is rendered before the opening PI 
+             * symbol of PI children of the root node with a greater document 
+             * order than the document element.
+             */
+            if (visible) {
+                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
+                    xmlOutputBufferWriteString(ctx->buf, "\x0A<?");
+                } else {
+                    xmlOutputBufferWriteString(ctx->buf, "<?");
+                }
+
+                xmlOutputBufferWriteString(ctx->buf,
+                                           (const char *) cur->name);
+                if ((cur->content != NULL) && (*(cur->content) != '\0')) {
+                    xmlChar *buffer;
+
+                    xmlOutputBufferWriteString(ctx->buf, " ");
+
+                    /* todo: do we need to normalize pi? */
+                    buffer = xmlC11NNormalizePI(cur->content);
+                    if (buffer != NULL) {
+                        xmlOutputBufferWriteString(ctx->buf,
+                                                   (const char *) buffer);
+                        xmlFree(buffer);
+                    } else {
+                        xmlC14NErrInternal("normalizing pi node");
+                        return (-1);
+                    }
+                }
+
+                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
+                    xmlOutputBufferWriteString(ctx->buf, "?>\x0A");
+                } else {
+                    xmlOutputBufferWriteString(ctx->buf, "?>");
+                }
+            }
+            break;
+        case XML_COMMENT_NODE:
+            /*
+             * Comment Nodes
+             * Nothing if generating canonical XML without  comments. For 
+             * canonical XML with comments, generate the opening comment 
+             * symbol (<!--), the string value of the node, and the 
+             * closing comment symbol (-->). Also, a trailing #xA is rendered 
+             * after the closing comment symbol for comment children of the 
+             * root node with a lesser document order than the document 
+             * element, and a leading #xA is rendered before the opening 
+             * comment symbol of comment children of the root node with a 
+             * greater document order than the document element. (Comment 
+             * children of the root node represent comments outside of the 
+             * top-level document element and outside of the document type 
+             * declaration).
+             */
+            if (visible && ctx->with_comments) {
+                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
+                    xmlOutputBufferWriteString(ctx->buf, "\x0A<!--");
+                } else {
+                    xmlOutputBufferWriteString(ctx->buf, "<!--");
+                }
+
+                if (cur->content != NULL) {
+                    xmlChar *buffer;
+
+                    /* todo: do we need to normalize comment? */
+                    buffer = xmlC11NNormalizeComment(cur->content);
+                    if (buffer != NULL) {
+                        xmlOutputBufferWriteString(ctx->buf,
+                                                   (const char *) buffer);
+                        xmlFree(buffer);
+                    } else {
+                        xmlC14NErrInternal("normalizing comment node");
+                        return (-1);
+                    }
+                }
+
+                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
+                    xmlOutputBufferWriteString(ctx->buf, "-->\x0A");
+                } else {
+                    xmlOutputBufferWriteString(ctx->buf, "-->");
+                }
+            }
+            break;
+        case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_FRAG_NODE:   /* should be processed as document? */
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:   /* should be processed as document? */
+#endif
+#ifdef LIBXML_HTML_ENABLED
+        case XML_HTML_DOCUMENT_NODE:   /* should be processed as document? */
+#endif
+            if (cur->children != NULL) {
+                ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
+                ctx->parent_is_doc = 1;
+                ret = xmlC14NProcessNodeList(ctx, cur->children);
+            }
+            break;
+
+        case XML_ATTRIBUTE_NODE:
+            xmlC14NErrInvalidNode("XML_ATTRIBUTE_NODE", "processing node");
+            return (-1);
+        case XML_NAMESPACE_DECL:
+            xmlC14NErrInvalidNode("XML_NAMESPACE_DECL", "processing node");
+            return (-1);
+        case XML_ENTITY_REF_NODE:
+            xmlC14NErrInvalidNode("XML_ENTITY_REF_NODE", "processing node");
+            return (-1);
+        case XML_ENTITY_NODE:
+            xmlC14NErrInvalidNode("XML_ENTITY_NODE", "processing node");
+            return (-1);
+
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+#ifdef LIBXML_XINCLUDE_ENABLED
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+#endif
+            /* 
+             * should be ignored according to "W3C Canonical XML" 
+             */
+            break;
+        default:
+            xmlC14NErrUnknownNode(cur->type, "processing node");
+            return (-1);
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlC14NProcessNodeList:
+ * @ctx: 		the pointer to C14N context object
+ * @cur:		the node to start from
+ *  		
+ * Processes all nodes in the row starting from cur.
+ *
+ * Returns non-negative value on success or negative value on fail
+ */
+static int
+xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+{
+    int ret;
+
+    if (ctx == NULL) {
+        xmlC14NErrParam("processing node list");
+        return (-1);
+    }
+
+    for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {
+        ret = xmlC14NProcessNode(ctx, cur);
+    }
+    return (ret);
+}
+
+
+/**
+ * xmlC14NFreeCtx:
+ * @ctx: the pointer to C14N context object
+ * 		
+ * Cleanups the C14N context object.
+ */
+
+static void
+xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
+{
+    if (ctx == NULL) {
+        xmlC14NErrParam("freeing context");
+        return;
+    }
+
+    if (ctx->ns_rendered != NULL) {
+        xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);
+    }
+    xmlFree(ctx);
+}
+
+/**
+ * xmlC14NNewCtx:
+ * @doc: 		the XML document for canonization
+ * @is_visible_callback:the function to use to determine is node visible 
+ *			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 ` 
+ *			canonicalization)
+ * @with_comments: 	include comments in the result (!=0) or not (==0)
+ * @buf: 		the output buffer to store canonical XML; this 
+ *			buffer MUST have encoder==NULL because C14N requires
+ *			UTF-8 output
+ *  		
+ * Creates new C14N context object to store C14N parameters.
+ *
+ * Returns pointer to newly created object (success) or NULL (fail)
+ */
+static xmlC14NCtxPtr
+xmlC14NNewCtx(xmlDocPtr doc,  
+	      xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
+              xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
+              int with_comments, xmlOutputBufferPtr buf)
+{
+    xmlC14NCtxPtr ctx = NULL;
+
+    if ((doc == NULL) || (buf == NULL)) {
+        xmlC14NErrParam("creating new context");
+        return (NULL);
+    }
+
+    /*
+     *  Validate the encoding output buffer encoding
+     */
+    if (buf->encoder != NULL) {
+        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
+"xmlC14NNewCtx: output buffer encoder != NULL but C14N requires UTF8 output\n");
+        return (NULL);
+    }
+
+    /*
+     *  Validate the XML document encoding value, if provided.
+     */
+    if (doc->charset != XML_CHAR_ENCODING_UTF8) {
+        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
+		   "xmlC14NNewCtx: source document not in UTF8\n");
+        return (NULL);
+    }
+
+    /*
+     * Allocate a new xmlC14NCtxPtr and fill the fields.
+     */
+    ctx = (xmlC14NCtxPtr) xmlMalloc(sizeof(xmlC14NCtx));
+    if (ctx == NULL) {
+	xmlC14NErrMemory("creating context");
+        return (NULL);
+    }
+    memset(ctx, 0, sizeof(xmlC14NCtx));
+
+    /*
+     * initialize C14N context
+     */
+    ctx->doc = doc;
+    ctx->with_comments = with_comments;
+    ctx->is_visible_callback = is_visible_callback;
+    ctx->user_data = user_data;
+    ctx->buf = buf;
+    ctx->parent_is_doc = 1;
+    ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
+    ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
+
+    if(ctx->ns_rendered == NULL) {
+        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_CREATE_STACK,
+		   "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
+	xmlC14NFreeCtx(ctx);
+        return (NULL);
+    }
+
+    /*
+     * Set "mode" flag and remember list of incluseve prefixes
+     * for exclusive c14n
+     */
+    ctx->mode = mode;
+    if(xmlC14NIsExclusive(ctx)) {
+        ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
+    }
+    return (ctx);
+}
+
+/**
+ * xmlC14NExecute:
+ * @doc: 		the XML document for canonization
+ * @is_visible_callback:the function to use to determine is node visible 
+ *			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_prefixes: the list of inclusive namespace prefixes 
+ *			ended with a NULL or NULL if there is no
+ *			inclusive namespaces (only for exclusive 
+ *			canonicalization, ignored otherwise)
+ * @with_comments: 	include comments in the result (!=0) or not (==0)
+ * @buf: 		the output buffer to store canonical XML; this 
+ *			buffer MUST have encoder==NULL because C14N requires
+ *			UTF-8 output
+ *  		
+ * Dumps the canonized image of given XML document into the provided buffer.
+ * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
+ * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
+ *
+ * Returns non-negative value on success or a negative value on fail  
+ */
+int 		
+xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
+	 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)) {
+        xmlC14NErrParam("executing c14n");
+        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
+     */
+    if (buf->encoder != NULL) {
+        xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
+"xmlC14NExecute: output buffer encoder != NULL but C14N requires UTF8 output\n");
+        return (-1);
+    }
+
+    ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data, 
+	            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");
+        return (-1);
+    }
+
+
+
+    /*  
+     * Root Node
+     * The root node is the parent of the top-level document element. The 
+     * result of processing each of its child nodes that is in the node-set 
+     * in document order. The root node does not generate a byte order mark, 
+     * XML declaration, nor anything from within the document type 
+     * declaration.
+     */
+    if (doc->children != NULL) {
+        ret = xmlC14NProcessNodeList(ctx, doc->children);
+        if (ret < 0) {
+            xmlC14NErrInternal("processing docs children list");
+            xmlC14NFreeCtx(ctx);
+            return (-1);
+        }
+    }
+
+    /*
+     * Flush buffer to get number of bytes written
+     */
+    ret = xmlOutputBufferFlush(buf);
+    if (ret < 0) {
+        xmlC14NErrInternal("flushing output buffer");
+        xmlC14NFreeCtx(ctx);
+        return (-1);
+    }
+
+    /* 
+     * Cleanup
+     */
+    xmlC14NFreeCtx(ctx);
+    return (ret);
+}
+
+/**
+ * xmlC14NDocSaveTo:
+ * @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
+ * @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 
+ *			canonicalization, ignored otherwise)
+ * @with_comments: 	include comments in the result (!=0) or not (==0)
+ * @buf: 		the output buffer to store canonical XML; this 
+ *			buffer MUST have encoder==NULL because C14N requires
+ *			UTF-8 output
+ *  		
+ * Dumps the canonized image of given XML document into the provided buffer.
+ * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
+ * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
+ *
+ * Returns non-negative value on success or a negative value on fail  
+ */
+int
+xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
+                 int mode, xmlChar ** inclusive_ns_prefixes,
+                 int with_comments, xmlOutputBufferPtr buf) {
+    return(xmlC14NExecute(doc, 
+			(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
+			nodes,
+			mode,
+			inclusive_ns_prefixes,
+			with_comments,
+			buf));
+}
+
+
+/**
+ * xmlC14NDocDumpMemory:
+ * @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
+ * @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 
+ *			canonicalization, ignored otherwise)
+ * @with_comments: 	include comments in the result (!=0) or not (==0)
+ * @doc_txt_ptr: 	the memory pointer for allocated canonical XML text;
+ *			the caller of this functions is responsible for calling
+ *			xmlFree() to free allocated memory 
+ *  		
+ * Dumps the canonized image of given XML document into memory.
+ * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
+ * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
+ *
+ * Returns the number of bytes written on success or a negative value on fail  
+ */
+int
+xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
+                     int mode, xmlChar ** inclusive_ns_prefixes,
+                     int with_comments, xmlChar ** doc_txt_ptr)
+{
+    int ret;
+    xmlOutputBufferPtr buf;
+
+    if (doc_txt_ptr == NULL) {
+        xmlC14NErrParam("dumping doc to memory");
+        return (-1);
+    }
+
+    *doc_txt_ptr = NULL;
+
+    /*
+     * create memory buffer with UTF8 (default) encoding 
+     */
+    buf = xmlAllocOutputBuffer(NULL);
+    if (buf == NULL) {
+        xmlC14NErrMemory("creating output buffer");
+        return (-1);
+    }
+
+    /*
+     * canonize document and write to buffer
+     */
+    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
+                           with_comments, buf);
+    if (ret < 0) {
+        xmlC14NErrInternal("saving doc to output buffer");
+        (void) xmlOutputBufferClose(buf);
+        return (-1);
+    }
+
+    ret = buf->buffer->use;
+    if (ret > 0) {
+        *doc_txt_ptr = xmlStrndup(buf->buffer->content, ret);
+    }
+    (void) xmlOutputBufferClose(buf);
+
+    if ((*doc_txt_ptr == NULL) && (ret > 0)) {
+        xmlC14NErrMemory("coping canonicanized document");
+        return (-1);
+    }
+    return (ret);
+}
+
+/**
+ * xmlC14NDocSave:
+ * @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
+ * @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 
+ *			canonicalization, ignored otherwise)
+ * @with_comments: 	include comments in the result (!=0) or not (==0)
+ * @filename: 		the filename to store canonical XML image
+ * @compression:	the compression level (zlib requred): 
+ *				-1 - libxml default,
+ *				 0 - uncompressed, 
+ *				>0 - compression level
+ *  		
+ * Dumps the canonized image of given XML document into the file.
+ * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
+ * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
+ *
+ * Returns the number of bytes written success or a negative value on fail  
+ */
+int
+xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
+               int mode, xmlChar ** inclusive_ns_prefixes,
+               int with_comments, const char *filename, int compression)
+{
+    xmlOutputBufferPtr buf;
+    int ret;
+
+    if (filename == NULL) {
+        xmlC14NErrParam("saving doc");
+        return (-1);
+    }
+#ifdef HAVE_ZLIB_H
+    if (compression < 0)
+        compression = xmlGetCompressMode();
+#endif
+
+    /* 
+     * save the content to a temp buffer, use default UTF8 encoding.
+     */
+    buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
+    if (buf == NULL) {
+        xmlC14NErrInternal("creating temporary filename");
+        return (-1);
+    }
+
+    /*
+     * canonize document and write to buffer
+     */
+    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
+                           with_comments, buf);
+    if (ret < 0) {
+        xmlC14NErrInternal("cannicanize document to buffer");
+        (void) xmlOutputBufferClose(buf);
+        return (-1);
+    }
+
+    /* 
+     * get the numbers of bytes written 
+     */
+    ret = xmlOutputBufferClose(buf);
+    return (ret);
+}
+
+
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define growBufferReentrant() {						\
+    buffer_size *= 2;							\
+    buffer = (xmlChar *)						\
+    		xmlRealloc(buffer, buffer_size * sizeof(xmlChar));	\
+    if (buffer == NULL) {						\
+	xmlC14NErrMemory("growing buffer");				\
+	return(NULL);							\
+    }									\
+}
+
+/** 
+ * xmlC11NNormalizeString:
+ * @input:		the input string
+ * @mode:		the normalization mode (attribute, comment, PI or text)
+ *
+ * Converts a string to a canonical (normalized) format. The code is stolen
+ * from xmlEncodeEntitiesReentrant(). Added normalization of \x09, \x0a, \x0A
+ * and the @mode parameter
+ *
+ * Returns a normalized string (caller is responsible for calling xmlFree())
+ * or NULL if an error occurs
+ */
+static xmlChar *
+xmlC11NNormalizeString(const xmlChar * input,
+                       xmlC14NNormalizationMode mode)
+{
+    const xmlChar *cur = input;
+    xmlChar *buffer = NULL;
+    xmlChar *out = NULL;
+    int buffer_size = 0;
+
+    if (input == NULL)
+        return (NULL);
+
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) {
+	xmlC14NErrMemory("allocating buffer");
+        return (NULL);
+    }
+    out = buffer;
+
+    while (*cur != '\0') {
+        if ((out - buffer) > (buffer_size - 10)) {
+            int indx = out - buffer;
+
+            growBufferReentrant();
+            out = &buffer[indx];
+        }
+
+        if ((*cur == '<') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
+                              (mode == XMLC14N_NORMALIZE_TEXT))) {
+            *out++ = '&';
+            *out++ = 'l';
+            *out++ = 't';
+            *out++ = ';';
+        } else if ((*cur == '>') && (mode == XMLC14N_NORMALIZE_TEXT)) {
+            *out++ = '&';
+            *out++ = 'g';
+            *out++ = 't';
+            *out++ = ';';
+        } else if ((*cur == '&') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
+                                     (mode == XMLC14N_NORMALIZE_TEXT))) {
+            *out++ = '&';
+            *out++ = 'a';
+            *out++ = 'm';
+            *out++ = 'p';
+            *out++ = ';';
+        } else if ((*cur == '"') && (mode == XMLC14N_NORMALIZE_ATTR)) {
+            *out++ = '&';
+            *out++ = 'q';
+            *out++ = 'u';
+            *out++ = 'o';
+            *out++ = 't';
+            *out++ = ';';
+        } else if ((*cur == '\x09') && (mode == XMLC14N_NORMALIZE_ATTR)) {
+            *out++ = '&';
+            *out++ = '#';
+            *out++ = 'x';
+            *out++ = '9';
+            *out++ = ';';
+        } else if ((*cur == '\x0A') && (mode == XMLC14N_NORMALIZE_ATTR)) {
+            *out++ = '&';
+            *out++ = '#';
+            *out++ = 'x';
+            *out++ = 'A';
+            *out++ = ';';
+        } else if ((*cur == '\x0D') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
+                                        (mode == XMLC14N_NORMALIZE_TEXT) ||
+                                        (mode == XMLC14N_NORMALIZE_COMMENT) ||
+					(mode == XMLC14N_NORMALIZE_PI))) {
+            *out++ = '&';
+            *out++ = '#';
+            *out++ = 'x';
+            *out++ = 'D';
+            *out++ = ';';
+        } else {
+            /*
+             * Works because on UTF-8, all extended sequences cannot
+             * result in bytes in the ASCII range.
+             */
+            *out++ = *cur;
+        }
+        cur++;
+    }
+    *out = 0;
+    return (buffer);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+#define bottom_c14n
+#include "elfgcchack.h"
+#endif /* LIBXML_C14N_ENABLED */
diff --git a/src/catalog.c b/src/catalog.c
new file mode 100644
index 0000000..af84b7c
--- /dev/null
+++ b/src/catalog.c
@@ -0,0 +1,3824 @@
+/**
+ * catalog.c: set of generic Catalog related routines 
+ *
+ * Reference:  SGML Open Technical Resolution TR9401:1997.
+ *             http://www.jclark.com/sp/catalog.htm
+ *
+ *             XML Catalogs Working Draft 06 August 2001
+ *             http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_CATALOG_ENABLED
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/hash.h>
+#include <libxml/uri.h>
+#include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
+#include <libxml/xmlerror.h>
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+
+#define MAX_DELEGATE	50
+#define MAX_CATAL_DEPTH	50
+
+#ifdef _WIN32
+# define PATH_SEAPARATOR ';'
+#else
+# define PATH_SEAPARATOR ':'
+#endif
+
+/**
+ * TODO:
+ *
+ * macro to flag unimplemented blocks
+ * XML_CATALOG_PREFER user env to select between system/public prefered
+ * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
+ *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
+ *> values "system" and "public".  I have made the default be "system" to
+ *> match yours.
+ */
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define XML_URN_PUBID "urn:publicid:"
+#define XML_CATAL_BREAK ((xmlChar *) -1)
+#ifndef XML_XML_DEFAULT_CATALOG
+#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
+#endif
+#ifndef XML_SGML_DEFAULT_CATALOG
+#define XML_SGML_DEFAULT_CATALOG "file:///etc/sgml/catalog"
+#endif
+
+#if defined(_WIN32) && defined(_MSC_VER)
+#undef XML_XML_DEFAULT_CATALOG
+static char XML_XML_DEFAULT_CATALOG[256] = "file:///etc/xml/catalog";
+#if defined(_WIN32_WCE)
+/* Windows CE don't have a A variant */
+#define GetModuleHandleA GetModuleHandle
+#define GetModuleFileNameA GetModuleFileName
+#else
+void* __stdcall GetModuleHandleA(const char*);
+unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
+#endif
+#endif
+
+static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
+static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
+
+/************************************************************************
+ *									*
+ *			Types, all private				*
+ *									*
+ ************************************************************************/
+
+typedef enum {
+    XML_CATA_REMOVED = -1,
+    XML_CATA_NONE = 0,
+    XML_CATA_CATALOG,
+    XML_CATA_BROKEN_CATALOG,
+    XML_CATA_NEXT_CATALOG,
+    XML_CATA_GROUP,
+    XML_CATA_PUBLIC,
+    XML_CATA_SYSTEM,
+    XML_CATA_REWRITE_SYSTEM,
+    XML_CATA_DELEGATE_PUBLIC,
+    XML_CATA_DELEGATE_SYSTEM,
+    XML_CATA_URI,
+    XML_CATA_REWRITE_URI,
+    XML_CATA_DELEGATE_URI,
+    SGML_CATA_SYSTEM,
+    SGML_CATA_PUBLIC,
+    SGML_CATA_ENTITY,
+    SGML_CATA_PENTITY,
+    SGML_CATA_DOCTYPE,
+    SGML_CATA_LINKTYPE,
+    SGML_CATA_NOTATION,
+    SGML_CATA_DELEGATE,
+    SGML_CATA_BASE,
+    SGML_CATA_CATALOG,
+    SGML_CATA_DOCUMENT,
+    SGML_CATA_SGMLDECL
+} xmlCatalogEntryType;
+
+typedef struct _xmlCatalogEntry xmlCatalogEntry;
+typedef xmlCatalogEntry *xmlCatalogEntryPtr;
+struct _xmlCatalogEntry {
+    struct _xmlCatalogEntry *next;
+    struct _xmlCatalogEntry *parent;
+    struct _xmlCatalogEntry *children;
+    xmlCatalogEntryType type;
+    xmlChar *name;
+    xmlChar *value;
+    xmlChar *URL;  /* The expanded URL using the base */
+    xmlCatalogPrefer prefer;
+    int dealloc;
+    int depth;
+    struct _xmlCatalogEntry *group;
+};
+
+typedef enum {
+    XML_XML_CATALOG_TYPE = 1,
+    XML_SGML_CATALOG_TYPE
+} xmlCatalogType;
+
+#define XML_MAX_SGML_CATA_DEPTH 10
+struct _xmlCatalog {
+    xmlCatalogType type;	/* either XML or SGML */
+
+    /*
+     * SGML Catalogs are stored as a simple hash table of catalog entries
+     * Catalog stack to check against overflows when building the
+     * SGML catalog
+     */
+    char *catalTab[XML_MAX_SGML_CATA_DEPTH];	/* stack of catals */
+    int          catalNr;	/* Number of current catal streams */
+    int          catalMax;	/* Max number of catal streams */
+    xmlHashTablePtr sgml;
+
+    /*
+     * XML Catalogs are stored as a tree of Catalog entries
+     */
+    xmlCatalogPrefer prefer;
+    xmlCatalogEntryPtr xml;
+};
+
+/************************************************************************
+ *									*
+ *			Global variables				*
+ *									*
+ ************************************************************************/
+
+/*
+ * Those are preferences
+ */
+static int xmlDebugCatalogs = 0;   /* used for debugging */
+static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
+static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
+
+/*
+ * Hash table containing all the trees of XML catalogs parsed by
+ * the application.
+ */
+static xmlHashTablePtr xmlCatalogXMLFiles = NULL;
+
+/*
+ * The default catalog in use by the application
+ */
+static xmlCatalogPtr xmlDefaultCatalog = NULL;
+
+/*
+ * A mutex for modifying the shared global catalog(s)
+ * xmlDefaultCatalog tree.
+ * It also protects xmlCatalogXMLFiles
+ * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
+ */
+static xmlRMutexPtr xmlCatalogMutex = NULL;
+
+/*
+ * Whether the catalog support was initialized.
+ */
+static int xmlCatalogInitialized = 0;
+
+/************************************************************************
+ *									*
+ * 			Catalog error handlers				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlCatalogErrMemory(const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
+                    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
+		    extra, NULL, NULL, 0, 0,
+		    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlCatalogErr:
+ * @catal: the Catalog entry
+ * @node: the context node
+ * @msg:  the error message
+ * @extra:  extra informations
+ *
+ * Handle a catalog error
+ */
+static void
+xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
+               const char *msg, const xmlChar *str1, const xmlChar *str2,
+	       const xmlChar *str3)
+{
+    __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
+                    error, XML_ERR_ERROR, NULL, 0,
+		    (const char *) str1, (const char *) str2,
+		    (const char *) str3, 0, 0,
+		    msg, str1, str2, str3);
+}
+
+
+/************************************************************************
+ *									*
+ *			Allocation and Freeing				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlNewCatalogEntry:
+ * @type:  type of entry
+ * @name:  name of the entry
+ * @value:  value of the entry
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ * @group:  for members of a group, the group entry 
+ *
+ * create a new Catalog entry, this type is shared both by XML and 
+ * SGML catalogs, but the acceptable types values differs.
+ *
+ * Returns the xmlCatalogEntryPtr or NULL in case of error
+ */
+static xmlCatalogEntryPtr
+xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
+	   const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer,
+	   xmlCatalogEntryPtr group) {
+    xmlCatalogEntryPtr ret;
+    xmlChar *normid = NULL;
+
+    ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
+    if (ret == NULL) {
+        xmlCatalogErrMemory("allocating catalog entry");
+	return(NULL);
+    }
+    ret->next = NULL;
+    ret->parent = NULL;
+    ret->children = NULL;
+    ret->type = type;
+    if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) {
+        normid = xmlCatalogNormalizePublic(name);
+        if (normid != NULL)
+            name = (*normid != 0 ? normid : NULL);
+    }
+    if (name != NULL)
+	ret->name = xmlStrdup(name);
+    else
+	ret->name = NULL;
+    if (normid != NULL)
+        xmlFree(normid);
+    if (value != NULL)
+	ret->value = xmlStrdup(value);
+    else
+	ret->value = NULL;
+    if (URL == NULL)
+	URL = value;
+    if (URL != NULL)
+	ret->URL = xmlStrdup(URL);
+    else
+	ret->URL = NULL;
+    ret->prefer = prefer;
+    ret->dealloc = 0;
+    ret->depth = 0;
+    ret->group = group;
+    return(ret);
+}
+
+static void
+xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
+
+/**
+ * xmlFreeCatalogEntry:
+ * @ret:  a Catalog entry
+ *
+ * Free the memory allocated to a Catalog entry
+ */
+static void
+xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) {
+    if (ret == NULL)
+	return;
+    /*
+     * Entries stored in the file hash must be deallocated
+     * only by the file hash cleaner !
+     */
+    if (ret->dealloc == 1)
+	return;
+
+    if (xmlDebugCatalogs) {
+	if (ret->name != NULL)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Free catalog entry %s\n", ret->name);
+	else if (ret->value != NULL)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Free catalog entry %s\n", ret->value);
+	else
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Free catalog entry\n");
+    }
+
+    if (ret->name != NULL)
+	xmlFree(ret->name);
+    if (ret->value != NULL)
+	xmlFree(ret->value);
+    if (ret->URL != NULL)
+	xmlFree(ret->URL);
+    xmlFree(ret);
+}
+
+/**
+ * xmlFreeCatalogEntryList:
+ * @ret:  a Catalog entry list
+ *
+ * Free the memory allocated to a full chained list of Catalog entries
+ */
+static void
+xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
+    xmlCatalogEntryPtr next;
+
+    while (ret != NULL) {
+	next = ret->next;
+	xmlFreeCatalogEntry(ret);
+	ret = next;
+    }
+}
+
+/**
+ * xmlFreeCatalogHashEntryList:
+ * @ret:  a Catalog entry list
+ *
+ * Free the memory allocated to list of Catalog entries from the
+ * catalog file hash.
+ */
+static void
+xmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) {
+    xmlCatalogEntryPtr children, next;
+
+    if (catal == NULL)
+	return;
+
+    children = catal->children;
+    while (children != NULL) {
+	next = children->next;
+	children->dealloc = 0;
+	children->children = NULL;
+	xmlFreeCatalogEntry(children);
+	children = next;
+    }
+    catal->dealloc = 0;
+    xmlFreeCatalogEntry(catal);
+}
+
+/**
+ * xmlCreateNewCatalog:
+ * @type:  type of catalog
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ *
+ * create a new Catalog, this type is shared both by XML and 
+ * SGML catalogs, but the acceptable types values differs.
+ *
+ * Returns the xmlCatalogPtr or NULL in case of error
+ */
+static xmlCatalogPtr
+xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
+    xmlCatalogPtr ret;
+
+    ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
+    if (ret == NULL) {
+        xmlCatalogErrMemory("allocating catalog");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlCatalog));
+    ret->type = type;
+    ret->catalNr = 0;
+    ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
+    ret->prefer = prefer;
+    if (ret->type == XML_SGML_CATALOG_TYPE)
+	ret->sgml = xmlHashCreate(10);
+    return(ret);
+}
+
+/**
+ * xmlFreeCatalog:
+ * @catal:  a Catalog
+ *
+ * Free the memory allocated to a Catalog
+ */
+void
+xmlFreeCatalog(xmlCatalogPtr catal) {
+    if (catal == NULL)
+	return;
+    if (catal->xml != NULL)
+	xmlFreeCatalogEntryList(catal->xml);
+    if (catal->sgml != NULL)
+	xmlHashFree(catal->sgml,
+		(xmlHashDeallocator) xmlFreeCatalogEntry);
+    xmlFree(catal);
+}
+
+/************************************************************************
+ *									*
+ *			Serializing Catalogs				*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlCatalogDumpEntry:
+ * @entry:  the catalog entry
+ * @out:  the file.
+ *
+ * Serialize an SGML Catalog entry
+ */
+static void
+xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
+    if ((entry == NULL) || (out == NULL))
+	return;
+    switch (entry->type) {
+	case SGML_CATA_ENTITY:
+	    fprintf(out, "ENTITY "); break;
+	case SGML_CATA_PENTITY:
+	    fprintf(out, "ENTITY %%"); break;
+	case SGML_CATA_DOCTYPE:
+	    fprintf(out, "DOCTYPE "); break;
+	case SGML_CATA_LINKTYPE:
+	    fprintf(out, "LINKTYPE "); break;
+	case SGML_CATA_NOTATION:
+	    fprintf(out, "NOTATION "); break;
+	case SGML_CATA_PUBLIC:
+	    fprintf(out, "PUBLIC "); break;
+	case SGML_CATA_SYSTEM:
+	    fprintf(out, "SYSTEM "); break;
+	case SGML_CATA_DELEGATE:
+	    fprintf(out, "DELEGATE "); break;
+	case SGML_CATA_BASE:
+	    fprintf(out, "BASE "); break;
+	case SGML_CATA_CATALOG:
+	    fprintf(out, "CATALOG "); break;
+	case SGML_CATA_DOCUMENT:
+	    fprintf(out, "DOCUMENT "); break;
+	case SGML_CATA_SGMLDECL:
+	    fprintf(out, "SGMLDECL "); break;
+	default:
+	    return;
+    }
+    switch (entry->type) {
+	case SGML_CATA_ENTITY:
+	case SGML_CATA_PENTITY:
+	case SGML_CATA_DOCTYPE:
+	case SGML_CATA_LINKTYPE:
+	case SGML_CATA_NOTATION:
+	    fprintf(out, "%s", (const char *) entry->name); break;
+	case SGML_CATA_PUBLIC:
+	case SGML_CATA_SYSTEM:
+	case SGML_CATA_SGMLDECL:
+	case SGML_CATA_DOCUMENT:
+	case SGML_CATA_CATALOG:
+	case SGML_CATA_BASE:
+	case SGML_CATA_DELEGATE:
+	    fprintf(out, "\"%s\"", entry->name); break;
+	default:
+	    break;
+    }
+    switch (entry->type) {
+	case SGML_CATA_ENTITY:
+	case SGML_CATA_PENTITY:
+	case SGML_CATA_DOCTYPE:
+	case SGML_CATA_LINKTYPE:
+	case SGML_CATA_NOTATION:
+	case SGML_CATA_PUBLIC:
+	case SGML_CATA_SYSTEM:
+	case SGML_CATA_DELEGATE:
+	    fprintf(out, " \"%s\"", entry->value); break;
+	default:
+	    break;
+    }
+    fprintf(out, "\n");
+}
+
+/**
+ * xmlDumpXMLCatalogNode:
+ * @catal:  top catalog entry
+ * @catalog: pointer to the xml tree
+ * @doc: the containing document
+ * @ns: the current namespace
+ * @cgroup: group node for group members
+ *
+ * Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively
+ * for group entries
+ */
+static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
+		    xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
+    xmlNodePtr node;
+    xmlCatalogEntryPtr cur;
+    /*
+     * add all the catalog entries
+     */
+    cur = catal;
+    while (cur != NULL) {
+        if (cur->group == cgroup) {
+	    switch (cur->type) {
+	        case XML_CATA_REMOVED:
+		    break;
+	        case XML_CATA_BROKEN_CATALOG:
+	        case XML_CATA_CATALOG:
+		    if (cur == catal) {
+			cur = cur->children;
+		        continue;
+		    }
+		    break;
+		case XML_CATA_NEXT_CATALOG:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
+		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
+		    xmlAddChild(catalog, node);
+                    break;
+		case XML_CATA_NONE:
+		    break;
+		case XML_CATA_GROUP:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
+		    xmlSetProp(node, BAD_CAST "id", cur->name);
+		    if (cur->value != NULL) {
+		        xmlNsPtr xns;
+			xns = xmlSearchNsByHref(doc, node, XML_XML_NAMESPACE);
+			if (xns != NULL)
+			    xmlSetNsProp(node, xns, BAD_CAST "base",
+			    		 cur->value);
+		    }
+		    switch (cur->prefer) {
+			case XML_CATA_PREFER_NONE:
+		            break;
+			case XML_CATA_PREFER_PUBLIC:
+		            xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
+			    break;
+			case XML_CATA_PREFER_SYSTEM:
+		            xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
+			    break;
+		    }
+		    xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
+		    xmlAddChild(catalog, node);
+	            break;
+		case XML_CATA_PUBLIC:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
+		    xmlSetProp(node, BAD_CAST "publicId", cur->name);
+		    xmlSetProp(node, BAD_CAST "uri", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_SYSTEM:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
+		    xmlSetProp(node, BAD_CAST "systemId", cur->name);
+		    xmlSetProp(node, BAD_CAST "uri", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_REWRITE_SYSTEM:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
+		    xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
+		    xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_DELEGATE_PUBLIC:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
+		    xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
+		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_DELEGATE_SYSTEM:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
+		    xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
+		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_URI:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
+		    xmlSetProp(node, BAD_CAST "name", cur->name);
+		    xmlSetProp(node, BAD_CAST "uri", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_REWRITE_URI:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
+		    xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
+		    xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case XML_CATA_DELEGATE_URI:
+		    node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
+		    xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
+		    xmlSetProp(node, BAD_CAST "catalog", cur->value);
+		    xmlAddChild(catalog, node);
+		    break;
+		case SGML_CATA_SYSTEM:
+		case SGML_CATA_PUBLIC:
+		case SGML_CATA_ENTITY:
+		case SGML_CATA_PENTITY:
+		case SGML_CATA_DOCTYPE:
+		case SGML_CATA_LINKTYPE:
+		case SGML_CATA_NOTATION:
+		case SGML_CATA_DELEGATE:
+		case SGML_CATA_BASE:
+		case SGML_CATA_CATALOG:
+		case SGML_CATA_DOCUMENT:
+		case SGML_CATA_SGMLDECL:
+		    break;
+	    }
+        }
+	cur = cur->next;
+    }
+}
+
+static int
+xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
+    int ret;
+    xmlDocPtr doc;
+    xmlNsPtr ns;
+    xmlDtdPtr dtd;
+    xmlNodePtr catalog;
+    xmlOutputBufferPtr buf;
+
+    /*
+     * Rebuild a catalog
+     */
+    doc = xmlNewDoc(NULL);
+    if (doc == NULL)
+	return(-1);
+    dtd = xmlNewDtd(doc, BAD_CAST "catalog",
+	       BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
+BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
+
+    xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
+
+    ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
+    if (ns == NULL) {
+	xmlFreeDoc(doc);
+	return(-1);
+    }
+    catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
+    if (catalog == NULL) {
+	xmlFreeNs(ns);
+	xmlFreeDoc(doc);
+	return(-1);
+    }
+    catalog->nsDef = ns;
+    xmlAddChild((xmlNodePtr) doc, catalog);
+
+    xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
+    
+    /*
+     * reserialize it
+     */
+    buf = xmlOutputBufferCreateFile(out, NULL);
+    if (buf == NULL) {
+	xmlFreeDoc(doc);
+	return(-1);
+    }
+    ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
+
+    /*
+     * Free it
+     */
+    xmlFreeDoc(doc);
+
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *			Converting SGML Catalogs to XML			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogConvertEntry:
+ * @entry:  the entry
+ * @catal:  pointer to the catalog being converted
+ *
+ * Convert one entry from the catalog
+ */
+static void
+xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) {
+    if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
+	(catal->xml == NULL))
+	return;
+    switch (entry->type) {
+	case SGML_CATA_ENTITY:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_PENTITY:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_DOCTYPE:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_LINKTYPE:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_NOTATION:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_PUBLIC:
+	    entry->type = XML_CATA_PUBLIC;
+	    break;
+	case SGML_CATA_SYSTEM:
+	    entry->type = XML_CATA_SYSTEM;
+	    break;
+	case SGML_CATA_DELEGATE:
+	    entry->type = XML_CATA_DELEGATE_PUBLIC;
+	    break;
+	case SGML_CATA_CATALOG:
+	    entry->type = XML_CATA_CATALOG;
+	    break;
+	default:
+	    xmlHashRemoveEntry(catal->sgml, entry->name,
+		               (xmlHashDeallocator) xmlFreeCatalogEntry);
+	    return;
+    }
+    /*
+     * Conversion successful, remove from the SGML catalog
+     * and add it to the default XML one
+     */
+    xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
+    entry->parent = catal->xml;
+    entry->next = NULL;
+    if (catal->xml->children == NULL)
+	catal->xml->children = entry;
+    else {
+	xmlCatalogEntryPtr prev;
+
+	prev = catal->xml->children;
+	while (prev->next != NULL)
+	    prev = prev->next;
+	prev->next = entry;
+    }
+}
+
+/**
+ * xmlConvertSGMLCatalog:
+ * @catal: the catalog
+ *
+ * Convert all the SGML catalog entries as XML ones
+ *
+ * Returns the number of entries converted if successful, -1 otherwise
+ */
+int
+xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
+
+    if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
+	return(-1);
+
+    if (xmlDebugCatalogs) {
+	xmlGenericError(xmlGenericErrorContext,
+		"Converting SGML catalog to XML\n");
+    }
+    xmlHashScan(catal->sgml,
+		(xmlHashScanner) xmlCatalogConvertEntry,
+		&catal);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			Helper function					*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogUnWrapURN:
+ * @urn:  an "urn:publicid:" to unwrap
+ *
+ * Expand the URN into the equivalent Public Identifier
+ *
+ * Returns the new identifier or NULL, the string must be deallocated
+ *         by the caller.
+ */
+static xmlChar *
+xmlCatalogUnWrapURN(const xmlChar *urn) {
+    xmlChar result[2000];
+    unsigned int i = 0;
+
+    if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
+	return(NULL);
+    urn += sizeof(XML_URN_PUBID) - 1;
+    
+    while (*urn != 0) {
+	if (i > sizeof(result) - 4)
+	    break;
+	if (*urn == '+') {
+	    result[i++] = ' ';
+	    urn++;
+	} else if (*urn == ':') {
+	    result[i++] = '/';
+	    result[i++] = '/';
+	    urn++;
+	} else if (*urn == ';') {
+	    result[i++] = ':';
+	    result[i++] = ':';
+	    urn++;
+	} else if (*urn == '%') {
+	    if ((urn[1] == '2') && (urn[2] == 'B'))
+		result[i++] = '+';
+	    else if ((urn[1] == '3') && (urn[2] == 'A'))
+		result[i++] = ':';
+	    else if ((urn[1] == '2') && (urn[2] == 'F'))
+		result[i++] = '/';
+	    else if ((urn[1] == '3') && (urn[2] == 'B'))
+		result[i++] = ';';
+	    else if ((urn[1] == '2') && (urn[2] == '7'))
+		result[i++] = '\'';
+	    else if ((urn[1] == '3') && (urn[2] == 'F'))
+		result[i++] = '?';
+	    else if ((urn[1] == '2') && (urn[2] == '3'))
+		result[i++] = '#';
+	    else if ((urn[1] == '2') && (urn[2] == '5'))
+		result[i++] = '%';
+	    else {
+		result[i++] = *urn;
+		urn++;
+		continue;
+	    }
+	    urn += 3;
+	} else {
+	    result[i++] = *urn;
+	    urn++;
+	}
+    }
+    result[i] = 0;
+
+    return(xmlStrdup(result));
+}
+
+/**
+ * xmlParseCatalogFile:
+ * @filename:  the filename
+ *
+ * parse an XML file and build a tree. It's like xmlParseFile()
+ * except it bypass all catalog lookups.
+ *
+ * Returns the resulting document tree or NULL in case of error
+ */
+
+xmlDocPtr
+xmlParseCatalogFile(const char *filename) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+    char *directory = NULL;
+    xmlParserInputPtr inputStream;
+    xmlParserInputBufferPtr buf;
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+#ifdef LIBXML_SAX1_ENABLED
+	if (xmlDefaultSAXHandler.error != NULL) {
+	    xmlDefaultSAXHandler.error(NULL, "out of memory\n");
+	}
+#endif
+	return(NULL);
+    }
+
+    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    inputStream = xmlNewInputStream(ctxt);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
+    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];
+
+    inputPush(ctxt, inputStream);
+    if ((ctxt->directory == NULL) && (directory == NULL))
+        directory = xmlParserGetDirectory(filename);
+    if ((ctxt->directory == NULL) && (directory != NULL))
+        ctxt->directory = directory;
+    ctxt->valid = 0;
+    ctxt->validate = 0;
+    ctxt->loadsubset = 0;
+    ctxt->pedantic = 0;
+    ctxt->dictNames = 1;
+
+    xmlParseDocument(ctxt);
+
+    if (ctxt->wellFormed)
+	ret = ctxt->myDoc;
+    else {
+        ret = NULL;
+        xmlFreeDoc(ctxt->myDoc);
+        ctxt->myDoc = NULL;
+    }
+    xmlFreeParserCtxt(ctxt);
+    
+    return(ret);
+}
+
+/**
+ * xmlLoadFileContent:
+ * @filename:  a file path
+ *
+ * Load a file content into memory.
+ *
+ * Returns a pointer to the 0 terminated string or NULL in case of error
+ */
+static xmlChar *
+xmlLoadFileContent(const char *filename)
+{
+#ifdef HAVE_STAT
+    int fd;
+#else
+    FILE *fd;
+#endif
+    int len;
+    long size;
+
+#ifdef HAVE_STAT
+    struct stat info;
+#endif
+    xmlChar *content;
+
+    if (filename == NULL)
+        return (NULL);
+
+#ifdef HAVE_STAT
+    if (stat(filename, &info) < 0)
+        return (NULL);
+#endif
+
+#ifdef HAVE_STAT
+    if ((fd = open(filename, O_RDONLY)) < 0)
+#else
+    if ((fd = fopen(filename, "rb")) == NULL)
+#endif
+    {
+        return (NULL);
+    }
+#ifdef HAVE_STAT
+    size = info.st_size;
+#else
+    if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) {        /* File operations denied? ok, just close and return failure */
+        fclose(fd);
+        return (NULL);
+    }
+#endif
+    content = xmlMallocAtomic(size + 10);
+    if (content == NULL) {
+        xmlCatalogErrMemory("allocating catalog data");
+        return (NULL);
+    }
+#ifdef HAVE_STAT
+    len = read(fd, content, size);
+#else
+    len = fread(content, 1, size, fd);
+#endif
+    if (len < 0) {
+        xmlFree(content);
+        return (NULL);
+    }
+#ifdef HAVE_STAT
+    close(fd);
+#else
+    fclose(fd);
+#endif
+    content[len] = 0;
+
+    return(content);
+}
+
+/**
+ * xmlCatalogNormalizePublic:
+ * @pubID:  the public ID string
+ *
+ *  Normalizes the Public Identifier
+ *
+ * Implements 6.2. Public Identifier Normalization
+ * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Returns the new string or NULL, the string must be deallocated
+ *         by the caller.
+ */
+static xmlChar *
+xmlCatalogNormalizePublic(const xmlChar *pubID)
+{
+    int ok = 1;
+    int white;
+    const xmlChar *p;
+    xmlChar *ret;
+    xmlChar *q;
+
+    if (pubID == NULL)
+        return(NULL);
+
+    white = 1;
+    for (p = pubID;*p != 0 && ok;p++) {
+        if (!xmlIsBlank_ch(*p))
+            white = 0;
+        else if (*p == 0x20 && !white)
+            white = 1;
+        else
+            ok = 0;
+    }
+    if (ok && !white)	/* is normalized */
+        return(NULL);
+
+    ret = xmlStrdup(pubID);
+    q = ret;
+    white = 0;
+    for (p = pubID;*p != 0;p++) {
+        if (xmlIsBlank_ch(*p)) {
+            if (q != ret)
+                white = 1;
+        } else {
+            if (white) {
+                *(q++) = 0x20;
+                white = 0;
+            }
+            *(q++) = *p;
+        }
+    }
+    *q = 0;
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *			The XML Catalog parser				*
+ *									*
+ ************************************************************************/
+
+static xmlCatalogEntryPtr
+xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
+static void
+xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
+	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);
+static xmlChar *
+xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
+	              const xmlChar *sysID);
+static xmlChar *
+xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
+
+
+/**
+ * xmlGetXMLCatalogEntryType:
+ * @name:  the name
+ *
+ * lookup the internal type associated to an XML catalog entry name
+ *
+ * Returns the type associated with that name
+ */
+static xmlCatalogEntryType
+xmlGetXMLCatalogEntryType(const xmlChar *name) {
+    xmlCatalogEntryType type = XML_CATA_NONE;
+    if (xmlStrEqual(name, (const xmlChar *) "system"))
+	type = XML_CATA_SYSTEM;
+    else if (xmlStrEqual(name, (const xmlChar *) "public"))
+	type = XML_CATA_PUBLIC;
+    else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
+	type = XML_CATA_REWRITE_SYSTEM;
+    else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
+	type = XML_CATA_DELEGATE_PUBLIC;
+    else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
+	type = XML_CATA_DELEGATE_SYSTEM;
+    else if (xmlStrEqual(name, (const xmlChar *) "uri"))
+	type = XML_CATA_URI;
+    else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
+	type = XML_CATA_REWRITE_URI;
+    else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
+	type = XML_CATA_DELEGATE_URI;
+    else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
+	type = XML_CATA_NEXT_CATALOG;
+    else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
+	type = XML_CATA_CATALOG;
+    return(type);
+}
+
+/**
+ * xmlParseXMLCatalogOneNode:
+ * @cur:  the XML node
+ * @type:  the type of Catalog entry
+ * @name:  the name of the node
+ * @attrName:  the attribute holding the value
+ * @uriAttrName:  the attribute holding the URI-Reference
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ * @cgroup:  the group which includes this node
+ *
+ * Finishes the examination of an XML tree node of a catalog and build
+ * a Catalog entry from it.
+ *
+ * Returns the new Catalog entry node or NULL in case of error.
+ */
+static xmlCatalogEntryPtr
+xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
+			  const xmlChar *name, const xmlChar *attrName,
+			  const xmlChar *uriAttrName, xmlCatalogPrefer prefer,
+			  xmlCatalogEntryPtr cgroup) {
+    int ok = 1;
+    xmlChar *uriValue;
+    xmlChar *nameValue = NULL;
+    xmlChar *base = NULL;
+    xmlChar *URL = NULL;
+    xmlCatalogEntryPtr ret = NULL;
+
+    if (attrName != NULL) {
+	nameValue = xmlGetProp(cur, attrName);
+	if (nameValue == NULL) {
+	    xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
+			  "%s entry lacks '%s'\n", name, attrName, NULL);
+	    ok = 0;
+	}
+    }
+    uriValue = xmlGetProp(cur, uriAttrName);
+    if (uriValue == NULL) {
+	xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
+		"%s entry lacks '%s'\n", name, uriAttrName, NULL);
+	ok = 0;
+    }
+    if (!ok) {
+	if (nameValue != NULL)
+	    xmlFree(nameValue);
+	if (uriValue != NULL)
+	    xmlFree(uriValue);
+	return(NULL);
+    }
+
+    base = xmlNodeGetBase(cur->doc, cur);
+    URL = xmlBuildURI(uriValue, base);
+    if (URL != NULL) {
+	if (xmlDebugCatalogs > 1) {
+	    if (nameValue != NULL)
+		xmlGenericError(xmlGenericErrorContext,
+			"Found %s: '%s' '%s'\n", name, nameValue, URL);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+			"Found %s: '%s'\n", name, URL);
+	}
+	ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
+    } else {
+	xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,
+		"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
+    }
+    if (nameValue != NULL)
+	xmlFree(nameValue);
+    if (uriValue != NULL)
+	xmlFree(uriValue);
+    if (base != NULL)
+	xmlFree(base);
+    if (URL != NULL)
+	xmlFree(URL);
+    return(ret);
+}
+
+/**
+ * xmlParseXMLCatalogNode:
+ * @cur:  the XML node
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ * @parent:  the parent Catalog entry
+ * @cgroup:  the group which includes this node
+ *
+ * Examines an XML tree node of a catalog and build
+ * a Catalog entry from it adding it to its parent. The examination can
+ * be recursive.
+ */
+static void
+xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
+	               xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup)
+{
+    xmlChar *base = NULL;
+    xmlCatalogEntryPtr entry = NULL;
+
+    if (cur == NULL)
+        return;
+    if (xmlStrEqual(cur->name, BAD_CAST "group")) {
+        xmlChar *prop;
+	xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;
+
+        prop = xmlGetProp(cur, BAD_CAST "prefer");
+        if (prop != NULL) {
+            if (xmlStrEqual(prop, BAD_CAST "system")) {
+                prefer = XML_CATA_PREFER_SYSTEM;
+            } else if (xmlStrEqual(prop, BAD_CAST "public")) {
+                prefer = XML_CATA_PREFER_PUBLIC;
+            } else {
+		xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,
+                              "Invalid value for prefer: '%s'\n",
+			      prop, NULL, NULL);
+            }
+            xmlFree(prop);
+	    pref = prefer;
+        }
+	prop = xmlGetProp(cur, BAD_CAST "id");
+	base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+	entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);
+	xmlFree(prop);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
+		BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
+		BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
+		BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
+		BAD_CAST "rewritePrefix", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
+		BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
+		BAD_CAST "catalog", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
+		BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
+		BAD_CAST "catalog", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
+		BAD_CAST "uri", BAD_CAST "name",
+		BAD_CAST "uri", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
+		BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
+		BAD_CAST "rewritePrefix", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
+		BAD_CAST "delegateURI", BAD_CAST "uriStartString",
+		BAD_CAST "catalog", prefer, cgroup);
+    } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
+	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
+		BAD_CAST "nextCatalog", NULL,
+		BAD_CAST "catalog", prefer, cgroup);
+    }
+    if (entry != NULL) {
+        if (parent != NULL) {
+	    entry->parent = parent;
+	    if (parent->children == NULL)
+		parent->children = entry;
+	    else {
+		xmlCatalogEntryPtr prev;
+
+		prev = parent->children;
+		while (prev->next != NULL)
+		    prev = prev->next;
+		prev->next = entry;
+	    }
+	}
+	if (entry->type == XML_CATA_GROUP) {
+	    /*
+	     * Recurse to propagate prefer to the subtree
+	     * (xml:base handling is automated)
+	     */
+            xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);
+	}
+    }
+    if (base != NULL)
+	xmlFree(base);
+}
+
+/**
+ * xmlParseXMLCatalogNodeList:
+ * @cur:  the XML node list of siblings
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ * @parent:  the parent Catalog entry
+ * @cgroup:  the group which includes this list
+ *
+ * Examines a list of XML sibling nodes of a catalog and build
+ * a list of Catalog entry from it adding it to the parent.
+ * The examination will recurse to examine node subtrees.
+ */
+static void
+xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
+	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {
+    while (cur != NULL) {
+	if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
+	    (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
+	    xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);
+	}
+	cur = cur->next;
+    }
+    /* TODO: sort the list according to REWRITE lengths and prefer value */
+}
+
+/**
+ * xmlParseXMLCatalogFile:
+ * @prefer:  the PUBLIC vs. SYSTEM current preference value
+ * @filename:  the filename for the catalog
+ *
+ * Parses the catalog file to extract the XML tree and then analyze the
+ * tree to build a list of Catalog entries corresponding to this catalog
+ * 
+ * Returns the resulting Catalog entries list
+ */
+static xmlCatalogEntryPtr
+xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    xmlChar *prop;
+    xmlCatalogEntryPtr parent = NULL;
+
+    if (filename == NULL)
+        return(NULL);
+
+    doc = xmlParseCatalogFile((const char *) filename);
+    if (doc == NULL) {
+	if (xmlDebugCatalogs)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Failed to parse catalog %s\n", filename);
+	return(NULL);
+    }
+
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"%d Parsing catalog %s\n", xmlGetThreadId(), filename);
+
+    cur = xmlDocGetRootElement(doc);
+    if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
+	(cur->ns != NULL) && (cur->ns->href != NULL) &&
+	(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
+
+	parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
+				    (const xmlChar *)filename, NULL, prefer, NULL);
+        if (parent == NULL) {
+	    xmlFreeDoc(doc);
+	    return(NULL);
+	}
+
+	prop = xmlGetProp(cur, BAD_CAST "prefer");
+	if (prop != NULL) {
+	    if (xmlStrEqual(prop, BAD_CAST "system")) {
+		prefer = XML_CATA_PREFER_SYSTEM;
+	    } else if (xmlStrEqual(prop, BAD_CAST "public")) {
+		prefer = XML_CATA_PREFER_PUBLIC;
+	    } else {
+		xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,
+			      "Invalid value for prefer: '%s'\n",
+			      prop, NULL, NULL);
+	    }
+	    xmlFree(prop);
+	}
+	cur = cur->children;
+	xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);
+    } else {
+	xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,
+		      "File %s is not an XML Catalog\n",
+		      filename, NULL, NULL);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+    xmlFreeDoc(doc);
+    return(parent);
+}
+
+/**
+ * xmlFetchXMLCatalogFile:
+ * @catal:  an existing but incomplete catalog entry
+ *
+ * Fetch and parse the subcatalog referenced by an entry
+ * 
+ * Returns 0 in case of success, -1 otherwise
+ */
+static int
+xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
+    xmlCatalogEntryPtr doc;
+
+    if (catal == NULL) 
+	return(-1);
+    if (catal->URL == NULL)
+	return(-1);
+    if (catal->children != NULL)
+	return(-1);
+
+    /*
+     * lock the whole catalog for modification
+     */
+    xmlRMutexLock(xmlCatalogMutex);
+    if (catal->children != NULL) {
+	/* Okay someone else did it in the meantime */
+	xmlRMutexUnlock(xmlCatalogMutex);
+	return(0);
+    }
+
+    if (xmlCatalogXMLFiles != NULL) {
+	doc = (xmlCatalogEntryPtr)
+	    xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
+	if (doc != NULL) {
+	    if (xmlDebugCatalogs)
+		xmlGenericError(xmlGenericErrorContext,
+		    "Found %s in file hash\n", catal->URL);
+
+	    if (catal->type == XML_CATA_CATALOG)
+		catal->children = doc->children;
+	    else
+		catal->children = doc;
+	    catal->dealloc = 0;
+	    xmlRMutexUnlock(xmlCatalogMutex);
+	    return(0);
+	}
+	if (xmlDebugCatalogs)
+	    xmlGenericError(xmlGenericErrorContext,
+		"%s not found in file hash\n", catal->URL);
+    }
+
+    /*
+     * Fetch and parse. Note that xmlParseXMLCatalogFile does not
+     * use the existing catalog, there is no recursion allowed at
+     * that level.
+     */
+    doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
+    if (doc == NULL) {
+	catal->type = XML_CATA_BROKEN_CATALOG;
+	xmlRMutexUnlock(xmlCatalogMutex);
+	return(-1);
+    }
+
+    if (catal->type == XML_CATA_CATALOG)
+	catal->children = doc->children;
+    else
+	catal->children = doc;
+
+    doc->dealloc = 1;
+
+    if (xmlCatalogXMLFiles == NULL)
+	xmlCatalogXMLFiles = xmlHashCreate(10);
+    if (xmlCatalogXMLFiles != NULL) {
+	if (xmlDebugCatalogs)
+	    xmlGenericError(xmlGenericErrorContext,
+		"%s added to file hash\n", catal->URL);
+	xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
+    }
+    xmlRMutexUnlock(xmlCatalogMutex);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			XML Catalog handling				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlAddXMLCatalog:
+ * @catal:  top of an XML catalog
+ * @type:  the type of record to add to the catalog
+ * @orig:  the system, public or prefix to match (or NULL)
+ * @replace:  the replacement value for the match
+ *
+ * Add an entry in the XML catalog, it may overwrite existing but
+ * different entries.
+ *
+ * Returns 0 if successful, -1 otherwise
+ */
+static int
+xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
+	      const xmlChar *orig, const xmlChar *replace) {
+    xmlCatalogEntryPtr cur;
+    xmlCatalogEntryType typ;
+    int doregister = 0;
+
+    if ((catal == NULL) || 
+	((catal->type != XML_CATA_CATALOG) &&
+	 (catal->type != XML_CATA_BROKEN_CATALOG)))
+	return(-1);
+    if (catal->children == NULL) {
+	xmlFetchXMLCatalogFile(catal);
+    }
+    if (catal->children == NULL)
+	doregister = 1;
+
+    typ = xmlGetXMLCatalogEntryType(type);
+    if (typ == XML_CATA_NONE) {
+	if (xmlDebugCatalogs)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Failed to add unknown element %s to catalog\n", type);
+	return(-1);
+    }
+
+    cur = catal->children;
+    /*
+     * Might be a simple "update in place"
+     */
+    if (cur != NULL) {
+	while (cur != NULL) {
+	    if ((orig != NULL) && (cur->type == typ) &&
+		(xmlStrEqual(orig, cur->name))) {
+		if (xmlDebugCatalogs)
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Updating element %s to catalog\n", type);
+		if (cur->value != NULL)
+		    xmlFree(cur->value);
+		if (cur->URL != NULL)
+		    xmlFree(cur->URL);
+		cur->value = xmlStrdup(replace);
+		cur->URL = xmlStrdup(replace);
+		return(0);
+	    }
+	    if (cur->next == NULL)
+		break;
+	    cur = cur->next;
+	}
+    }
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Adding element %s to catalog\n", type);
+    if (cur == NULL)
+	catal->children = xmlNewCatalogEntry(typ, orig, replace,
+		                             NULL, catal->prefer, NULL);
+    else
+	cur->next = xmlNewCatalogEntry(typ, orig, replace,
+		                       NULL, catal->prefer, NULL);
+    if (doregister) {
+        catal->type = XML_CATA_CATALOG;
+	cur = xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
+	if (cur != NULL)
+	    cur->children = catal->children;
+    }
+
+    return(0);
+}
+
+/**
+ * xmlDelXMLCatalog:
+ * @catal:  top of an XML catalog
+ * @value:  the value to remove from the catalog
+ *
+ * Remove entries in the XML catalog where the value or the URI
+ * is equal to @value
+ *
+ * Returns the number of entries removed if successful, -1 otherwise
+ */
+static int
+xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
+    xmlCatalogEntryPtr cur;
+    int ret = 0;
+
+    if ((catal == NULL) || 
+	((catal->type != XML_CATA_CATALOG) &&
+	 (catal->type != XML_CATA_BROKEN_CATALOG)))
+	return(-1);
+    if (value == NULL)
+	return(-1);
+    if (catal->children == NULL) {
+	xmlFetchXMLCatalogFile(catal);
+    }
+
+    /*
+     * Scan the children
+     */
+    cur = catal->children;
+    while (cur != NULL) {
+	if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
+	    (xmlStrEqual(value, cur->value))) {
+	    if (xmlDebugCatalogs) {
+		if (cur->name != NULL)
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Removing element %s from catalog\n", cur->name);
+		else
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Removing element %s from catalog\n", cur->value);
+	    }
+	    cur->type = XML_CATA_REMOVED;
+	}
+	cur = cur->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlCatalogXMLResolve:
+ * @catal:  a catalog list
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier for a
+ * list of catalog entries.
+ *
+ * Implements (or tries to) 7.1. External Identifier Resolution
+ * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Returns the URI of the resource or NULL if not found
+ */
+static xmlChar *
+xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
+	              const xmlChar *sysID) {
+    xmlChar *ret = NULL;
+    xmlCatalogEntryPtr cur;
+    int haveDelegate = 0;
+    int haveNext = 0;
+
+    /*
+     * protection against loops
+     */
+    if (catal->depth > MAX_CATAL_DEPTH) {
+	xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
+		      "Detected recursion in catalog %s\n",
+		      catal->name, NULL, NULL);
+	return(NULL);
+    }
+    catal->depth++;
+
+    /*
+     * First tries steps 2/ 3/ 4/ if a system ID is provided.
+     */
+    if (sysID != NULL) {
+	xmlCatalogEntryPtr rewrite = NULL;
+	int lenrewrite = 0, len;
+	cur = catal;
+	haveDelegate = 0;
+	while (cur != NULL) {
+	    switch (cur->type) {
+		case XML_CATA_SYSTEM:
+		    if (xmlStrEqual(sysID, cur->name)) {
+			if (xmlDebugCatalogs)
+			    xmlGenericError(xmlGenericErrorContext,
+				    "Found system match %s, using %s\n",
+				            cur->name, cur->URL);
+			catal->depth--;
+			return(xmlStrdup(cur->URL));
+		    }
+		    break;
+		case XML_CATA_REWRITE_SYSTEM:
+		    len = xmlStrlen(cur->name);
+		    if ((len > lenrewrite) &&
+			(!xmlStrncmp(sysID, cur->name, len))) {
+			lenrewrite = len;
+			rewrite = cur;
+		    }
+		    break;
+		case XML_CATA_DELEGATE_SYSTEM:
+		    if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
+			haveDelegate++;
+		    break;
+		case XML_CATA_NEXT_CATALOG:
+		    haveNext++;
+		    break;
+		default:
+		    break;
+	    }
+	    cur = cur->next;
+	}
+	if (rewrite != NULL) {
+	    if (xmlDebugCatalogs)
+		xmlGenericError(xmlGenericErrorContext,
+			"Using rewriting rule %s\n", rewrite->name);
+	    ret = xmlStrdup(rewrite->URL);
+	    if (ret != NULL)
+		ret = xmlStrcat(ret, &sysID[lenrewrite]);
+	    catal->depth--;
+	    return(ret);
+	}
+	if (haveDelegate) {
+	    const xmlChar *delegates[MAX_DELEGATE];
+	    int nbList = 0, i;
+
+	    /*
+	     * Assume the entries have been sorted by decreasing substring
+	     * matches when the list was produced.
+	     */
+	    cur = catal;
+	    while (cur != NULL) {
+		if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
+		    (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
+		    for (i = 0;i < nbList;i++)
+			if (xmlStrEqual(cur->URL, delegates[i]))
+			    break;
+		    if (i < nbList) {
+			cur = cur->next;
+			continue;
+		    }
+		    if (nbList < MAX_DELEGATE)
+			delegates[nbList++] = cur->URL;
+
+		    if (cur->children == NULL) {
+			xmlFetchXMLCatalogFile(cur);
+		    }
+		    if (cur->children != NULL) {
+			if (xmlDebugCatalogs)
+			    xmlGenericError(xmlGenericErrorContext,
+				    "Trying system delegate %s\n", cur->URL);
+			ret = xmlCatalogListXMLResolve(
+				cur->children, NULL, sysID);
+			if (ret != NULL) {
+			    catal->depth--;
+			    return(ret);
+			}
+		    }
+		}
+		cur = cur->next;
+	    }
+	    /*
+	     * Apply the cut algorithm explained in 4/
+	     */
+	    catal->depth--;
+	    return(XML_CATAL_BREAK);
+	}
+    }
+    /*
+     * Then tries 5/ 6/ if a public ID is provided
+     */
+    if (pubID != NULL) {
+	cur = catal;
+	haveDelegate = 0;
+	while (cur != NULL) {
+	    switch (cur->type) {
+		case XML_CATA_PUBLIC:
+		    if (xmlStrEqual(pubID, cur->name)) {
+			if (xmlDebugCatalogs)
+			    xmlGenericError(xmlGenericErrorContext,
+				    "Found public match %s\n", cur->name);
+			catal->depth--;
+			return(xmlStrdup(cur->URL));
+		    }
+		    break;
+		case XML_CATA_DELEGATE_PUBLIC:
+		    if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
+			(cur->prefer == XML_CATA_PREFER_PUBLIC))
+			haveDelegate++;
+		    break;
+		case XML_CATA_NEXT_CATALOG:
+		    if (sysID == NULL)
+			haveNext++;
+		    break;
+		default:
+		    break;
+	    }
+	    cur = cur->next;
+	}
+	if (haveDelegate) {
+	    const xmlChar *delegates[MAX_DELEGATE];
+	    int nbList = 0, i;
+
+	    /*
+	     * Assume the entries have been sorted by decreasing substring
+	     * matches when the list was produced.
+	     */
+	    cur = catal;
+	    while (cur != NULL) {
+		if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
+		    (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
+		    (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
+
+		    for (i = 0;i < nbList;i++)
+			if (xmlStrEqual(cur->URL, delegates[i]))
+			    break;
+		    if (i < nbList) {
+			cur = cur->next;
+			continue;
+		    }
+		    if (nbList < MAX_DELEGATE)
+			delegates[nbList++] = cur->URL;
+			    
+		    if (cur->children == NULL) {
+			xmlFetchXMLCatalogFile(cur);
+		    }
+		    if (cur->children != NULL) {
+			if (xmlDebugCatalogs)
+			    xmlGenericError(xmlGenericErrorContext,
+				    "Trying public delegate %s\n", cur->URL);
+			ret = xmlCatalogListXMLResolve(
+				cur->children, pubID, NULL);
+			if (ret != NULL) {
+			    catal->depth--;
+			    return(ret);
+			}
+		    }
+		}
+		cur = cur->next;
+	    }
+	    /*
+	     * Apply the cut algorithm explained in 4/
+	     */
+	    catal->depth--;
+	    return(XML_CATAL_BREAK);
+	}
+    }
+    if (haveNext) {
+	cur = catal;
+	while (cur != NULL) {
+	    if (cur->type == XML_CATA_NEXT_CATALOG) {
+		if (cur->children == NULL) {
+		    xmlFetchXMLCatalogFile(cur);
+		}
+		if (cur->children != NULL) {
+		    ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
+		    if (ret != NULL) {
+			catal->depth--;
+			return(ret);
+		    } else if (catal->depth > MAX_CATAL_DEPTH) {
+		        return(NULL);
+		    }
+		}
+	    }
+	    cur = cur->next;
+	}
+    }
+
+    catal->depth--;
+    return(NULL);
+}
+
+/**
+ * xmlCatalogXMLResolveURI:
+ * @catal:  a catalog list
+ * @URI:  the URI
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier for a
+ * list of catalog entries.
+ *
+ * Implements (or tries to) 7.2.2. URI Resolution
+ * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Returns the URI of the resource or NULL if not found
+ */
+static xmlChar *
+xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
+    xmlChar *ret = NULL;
+    xmlCatalogEntryPtr cur;
+    int haveDelegate = 0;
+    int haveNext = 0;
+    xmlCatalogEntryPtr rewrite = NULL;
+    int lenrewrite = 0, len;
+
+    if (catal == NULL)
+	return(NULL);
+
+    if (URI == NULL)
+	return(NULL);
+
+    if (catal->depth > MAX_CATAL_DEPTH) {
+	xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
+		      "Detected recursion in catalog %s\n",
+		      catal->name, NULL, NULL);
+	return(NULL);
+    }
+
+    /*
+     * First tries steps 2/ 3/ 4/ if a system ID is provided.
+     */
+    cur = catal;
+    haveDelegate = 0;
+    while (cur != NULL) {
+	switch (cur->type) {
+	    case XML_CATA_URI:
+		if (xmlStrEqual(URI, cur->name)) {
+		    if (xmlDebugCatalogs)
+			xmlGenericError(xmlGenericErrorContext,
+				"Found URI match %s\n", cur->name);
+		    return(xmlStrdup(cur->URL));
+		}
+		break;
+	    case XML_CATA_REWRITE_URI:
+		len = xmlStrlen(cur->name);
+		if ((len > lenrewrite) &&
+		    (!xmlStrncmp(URI, cur->name, len))) {
+		    lenrewrite = len;
+		    rewrite = cur;
+		}
+		break;
+	    case XML_CATA_DELEGATE_URI:
+		if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
+		    haveDelegate++;
+		break;
+	    case XML_CATA_NEXT_CATALOG:
+		haveNext++;
+		break;
+	    default:
+		break;
+	}
+	cur = cur->next;
+    }
+    if (rewrite != NULL) {
+	if (xmlDebugCatalogs)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Using rewriting rule %s\n", rewrite->name);
+	ret = xmlStrdup(rewrite->URL);
+	if (ret != NULL)
+	    ret = xmlStrcat(ret, &URI[lenrewrite]);
+	return(ret);
+    }
+    if (haveDelegate) {
+	const xmlChar *delegates[MAX_DELEGATE];
+	int nbList = 0, i;
+
+	/*
+	 * Assume the entries have been sorted by decreasing substring
+	 * matches when the list was produced.
+	 */
+	cur = catal;
+	while (cur != NULL) {
+	    if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
+	         (cur->type == XML_CATA_DELEGATE_URI)) &&
+		(!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
+		for (i = 0;i < nbList;i++)
+		    if (xmlStrEqual(cur->URL, delegates[i]))
+			break;
+		if (i < nbList) {
+		    cur = cur->next;
+		    continue;
+		}
+		if (nbList < MAX_DELEGATE)
+		    delegates[nbList++] = cur->URL;
+
+		if (cur->children == NULL) {
+		    xmlFetchXMLCatalogFile(cur);
+		}
+		if (cur->children != NULL) {
+		    if (xmlDebugCatalogs)
+			xmlGenericError(xmlGenericErrorContext,
+				"Trying URI delegate %s\n", cur->URL);
+		    ret = xmlCatalogListXMLResolveURI(
+			    cur->children, URI);
+		    if (ret != NULL)
+			return(ret);
+		}
+	    }
+	    cur = cur->next;
+	}
+	/*
+	 * Apply the cut algorithm explained in 4/
+	 */
+	return(XML_CATAL_BREAK);
+    }
+    if (haveNext) {
+	cur = catal;
+	while (cur != NULL) {
+	    if (cur->type == XML_CATA_NEXT_CATALOG) {
+		if (cur->children == NULL) {
+		    xmlFetchXMLCatalogFile(cur);
+		}
+		if (cur->children != NULL) {
+		    ret = xmlCatalogListXMLResolveURI(cur->children, URI);
+		    if (ret != NULL)
+			return(ret);
+		}
+	    }
+	    cur = cur->next;
+	}
+    }
+
+    return(NULL);
+}
+
+/**
+ * xmlCatalogListXMLResolve:
+ * @catal:  a catalog list
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier for a
+ * list of catalogs
+ *
+ * Implements (or tries to) 7.1. External Identifier Resolution
+ * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Returns the URI of the resource or NULL if not found
+ */
+static xmlChar *
+xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
+	              const xmlChar *sysID) {
+    xmlChar *ret = NULL;
+    xmlChar *urnID = NULL;
+    xmlChar *normid;
+    
+    if (catal == NULL)
+        return(NULL);
+    if ((pubID == NULL) && (sysID == NULL))
+	return(NULL);
+
+    normid = xmlCatalogNormalizePublic(pubID);
+    if (normid != NULL)
+        pubID = (*normid != 0 ? normid : NULL);
+    
+    if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
+	urnID = xmlCatalogUnWrapURN(pubID);
+	if (xmlDebugCatalogs) {
+	    if (urnID == NULL)
+		xmlGenericError(xmlGenericErrorContext,
+			"Public URN ID %s expanded to NULL\n", pubID);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+			"Public URN ID expanded to %s\n", urnID);
+	}
+	ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
+	if (urnID != NULL)
+	    xmlFree(urnID);
+	if (normid != NULL)
+	    xmlFree(normid);
+	return(ret);
+    }
+    if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
+	urnID = xmlCatalogUnWrapURN(sysID);
+	if (xmlDebugCatalogs) {
+	    if (urnID == NULL)
+		xmlGenericError(xmlGenericErrorContext,
+			"System URN ID %s expanded to NULL\n", sysID);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+			"System URN ID expanded to %s\n", urnID);
+	}
+	if (pubID == NULL)
+	    ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
+	else if (xmlStrEqual(pubID, urnID))
+	    ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
+	else {
+	    ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
+	}
+	if (urnID != NULL)
+	    xmlFree(urnID);
+	if (normid != NULL)
+	    xmlFree(normid);
+	return(ret);
+    }
+    while (catal != NULL) {
+	if (catal->type == XML_CATA_CATALOG) {
+	    if (catal->children == NULL) {
+		xmlFetchXMLCatalogFile(catal);
+	    }
+	    if (catal->children != NULL) {
+		ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
+		if (ret != NULL) {
+		    break;
+                } else if ((catal->children != NULL) &&
+		           (catal->children->depth > MAX_CATAL_DEPTH)) {
+	            ret = NULL;
+		    break;
+	        }
+	    }
+	}
+	catal = catal->next;
+    }
+    if (normid != NULL)
+	xmlFree(normid);
+    return(ret);
+}
+
+/**
+ * xmlCatalogListXMLResolveURI:
+ * @catal:  a catalog list
+ * @URI:  the URI
+ *
+ * Do a complete resolution lookup of an URI for a list of catalogs
+ *
+ * Implements (or tries to) 7.2. URI Resolution
+ * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Returns the URI of the resource or NULL if not found
+ */
+static xmlChar *
+xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
+    xmlChar *ret = NULL;
+    xmlChar *urnID = NULL;
+    
+    if (catal == NULL)
+        return(NULL);
+    if (URI == NULL)
+	return(NULL);
+
+    if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
+	urnID = xmlCatalogUnWrapURN(URI);
+	if (xmlDebugCatalogs) {
+	    if (urnID == NULL)
+		xmlGenericError(xmlGenericErrorContext,
+			"URN ID %s expanded to NULL\n", URI);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+			"URN ID expanded to %s\n", urnID);
+	}
+	ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
+	if (urnID != NULL)
+	    xmlFree(urnID);
+	return(ret);
+    }
+    while (catal != NULL) {
+	if (catal->type == XML_CATA_CATALOG) {
+	    if (catal->children == NULL) {
+		xmlFetchXMLCatalogFile(catal);
+	    }
+	    if (catal->children != NULL) {
+		ret = xmlCatalogXMLResolveURI(catal->children, URI);
+		if (ret != NULL)
+		    return(ret);
+	    }
+	}
+	catal = catal->next;
+    }
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *			The SGML Catalog parser				*
+ *									*
+ ************************************************************************/
+
+
+#define RAW *cur
+#define NEXT cur++;
+#define SKIP(x) cur += x;
+
+#define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
+
+/**
+ * xmlParseSGMLCatalogComment:
+ * @cur:  the current character
+ *
+ * Skip a comment in an SGML catalog
+ *
+ * Returns new current character
+ */
+static const xmlChar *
+xmlParseSGMLCatalogComment(const xmlChar *cur) {
+    if ((cur[0] != '-') || (cur[1] != '-')) 
+	return(cur);
+    SKIP(2);
+    while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
+	NEXT;
+    if (cur[0] == 0) {
+	return(NULL);
+    }
+    return(cur + 2);
+}
+
+/**
+ * xmlParseSGMLCatalogPubid:
+ * @cur:  the current character
+ * @id:  the return location
+ *
+ * Parse an SGML catalog ID
+ *
+ * Returns new current character and store the value in @id
+ */
+static const xmlChar *
+xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
+    xmlChar *buf = NULL, *tmp;
+    int len = 0;
+    int size = 50;
+    xmlChar stop;
+    int count = 0;
+
+    *id = NULL;
+
+    if (RAW == '"') {
+        NEXT;
+	stop = '"';
+    } else if (RAW == '\'') {
+        NEXT;
+	stop = '\'';
+    } else {
+	stop = ' ';
+    }
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+        xmlCatalogErrMemory("allocating public ID");
+	return(NULL);
+    }
+    while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
+	if ((*cur == stop) && (stop != ' '))
+	    break;
+	if ((stop == ' ') && (IS_BLANK_CH(*cur)))
+	    break;
+	if (len + 1 >= size) {
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+		xmlCatalogErrMemory("allocating public ID");
+		xmlFree(buf);
+		return(NULL);
+	    }
+	    buf = tmp;
+	}
+	buf[len++] = *cur;
+	count++;
+	NEXT;
+    }
+    buf[len] = 0;
+    if (stop == ' ') {
+	if (!IS_BLANK_CH(*cur)) {
+	    xmlFree(buf);
+	    return(NULL);
+	}
+    } else {
+	if (*cur != stop) {
+	    xmlFree(buf);
+	    return(NULL);
+	}
+	NEXT;
+    }
+    *id = buf;
+    return(cur);
+}
+
+/**
+ * xmlParseSGMLCatalogName:
+ * @cur:  the current character
+ * @name:  the return location
+ *
+ * Parse an SGML catalog name
+ *
+ * Returns new current character and store the value in @name
+ */
+static const xmlChar *
+xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
+    xmlChar buf[XML_MAX_NAMELEN + 5];
+    int len = 0;
+    int c;
+
+    *name = NULL;
+
+    /*
+     * Handler for more complex cases
+     */
+    c = *cur;
+    if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
+	return(NULL);
+    }
+
+    while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || (c == ':'))) {
+	buf[len++] = c;
+	cur++;
+	c = *cur;
+	if (len >= XML_MAX_NAMELEN)
+	    return(NULL);
+    }
+    *name = xmlStrndup(buf, len);
+    return(cur);
+}
+
+/**
+ * xmlGetSGMLCatalogEntryType:
+ * @name:  the entry name
+ *
+ * Get the Catalog entry type for a given SGML Catalog name
+ *
+ * Returns Catalog entry type
+ */
+static xmlCatalogEntryType
+xmlGetSGMLCatalogEntryType(const xmlChar *name) {
+    xmlCatalogEntryType type = XML_CATA_NONE;
+    if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
+	type = SGML_CATA_SYSTEM;
+    else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
+	type = SGML_CATA_PUBLIC;
+    else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
+	type = SGML_CATA_DELEGATE;
+    else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
+	type = SGML_CATA_ENTITY;
+    else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
+	type = SGML_CATA_DOCTYPE;
+    else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
+	type = SGML_CATA_LINKTYPE;
+    else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
+	type = SGML_CATA_NOTATION;
+    else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
+	type = SGML_CATA_SGMLDECL;
+    else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
+	type = SGML_CATA_DOCUMENT;
+    else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
+	type = SGML_CATA_CATALOG;
+    else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
+	type = SGML_CATA_BASE;
+    return(type);
+}
+
+/**
+ * xmlParseSGMLCatalog:
+ * @catal:  the SGML Catalog
+ * @value:  the content of the SGML Catalog serialization
+ * @file:  the filepath for the catalog
+ * @super:  should this be handled as a Super Catalog in which case
+ *          parsing is not recursive
+ *
+ * Parse an SGML catalog content and fill up the @catal hash table with
+ * the new entries found.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+static int
+xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
+	            const char *file, int super) {
+    const xmlChar *cur = value;
+    xmlChar *base = NULL;
+    int res;
+
+    if ((cur == NULL) || (file == NULL))
+        return(-1);
+    base = xmlStrdup((const xmlChar *) file);
+
+    while ((cur != NULL) && (cur[0] != 0)) {
+	SKIP_BLANKS;
+	if (cur[0] == 0)
+	    break;
+	if ((cur[0] == '-') && (cur[1] == '-')) {
+	    cur = xmlParseSGMLCatalogComment(cur);
+	    if (cur == NULL) {
+		/* error */
+		break;
+	    }
+	} else {
+	    xmlChar *sysid = NULL;
+	    xmlChar *name = NULL;
+	    xmlCatalogEntryType type = XML_CATA_NONE;
+
+	    cur = xmlParseSGMLCatalogName(cur, &name);
+	    if (name == NULL) {
+		/* error */
+		break;
+	    }
+	    if (!IS_BLANK_CH(*cur)) {
+		/* error */
+		break;
+	    }
+	    SKIP_BLANKS;
+	    if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
+                type = SGML_CATA_SYSTEM;
+	    else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
+                type = SGML_CATA_PUBLIC;
+	    else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
+                type = SGML_CATA_DELEGATE;
+	    else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
+                type = SGML_CATA_ENTITY;
+	    else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
+                type = SGML_CATA_DOCTYPE;
+	    else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
+                type = SGML_CATA_LINKTYPE;
+	    else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
+                type = SGML_CATA_NOTATION;
+	    else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
+                type = SGML_CATA_SGMLDECL;
+	    else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
+                type = SGML_CATA_DOCUMENT;
+	    else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
+                type = SGML_CATA_CATALOG;
+	    else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
+                type = SGML_CATA_BASE;
+	    else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
+		xmlFree(name);
+		cur = xmlParseSGMLCatalogName(cur, &name);
+		if (name == NULL) {
+		    /* error */
+		    break;
+		}
+		xmlFree(name);
+		continue;
+	    }
+	    xmlFree(name);
+	    name = NULL;
+
+	    switch(type) {
+		case SGML_CATA_ENTITY:
+		    if (*cur == '%')
+			type = SGML_CATA_PENTITY;
+		case SGML_CATA_PENTITY:
+		case SGML_CATA_DOCTYPE:
+		case SGML_CATA_LINKTYPE:
+		case SGML_CATA_NOTATION:
+		    cur = xmlParseSGMLCatalogName(cur, &name);
+		    if (cur == NULL) {
+			/* error */
+			break;
+		    }
+		    if (!IS_BLANK_CH(*cur)) {
+			/* error */
+			break;
+		    }
+		    SKIP_BLANKS;
+		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
+		    if (cur == NULL) {
+			/* error */
+			break;
+		    }
+		    break;
+		case SGML_CATA_PUBLIC:
+		case SGML_CATA_SYSTEM:
+		case SGML_CATA_DELEGATE:
+		    cur = xmlParseSGMLCatalogPubid(cur, &name);
+		    if (cur == NULL) {
+			/* error */
+			break;
+		    }
+		    if (type != SGML_CATA_SYSTEM) {
+		        xmlChar *normid;
+
+		        normid = xmlCatalogNormalizePublic(name);
+		        if (normid != NULL) {
+		            if (name != NULL)
+		                xmlFree(name);
+		            if (*normid != 0)
+		                name = normid;
+		            else {
+		                xmlFree(normid);
+		                name = NULL;
+		            }
+		        }
+		    }
+		    if (!IS_BLANK_CH(*cur)) {
+			/* error */
+			break;
+		    }
+		    SKIP_BLANKS;
+		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
+		    if (cur == NULL) {
+			/* error */
+			break;
+		    }
+		    break;
+		case SGML_CATA_BASE:
+		case SGML_CATA_CATALOG:
+		case SGML_CATA_DOCUMENT:
+		case SGML_CATA_SGMLDECL:
+		    cur = xmlParseSGMLCatalogPubid(cur, &sysid);
+		    if (cur == NULL) {
+			/* error */
+			break;
+		    }
+		    break;
+		default:
+		    break;
+	    }
+	    if (cur == NULL) {
+		if (name != NULL)
+		    xmlFree(name);
+		if (sysid != NULL)
+		    xmlFree(sysid);
+		break;
+	    } else if (type == SGML_CATA_BASE) {
+		if (base != NULL)
+		    xmlFree(base);
+		base = xmlStrdup(sysid);
+	    } else if ((type == SGML_CATA_PUBLIC) ||
+		       (type == SGML_CATA_SYSTEM)) {
+		xmlChar *filename;
+
+		filename = xmlBuildURI(sysid, base);
+		if (filename != NULL) {
+		    xmlCatalogEntryPtr entry;
+
+		    entry = xmlNewCatalogEntry(type, name, filename,
+			                       NULL, XML_CATA_PREFER_NONE, NULL);
+		    res = xmlHashAddEntry(catal->sgml, name, entry);
+		    if (res < 0) {
+			xmlFreeCatalogEntry(entry);
+		    }
+		    xmlFree(filename);
+		}
+
+	    } else if (type == SGML_CATA_CATALOG) {
+		if (super) {
+		    xmlCatalogEntryPtr entry;
+
+		    entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
+			                       XML_CATA_PREFER_NONE, NULL);
+		    res = xmlHashAddEntry(catal->sgml, sysid, entry);
+		    if (res < 0) {
+			xmlFreeCatalogEntry(entry);
+		    }
+		} else {
+		    xmlChar *filename;
+
+		    filename = xmlBuildURI(sysid, base);
+		    if (filename != NULL) {
+			xmlExpandCatalog(catal, (const char *)filename);
+			xmlFree(filename);
+		    }
+		}
+	    }
+	    /*
+	     * drop anything else we won't handle it
+	     */
+	    if (name != NULL)
+		xmlFree(name);
+	    if (sysid != NULL)
+		xmlFree(sysid);
+	}
+    }
+    if (base != NULL)
+	xmlFree(base);
+    if (cur == NULL)
+	return(-1);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			SGML Catalog handling				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogGetSGMLPublic:
+ * @catal:  an SGML catalog hash
+ * @pubID:  the public ID string
+ *
+ * Try to lookup the catalog local reference associated to a public ID
+ *
+ * Returns the local resource if found or NULL otherwise.
+ */
+static const xmlChar *
+xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
+    xmlCatalogEntryPtr entry;
+    xmlChar *normid;
+
+    if (catal == NULL)
+	return(NULL);
+
+    normid = xmlCatalogNormalizePublic(pubID);
+    if (normid != NULL)
+        pubID = (*normid != 0 ? normid : NULL);
+
+    entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
+    if (entry == NULL) {
+	if (normid != NULL)
+	    xmlFree(normid);
+	return(NULL);
+    }
+    if (entry->type == SGML_CATA_PUBLIC) {
+	if (normid != NULL)
+	    xmlFree(normid);
+	return(entry->URL);
+    }
+    if (normid != NULL)
+        xmlFree(normid);
+    return(NULL);
+}
+
+/**
+ * xmlCatalogGetSGMLSystem:
+ * @catal:  an SGML catalog hash
+ * @sysID:  the system ID string
+ *
+ * Try to lookup the catalog local reference for a system ID
+ *
+ * Returns the local resource if found or NULL otherwise.
+ */
+static const xmlChar *
+xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
+    xmlCatalogEntryPtr entry;
+
+    if (catal == NULL)
+	return(NULL);
+
+    entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
+    if (entry == NULL)
+	return(NULL);
+    if (entry->type == SGML_CATA_SYSTEM)
+	return(entry->URL);
+    return(NULL);
+}
+
+/**
+ * xmlCatalogSGMLResolve:
+ * @catal:  the SGML catalog
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier
+ *
+ * Returns the URI of the resource or NULL if not found
+ */
+static const xmlChar *
+xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
+	              const xmlChar *sysID) {
+    const xmlChar *ret = NULL;
+
+    if (catal->sgml == NULL)
+	return(NULL);
+
+    if (pubID != NULL)
+	ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
+    if (ret != NULL)
+	return(ret);
+    if (sysID != NULL)
+	ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
+    if (ret != NULL)
+	return(ret);
+    return(NULL);
+}
+
+/************************************************************************
+ *									*
+ *			Specific Public interfaces			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlLoadSGMLSuperCatalog:
+ * @filename:  a file path
+ *
+ * Load an SGML super catalog. It won't expand CATALOG or DELEGATE
+ * references. This is only needed for manipulating SGML Super Catalogs
+ * like adding and removing CATALOG or DELEGATE entries.
+ *
+ * Returns the catalog parsed or NULL in case of error
+ */
+xmlCatalogPtr
+xmlLoadSGMLSuperCatalog(const char *filename)
+{
+    xmlChar *content;
+    xmlCatalogPtr catal;
+    int ret;
+
+    content = xmlLoadFileContent(filename);
+    if (content == NULL)
+        return(NULL);
+
+    catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+    if (catal == NULL) {
+	xmlFree(content);
+	return(NULL);
+    }
+
+    ret = xmlParseSGMLCatalog(catal, content, filename, 1);
+    xmlFree(content);
+    if (ret < 0) {
+	xmlFreeCatalog(catal);
+	return(NULL);
+    }
+    return (catal);
+}
+
+/**
+ * xmlLoadACatalog:
+ * @filename:  a file path
+ *
+ * Load the catalog and build the associated data structures.
+ * This can be either an XML Catalog or an SGML Catalog
+ * It will recurse in SGML CATALOG entries. On the other hand XML
+ * Catalogs are not handled recursively.
+ *
+ * Returns the catalog parsed or NULL in case of error
+ */
+xmlCatalogPtr
+xmlLoadACatalog(const char *filename)
+{
+    xmlChar *content;
+    xmlChar *first;
+    xmlCatalogPtr catal;
+    int ret;
+
+    content = xmlLoadFileContent(filename);
+    if (content == NULL)
+        return(NULL);
+
+
+    first = content;
+   
+    while ((*first != 0) && (*first != '-') && (*first != '<') &&
+	   (!(((*first >= 'A') && (*first <= 'Z')) ||
+	      ((*first >= 'a') && (*first <= 'z')))))
+	first++;
+
+    if (*first != '<') {
+	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+	if (catal == NULL) {
+	    xmlFree(content);
+	    return(NULL);
+	}
+        ret = xmlParseSGMLCatalog(catal, content, filename, 0);
+	if (ret < 0) {
+	    xmlFreeCatalog(catal);
+	    xmlFree(content);
+	    return(NULL);
+	}
+    } else {
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
+	if (catal == NULL) {
+	    xmlFree(content);
+	    return(NULL);
+	}
+        catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
+		       NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
+    }
+    xmlFree(content);
+    return (catal);
+}
+
+/**
+ * xmlExpandCatalog:
+ * @catal:  a catalog
+ * @filename:  a file path
+ *
+ * Load the catalog and expand the existing catal structure.
+ * This can be either an XML Catalog or an SGML Catalog
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+static int
+xmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
+{
+    int ret;
+
+    if ((catal == NULL) || (filename == NULL))
+	return(-1);
+
+
+    if (catal->type == XML_SGML_CATALOG_TYPE) {
+	xmlChar *content;
+
+	content = xmlLoadFileContent(filename);
+	if (content == NULL)
+	    return(-1);
+
+        ret = xmlParseSGMLCatalog(catal, content, filename, 0);
+	if (ret < 0) {
+	    xmlFree(content);
+	    return(-1);
+	}
+	xmlFree(content);
+    } else {
+	xmlCatalogEntryPtr tmp, cur;
+	tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
+		       NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
+
+	cur = catal->xml;
+	if (cur == NULL) {
+	    catal->xml = tmp;
+	} else {
+	    while (cur->next != NULL) cur = cur->next;
+	    cur->next = tmp;
+	}
+    }
+    return (0);
+}
+
+/**
+ * xmlACatalogResolveSystem:
+ * @catal:  a Catalog
+ * @sysID:  the system ID string
+ *
+ * Try to lookup the catalog resource for a system ID
+ *
+ * Returns the resource if found or NULL otherwise, the value returned
+ *      must be freed by the caller.
+ */
+xmlChar *
+xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
+    xmlChar *ret = NULL;
+
+    if ((sysID == NULL) || (catal == NULL))
+	return(NULL);
+    
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Resolve sysID %s\n", sysID);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
+	if (ret == XML_CATAL_BREAK)
+	    ret = NULL;
+    } else {
+	const xmlChar *sgml;
+
+	sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
+	if (sgml != NULL)
+	    ret = xmlStrdup(sgml);
+    }
+    return(ret);
+}
+
+/**
+ * xmlACatalogResolvePublic:
+ * @catal:  a Catalog
+ * @pubID:  the public ID string
+ *
+ * Try to lookup the catalog local reference associated to a public ID in that catalog
+ *
+ * Returns the local resource if found or NULL otherwise, the value returned
+ *      must be freed by the caller.
+ */
+xmlChar *
+xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
+    xmlChar *ret = NULL;
+
+    if ((pubID == NULL) || (catal == NULL))
+	return(NULL);
+    
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Resolve pubID %s\n", pubID);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
+	if (ret == XML_CATAL_BREAK)
+	    ret = NULL;
+    } else {
+	const xmlChar *sgml;
+
+	sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
+	if (sgml != NULL)
+	    ret = xmlStrdup(sgml);
+    }
+    return(ret);
+}
+
+/**
+ * xmlACatalogResolve:
+ * @catal:  a Catalog
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
+                   const xmlChar * sysID)
+{
+    xmlChar *ret = NULL;
+
+    if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
+        return (NULL);
+
+    if (xmlDebugCatalogs) {
+         if ((pubID != NULL) && (sysID != NULL)) {
+             xmlGenericError(xmlGenericErrorContext,
+                             "Resolve: pubID %s sysID %s\n", pubID, sysID);
+         } else if (pubID != NULL) {
+             xmlGenericError(xmlGenericErrorContext,
+                             "Resolve: pubID %s\n", pubID);
+         } else {
+             xmlGenericError(xmlGenericErrorContext,
+                             "Resolve: sysID %s\n", sysID);
+         }
+    }
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+        ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
+	if (ret == XML_CATAL_BREAK)
+	    ret = NULL;
+    } else {
+        const xmlChar *sgml;
+
+        sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
+        if (sgml != NULL)
+            ret = xmlStrdup(sgml);
+    }
+    return (ret);
+}
+
+/**
+ * xmlACatalogResolveURI:
+ * @catal:  a Catalog
+ * @URI:  the URI
+ *
+ * Do a complete resolution lookup of an URI
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
+    xmlChar *ret = NULL;
+
+    if ((URI == NULL) || (catal == NULL))
+	return(NULL);
+
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Resolve URI %s\n", URI);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
+	if (ret == XML_CATAL_BREAK)
+	    ret = NULL;
+    } else {
+	const xmlChar *sgml;
+
+	sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
+	if (sgml != NULL)
+            ret = xmlStrdup(sgml);
+    }
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlACatalogDump:
+ * @catal:  a Catalog
+ * @out:  the file.
+ *
+ * Dump the given catalog to the given file.
+ */
+void
+xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
+    if ((out == NULL) || (catal == NULL))
+	return;
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	xmlDumpXMLCatalog(out, catal->xml);
+    } else {
+	xmlHashScan(catal->sgml,
+		    (xmlHashScanner) xmlCatalogDumpEntry, out);
+    } 
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlACatalogAdd:
+ * @catal:  a Catalog
+ * @type:  the type of record to add to the catalog
+ * @orig:  the system, public or prefix to match 
+ * @replace:  the replacement value for the match
+ *
+ * Add an entry in the catalog, it may overwrite existing but
+ * different entries.
+ *
+ * Returns 0 if successful, -1 otherwise
+ */
+int
+xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
+              const xmlChar * orig, const xmlChar * replace)
+{
+    int res = -1;
+
+    if (catal == NULL)
+	return(-1);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+        res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
+    } else {
+        xmlCatalogEntryType cattype;
+
+        cattype = xmlGetSGMLCatalogEntryType(type);
+        if (cattype != XML_CATA_NONE) {
+            xmlCatalogEntryPtr entry;
+
+            entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
+                                       XML_CATA_PREFER_NONE, NULL);
+	    if (catal->sgml == NULL)
+		catal->sgml = xmlHashCreate(10);
+            res = xmlHashAddEntry(catal->sgml, orig, entry);
+        }
+    }
+    return (res);
+}
+
+/**
+ * xmlACatalogRemove:
+ * @catal:  a Catalog
+ * @value:  the value to remove
+ *
+ * Remove an entry from the catalog
+ *
+ * Returns the number of entries removed if successful, -1 otherwise
+ */
+int
+xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
+    int res = -1;
+
+    if ((catal == NULL) || (value == NULL))
+	return(-1);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	res = xmlDelXMLCatalog(catal->xml, value);
+    } else {
+	res = xmlHashRemoveEntry(catal->sgml, value,
+		(xmlHashDeallocator) xmlFreeCatalogEntry);
+	if (res == 0)
+	    res = 1;
+    } 
+    return(res);
+}
+
+/**
+ * xmlNewCatalog:
+ * @sgml:  should this create an SGML catalog
+ *
+ * create a new Catalog.
+ *
+ * Returns the xmlCatalogPtr or NULL in case of error
+ */
+xmlCatalogPtr
+xmlNewCatalog(int sgml) {
+    xmlCatalogPtr catal = NULL;
+
+    if (sgml) {
+	catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
+		                    xmlCatalogDefaultPrefer);
+        if ((catal != NULL) && (catal->sgml == NULL))
+	    catal->sgml = xmlHashCreate(10);
+    } else
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
+		                    xmlCatalogDefaultPrefer);
+    return(catal);
+}
+
+/**
+ * xmlCatalogIsEmpty:
+ * @catal:  should this create an SGML catalog
+ *
+ * Check is a catalog is empty
+ *
+ * Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
+ */
+int
+xmlCatalogIsEmpty(xmlCatalogPtr catal) {
+    if (catal == NULL)
+	return(-1);
+
+    if (catal->type == XML_XML_CATALOG_TYPE) {
+	if (catal->xml == NULL)
+	    return(1);
+	if ((catal->xml->type != XML_CATA_CATALOG) &&
+	    (catal->xml->type != XML_CATA_BROKEN_CATALOG))
+	    return(-1);
+	if (catal->xml->children == NULL)
+	    return(1);
+        return(0);
+    } else {
+	int res;
+
+	if (catal->sgml == NULL)
+	    return(1);
+	res = xmlHashSize(catal->sgml);
+	if (res == 0)
+	    return(1);
+	if (res < 0)
+	    return(-1);
+    } 
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *   Public interfaces manipulating the global shared default catalog	*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlInitializeCatalogData:
+ *
+ * Do the catalog initialization only of global data, doesn't try to load
+ * any catalog actually.
+ * this function is not thread safe, catalog initialization should
+ * preferably be done once at startup
+ */
+static void
+xmlInitializeCatalogData(void) {
+    if (xmlCatalogInitialized != 0)
+	return;
+
+    if (getenv("XML_DEBUG_CATALOG")) 
+	xmlDebugCatalogs = 1;
+    xmlCatalogMutex = xmlNewRMutex();
+
+    xmlCatalogInitialized = 1;
+}
+/**
+ * xmlInitializeCatalog:
+ *
+ * Do the catalog initialization.
+ * this function is not thread safe, catalog initialization should
+ * preferably be done once at startup
+ */
+void
+xmlInitializeCatalog(void) {
+    if (xmlCatalogInitialized != 0)
+	return;
+
+    xmlInitializeCatalogData();
+    xmlRMutexLock(xmlCatalogMutex);
+
+    if (getenv("XML_DEBUG_CATALOG")) 
+	xmlDebugCatalogs = 1;
+
+    if (xmlDefaultCatalog == NULL) {
+	const char *catalogs;
+	char *path;
+	const char *cur, *paths;
+	xmlCatalogPtr catal;
+	xmlCatalogEntryPtr *nextent;
+
+	catalogs = (const char *) getenv("XML_CATALOG_FILES");
+	if (catalogs == NULL)
+#if defined(_WIN32) && defined(_MSC_VER)
+    {
+		void* hmodule;
+		hmodule = GetModuleHandleA("libxml2.dll");
+		if (hmodule == NULL)
+			hmodule = GetModuleHandleA(NULL);
+		if (hmodule != NULL) {
+			char buf[256];
+			unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
+			if (len != 0) {
+				char* p = &(buf[len]);
+				while (*p != '\\' && p > buf) 
+					p--;
+				if (p != buf) {
+					xmlChar* uri;
+					strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
+					uri = xmlCanonicPath(buf);
+					if (uri != NULL) {
+						strncpy(XML_XML_DEFAULT_CATALOG, uri, 255);
+						xmlFree(uri);
+					}
+				}
+			}
+		}
+		catalogs = XML_XML_DEFAULT_CATALOG;
+    }
+#else
+	    catalogs = XML_XML_DEFAULT_CATALOG;
+#endif
+
+	catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, 
+		xmlCatalogDefaultPrefer);
+	if (catal != NULL) {
+	    /* the XML_CATALOG_FILES envvar is allowed to contain a 
+	       space-separated list of entries. */
+	    cur = catalogs;
+	    nextent = &catal->xml;
+	    while (*cur != '\0') {
+		while (xmlIsBlank_ch(*cur)) 
+		    cur++;
+		if (*cur != 0) {
+		    paths = cur;
+		    while ((*cur != 0) && (!xmlIsBlank_ch(*cur)))
+			cur++;
+		    path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
+		    if (path != NULL) {
+			*nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
+				NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL);
+			if (*nextent != NULL)
+			    nextent = &((*nextent)->next);
+			xmlFree(path);
+		    }
+		}
+	    }
+	    xmlDefaultCatalog = catal;
+	}
+    }
+
+    xmlRMutexUnlock(xmlCatalogMutex);
+}
+
+
+/**
+ * xmlLoadCatalog:
+ * @filename:  a file path
+ *
+ * Load the catalog and makes its definitions effective for the default
+ * external entity loader. It will recurse in SGML CATALOG entries.
+ * this function is not thread safe, catalog initialization should
+ * preferably be done once at startup
+ *
+ * Returns 0 in case of success -1 in case of error
+ */
+int
+xmlLoadCatalog(const char *filename)
+{
+    int ret;
+    xmlCatalogPtr catal;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalogData();
+
+    xmlRMutexLock(xmlCatalogMutex);
+
+    if (xmlDefaultCatalog == NULL) {
+	catal = xmlLoadACatalog(filename);
+	if (catal == NULL) {
+	    xmlRMutexUnlock(xmlCatalogMutex);
+	    return(-1);
+	}
+
+	xmlDefaultCatalog = catal;
+	xmlRMutexUnlock(xmlCatalogMutex);
+	return(0);
+    }
+
+    ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
+    xmlRMutexUnlock(xmlCatalogMutex);
+    return(ret);
+}
+
+/**
+ * xmlLoadCatalogs:
+ * @pathss:  a list of directories separated by a colon or a space.
+ *
+ * Load the catalogs and makes their definitions effective for the default
+ * external entity loader.
+ * this function is not thread safe, catalog initialization should
+ * preferably be done once at startup
+ */
+void
+xmlLoadCatalogs(const char *pathss) {
+    const char *cur;
+    const char *paths;
+    xmlChar *path;
+#ifdef _WIN32
+    int i, iLen;
+#endif
+
+    if (pathss == NULL)
+	return;
+
+    cur = pathss;
+    while (*cur != 0) {
+	while (xmlIsBlank_ch(*cur)) cur++;
+	if (*cur != 0) {
+	    paths = cur;
+	    while ((*cur != 0) && (*cur != PATH_SEAPARATOR) && (!xmlIsBlank_ch(*cur)))
+		cur++;
+	    path = xmlStrndup((const xmlChar *)paths, cur - paths);
+#ifdef _WIN32
+        iLen = strlen(path);
+        for(i = 0; i < iLen; i++) {
+            if(path[i] == '\\') {
+                path[i] = '/';
+            }
+        }
+#endif
+	    if (path != NULL) {
+		xmlLoadCatalog((const char *) path);
+		xmlFree(path);
+	    }
+	}
+	while (*cur == PATH_SEAPARATOR)
+	    cur++;
+    }
+}
+
+/**
+ * xmlCatalogCleanup:
+ *
+ * Free up all the memory associated with catalogs
+ */
+void
+xmlCatalogCleanup(void) {
+    if (xmlCatalogInitialized == 0)
+        return;
+
+    xmlRMutexLock(xmlCatalogMutex);
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Catalogs cleanup\n");
+    if (xmlCatalogXMLFiles != NULL)
+	xmlHashFree(xmlCatalogXMLFiles, 
+		    (xmlHashDeallocator)xmlFreeCatalogHashEntryList);
+    xmlCatalogXMLFiles = NULL;
+    if (xmlDefaultCatalog != NULL)
+	xmlFreeCatalog(xmlDefaultCatalog);
+    xmlDefaultCatalog = NULL;
+    xmlDebugCatalogs = 0;
+    xmlCatalogInitialized = 0;
+    xmlRMutexUnlock(xmlCatalogMutex);
+    xmlFreeRMutex(xmlCatalogMutex);
+}
+
+/**
+ * xmlCatalogResolveSystem:
+ * @sysID:  the system ID string
+ *
+ * Try to lookup the catalog resource for a system ID
+ *
+ * Returns the resource if found or NULL otherwise, the value returned
+ *      must be freed by the caller.
+ */
+xmlChar *
+xmlCatalogResolveSystem(const xmlChar *sysID) {
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
+    return(ret);
+}
+
+/**
+ * xmlCatalogResolvePublic:
+ * @pubID:  the public ID string
+ *
+ * Try to lookup the catalog reference associated to a public ID
+ *
+ * Returns the resource if found or NULL otherwise, the value returned
+ *      must be freed by the caller.
+ */
+xmlChar *
+xmlCatalogResolvePublic(const xmlChar *pubID) {
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
+    return(ret);
+}
+
+/**
+ * xmlCatalogResolve:
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
+    return(ret);
+}
+
+/**
+ * xmlCatalogResolveURI:
+ * @URI:  the URI
+ *
+ * Do a complete resolution lookup of an URI
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlCatalogResolveURI(const xmlChar *URI) {
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlCatalogDump:
+ * @out:  the file.
+ *
+ * Dump all the global catalog content to the given file.
+ */
+void
+xmlCatalogDump(FILE *out) {
+    if (out == NULL)
+	return;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    xmlACatalogDump(xmlDefaultCatalog, out);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlCatalogAdd:
+ * @type:  the type of record to add to the catalog
+ * @orig:  the system, public or prefix to match 
+ * @replace:  the replacement value for the match
+ *
+ * Add an entry in the catalog, it may overwrite existing but
+ * different entries.
+ * If called before any other catalog routine, allows to override the
+ * default shared catalog put in place by xmlInitializeCatalog();
+ *
+ * Returns 0 if successful, -1 otherwise
+ */
+int
+xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
+    int res = -1;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalogData();
+
+    xmlRMutexLock(xmlCatalogMutex);
+    /*
+     * Specific case where one want to override the default catalog
+     * put in place by xmlInitializeCatalog();
+     */
+    if ((xmlDefaultCatalog == NULL) &&
+	(xmlStrEqual(type, BAD_CAST "catalog"))) {
+	xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
+		                          xmlCatalogDefaultPrefer);
+	xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
+				    orig, NULL,  xmlCatalogDefaultPrefer, NULL);
+
+	xmlRMutexUnlock(xmlCatalogMutex);
+	return(0);
+    } 
+
+    res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
+    xmlRMutexUnlock(xmlCatalogMutex);
+    return(res);
+}
+
+/**
+ * xmlCatalogRemove:
+ * @value:  the value to remove
+ *
+ * Remove an entry from the catalog
+ *
+ * Returns the number of entries removed if successful, -1 otherwise
+ */
+int
+xmlCatalogRemove(const xmlChar *value) {
+    int res;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    xmlRMutexLock(xmlCatalogMutex);
+    res = xmlACatalogRemove(xmlDefaultCatalog, value);
+    xmlRMutexUnlock(xmlCatalogMutex);
+    return(res);
+}
+
+/**
+ * xmlCatalogConvert:
+ *
+ * Convert all the SGML catalog entries as XML ones
+ *
+ * Returns the number of entries converted if successful, -1 otherwise
+ */
+int
+xmlCatalogConvert(void) {
+    int res = -1;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    xmlRMutexLock(xmlCatalogMutex);
+    res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
+    xmlRMutexUnlock(xmlCatalogMutex);
+    return(res);
+}
+
+/************************************************************************
+ *									*
+ *	Public interface manipulating the common preferences		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogGetDefaults:
+ *
+ * Used to get the user preference w.r.t. to what catalogs should
+ * be accepted
+ *
+ * Returns the current xmlCatalogAllow value
+ */
+xmlCatalogAllow
+xmlCatalogGetDefaults(void) {
+    return(xmlCatalogDefaultAllow);
+}
+
+/**
+ * xmlCatalogSetDefaults:
+ * @allow:  what catalogs should be accepted
+ *
+ * Used to set the user preference w.r.t. to what catalogs should
+ * be accepted
+ */
+void
+xmlCatalogSetDefaults(xmlCatalogAllow allow) {
+    if (xmlDebugCatalogs) {
+	switch (allow) {
+	    case XML_CATA_ALLOW_NONE:
+		xmlGenericError(xmlGenericErrorContext,
+			"Disabling catalog usage\n");
+		break;
+	    case XML_CATA_ALLOW_GLOBAL:
+		xmlGenericError(xmlGenericErrorContext,
+			"Allowing only global catalogs\n");
+		break;
+	    case XML_CATA_ALLOW_DOCUMENT:
+		xmlGenericError(xmlGenericErrorContext,
+			"Allowing only catalogs from the document\n");
+		break;
+	    case XML_CATA_ALLOW_ALL:
+		xmlGenericError(xmlGenericErrorContext,
+			"Allowing all catalogs\n");
+		break;
+	}
+    }
+    xmlCatalogDefaultAllow = allow;
+}
+
+/**
+ * xmlCatalogSetDefaultPrefer:
+ * @prefer:  the default preference for delegation
+ *
+ * Allows to set the preference between public and system for deletion
+ * in XML Catalog resolution. C.f. section 4.1.1 of the spec
+ * Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
+ *
+ * Returns the previous value of the default preference for delegation
+ */
+xmlCatalogPrefer
+xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
+    xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
+
+    if (prefer == XML_CATA_PREFER_NONE)
+	return(ret);
+
+    if (xmlDebugCatalogs) {
+	switch (prefer) {
+	    case XML_CATA_PREFER_PUBLIC:
+		xmlGenericError(xmlGenericErrorContext,
+			"Setting catalog preference to PUBLIC\n");
+		break;
+	    case XML_CATA_PREFER_SYSTEM:
+		xmlGenericError(xmlGenericErrorContext,
+			"Setting catalog preference to SYSTEM\n");
+		break;
+	    case XML_CATA_PREFER_NONE:
+		break;
+	}
+    }
+    xmlCatalogDefaultPrefer = prefer;
+    return(ret);
+}
+
+/**
+ * xmlCatalogSetDebug:
+ * @level:  the debug level of catalogs required
+ *
+ * Used to set the debug level for catalog operation, 0 disable
+ * debugging, 1 enable it
+ *
+ * Returns the previous value of the catalog debugging level
+ */
+int
+xmlCatalogSetDebug(int level) {
+    int ret = xmlDebugCatalogs;
+
+    if (level <= 0)
+        xmlDebugCatalogs = 0;
+    else
+	xmlDebugCatalogs = level;
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *   Minimal interfaces used for per-document catalogs by the parser	*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCatalogFreeLocal:
+ * @catalogs:  a document's list of catalogs
+ *
+ * Free up the memory associated to the catalog list
+ */
+void
+xmlCatalogFreeLocal(void *catalogs) {
+    xmlCatalogEntryPtr catal;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    catal = (xmlCatalogEntryPtr) catalogs;
+    if (catal != NULL)
+	xmlFreeCatalogEntryList(catal);
+}
+
+
+/**
+ * xmlCatalogAddLocal:
+ * @catalogs:  a document's list of catalogs
+ * @URL:  the URL to a new local catalog
+ *
+ * Add the new entry to the catalog list
+ *
+ * Returns the updated list
+ */
+void *	
+xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
+    xmlCatalogEntryPtr catal, add;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    if (URL == NULL)
+	return(catalogs);
+
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Adding document catalog %s\n", URL);
+
+    add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
+	                     xmlCatalogDefaultPrefer, NULL);
+    if (add == NULL)
+	return(catalogs);
+
+    catal = (xmlCatalogEntryPtr) catalogs;
+    if (catal == NULL) 
+	return((void *) add);
+
+    while (catal->next != NULL)
+	catal = catal->next;
+    catal->next = add;
+    return(catalogs);
+}
+
+/**
+ * xmlCatalogLocalResolve:
+ * @catalogs:  a document's list of catalogs
+ * @pubID:  the public ID string
+ * @sysID:  the system ID string
+ *
+ * Do a complete resolution lookup of an External Identifier using a 
+ * document's private catalog list
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
+	               const xmlChar *sysID) {
+    xmlCatalogEntryPtr catal;
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    if ((pubID == NULL) && (sysID == NULL))
+	return(NULL);
+
+    if (xmlDebugCatalogs) {
+        if ((pubID != NULL) && (sysID != NULL)) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "Local Resolve: pubID %s sysID %s\n", pubID, sysID);
+        } else if (pubID != NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "Local Resolve: pubID %s\n", pubID);
+        } else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "Local Resolve: sysID %s\n", sysID);
+        }
+    }
+
+    catal = (xmlCatalogEntryPtr) catalogs;
+    if (catal == NULL)
+	return(NULL);
+    ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
+    if ((ret != NULL) && (ret != XML_CATAL_BREAK))
+	return(ret);
+    return(NULL);
+}
+
+/**
+ * xmlCatalogLocalResolveURI:
+ * @catalogs:  a document's list of catalogs
+ * @URI:  the URI
+ *
+ * Do a complete resolution lookup of an URI using a 
+ * document's private catalog list
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ *      by the caller.
+ */
+xmlChar *
+xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
+    xmlCatalogEntryPtr catal;
+    xmlChar *ret;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    if (URI == NULL)
+	return(NULL);
+
+    if (xmlDebugCatalogs)
+	xmlGenericError(xmlGenericErrorContext,
+		"Resolve URI %s\n", URI);
+
+    catal = (xmlCatalogEntryPtr) catalogs;
+    if (catal == NULL)
+	return(NULL);
+    ret = xmlCatalogListXMLResolveURI(catal, URI);
+    if ((ret != NULL) && (ret != XML_CATAL_BREAK))
+	return(ret);
+    return(NULL);
+}
+
+/************************************************************************
+ *									*
+ *			Deprecated interfaces				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlCatalogGetSystem:
+ * @sysID:  the system ID string
+ *
+ * Try to lookup the catalog reference associated to a system ID
+ * DEPRECATED, use xmlCatalogResolveSystem()
+ *
+ * Returns the resource if found or NULL otherwise.
+ */
+const xmlChar *
+xmlCatalogGetSystem(const xmlChar *sysID) {
+    xmlChar *ret;
+    static xmlChar result[1000];
+    static int msg = 0;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    if (msg == 0) {
+	xmlGenericError(xmlGenericErrorContext,
+		"Use of deprecated xmlCatalogGetSystem() call\n");
+	msg++;
+    }
+
+    if (sysID == NULL)
+	return(NULL);
+    
+    /*
+     * Check first the XML catalogs
+     */
+    if (xmlDefaultCatalog != NULL) {
+	ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
+	if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
+	    snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
+	    result[sizeof(result) - 1] = 0;
+	    return(result);
+	}
+    }
+
+    if (xmlDefaultCatalog != NULL)
+	return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
+    return(NULL);
+}
+
+/**
+ * xmlCatalogGetPublic:
+ * @pubID:  the public ID string
+ *
+ * Try to lookup the catalog reference associated to a public ID
+ * DEPRECATED, use xmlCatalogResolvePublic()
+ *
+ * Returns the resource if found or NULL otherwise.
+ */
+const xmlChar *
+xmlCatalogGetPublic(const xmlChar *pubID) {
+    xmlChar *ret;
+    static xmlChar result[1000];
+    static int msg = 0;
+
+    if (!xmlCatalogInitialized)
+	xmlInitializeCatalog();
+
+    if (msg == 0) {
+	xmlGenericError(xmlGenericErrorContext,
+		"Use of deprecated xmlCatalogGetPublic() call\n");
+	msg++;
+    }
+
+    if (pubID == NULL)
+	return(NULL);
+    
+    /*
+     * Check first the XML catalogs
+     */
+    if (xmlDefaultCatalog != NULL) {
+	ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
+	if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
+	    snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
+	    result[sizeof(result) - 1] = 0;
+	    return(result);
+	}
+    }
+
+    if (xmlDefaultCatalog != NULL)
+	return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
+    return(NULL);
+}
+
+#define bottom_catalog
+#include "elfgcchack.h"
+#endif /* LIBXML_CATALOG_ENABLED */
diff --git a/src/check-relaxng-test-suite.py b/src/check-relaxng-test-suite.py
new file mode 100755
index 0000000..2427b02
--- /dev/null
+++ b/src/check-relaxng-test-suite.py
@@ -0,0 +1,395 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import os
+import string
+import io
+sys.path.insert(0, "python")
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+debug = 0
+verbose = 0
+quiet = 1
+
+#
+# the testsuite description
+#
+CONF=os.path.join(os.path.dirname(__file__), "test/relaxng/OASIS/spectest.xml")
+LOG="check-relaxng-test-suite.log"
+RES="relaxng-test-results.xml"
+
+log = open(LOG, "w")
+nb_schemas_tests = 0
+nb_schemas_success = 0
+nb_schemas_failed = 0
+nb_instances_tests = 0
+nb_instances_success = 0
+nb_instances_failed = 0
+
+libxml2.lineNumbersDefault(1)
+#
+# Error and warnng callbacks
+#
+def callback(ctx, str):
+    global log
+    log.write("%s%s" % (ctx, str))
+
+libxml2.registerErrorHandler(callback, "")
+
+#
+# Resolver callback
+#
+resources = {}
+def resolver(URL, ID, ctxt):
+    global resources
+
+    if string.find(URL, '#') != -1:
+        URL = URL[0:string.find(URL, '#')]
+    if URL in resources:
+        return(io.StringIO(resources[URL]))
+    log.write("Resolver failure: asked %s\n" % (URL))
+    log.write("resources: %s\n" % (resources))
+    return None
+
+#
+# Load the previous results
+#
+#results = {}
+#previous = {}
+#
+#try:
+#    res = libxml2.parseFile(RES)
+#except:
+#    log.write("Could not parse %s" % (RES))
+    
+#
+# handle a valid instance
+#
+def handle_valid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nFailed to parse correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+	return
+
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+    except:
+        ret = -1
+    if ret != 0:
+        log.write("\nFailed to validate correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+    doc.freeDoc()
+
+#
+# handle an invalid instance
+#
+def handle_invalid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	return
+
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+    except:
+        ret = -1
+    if ret == 0:
+        log.write("\nFailed to detect validation problem in instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+    doc.freeDoc()
+
+#
+# handle an incorrect test
+#
+def handle_correct(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs == None:
+        log.write("\nFailed to compile correct schema:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+	nb_schemas_success = nb_schemas_success + 1
+    return rngs
+        
+def handle_incorrect(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs != None:
+        log.write("\nFailed to detect schema error in:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+#	log.write("\nSuccess detecting schema error in:\n-----\n")
+#	log.write(schema)
+#	log.write("\n-----\n")
+	nb_schemas_success = nb_schemas_success + 1
+    return None
+
+#
+# resource handling: keep a dictionary of URL->string mappings
+#
+def handle_resource(node, dir):
+    global resources
+
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    res = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    res = res + child.serialize()
+	child = child.__next__
+    resources[name] = res
+
+#
+# dir handling: pseudo directory resources
+#
+def handle_dir(node, dir):
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, name)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, name)
+
+#
+# handle a testCase element
+#
+def handle_testCase(node):
+    global nb_schemas_tests
+    global nb_instances_tests
+    global resources
+
+    sections = node.xpathEval('string(section)')
+    log.write("\n    ======== test %d line %d section %s ==========\n" % (
+
+              nb_schemas_tests, node.lineNo(), sections))
+    resources = {}
+    if debug:
+        print("test %d line %d" % (nb_schemas_tests, node.lineNo()))
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, None)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, None)
+
+    tsts = node.xpathEval('incorrect')
+    if tsts != []:
+        if len(tsts) != 1:
+	    print("warning test line %d has more than one <incorrect> example" %(node.lineNo()))
+	schema = handle_incorrect(tsts[0])
+    else:
+        tsts = node.xpathEval('correct')
+	if tsts != []:
+	    if len(tsts) != 1:
+		print("warning test line %d has more than one <correct> example"% (node.lineNo()))
+	    schema = handle_correct(tsts[0])
+	else:
+	    print("warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo()))
+
+    nb_schemas_tests = nb_schemas_tests + 1;
+    
+    valids = node.xpathEval('valid')
+    invalids = node.xpathEval('invalid')
+    nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
+    if schema != None:
+        for valid in valids:
+	    handle_valid(valid, schema)
+        for invalid in invalids:
+	    handle_invalid(invalid, schema)
+
+
+#
+# handle a testSuite element
+#
+def handle_testSuite(node, level = 0):
+    global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
+    global nb_instances_tests, nb_instances_success, nb_instances_failed
+    global quiet
+    if level >= 1:
+	old_schemas_tests = nb_schemas_tests
+	old_schemas_success = nb_schemas_success
+	old_schemas_failed = nb_schemas_failed
+	old_instances_tests = nb_instances_tests
+	old_instances_success = nb_instances_success
+	old_instances_failed = nb_instances_failed
+
+    docs = node.xpathEval('documentation')
+    authors = node.xpathEval('author')
+    if docs != []:
+        msg = ""
+        for doc in docs:
+	    msg = msg + doc.content + " "
+	if authors != []:
+	    msg = msg + "written by "
+	    for author in authors:
+	        msg = msg + author.content + " "
+	if quiet == 0:
+	    print(msg)
+    sections = node.xpathEval('section')
+    if sections != [] and level <= 0:
+        msg = ""
+        for section in sections:
+	    msg = msg + section.content + " "
+	if quiet == 0:
+	    print("Tests for section %s" % (msg))
+    for test in node.xpathEval('testCase'):
+        handle_testCase(test)
+    for test in node.xpathEval('testSuite'):
+        handle_testSuite(test, level + 1)
+	        
+
+    if verbose and level >= 1 and sections != []:
+        msg = ""
+        for section in sections:
+	    msg = msg + section.content + " "
+        print("Result of tests for section %s" % (msg))
+        if nb_schemas_tests != old_schemas_tests:
+	    print("found %d test schemas: %d success %d failures" % (
+		  nb_schemas_tests - old_schemas_tests,
+		  nb_schemas_success - old_schemas_success,
+		  nb_schemas_failed - old_schemas_failed))
+	if nb_instances_tests != old_instances_tests:
+	    print("found %d test instances: %d success %d failures" % (
+		  nb_instances_tests - old_instances_tests,
+		  nb_instances_success - old_instances_success,
+		  nb_instances_failed - old_instances_failed))
+#
+# Parse the conf file
+#
+libxml2.substituteEntitiesDefault(1);
+testsuite = libxml2.parseFile(CONF)
+libxml2.setEntityLoader(resolver)
+root = testsuite.getRootElement()
+if root.name != 'testSuite':
+    print("%s doesn't start with a testSuite element, aborting" % (CONF))
+    sys.exit(1)
+if quiet == 0:
+    print("Running Relax NG testsuite")
+handle_testSuite(root)
+
+if quiet == 0:
+    print("\nTOTAL:\n")
+if quiet == 0 or nb_schemas_failed != 0:
+    print("found %d test schemas: %d success %d failures" % (
+      nb_schemas_tests, nb_schemas_success, nb_schemas_failed))
+if quiet == 0 or nb_instances_failed != 0:
+    print("found %d test instances: %d success %d failures" % (
+      nb_instances_tests, nb_instances_success, nb_instances_failed))
+
+testsuite.freeDoc()
+
+# Memory debug specific
+libxml2.relaxNGCleanupTypes()
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    if quiet == 0:
+	print("OK")
+else:
+    print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+    libxml2.dumpMemory()
diff --git a/src/check-relaxng-test-suite2.py b/src/check-relaxng-test-suite2.py
new file mode 100755
index 0000000..094e88d
--- /dev/null
+++ b/src/check-relaxng-test-suite2.py
@@ -0,0 +1,419 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import os
+import string
+import io
+sys.path.insert(0, "python")
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+debug = 0
+quiet = 1
+
+#
+# the testsuite description
+#
+CONF=os.path.join(os.path.dirname(__file__), "test/relaxng/testsuite.xml")
+LOG="check-relaxng-test-suite2.log"
+
+log = open(LOG, "w")
+nb_schemas_tests = 0
+nb_schemas_success = 0
+nb_schemas_failed = 0
+nb_instances_tests = 0
+nb_instances_success = 0
+nb_instances_failed = 0
+
+libxml2.lineNumbersDefault(1)
+#
+# Resolver callback
+#
+resources = {}
+def resolver(URL, ID, ctxt):
+    global resources
+
+    if URL in resources:
+        return(io.StringIO(resources[URL]))
+    log.write("Resolver failure: asked %s\n" % (URL))
+    log.write("resources: %s\n" % (resources))
+    return None
+
+#
+# Load the previous results
+#
+#results = {}
+#previous = {}
+#
+#try:
+#    res = libxml2.parseFile(RES)
+#except:
+#    log.write("Could not parse %s" % (RES))
+    
+#
+# handle a valid instance
+#
+def handle_valid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = node.prop("dtd")
+    if instance == None:
+        instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+#    mem = libxml2.debugMemory(1);
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nFailed to parse correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+	return
+
+    if debug:
+        print("instance line %d" % (node.lineNo()))
+       
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+	del ctxt
+    except:
+        ret = -1
+
+    doc.freeDoc()
+#    if mem != libxml2.debugMemory(1):
+#	print "validating instance %d line %d leaks" % (
+#		  nb_instances_tests, node.lineNo())
+
+    if ret != 0:
+        log.write("\nFailed to validate correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+
+#
+# handle an invalid instance
+#
+def handle_invalid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = node.prop("dtd")
+    if instance == None:
+        instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+#    mem = libxml2.debugMemory(1);
+
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	return
+
+    if debug:
+        print("instance line %d" % (node.lineNo()))
+       
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+	del ctxt
+
+    except:
+        ret = -1
+
+    doc.freeDoc()
+#    mem2 = libxml2.debugMemory(1)
+#    if mem != mem2:
+#	print "validating instance %d line %d leaks %d bytes" % (
+#		  nb_instances_tests, node.lineNo(), mem2 - mem)
+    
+    if ret == 0:
+        log.write("\nFailed to detect validation problem in instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+
+#
+# handle an incorrect test
+#
+def handle_correct(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs == None:
+        log.write("\nFailed to compile correct schema:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+	nb_schemas_success = nb_schemas_success + 1
+    return rngs
+        
+def handle_incorrect(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs != None:
+        log.write("\nFailed to detect schema error in:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+#	log.write("\nSuccess detecting schema error in:\n-----\n")
+#	log.write(schema)
+#	log.write("\n-----\n")
+	nb_schemas_success = nb_schemas_success + 1
+    return None
+
+#
+# resource handling: keep a dictionary of URL->string mappings
+#
+def handle_resource(node, dir):
+    global resources
+
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    res = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    res = res + child.serialize()
+	child = child.__next__
+    resources[name] = res
+
+#
+# dir handling: pseudo directory resources
+#
+def handle_dir(node, dir):
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, name)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, name)
+
+#
+# handle a testCase element
+#
+def handle_testCase(node):
+    global nb_schemas_tests
+    global nb_instances_tests
+    global resources
+
+    sections = node.xpathEval('string(section)')
+    log.write("\n    ======== test %d line %d section %s ==========\n" % (
+
+              nb_schemas_tests, node.lineNo(), sections))
+    resources = {}
+    if debug:
+        print("test %d line %d" % (nb_schemas_tests, node.lineNo()))
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, None)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, None)
+
+    tsts = node.xpathEval('incorrect')
+    if tsts != []:
+        if len(tsts) != 1:
+	    print("warning test line %d has more than one <incorrect> example" %(node.lineNo()))
+	schema = handle_incorrect(tsts[0])
+    else:
+        tsts = node.xpathEval('correct')
+	if tsts != []:
+	    if len(tsts) != 1:
+		print("warning test line %d has more than one <correct> example"% (node.lineNo()))
+	    schema = handle_correct(tsts[0])
+	else:
+	    print("warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo()))
+
+    nb_schemas_tests = nb_schemas_tests + 1;
+    
+    valids = node.xpathEval('valid')
+    invalids = node.xpathEval('invalid')
+    nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
+    if schema != None:
+        for valid in valids:
+	    handle_valid(valid, schema)
+        for invalid in invalids:
+	    handle_invalid(invalid, schema)
+
+
+#
+# handle a testSuite element
+#
+def handle_testSuite(node, level = 0):
+    global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
+    global nb_instances_tests, nb_instances_success, nb_instances_failed
+    if level >= 1:
+	old_schemas_tests = nb_schemas_tests
+	old_schemas_success = nb_schemas_success
+	old_schemas_failed = nb_schemas_failed
+	old_instances_tests = nb_instances_tests
+	old_instances_success = nb_instances_success
+	old_instances_failed = nb_instances_failed
+
+    docs = node.xpathEval('documentation')
+    authors = node.xpathEval('author')
+    if docs != []:
+        msg = ""
+        for doc in docs:
+	    msg = msg + doc.content + " "
+	if authors != []:
+	    msg = msg + "written by "
+	    for author in authors:
+	        msg = msg + author.content + " "
+	if quiet == 0:
+	    print(msg)
+    sections = node.xpathEval('section')
+    if sections != [] and level <= 0:
+        msg = ""
+        for section in sections:
+	    msg = msg + section.content + " "
+	if quiet == 0:
+	    print("Tests for section %s" % (msg))
+    for test in node.xpathEval('testCase'):
+        handle_testCase(test)
+    for test in node.xpathEval('testSuite'):
+        handle_testSuite(test, level + 1)
+	        
+
+    if level >= 1 and sections != []:
+        msg = ""
+        for section in sections:
+	    msg = msg + section.content + " "
+        print("Result of tests for section %s" % (msg))
+        if nb_schemas_tests != old_schemas_tests:
+	    print("found %d test schemas: %d success %d failures" % (
+		  nb_schemas_tests - old_schemas_tests,
+		  nb_schemas_success - old_schemas_success,
+		  nb_schemas_failed - old_schemas_failed))
+	if nb_instances_tests != old_instances_tests:
+	    print("found %d test instances: %d success %d failures" % (
+		  nb_instances_tests - old_instances_tests,
+		  nb_instances_success - old_instances_success,
+		  nb_instances_failed - old_instances_failed))
+#
+# Parse the conf file
+#
+libxml2.substituteEntitiesDefault(1);
+testsuite = libxml2.parseFile(CONF)
+
+#
+# Error and warnng callbacks
+#
+def callback(ctx, str):
+    global log
+    log.write("%s%s" % (ctx, str))
+
+libxml2.registerErrorHandler(callback, "")
+
+libxml2.setEntityLoader(resolver)
+root = testsuite.getRootElement()
+if root.name != 'testSuite':
+    print("%s doesn't start with a testSuite element, aborting" % (CONF))
+    sys.exit(1)
+if quiet == 0:
+    print("Running Relax NG testsuite")
+handle_testSuite(root)
+
+if quiet == 0:
+    print("\nTOTAL:\n")
+if quiet == 0 or nb_schemas_failed != 0:
+    print("found %d test schemas: %d success %d failures" % (
+      nb_schemas_tests, nb_schemas_success, nb_schemas_failed))
+if quiet == 0 or nb_instances_failed != 0:
+    print("found %d test instances: %d success %d failures" % (
+      nb_instances_tests, nb_instances_success, nb_instances_failed))
+
+
+testsuite.freeDoc()
+
+# Memory debug specific
+libxml2.relaxNGCleanupTypes()
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    if quiet == 0:
+	print("OK")
+else:
+    print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+    libxml2.dumpMemory()
diff --git a/src/check-xinclude-test-suite.py b/src/check-xinclude-test-suite.py
new file mode 100755
index 0000000..b88e490
--- /dev/null
+++ b/src/check-xinclude-test-suite.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import os
+import string
+sys.path.insert(0, "python")
+import libxml2
+
+#
+# the testsuite description
+#
+DIR="xinclude-test-suite"
+CONF="testdescr.xml"
+LOG="check-xinclude-test-suite.log"
+
+log = open(LOG, "w")
+
+os.chdir(DIR)
+
+test_nr = 0
+test_succeed = 0
+test_failed = 0
+test_error = 0
+#
+# Error and warning handlers
+#
+error_nr = 0
+error_msg = ''
+
+def errorHandler(ctx, str):
+    global error_nr
+    global error_msg
+
+    if string.find(str, "error:") >= 0:
+	error_nr = error_nr + 1
+    if len(error_msg) < 300:
+        if len(error_msg) == 0 or error_msg[-1] == '\n':
+	    error_msg = error_msg + "   >>" + str
+	else:
+	    error_msg = error_msg + str
+
+libxml2.registerErrorHandler(errorHandler, None)
+
+def testXInclude(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    print("testXInclude(%s, %s)" % (filename, id))
+    return 1
+
+def runTest(test, basedir):
+    global test_nr
+    global test_failed
+    global test_error
+    global test_succeed
+    global error_msg
+    global log
+
+    fatal_error = 0
+    uri = test.prop('href')
+    id = test.prop('id')
+    type = test.prop('type')
+    if uri == None:
+        print("Test without ID:", uri)
+	return -1
+    if id == None:
+        print("Test without URI:", id)
+	return -1
+    if type == None:
+        print("Test without URI:", id)
+	return -1
+    if basedir != None:
+	URI = basedir + "/" + uri
+    else:
+        URI = uri
+    if os.access(URI, os.R_OK) == 0:
+        print("Test %s missing: base %s uri %s" % (URI, basedir, uri))
+	return -1
+
+    expected = None
+    outputfile = None
+    diff = None
+    if type != 'error':
+	output = test.xpathEval('string(output)')
+	if output == 'No output file.':
+	    output = None
+	if output == '':
+	    output = None
+	if output != None:
+	    if basedir != None:
+		output = basedir + "/" + output
+	    if os.access(output, os.R_OK) == 0:
+		print("Result for %s missing: %s" % (id, output))
+		output = None
+	    else:
+		try:
+		    f = open(output)
+		    expected = f.read()
+		    outputfile = output
+		except:
+		    print("Result for %s unreadable: %s" % (id, output))
+
+    try:
+        # print "testing %s" % (URI)
+	doc = libxml2.parseFile(URI)
+    except:
+        doc = None
+    if doc != None:
+        res = doc.xincludeProcess()
+	if res >= 0 and expected != None:
+	    result = doc.serialize()
+	    if result != expected:
+	        print("Result for %s differs" % (id))
+		open("xinclude.res", "w").write(result)
+		diff = os.popen("diff %s xinclude.res" % outputfile).read()
+
+	doc.freeDoc()
+    else:
+        print("Failed to parse %s" % (URI))
+	res = -1
+
+    
+
+    test_nr = test_nr + 1
+    if type == 'success':
+	if res > 0:
+	    test_succeed = test_succeed + 1
+	elif res == 0:
+	    test_failed = test_failed + 1
+	    print("Test %s: no substitution done ???" % (id))
+	elif res < 0:
+	    test_error = test_error + 1
+	    print("Test %s: failed valid XInclude processing" % (id))
+    elif type == 'error':
+	if res > 0:
+	    test_error = test_error + 1
+	    print("Test %s: failed to detect invalid XInclude processing" % (id))
+	elif res == 0:
+	    test_failed = test_failed + 1
+	    print("Test %s: Invalid but no substitution done" % (id))
+	elif res < 0:
+	    test_succeed = test_succeed + 1
+    elif type == 'optional':
+	if res > 0:
+	    test_succeed = test_succeed + 1
+	else:
+	    print("Test %s: failed optional test" % (id))
+
+    # Log the ontext
+    if res != 1:
+	log.write("Test ID %s\n" % (id))
+	log.write("   File: %s\n" % (URI))
+	content = string.strip(test.content)
+	while content[-1] == '\n':
+	    content = content[0:-1]
+	log.write("   %s:%s\n\n" % (type, content))
+	if error_msg != '':
+	    log.write("   ----\n%s   ----\n" % (error_msg))
+	    error_msg = ''
+	log.write("\n")
+    if diff != None:
+        log.write("diff from test %s:\n" %(id))
+	log.write("   -----------\n%s\n   -----------\n" % (diff));
+
+    return 0
+	    
+
+def runTestCases(case):
+    creator = case.prop('creator')
+    if creator != None:
+	print("=>", creator)
+    base = case.getBase(None)
+    basedir = case.prop('basedir')
+    if basedir != None:
+	base = libxml2.buildURI(basedir, base)
+    test = case.children
+    while test != None:
+        if test.name == 'testcase':
+	    runTest(test, base)
+	if test.name == 'testcases':
+	    runTestCases(test)
+        test = test.__next__
+        
+conf = libxml2.parseFile(CONF)
+if conf == None:
+    print("Unable to load %s" % CONF)
+    sys.exit(1)
+
+testsuite = conf.getRootElement()
+if testsuite.name != 'testsuite':
+    print("Expecting TESTSUITE root element: aborting")
+    sys.exit(1)
+
+profile = testsuite.prop('PROFILE')
+if profile != None:
+    print(profile)
+
+start = time.time()
+
+case = testsuite.children
+while case != None:
+    if case.name == 'testcases':
+	old_test_nr = test_nr
+	old_test_succeed = test_succeed
+	old_test_failed = test_failed
+	old_test_error = test_error
+        runTestCases(case)
+	print("   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
+	       test_nr - old_test_nr, test_succeed - old_test_succeed,
+	       test_failed - old_test_failed, test_error - old_test_error))
+    case = case.__next__
+
+conf.freeDoc()
+log.close()
+
+print("Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
+      test_nr, test_succeed, test_failed, test_error, time.time() - start))
diff --git a/src/check-xml-test-suite.py b/src/check-xml-test-suite.py
new file mode 100755
index 0000000..fdfa896
--- /dev/null
+++ b/src/check-xml-test-suite.py
@@ -0,0 +1,410 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import os
+import string
+sys.path.insert(0, "python")
+import libxml2
+
+test_nr = 0
+test_succeed = 0
+test_failed = 0
+test_error = 0
+
+#
+# the testsuite description
+#
+CONF="xml-test-suite/xmlconf/xmlconf.xml"
+LOG="check-xml-test-suite.log"
+
+log = open(LOG, "w")
+
+#
+# Error and warning handlers
+#
+error_nr = 0
+error_msg = ''
+def errorHandler(ctx, str):
+    global error_nr
+    global error_msg
+
+    error_nr = error_nr + 1
+    if len(error_msg) < 300:
+        if len(error_msg) == 0 or error_msg[-1] == '\n':
+	    error_msg = error_msg + "   >>" + str
+	else:
+	    error_msg = error_msg + str
+
+libxml2.registerErrorHandler(errorHandler, None)
+
+#warning_nr = 0
+#warning = ''
+#def warningHandler(ctx, str):
+#    global warning_nr
+#    global warning
+#
+#    warning_nr = warning_nr + 1
+#    warning = warning + str
+#
+#libxml2.registerWarningHandler(warningHandler, None)
+
+#
+# Used to load the XML testsuite description
+#
+def loadNoentDoc(filename):
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return None
+    ctxt.replaceEntities(1)
+    ctxt.parseDocument()
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if ctxt.wellFormed() != 1:
+        doc.freeDoc()
+	return None
+    return doc
+
+#
+# The conformance testing routines
+#
+
+def testNotWf(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if doc != None:
+	doc.freeDoc()
+    if ret == 0 or ctxt.wellFormed() != 0:
+        print("%s: error: Well Formedness error not detected" % (id))
+	log.write("%s: error: Well Formedness error not detected\n" % (id))
+	return 0
+    return 1
+
+def testNotWfEnt(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.replaceEntities(1)
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if doc != None:
+	doc.freeDoc()
+    if ret == 0 or ctxt.wellFormed() != 0:
+        print("%s: error: Well Formedness error not detected" % (id))
+	log.write("%s: error: Well Formedness error not detected\n" % (id))
+	return 0
+    return 1
+
+def testNotWfEntDtd(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.replaceEntities(1)
+    ctxt.loadSubset(1)
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if doc != None:
+	doc.freeDoc()
+    if ret == 0 or ctxt.wellFormed() != 0:
+        print("%s: error: Well Formedness error not detected" % (id))
+	log.write("%s: error: Well Formedness error not detected\n" % (id))
+	return 0
+    return 1
+
+def testWfEntDtd(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.replaceEntities(1)
+    ctxt.loadSubset(1)
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if doc == None or ret != 0 or ctxt.wellFormed() == 0:
+        print("%s: error: wrongly failed to parse the document" % (id))
+	log.write("%s: error: wrongly failed to parse the document\n" % (id))
+	if doc != None:
+	    doc.freeDoc()
+	return 0
+    if error_nr != 0:
+        print("%s: warning: WF document generated an error msg" % (id))
+	log.write("%s: error: WF document generated an error msg\n" % (id))
+	doc.freeDoc()
+	return 2
+    doc.freeDoc()
+    return 1
+
+def testError(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.replaceEntities(1)
+    ctxt.loadSubset(1)
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    if doc != None:
+	doc.freeDoc()
+    if ctxt.wellFormed() == 0:
+        print("%s: warning: failed to parse the document but accepted" % (id))
+	log.write("%s: warning: failed to parse the document but accepte\n" % (id))
+	return 2
+    if error_nr != 0:
+        print("%s: warning: WF document generated an error msg" % (id))
+	log.write("%s: error: WF document generated an error msg\n" % (id))
+	return 2
+    return 1
+
+def testInvalid(filename, id):
+    global error_nr
+    global error_msg
+    global log
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.validate(1)
+    ret = ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    valid = ctxt.isValid()
+    if doc == None:
+        print("%s: error: wrongly failed to parse the document" % (id))
+	log.write("%s: error: wrongly failed to parse the document\n" % (id))
+	return 0
+    if valid == 1:
+        print("%s: error: Validity error not detected" % (id))
+	log.write("%s: error: Validity error not detected\n" % (id))
+	doc.freeDoc()
+	return 0
+    if error_nr == 0:
+        print("%s: warning: Validity error not reported" % (id))
+	log.write("%s: warning: Validity error not reported\n" % (id))
+	doc.freeDoc()
+	return 2
+        
+    doc.freeDoc()
+    return 1
+
+def testValid(filename, id):
+    global error_nr
+    global error_msg
+
+    error_nr = 0
+    error_msg = ''
+
+    ctxt = libxml2.createFileParserCtxt(filename)
+    if ctxt == None:
+        return -1
+    ctxt.validate(1)
+    ctxt.parseDocument()
+
+    try:
+	doc = ctxt.doc()
+    except:
+        doc = None
+    valid = ctxt.isValid()
+    if doc == None:
+        print("%s: error: wrongly failed to parse the document" % (id))
+	log.write("%s: error: wrongly failed to parse the document\n" % (id))
+	return 0
+    if valid != 1:
+        print("%s: error: Validity check failed" % (id))
+	log.write("%s: error: Validity check failed\n" % (id))
+	doc.freeDoc()
+	return 0
+    if error_nr != 0 or valid != 1:
+        print("%s: warning: valid document reported an error" % (id))
+	log.write("%s: warning: valid document reported an error\n" % (id))
+	doc.freeDoc()
+	return 2
+    doc.freeDoc()
+    return 1
+
+def runTest(test):
+    global test_nr
+    global test_succeed
+    global test_failed
+    global error_msg
+    global log
+
+    uri = test.prop('URI')
+    id = test.prop('ID')
+    if uri == None:
+        print("Test without ID:", uri)
+	return -1
+    if id == None:
+        print("Test without URI:", id)
+	return -1
+    base = test.getBase(None)
+    URI = libxml2.buildURI(uri, base)
+    if os.access(URI, os.R_OK) == 0:
+        print("Test %s missing: base %s uri %s" % (URI, base, uri))
+	return -1
+    type = test.prop('TYPE')
+    if type == None:
+        print("Test %s missing TYPE" % (id))
+	return -1
+
+    extra = None
+    if type == "invalid":
+        res = testInvalid(URI, id)
+    elif type == "valid":
+        res = testValid(URI, id)
+    elif type == "not-wf":
+        extra =  test.prop('ENTITIES')
+	# print URI
+	#if extra == None:
+	#    res = testNotWfEntDtd(URI, id)
+ 	#elif extra == 'none':
+	#    res = testNotWf(URI, id)
+	#elif extra == 'general':
+	#    res = testNotWfEnt(URI, id)
+	#elif extra == 'both' or extra == 'parameter':
+	res = testNotWfEntDtd(URI, id)
+	#else:
+	#    print "Unknow value %s for an ENTITIES test value" % (extra)
+	#    return -1
+    elif type == "error":
+	res = testError(URI, id)
+    else:
+        # TODO skipped for now
+	return -1
+
+    test_nr = test_nr + 1
+    if res > 0:
+	test_succeed = test_succeed + 1
+    elif res == 0:
+	test_failed = test_failed + 1
+    elif res < 0:
+	test_error = test_error + 1
+
+    # Log the ontext
+    if res != 1:
+	log.write("   File: %s\n" % (URI))
+	content = string.strip(test.content)
+	while content[-1] == '\n':
+	    content = content[0:-1]
+	if extra != None:
+	    log.write("   %s:%s:%s\n" % (type, extra, content))
+	else:
+	    log.write("   %s:%s\n\n" % (type, content))
+	if error_msg != '':
+	    log.write("   ----\n%s   ----\n" % (error_msg))
+	    error_msg = ''
+	log.write("\n")
+
+    return 0
+	    
+
+def runTestCases(case):
+    profile = case.prop('PROFILE')
+    if profile != None and \
+       string.find(profile, "IBM XML Conformance Test Suite - Production") < 0:
+	print("=>", profile)
+    test = case.children
+    while test != None:
+        if test.name == 'TEST':
+	    runTest(test)
+	if test.name == 'TESTCASES':
+	    runTestCases(test)
+        test = test.__next__
+        
+conf = loadNoentDoc(CONF)
+if conf == None:
+    print("Unable to load %s" % CONF)
+    sys.exit(1)
+
+testsuite = conf.getRootElement()
+if testsuite.name != 'TESTSUITE':
+    print("Expecting TESTSUITE root element: aborting")
+    sys.exit(1)
+
+profile = testsuite.prop('PROFILE')
+if profile != None:
+    print(profile)
+
+start = time.time()
+
+case = testsuite.children
+while case != None:
+    if case.name == 'TESTCASES':
+	old_test_nr = test_nr
+	old_test_succeed = test_succeed
+	old_test_failed = test_failed
+	old_test_error = test_error
+        runTestCases(case)
+	print("   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
+	       test_nr - old_test_nr, test_succeed - old_test_succeed,
+	       test_failed - old_test_failed, test_error - old_test_error))
+    case = case.__next__
+
+conf.freeDoc()
+log.close()
+
+print("Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
+      test_nr, test_succeed, test_failed, test_error, time.time() - start))
diff --git a/src/check-xsddata-test-suite.py b/src/check-xsddata-test-suite.py
new file mode 100755
index 0000000..71643a1
--- /dev/null
+++ b/src/check-xsddata-test-suite.py
@@ -0,0 +1,421 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import os
+import string
+import io
+sys.path.insert(0, "python")
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+debug = 0
+verbose = 0
+quiet = 1
+
+#
+# the testsuite description
+#
+CONF=os.path.join(os.path.dirname(__file__), "test/xsdtest/xsdtestsuite.xml")
+LOG="check-xsddata-test-suite.log"
+
+log = open(LOG, "w")
+nb_schemas_tests = 0
+nb_schemas_success = 0
+nb_schemas_failed = 0
+nb_instances_tests = 0
+nb_instances_success = 0
+nb_instances_failed = 0
+
+libxml2.lineNumbersDefault(1)
+#
+# Error and warnng callbacks
+#
+def callback(ctx, str):
+    global log
+    log.write("%s%s" % (ctx, str))
+
+libxml2.registerErrorHandler(callback, "")
+
+#
+# Resolver callback
+#
+resources = {}
+def resolver(URL, ID, ctxt):
+    global resources
+
+    if URL in resources:
+        return(io.StringIO(resources[URL]))
+    log.write("Resolver failure: asked %s\n" % (URL))
+    log.write("resources: %s\n" % (resources))
+    return None
+
+#
+# handle a valid instance
+#
+def handle_valid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = node.prop("dtd")
+    if instance == None:
+        instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+    mem = libxml2.debugMemory(1);
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nFailed to parse correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+	return
+
+    if debug:
+        print("instance line %d" % (node.lineNo()))
+       
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+	del ctxt
+    except:
+        ret = -1
+
+    doc.freeDoc()
+    if mem != libxml2.debugMemory(1):
+	print("validating instance %d line %d leaks" % (
+		  nb_instances_tests, node.lineNo()))
+
+    if ret != 0:
+        log.write("\nFailed to validate correct instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+
+#
+# handle an invalid instance
+#
+def handle_invalid(node, schema):
+    global log
+    global nb_instances_success
+    global nb_instances_failed
+
+    instance = node.prop("dtd")
+    if instance == None:
+        instance = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    instance = instance + child.serialize()
+	child = child.__next__
+
+#    mem = libxml2.debugMemory(1);
+
+    try:
+	doc = libxml2.parseDoc(instance)
+    except:
+        doc = None
+
+    if doc == None:
+        log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	return
+
+    if debug:
+        print("instance line %d" % (node.lineNo()))
+       
+    try:
+        ctxt = schema.relaxNGNewValidCtxt()
+	ret = doc.relaxNGValidateDoc(ctxt)
+	del ctxt
+
+    except:
+        ret = -1
+
+    doc.freeDoc()
+#    if mem != libxml2.debugMemory(1):
+#	print "validating instance %d line %d leaks" % (
+#		  nb_instances_tests, node.lineNo())
+    
+    if ret == 0:
+        log.write("\nFailed to detect validation problem in instance:\n-----\n")
+	log.write(instance)
+        log.write("\n-----\n")
+	nb_instances_failed = nb_instances_failed + 1
+    else:
+	nb_instances_success = nb_instances_success + 1
+
+#
+# handle an incorrect test
+#
+def handle_correct(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs == None:
+        log.write("\nFailed to compile correct schema:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+	nb_schemas_success = nb_schemas_success + 1
+    return rngs
+        
+def handle_incorrect(node):
+    global log
+    global nb_schemas_success
+    global nb_schemas_failed
+
+    schema = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    schema = schema + child.serialize()
+	child = child.__next__
+
+    try:
+	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+	rngs = rngp.relaxNGParse()
+    except:
+        rngs = None
+    if rngs != None:
+        log.write("\nFailed to detect schema error in:\n-----\n")
+	log.write(schema)
+        log.write("\n-----\n")
+	nb_schemas_failed = nb_schemas_failed + 1
+    else:
+#	log.write("\nSuccess detecting schema error in:\n-----\n")
+#	log.write(schema)
+#	log.write("\n-----\n")
+	nb_schemas_success = nb_schemas_success + 1
+    return None
+
+#
+# resource handling: keep a dictionary of URL->string mappings
+#
+def handle_resource(node, dir):
+    global resources
+
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    res = ""
+    child = node.children
+    while child != None:
+        if child.type != 'text':
+	    res = res + child.serialize()
+	child = child.__next__
+    resources[name] = res
+
+#
+# dir handling: pseudo directory resources
+#
+def handle_dir(node, dir):
+    try:
+	name = node.prop('name')
+    except:
+        name = None
+
+    if name == None or name == '':
+        log.write("resource has no name")
+	return;
+        
+    if dir != None:
+#        name = libxml2.buildURI(name, dir)
+        name = dir + '/' + name
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, name)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, name)
+
+#
+# handle a testCase element
+#
+def handle_testCase(node):
+    global nb_schemas_tests
+    global nb_instances_tests
+    global resources
+
+    sections = node.xpathEval('string(section)')
+    log.write("\n    ======== test %d line %d section %s ==========\n" % (
+
+              nb_schemas_tests, node.lineNo(), sections))
+    resources = {}
+    if debug:
+        print("test %d line %d" % (nb_schemas_tests, node.lineNo()))
+
+    dirs = node.xpathEval('dir')
+    for dir in dirs:
+        handle_dir(dir, None)
+    res = node.xpathEval('resource')
+    for r in res:
+        handle_resource(r, None)
+
+    tsts = node.xpathEval('incorrect')
+    if tsts != []:
+        if len(tsts) != 1:
+	    print("warning test line %d has more than one <incorrect> example" %(node.lineNo()))
+	schema = handle_incorrect(tsts[0])
+    else:
+        tsts = node.xpathEval('correct')
+	if tsts != []:
+	    if len(tsts) != 1:
+		print("warning test line %d has more than one <correct> example"% (node.lineNo()))
+	    schema = handle_correct(tsts[0])
+	else:
+	    print("warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo()))
+
+    nb_schemas_tests = nb_schemas_tests + 1;
+    
+    valids = node.xpathEval('valid')
+    invalids = node.xpathEval('invalid')
+    nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
+    if schema != None:
+        for valid in valids:
+	    handle_valid(valid, schema)
+        for invalid in invalids:
+	    handle_invalid(invalid, schema)
+
+
+#
+# handle a testSuite element
+#
+def handle_testSuite(node, level = 0):
+    global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
+    global nb_instances_tests, nb_instances_success, nb_instances_failed
+    if verbose and level >= 0:
+	old_schemas_tests = nb_schemas_tests
+	old_schemas_success = nb_schemas_success
+	old_schemas_failed = nb_schemas_failed
+	old_instances_tests = nb_instances_tests
+	old_instances_success = nb_instances_success
+	old_instances_failed = nb_instances_failed
+
+    docs = node.xpathEval('documentation')
+    authors = node.xpathEval('author')
+    if docs != []:
+        msg = ""
+        for doc in docs:
+	    msg = msg + doc.content + " "
+	if authors != []:
+	    msg = msg + "written by "
+	    for author in authors:
+	        msg = msg + author.content + " "
+	if quiet == 0:
+	    print(msg)
+    sections = node.xpathEval('section')
+    if verbose and sections != [] and level <= 0:
+        msg = ""
+        for section in sections:
+	    msg = msg + section.content + " "
+	if quiet == 0:
+	    print("Tests for section %s" % (msg))
+    for test in node.xpathEval('testCase'):
+        handle_testCase(test)
+    for test in node.xpathEval('testSuite'):
+        handle_testSuite(test, level + 1)
+	        
+
+    if verbose and level >= 0 :
+        if sections != []:
+	    msg = ""
+	    for section in sections:
+		msg = msg + section.content + " "
+	    print("Result of tests for section %s" % (msg))
+	elif docs != []:
+	    msg = ""
+	    for doc in docs:
+	        msg = msg + doc.content + " "
+	    print("Result of tests for %s" % (msg))
+
+        if nb_schemas_tests != old_schemas_tests:
+	    print("found %d test schemas: %d success %d failures" % (
+		  nb_schemas_tests - old_schemas_tests,
+		  nb_schemas_success - old_schemas_success,
+		  nb_schemas_failed - old_schemas_failed))
+	if nb_instances_tests != old_instances_tests:
+	    print("found %d test instances: %d success %d failures" % (
+		  nb_instances_tests - old_instances_tests,
+		  nb_instances_success - old_instances_success,
+		  nb_instances_failed - old_instances_failed))
+#
+# Parse the conf file
+#
+libxml2.substituteEntitiesDefault(1);
+testsuite = libxml2.parseFile(CONF)
+
+#
+# Error and warnng callbacks
+#
+def callback(ctx, str):
+    global log
+    log.write("%s%s" % (ctx, str))
+
+libxml2.registerErrorHandler(callback, "")
+
+libxml2.setEntityLoader(resolver)
+root = testsuite.getRootElement()
+if root.name != 'testSuite':
+    print("%s doesn't start with a testSuite element, aborting" % (CONF))
+    sys.exit(1)
+if quiet == 0:
+    print("Running Relax NG testsuite")
+handle_testSuite(root)
+
+if quiet == 0 or nb_schemas_failed != 0:
+    print("\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
+      nb_schemas_tests, nb_schemas_success, nb_schemas_failed))
+if quiet == 0 or nb_instances_failed != 0:
+    print("found %d test instances: %d success %d failures" % (
+      nb_instances_tests, nb_instances_success, nb_instances_failed))
+
+testsuite.freeDoc()
+
+# Memory debug specific
+libxml2.relaxNGCleanupTypes()
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    if quiet == 0:
+	print("OK")
+else:
+    print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
+    libxml2.dumpMemory()
diff --git a/src/chvalid.c b/src/chvalid.c
new file mode 100644
index 0000000..00dd962
--- /dev/null
+++ b/src/chvalid.c
@@ -0,0 +1,336 @@
+/*
+ * chvalid.c:	this module implements the character range
+ *		validation APIs
+ *
+ * This file is automatically generated from the cvs source
+ * definition files using the genChRanges.py Python script
+ *
+ * Generation date: Mon Mar 27 11:09:48 2006
+ * Sources: chvalid.def
+ * William Brack <wbrack@mmm.com.hk>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+#include <libxml/chvalid.h>
+
+/*
+ * The initial tables ({func_name}_tab) are used to validate whether a
+ * single-byte character is within the specified group.  Each table
+ * contains 256 bytes, with each byte representing one of the 256
+ * possible characters.  If the table byte is set, the character is
+ * allowed.
+ *
+ */
+const unsigned char xmlIsPubidChar_tab[256] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01,
+    0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00 };
+
+static const xmlChSRange xmlIsBaseChar_srng[] = { {0x100, 0x131}, 
+    {0x134, 0x13e}, {0x141, 0x148}, {0x14a, 0x17e}, {0x180, 0x1c3}, 
+    {0x1cd, 0x1f0}, {0x1f4, 0x1f5}, {0x1fa, 0x217}, {0x250, 0x2a8}, 
+    {0x2bb, 0x2c1}, {0x386, 0x386}, {0x388, 0x38a}, {0x38c, 0x38c}, 
+    {0x38e, 0x3a1}, {0x3a3, 0x3ce}, {0x3d0, 0x3d6}, {0x3da, 0x3da}, 
+    {0x3dc, 0x3dc}, {0x3de, 0x3de}, {0x3e0, 0x3e0}, {0x3e2, 0x3f3}, 
+    {0x401, 0x40c}, {0x40e, 0x44f}, {0x451, 0x45c}, {0x45e, 0x481}, 
+    {0x490, 0x4c4}, {0x4c7, 0x4c8}, {0x4cb, 0x4cc}, {0x4d0, 0x4eb}, 
+    {0x4ee, 0x4f5}, {0x4f8, 0x4f9}, {0x531, 0x556}, {0x559, 0x559}, 
+    {0x561, 0x586}, {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x621, 0x63a}, 
+    {0x641, 0x64a}, {0x671, 0x6b7}, {0x6ba, 0x6be}, {0x6c0, 0x6ce}, 
+    {0x6d0, 0x6d3}, {0x6d5, 0x6d5}, {0x6e5, 0x6e6}, {0x905, 0x939}, 
+    {0x93d, 0x93d}, {0x958, 0x961}, {0x985, 0x98c}, {0x98f, 0x990}, 
+    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b2, 0x9b2}, {0x9b6, 0x9b9}, 
+    {0x9dc, 0x9dd}, {0x9df, 0x9e1}, {0x9f0, 0x9f1}, {0xa05, 0xa0a}, 
+    {0xa0f, 0xa10}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa32, 0xa33}, 
+    {0xa35, 0xa36}, {0xa38, 0xa39}, {0xa59, 0xa5c}, {0xa5e, 0xa5e}, 
+    {0xa72, 0xa74}, {0xa85, 0xa8b}, {0xa8d, 0xa8d}, {0xa8f, 0xa91}, 
+    {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab2, 0xab3}, {0xab5, 0xab9}, 
+    {0xabd, 0xabd}, {0xae0, 0xae0}, {0xb05, 0xb0c}, {0xb0f, 0xb10}, 
+    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb32, 0xb33}, {0xb36, 0xb39}, 
+    {0xb3d, 0xb3d}, {0xb5c, 0xb5d}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, 
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xb99, 0xb9a}, {0xb9c, 0xb9c}, 
+    {0xb9e, 0xb9f}, {0xba3, 0xba4}, {0xba8, 0xbaa}, {0xbae, 0xbb5}, 
+    {0xbb7, 0xbb9}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, 
+    {0xc2a, 0xc33}, {0xc35, 0xc39}, {0xc60, 0xc61}, {0xc85, 0xc8c}, 
+    {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, 
+    {0xcde, 0xcde}, {0xce0, 0xce1}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, 
+    {0xd12, 0xd28}, {0xd2a, 0xd39}, {0xd60, 0xd61}, {0xe01, 0xe2e}, 
+    {0xe30, 0xe30}, {0xe32, 0xe33}, {0xe40, 0xe45}, {0xe81, 0xe82}, 
+    {0xe84, 0xe84}, {0xe87, 0xe88}, {0xe8a, 0xe8a}, {0xe8d, 0xe8d}, 
+    {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xea5, 0xea5}, 
+    {0xea7, 0xea7}, {0xeaa, 0xeab}, {0xead, 0xeae}, {0xeb0, 0xeb0}, 
+    {0xeb2, 0xeb3}, {0xebd, 0xebd}, {0xec0, 0xec4}, {0xf40, 0xf47}, 
+    {0xf49, 0xf69}, {0x10a0, 0x10c5}, {0x10d0, 0x10f6}, {0x1100, 0x1100}, 
+    {0x1102, 0x1103}, {0x1105, 0x1107}, {0x1109, 0x1109}, {0x110b, 0x110c}, 
+    {0x110e, 0x1112}, {0x113c, 0x113c}, {0x113e, 0x113e}, {0x1140, 0x1140}, 
+    {0x114c, 0x114c}, {0x114e, 0x114e}, {0x1150, 0x1150}, {0x1154, 0x1155}, 
+    {0x1159, 0x1159}, {0x115f, 0x1161}, {0x1163, 0x1163}, {0x1165, 0x1165}, 
+    {0x1167, 0x1167}, {0x1169, 0x1169}, {0x116d, 0x116e}, {0x1172, 0x1173}, 
+    {0x1175, 0x1175}, {0x119e, 0x119e}, {0x11a8, 0x11a8}, {0x11ab, 0x11ab}, 
+    {0x11ae, 0x11af}, {0x11b7, 0x11b8}, {0x11ba, 0x11ba}, {0x11bc, 0x11c2}, 
+    {0x11eb, 0x11eb}, {0x11f0, 0x11f0}, {0x11f9, 0x11f9}, {0x1e00, 0x1e9b}, 
+    {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, 
+    {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f59, 0x1f59}, {0x1f5b, 0x1f5b}, 
+    {0x1f5d, 0x1f5d}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, 
+    {0x1fbe, 0x1fbe}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, 
+    {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, 
+    {0x2126, 0x2126}, {0x212a, 0x212b}, {0x212e, 0x212e}, {0x2180, 0x2182}, 
+    {0x3041, 0x3094}, {0x30a1, 0x30fa}, {0x3105, 0x312c}, {0xac00, 0xd7a3}};
+const xmlChRangeGroup xmlIsBaseCharGroup =
+	{197, 0, xmlIsBaseChar_srng, (xmlChLRangePtr)0};
+
+static const xmlChSRange xmlIsChar_srng[] = { {0x100, 0xd7ff}, 
+    {0xe000, 0xfffd}};
+static const xmlChLRange xmlIsChar_lrng[] = { {0x10000, 0x10ffff}};
+const xmlChRangeGroup xmlIsCharGroup =
+	{2, 1, xmlIsChar_srng, xmlIsChar_lrng};
+
+static const xmlChSRange xmlIsCombining_srng[] = { {0x300, 0x345}, 
+    {0x360, 0x361}, {0x483, 0x486}, {0x591, 0x5a1}, {0x5a3, 0x5b9}, 
+    {0x5bb, 0x5bd}, {0x5bf, 0x5bf}, {0x5c1, 0x5c2}, {0x5c4, 0x5c4}, 
+    {0x64b, 0x652}, {0x670, 0x670}, {0x6d6, 0x6dc}, {0x6dd, 0x6df}, 
+    {0x6e0, 0x6e4}, {0x6e7, 0x6e8}, {0x6ea, 0x6ed}, {0x901, 0x903}, 
+    {0x93c, 0x93c}, {0x93e, 0x94c}, {0x94d, 0x94d}, {0x951, 0x954}, 
+    {0x962, 0x963}, {0x981, 0x983}, {0x9bc, 0x9bc}, {0x9be, 0x9be}, 
+    {0x9bf, 0x9bf}, {0x9c0, 0x9c4}, {0x9c7, 0x9c8}, {0x9cb, 0x9cd}, 
+    {0x9d7, 0x9d7}, {0x9e2, 0x9e3}, {0xa02, 0xa02}, {0xa3c, 0xa3c}, 
+    {0xa3e, 0xa3e}, {0xa3f, 0xa3f}, {0xa40, 0xa42}, {0xa47, 0xa48}, 
+    {0xa4b, 0xa4d}, {0xa70, 0xa71}, {0xa81, 0xa83}, {0xabc, 0xabc}, 
+    {0xabe, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd}, {0xb01, 0xb03}, 
+    {0xb3c, 0xb3c}, {0xb3e, 0xb43}, {0xb47, 0xb48}, {0xb4b, 0xb4d}, 
+    {0xb56, 0xb57}, {0xb82, 0xb83}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, 
+    {0xbca, 0xbcd}, {0xbd7, 0xbd7}, {0xc01, 0xc03}, {0xc3e, 0xc44}, 
+    {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc55, 0xc56}, {0xc82, 0xc83}, 
+    {0xcbe, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xcd5, 0xcd6}, 
+    {0xd02, 0xd03}, {0xd3e, 0xd43}, {0xd46, 0xd48}, {0xd4a, 0xd4d}, 
+    {0xd57, 0xd57}, {0xe31, 0xe31}, {0xe34, 0xe3a}, {0xe47, 0xe4e}, 
+    {0xeb1, 0xeb1}, {0xeb4, 0xeb9}, {0xebb, 0xebc}, {0xec8, 0xecd}, 
+    {0xf18, 0xf19}, {0xf35, 0xf35}, {0xf37, 0xf37}, {0xf39, 0xf39}, 
+    {0xf3e, 0xf3e}, {0xf3f, 0xf3f}, {0xf71, 0xf84}, {0xf86, 0xf8b}, 
+    {0xf90, 0xf95}, {0xf97, 0xf97}, {0xf99, 0xfad}, {0xfb1, 0xfb7}, 
+    {0xfb9, 0xfb9}, {0x20d0, 0x20dc}, {0x20e1, 0x20e1}, {0x302a, 0x302f}, 
+    {0x3099, 0x3099}, {0x309a, 0x309a}};
+const xmlChRangeGroup xmlIsCombiningGroup =
+	{95, 0, xmlIsCombining_srng, (xmlChLRangePtr)0};
+
+static const xmlChSRange xmlIsDigit_srng[] = { {0x660, 0x669}, 
+    {0x6f0, 0x6f9}, {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, 
+    {0xae6, 0xaef}, {0xb66, 0xb6f}, {0xbe7, 0xbef}, {0xc66, 0xc6f}, 
+    {0xce6, 0xcef}, {0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, 
+    {0xf20, 0xf29}};
+const xmlChRangeGroup xmlIsDigitGroup =
+	{14, 0, xmlIsDigit_srng, (xmlChLRangePtr)0};
+
+static const xmlChSRange xmlIsExtender_srng[] = { {0x2d0, 0x2d0}, 
+    {0x2d1, 0x2d1}, {0x387, 0x387}, {0x640, 0x640}, {0xe46, 0xe46}, 
+    {0xec6, 0xec6}, {0x3005, 0x3005}, {0x3031, 0x3035}, {0x309d, 0x309e}, 
+    {0x30fc, 0x30fe}};
+const xmlChRangeGroup xmlIsExtenderGroup =
+	{10, 0, xmlIsExtender_srng, (xmlChLRangePtr)0};
+
+static const xmlChSRange xmlIsIdeographic_srng[] = { {0x3007, 0x3007}, 
+    {0x3021, 0x3029}, {0x4e00, 0x9fa5}};
+const xmlChRangeGroup xmlIsIdeographicGroup =
+	{3, 0, xmlIsIdeographic_srng, (xmlChLRangePtr)0};
+
+
+/**
+ * xmlCharInRange:
+ * @val: character to be validated
+ * @rptr: pointer to range to be used to validate
+ *
+ * Does a binary search of the range table to determine if char
+ * is valid
+ *
+ * Returns: true if character valid, false otherwise
+ */
+int
+xmlCharInRange (unsigned int val, const xmlChRangeGroup *rptr) {
+    int low, high, mid;
+    const xmlChSRange *sptr;
+    const xmlChLRange *lptr;
+
+    if (rptr == NULL) return(0);
+    if (val < 0x10000) {	/* is val in 'short' or 'long'  array? */
+	if (rptr->nbShortRange == 0)
+	    return 0;
+	low = 0;
+	high = rptr->nbShortRange - 1;
+	sptr = rptr->shortRange;
+	while (low <= high) {
+	    mid = (low + high) / 2;
+	    if ((unsigned short) val < sptr[mid].low) {
+		high = mid - 1;
+	    } else {
+	        if ((unsigned short) val > sptr[mid].high) {
+		    low = mid + 1;
+		} else {
+		    return 1;
+		}
+	    }
+	}
+    } else {
+	if (rptr->nbLongRange == 0) {
+	    return 0;
+	}
+	low = 0;
+	high = rptr->nbLongRange - 1;
+	lptr = rptr->longRange;
+	while (low <= high) {
+	    mid = (low + high) / 2;
+	    if (val < lptr[mid].low) {
+		high = mid - 1;
+	    } else {
+	        if (val > lptr[mid].high) {
+		    low = mid + 1;
+		} else {
+		    return 1;
+		}
+	    }
+	}
+    }
+    return 0;
+}
+
+
+/**
+ * xmlIsBaseChar:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsBaseChar_ch or xmlIsBaseCharQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsBaseChar(unsigned int ch) {
+    return(xmlIsBaseCharQ(ch));
+}
+
+
+/**
+ * xmlIsBlank:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsBlank_ch or xmlIsBlankQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsBlank(unsigned int ch) {
+    return(xmlIsBlankQ(ch));
+}
+
+
+/**
+ * xmlIsChar:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsChar_ch or xmlIsCharQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsChar(unsigned int ch) {
+    return(xmlIsCharQ(ch));
+}
+
+
+/**
+ * xmlIsCombining:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsCombiningQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsCombining(unsigned int ch) {
+    return(xmlIsCombiningQ(ch));
+}
+
+
+/**
+ * xmlIsDigit:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsDigit_ch or xmlIsDigitQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsDigit(unsigned int ch) {
+    return(xmlIsDigitQ(ch));
+}
+
+
+/**
+ * xmlIsExtender:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsExtender_ch or xmlIsExtenderQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsExtender(unsigned int ch) {
+    return(xmlIsExtenderQ(ch));
+}
+
+
+/**
+ * xmlIsIdeographic:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsIdeographicQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsIdeographic(unsigned int ch) {
+    return(xmlIsIdeographicQ(ch));
+}
+
+
+/**
+ * xmlIsPubidChar:
+ * @ch:  character to validate
+ *
+ * This function is DEPRECATED.
+ * Use xmlIsPubidChar_ch or xmlIsPubidCharQ instead
+ *
+ * Returns true if argument valid, false otherwise
+ */
+int
+xmlIsPubidChar(unsigned int ch) {
+    return(xmlIsPubidCharQ(ch));
+}
+
+#define bottom_chvalid
+#include "elfgcchack.h"
diff --git a/src/config.guess b/src/config.guess
new file mode 100755
index 0000000..dc84c68
--- /dev/null
+++ b/src/config.guess
@@ -0,0 +1,1501 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..d60f362
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,311 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+#undef PACKAGE
+#undef VERSION
+#undef HAVE_LIBZ
+#undef HAVE_LIBM
+#undef HAVE_ISINF
+#undef 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
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#undef HAVE_ARPA_NAMESER_H
+
+/* Whether struct sockaddr::__ss_family exists */
+#undef HAVE_BROKEN_SS_FAMILY
+
+/* Define to 1 if you have the `class' function. */
+#undef HAVE_CLASS
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Have dlopen based dso */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the <dl.h> header file. */
+#undef HAVE_DL_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `finite' function. */
+#undef HAVE_FINITE
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define to 1 if you have the `fpclass' function. */
+#undef HAVE_FPCLASS
+
+/* Define to 1 if you have the `fprintf' function. */
+#undef HAVE_FPRINTF
+
+/* Define to 1 if you have the `fp_class' function. */
+#undef HAVE_FP_CLASS
+
+/* Define to 1 if you have the <fp_class.h> header file. */
+#undef HAVE_FP_CLASS_H
+
+/* Define to 1 if you have the `ftime' function. */
+#undef HAVE_FTIME
+
+/* Define if getaddrinfo is there */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <inttypes.h.h> header file. */
+#undef HAVE_INTTYPES_H_H
+
+/* Define if isinf is there */
+#undef HAVE_ISINF
+
+/* Define if isnan is there */
+#undef HAVE_ISNAN
+
+/* Define to 1 if you have the `isnand' function. */
+#undef HAVE_ISNAND
+
+/* Define if history library is there (-lhistory) */
+#undef HAVE_LIBHISTORY
+
+/* Define if pthread library is there (-lpthread) */
+#undef HAVE_LIBPTHREAD
+
+/* Define if readline library is there (-lreadline) */
+#undef HAVE_LIBREADLINE
+
+/* Have compression library */
+#undef HAVE_LIBZ
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the `localtime' function. */
+#undef HAVE_LOCALTIME
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <nan.h> header file. */
+#undef HAVE_NAN_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the `printf' function. */
+#undef HAVE_PRINTF
+
+/* Define if <pthread.h> is there */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#undef HAVE_RESOLV_H
+
+/* Have shl_load based dso */
+#undef HAVE_SHLLOAD
+
+/* Define to 1 if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the `sprintf' function. */
+#undef HAVE_SPRINTF
+
+/* Define to 1 if you have the `sscanf' function. */
+#undef HAVE_SSCANF
+
+/* Define to 1 if you have the `stat' function. */
+#undef HAVE_STAT
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#undef HAVE_SYS_TIMEB_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Whether va_copy() is available */
+#undef HAVE_VA_COPY
+
+/* Define to 1 if you have the `vfprintf' function. */
+#undef HAVE_VFPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `vsprintf' function. */
+#undef HAVE_VSPRINTF
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to 1 if you have the `_stat' function. */
+#undef HAVE__STAT
+
+/* Whether __va_copy() is available */
+#undef HAVE___VA_COPY
+
+/* Define as const if the declaration of iconv() needs const. */
+#undef ICONV_CONST
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#undef PROTOTYPES
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Support for IPv6 */
+#undef SUPPORT_IP6
+
+/* Version number of package */
+#undef VERSION
+
+/* Determine what socket length (socklen_t) data type is */
+#undef XML_SOCKLEN_T
+
+/* Using the Win32 Socket implementation */
+#undef _WINSOCKAPI_
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#undef __PROTOTYPES
+
+/* Win32 Std C name mangling work-around */
+#undef snprintf
+
+/* ss_family is not defined here, use __ss_family instead */
+#undef ss_family
+
+/* Win32 Std C name mangling work-around */
+#undef vsnprintf
diff --git a/src/config.sub b/src/config.sub
new file mode 100755
index 0000000..2a55a50
--- /dev/null
+++ b/src/config.sub
@@ -0,0 +1,1705 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+        -auroraux)
+	        os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/configure b/src/configure
new file mode 100755
index 0000000..412faed
--- /dev/null
+++ b/src/configure
@@ -0,0 +1,16827 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.65.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+$*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "$0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="entities.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+PYTHON_TESTS
+RELDATE
+RDL_LIBS
+M_LIBS
+PYTHON_SITE_PACKAGES
+PYTHON_INCLUDES
+PYTHON_VERSION
+HAVE_ISINF
+HAVE_ISNAN
+XML_INCLUDEDIR
+ICONV_LIBS
+XML_LIBTOOLLIBS
+XML_LIBS
+XML_LIBDIR
+XML_CFLAGS
+CYGWIN_EXTRA_PYTHON_LIBADD
+CYGWIN_EXTRA_LDFLAGS
+WIN32_EXTRA_LDFLAGS
+WIN32_EXTRA_LIBADD
+WITH_RUN_DEBUG
+WITH_MEM_DEBUG
+TEST_DEBUG
+DEBUG_OBJ
+WITH_DEBUG
+TEST_REGEXPS
+WITH_REGEXPS
+TEST_SCHEMAS
+WITH_SCHEMAS
+TEST_SCHEMATRON
+WITH_SCHEMATRON
+WITH_ISO8859X
+WITH_ICONV
+WITH_ICU
+WITH_OUTPUT
+TEST_XPATH
+XPATH_OBJ
+WITH_XPATH
+TEST_XINCLUDE
+XINCLUDE_OBJ
+WITH_XINCLUDE
+TEST_C14N
+C14N_OBJ
+WITH_C14N
+TEST_XPTR
+XPTR_OBJ
+WITH_XPTR
+DOCB_OBJ
+WITH_DOCB
+TEST_CATALOG
+CATALOG_OBJ
+WITH_CATALOG
+TEST_VTIME
+TEST_VALID
+WITH_VALID
+TEST_PHTML
+TEST_HTML
+HTML_OBJ
+WITH_HTML
+TEST_PUSH
+WITH_PUSH
+TEST_SAX
+WITH_SAX1
+TEST_PATTERN
+WITH_PATTERN
+WITH_WRITER
+READER_TEST
+WITH_READER
+WITH_LEGACY
+HTTP_OBJ
+WITH_HTTP
+FTP_OBJ
+WITH_FTP
+WITH_TREE
+THREADS_W32
+TEST_THREADS
+THREAD_CFLAGS
+WITH_THREADS
+BASE_THREAD_LIBS
+THREAD_LIBS
+WITH_TRIO
+WITH_TRIO_SOURCES_FALSE
+WITH_TRIO_SOURCES_TRUE
+STATIC_BINARIES
+TEST_MODULES
+MODULE_EXTENSION
+MODULE_PLATFORM_LIBS
+WITH_MODULES
+PYTHON_LIBS
+PYTHON_SUBDIR
+pythondir
+WITH_PYTHON_FALSE
+WITH_PYTHON_TRUE
+PYTHON
+WITH_ZLIB
+Z_LIBS
+Z_CFLAGS
+REBUILD_DOCS_FALSE
+REBUILD_DOCS_TRUE
+HTML_DIR
+USE_VERSION_SCRIPT_FALSE
+USE_VERSION_SCRIPT_TRUE
+VERSION_SCRIPT_FLAGS
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+lt_ECHO
+RANLIB
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+ANSI2KNR
+U
+EGREP
+GREP
+XSLTPROC
+XMLLINT
+WGET
+PERL
+TAR
+MV
+RM
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LIBXML_VERSION_EXTRA
+LIBXML_VERSION_NUMBER
+LIBXML_VERSION_INFO
+LIBXML_VERSION
+LIBXML_MICRO_VERSION
+LIBXML_MINOR_VERSION
+LIBXML_MAJOR_VERSION
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+with_c14n
+with_catalog
+with_debug
+with_docbook
+with_fexceptions
+with_ftp
+with_history
+with_html
+with_html_dir
+with_html_subdir
+with_http
+with_iconv
+with_iso8859x
+with_legacy
+with_mem_debug
+with_minimum
+with_output
+with_pattern
+with_push
+with_python
+with_reader
+with_readline
+with_regexps
+with_run_debug
+with_sax1
+with_schemas
+with_schematron
+with_threads
+with_thread_alloc
+with_tree
+with_valid
+with_writer
+with_xinclude
+with_xpath
+with_xptr
+with_modules
+with_zlib
+with_coverage
+enable_rebuild_docs
+enable_ipv6
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-rebuild-docs[=yes/no]  rebuild some generated docs [default=yes]
+  --enable-ipv6[=yes/no]  enables compilation of IPv6 code [default=yes]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-c14n             add the Canonicalization support (on)
+  --with-catalog          add the Catalog support (on)
+  --with-debug            add the debugging module (on)
+  --with-docbook          add Docbook SGML support (on)
+  --with-fexceptions      add GCC flag -fexceptions for C++ exceptions (off)
+  --with-ftp              add the FTP support (on)
+  --with-history          add history support to xmllint shell(off)
+  --with-html             add the HTML support (on)
+  --with-html-dir=path    path to base html directory, default
+                          $datadir/doc/html
+  --with-html-subdir=path directory used under html-dir, default
+                          $PACKAGE-$VERSION/html
+  --with-http             add the HTTP support (on)
+  --with-iconv[=DIR]      add ICONV support (on)
+  --with-iso8859x         add ISO8859X support if no iconv (on)
+  --with-legacy           add deprecated APIs for compatibility (on)
+  --with-mem-debug        add the memory debugging module (off)
+  --with-minimum          build a minimally sized library (off)
+  --with-output           add the serialization support (on)
+  --with-pattern          add the xmlPattern selection interface (on)
+  --with-push             add the PUSH parser interfaces (on)
+  --with-python[=DIR]     build Python bindings if found
+  --with-reader           add the xmlReader parsing interface (on)
+  --with-readline=DIR     use readline in DIR
+  --with-regexps          add Regular Expressions support (on)
+  --with-run-debug        add the runtime debugging module (off)
+  --with-sax1             add the older SAX1 interface (on)
+  --with-schemas          add Relax-NG and Schemas support (on)
+  --with-schematron       add Schematron support (on)
+  --with-threads          add multithread support(on)
+  --with-thread-alloc     add per-thread memory(off)
+  --with-tree             add the DOM like tree manipulation APIs (on)
+  --with-valid            add the DTD validation support (on)
+  --with-writer           add the xmlWriter saving interface (on)
+  --with-xinclude         add the XInclude support (on)
+  --with-xpath            add the XPATH support (on)
+  --with-xptr             add the XPointer support (on)
+  --with-modules          add the dynamic modules support (on)
+  --with-zlib[=DIR]       use libz in DIR
+  --with-coverage         build for code coverage with GCC (off)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.65
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.65.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+LIBXML_MAJOR_VERSION=2
+LIBXML_MINOR_VERSION=7
+LIBXML_MICRO_VERSION=7
+LIBXML_MICRO_VERSION_SUFFIX=
+LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX
+LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
+
+LIBXML_VERSION_NUMBER=`expr $LIBXML_MAJOR_VERSION \* 10000 + $LIBXML_MINOR_VERSION \* 100 + $LIBXML_MICRO_VERSION`
+
+if test -f CVS/Entries ; then
+  extra=`grep ChangeLog CVS/Entries | grep -v LIBXML | sed -e s\%/ChangeLog/1\.%% -e s\%/.*$%%`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-CVS$extra"
+  fi
+else if test -d .svn ; then
+  extra=`svn info | grep Revision | sed 's+Revision: ++'`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-SVN$extra"
+  fi
+else if test -d .git ; then
+  extra=`git describe | sed 's+LIBXML[0-9.]*-++'`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-GIT$extra"
+  fi
+fi
+fi
+fi
+
+
+
+
+
+
+
+
+VERSION=${LIBXML_VERSION}
+
+am__api_version='1.11'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=libxml2
+ VERSION=$VERSION
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Extract the first word of "rm", so it can be a program name with args.
+set dummy rm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_RM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $RM in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_RM="$RM" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_RM" && ac_cv_path_RM="/bin/rm"
+  ;;
+esac
+fi
+RM=$ac_cv_path_RM
+if test -n "$RM"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5
+$as_echo "$RM" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "mv", so it can be a program name with args.
+set dummy mv; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_MV+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MV in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MV="$MV" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_MV" && ac_cv_path_MV="/bin/mv"
+  ;;
+esac
+fi
+MV=$ac_cv_path_MV
+if test -n "$MV"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MV" >&5
+$as_echo "$MV" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "tar", so it can be a program name with args.
+set dummy tar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_TAR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $TAR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_TAR" && ac_cv_path_TAR="/bin/tar"
+  ;;
+esac
+fi
+TAR=$ac_cv_path_TAR
+if test -n "$TAR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5
+$as_echo "$TAR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PERL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="/usr/bin/perl"
+  ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "wget", so it can be a program name with args.
+set dummy wget; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_WGET+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $WGET in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_WGET" && ac_cv_path_WGET="/usr/bin/wget"
+  ;;
+esac
+fi
+WGET=$ac_cv_path_WGET
+if test -n "$WGET"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
+$as_echo "$WGET" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "xmllint", so it can be a program name with args.
+set dummy xmllint; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_XMLLINT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XMLLINT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XMLLINT="$XMLLINT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_XMLLINT="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_XMLLINT" && ac_cv_path_XMLLINT="/usr/bin/xmllint"
+  ;;
+esac
+fi
+XMLLINT=$ac_cv_path_XMLLINT
+if test -n "$XMLLINT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XMLLINT" >&5
+$as_echo "$XMLLINT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "xsltproc", so it can be a program name with args.
+set dummy xsltproc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_XSLTPROC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $XSLTPROC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_XSLTPROC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_XSLTPROC" && ac_cv_path_XSLTPROC="/usr/bin/xsltproc"
+  ;;
+esac
+fi
+XSLTPROC=$ac_cv_path_XSLTPROC
+if test -n "$XSLTPROC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5
+$as_echo "$XSLTPROC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for function prototypes" >&5
+$as_echo_n "checking for function prototypes... " >&6; }
+if test "$ac_cv_prog_cc_c89" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define PROTOTYPES 1" >>confdefs.h
+
+
+$as_echo "#define __PROTOTYPES 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+if test "$ac_cv_prog_cc_stdc" != no; then
+  U= ANSI2KNR=
+else
+  U=_ ANSI2KNR=./ansi2knr
+fi
+# Ensure some checks needed by ansi2knr itself.
+
+for ac_header in string.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRING_H 1
+_ACEOF
+
+fi
+
+done
+
+
+test "x$U" != "x" && as_fn_error "Compiler not ANSI compliant" "$LINENO" 5
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AS+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AS="${ac_tool_prefix}as"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+  ac_ct_AS=$AS
+  # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AS+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AS"; then
+  ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AS="as"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AS" = x; then
+    AS="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AS=$ac_ct_AS
+  fi
+else
+  AS="$ac_cv_prog_AS"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+  ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6b'
+macro_revision='1.3017'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:5603: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:5606: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:5609: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 6811 "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8067: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:8071: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8406: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:8410: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8511: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:8515: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8566: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:8570: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec=
+	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec='$convenience'
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_from_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  whole_archive_flag_spec=''
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld='+b $libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LDFLAGS="$save_LDFLAGS"
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+	pic_flag=$lt_prog_compiler_pic
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        then
+	  archive_cmds_need_lc=no
+        else
+	  archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 10950 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 11046 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+VERSION_SCRIPT_FLAGS=
+# lt_cv_prog_gnu_ld is from libtool 2.+
+if test "$lt_cv_prog_gnu_ld" = yes; then
+  VERSION_SCRIPT_FLAGS=-Wl,--version-script=
+else
+  case $host in
+  *-*-sunos*) VERSION_SCRIPT_FLAGS="-Wl,-M -Wl,";;
+  esac
+fi
+
+ if test -n "$VERSION_SCRIPT_FLAGS"; then
+  USE_VERSION_SCRIPT_TRUE=
+  USE_VERSION_SCRIPT_FALSE='#'
+else
+  USE_VERSION_SCRIPT_TRUE='#'
+  USE_VERSION_SCRIPT_FALSE=
+fi
+
+
+
+_cppflags="${CPPFLAGS}"
+_ldflags="${LDFLAGS}"
+
+
+# Check whether --with-c14n was given.
+if test "${with_c14n+set}" = set; then :
+  withval=$with_c14n;
+fi
+
+
+# Check whether --with-catalog was given.
+if test "${with_catalog+set}" = set; then :
+  withval=$with_catalog;
+fi
+
+
+# Check whether --with-debug was given.
+if test "${with_debug+set}" = set; then :
+  withval=$with_debug;
+fi
+
+
+# Check whether --with-docbook was given.
+if test "${with_docbook+set}" = set; then :
+  withval=$with_docbook;
+fi
+
+
+# Check whether --with-fexceptions was given.
+if test "${with_fexceptions+set}" = set; then :
+  withval=$with_fexceptions;
+fi
+
+
+# Check whether --with-ftp was given.
+if test "${with_ftp+set}" = set; then :
+  withval=$with_ftp;
+fi
+
+
+# Check whether --with-history was given.
+if test "${with_history+set}" = set; then :
+  withval=$with_history;
+fi
+
+
+# Check whether --with-html was given.
+if test "${with_html+set}" = set; then :
+  withval=$with_html;
+fi
+
+
+# Check whether --with-html-dir was given.
+if test "${with_html_dir+set}" = set; then :
+  withval=$with_html_dir; HTML_DIR=$withval
+else
+  HTML_DIR='$(datadir)/doc'
+fi
+
+
+
+# Check whether --with-html-subdir was given.
+if test "${with_html_subdir+set}" = set; then :
+  withval=$with_html_subdir; test "x$withval" != "x" && HTML_DIR="$HTML_DIR/$withval"
+else
+  HTML_DIR="$HTML_DIR/\$(PACKAGE)-\$(VERSION)/html"
+fi
+
+
+
+# Check whether --with-http was given.
+if test "${with_http+set}" = set; then :
+  withval=$with_http;
+fi
+
+
+# Check whether --with-iconv was given.
+if test "${with_iconv+set}" = set; then :
+  withval=$with_iconv;
+fi
+
+
+# Check whether --with-iso8859x was given.
+if test "${with_iso8859x+set}" = set; then :
+  withval=$with_iso8859x;
+fi
+
+
+# Check whether --with-legacy was given.
+if test "${with_legacy+set}" = set; then :
+  withval=$with_legacy;
+fi
+
+
+# Check whether --with-mem_debug was given.
+if test "${with_mem_debug+set}" = set; then :
+  withval=$with_mem_debug;
+fi
+
+
+# Check whether --with-minimum was given.
+if test "${with_minimum+set}" = set; then :
+  withval=$with_minimum;
+fi
+
+
+# Check whether --with-output was given.
+if test "${with_output+set}" = set; then :
+  withval=$with_output;
+fi
+
+
+# Check whether --with-pattern was given.
+if test "${with_pattern+set}" = set; then :
+  withval=$with_pattern;
+fi
+
+
+# Check whether --with-push was given.
+if test "${with_push+set}" = set; then :
+  withval=$with_push;
+fi
+
+
+# Check whether --with-python was given.
+if test "${with_python+set}" = set; then :
+  withval=$with_python;
+fi
+
+
+# Check whether --with-reader was given.
+if test "${with_reader+set}" = set; then :
+  withval=$with_reader;
+fi
+
+
+# Check whether --with-readline was given.
+if test "${with_readline+set}" = set; then :
+  withval=$with_readline;
+  if test "$withval" != "no" -a "$withval" != "yes"; then
+    RDL_DIR=$withval
+    CPPFLAGS="${CPPFLAGS} -I$withval/include"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
+  fi
+
+fi
+
+
+# Check whether --with-regexps was given.
+if test "${with_regexps+set}" = set; then :
+  withval=$with_regexps;
+fi
+
+
+# Check whether --with-run_debug was given.
+if test "${with_run_debug+set}" = set; then :
+  withval=$with_run_debug;
+fi
+
+
+# Check whether --with-sax1 was given.
+if test "${with_sax1+set}" = set; then :
+  withval=$with_sax1;
+fi
+
+
+# Check whether --with-schemas was given.
+if test "${with_schemas+set}" = set; then :
+  withval=$with_schemas;
+fi
+
+
+# Check whether --with-schematron was given.
+if test "${with_schematron+set}" = set; then :
+  withval=$with_schematron;
+fi
+
+
+# Check whether --with-threads was given.
+if test "${with_threads+set}" = set; then :
+  withval=$with_threads;
+fi
+
+
+# Check whether --with-thread-alloc was given.
+if test "${with_thread_alloc+set}" = set; then :
+  withval=$with_thread_alloc;
+fi
+
+
+# Check whether --with-tree was given.
+if test "${with_tree+set}" = set; then :
+  withval=$with_tree;
+fi
+
+
+# Check whether --with-valid was given.
+if test "${with_valid+set}" = set; then :
+  withval=$with_valid;
+fi
+
+
+# Check whether --with-writer was given.
+if test "${with_writer+set}" = set; then :
+  withval=$with_writer;
+fi
+
+
+# Check whether --with-xinclude was given.
+if test "${with_xinclude+set}" = set; then :
+  withval=$with_xinclude;
+fi
+
+
+# Check whether --with-xpath was given.
+if test "${with_xpath+set}" = set; then :
+  withval=$with_xpath;
+fi
+
+
+# Check whether --with-xptr was given.
+if test "${with_xptr+set}" = set; then :
+  withval=$with_xptr;
+fi
+
+
+# Check whether --with-modules was given.
+if test "${with_modules+set}" = set; then :
+  withval=$with_modules;
+fi
+
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+  withval=$with_zlib;
+  if test "$withval" != "no" -a "$withval" != "yes"; then
+    Z_DIR=$withval
+    CPPFLAGS="${CPPFLAGS} -I$withval/include"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
+  fi
+
+fi
+
+
+# Check whether --with-coverage was given.
+if test "${with_coverage+set}" = set; then :
+  withval=$with_coverage;
+fi
+
+
+# Check whether --enable-rebuild-docs was given.
+if test "${enable_rebuild_docs+set}" = set; then :
+  enableval=$enable_rebuild_docs;
+fi
+
+ if test "$enable_rebuild_docs" = "no"; then
+  REBUILD_DOCS_TRUE=
+  REBUILD_DOCS_FALSE='#'
+else
+  REBUILD_DOCS_TRUE='#'
+  REBUILD_DOCS_FALSE=
+fi
+
+
+if test "$with_schemas" = "yes"
+then
+    with_pattern=yes
+    with_regexps=yes
+fi
+if test "$with_schematron" = "yes"
+then
+    with_pattern=yes
+    with_xpath=yes
+fi
+if test "$with_reader" = "yes"
+then
+    with_push=yes
+fi
+if test "$with_xptr" = "yes"
+then
+    with_xpath=yes
+fi
+if test "$with_minimum" = "yes"
+then
+    echo "Configuring for a minimal library"
+    if test "$with_c14n" = ""
+    then
+      with_c14n=no
+    fi
+    if test "$with_catalog" = ""
+    then
+      with_catalog=no
+    fi
+    echo So far so good!
+    if test "$with_debug" = ""
+    then
+      with_debug=no
+    fi
+    if test "$with_docbook" = ""
+    then
+      with_docbook=no
+    fi
+    if test "$with_fexceptions" = ""
+    then
+      with_fexceptions=no
+    fi
+    if test "$with_ftp" = ""
+    then
+      with_ftp=no
+    fi
+    if test "$with_history" = ""
+    then
+      with_history=no
+    fi
+    if test "$with_html" = ""
+    then
+      with_html=no
+    fi
+    if test "$with_http" = ""
+    then
+      with_http=no
+    fi
+    if test "$with_iconv" = ""
+    then
+      with_iconv=no
+    fi
+    if test "$with_iso8859x" = ""
+    then
+      with_iso8859x=no
+    fi
+    if test "$with_legacy" = ""
+    then
+      with_legacy=no
+    fi
+    if test "$with_mem_debug" = ""
+    then
+      with_mem_debug=no
+    fi
+    if test "$with_output" = ""
+    then
+      with_output=no
+    fi
+    if test "$with_pattern" = ""
+    then
+      with_pattern=no
+    fi
+    if test "$with_push" = ""
+    then
+      with_push=no
+    fi
+    if test "$with_python" = ""
+    then
+      with_python=no
+    fi
+    if test "$with_reader" = ""
+    then
+      with_reader=no
+    fi
+    if test "$with_readline" = ""
+    then
+      with_readline=no
+    fi
+    if test "$with_regexps" = ""
+    then
+      with_regexps=no
+    fi
+    if test "$with_run_debug" = ""
+    then
+      with_run_debug=no
+    fi
+    if test "$with_sax1" = ""
+    then
+      with_sax1=no
+    fi
+    if test "$with_schemas" = ""
+    then
+      with_schemas=no
+    fi
+    if test "$with_schematron" = ""
+    then
+      with_schematron=no
+    fi
+    if test "$with_threads" = ""
+    then
+      with_threads=no
+    fi
+    if test "$with_thread_alloc" = ""
+    then
+      with_thread_alloc=no
+   fi
+    if test "$with_tree" = ""
+    then
+      with_tree=no
+    fi
+    if test "$with_valid" = ""
+    then
+      with_valid=no
+    fi
+    if test "$with_writer" = ""
+    then
+      with_writer=no
+    fi
+    if test "$with_xinclude" = ""
+    then
+      with_xinclude=no
+    fi
+    if test "$with_xpath" = ""
+    then
+      with_xpath=no
+    fi
+    if test "$with_xptr" = ""
+    then
+      with_xptr=no
+    fi
+    if test "$with_zlib" = ""
+    then
+      with_zlib=no
+    fi
+    if test "$with_modules" = ""
+    then
+      with_modules=no
+    fi
+fi
+
+echo Checking zlib
+
+
+WITH_ZLIB=0
+if test "$with_zlib" = "no"; then
+    echo "Disabling compression support"
+else
+    for ac_header in zlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5
+$as_echo_n "checking for gzread in -lz... " >&6; }
+if test "${ac_cv_lib_z_gzread+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gzread ();
+int
+main ()
+{
+return gzread ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_gzread=yes
+else
+  ac_cv_lib_z_gzread=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5
+$as_echo "$ac_cv_lib_z_gzread" >&6; }
+if test "x$ac_cv_lib_z_gzread" = x""yes; then :
+
+
+$as_echo "#define HAVE_LIBZ 1" >>confdefs.h
+
+	    WITH_ZLIB=1
+	    if test "x${Z_DIR}" != "x"; then
+		Z_CFLAGS="-I${Z_DIR}/include"
+		Z_LIBS="-L${Z_DIR}/lib -lz"
+		case ${host} in
+		    *-*-solaris*)
+			Z_LIBS="-L${Z_DIR}/lib -R${Z_DIR}/lib -lz"
+			;;
+		esac
+	    else
+		Z_LIBS="-lz"
+	    fi
+fi
+
+fi
+
+done
+
+fi
+
+
+
+
+
+CPPFLAGS=${_cppflags}
+LDFLAGS=${_ldflags}
+
+echo Checking headers
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in fcntl.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FCNTL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in unistd.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UNISTD_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in ctype.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CTYPE_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in dirent.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default"
+if test "x$ac_cv_header_dirent_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DIRENT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in errno.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ERRNO_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in malloc.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_malloc_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MALLOC_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stdarg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdarg_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDARG_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/stat.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_STAT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/types.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_TYPES_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stdint.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDINT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in inttypes.h.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h.h" "ac_cv_header_inttypes_h_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_INTTYPES_H_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in time.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TIME_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in ansidecl.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "ansidecl.h" "ac_cv_header_ansidecl_h" "$ac_includes_default"
+if test "x$ac_cv_header_ansidecl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ANSIDECL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in ieeefp.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "ieeefp.h" "ac_cv_header_ieeefp_h" "$ac_includes_default"
+if test "x$ac_cv_header_ieeefp_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_IEEEFP_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in nan.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "nan.h" "ac_cv_header_nan_h" "$ac_includes_default"
+if test "x$ac_cv_header_nan_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NAN_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in math.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default"
+if test "x$ac_cv_header_math_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MATH_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in limits.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in fp_class.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fp_class.h" "ac_cv_header_fp_class_h" "$ac_includes_default"
+if test "x$ac_cv_header_fp_class_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FP_CLASS_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in float.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOAT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/socket.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+
+"
+if test "x$ac_cv_header_sys_socket_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SOCKET_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in netinet/in.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+
+"
+if test "x$ac_cv_header_netinet_in_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NETINET_IN_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in arpa/inet.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+#if HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+
+"
+if test "x$ac_cv_header_arpa_inet_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ARPA_INET_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in netdb.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default"
+if test "x$ac_cv_header_netdb_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NETDB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/time.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_TIME_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/select.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_select_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SELECT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in poll.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default"
+if test "x$ac_cv_header_poll_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_POLL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/mman.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/timeb.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/timeb.h" "ac_cv_header_sys_timeb_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_timeb_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_TIMEB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in signal.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default"
+if test "x$ac_cv_header_signal_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGNAL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in arpa/nameser.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "arpa/nameser.h" "ac_cv_header_arpa_nameser_h" "#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+
+"
+if test "x$ac_cv_header_arpa_nameser_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ARPA_NAMESER_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in resolv.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "resolv.h" "ac_cv_header_resolv_h" "#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+#if HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+# endif
+
+"
+if test "x$ac_cv_header_resolv_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_RESOLV_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in dl.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "dl.h" "ac_cv_header_dl_h" "$ac_includes_default"
+if test "x$ac_cv_header_dl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+echo Checking libraries
+
+for ac_func in strftime
+do :
+  ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
+if test "x$ac_cv_func_strftime" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+else
+  # strftime is in -lintl on SCO UNIX.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
+$as_echo_n "checking for strftime in -lintl... " >&6; }
+if test "${ac_cv_lib_intl_strftime+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strftime ();
+int
+main ()
+{
+return strftime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_intl_strftime=yes
+else
+  ac_cv_lib_intl_strftime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
+$as_echo "$ac_cv_lib_intl_strftime" >&6; }
+if test "x$ac_cv_lib_intl_strftime" = x""yes; then :
+  $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+for ac_func in strdup strndup strerror
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in finite isnand fp_class class fpclass
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strftime localtime gettimeofday ftime
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in stat _stat signal
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in printf sprintf fprintf snprintf vfprintf vsprintf vsnprintf sscanf
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  NEED_TRIO=1
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for va_copy" >&5
+$as_echo_n "checking for va_copy... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+va_list ap1,ap2;
+int
+main ()
+{
+va_copy(ap1,ap2);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_va_copy=yes
+else
+  have_va_copy=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_va_copy" >&5
+$as_echo "$have_va_copy" >&6; }
+if test x"$have_va_copy" = x"yes"; then
+
+$as_echo "#define HAVE_VA_COPY 1" >>confdefs.h
+
+else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __va_copy" >&5
+$as_echo_n "checking for __va_copy... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+    va_list ap1,ap2;
+int
+main ()
+{
+__va_copy(ap1,ap2);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have___va_copy=yes
+else
+  have___va_copy=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have___va_copy" >&5
+$as_echo "$have___va_copy" >&6; }
+    if test x"$have___va_copy" = x"yes"; then
+
+$as_echo "#define HAVE___VA_COPY 1" >>confdefs.h
+
+    fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostent" >&5
+$as_echo_n "checking for library containing gethostent... " >&6; }
+if test "${ac_cv_search_gethostent+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostent ();
+int
+main ()
+{
+return gethostent ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_gethostent=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_gethostent+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_gethostent+set}" = set; then :
+
+else
+  ac_cv_search_gethostent=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostent" >&5
+$as_echo "$ac_cv_search_gethostent" >&6; }
+ac_res=$ac_cv_search_gethostent
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' socket net network; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_setsockopt+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+
+else
+  ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing connect" >&5
+$as_echo_n "checking for library containing connect... " >&6; }
+if test "${ac_cv_search_connect+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+int
+main ()
+{
+return connect ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' inet; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_connect=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_connect+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_connect+set}" = set; then :
+
+else
+  ac_cv_search_connect=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_connect" >&5
+$as_echo "$ac_cv_search_connect" >&6; }
+ac_res=$ac_cv_search_connect
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for type of socket length (socklen_t)" >&5
+$as_echo_n "checking for type of socket length (socklen_t)... " >&6; }
+cat > conftest.$ac_ext <<EOF
+#line 12868 "configure"
+#include "confdefs.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+int main(void) {
+
+(void)getsockopt (1, 1, 1, NULL, (socklen_t *)NULL)
+; return 0; }
+EOF
+if { (eval echo configure:12879: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+  rm -rf conftest*
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: socklen_t *" >&5
+$as_echo "socklen_t *" >&6; }
+  XML_SOCKLEN_T=socklen_t
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+
+  cat > conftest.$ac_ext <<EOF
+#line 12891 "configure"
+#include "confdefs.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+int main(void) {
+
+(void)getsockopt (1, 1, 1, NULL, (size_t *)NULL)
+; return 0; }
+EOF
+if { (eval echo configure:12902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+  rm -rf conftest*
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: size_t *" >&5
+$as_echo "size_t *" >&6; }
+    XML_SOCKLEN_T=size_t
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+
+    cat > conftest.$ac_ext <<EOF
+#line 12914 "configure"
+#include "confdefs.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+int main(void) {
+
+(void)getsockopt (1, 1, 1, NULL, (int *)NULL)
+; return 0; }
+EOF
+if { (eval echo configure:12925: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; _out=`eval $ac_compile 2>&1` && test "x$_out" = x; }; then
+  rm -rf conftest*
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: int *" >&5
+$as_echo "int *" >&6; }
+      XML_SOCKLEN_T=int
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not determine" >&5
+$as_echo "$as_me: WARNING: could not determine" >&2;}
+      XML_SOCKLEN_T="int"
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+
+cat >>confdefs.h <<_ACEOF
+#define XML_SOCKLEN_T $XML_SOCKLEN_T
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable IPv6" >&5
+$as_echo_n "checking whether to enable IPv6... " >&6; }
+# Check whether --enable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then :
+  enableval=$enable_ipv6;
+else
+  enable_ipv6=yes
+fi
+
+if test "$with_minimum" = "yes"
+then
+    enable_ipv6=no
+fi
+if test $enable_ipv6 = yes; then
+  have_ipv6=no
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    #include <sys/types.h>
+    #include <sys/socket.h>
+
+int
+main ()
+{
+
+    struct sockaddr_storage ss;
+    socket(AF_INET6, SOCK_STREAM, 0)
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  have_ipv6=yes
+else
+  have_ipv6=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ipv6" >&5
+$as_echo "$have_ipv6" >&6; }
+
+  if test $have_ipv6 = yes; then
+
+$as_echo "#define SUPPORT_IP6 /**/" >>confdefs.h
+
+    have_broken_ss_family=no
+
+                                { $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr::ss_family" >&5
+$as_echo_n "checking struct sockaddr::ss_family... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #include <sys/types.h>
+      #include <sys/socket.h>
+
+int
+main ()
+{
+
+      struct sockaddr_storage ss ;
+      ss.ss_family = 0 ;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  have_ss_family=yes
+else
+  have_ss_family=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ss_family" >&5
+$as_echo "$have_ss_family" >&6; }
+    if test x$have_ss_family = xno ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking broken struct sockaddr::ss_family" >&5
+$as_echo_n "checking broken struct sockaddr::ss_family... " >&6; }
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+        #include <sys/types.h>
+        #include <sys/socket.h>
+
+int
+main ()
+{
+
+        struct sockaddr_storage ss ;
+        ss.__ss_family = 0 ;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  have_broken_ss_family=yes
+else
+  have_broken_ss_family=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_broken_ss_family" >&5
+$as_echo "$have_broken_ss_family" >&6; }
+      if test x$have_broken_ss_family = xyes ; then
+
+$as_echo "#define HAVE_BROKEN_SS_FAMILY /**/" >>confdefs.h
+
+
+$as_echo "#define ss_family __ss_family" >>confdefs.h
+
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ss_family and __ss_family not found" >&5
+$as_echo "$as_me: WARNING: ss_family and __ss_family not found" >&2;}
+      fi
+    fi
+
+    have_getaddrinfo=no
+    ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
+if test "x$ac_cv_func_getaddrinfo" = x""yes; then :
+  have_getaddrinfo=yes
+fi
+
+    if test $have_getaddrinfo != yes; then
+      for lib in bsd socket inet; do
+        as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_getaddrinfo" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -l$lib" >&5
+$as_echo_n "checking for getaddrinfo in -l$lib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  LIBS="$LIBS -l$lib";have_getaddrinfo=yes;break
+fi
+
+      done
+    fi
+
+    if test $have_getaddrinfo = yes; then
+
+$as_echo "#define HAVE_GETADDRINFO /**/" >>confdefs.h
+
+    fi
+  fi
+fi
+
+
+ac_fn_c_check_func "$LINENO" "isnan" "ac_cv_func_isnan"
+if test "x$ac_cv_func_isnan" = x""yes; then :
+
+$as_echo "#define HAVE_ISNAN /**/" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isnan in -lm" >&5
+$as_echo_n "checking for isnan in -lm... " >&6; }
+if test "${ac_cv_lib_m_isnan+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char isnan ();
+int
+main ()
+{
+return isnan ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_isnan=yes
+else
+  ac_cv_lib_m_isnan=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_isnan" >&5
+$as_echo "$ac_cv_lib_m_isnan" >&6; }
+if test "x$ac_cv_lib_m_isnan" = x""yes; then :
+
+$as_echo "#define HAVE_ISNAN /**/" >>confdefs.h
+
+fi
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "isinf" "ac_cv_func_isinf"
+if test "x$ac_cv_func_isinf" = x""yes; then :
+
+$as_echo "#define HAVE_ISINF /**/" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinf in -lm" >&5
+$as_echo_n "checking for isinf in -lm... " >&6; }
+if test "${ac_cv_lib_m_isinf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char isinf ();
+int
+main ()
+{
+return isinf ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_isinf=yes
+else
+  ac_cv_lib_m_isinf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_isinf" >&5
+$as_echo "$ac_cv_lib_m_isinf" >&6; }
+if test "x$ac_cv_lib_m_isinf" = x""yes; then :
+
+$as_echo "#define HAVE_ISINF /**/" >>confdefs.h
+
+fi
+
+fi
+
+
+XML_LIBDIR='-L${libdir}'
+XML_INCLUDEDIR='-I${includedir}/libxml2'
+
+XML_CFLAGS=""
+RDL_LIBS=""
+
+if test "${GCC}" != "yes" ; then
+    case "${host}" in
+          hppa*-*-hpux* )
+	       CFLAGS="${CFLAGS} -Wp,-H30000"
+	       ;;
+          *-dec-osf* )
+               CFLAGS="${CFLAGS} -ieee"
+               ;;
+	  alpha*-*-linux* )
+	       CFLAGS="${CFLAGS} -ieee"
+	       ;;
+    esac
+else
+    if test "$with_fexceptions" = "yes"
+    then
+        #
+	# Not activated by default because this inflates the code size
+	# Used to allow propagation of C++ exceptions through the library
+	#
+	CFLAGS="${CFLAGS} -fexceptions"
+    fi
+
+    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
+    case "${host}" in
+          alpha*-*-linux* )
+	       CFLAGS="${CFLAGS} -mieee"
+	       ;;
+	  alpha*-*-osf* )
+	       CFLAGS="${CFLAGS} -mieee"
+	       ;;
+    esac
+fi
+case ${host} in
+    *-*-solaris*)
+        XML_LIBDIR="${XML_LIBDIR} -R${libdir}"
+        ;;
+    hppa*-hp-mpeix)
+        NEED_TRIO=1
+	;;
+    *-*-mingw* | *-*-cygwin* | *-*-msvc* )
+        # If the host is Windows, and shared libraries are disabled, we
+        # need to add -DLIBXML_STATIC to CFLAGS in order for linking to
+        # work properly (without it, xmlexports.h would force the use of
+        # DLL imports, which obviously aren't present in a static
+        # library).
+        if test "x$enable_shared" = "xno"; then
+            XML_CFLAGS="$XML_CFLAGS -DLIBXML_STATIC"
+            CFLAGS="$CFLAGS -DLIBXML_STATIC"
+        fi
+        ;;
+esac
+
+
+
+PYTHON_VERSION=
+PYTHON_INCLUDES=
+PYTHON_SITE_PACKAGES=
+PYTHON_TESTS=
+pythondir=
+if test "$with_python" != "no" ; then
+    if test -x "$with_python/bin/python"
+    then
+        echo Found python in $with_python/bin/python
+        PYTHON="$with_python/bin/python"
+    else
+	if test -x "$with_python"
+	then
+	    echo Found python in $with_python
+	    PYTHON="$with_python"
+	else
+	    if test -x "$PYTHON"
+	    then
+	        echo Found python in environment PYTHON=$PYTHON
+		with_python=`$PYTHON -c "import sys; print sys.exec_prefix"`
+	    else
+		# Extract the first word of "python python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5", so it can be a program name with args.
+set dummy python python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PYTHON+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PYTHON in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+	    fi
+	fi
+    fi
+    if test "$PYTHON" != ""
+    then
+        PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[0:3]"`
+	echo Found Python version $PYTHON_VERSION
+    fi
+    if test "$PYTHON_VERSION" != ""
+    then
+	if test -r $with_python/include/python$PYTHON_VERSION/Python.h -a \
+	   -d $with_python/lib/python$PYTHON_VERSION/site-packages
+	then
+	    PYTHON_INCLUDES=$with_python/include/python$PYTHON_VERSION
+	    PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+	else
+	    if test -r $prefix/include/python$PYTHON_VERSION/Python.h
+	    then
+	        PYTHON_INCLUDES=$prefix/include/python$PYTHON_VERSION
+	        PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+	    else
+		if test -r /usr/include/python$PYTHON_VERSION/Python.h
+		then
+		    PYTHON_INCLUDES=/usr/include/python$PYTHON_VERSION
+	            PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+		else
+		    echo could not find python$PYTHON_VERSION/Python.h
+		fi
+	    fi
+	    if test ! -d "$PYTHON_SITE_PACKAGES"
+	    then
+		    PYTHON_SITE_PACKAGES=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib()"`
+	    fi
+	fi
+	PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags`
+    fi
+    if test "$with_python" != ""
+    then
+        pythondir='$(PYTHON_SITE_PACKAGES)'
+    else
+        pythondir='$(libdir)/python$(PYTHON_VERSION)/site-packages'
+    fi
+else
+    PYTHON=
+fi
+ if test "$PYTHON_INCLUDES" != ""; then
+  WITH_PYTHON_TRUE=
+  WITH_PYTHON_FALSE='#'
+else
+  WITH_PYTHON_TRUE='#'
+  WITH_PYTHON_FALSE=
+fi
+
+if test "$PYTHON_INCLUDES" != ""
+then
+    PYTHON_SUBDIR=python
+else
+    PYTHON_SUBDIR=
+fi
+
+
+
+
+WITH_MODULES=0
+TEST_MODULES=
+
+if test "$with_modules" != "no" ; then
+ case "$host" in
+  *-*-cygwin*)
+  MODULE_EXTENSION=".dll"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lcygwin" >&5
+$as_echo_n "checking for dlopen in -lcygwin... " >&6; }
+if test "${ac_cv_lib_cygwin_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcygwin  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_cygwin_dlopen=yes
+else
+  ac_cv_lib_cygwin_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cygwin_dlopen" >&5
+$as_echo "$ac_cv_lib_cygwin_dlopen" >&6; }
+if test "x$ac_cv_lib_cygwin_dlopen" = x""yes; then :
+
+    WITH_MODULES=1
+    MODULE_PLATFORM_LIBS=
+
+$as_echo "#define HAVE_DLOPEN /**/" >>confdefs.h
+
+
+fi
+
+  ;;
+  *-*-mingw*)
+  MODULE_EXTENSION=".dll"
+  WITH_MODULES=1
+  ;;
+  *)
+  ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+  libxml_have_shl_load=yes
+else
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+
+      MODULE_PLATFORM_LIBS="-ldld"
+      libxml_have_shl_load=yes
+else
+
+      ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+  libxml_have_dlopen=yes
+else
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+
+          MODULE_PLATFORM_LIBS="-ldl"
+          libxml_have_dlopen=yes
+fi
+
+fi
+
+fi
+
+fi
+
+
+  if test "${libxml_have_shl_load}" = "yes"; then
+    MODULE_EXTENSION=".sl"
+    WITH_MODULES=1
+
+$as_echo "#define HAVE_SHLLOAD /**/" >>confdefs.h
+
+  fi
+
+  if test "${libxml_have_dlopen}" = "yes"; then
+    case "${host}" in
+      *-*-hpux* )
+	MODULE_EXTENSION=".sl"
+	;;
+      * )
+	MODULE_EXTENSION=".so"
+	;;
+    esac
+
+    WITH_MODULES=1
+
+$as_echo "#define HAVE_DLOPEN /**/" >>confdefs.h
+
+  fi
+ ;;
+ esac
+fi
+
+if test "${WITH_MODULES}" = "1"; then
+  TEST_MODULES="ModuleTests"
+fi
+
+
+
+
+
+
+
+if [ "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/XML" ] || \
+   [ "${LOGNAME}" = "veillard" -a "`pwd`" = "/home/veillard/libxml2" ] || \
+   [ "${LOGNAME}" = "bill" -a "`pwd`" = "/home/bill/gnomesvn/libxml2" ]
+   then
+    if test "$with_minimum" != "yes"
+    then
+	if test "${with_mem_debug}" = "" ; then
+	    echo Activating memory debugging
+	    with_mem_debug="yes"
+	    with_run_debug="yes"
+	fi
+	if test "${with_docbook}" = "" ; then
+	    with_docbook="yes"
+	fi
+    fi
+    if test "${GCC}" = "yes" ; then
+    CFLAGS="-g -O -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
+    fi
+    STATIC_BINARIES="-static"
+else
+    STATIC_BINARIES=
+fi
+
+
+
+if test "${NEED_TRIO}" = "1" ; then
+    echo Adding trio library for string functions
+    WITH_TRIO=1
+else
+    WITH_TRIO=0
+fi
+ if test "${NEED_TRIO}" = "1"; then
+  WITH_TRIO_SOURCES_TRUE=
+  WITH_TRIO_SOURCES_FALSE='#'
+else
+  WITH_TRIO_SOURCES_TRUE='#'
+  WITH_TRIO_SOURCES_FALSE=
+fi
+
+
+
+echo Checking configuration requirements
+
+THREAD_LIBS=""
+BASE_THREAD_LIBS=""
+WITH_THREADS=0
+THREAD_CFLAGS=""
+TEST_THREADS=""
+THREADS_W32=""
+
+if test "$with_threads" = "no" ; then
+    echo Disabling multithreaded support
+else
+    echo Enabling multithreaded support
+        if test "$with_threads" = "pthread" || test "$with_threads" = "" || test "$with_threads" = "yes" ; then
+        ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = x""yes; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in -lpthread" >&5
+$as_echo_n "checking for pthread_join in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_join+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread_pthread_join=yes
+else
+  ac_cv_lib_pthread_pthread_join=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_join" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_join" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_join" = x""yes; then :
+
+	       THREAD_LIBS="-lpthread"
+
+$as_echo "#define HAVE_LIBPTHREAD /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_PTHREAD_H /**/" >>confdefs.h
+
+	       WITH_THREADS="1"
+fi
+
+fi
+
+
+    fi
+    case $host_os in
+       *mingw32*) if test "$THREAD_LIBS" != "-lpthread"; then
+               WITH_THREADS="1"
+               THREADS_W32="Win32"
+	       THREAD_CFLAGS="$THREAD_CFLAGS -DHAVE_WIN32_THREADS"
+           fi
+       ;;
+       *cygwin*) THREAD_LIBS=""
+       ;;
+       *beos*) WITH_THREADS="1"
+	   THREAD_CFLAGS="$THREAD_CFLAGS -DHAVE_BEOS_THREADS"
+       ;;
+       *linux*)
+           if test "${GCC}" = "yes" ; then
+	       GCC_VERSION=`${CC} --version | head -1 | awk '{print $3}'`
+	       GCC_MAJOR=`echo ${GCC_VERSION} | sed 's+\..*++'`
+	       GCC_MEDIUM=`echo ${GCC_VERSION} | sed 's+[0-9]*\.++' | sed 's+\..*++'`
+	       if test "${THREAD_LIBS}" = "-lpthread" ; then
+	           if expr ${GCC_MEDIUM} \> 2 \& ${GCC_MAJOR} = 3 > /dev/null
+		   then
+		       THREAD_LIBS=""
+		       BASE_THREAD_LIBS="-lpthread"
+		   else
+		   if expr ${GCC_MAJOR} \> 3 > /dev/null
+		   then
+		       THREAD_LIBS=""
+		       BASE_THREAD_LIBS="-lpthread"
+		   else
+		       echo old GCC disabling weak symbols for pthread
+		   fi
+		   fi
+	       fi
+	   fi
+       ;;
+    esac
+    if test "$WITH_THREADS" = "1" ; then
+	THREAD_CFLAGS="$THREAD_CFLAGS -D_REENTRANT"
+	TEST_THREADS="Threadtests"
+    fi
+fi
+if test "$with_thread_alloc" = "yes" -a "$WITH_THREADS" = "1" ; then
+    THREAD_CFLAGS="$THREAD_CFLAGS -DLIBXML_THREAD_ALLOC_ENABLED"
+fi
+
+
+
+
+
+
+
+
+if test "$with_history" = "yes" ; then
+    echo Enabling xmllint shell history
+            unset tcap
+    for termlib in ncurses curses termcap terminfo termlib; do
+	as_ac_Lib=`$as_echo "ac_cv_lib_${termlib}''_tputs" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tputs in -l${termlib}" >&5
+$as_echo_n "checking for tputs in -l${termlib}... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l${termlib}  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+int
+main ()
+{
+return tputs ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  tcap="-l$termlib"
+fi
+
+	test -n "$tcap" && break
+    done
+
+    ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default"
+if test "x$ac_cv_header_readline_history_h" = x""yes; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -lhistory" >&5
+$as_echo_n "checking for append_history in -lhistory... " >&6; }
+if test "${ac_cv_lib_history_append_history+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lhistory  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char append_history ();
+int
+main ()
+{
+return append_history ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_history_append_history=yes
+else
+  ac_cv_lib_history_append_history=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_history_append_history" >&5
+$as_echo "$ac_cv_lib_history_append_history" >&6; }
+if test "x$ac_cv_lib_history_append_history" = x""yes; then :
+
+	   RDL_LIBS="-lhistory"
+
+$as_echo "#define HAVE_LIBHISTORY /**/" >>confdefs.h
+
+fi
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_readline_readline_h" = x""yes; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5
+$as_echo_n "checking for readline in -lreadline... " >&6; }
+if test "${ac_cv_lib_readline_readline+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $tcap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_readline=yes
+else
+  ac_cv_lib_readline_readline=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5
+$as_echo "$ac_cv_lib_readline_readline" >&6; }
+if test "x$ac_cv_lib_readline_readline" = x""yes; then :
+
+	   RDL_LIBS="-lreadline $RDL_LIBS $tcap"
+
+$as_echo "#define HAVE_LIBREADLINE /**/" >>confdefs.h
+
+fi
+
+fi
+
+
+    if test -n "$RDL_DIR" -a -n "$RDL_LIBS"; then
+	CPPFLAGS="$CPPFLAGS -I${RDL_DIR}/include"
+	RDL_LIBS="-L${RDL_DIR}/lib $RDL_LIBS"
+    fi
+fi
+
+if test "$with_tree" = "no" ; then
+    echo Disabling DOM like tree manipulation APIs
+    WITH_TREE=0
+else
+    WITH_TREE=1
+fi
+
+
+if test "$with_ftp" = "no" ; then
+    echo Disabling FTP support
+    WITH_FTP=0
+    FTP_OBJ=
+else
+    WITH_FTP=1
+    FTP_OBJ=nanoftp.o
+fi
+
+
+
+if test "$with_http" = "no" ; then
+    echo Disabling HTTP support
+    WITH_HTTP=0
+    HTTP_OBJ=
+else
+    WITH_HTTP=1
+    HTTP_OBJ=nanohttp.o
+fi
+
+
+
+if test "$with_legacy" = "no" ; then
+    echo Disabling deprecated APIs
+    WITH_LEGACY=0
+else
+    WITH_LEGACY=1
+fi
+
+
+if test "$with_reader" = "no" ; then
+    echo Disabling the xmlReader parsing interface
+    WITH_READER=0
+    READER_TEST=
+else
+    WITH_READER=1
+    READER_TEST=Readertests
+    if test "$with_push" = "no" ; then
+        echo xmlReader requires Push interface - enabling it
+	with_push=yes
+    fi
+fi
+
+
+
+if test "$with_writer" = "no" ; then
+    echo Disabling the xmlWriter saving interface
+    WITH_WRITER=0
+#    WRITER_TEST=
+else
+    WITH_WRITER=1
+#    WRITER_TEST=Writertests
+    if test "$with_push" = "no" ; then
+        echo xmlWriter requires Push interface - enabling it
+	with_push=yes
+    fi
+    if test "$with_output" = "no" ; then
+        echo xmlWriter requires Output interface - enabling it
+	with_output=yes
+    fi
+fi
+
+#AC_SUBST(WRITER_TEST)
+
+if test "$with_pattern" = "no" ; then
+    echo Disabling the xmlPattern parsing interface
+    WITH_PATTERN=0
+    TEST_PATTERN=
+else
+    WITH_PATTERN=1
+    TEST_PATTERN=Patterntests
+fi
+
+
+
+if test "$with_sax1" = "no" ; then
+    echo Disabling the older SAX1 interface
+    WITH_SAX1=0
+    TEST_SAX=
+else
+    WITH_SAX1=1
+    TEST_SAX=SAXtests
+fi
+
+
+
+if test "$with_push" = "no" ; then
+    echo Disabling the PUSH parser interfaces
+    WITH_PUSH=0
+    TEST_PUSH=
+else
+    WITH_PUSH=1
+    TEST_PUSH="XMLPushtests"
+fi
+
+
+
+if test "$with_html" = "no" ; then
+    echo Disabling HTML support
+    WITH_HTML=0
+    HTML_OBJ=
+    TEST_HTML=
+else
+    WITH_HTML=1
+    HTML_OBJ="HTMLparser.o HTMLtree.o"
+    TEST_HTML=HTMLtests
+    if test "$with_push" != "no" ; then
+        TEST_PHTML=HTMLPushtests
+    else
+        TEST_PHTML=
+    fi
+fi
+
+
+
+
+
+if test "$with_valid" = "no" ; then
+    echo Disabling DTD validation support
+    WITH_VALID=0
+    TEST_VALID=
+    TEST_VTIME=
+else
+    WITH_VALID=1
+    TEST_VALID=Validtests
+    TEST_VTIME=VTimingtests
+fi
+
+
+
+
+if test "$with_catalog" = "no" ; then
+    echo Disabling Catalog support
+    WITH_CATALOG=0
+    CATALOG_OBJ=
+    TEST_CATALOG=
+else
+    WITH_CATALOG=1
+    CATALOG_OBJ="catalog.o"
+    TEST_CATALOG=Catatests
+fi
+
+
+
+
+if test "$with_docbook" = "no" ; then
+    echo Disabling Docbook support
+    WITH_DOCB=0
+    DOCB_OBJ=
+else
+    WITH_DOCB=1
+    DOCB_OBJ="DOCBparser.o"
+fi
+
+
+
+
+if test "$with_xptr" = "no" ; then
+    echo Disabling XPointer support
+    WITH_XPTR=0
+    XPTR_OBJ=
+    TEST_XPTR=
+else
+    WITH_XPTR=1
+    XPTR_OBJ=xpointer.o
+    TEST_XPTR=XPtrtests
+    if test "$with_xpath" = "no" ; then
+        echo XPointer requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+
+
+
+
+if test "$with_c14n" = "no" ; then
+    echo Disabling C14N support
+    WITH_C14N=0
+    C14N_OBJ=
+    TEST_C14N=
+else
+    WITH_C14N=1
+    C14N_OBJ="c14n.c"
+    TEST_C14N=C14Ntests
+    if test "$with_xpath" = "no" ; then
+        echo C14N requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+
+
+
+
+if test "$with_xinclude" = "no" ; then
+    echo Disabling XInclude support
+    WITH_XINCLUDE=0
+    XINCLUDE_OBJ=
+    with_xinclude="no"
+    TEST_XINCLUDE=
+else
+    WITH_XINCLUDE=1
+    XINCLUDE_OBJ=xinclude.o
+    TEST_XINCLUDE=XIncludetests
+    if test "$with_xpath" = "no" ; then
+        echo XInclude requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+
+
+
+
+if test "$with_xpath" = "no" ; then
+    echo Disabling XPATH support
+    WITH_XPATH=0
+    XPATH_OBJ=
+    TEST_XPATH=
+else
+    WITH_XPATH=1
+    XPATH_OBJ=xpath.o
+    TEST_XPATH=XPathtests
+fi
+
+
+
+
+if test "$with_output" = "no" ; then
+    echo Disabling serialization/saving support
+    WITH_OUTPUT=0
+else
+    WITH_OUTPUT=1
+fi
+
+
+WITH_ICU=1
+
+
+WITH_ICONV=0
+if test "$with_iconv" = "no" ; then
+    echo Disabling ICONV support
+else
+    if test "$with_iconv" != "yes" -a "$with_iconv" != "" ; then
+	CPPFLAGS="${CPPFLAGS} -I$with_iconv/include"
+	# Export this since our headers include iconv.h
+	XML_INCLUDEDIR="${XML_INCLUDEDIR} -I$with_iconv/include"
+	ICONV_LIBS="-L$with_iconv/lib"
+    fi
+
+    ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default"
+if test "x$ac_cv_header_iconv_h" = x""yes; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5
+$as_echo_n "checking for iconv... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+
+iconv_t cd = iconv_open ("","");
+iconv (cd, NULL, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	    WITH_ICONV=1
+else
+
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv in -liconv" >&5
+$as_echo_n "checking for iconv in -liconv... " >&6; }
+
+	    _ldflags="${LDFLAGS}"
+	    _libs="${LIBS}"
+	    LDFLAGS="${LDFLAGS} ${ICONV_LIBS}"
+	    LIBS="${LIBS} -liconv"
+
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+
+iconv_t cd = iconv_open ("","");
+iconv (cd, NULL, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+		WITH_ICONV=1
+		ICONV_LIBS="${ICONV_LIBS} -liconv"
+		LIBS="${_libs}"
+		LDFLAGS="${_ldflags}"
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		LIBS="${_libs}"
+		LDFLAGS="${_ldflags}"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+
+	if test "$WITH_ICONV" = "1" ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5
+$as_echo_n "checking for iconv declaration... " >&6; }
+		if test "${xml_cv_iconv_arg2+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  xml_cv_iconv_arg2=""
+else
+  xml_cv_iconv_arg2="const"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+		xml_cv_iconv_decl="extern size_t iconv (iconv_t cd, $xml_cv_iconv_arg2 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${xml_xxx:-
+	}$xml_cv_iconv_decl" >&5
+$as_echo "${xml_xxx:-
+	}$xml_cv_iconv_decl" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define ICONV_CONST $xml_cv_iconv_arg2
+_ACEOF
+
+	fi
+fi
+case "$host" in
+	*mingw*) M_LIBS=""
+	;;
+	*beos*) M_LIBS=""
+	;;
+        *haiku*) M_LIBS=""
+        ;;
+	*) M_LIBS="-lm"
+	;;
+esac
+XML_LIBS="-lxml2 $Z_LIBS $THREAD_LIBS $ICONV_LIBS $M_LIBS $LIBS"
+XML_LIBTOOLLIBS="libxml2.la"
+
+
+WITH_ISO8859X=1
+if test "$WITH_ICONV" != "1" ; then
+if test "$with_iso8859x" = "no" ; then
+    echo Disabling ISO8859X support
+    WITH_ISO8859X=0
+fi
+fi
+
+
+if test "$with_schematron" = "no" ; then
+    echo "Disabling Schematron support"
+    WITH_SCHEMATRON=0
+    TEST_SCHEMATRON=
+else
+    echo "Enabled Schematron support"
+    WITH_SCHEMATRON=1
+    TEST_SCHEMATRON="Schematrontests"
+    with_xpath=yes
+    with_pattern=yes
+fi
+
+
+
+if test "$with_schemas" = "no" ; then
+    echo "Disabling Schemas/Relax-NG support"
+    WITH_SCHEMAS=0
+    TEST_SCHEMAS=
+else
+    echo "Enabled Schemas/Relax-NG support"
+    WITH_SCHEMAS=1
+    TEST_SCHEMAS="Schemastests Relaxtests"
+    if test "$PYTHON_INCLUDES" != "" ; then
+        PYTHON_TESTS="$PYTHON_TESTS RelaxNGPythonTests SchemasPythonTests"
+    fi
+    with_regexps=yes
+fi
+
+
+
+if test "$with_regexps" = "no" ; then
+    echo Disabling Regexps support
+    WITH_REGEXPS=0
+    TEST_REGEXPS=
+else
+    WITH_REGEXPS=1
+    TEST_REGEXPS="Regexptests Automatatests"
+fi
+
+
+
+if test "$with_debug" = "no" ; then
+    echo Disabling DEBUG support
+    WITH_DEBUG=0
+    DEBUG_OBJ=
+    TEST_DEBUG=
+else
+    WITH_DEBUG=1
+    DEBUG_OBJ=debugXML.o
+    TEST_DEBUG=Scripttests
+fi
+
+
+
+
+if test "$with_mem_debug" = "yes" ; then
+    if test "$with_thread_alloc" = "yes" ; then
+        echo Disabling memory debug - cannot use mem-debug with thread-alloc!
+	WITH_MEM_DEBUG=0
+    else
+        echo Enabling memory debug support
+        WITH_MEM_DEBUG=1
+    fi
+else
+    WITH_MEM_DEBUG=0
+fi
+
+
+if test "$with_run_debug" = "yes" ; then
+    echo Enabling runtime debug support
+    WITH_RUN_DEBUG=1
+else
+    WITH_RUN_DEBUG=0
+fi
+
+
+WIN32_EXTRA_LIBADD=
+WIN32_EXTRA_LDFLAGS=
+CYGWIN_EXTRA_LDFLAGS=
+CYGWIN_EXTRA_PYTHON_LIBADD=
+case "$host" in
+ *-*-mingw*)
+ CPPFLAGS="$CPPFLAGS -DWIN32"
+ WIN32_EXTRA_LIBADD="-lws2_32"
+ WIN32_EXTRA_LDFLAGS="-no-undefined"
+
+$as_echo "#define _WINSOCKAPI_ 1" >>confdefs.h
+
+
+$as_echo "#define snprintf _snprintf" >>confdefs.h
+
+
+$as_echo "#define vsnprintf _vsnprintf" >>confdefs.h
+
+ ;;
+ *-*-cygwin*)
+ CYGWIN_EXTRA_LDFLAGS="-no-undefined"
+ if test "${PYTHON}" != ""
+ then
+   CYGWIN_EXTRA_PYTHON_LIBADD="-L/usr/lib/python${PYTHON_VERSION}/config -lpython${PYTHON_VERSION}"
+ fi
+ ;;
+esac
+
+
+
+
+
+if test "$with_coverage" = "yes" -a "${GCC}" = "yes"
+then
+    echo Enabling code coverage for GCC
+    CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
+    LDFLAGS="$LDFLAGS -fprofile-arcs -ftest-coverage"
+else
+    echo Disabling code coverage for GCC
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RELDATE=`date +'%a %b %e %Y'`
+
+
+
+rm -f COPYING.LIB COPYING
+ln -s Copyright COPYING
+
+# keep on one line for cygwin c.f. #130896
+ac_config_files="$ac_config_files include/libxml/xmlversion.h xml2-config"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_VERSION_SCRIPT_TRUE}" && test -z "${USE_VERSION_SCRIPT_FALSE}"; then
+  as_fn_error "conditional \"USE_VERSION_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${REBUILD_DOCS_TRUE}" && test -z "${REBUILD_DOCS_FALSE}"; then
+  as_fn_error "conditional \"REBUILD_DOCS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PYTHON_TRUE}" && test -z "${WITH_PYTHON_FALSE}"; then
+  as_fn_error "conditional \"WITH_PYTHON\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_TRIO_SOURCES_TRUE}" && test -z "${WITH_TRIO_SOURCES_FALSE}"; then
+  as_fn_error "conditional \"WITH_TRIO_SOURCES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.65.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.65,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"')  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+  ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "include/libxml/xmlversion.h") CONFIG_FILES="$CONFIG_FILES include/libxml/xmlversion.h" ;;
+    "xml2-config") CONFIG_FILES="$CONFIG_FILES xml2-config" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Assembler program.
+AS=$AS
+
+# DLL creation program.
+DLLTOOL=$DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$OBJDUMP
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1+=\$2"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+    ;;
+  esac
+
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+chmod +x xml2-config
+echo Done configuring
diff --git a/src/configure.in b/src/configure.in
new file mode 100644
index 0000000..17c11cd
--- /dev/null
+++ b/src/configure.in
@@ -0,0 +1,1462 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(entities.c)
+AM_CONFIG_HEADER(config.h)
+AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_HOST
+
+LIBXML_MAJOR_VERSION=2
+LIBXML_MINOR_VERSION=7
+LIBXML_MICRO_VERSION=7
+LIBXML_MICRO_VERSION_SUFFIX=
+LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX
+LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
+
+LIBXML_VERSION_NUMBER=`expr $LIBXML_MAJOR_VERSION \* 10000 + $LIBXML_MINOR_VERSION \* 100 + $LIBXML_MICRO_VERSION`
+
+if test -f CVS/Entries ; then
+  extra=`grep ChangeLog CVS/Entries | grep -v LIBXML | sed -e s\%/ChangeLog/1\.%% -e s\%/.*$%%`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-CVS$extra"
+  fi
+else if test -d .svn ; then
+  extra=`svn info | grep Revision | sed 's+Revision: ++'`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-SVN$extra"
+  fi
+else if test -d .git ; then
+  extra=`git describe | sed 's+LIBXML[[0-9.]]*-++'`
+  echo extra=$extra
+  if test "$extra" != ""
+  then
+      LIBXML_VERSION_EXTRA="-GIT$extra"
+  fi
+fi
+fi
+fi
+AC_SUBST(LIBXML_MAJOR_VERSION)
+AC_SUBST(LIBXML_MINOR_VERSION)
+AC_SUBST(LIBXML_MICRO_VERSION)
+AC_SUBST(LIBXML_VERSION)
+AC_SUBST(LIBXML_VERSION_INFO)
+AC_SUBST(LIBXML_VERSION_NUMBER)
+AC_SUBST(LIBXML_VERSION_EXTRA)
+
+VERSION=${LIBXML_VERSION}
+
+AM_INIT_AUTOMAKE(libxml2, $VERSION)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_CPP
+AC_PATH_PROG(RM, rm, /bin/rm)
+AC_PATH_PROG(MV, mv, /bin/mv)
+AC_PATH_PROG(TAR, tar, /bin/tar)
+AC_PATH_PROG(PERL, perl, /usr/bin/perl)
+AC_PATH_PROG(WGET, wget, /usr/bin/wget)
+AC_PATH_PROG(XMLLINT, xmllint, /usr/bin/xmllint)
+AC_PATH_PROG(XSLTPROC, xsltproc, /usr/bin/xsltproc)
+
+dnl Make sure we have an ANSI compiler
+AM_C_PROTOTYPES
+test "x$U" != "x" && AC_MSG_ERROR(Compiler not ANSI compliant)
+
+AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
+
+dnl
+dnl if the system support linker version scripts for symbol versioning
+dnl then add it
+dnl
+VERSION_SCRIPT_FLAGS=
+# lt_cv_prog_gnu_ld is from libtool 2.+
+if test "$lt_cv_prog_gnu_ld" = yes; then
+  VERSION_SCRIPT_FLAGS=-Wl,--version-script=
+else
+  case $host in
+  *-*-sunos*) VERSION_SCRIPT_FLAGS="-Wl,-M -Wl,";;
+  esac
+fi
+AC_SUBST(VERSION_SCRIPT_FLAGS)
+AM_CONDITIONAL([USE_VERSION_SCRIPT], [test -n "$VERSION_SCRIPT_FLAGS"])
+
+dnl
+dnl We process the AC_ARG_WITH first so that later we can modify
+dnl some of them to try to prevent impossible combinations.  This
+dnl also allows up so alphabetize the choices
+dnl
+
+dnl
+dnl zlib option might change flags, so we save them initially
+dnl
+_cppflags="${CPPFLAGS}"
+_ldflags="${LDFLAGS}"
+
+AC_ARG_WITH(c14n,
+[  --with-c14n             add the Canonicalization support (on)])
+AC_ARG_WITH(catalog,
+[  --with-catalog          add the Catalog support (on)])
+AC_ARG_WITH(debug,
+[  --with-debug            add the debugging module (on)])
+AC_ARG_WITH(docbook,
+[  --with-docbook          add Docbook SGML support (on)])
+AC_ARG_WITH(fexceptions,
+[  --with-fexceptions      add GCC flag -fexceptions for C++ exceptions (off)])
+AC_ARG_WITH(ftp,
+[  --with-ftp              add the FTP support (on)])
+AC_ARG_WITH(history,
+[  --with-history          add history support to xmllint shell(off)])
+AC_ARG_WITH(html,
+[  --with-html             add the HTML support (on)])
+dnl Specific dir for HTML output ?
+AC_ARG_WITH(html-dir, AC_HELP_STRING([--with-html-dir=path],
+            [path to base html directory, default $datadir/doc/html]),
+            [HTML_DIR=$withval], [HTML_DIR='$(datadir)/doc'])
+
+AC_ARG_WITH(html-subdir, AC_HELP_STRING([--with-html-subdir=path],
+            [directory used under html-dir, default $PACKAGE-$VERSION/html]),
+            [test "x$withval" != "x" && HTML_DIR="$HTML_DIR/$withval"],
+            [HTML_DIR="$HTML_DIR/\$(PACKAGE)-\$(VERSION)/html"])
+AC_SUBST(HTML_DIR)
+AC_ARG_WITH(http,
+[  --with-http             add the HTTP support (on)])
+AC_ARG_WITH(iconv,
+[  --with-iconv[[=DIR]]      add ICONV support (on)])
+AC_ARG_WITH(iso8859x,
+[  --with-iso8859x         add ISO8859X support if no iconv (on)])
+AC_ARG_WITH(legacy,
+[  --with-legacy           add deprecated APIs for compatibility (on)])
+AC_ARG_WITH(mem_debug,
+[  --with-mem-debug        add the memory debugging module (off)])
+AC_ARG_WITH(minimum,
+[  --with-minimum          build a minimally sized library (off)])
+AC_ARG_WITH(output,
+[  --with-output           add the serialization support (on)])
+AC_ARG_WITH(pattern,
+[  --with-pattern          add the xmlPattern selection interface (on)])
+AC_ARG_WITH(push,
+[  --with-push             add the PUSH parser interfaces (on)])
+AC_ARG_WITH(python,
+[  --with-python[[=DIR]]     build Python bindings if found])
+AC_ARG_WITH(reader,
+[  --with-reader           add the xmlReader parsing interface (on)])
+AC_ARG_WITH(readline,
+[  --with-readline=DIR     use readline in DIR],[
+  if test "$withval" != "no" -a "$withval" != "yes"; then
+    RDL_DIR=$withval
+    CPPFLAGS="${CPPFLAGS} -I$withval/include"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
+  fi
+])
+AC_ARG_WITH(regexps,
+[  --with-regexps          add Regular Expressions support (on)])
+AC_ARG_WITH(run_debug,
+[  --with-run-debug        add the runtime debugging module (off)])
+AC_ARG_WITH(sax1,
+[  --with-sax1             add the older SAX1 interface (on)])
+AC_ARG_WITH(schemas,
+[  --with-schemas          add Relax-NG and Schemas support (on)])
+AC_ARG_WITH(schematron,
+[  --with-schematron       add Schematron support (on)])
+AC_ARG_WITH(threads,
+[  --with-threads          add multithread support(on)])
+AC_ARG_WITH(thread-alloc,
+[  --with-thread-alloc     add per-thread memory(off)])
+AC_ARG_WITH(tree,
+[  --with-tree             add the DOM like tree manipulation APIs (on)])
+AC_ARG_WITH(valid,
+[  --with-valid            add the DTD validation support (on)])
+AC_ARG_WITH(writer,
+[  --with-writer           add the xmlWriter saving interface (on)])
+AC_ARG_WITH(xinclude,
+[  --with-xinclude         add the XInclude support (on)])
+AC_ARG_WITH(xpath,
+[  --with-xpath            add the XPATH support (on)])
+AC_ARG_WITH(xptr,
+[  --with-xptr             add the XPointer support (on)])
+AC_ARG_WITH(modules,
+[  --with-modules          add the dynamic modules support (on)])
+AC_ARG_WITH(zlib,
+[  --with-zlib[[=DIR]]       use libz in DIR],[
+  if test "$withval" != "no" -a "$withval" != "yes"; then
+    Z_DIR=$withval
+    CPPFLAGS="${CPPFLAGS} -I$withval/include"
+    LDFLAGS="${LDFLAGS} -L$withval/lib"
+  fi
+])
+AC_ARG_WITH(coverage,
+[  --with-coverage         build for code coverage with GCC (off)])
+
+AC_ARG_ENABLE(rebuild-docs,
+[  --enable-rebuild-docs[[=yes/no]]  rebuild some generated docs [[default=yes]]])
+AM_CONDITIONAL([REBUILD_DOCS], [test "$enable_rebuild_docs" = "no"])
+
+dnl
+dnl hard dependancies on options
+dnl
+if test "$with_schemas" = "yes"
+then
+    with_pattern=yes
+    with_regexps=yes
+fi
+if test "$with_schematron" = "yes"
+then
+    with_pattern=yes
+    with_xpath=yes
+fi
+if test "$with_reader" = "yes"
+then
+    with_push=yes
+fi
+if test "$with_xptr" = "yes"
+then
+    with_xpath=yes
+fi
+dnl
+dnl option to build a minimal libxml2 library
+dnl
+if test "$with_minimum" = "yes"
+then
+    echo "Configuring for a minimal library"
+    if test "$with_c14n" = ""
+    then
+      with_c14n=no
+    fi
+    if test "$with_catalog" = ""
+    then
+      with_catalog=no
+    fi
+    echo So far so good!
+    if test "$with_debug" = ""
+    then
+      with_debug=no
+    fi
+    if test "$with_docbook" = ""
+    then
+      with_docbook=no
+    fi
+    if test "$with_fexceptions" = ""
+    then
+      with_fexceptions=no
+    fi
+    if test "$with_ftp" = ""
+    then
+      with_ftp=no 
+    fi
+    if test "$with_history" = ""
+    then
+      with_history=no
+    fi
+    if test "$with_html" = ""
+    then
+      with_html=no
+    fi
+    if test "$with_http" = ""
+    then
+      with_http=no 
+    fi
+    if test "$with_iconv" = ""
+    then
+      with_iconv=no
+    fi
+    if test "$with_iso8859x" = ""
+    then
+      with_iso8859x=no
+    fi
+    if test "$with_legacy" = ""
+    then
+      with_legacy=no
+    fi
+    if test "$with_mem_debug" = ""
+    then 
+      with_mem_debug=no
+    fi
+    if test "$with_output" = ""
+    then
+      with_output=no
+    fi
+    if test "$with_pattern" = ""
+    then
+      with_pattern=no
+    fi
+    if test "$with_push" = ""
+    then
+      with_push=no
+    fi
+    if test "$with_python" = ""
+    then
+      with_python=no
+    fi
+    if test "$with_reader" = ""
+    then
+      with_reader=no
+    fi
+    if test "$with_readline" = ""
+    then
+      with_readline=no
+    fi
+    if test "$with_regexps" = ""
+    then
+      with_regexps=no
+    fi
+    if test "$with_run_debug" = ""
+    then
+      with_run_debug=no
+    fi
+    if test "$with_sax1" = ""
+    then
+      with_sax1=no
+    fi
+    if test "$with_schemas" = ""
+    then
+      with_schemas=no
+    fi
+    if test "$with_schematron" = ""
+    then
+      with_schematron=no
+    fi
+    if test "$with_threads" = ""
+    then
+      with_threads=no
+    fi
+    if test "$with_thread_alloc" = ""
+    then
+      with_thread_alloc=no
+   fi
+    if test "$with_tree" = ""
+    then
+      with_tree=no
+    fi
+    if test "$with_valid" = ""
+    then
+      with_valid=no
+    fi
+    if test "$with_writer" = ""
+    then
+      with_writer=no
+    fi
+    if test "$with_xinclude" = ""
+    then
+      with_xinclude=no
+    fi
+    if test "$with_xpath" = ""
+    then
+      with_xpath=no
+    fi
+    if test "$with_xptr" = ""
+    then
+      with_xptr=no
+    fi
+    if test "$with_zlib" = ""
+    then
+      with_zlib=no
+    fi
+    if test "$with_modules" = ""
+    then
+      with_modules=no
+    fi
+fi
+
+echo Checking zlib
+
+dnl Checks for zlib library.
+
+WITH_ZLIB=0
+if test "$with_zlib" = "no"; then
+    echo "Disabling compression support"
+else
+    AC_CHECK_HEADERS(zlib.h,
+	AC_CHECK_LIB(z, gzread,[
+	    AC_DEFINE([HAVE_LIBZ], [1], [Have compression library])
+	    WITH_ZLIB=1
+	    if test "x${Z_DIR}" != "x"; then
+		Z_CFLAGS="-I${Z_DIR}/include"
+		Z_LIBS="-L${Z_DIR}/lib -lz"
+		[case ${host} in
+		    *-*-solaris*)
+			Z_LIBS="-L${Z_DIR}/lib -R${Z_DIR}/lib -lz"
+			;;
+		esac]
+	    else
+		Z_LIBS="-lz"
+	    fi]))
+fi
+
+AC_SUBST(Z_CFLAGS)
+AC_SUBST(Z_LIBS)
+AC_SUBST(WITH_ZLIB)
+
+CPPFLAGS=${_cppflags}
+LDFLAGS=${_ldflags}
+
+echo Checking headers
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h])
+AC_CHECK_HEADERS([unistd.h])
+AC_CHECK_HEADERS([ctype.h])
+AC_CHECK_HEADERS([dirent.h])
+AC_CHECK_HEADERS([errno.h])
+AC_CHECK_HEADERS([malloc.h])
+AC_CHECK_HEADERS([stdarg.h])
+AC_CHECK_HEADERS([sys/stat.h])
+AC_CHECK_HEADERS([sys/types.h])
+AC_CHECK_HEADERS([stdint.h])
+AC_CHECK_HEADERS([inttypes.h.h])
+AC_CHECK_HEADERS([time.h])
+AC_CHECK_HEADERS([ansidecl.h])
+AC_CHECK_HEADERS([ieeefp.h])
+AC_CHECK_HEADERS([nan.h])
+AC_CHECK_HEADERS([math.h])
+AC_CHECK_HEADERS([limits.h])
+AC_CHECK_HEADERS([fp_class.h])
+AC_CHECK_HEADERS([float.h])
+AC_CHECK_HEADERS([stdlib.h])
+AC_CHECK_HEADERS([sys/socket.h], [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+])
+AC_CHECK_HEADERS([netinet/in.h], [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+])
+AC_CHECK_HEADERS([arpa/inet.h], [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+#if HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+])
+AC_CHECK_HEADERS([netdb.h])
+AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_HEADERS([sys/select.h])
+AC_CHECK_HEADERS([poll.h])
+AC_CHECK_HEADERS([sys/mman.h])
+AC_CHECK_HEADERS([sys/timeb.h])
+AC_CHECK_HEADERS([signal.h])
+AC_CHECK_HEADERS([arpa/nameser.h], [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+])
+AC_CHECK_HEADERS([resolv.h], [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+#if HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+# endif
+])
+AC_CHECK_HEADERS([dl.h])
+AC_CHECK_HEADERS([dlfcn.h])
+
+
+echo Checking libraries
+
+dnl Checks for library functions.
+AC_FUNC_STRFTIME
+AC_CHECK_FUNCS(strdup strndup strerror)
+AC_CHECK_FUNCS(finite isnand fp_class class fpclass)
+AC_CHECK_FUNCS(strftime localtime gettimeofday ftime)
+AC_CHECK_FUNCS(stat _stat signal)
+
+dnl Checking the standard string functions availability
+AC_CHECK_FUNCS(printf sprintf fprintf snprintf vfprintf vsprintf vsnprintf sscanf,,
+               NEED_TRIO=1)
+
+dnl Checking for va_copy availability
+AC_MSG_CHECKING([for va_copy])
+AC_TRY_LINK([#include <stdarg.h>
+va_list ap1,ap2;], [va_copy(ap1,ap2);],
+have_va_copy=yes,
+have_va_copy=no)
+AC_MSG_RESULT($have_va_copy)
+if test x"$have_va_copy" = x"yes"; then
+    AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
+else
+    AC_MSG_CHECKING([for __va_copy])
+    AC_TRY_LINK([#include <stdarg.h>
+    va_list ap1,ap2;], [__va_copy(ap1,ap2);],
+    have___va_copy=yes,
+    have___va_copy=no)
+    AC_MSG_RESULT($have___va_copy)
+    if test x"$have___va_copy" = x"yes"; then
+        AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available])
+    fi
+fi
+
+dnl Checks for inet libraries:
+AC_SEARCH_LIBS(gethostent, [nsl])
+AC_SEARCH_LIBS(setsockopt, [socket net network])
+AC_SEARCH_LIBS(connect, [inet])
+
+dnl Determine what socket length (socklen_t) data type is
+AC_MSG_CHECKING([for type of socket length (socklen_t)])
+AC_TRY_COMPILE2([
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>],[
+(void)getsockopt (1, 1, 1, NULL, (socklen_t *)NULL)],[
+  AC_MSG_RESULT(socklen_t *)
+  XML_SOCKLEN_T=socklen_t],[
+  AC_TRY_COMPILE2([
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>],[
+(void)getsockopt (1, 1, 1, NULL, (size_t *)NULL)],[
+    AC_MSG_RESULT(size_t *)
+    XML_SOCKLEN_T=size_t],[
+    AC_TRY_COMPILE2([
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h>],[
+(void)getsockopt (1, 1, 1, NULL, (int *)NULL)],[
+      AC_MSG_RESULT(int *)
+      XML_SOCKLEN_T=int],[
+      AC_MSG_WARN(could not determine)
+      XML_SOCKLEN_T="int"])])])
+AC_DEFINE_UNQUOTED(XML_SOCKLEN_T, $XML_SOCKLEN_T, [Determine what socket length (socklen_t) data type is])
+
+dnl ***********************Checking for availability of IPv6*******************
+
+AC_MSG_CHECKING([whether to enable IPv6])
+AC_ARG_ENABLE(ipv6, [  --enable-ipv6[[=yes/no]]  enables compilation of IPv6 code [[default=yes]]],, enable_ipv6=yes)
+if test "$with_minimum" = "yes"
+then
+    enable_ipv6=no
+fi
+if test $enable_ipv6 = yes; then
+  have_ipv6=no
+  AC_TRY_COMPILE([
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    ], [
+    struct sockaddr_storage ss;
+    socket(AF_INET6, SOCK_STREAM, 0)
+    ],
+    have_ipv6=yes,
+    have_ipv6=no
+  )
+  AC_MSG_RESULT($have_ipv6)
+
+  if test $have_ipv6 = yes; then
+    AC_DEFINE([SUPPORT_IP6], [], [Support for IPv6])
+    have_broken_ss_family=no
+
+    dnl *********************************************************************
+    dnl on some platforms (like AIX 5L), the structure sockaddr doesn't have
+    dnl a ss_family member, but rather __ss_family. Let's detect that
+    dnl and define the HAVE_BROKEN_SS_FAMILY when we are on one of these
+    dnl platforms.  However, we should only do this if ss_family is not
+    dnl present.
+    dnl ********************************************************************
+    AC_MSG_CHECKING([struct sockaddr::ss_family])
+    AC_TRY_COMPILE([
+      #include <sys/types.h>
+      #include <sys/socket.h>
+      ], [
+      struct sockaddr_storage ss ;
+      ss.ss_family = 0 ;
+      ],
+      have_ss_family=yes,
+      have_ss_family=no
+    )
+    AC_MSG_RESULT($have_ss_family)
+    if test x$have_ss_family = xno ; then
+      AC_MSG_CHECKING([broken struct sockaddr::ss_family])
+      AC_TRY_COMPILE([
+        #include <sys/types.h>
+        #include <sys/socket.h>
+        ], [
+        struct sockaddr_storage ss ;
+        ss.__ss_family = 0 ;
+        ],
+        have_broken_ss_family=yes,
+        have_broken_ss_family=no
+      )
+      AC_MSG_RESULT($have_broken_ss_family)
+      if test x$have_broken_ss_family = xyes ; then
+        AC_DEFINE(HAVE_BROKEN_SS_FAMILY, [],
+	  [Whether struct sockaddr::__ss_family exists]) 
+        AC_DEFINE(ss_family, __ss_family,
+	  [ss_family is not defined here, use __ss_family instead])
+      else
+        AC_MSG_WARN(ss_family and __ss_family not found)
+      fi
+    fi
+
+    have_getaddrinfo=no
+    AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes)
+    if test $have_getaddrinfo != yes; then
+      for lib in bsd socket inet; do
+        AC_CHECK_LIB($lib, getaddrinfo, [LIBS="$LIBS -l$lib";have_getaddrinfo=yes;break])
+      done
+    fi
+
+    if test $have_getaddrinfo = yes; then
+      AC_DEFINE([HAVE_GETADDRINFO], [], [Define if getaddrinfo is there])
+    fi
+  fi
+fi 
+
+dnl ******************************End IPv6 checks******************************
+
+dnl Checks for isnan in libm if not in libc
+AC_CHECK_FUNC(isnan, AC_DEFINE([HAVE_ISNAN],[], [Define if isnan is there]) , AC_CHECK_LIB(m, isnan,
+  [AC_DEFINE([HAVE_ISNAN],[], [Define if isnan is there])]))
+
+AC_CHECK_FUNC(isinf, AC_DEFINE([HAVE_ISINF], [], [Define if isinf is there]) , AC_CHECK_LIB(m, isinf,
+  [AC_DEFINE([HAVE_ISINF], [], [Define if isinf is there])]))
+
+XML_LIBDIR='-L${libdir}'
+XML_INCLUDEDIR='-I${includedir}/libxml2'
+
+dnl
+dnl Extra flags
+dnl
+XML_CFLAGS=""
+RDL_LIBS=""
+
+dnl
+dnl Workaround for native compilers
+dnl  HP  : http://bugs.gnome.org/db/31/3163.html
+dnl  DEC : Enable NaN/Inf
+dnl
+if test "${GCC}" != "yes" ; then
+    case "${host}" in
+          hppa*-*-hpux* )
+	       CFLAGS="${CFLAGS} -Wp,-H30000"
+	       ;;
+          *-dec-osf* )
+               CFLAGS="${CFLAGS} -ieee"
+               ;;
+	  alpha*-*-linux* )
+	       CFLAGS="${CFLAGS} -ieee"
+	       ;;
+    esac
+else
+    if test "$with_fexceptions" = "yes"
+    then
+        #
+	# Not activated by default because this inflates the code size
+	# Used to allow propagation of C++ exceptions through the library
+	#
+	CFLAGS="${CFLAGS} -fexceptions"
+    fi
+       
+    CFLAGS="${CFLAGS} -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" 
+    case "${host}" in
+          alpha*-*-linux* )
+	       CFLAGS="${CFLAGS} -mieee"
+	       ;;
+	  alpha*-*-osf* )
+	       CFLAGS="${CFLAGS} -mieee"
+	       ;;
+    esac
+fi
+case ${host} in
+    *-*-solaris*)
+        XML_LIBDIR="${XML_LIBDIR} -R${libdir}"
+        ;;
+    hppa*-hp-mpeix)
+        NEED_TRIO=1
+	;;
+    *-*-mingw* | *-*-cygwin* | *-*-msvc* )
+        # If the host is Windows, and shared libraries are disabled, we
+        # need to add -DLIBXML_STATIC to CFLAGS in order for linking to
+        # work properly (without it, xmlexports.h would force the use of
+        # DLL imports, which obviously aren't present in a static
+        # library).
+        if test "x$enable_shared" = "xno"; then
+            XML_CFLAGS="$XML_CFLAGS -DLIBXML_STATIC"
+            CFLAGS="$CFLAGS -DLIBXML_STATIC"
+        fi
+        ;;
+esac
+
+
+dnl
+dnl check for python
+dnl
+
+PYTHON_VERSION=
+PYTHON_INCLUDES=
+PYTHON_SITE_PACKAGES=
+PYTHON_TESTS=
+pythondir=
+if test "$with_python" != "no" ; then
+    if test -x "$with_python/bin/python"
+    then
+        echo Found python in $with_python/bin/python
+        PYTHON="$with_python/bin/python"
+    else
+	if test -x "$with_python"
+	then
+	    echo Found python in $with_python
+	    PYTHON="$with_python"
+	else
+	    if test -x "$PYTHON"
+	    then
+	        echo Found python in environment PYTHON=$PYTHON
+		with_python=`$PYTHON -c "import sys; print sys.exec_prefix"`
+	    else
+		AC_PATH_PROG(PYTHON, python python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5)
+	    fi
+	fi
+    fi
+    if test "$PYTHON" != ""
+    then
+        PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[[0:3]]"`
+	echo Found Python version $PYTHON_VERSION
+    fi
+    if test "$PYTHON_VERSION" != ""
+    then
+	if test -r $with_python/include/python$PYTHON_VERSION/Python.h -a \
+	   -d $with_python/lib/python$PYTHON_VERSION/site-packages
+	then
+	    PYTHON_INCLUDES=$with_python/include/python$PYTHON_VERSION
+	    PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+	else
+	    if test -r $prefix/include/python$PYTHON_VERSION/Python.h
+	    then
+	        PYTHON_INCLUDES=$prefix/include/python$PYTHON_VERSION
+	        PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+	    else
+		if test -r /usr/include/python$PYTHON_VERSION/Python.h
+		then
+		    PYTHON_INCLUDES=/usr/include/python$PYTHON_VERSION
+	            PYTHON_SITE_PACKAGES=$libdir/python$PYTHON_VERSION/site-packages
+		else
+		    echo could not find python$PYTHON_VERSION/Python.h
+		fi
+	    fi
+	    if test ! -d "$PYTHON_SITE_PACKAGES"
+	    then
+		    PYTHON_SITE_PACKAGES=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib()"`
+	    fi
+	fi
+	PYTHON_LIBS=`python$PYTHON_VERSION-config --ldflags`
+    fi
+    if test "$with_python" != ""
+    then
+        pythondir='$(PYTHON_SITE_PACKAGES)'
+    else
+        pythondir='$(libdir)/python$(PYTHON_VERSION)/site-packages'
+    fi
+else
+    PYTHON=
+fi
+AM_CONDITIONAL(WITH_PYTHON, test "$PYTHON_INCLUDES" != "")
+if test "$PYTHON_INCLUDES" != ""
+then
+    PYTHON_SUBDIR=python
+else
+    PYTHON_SUBDIR=
+fi
+AC_SUBST(pythondir)
+AC_SUBST(PYTHON_SUBDIR)
+AC_SUBST(PYTHON_LIBS)
+
+dnl check for dso support
+WITH_MODULES=0
+TEST_MODULES=
+
+if test "$with_modules" != "no" ; then
+ case "$host" in
+  *-*-cygwin*)
+  MODULE_EXTENSION=".dll"
+  AC_CHECK_LIB(cygwin, dlopen, [
+    WITH_MODULES=1
+    MODULE_PLATFORM_LIBS=
+    AC_DEFINE([HAVE_DLOPEN], [], [Have dlopen based dso])
+  ])
+  ;;
+  *-*-mingw*)
+  MODULE_EXTENSION=".dll"
+  WITH_MODULES=1
+  ;;
+  *)
+  AC_CHECK_FUNC(shl_load, libxml_have_shl_load=yes, [
+    AC_CHECK_LIB(dld, shl_load, [
+      MODULE_PLATFORM_LIBS="-ldld"
+      libxml_have_shl_load=yes], [
+      AC_CHECK_FUNC(dlopen, libxml_have_dlopen=yes, [
+        AC_CHECK_LIB(dl, dlopen, [
+          MODULE_PLATFORM_LIBS="-ldl"
+          libxml_have_dlopen=yes])])])])
+
+  if test "${libxml_have_shl_load}" = "yes"; then
+    MODULE_EXTENSION=".sl"
+    WITH_MODULES=1
+    AC_DEFINE([HAVE_SHLLOAD], [], [Have shl_load based dso])
+  fi
+ 
+  if test "${libxml_have_dlopen}" = "yes"; then
+    case "${host}" in
+      *-*-hpux* )
+	MODULE_EXTENSION=".sl"
+	;;
+      * )
+	MODULE_EXTENSION=".so"
+	;;
+    esac
+
+    WITH_MODULES=1
+    AC_DEFINE([HAVE_DLOPEN], [], [Have dlopen based dso])
+  fi
+ ;;
+ esac
+fi
+
+if test "${WITH_MODULES}" = "1"; then
+  TEST_MODULES="ModuleTests"
+fi  
+
+AC_SUBST(WITH_MODULES)
+AC_SUBST(MODULE_PLATFORM_LIBS)
+AC_SUBST(MODULE_EXTENSION)
+AC_SUBST(TEST_MODULES)
+
+dnl
+dnl Tester makes use of readline if present
+dnl
+
+dnl
+dnl specific tests to setup DV and Bill's devel environments with debug etc ...
+dnl (-Wunreachable-code)
+dnl
+if [[ "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/XML" ]] || \
+   [[ "${LOGNAME}" = "veillard" -a "`pwd`" = "/home/veillard/libxml2" ]] || \
+   [[ "${LOGNAME}" = "bill" -a "`pwd`" = "/home/bill/gnomesvn/libxml2" ]]
+   then
+    if test "$with_minimum" != "yes"
+    then
+	if test "${with_mem_debug}" = "" ; then
+	    echo Activating memory debugging
+	    with_mem_debug="yes"
+	    with_run_debug="yes"
+	fi
+	if test "${with_docbook}" = "" ; then
+	    with_docbook="yes"
+	fi
+    fi
+    if test "${GCC}" = "yes" ; then
+    CFLAGS="-g -O -pedantic -W -Wformat -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls -Wall"
+    fi
+    STATIC_BINARIES="-static"
+dnl -Wcast-qual -ansi
+else
+    STATIC_BINARIES=
+fi
+AC_SUBST(STATIC_BINARIES)
+
+dnl
+dnl Check for trio string functions
+dnl
+
+if test "${NEED_TRIO}" = "1" ; then
+    echo Adding trio library for string functions
+    WITH_TRIO=1
+else    
+    WITH_TRIO=0
+fi
+AM_CONDITIONAL(WITH_TRIO_SOURCES, test "${NEED_TRIO}" = "1")
+AC_SUBST(WITH_TRIO)
+
+dnl
+dnl Allow to enable/disable various pieces
+dnl
+echo Checking configuration requirements
+
+dnl
+dnl Thread-related stuff
+dnl
+THREAD_LIBS=""
+BASE_THREAD_LIBS=""
+WITH_THREADS=0
+THREAD_CFLAGS=""
+TEST_THREADS=""
+THREADS_W32=""
+
+if test "$with_threads" = "no" ; then
+    echo Disabling multithreaded support
+else
+    echo Enabling multithreaded support
+    dnl Use pthread by default
+    if test "$with_threads" = "pthread" || test "$with_threads" = "" || test "$with_threads" = "yes" ; then
+        AC_CHECK_HEADER(pthread.h,
+	    AC_CHECK_LIB(pthread, pthread_join,[
+	       THREAD_LIBS="-lpthread"
+	       AC_DEFINE([HAVE_LIBPTHREAD], [], [Define if pthread library is there (-lpthread)])
+	       AC_DEFINE([HAVE_PTHREAD_H], [], [Define if <pthread.h> is there])
+	       WITH_THREADS="1"]))
+    fi
+    case $host_os in
+       *mingw32*) if test "$THREAD_LIBS" != "-lpthread"; then
+               WITH_THREADS="1"
+               THREADS_W32="Win32"
+	       THREAD_CFLAGS="$THREAD_CFLAGS -DHAVE_WIN32_THREADS"
+           fi
+       ;;
+       *cygwin*) THREAD_LIBS=""
+       ;;
+       *beos*) WITH_THREADS="1"
+	   THREAD_CFLAGS="$THREAD_CFLAGS -DHAVE_BEOS_THREADS"
+       ;;
+       *linux*)
+           if test "${GCC}" = "yes" ; then
+	       GCC_VERSION=`${CC} --version | head -1 | awk '{print $3}'`
+	       GCC_MAJOR=`echo ${GCC_VERSION} | sed 's+\..*++'`
+	       GCC_MEDIUM=`echo ${GCC_VERSION} | sed 's+[[0-9]]*\.++' | sed 's+\..*++'`
+	       if test "${THREAD_LIBS}" = "-lpthread" ; then
+	           if expr ${GCC_MEDIUM} \> 2 \& ${GCC_MAJOR} = 3 > /dev/null
+		   then
+		       THREAD_LIBS=""
+		       BASE_THREAD_LIBS="-lpthread"
+		   else
+		   if expr ${GCC_MAJOR} \> 3 > /dev/null
+		   then
+		       THREAD_LIBS=""
+		       BASE_THREAD_LIBS="-lpthread"
+		   else
+		       echo old GCC disabling weak symbols for pthread
+		   fi
+		   fi
+	       fi
+	   fi
+       ;;
+    esac
+    if test "$WITH_THREADS" = "1" ; then
+	THREAD_CFLAGS="$THREAD_CFLAGS -D_REENTRANT"
+	TEST_THREADS="Threadtests"
+    fi
+fi
+if test "$with_thread_alloc" = "yes" -a "$WITH_THREADS" = "1" ; then
+    THREAD_CFLAGS="$THREAD_CFLAGS -DLIBXML_THREAD_ALLOC_ENABLED"
+fi
+
+AC_SUBST(THREAD_LIBS)
+AC_SUBST(BASE_THREAD_LIBS)
+AC_SUBST(WITH_THREADS)
+AC_SUBST(THREAD_CFLAGS)
+AC_SUBST(TEST_THREADS)
+AC_SUBST(THREADS_W32)
+
+dnl
+dnl xmllint shell history
+dnl
+if test "$with_history" = "yes" ; then
+    echo Enabling xmllint shell history
+    dnl check for terminal library. this is a very cool solution
+    dnl from octave's configure.in
+    unset tcap
+    for termlib in ncurses curses termcap terminfo termlib; do
+	AC_CHECK_LIB(${termlib}, tputs, [tcap="-l$termlib"])
+	test -n "$tcap" && break
+    done
+
+    AC_CHECK_HEADER(readline/history.h,
+	AC_CHECK_LIB(history, append_history,[
+	   RDL_LIBS="-lhistory"
+	   AC_DEFINE([HAVE_LIBHISTORY], [], [Define if history library is there (-lhistory)])]))
+    AC_CHECK_HEADER(readline/readline.h,
+	AC_CHECK_LIB(readline, readline,[
+	   RDL_LIBS="-lreadline $RDL_LIBS $tcap"
+	   AC_DEFINE([HAVE_LIBREADLINE], [], [Define if readline library is there (-lreadline)])], , $tcap))
+    if test -n "$RDL_DIR" -a -n "$RDL_LIBS"; then
+	CPPFLAGS="$CPPFLAGS -I${RDL_DIR}/include"
+	RDL_LIBS="-L${RDL_DIR}/lib $RDL_LIBS"
+    fi
+fi
+
+dnl
+dnl Tree functions
+dnl
+if test "$with_tree" = "no" ; then
+    echo Disabling DOM like tree manipulation APIs
+    WITH_TREE=0
+else    
+    WITH_TREE=1
+fi
+AC_SUBST(WITH_TREE)
+
+if test "$with_ftp" = "no" ; then
+    echo Disabling FTP support
+    WITH_FTP=0
+    FTP_OBJ=
+else    
+    WITH_FTP=1
+    FTP_OBJ=nanoftp.o
+fi
+AC_SUBST(WITH_FTP)
+AC_SUBST(FTP_OBJ)
+
+if test "$with_http" = "no" ; then
+    echo Disabling HTTP support
+    WITH_HTTP=0
+    HTTP_OBJ=
+else    
+    WITH_HTTP=1
+    HTTP_OBJ=nanohttp.o
+fi
+AC_SUBST(WITH_HTTP)
+AC_SUBST(HTTP_OBJ)
+
+if test "$with_legacy" = "no" ; then
+    echo Disabling deprecated APIs
+    WITH_LEGACY=0
+else    
+    WITH_LEGACY=1
+fi
+AC_SUBST(WITH_LEGACY)
+
+if test "$with_reader" = "no" ; then
+    echo Disabling the xmlReader parsing interface
+    WITH_READER=0
+    READER_TEST=
+else    
+    WITH_READER=1
+    READER_TEST=Readertests
+    if test "$with_push" = "no" ; then
+        echo xmlReader requires Push interface - enabling it
+	with_push=yes
+    fi
+fi
+AC_SUBST(WITH_READER)
+AC_SUBST(READER_TEST)
+
+if test "$with_writer" = "no" ; then
+    echo Disabling the xmlWriter saving interface
+    WITH_WRITER=0
+#    WRITER_TEST=
+else    
+    WITH_WRITER=1
+#    WRITER_TEST=Writertests
+    if test "$with_push" = "no" ; then
+        echo xmlWriter requires Push interface - enabling it
+	with_push=yes
+    fi
+    if test "$with_output" = "no" ; then
+        echo xmlWriter requires Output interface - enabling it
+	with_output=yes
+    fi
+fi
+AC_SUBST(WITH_WRITER)
+#AC_SUBST(WRITER_TEST)
+
+if test "$with_pattern" = "no" ; then
+    echo Disabling the xmlPattern parsing interface
+    WITH_PATTERN=0
+    TEST_PATTERN=
+else    
+    WITH_PATTERN=1
+    TEST_PATTERN=Patterntests
+fi
+AC_SUBST(WITH_PATTERN)
+AC_SUBST(TEST_PATTERN)
+
+if test "$with_sax1" = "no" ; then
+    echo Disabling the older SAX1 interface
+    WITH_SAX1=0
+    TEST_SAX=
+else    
+    WITH_SAX1=1
+    TEST_SAX=SAXtests
+fi
+AC_SUBST(WITH_SAX1)
+AC_SUBST(TEST_SAX)
+
+if test "$with_push" = "no" ; then
+    echo Disabling the PUSH parser interfaces
+    WITH_PUSH=0
+    TEST_PUSH=
+else    
+    WITH_PUSH=1
+    TEST_PUSH="XMLPushtests"
+fi
+AC_SUBST(WITH_PUSH)
+AC_SUBST(TEST_PUSH)
+
+if test "$with_html" = "no" ; then
+    echo Disabling HTML support
+    WITH_HTML=0
+    HTML_OBJ=
+    TEST_HTML=
+else    
+    WITH_HTML=1
+    HTML_OBJ="HTMLparser.o HTMLtree.o"
+    TEST_HTML=HTMLtests
+    if test "$with_push" != "no" ; then
+        TEST_PHTML=HTMLPushtests
+    else
+        TEST_PHTML=
+    fi
+fi
+AC_SUBST(WITH_HTML)
+AC_SUBST(HTML_OBJ)
+AC_SUBST(TEST_HTML)
+AC_SUBST(TEST_PHTML)
+
+if test "$with_valid" = "no" ; then
+    echo Disabling DTD validation support
+    WITH_VALID=0
+    TEST_VALID=
+    TEST_VTIME=
+else    
+    WITH_VALID=1
+    TEST_VALID=Validtests
+    TEST_VTIME=VTimingtests
+fi
+AC_SUBST(WITH_VALID)
+AC_SUBST(TEST_VALID)
+AC_SUBST(TEST_VTIME)
+
+if test "$with_catalog" = "no" ; then
+    echo Disabling Catalog support
+    WITH_CATALOG=0
+    CATALOG_OBJ=
+    TEST_CATALOG=
+else    
+    WITH_CATALOG=1
+    CATALOG_OBJ="catalog.o"
+    TEST_CATALOG=Catatests
+fi
+AC_SUBST(WITH_CATALOG)
+AC_SUBST(CATALOG_OBJ)
+AC_SUBST(TEST_CATALOG)
+
+if test "$with_docbook" = "no" ; then
+    echo Disabling Docbook support
+    WITH_DOCB=0
+    DOCB_OBJ=
+else    
+    WITH_DOCB=1
+    DOCB_OBJ="DOCBparser.o"
+fi
+AC_SUBST(WITH_DOCB)
+AC_SUBST(DOCB_OBJ)
+
+
+if test "$with_xptr" = "no" ; then
+    echo Disabling XPointer support
+    WITH_XPTR=0
+    XPTR_OBJ=
+    TEST_XPTR=
+else    
+    WITH_XPTR=1
+    XPTR_OBJ=xpointer.o
+    TEST_XPTR=XPtrtests
+    if test "$with_xpath" = "no" ; then
+        echo XPointer requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+AC_SUBST(WITH_XPTR)
+AC_SUBST(XPTR_OBJ)
+AC_SUBST(TEST_XPTR)
+
+if test "$with_c14n" = "no" ; then
+    echo Disabling C14N support
+    WITH_C14N=0
+    C14N_OBJ=
+    TEST_C14N=
+else    
+    WITH_C14N=1
+    C14N_OBJ="c14n.c"
+    TEST_C14N=C14Ntests
+    if test "$with_xpath" = "no" ; then
+        echo C14N requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+AC_SUBST(WITH_C14N)
+AC_SUBST(C14N_OBJ)
+AC_SUBST(TEST_C14N)
+
+if test "$with_xinclude" = "no" ; then
+    echo Disabling XInclude support
+    WITH_XINCLUDE=0
+    XINCLUDE_OBJ=
+    with_xinclude="no"
+    TEST_XINCLUDE=
+else    
+    WITH_XINCLUDE=1
+    XINCLUDE_OBJ=xinclude.o
+    TEST_XINCLUDE=XIncludetests
+    if test "$with_xpath" = "no" ; then
+        echo XInclude requires XPath support - enabling it
+	with_xpath=yes
+    fi
+fi
+AC_SUBST(WITH_XINCLUDE)
+AC_SUBST(XINCLUDE_OBJ)
+AC_SUBST(TEST_XINCLUDE)
+
+if test "$with_xpath" = "no" ; then
+    echo Disabling XPATH support
+    WITH_XPATH=0
+    XPATH_OBJ=
+    TEST_XPATH=
+else    
+    WITH_XPATH=1
+    XPATH_OBJ=xpath.o
+    TEST_XPATH=XPathtests
+fi
+AC_SUBST(WITH_XPATH)
+AC_SUBST(XPATH_OBJ)
+AC_SUBST(TEST_XPATH)
+
+dnl
+dnl output functions
+dnl
+if test "$with_output" = "no" ; then
+    echo Disabling serialization/saving support
+    WITH_OUTPUT=0
+else    
+    WITH_OUTPUT=1
+fi
+AC_SUBST(WITH_OUTPUT)
+
+WITH_ICONV=0
+if test "$with_iconv" = "no" ; then
+    echo Disabling ICONV support
+else
+    if test "$with_iconv" != "yes" -a "$with_iconv" != "" ; then
+	CPPFLAGS="${CPPFLAGS} -I$with_iconv/include"
+	# Export this since our headers include iconv.h
+	XML_INCLUDEDIR="${XML_INCLUDEDIR} -I$with_iconv/include"
+	ICONV_LIBS="-L$with_iconv/lib"
+    fi
+
+    AC_CHECK_HEADER(iconv.h,
+	AC_MSG_CHECKING(for iconv)
+	AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],[
+iconv_t cd = iconv_open ("","");
+iconv (cd, NULL, NULL, NULL, NULL);],[
+	    AC_MSG_RESULT(yes)
+	    WITH_ICONV=1],[
+	    AC_MSG_RESULT(no)
+	    AC_MSG_CHECKING(for iconv in -liconv)
+
+	    _ldflags="${LDFLAGS}"
+	    _libs="${LIBS}"
+	    LDFLAGS="${LDFLAGS} ${ICONV_LIBS}"
+	    LIBS="${LIBS} -liconv"
+
+	    AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],[
+iconv_t cd = iconv_open ("","");
+iconv (cd, NULL, NULL, NULL, NULL);],[
+		AC_MSG_RESULT(yes)
+		WITH_ICONV=1
+		ICONV_LIBS="${ICONV_LIBS} -liconv"
+		LIBS="${_libs}"
+		LDFLAGS="${_ldflags}"],[
+		AC_MSG_RESULT(no)
+		LIBS="${_libs}"
+		LDFLAGS="${_ldflags}"])]))
+
+	if test "$WITH_ICONV" = "1" ; then
+		AC_MSG_CHECKING([for iconv declaration])
+		AC_CACHE_VAL(xml_cv_iconv_arg2, [
+			AC_TRY_COMPILE([#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], xml_cv_iconv_arg2="", xml_cv_iconv_arg2="const")])
+
+		xml_cv_iconv_decl="extern size_t iconv (iconv_t cd, $xml_cv_iconv_arg2 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
+		AC_MSG_RESULT([${xml_xxx:-
+	}$xml_cv_iconv_decl])
+		AC_DEFINE_UNQUOTED(ICONV_CONST, $xml_cv_iconv_arg2,
+			[Define as const if the declaration of iconv() needs const.])
+	fi
+fi
+case "$host" in
+	*mingw*) M_LIBS=""
+	;;
+	*beos*) M_LIBS=""
+	;;
+        *haiku*) M_LIBS=""
+        ;;
+	*) M_LIBS="-lm"
+	;;
+esac
+XML_LIBS="-lxml2 $Z_LIBS $THREAD_LIBS $ICONV_LIBS $M_LIBS $LIBS"
+XML_LIBTOOLLIBS="libxml2.la"
+AC_SUBST(WITH_ICONV)
+
+WITH_ISO8859X=1
+if test "$WITH_ICONV" != "1" ; then
+if test "$with_iso8859x" = "no" ; then
+    echo Disabling ISO8859X support
+    WITH_ISO8859X=0
+fi
+fi
+AC_SUBST(WITH_ISO8859X)
+
+if test "$with_schematron" = "no" ; then
+    echo "Disabling Schematron support"
+    WITH_SCHEMATRON=0
+    TEST_SCHEMATRON=
+else    
+    echo "Enabled Schematron support"
+    WITH_SCHEMATRON=1
+    TEST_SCHEMATRON="Schematrontests"
+    with_xpath=yes
+    with_pattern=yes
+fi
+AC_SUBST(WITH_SCHEMATRON)
+AC_SUBST(TEST_SCHEMATRON)
+
+if test "$with_schemas" = "no" ; then
+    echo "Disabling Schemas/Relax-NG support"
+    WITH_SCHEMAS=0
+    TEST_SCHEMAS=
+else    
+    echo "Enabled Schemas/Relax-NG support"
+    WITH_SCHEMAS=1
+    TEST_SCHEMAS="Schemastests Relaxtests"
+    if test "$PYTHON_INCLUDES" != "" ; then
+        PYTHON_TESTS="$PYTHON_TESTS RelaxNGPythonTests SchemasPythonTests"
+    fi
+    with_regexps=yes
+fi
+AC_SUBST(WITH_SCHEMAS)
+AC_SUBST(TEST_SCHEMAS)
+
+if test "$with_regexps" = "no" ; then
+    echo Disabling Regexps support
+    WITH_REGEXPS=0
+    TEST_REGEXPS=
+else    
+    WITH_REGEXPS=1
+    TEST_REGEXPS="Regexptests Automatatests"
+fi
+AC_SUBST(WITH_REGEXPS)
+AC_SUBST(TEST_REGEXPS)
+
+if test "$with_debug" = "no" ; then
+    echo Disabling DEBUG support
+    WITH_DEBUG=0
+    DEBUG_OBJ=
+    TEST_DEBUG=
+else    
+    WITH_DEBUG=1
+    DEBUG_OBJ=debugXML.o
+    TEST_DEBUG=Scripttests
+fi
+AC_SUBST(WITH_DEBUG)
+AC_SUBST(DEBUG_OBJ)
+AC_SUBST(TEST_DEBUG)
+
+if test "$with_mem_debug" = "yes" ; then
+    if test "$with_thread_alloc" = "yes" ; then
+        echo Disabling memory debug - cannot use mem-debug with thread-alloc!
+	WITH_MEM_DEBUG=0
+    else
+        echo Enabling memory debug support
+        WITH_MEM_DEBUG=1
+    fi
+else    
+    WITH_MEM_DEBUG=0
+fi
+AC_SUBST(WITH_MEM_DEBUG)
+
+if test "$with_run_debug" = "yes" ; then
+    echo Enabling runtime debug support
+    WITH_RUN_DEBUG=1
+else    
+    WITH_RUN_DEBUG=0
+fi
+AC_SUBST(WITH_RUN_DEBUG)
+
+WIN32_EXTRA_LIBADD=
+WIN32_EXTRA_LDFLAGS=
+CYGWIN_EXTRA_LDFLAGS=
+CYGWIN_EXTRA_PYTHON_LIBADD=
+case "$host" in
+ *-*-mingw*)
+ CPPFLAGS="$CPPFLAGS -DWIN32"
+ WIN32_EXTRA_LIBADD="-lws2_32"
+ WIN32_EXTRA_LDFLAGS="-no-undefined"
+ AC_DEFINE([_WINSOCKAPI_],1,[Using the Win32 Socket implementation])
+ AC_DEFINE([snprintf],[_snprintf],[Win32 Std C name mangling work-around])
+ AC_DEFINE([vsnprintf],[_vsnprintf],[Win32 Std C name mangling work-around])
+ ;;
+ *-*-cygwin*)
+ CYGWIN_EXTRA_LDFLAGS="-no-undefined"
+ if test "${PYTHON}" != ""
+ then
+   CYGWIN_EXTRA_PYTHON_LIBADD="-L/usr/lib/python${PYTHON_VERSION}/config -lpython${PYTHON_VERSION}"
+ fi
+ ;;
+esac
+AC_SUBST(WIN32_EXTRA_LIBADD)
+AC_SUBST(WIN32_EXTRA_LDFLAGS)
+AC_SUBST(CYGWIN_EXTRA_LDFLAGS)
+AC_SUBST(CYGWIN_EXTRA_PYTHON_LIBADD)
+
+if test "$with_coverage" = "yes" -a "${GCC}" = "yes"
+then
+    echo Enabling code coverage for GCC
+    CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
+    LDFLAGS="$LDFLAGS -fprofile-arcs -ftest-coverage"
+else
+    echo Disabling code coverage for GCC
+fi
+
+AC_SUBST(CPPFLAGS)
+AC_SUBST(CFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(XML_CFLAGS)
+
+AC_SUBST(XML_LIBDIR)
+AC_SUBST(XML_LIBS)
+AC_SUBST(XML_LIBTOOLLIBS)
+AC_SUBST(ICONV_LIBS)
+AC_SUBST(XML_INCLUDEDIR)
+AC_SUBST(HTML_DIR)
+AC_SUBST(HAVE_ISNAN)
+AC_SUBST(HAVE_ISINF)
+AC_SUBST(PYTHON)
+AC_SUBST(PYTHON_VERSION)
+AC_SUBST(PYTHON_INCLUDES)
+AC_SUBST(PYTHON_SITE_PACKAGES)
+
+AC_SUBST(M_LIBS)
+AC_SUBST(RDL_LIBS)
+
+dnl for the spec file
+RELDATE=`date +'%a %b %e %Y'`
+AC_SUBST(RELDATE)
+AC_SUBST(PYTHON_TESTS)
+
+rm -f COPYING.LIB COPYING
+ln -s Copyright COPYING
+
+# keep on one line for cygwin c.f. #130896
+AC_OUTPUT(libxml2.spec:libxml.spec.in Makefile include/Makefile include/libxml/Makefile doc/Makefile doc/examples/Makefile doc/devhelp/Makefile example/Makefile python/Makefile python/tests/Makefile xstc/Makefile include/libxml/xmlversion.h xml2-config libxml-2.0.pc libxml-2.0-uninstalled.pc python/setup.py)
+
+chmod +x xml2-config python/setup.py
+echo Done configuring
diff --git a/src/dbgen.pl b/src/dbgen.pl
new file mode 100755
index 0000000..1383d6e
--- /dev/null
+++ b/src/dbgen.pl
@@ -0,0 +1,43 @@
+#!/usr/bin/perl
+
+$size = shift;
+
+if ($size eq "") 
+{
+    die "usage:  dbgen.pl [size]\n";
+}
+
+@firstnames = ("Al", "Bob", "Charles", "David", "Egon", "Farbood", 
+               "George", "Hank", "Inki", "James");
+@lastnames = ("Aranow", "Barker", "Corsetti", "Dershowitz", "Engleman", 
+              "Franklin", "Grice", "Haverford", "Ilvedson", "Jones");
+@states = ("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", 
+           "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", 
+           "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", 
+           "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", 
+           "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY");
+
+print "<?xml version=\"1.0\"?>\n";
+print "\n";
+print "<table>\n";
+
+for ($i=0; $i<$size; $i++)
+{
+    $first = $firstnames [$i % 10];
+    $last = $lastnames [($i / 10) % 10];
+    $state = $states [($i / 100) % 50];
+    $zip = 22000 + $i / 5000;
+
+    printf "  <row>\n";
+    printf "    <id>%04d</id>\n", $i;
+    printf "    <firstname>$first</firstname>\n", $i;
+    printf "    <lastname>$last</lastname>\n", $i;
+    printf "    <street>%d Any St.</street>\n", ($i % 100) + 1;
+    printf "    <city>Anytown</city>\n";
+    printf "    <state>$state</state>\n";
+    printf "    <zip>%d</zip>\n", $zip;
+    printf "  </row>\n";
+}
+
+print "</table>\n";
+
diff --git a/src/dbgenattr.pl b/src/dbgenattr.pl
new file mode 100755
index 0000000..dce11cd
--- /dev/null
+++ b/src/dbgenattr.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+$size = shift;
+
+if ($size eq "") 
+{
+    die "usage:  dbgen.pl [size]\n";
+}
+
+@firstnames = ("Al", "Bob", "Charles", "David", "Egon", "Farbood", 
+               "George", "Hank", "Inki", "James");
+@lastnames = ("Aranow", "Barker", "Corsetti", "Dershowitz", "Engleman", 
+              "Franklin", "Grice", "Haverford", "Ilvedson", "Jones");
+@states = ("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", 
+           "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", 
+           "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", 
+           "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", 
+           "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY");
+
+print "<?xml version=\"1.0\"?>\n";
+print "\n";
+print "<table>\n";
+
+for ($i=0; $i<$size; $i++)
+{
+    $first = $firstnames [$i % 10];
+    $last = $lastnames [($i / 10) % 10];
+    $state = $states [($i / 100) % 50];
+    $zip = 22000 + $i / 5000;
+
+    printf "  <row\n";
+    printf "    id='%04d'\n", $i;
+    printf "    firstname='$first'\n", $i;
+    printf "    lastname='$last'\n", $i;
+    printf "    street='%d Any St.'\n", ($i % 100) + 1;
+    printf "    city='Anytown'\n";
+    printf "    state='$state'\n";
+    printf "    zip='%d'/>\n", $zip;
+}
+
+print "</table>\n";
+
diff --git a/src/debugXML.c b/src/debugXML.c
new file mode 100644
index 0000000..49b9a13
--- /dev/null
+++ b/src/debugXML.c
@@ -0,0 +1,3262 @@
+/*
+ * debugXML.c : This is a set of routines used for debugging the tree
+ *              produced by the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+#ifdef LIBXML_DEBUG_ENABLED
+
+#include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/valid.h>
+#include <libxml/debugXML.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/uri.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#endif
+
+#define DUMP_TEXT_TYPE 1
+
+typedef struct _xmlDebugCtxt xmlDebugCtxt;
+typedef xmlDebugCtxt *xmlDebugCtxtPtr;
+struct _xmlDebugCtxt {
+    FILE *output;               /* the output file */
+    char shift[101];            /* used for indenting */
+    int depth;                  /* current depth */
+    xmlDocPtr doc;              /* current document */
+    xmlNodePtr node;		/* current node */
+    xmlDictPtr dict;		/* the doc dictionnary */
+    int check;                  /* do just checkings */
+    int errors;                 /* number of errors found */
+    int nodict;			/* if the document has no dictionnary */
+    int options;		/* options */
+};
+
+static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node);
+
+static void
+xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt)
+{
+    int i;
+
+    ctxt->depth = 0;
+    ctxt->check = 0;
+    ctxt->errors = 0;
+    ctxt->output = stdout;
+    ctxt->doc = NULL;
+    ctxt->node = NULL;
+    ctxt->dict = NULL;
+    ctxt->nodict = 0;
+    ctxt->options = 0;
+    for (i = 0; i < 100; i++)
+        ctxt->shift[i] = ' ';
+    ctxt->shift[100] = 0;
+}
+
+static void
+xmlCtxtDumpCleanCtxt(xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+ /* remove the ATTRIBUTE_UNUSED when this is added */
+}
+
+/**
+ * xmlNsCheckScope:
+ * @node: the node
+ * @ns: the namespace node
+ *
+ * Check that a given namespace is in scope on a node.
+ *
+ * Returns 1 if in scope, -1 in case of argument error, 
+ *         -2 if the namespace is not in scope, and -3 if not on
+ *         an ancestor node.
+ */
+static int
+xmlNsCheckScope(xmlNodePtr node, xmlNsPtr ns)
+{
+    xmlNsPtr cur;
+
+    if ((node == NULL) || (ns == NULL))
+        return(-1);
+
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE) &&
+	(node->type != XML_DOCUMENT_NODE) &&
+	(node->type != XML_TEXT_NODE) &&
+	(node->type != XML_HTML_DOCUMENT_NODE) &&
+	(node->type != XML_XINCLUDE_START))
+	return(-2);
+
+    while ((node != NULL) &&
+           ((node->type == XML_ELEMENT_NODE) ||
+            (node->type == XML_ATTRIBUTE_NODE) ||
+            (node->type == XML_TEXT_NODE) ||
+	    (node->type == XML_XINCLUDE_START))) {
+	if ((node->type == XML_ELEMENT_NODE) ||
+	    (node->type == XML_XINCLUDE_START)) {
+	    cur = node->nsDef;
+	    while (cur != NULL) {
+	        if (cur == ns)
+		    return(1);
+		if (xmlStrEqual(cur->prefix, ns->prefix))
+		    return(-2);
+		cur = cur->next;
+	    }
+	}
+	node = node->parent;
+    }
+    /* the xml namespace may be declared on the document node */
+    if ((node != NULL) &&
+        ((node->type == XML_DOCUMENT_NODE) ||
+	 (node->type == XML_HTML_DOCUMENT_NODE))) {
+	 xmlNsPtr oldNs = ((xmlDocPtr) node)->oldNs;
+	 if (oldNs == ns)
+	     return(1);
+    }
+    return(-3);
+}
+
+static void
+xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt)
+{
+    if (ctxt->check)
+        return;
+    if ((ctxt->output != NULL) && (ctxt->depth > 0)) {
+        if (ctxt->depth < 50)
+            fprintf(ctxt->output, "%s", &ctxt->shift[100 - 2 * ctxt->depth]);
+        else
+            fprintf(ctxt->output, "%s", ctxt->shift);
+    }
+}
+
+/**
+ * xmlDebugErr:
+ * @ctxt:  a debug context
+ * @error:  the error code
+ *
+ * Handle a debug error.
+ */
+static void
+xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg)
+{
+    ctxt->errors++;
+    __xmlRaiseError(NULL, NULL, NULL,
+		    NULL, ctxt->node, XML_FROM_CHECK,
+		    error, XML_ERR_ERROR, NULL, 0,
+		    NULL, NULL, NULL, 0, 0,
+		    "%s", msg);
+}
+static void
+xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
+{
+    ctxt->errors++;
+    __xmlRaiseError(NULL, NULL, NULL,
+		    NULL, ctxt->node, XML_FROM_CHECK,
+		    error, XML_ERR_ERROR, NULL, 0,
+		    NULL, NULL, NULL, 0, 0,
+		    msg, extra);
+}
+static void
+xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
+{
+    ctxt->errors++;
+    __xmlRaiseError(NULL, NULL, NULL,
+		    NULL, ctxt->node, XML_FROM_CHECK,
+		    error, XML_ERR_ERROR, NULL, 0,
+		    NULL, NULL, NULL, 0, 0,
+		    msg, extra);
+}
+
+/**
+ * xmlCtxtNsCheckScope:
+ * @ctxt: the debugging context
+ * @node: the node
+ * @ns: the namespace node
+ *
+ * Report if a given namespace is is not in scope.
+ */
+static void
+xmlCtxtNsCheckScope(xmlDebugCtxtPtr ctxt, xmlNodePtr node, xmlNsPtr ns)
+{
+    int ret;
+
+    ret = xmlNsCheckScope(node, ns);
+    if (ret == -2) {
+        if (ns->prefix == NULL)
+	    xmlDebugErr(ctxt, XML_CHECK_NS_SCOPE,
+			"Reference to default namespace not in scope\n");
+	else
+	    xmlDebugErr3(ctxt, XML_CHECK_NS_SCOPE,
+			 "Reference to namespace '%s' not in scope\n",
+			 (char *) ns->prefix);
+    }
+    if (ret == -3) {
+        if (ns->prefix == NULL)
+	    xmlDebugErr(ctxt, XML_CHECK_NS_ANCESTOR,
+			"Reference to default namespace not on ancestor\n");
+	else
+	    xmlDebugErr3(ctxt, XML_CHECK_NS_ANCESTOR,
+			 "Reference to namespace '%s' not on ancestor\n",
+			 (char *) ns->prefix);
+    }
+}
+
+/**
+ * xmlCtxtCheckString:
+ * @ctxt: the debug context
+ * @str: the string
+ *
+ * Do debugging on the string, currently it just checks the UTF-8 content
+ */
+static void
+xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
+{
+    if (str == NULL) return;
+    if (ctxt->check) {
+        if (!xmlCheckUTF8(str)) {
+	    xmlDebugErr3(ctxt, XML_CHECK_NOT_UTF8,
+			 "String is not UTF-8 %s", (const char *) str);
+	}
+    }
+}
+
+/**
+ * xmlCtxtCheckName:
+ * @ctxt: the debug context
+ * @name: the name
+ *
+ * Do debugging on the name, for example the dictionnary status and
+ * conformance to the Name production.
+ */
+static void
+xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name)
+{
+    if (ctxt->check) {
+	if (name == NULL) {
+	    xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
+	    return;
+	}
+        if (xmlValidateName(name, 0)) {
+	    xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
+			 "Name is not an NCName '%s'", (const char *) name);
+	}
+	if ((ctxt->dict != NULL) &&
+	    (!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);
+	}
+    }
+}
+
+static void
+xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) {
+    xmlDocPtr doc;
+    xmlDictPtr dict;
+
+    doc = node->doc;
+
+    if (node->parent == NULL)
+        xmlDebugErr(ctxt, XML_CHECK_NO_PARENT,
+	            "Node has no parent\n");
+    if (node->doc == NULL) {
+        xmlDebugErr(ctxt, XML_CHECK_NO_DOC,
+	            "Node has no doc\n");
+        dict = NULL;
+    } else {
+	dict = doc->dict;
+	if ((dict == NULL) && (ctxt->nodict == 0)) {
+#if 0
+            /* desactivated right now as it raises too many errors */
+	    if (doc->type == XML_DOCUMENT_NODE)
+		xmlDebugErr(ctxt, XML_CHECK_NO_DICT,
+			    "Document has no dictionnary\n");
+#endif
+	    ctxt->nodict = 1;
+	}
+	if (ctxt->doc == NULL)
+	    ctxt->doc = doc;
+
+	if (ctxt->dict == NULL) {
+	    ctxt->dict = dict;
+	}
+    }
+    if ((node->parent != NULL) && (node->doc != node->parent->doc) &&
+        (!xmlStrEqual(node->name, BAD_CAST "pseudoroot")))
+        xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC,
+	            "Node doc differs from parent's one\n");
+    if (node->prev == NULL) {
+        if (node->type == XML_ATTRIBUTE_NODE) {
+	    if ((node->parent != NULL) &&
+	        (node != (xmlNodePtr) node->parent->properties))
+		xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
+                    "Attr has no prev and not first of attr list\n");
+	        
+        } else if ((node->parent != NULL) && (node->parent->children != node))
+	    xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
+                    "Node has no prev and not first of parent list\n");
+    } else {
+        if (node->prev->next != node)
+	    xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV,
+                        "Node prev->next : back link wrong\n");
+    }
+    if (node->next == NULL) {
+	if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) &&
+	    (node->parent->last != node) &&
+	    (node->parent->type == XML_ELEMENT_NODE))
+	    xmlDebugErr(ctxt, XML_CHECK_NO_NEXT,
+                    "Node has no next and not last of parent list\n");
+    } else {
+        if (node->next->prev != node)
+	    xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT,
+                    "Node next->prev : forward link wrong\n");
+        if (node->next->parent != node->parent)
+	    xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT,
+                    "Node next->prev : forward link wrong\n");
+    }
+    if (node->type == XML_ELEMENT_NODE) {
+        xmlNsPtr ns;
+
+	ns = node->nsDef;
+	while (ns != NULL) {
+	    xmlCtxtNsCheckScope(ctxt, node, ns);
+	    ns = ns->next;
+	}
+	if (node->ns != NULL)
+	    xmlCtxtNsCheckScope(ctxt, node, node->ns);
+    } else if (node->type == XML_ATTRIBUTE_NODE) {
+	if (node->ns != NULL)
+	    xmlCtxtNsCheckScope(ctxt, node, node->ns);
+    }
+
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE) &&
+	(node->type != XML_ELEMENT_DECL) &&
+	(node->type != XML_ATTRIBUTE_DECL) &&
+	(node->type != XML_DTD_NODE) &&
+	(node->type != XML_HTML_DOCUMENT_NODE) &&
+	(node->type != XML_DOCUMENT_NODE)) {
+	if (node->content != NULL)
+	    xmlCtxtCheckString(ctxt, (const xmlChar *) node->content);
+    }
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    xmlCtxtCheckName(ctxt, node->name);
+	    break;
+        case XML_TEXT_NODE:
+	    if ((node->name == xmlStringText) ||
+	        (node->name == xmlStringTextNoenc))
+		break;
+	    /* some case of entity substitution can lead to this */
+	    if ((ctxt->dict != NULL) &&
+	        (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
+		                             7)))
+		break;
+
+	    xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
+			 "Text node has wrong name '%s'",
+			 (const char *) node->name);
+	    break;
+        case XML_COMMENT_NODE:
+	    if (node->name == xmlStringComment)
+		break;
+	    xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
+			 "Comment node has wrong name '%s'",
+			 (const char *) node->name);
+	    break;
+        case XML_PI_NODE:
+	    xmlCtxtCheckName(ctxt, node->name);
+	    break;
+        case XML_CDATA_SECTION_NODE:
+	    if (node->name == NULL)
+		break;
+	    xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL,
+			 "CData section has non NULL name '%s'",
+			 (const char *) node->name);
+	    break;
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_NAMESPACE_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+	    break;
+    }
+}
+
+static void
+xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
+{
+    int i;
+
+    if (ctxt->check) {
+        return;
+    }
+    /* TODO: check UTF8 content of the string */
+    if (str == NULL) {
+        fprintf(ctxt->output, "(NULL)");
+        return;
+    }
+    for (i = 0; i < 40; i++)
+        if (str[i] == 0)
+            return;
+        else if (IS_BLANK_CH(str[i]))
+            fputc(' ', ctxt->output);
+        else if (str[i] >= 0x80)
+            fprintf(ctxt->output, "#%X", str[i]);
+        else
+            fputc(str[i], ctxt->output);
+    fprintf(ctxt->output, "...");
+}
+
+static void
+xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (dtd == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DTD node is NULL\n");
+        return;
+    }
+
+    if (dtd->type != XML_DTD_NODE) {
+	xmlDebugErr(ctxt, XML_CHECK_NOT_DTD,
+	            "Node is not a DTD");
+        return;
+    }
+    if (!ctxt->check) {
+        if (dtd->name != NULL)
+            fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name);
+        else
+            fprintf(ctxt->output, "DTD");
+        if (dtd->ExternalID != NULL)
+            fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID);
+        if (dtd->SystemID != NULL)
+            fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID);
+        fprintf(ctxt->output, "\n");
+    }
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd);
+}
+
+static void
+xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (attr == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Attribute declaration is NULL\n");
+        return;
+    }
+    if (attr->type != XML_ATTRIBUTE_DECL) {
+	xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL,
+	            "Node is not an attribute declaration");
+        return;
+    }
+    if (attr->name != NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
+    } else
+	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
+	            "Node attribute declaration has no name");
+    if (attr->elem != NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, " for %s", (char *) attr->elem);
+    } else
+	xmlDebugErr(ctxt, XML_CHECK_NO_ELEM,
+	            "Node attribute declaration has no element name");
+    if (!ctxt->check) {
+        switch (attr->atype) {
+            case XML_ATTRIBUTE_CDATA:
+                fprintf(ctxt->output, " CDATA");
+                break;
+            case XML_ATTRIBUTE_ID:
+                fprintf(ctxt->output, " ID");
+                break;
+            case XML_ATTRIBUTE_IDREF:
+                fprintf(ctxt->output, " IDREF");
+                break;
+            case XML_ATTRIBUTE_IDREFS:
+                fprintf(ctxt->output, " IDREFS");
+                break;
+            case XML_ATTRIBUTE_ENTITY:
+                fprintf(ctxt->output, " ENTITY");
+                break;
+            case XML_ATTRIBUTE_ENTITIES:
+                fprintf(ctxt->output, " ENTITIES");
+                break;
+            case XML_ATTRIBUTE_NMTOKEN:
+                fprintf(ctxt->output, " NMTOKEN");
+                break;
+            case XML_ATTRIBUTE_NMTOKENS:
+                fprintf(ctxt->output, " NMTOKENS");
+                break;
+            case XML_ATTRIBUTE_ENUMERATION:
+                fprintf(ctxt->output, " ENUMERATION");
+                break;
+            case XML_ATTRIBUTE_NOTATION:
+                fprintf(ctxt->output, " NOTATION ");
+                break;
+        }
+        if (attr->tree != NULL) {
+            int indx;
+            xmlEnumerationPtr cur = attr->tree;
+
+            for (indx = 0; indx < 5; indx++) {
+                if (indx != 0)
+                    fprintf(ctxt->output, "|%s", (char *) cur->name);
+                else
+                    fprintf(ctxt->output, " (%s", (char *) cur->name);
+                cur = cur->next;
+                if (cur == NULL)
+                    break;
+            }
+            if (cur == NULL)
+                fprintf(ctxt->output, ")");
+            else
+                fprintf(ctxt->output, "...)");
+        }
+        switch (attr->def) {
+            case XML_ATTRIBUTE_NONE:
+                break;
+            case XML_ATTRIBUTE_REQUIRED:
+                fprintf(ctxt->output, " REQUIRED");
+                break;
+            case XML_ATTRIBUTE_IMPLIED:
+                fprintf(ctxt->output, " IMPLIED");
+                break;
+            case XML_ATTRIBUTE_FIXED:
+                fprintf(ctxt->output, " FIXED");
+                break;
+        }
+        if (attr->defaultValue != NULL) {
+            fprintf(ctxt->output, "\"");
+            xmlCtxtDumpString(ctxt, attr->defaultValue);
+            fprintf(ctxt->output, "\"");
+        }
+        fprintf(ctxt->output, "\n");
+    }
+
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
+}
+
+static void
+xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (elem == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Element declaration is NULL\n");
+        return;
+    }
+    if (elem->type != XML_ELEMENT_DECL) {
+	xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL,
+	            "Node is not an element declaration");
+        return;
+    }
+    if (elem->name != NULL) {
+        if (!ctxt->check) {
+            fprintf(ctxt->output, "ELEMDECL(");
+            xmlCtxtDumpString(ctxt, elem->name);
+            fprintf(ctxt->output, ")");
+        }
+    } else
+	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
+	            "Element declaration has no name");
+    if (!ctxt->check) {
+        switch (elem->etype) {
+            case XML_ELEMENT_TYPE_UNDEFINED:
+                fprintf(ctxt->output, ", UNDEFINED");
+                break;
+            case XML_ELEMENT_TYPE_EMPTY:
+                fprintf(ctxt->output, ", EMPTY");
+                break;
+            case XML_ELEMENT_TYPE_ANY:
+                fprintf(ctxt->output, ", ANY");
+                break;
+            case XML_ELEMENT_TYPE_MIXED:
+                fprintf(ctxt->output, ", MIXED ");
+                break;
+            case XML_ELEMENT_TYPE_ELEMENT:
+                fprintf(ctxt->output, ", MIXED ");
+                break;
+        }
+        if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) {
+            char buf[5001];
+
+            buf[0] = 0;
+            xmlSnprintfElementContent(buf, 5000, elem->content, 1);
+            buf[5000] = 0;
+            fprintf(ctxt->output, "%s", buf);
+        }
+        fprintf(ctxt->output, "\n");
+    }
+
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem);
+}
+
+static void
+xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (ent == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Entity declaration is NULL\n");
+        return;
+    }
+    if (ent->type != XML_ENTITY_DECL) {
+	xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL,
+	            "Node is not an entity declaration");
+        return;
+    }
+    if (ent->name != NULL) {
+        if (!ctxt->check) {
+            fprintf(ctxt->output, "ENTITYDECL(");
+            xmlCtxtDumpString(ctxt, ent->name);
+            fprintf(ctxt->output, ")");
+        }
+    } else
+	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
+	            "Entity declaration has no name");
+    if (!ctxt->check) {
+        switch (ent->etype) {
+            case XML_INTERNAL_GENERAL_ENTITY:
+                fprintf(ctxt->output, ", internal\n");
+                break;
+            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+                fprintf(ctxt->output, ", external parsed\n");
+                break;
+            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+                fprintf(ctxt->output, ", unparsed\n");
+                break;
+            case XML_INTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, ", parameter\n");
+                break;
+            case XML_EXTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, ", external parameter\n");
+                break;
+            case XML_INTERNAL_PREDEFINED_ENTITY:
+                fprintf(ctxt->output, ", predefined\n");
+                break;
+        }
+        if (ent->ExternalID) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, " ExternalID=%s\n",
+                    (char *) ent->ExternalID);
+        }
+        if (ent->SystemID) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, " SystemID=%s\n",
+                    (char *) ent->SystemID);
+        }
+        if (ent->URI != NULL) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI);
+        }
+        if (ent->content) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, " content=");
+            xmlCtxtDumpString(ctxt, ent->content);
+            fprintf(ctxt->output, "\n");
+        }
+    }
+
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent);
+}
+
+static void
+xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (ns == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "namespace node is NULL\n");
+        return;
+    }
+    if (ns->type != XML_NAMESPACE_DECL) {
+	xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL,
+	            "Node is not a namespace declaration");
+        return;
+    }
+    if (ns->href == NULL) {
+        if (ns->prefix != NULL)
+	    xmlDebugErr3(ctxt, XML_CHECK_NO_HREF,
+                    "Incomplete namespace %s href=NULL\n",
+                    (char *) ns->prefix);
+        else
+	    xmlDebugErr(ctxt, XML_CHECK_NO_HREF,
+                    "Incomplete default namespace href=NULL\n");
+    } else {
+        if (!ctxt->check) {
+            if (ns->prefix != NULL)
+                fprintf(ctxt->output, "namespace %s href=",
+                        (char *) ns->prefix);
+            else
+                fprintf(ctxt->output, "default namespace href=");
+
+            xmlCtxtDumpString(ctxt, ns->href);
+            fprintf(ctxt->output, "\n");
+        }
+    }
+}
+
+static void
+xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
+{
+    while (ns != NULL) {
+        xmlCtxtDumpNamespace(ctxt, ns);
+        ns = ns->next;
+    }
+}
+
+static void
+xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (ent == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Entity is NULL\n");
+        return;
+    }
+    if (!ctxt->check) {
+        switch (ent->etype) {
+            case XML_INTERNAL_GENERAL_ENTITY:
+                fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
+                break;
+            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
+                break;
+            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
+                break;
+            case XML_INTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
+                break;
+            case XML_EXTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY ");
+                break;
+            default:
+                fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype);
+        }
+        fprintf(ctxt->output, "%s\n", ent->name);
+        if (ent->ExternalID) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "ExternalID=%s\n",
+                    (char *) ent->ExternalID);
+        }
+        if (ent->SystemID) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID);
+        }
+        if (ent->URI) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI);
+        }
+        if (ent->content) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "content=");
+            xmlCtxtDumpString(ctxt, ent->content);
+            fprintf(ctxt->output, "\n");
+        }
+    }
+}
+
+/**
+ * xmlCtxtDumpAttr:
+ * @output:  the FILE * for the output
+ * @attr:  the attribute
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the attribute
+ */
+static void
+xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
+{
+    xmlCtxtDumpSpaces(ctxt);
+
+    if (attr == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Attr is NULL");
+        return;
+    }
+    if (!ctxt->check) {
+        fprintf(ctxt->output, "ATTRIBUTE ");
+	xmlCtxtDumpString(ctxt, attr->name);
+        fprintf(ctxt->output, "\n");
+        if (attr->children != NULL) {
+            ctxt->depth++;
+            xmlCtxtDumpNodeList(ctxt, attr->children);
+            ctxt->depth--;
+        }
+    }
+    if (attr->name == NULL)
+	xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
+	            "Attribute has no name");
+
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
+}
+
+/**
+ * xmlCtxtDumpAttrList:
+ * @output:  the FILE * for the output
+ * @attr:  the attribute list
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the attribute list
+ */
+static void
+xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
+{
+    while (attr != NULL) {
+        xmlCtxtDumpAttr(ctxt, attr);
+        attr = attr->next;
+    }
+}
+
+/**
+ * xmlCtxtDumpOneNode:
+ * @output:  the FILE * for the output
+ * @node:  the node
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the element node, it is not recursive
+ */
+static void
+xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
+{
+    if (node == NULL) {
+        if (!ctxt->check) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "node is NULL\n");
+        }
+        return;
+    }
+    ctxt->node = node;
+
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "ELEMENT ");
+                if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
+                    xmlCtxtDumpString(ctxt, node->ns->prefix);
+                    fprintf(ctxt->output, ":");
+                }
+                xmlCtxtDumpString(ctxt, node->name);
+                fprintf(ctxt->output, "\n");
+            }
+            break;
+        case XML_ATTRIBUTE_NODE:
+            if (!ctxt->check)
+                xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
+            xmlCtxtGenericNodeCheck(ctxt, node);
+            return;
+        case XML_TEXT_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                if (node->name == (const xmlChar *) xmlStringTextNoenc)
+                    fprintf(ctxt->output, "TEXT no enc");
+                else
+                    fprintf(ctxt->output, "TEXT");
+		if (ctxt->options & DUMP_TEXT_TYPE) {
+		    if (node->content == (xmlChar *) &(node->properties))
+			fprintf(ctxt->output, " compact\n");
+		    else if (xmlDictOwns(ctxt->dict, node->content) == 1)
+			fprintf(ctxt->output, " interned\n");
+		    else
+			fprintf(ctxt->output, "\n");
+		} else
+		    fprintf(ctxt->output, "\n");
+            }
+            break;
+        case XML_CDATA_SECTION_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "CDATA_SECTION\n");
+            }
+            break;
+        case XML_ENTITY_REF_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "ENTITY_REF(%s)\n",
+                        (char *) node->name);
+            }
+            break;
+        case XML_ENTITY_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "ENTITY\n");
+            }
+            break;
+        case XML_PI_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "PI %s\n", (char *) node->name);
+            }
+            break;
+        case XML_COMMENT_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "COMMENT\n");
+            }
+            break;
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+            }
+            fprintf(ctxt->output, "Error, DOCUMENT found here\n");
+            xmlCtxtGenericNodeCheck(ctxt, node);
+            return;
+        case XML_DOCUMENT_TYPE_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "DOCUMENT_TYPE\n");
+            }
+            break;
+        case XML_DOCUMENT_FRAG_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "DOCUMENT_FRAG\n");
+            }
+            break;
+        case XML_NOTATION_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "NOTATION\n");
+            }
+            break;
+        case XML_DTD_NODE:
+            xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node);
+            return;
+        case XML_ELEMENT_DECL:
+            xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node);
+            return;
+        case XML_ATTRIBUTE_DECL:
+            xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node);
+            return;
+        case XML_ENTITY_DECL:
+            xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node);
+            return;
+        case XML_NAMESPACE_DECL:
+            xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node);
+            return;
+        case XML_XINCLUDE_START:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "INCLUDE START\n");
+            }
+            return;
+        case XML_XINCLUDE_END:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "INCLUDE END\n");
+            }
+            return;
+        default:
+            if (!ctxt->check)
+                xmlCtxtDumpSpaces(ctxt);
+	    xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
+	                "Unknown node type %d\n", node->type);
+            return;
+    }
+    if (node->doc == NULL) {
+        if (!ctxt->check) {
+            xmlCtxtDumpSpaces(ctxt);
+        }
+        fprintf(ctxt->output, "PBM: doc == NULL !!!\n");
+    }
+    ctxt->depth++;
+    if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
+        xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
+    if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
+        xmlCtxtDumpAttrList(ctxt, node->properties);
+    if (node->type != XML_ENTITY_REF_NODE) {
+        if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                fprintf(ctxt->output, "content=");
+                xmlCtxtDumpString(ctxt, node->content);
+                fprintf(ctxt->output, "\n");
+            }
+        }
+    } else {
+        xmlEntityPtr ent;
+
+        ent = xmlGetDocEntity(node->doc, node->name);
+        if (ent != NULL)
+            xmlCtxtDumpEntity(ctxt, ent);
+    }
+    ctxt->depth--;
+
+    /*
+     * Do a bit of checking
+     */
+    xmlCtxtGenericNodeCheck(ctxt, node);
+}
+
+/**
+ * xmlCtxtDumpNode:
+ * @output:  the FILE * for the output
+ * @node:  the node
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the element node, it is recursive
+ */
+static void
+xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
+{
+    if (node == NULL) {
+        if (!ctxt->check) {
+            xmlCtxtDumpSpaces(ctxt);
+            fprintf(ctxt->output, "node is NULL\n");
+        }
+        return;
+    }
+    xmlCtxtDumpOneNode(ctxt, node);
+    if ((node->type != XML_NAMESPACE_DECL) && 
+        (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
+        ctxt->depth++;
+        xmlCtxtDumpNodeList(ctxt, node->children);
+        ctxt->depth--;
+    }
+}
+
+/**
+ * xmlCtxtDumpNodeList:
+ * @output:  the FILE * for the output
+ * @node:  the node list
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the list of element node, it is recursive
+ */
+static void
+xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
+{
+    while (node != NULL) {
+        xmlCtxtDumpNode(ctxt, node);
+        node = node->next;
+    }
+}
+
+static void
+xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
+{
+    if (doc == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
+        return;
+    }
+    ctxt->node = (xmlNodePtr) doc;
+
+    switch (doc->type) {
+        case XML_ELEMENT_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT,
+	                "Misplaced ELEMENT node\n");
+            break;
+        case XML_ATTRIBUTE_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE,
+	                "Misplaced ATTRIBUTE node\n");
+            break;
+        case XML_TEXT_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT,
+	                "Misplaced TEXT node\n");
+            break;
+        case XML_CDATA_SECTION_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA,
+	                "Misplaced CDATA node\n");
+            break;
+        case XML_ENTITY_REF_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF,
+	                "Misplaced ENTITYREF node\n");
+            break;
+        case XML_ENTITY_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY,
+	                "Misplaced ENTITY node\n");
+            break;
+        case XML_PI_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_PI,
+	                "Misplaced PI node\n");
+            break;
+        case XML_COMMENT_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT,
+	                "Misplaced COMMENT node\n");
+            break;
+        case XML_DOCUMENT_NODE:
+	    if (!ctxt->check)
+		fprintf(ctxt->output, "DOCUMENT\n");
+            break;
+        case XML_HTML_DOCUMENT_NODE:
+	    if (!ctxt->check)
+		fprintf(ctxt->output, "HTML DOCUMENT\n");
+            break;
+        case XML_DOCUMENT_TYPE_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
+	                "Misplaced DOCTYPE node\n");
+            break;
+        case XML_DOCUMENT_FRAG_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT,
+	                "Misplaced FRAGMENT node\n");
+            break;
+        case XML_NOTATION_NODE:
+	    xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION,
+	                "Misplaced NOTATION node\n");
+            break;
+        default:
+	    xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
+	                "Unknown node type %d\n", doc->type);
+    }
+}
+
+/**
+ * xmlCtxtDumpDocumentHead:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information cncerning the document, not recursive
+ */
+static void
+xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
+{
+    if (doc == NULL) return;
+    xmlCtxtDumpDocHead(ctxt, doc);
+    if (!ctxt->check) {
+        if (doc->name != NULL) {
+            fprintf(ctxt->output, "name=");
+            xmlCtxtDumpString(ctxt, BAD_CAST doc->name);
+            fprintf(ctxt->output, "\n");
+        }
+        if (doc->version != NULL) {
+            fprintf(ctxt->output, "version=");
+            xmlCtxtDumpString(ctxt, doc->version);
+            fprintf(ctxt->output, "\n");
+        }
+        if (doc->encoding != NULL) {
+            fprintf(ctxt->output, "encoding=");
+            xmlCtxtDumpString(ctxt, doc->encoding);
+            fprintf(ctxt->output, "\n");
+        }
+        if (doc->URL != NULL) {
+            fprintf(ctxt->output, "URL=");
+            xmlCtxtDumpString(ctxt, doc->URL);
+            fprintf(ctxt->output, "\n");
+        }
+        if (doc->standalone)
+            fprintf(ctxt->output, "standalone=true\n");
+    }
+    if (doc->oldNs != NULL)
+        xmlCtxtDumpNamespaceList(ctxt, doc->oldNs);
+}
+
+/**
+ * xmlCtxtDumpDocument:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information for the document, it's recursive
+ */
+static void
+xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
+{
+    if (doc == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
+        return;
+    }
+    xmlCtxtDumpDocumentHead(ctxt, doc);
+    if (((doc->type == XML_DOCUMENT_NODE) ||
+         (doc->type == XML_HTML_DOCUMENT_NODE))
+        && (doc->children != NULL)) {
+        ctxt->depth++;
+        xmlCtxtDumpNodeList(ctxt, doc->children);
+        ctxt->depth--;
+    }
+}
+
+static void
+xmlCtxtDumpEntityCallback(xmlEntityPtr cur, xmlDebugCtxtPtr ctxt)
+{
+    if (cur == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Entity is NULL");
+        return;
+    }
+    if (!ctxt->check) {
+        fprintf(ctxt->output, "%s : ", (char *) cur->name);
+        switch (cur->etype) {
+            case XML_INTERNAL_GENERAL_ENTITY:
+                fprintf(ctxt->output, "INTERNAL GENERAL, ");
+                break;
+            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL PARSED, ");
+                break;
+            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
+                break;
+            case XML_INTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, "INTERNAL PARAMETER, ");
+                break;
+            case XML_EXTERNAL_PARAMETER_ENTITY:
+                fprintf(ctxt->output, "EXTERNAL PARAMETER, ");
+                break;
+            default:
+		xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE,
+			     "Unknown entity type %d\n", cur->etype);
+        }
+        if (cur->ExternalID != NULL)
+            fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID);
+        if (cur->SystemID != NULL)
+            fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID);
+        if (cur->orig != NULL)
+            fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig);
+        if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL))
+            fprintf(ctxt->output, "\n content \"%s\"",
+                    (char *) cur->content);
+        fprintf(ctxt->output, "\n");
+    }
+}
+
+/**
+ * xmlCtxtDumpEntities:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information for all the entities in use by the document
+ */
+static void
+xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
+{
+    if (doc == NULL) return;
+    xmlCtxtDumpDocHead(ctxt, doc);
+    if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
+        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
+            doc->intSubset->entities;
+
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Entities in internal subset\n");
+        xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback,
+                    ctxt);
+    } else
+        fprintf(ctxt->output, "No entities in internal subset\n");
+    if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
+        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
+            doc->extSubset->entities;
+
+        if (!ctxt->check)
+            fprintf(ctxt->output, "Entities in external subset\n");
+        xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback,
+                    ctxt);
+    } else if (!ctxt->check)
+        fprintf(ctxt->output, "No entities in external subset\n");
+}
+
+/**
+ * xmlCtxtDumpDTD:
+ * @output:  the FILE * for the output
+ * @dtd:  the DTD
+ *
+ * Dumps debug information for the DTD
+ */
+static void
+xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
+{
+    if (dtd == NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DTD is NULL\n");
+        return;
+    }
+    xmlCtxtDumpDtdNode(ctxt, dtd);
+    if (dtd->children == NULL)
+        fprintf(ctxt->output, "    DTD is empty\n");
+    else {
+        ctxt->depth++;
+        xmlCtxtDumpNodeList(ctxt, dtd->children);
+        ctxt->depth--;
+    }
+}
+
+/************************************************************************
+ *									*
+ *			Public entry points for dump			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlDebugDumpString:
+ * @output:  the FILE * for the output
+ * @str:  the string
+ *
+ * Dumps informations about the string, shorten it if necessary
+ */
+void
+xmlDebugDumpString(FILE * output, const xmlChar * str)
+{
+    int i;
+
+    if (output == NULL)
+	output = stdout;
+    if (str == NULL) {
+        fprintf(output, "(NULL)");
+        return;
+    }
+    for (i = 0; i < 40; i++)
+        if (str[i] == 0)
+            return;
+        else if (IS_BLANK_CH(str[i]))
+            fputc(' ', output);
+        else if (str[i] >= 0x80)
+            fprintf(output, "#%X", str[i]);
+        else
+            fputc(str[i], output);
+    fprintf(output, "...");
+}
+
+/**
+ * xmlDebugDumpAttr:
+ * @output:  the FILE * for the output
+ * @attr:  the attribute
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the attribute
+ */
+void
+xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL) return;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpAttr(&ctxt, attr);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+
+/**
+ * xmlDebugDumpEntities:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information for all the entities in use by the document
+ */
+void
+xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL) return;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    xmlCtxtDumpEntities(&ctxt, doc);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpAttrList:
+ * @output:  the FILE * for the output
+ * @attr:  the attribute list
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the attribute list
+ */
+void
+xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL) return;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpAttrList(&ctxt, attr);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpOneNode:
+ * @output:  the FILE * for the output
+ * @node:  the node
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the element node, it is not recursive
+ */
+void
+xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL) return;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpOneNode(&ctxt, node);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpNode:
+ * @output:  the FILE * for the output
+ * @node:  the node
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the element node, it is recursive
+ */
+void
+xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpNode(&ctxt, node);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpNodeList:
+ * @output:  the FILE * for the output
+ * @node:  the node list
+ * @depth:  the indentation level.
+ *
+ * Dumps debug information for the list of element node, it is recursive
+ */
+void
+xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpNodeList(&ctxt, node);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpDocumentHead:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information cncerning the document, not recursive
+ */
+void
+xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.options |= DUMP_TEXT_TYPE;
+    ctxt.output = output;
+    xmlCtxtDumpDocumentHead(&ctxt, doc);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpDocument:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Dumps debug information for the document, it's recursive
+ */
+void
+xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.options |= DUMP_TEXT_TYPE;
+    ctxt.output = output;
+    xmlCtxtDumpDocument(&ctxt, doc);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/**
+ * xmlDebugDumpDTD:
+ * @output:  the FILE * for the output
+ * @dtd:  the DTD
+ *
+ * Dumps debug information for the DTD
+ */
+void
+xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.options |= DUMP_TEXT_TYPE;
+    ctxt.output = output;
+    xmlCtxtDumpDTD(&ctxt, dtd);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+}
+
+/************************************************************************
+ *									*
+ *			Public entry points for checkings		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlDebugCheckDocument:
+ * @output:  the FILE * for the output
+ * @doc:  the document
+ *
+ * Check the document for potential content problems, and output
+ * the errors to @output
+ *
+ * Returns the number of errors found
+ */
+int
+xmlDebugCheckDocument(FILE * output, xmlDocPtr doc)
+{
+    xmlDebugCtxt ctxt;
+
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.check = 1;
+    xmlCtxtDumpDocument(&ctxt, doc);
+    xmlCtxtDumpCleanCtxt(&ctxt);
+    return(ctxt.errors);
+}
+
+/************************************************************************
+ *									*
+ *			Helpers for Shell				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlLsCountNode:
+ * @node:  the node to count
+ *
+ * Count the children of @node.
+ *
+ * Returns the number of children of @node.
+ */
+int
+xmlLsCountNode(xmlNodePtr node) {
+    int ret = 0;
+    xmlNodePtr list = NULL;
+    
+    if (node == NULL)
+	return(0);
+
+    switch (node->type) {
+	case XML_ELEMENT_NODE:
+	    list = node->children;
+	    break;
+	case XML_DOCUMENT_NODE:
+	case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    list = ((xmlDocPtr) node)->children;
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    list = ((xmlAttrPtr) node)->children;
+	    break;
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_PI_NODE:
+	case XML_COMMENT_NODE:
+	    if (node->content != NULL) {
+		ret = xmlStrlen(node->content);
+            }
+	    break;
+	case XML_ENTITY_REF_NODE:
+	case XML_DOCUMENT_TYPE_NODE:
+	case XML_ENTITY_NODE:
+	case XML_DOCUMENT_FRAG_NODE:
+	case XML_NOTATION_NODE:
+	case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+	    ret = 1;
+	    break;
+    }
+    for (;list != NULL;ret++) 
+        list = list->next;
+    return(ret);
+}
+
+/**
+ * xmlLsOneNode:
+ * @output:  the FILE * for the output
+ * @node:  the node to dump
+ *
+ * Dump to @output the type and name of @node.
+ */
+void
+xmlLsOneNode(FILE *output, xmlNodePtr node) {
+    if (output == NULL) return;
+    if (node == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    switch (node->type) {
+	case XML_ELEMENT_NODE:
+	    fprintf(output, "-");
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    fprintf(output, "a");
+	    break;
+	case XML_TEXT_NODE:
+	    fprintf(output, "t");
+	    break;
+	case XML_CDATA_SECTION_NODE:
+	    fprintf(output, "C");
+	    break;
+	case XML_ENTITY_REF_NODE:
+	    fprintf(output, "e");
+	    break;
+	case XML_ENTITY_NODE:
+	    fprintf(output, "E");
+	    break;
+	case XML_PI_NODE:
+	    fprintf(output, "p");
+	    break;
+	case XML_COMMENT_NODE:
+	    fprintf(output, "c");
+	    break;
+	case XML_DOCUMENT_NODE:
+	    fprintf(output, "d");
+	    break;
+	case XML_HTML_DOCUMENT_NODE:
+	    fprintf(output, "h");
+	    break;
+	case XML_DOCUMENT_TYPE_NODE:
+	    fprintf(output, "T");
+	    break;
+	case XML_DOCUMENT_FRAG_NODE:
+	    fprintf(output, "F");
+	    break;
+	case XML_NOTATION_NODE:
+	    fprintf(output, "N");
+	    break;
+	case XML_NAMESPACE_DECL:
+	    fprintf(output, "n");
+	    break;
+	default:
+	    fprintf(output, "?");
+    }
+    if (node->type != XML_NAMESPACE_DECL) {
+	if (node->properties != NULL)
+	    fprintf(output, "a");
+	else	
+	    fprintf(output, "-");
+	if (node->nsDef != NULL) 
+	    fprintf(output, "n");
+	else	
+	    fprintf(output, "-");
+    }
+
+    fprintf(output, " %8d ", xmlLsCountNode(node));
+
+    switch (node->type) {
+	case XML_ELEMENT_NODE:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+	    break;
+	case XML_TEXT_NODE:
+	    if (node->content != NULL) {
+		xmlDebugDumpString(output, node->content);
+            }
+	    break;
+	case XML_CDATA_SECTION_NODE:
+	    break;
+	case XML_ENTITY_REF_NODE:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+	    break;
+	case XML_ENTITY_NODE:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+	    break;
+	case XML_PI_NODE:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+	    break;
+	case XML_COMMENT_NODE:
+	    break;
+	case XML_DOCUMENT_NODE:
+	    break;
+	case XML_HTML_DOCUMENT_NODE:
+	    break;
+	case XML_DOCUMENT_TYPE_NODE:
+	    break;
+	case XML_DOCUMENT_FRAG_NODE:
+	    break;
+	case XML_NOTATION_NODE:
+	    break;
+	case XML_NAMESPACE_DECL: {
+	    xmlNsPtr ns = (xmlNsPtr) node;
+
+	    if (ns->prefix == NULL)
+		fprintf(output, "default -> %s", (char *)ns->href);
+	    else
+		fprintf(output, "%s -> %s", (char *)ns->prefix,
+			(char *)ns->href);
+	    break;
+	}
+	default:
+	    if (node->name != NULL)
+		fprintf(output, "%s", (const char *) node->name);
+    }
+    fprintf(output, "\n");
+}
+
+/**
+ * xmlBoolToText:
+ * @boolval: a bool to turn into text
+ *
+ * Convenient way to turn bool into text 
+ *
+ * Returns a pointer to either "True" or "False"
+ */
+const char *
+xmlBoolToText(int boolval)
+{
+    if (boolval)
+        return("True");
+    else
+        return("False");
+}
+
+#ifdef LIBXML_XPATH_ENABLED
+/****************************************************************
+ *								*
+ *	 	The XML shell related functions			*
+ *								*
+ ****************************************************************/
+
+
+
+/*
+ * TODO: Improvement/cleanups for the XML shell
+ *     - allow to shell out an editor on a subpart
+ *     - cleanup function registrations (with help) and calling
+ *     - provide registration routines
+ */
+
+/**
+ * xmlShellPrintXPathError:
+ * @errorType: valid xpath error id
+ * @arg: the argument that cause xpath to fail
+ *
+ * Print the xpath error to libxml default error channel
+ */
+void
+xmlShellPrintXPathError(int errorType, const char *arg)
+{
+    const char *default_arg = "Result";
+
+    if (!arg)
+        arg = default_arg;
+
+    switch (errorType) {
+        case XPATH_UNDEFINED:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s: no such node\n", arg);
+            break;
+
+        case XPATH_BOOLEAN:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a Boolean\n", arg);
+            break;
+        case XPATH_NUMBER:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a number\n", arg);
+            break;
+        case XPATH_STRING:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a string\n", arg);
+            break;
+        case XPATH_POINT:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a point\n", arg);
+            break;
+        case XPATH_RANGE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a range\n", arg);
+            break;
+        case XPATH_LOCATIONSET:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is a range\n", arg);
+            break;
+        case XPATH_USERS:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is user-defined\n", arg);
+            break;
+        case XPATH_XSLT_TREE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "%s is an XSLT value tree\n", arg);
+            break;
+    }
+#if 0
+    xmlGenericError(xmlGenericErrorContext,
+                    "Try casting the result string function (xpath builtin)\n",
+                    arg);
+#endif
+}
+
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlShellPrintNodeCtxt:
+ * @ctxt : a non-null shell context
+ * @node : a non-null node to print to the output FILE
+ *
+ * Print node to the output FILE
+ */
+static void
+xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
+{
+    FILE *fp;
+
+    if (!node)
+        return;
+    if (ctxt == NULL)
+	fp = stdout;
+    else
+	fp = ctxt->output;
+
+    if (node->type == XML_DOCUMENT_NODE)
+        xmlDocDump(fp, (xmlDocPtr) node);
+    else if (node->type == XML_ATTRIBUTE_NODE)
+        xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
+    else
+        xmlElemDump(fp, node->doc, node);
+
+    fprintf(fp, "\n");
+}
+
+/**
+ * xmlShellPrintNode:
+ * @node : a non-null node to print to the output FILE
+ *
+ * Print node to the output FILE
+ */
+void
+xmlShellPrintNode(xmlNodePtr node)
+{
+    xmlShellPrintNodeCtxt(NULL, node);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlShellPrintXPathResultCtxt:
+ * @ctxt: a valid shell context
+ * @list: a valid result generated by an xpath evaluation
+ *
+ * Prints result to the output FILE
+ */
+static void
+xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
+{
+    if (!ctxt)
+       return;
+
+    if (list != NULL) {
+        switch (list->type) {
+            case XPATH_NODESET:{
+#ifdef LIBXML_OUTPUT_ENABLED
+                    int indx;
+
+                    if (list->nodesetval) {
+                        for (indx = 0; indx < list->nodesetval->nodeNr;
+                             indx++) {
+                            xmlShellPrintNodeCtxt(ctxt,
+				    list->nodesetval->nodeTab[indx]);
+                        }
+                    } else {
+                        xmlGenericError(xmlGenericErrorContext,
+                                        "Empty node set\n");
+                    }
+                    break;
+#else
+		    xmlGenericError(xmlGenericErrorContext,
+				    "Node set\n");
+#endif /* LIBXML_OUTPUT_ENABLED */
+                }
+            case XPATH_BOOLEAN:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a Boolean:%s\n",
+                                xmlBoolToText(list->boolval));
+                break;
+            case XPATH_NUMBER:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a number:%0g\n", list->floatval);
+                break;
+            case XPATH_STRING:
+                xmlGenericError(xmlGenericErrorContext,
+                                "Is a string:%s\n", list->stringval);
+                break;
+
+            default:
+                xmlShellPrintXPathError(list->type, NULL);
+        }
+    }
+}
+
+/**
+ * xmlShellPrintXPathResult:
+ * @list: a valid result generated by an xpath evaluation
+ *
+ * Prints result to the output FILE
+ */
+void
+xmlShellPrintXPathResult(xmlXPathObjectPtr list)
+{
+    xmlShellPrintXPathResultCtxt(NULL, list);
+}
+
+/**
+ * xmlShellList:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "ls"
+ * Does an Unix like listing of the given node (like a directory)
+ *
+ * Returns 0
+ */
+int
+xmlShellList(xmlShellCtxtPtr ctxt,
+             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlNodePtr cur;
+    if (!ctxt)
+        return (0);
+    if (node == NULL) {
+	fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }
+    if ((node->type == XML_DOCUMENT_NODE) ||
+        (node->type == XML_HTML_DOCUMENT_NODE)) {
+        cur = ((xmlDocPtr) node)->children;
+    } else if (node->type == XML_NAMESPACE_DECL) {
+        xmlLsOneNode(ctxt->output, node);
+        return (0);
+    } else if (node->children != NULL) {
+        cur = node->children;
+    } else {
+        xmlLsOneNode(ctxt->output, node);
+        return (0);
+    }
+    while (cur != NULL) {
+        xmlLsOneNode(ctxt->output, cur);
+        cur = cur->next;
+    }
+    return (0);
+}
+
+/**
+ * xmlShellBase:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "base"
+ * dumps the current XML base of the node
+ *
+ * Returns 0
+ */
+int
+xmlShellBase(xmlShellCtxtPtr ctxt,
+             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlChar *base;
+    if (!ctxt)
+        return 0;
+    if (node == NULL) {
+	fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }    
+
+    base = xmlNodeGetBase(node->doc, node);
+
+    if (base == NULL) {
+        fprintf(ctxt->output, " No base found !!!\n");
+    } else {
+        fprintf(ctxt->output, "%s\n", base);
+        xmlFree(base);
+    }
+    return (0);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlShellSetBase:
+ * @ctxt:  the shell context
+ * @arg:  the new base
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "setbase"
+ * change the current XML base of the node
+ *
+ * Returns 0
+ */
+static int
+xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlNodeSetBase(node, (xmlChar*) arg);
+    return (0);
+}
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+/**
+ * xmlShellRegisterNamespace:
+ * @ctxt:  the shell context
+ * @arg:  a string in prefix=nsuri format
+ * @node:  unused
+ * @node2:  unused
+ *
+ * Implements the XML shell function "setns"
+ * register/unregister a prefix=namespace pair
+ * on the XPath context
+ *
+ * Returns 0 on success and a negative value otherwise.
+ */
+static int
+xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
+      xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlChar* nsListDup;
+    xmlChar* prefix;
+    xmlChar* href;
+    xmlChar* next;
+
+    nsListDup = xmlStrdup((xmlChar *) arg);
+    next = nsListDup;
+    while(next != NULL) {
+	/* skip spaces */
+	/*while((*next) == ' ') next++;*/
+	if((*next) == '\0') break;
+
+	/* find prefix */
+	prefix = next;
+	next = (xmlChar*)xmlStrchr(next, '=');
+	if(next == NULL) {
+	    fprintf(ctxt->output, "setns: prefix=[nsuri] required\n");
+	    xmlFree(nsListDup);
+	    return(-1);
+	}
+	*(next++) = '\0';
+
+	/* find href */
+	href = next;
+	next = (xmlChar*)xmlStrchr(next, ' ');
+	if(next != NULL) {
+	    *(next++) = '\0';
+	}
+
+	/* do register namespace */
+	if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) {
+	    fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
+	    xmlFree(nsListDup);
+	    return(-1);
+	}
+    }
+
+    xmlFree(nsListDup);
+    return(0);
+}
+/**
+ * xmlShellRegisterRootNamespaces:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  the root element
+ * @node2:  unused
+ *
+ * Implements the XML shell function "setrootns"
+ * which registers all namespaces declarations found on the root element.
+ *
+ * Returns 0 on success and a negative value otherwise.
+ */
+static int
+xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
+      xmlNodePtr root, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlNsPtr ns;
+
+    if ((root == NULL) || (root->type != XML_ELEMENT_NODE) ||
+        (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL))
+	return(-1);
+    ns = root->nsDef;
+    while (ns != NULL) {
+        if (ns->prefix == NULL)
+	    xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href);
+	else
+	    xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href);
+        ns = ns->next;
+    }
+    return(0);
+}
+#endif
+
+/**
+ * xmlShellGrep:
+ * @ctxt:  the shell context
+ * @arg:  the string or regular expression to find
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "grep"
+ * dumps informations about the node (namespace, attributes, content).
+ *
+ * Returns 0
+ */
+static int
+xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+            char *arg, xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    if (!ctxt)
+        return (0);
+    if (node == NULL)
+	return (0);
+    if (arg == NULL)
+	return (0);
+#ifdef LIBXML_REGEXP_ENABLED
+    if ((xmlStrchr((xmlChar *) arg, '?')) ||
+	(xmlStrchr((xmlChar *) arg, '*')) ||
+	(xmlStrchr((xmlChar *) arg, '.')) ||
+	(xmlStrchr((xmlChar *) arg, '['))) {
+    }
+#endif
+    while (node != NULL) {
+        if (node->type == XML_COMMENT_NODE) {
+	    if (xmlStrstr(node->content, (xmlChar *) arg)) {
+
+		fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
+                xmlShellList(ctxt, NULL, node, NULL);
+	    }
+        } else if (node->type == XML_TEXT_NODE) {
+	    if (xmlStrstr(node->content, (xmlChar *) arg)) {
+
+		fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
+                xmlShellList(ctxt, NULL, node->parent, NULL);
+	    }
+        }
+
+        /*
+         * Browse the full subtree, deep first
+         */
+
+        if ((node->type == XML_DOCUMENT_NODE) ||
+            (node->type == XML_HTML_DOCUMENT_NODE)) {
+            node = ((xmlDocPtr) node)->children;
+        } else if ((node->children != NULL)
+                   && (node->type != XML_ENTITY_REF_NODE)) {
+            /* deep first */
+            node = node->children;
+        } else if (node->next != NULL) {
+            /* then siblings */
+            node = node->next;
+        } else {
+            /* go up to parents->next if needed */
+            while (node != NULL) {
+                if (node->parent != NULL) {
+                    node = node->parent;
+                }
+                if (node->next != NULL) {
+                    node = node->next;
+                    break;
+                }
+                if (node->parent == NULL) {
+                    node = NULL;
+                    break;
+                }
+            }
+	}
+    }
+    return (0);
+}
+
+/**
+ * xmlShellDir:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "dir"
+ * dumps informations about the node (namespace, attributes, content).
+ *
+ * Returns 0
+ */
+int
+xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+            char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
+            xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    if (!ctxt)
+        return (0);
+    if (node == NULL) {
+	fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }    
+    if ((node->type == XML_DOCUMENT_NODE) ||
+        (node->type == XML_HTML_DOCUMENT_NODE)) {
+        xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
+    } else if (node->type == XML_ATTRIBUTE_NODE) {
+        xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
+    } else {
+        xmlDebugDumpOneNode(ctxt->output, node, 0);
+    }
+    return (0);
+}
+
+/**
+ * xmlShellSetContent:
+ * @ctxt:  the shell context
+ * @value:  the content as a string
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "dir"
+ * dumps informations about the node (namespace, attributes, content).
+ *
+ * Returns 0
+ */
+static int
+xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
+            char *value, xmlNodePtr node,
+            xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlNodePtr results;
+    xmlParserErrors ret;
+
+    if (!ctxt)
+        return (0);
+    if (node == NULL) {
+	fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }
+    if (value == NULL) {
+        fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }
+
+    ret = xmlParseInNodeContext(node, value, strlen(value), 0, &results);
+    if (ret == XML_ERR_OK) {
+	if (node->children != NULL) {
+	    xmlFreeNodeList(node->children);
+	    node->children = NULL;
+	    node->last = NULL;
+	}
+	xmlAddChildList(node, results);
+    } else {
+        fprintf(ctxt->output, "failed to parse content\n");
+    }
+    return (0);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+/**
+ * xmlShellRNGValidate:
+ * @ctxt:  the shell context
+ * @schemas:  the path to the Relax-NG schemas
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "relaxng"
+ * validating the instance against a Relax-NG schemas
+ *
+ * Returns 0
+ */
+static int
+xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
+            xmlNodePtr node ATTRIBUTE_UNUSED,
+	    xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlRelaxNGPtr relaxngschemas;
+    xmlRelaxNGParserCtxtPtr ctxt;
+    xmlRelaxNGValidCtxtPtr vctxt;
+    int ret;
+
+    ctxt = xmlRelaxNGNewParserCtxt(schemas);
+    xmlRelaxNGSetParserErrors(ctxt,
+	    (xmlRelaxNGValidityErrorFunc) fprintf,
+	    (xmlRelaxNGValidityWarningFunc) fprintf,
+	    stderr);
+    relaxngschemas = xmlRelaxNGParse(ctxt);
+    xmlRelaxNGFreeParserCtxt(ctxt);
+    if (relaxngschemas == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"Relax-NG schema %s failed to compile\n", schemas);
+	return(-1);
+    }
+    vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
+    xmlRelaxNGSetValidErrors(vctxt,
+	    (xmlRelaxNGValidityErrorFunc) fprintf,
+	    (xmlRelaxNGValidityWarningFunc) fprintf,
+	    stderr);
+    ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
+    if (ret == 0) {
+	fprintf(stderr, "%s validates\n", sctxt->filename);
+    } else if (ret > 0) {
+	fprintf(stderr, "%s fails to validate\n", sctxt->filename);
+    } else {
+	fprintf(stderr, "%s validation generated an internal error\n",
+	       sctxt->filename);
+    }
+    xmlRelaxNGFreeValidCtxt(vctxt);
+    if (relaxngschemas != NULL)
+	xmlRelaxNGFree(relaxngschemas);
+    return(0);
+}
+#endif
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlShellCat:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @node:  a node
+ * @node2:  unused
+ *
+ * Implements the XML shell function "cat"
+ * dumps the serialization node content (XML or HTML).
+ *
+ * Returns 0
+ */
+int
+xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
+            xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    if (!ctxt)
+        return (0);
+    if (node == NULL) {
+	fprintf(ctxt->output, "NULL\n");
+	return (0);
+    }    
+    if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
+#ifdef LIBXML_HTML_ENABLED
+        if (node->type == XML_HTML_DOCUMENT_NODE)
+            htmlDocDump(ctxt->output, (htmlDocPtr) node);
+        else
+            htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
+#else
+        if (node->type == XML_DOCUMENT_NODE)
+            xmlDocDump(ctxt->output, (xmlDocPtr) node);
+        else
+            xmlElemDump(ctxt->output, ctxt->doc, node);
+#endif /* LIBXML_HTML_ENABLED */
+    } else {
+        if (node->type == XML_DOCUMENT_NODE)
+            xmlDocDump(ctxt->output, (xmlDocPtr) node);
+        else
+            xmlElemDump(ctxt->output, ctxt->doc, node);
+    }
+    fprintf(ctxt->output, "\n");
+    return (0);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlShellLoad:
+ * @ctxt:  the shell context
+ * @filename:  the file name
+ * @node:  unused
+ * @node2:  unused
+ *
+ * Implements the XML shell function "load"
+ * loads a new document specified by the filename
+ *
+ * Returns 0 or -1 if loading failed
+ */
+int
+xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
+             xmlNodePtr node ATTRIBUTE_UNUSED,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlDocPtr doc;
+    int html = 0;
+
+    if ((ctxt == NULL) || (filename == NULL)) return(-1);
+    if (ctxt->doc != NULL)
+        html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
+
+    if (html) {
+#ifdef LIBXML_HTML_ENABLED
+        doc = htmlParseFile(filename, NULL);
+#else
+        fprintf(ctxt->output, "HTML support not compiled in\n");
+        doc = NULL;
+#endif /* LIBXML_HTML_ENABLED */
+    } else {
+        doc = xmlReadFile(filename,NULL,0);
+    }
+    if (doc != NULL) {
+        if (ctxt->loaded == 1) {
+            xmlFreeDoc(ctxt->doc);
+        }
+        ctxt->loaded = 1;
+#ifdef LIBXML_XPATH_ENABLED
+        xmlXPathFreeContext(ctxt->pctxt);
+#endif /* LIBXML_XPATH_ENABLED */
+        xmlFree(ctxt->filename);
+        ctxt->doc = doc;
+        ctxt->node = (xmlNodePtr) doc;
+#ifdef LIBXML_XPATH_ENABLED
+        ctxt->pctxt = xmlXPathNewContext(doc);
+#endif /* LIBXML_XPATH_ENABLED */
+        ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename);
+    } else
+        return (-1);
+    return (0);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlShellWrite:
+ * @ctxt:  the shell context
+ * @filename:  the file name
+ * @node:  a node in the tree
+ * @node2:  unused
+ *
+ * Implements the XML shell function "write"
+ * Write the current node to the filename, it saves the serialization
+ * of the subtree under the @node specified
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
+              xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    if (node == NULL)
+        return (-1);
+    if ((filename == NULL) || (filename[0] == 0)) {
+        return (-1);
+    }
+#ifdef W_OK
+    if (access((char *) filename, W_OK)) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Cannot write to %s\n", filename);
+        return (-1);
+    }
+#endif
+    switch (node->type) {
+        case XML_DOCUMENT_NODE:
+            if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
+            break;
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_HTML_ENABLED
+            if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
+#else
+            if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to write to %s\n", filename);
+                return (-1);
+            }
+#endif /* LIBXML_HTML_ENABLED */
+            break;
+        default:{
+                FILE *f;
+
+                f = fopen((char *) filename, "w");
+                if (f == NULL) {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "Failed to write to %s\n", filename);
+                    return (-1);
+                }
+                xmlElemDump(f, ctxt->doc, node);
+                fclose(f);
+            }
+    }
+    return (0);
+}
+
+/**
+ * xmlShellSave:
+ * @ctxt:  the shell context
+ * @filename:  the file name (optional)
+ * @node:  unused
+ * @node2:  unused
+ *
+ * Implements the XML shell function "save"
+ * Write the current document to the filename, or it's original name
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
+             xmlNodePtr node ATTRIBUTE_UNUSED,
+             xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    if ((ctxt == NULL) || (ctxt->doc == NULL))
+        return (-1);
+    if ((filename == NULL) || (filename[0] == 0))
+        filename = ctxt->filename;
+    if (filename == NULL)
+        return (-1);
+#ifdef W_OK
+    if (access((char *) filename, W_OK)) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Cannot save to %s\n", filename);
+        return (-1);
+    }
+#endif
+    switch (ctxt->doc->type) {
+        case XML_DOCUMENT_NODE:
+            if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
+            break;
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_HTML_ENABLED
+            if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
+#else
+            if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "Failed to save to %s\n", filename);
+            }
+#endif /* LIBXML_HTML_ENABLED */
+            break;
+        default:
+            xmlGenericError(xmlGenericErrorContext,
+	    "To save to subparts of a document use the 'write' command\n");
+            return (-1);
+
+    }
+    return (0);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+/**
+ * xmlShellValidate:
+ * @ctxt:  the shell context
+ * @dtd:  the DTD URI (optional)
+ * @node:  unused
+ * @node2:  unused
+ *
+ * Implements the XML shell function "validate"
+ * Validate the document, if a DTD path is provided, then the validation
+ * is done against the given DTD.
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
+                 xmlNodePtr node ATTRIBUTE_UNUSED,
+                 xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlValidCtxt vctxt;
+    int res = -1;
+
+    if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
+    vctxt.userData = stderr;
+    vctxt.error = (xmlValidityErrorFunc) fprintf;
+    vctxt.warning = (xmlValidityWarningFunc) fprintf;
+
+    if ((dtd == NULL) || (dtd[0] == 0)) {
+        res = xmlValidateDocument(&vctxt, ctxt->doc);
+    } else {
+        xmlDtdPtr subset;
+
+        subset = xmlParseDTD(NULL, (xmlChar *) dtd);
+        if (subset != NULL) {
+            res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
+
+            xmlFreeDtd(subset);
+        }
+    }
+    return (res);
+}
+#endif /* LIBXML_VALID_ENABLED */
+
+/**
+ * xmlShellDu:
+ * @ctxt:  the shell context
+ * @arg:  unused
+ * @tree:  a node defining a subtree
+ * @node2:  unused
+ *
+ * Implements the XML shell function "du"
+ * show the structure of the subtree under node @tree
+ * If @tree is null, the command works on the current node.
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlShellDu(xmlShellCtxtPtr ctxt,
+           char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
+           xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlNodePtr node;
+    int indent = 0, i;
+
+    if (!ctxt)
+	return (-1);
+
+    if (tree == NULL)
+        return (-1);
+    node = tree;
+    while (node != NULL) {
+        if ((node->type == XML_DOCUMENT_NODE) ||
+            (node->type == XML_HTML_DOCUMENT_NODE)) {
+            fprintf(ctxt->output, "/\n");
+        } else if (node->type == XML_ELEMENT_NODE) {
+            for (i = 0; i < indent; i++)
+                fprintf(ctxt->output, "  ");
+            fprintf(ctxt->output, "%s\n", node->name);
+        } else {
+        }
+
+        /*
+         * Browse the full subtree, deep first
+         */
+
+        if ((node->type == XML_DOCUMENT_NODE) ||
+            (node->type == XML_HTML_DOCUMENT_NODE)) {
+            node = ((xmlDocPtr) node)->children;
+        } else if ((node->children != NULL)
+                   && (node->type != XML_ENTITY_REF_NODE)) {
+            /* deep first */
+            node = node->children;
+            indent++;
+        } else if ((node != tree) && (node->next != NULL)) {
+            /* then siblings */
+            node = node->next;
+        } else if (node != tree) {
+            /* go up to parents->next if needed */
+            while (node != tree) {
+                if (node->parent != NULL) {
+                    node = node->parent;
+                    indent--;
+                }
+                if ((node != tree) && (node->next != NULL)) {
+                    node = node->next;
+                    break;
+                }
+                if (node->parent == NULL) {
+                    node = NULL;
+                    break;
+                }
+                if (node == tree) {
+                    node = NULL;
+                    break;
+                }
+            }
+            /* exit condition */
+            if (node == tree)
+                node = NULL;
+        } else
+            node = NULL;
+    }
+    return (0);
+}
+
+/**
+ * xmlShellPwd:
+ * @ctxt:  the shell context
+ * @buffer:  the output buffer
+ * @node:  a node 
+ * @node2:  unused
+ *
+ * Implements the XML shell function "pwd"
+ * Show the full path from the root to the node, if needed building
+ * thumblers when similar elements exists at a given ancestor level.
+ * The output is compatible with XPath commands.
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
+            xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
+{
+    xmlChar *path;
+
+    if ((node == NULL) || (buffer == NULL))
+        return (-1);
+
+    path = xmlGetNodePath(node);
+    if (path == NULL)
+	return (-1);
+
+    /*
+     * This test prevents buffer overflow, because this routine
+     * is only called by xmlShell, in which the second argument is
+     * 500 chars long.
+     * It is a dirty hack before a cleaner solution is found.
+     * Documentation should mention that the second argument must
+     * be at least 500 chars long, and could be stripped if too long.
+     */
+    snprintf(buffer, 499, "%s", path);
+    buffer[499] = '0';
+    xmlFree(path);
+
+    return (0);
+}
+
+/**
+ * xmlShell:
+ * @doc:  the initial document
+ * @filename:  the output buffer
+ * @input:  the line reading function
+ * @output:  the output FILE*, defaults to stdout if NULL
+ *
+ * Implements the XML shell 
+ * This allow to load, validate, view, modify and save a document
+ * using a environment similar to a UNIX commandline.
+ */
+void
+xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
+         FILE * output)
+{
+    char prompt[500] = "/ > ";
+    char *cmdline = NULL, *cur;
+    char command[100];
+    char arg[400];
+    int i;
+    xmlShellCtxtPtr ctxt;
+    xmlXPathObjectPtr list;
+
+    if (doc == NULL)
+        return;
+    if (filename == NULL)
+        return;
+    if (input == NULL)
+        return;
+    if (output == NULL)
+        output = stdout;
+    ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
+    if (ctxt == NULL)
+        return;
+    ctxt->loaded = 0;
+    ctxt->doc = doc;
+    ctxt->input = input;
+    ctxt->output = output;
+    ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
+    ctxt->node = (xmlNodePtr) ctxt->doc;
+
+#ifdef LIBXML_XPATH_ENABLED
+    ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
+    if (ctxt->pctxt == NULL) {
+        xmlFree(ctxt);
+        return;
+    }
+#endif /* LIBXML_XPATH_ENABLED */
+    while (1) {
+        if (ctxt->node == (xmlNodePtr) ctxt->doc)
+            snprintf(prompt, sizeof(prompt), "%s > ", "/");
+        else if ((ctxt->node != NULL) && (ctxt->node->name))
+            snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
+        else
+            snprintf(prompt, sizeof(prompt), "? > ");
+        prompt[sizeof(prompt) - 1] = 0;
+
+        /*
+         * Get a new command line
+         */
+        cmdline = ctxt->input(prompt);
+        if (cmdline == NULL)
+            break;
+
+        /*
+         * Parse the command itself
+         */
+        cur = cmdline;
+        while ((*cur == ' ') || (*cur == '\t'))
+            cur++;
+        i = 0;
+        while ((*cur != ' ') && (*cur != '\t') &&
+               (*cur != '\n') && (*cur != '\r')) {
+            if (*cur == 0)
+                break;
+            command[i++] = *cur++;
+        }
+        command[i] = 0;
+        if (i == 0)
+            continue;
+
+        /*
+         * Parse the argument
+         */
+        while ((*cur == ' ') || (*cur == '\t'))
+            cur++;
+        i = 0;
+        while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
+            if (*cur == 0)
+                break;
+            arg[i++] = *cur++;
+        }
+        arg[i] = 0;
+
+        /*
+         * start interpreting the command
+         */
+        if (!strcmp(command, "exit"))
+            break;
+        if (!strcmp(command, "quit"))
+            break;
+        if (!strcmp(command, "bye"))
+            break;
+		if (!strcmp(command, "help")) {
+		  fprintf(ctxt->output, "\tbase         display XML base of the node\n");
+		  fprintf(ctxt->output, "\tsetbase URI  change the XML base of the node\n");
+		  fprintf(ctxt->output, "\tbye          leave shell\n");
+		  fprintf(ctxt->output, "\tcat [node]   display node or current node\n");
+		  fprintf(ctxt->output, "\tcd [path]    change directory to path or to root\n");
+		  fprintf(ctxt->output, "\tdir [path]   dumps informations about the node (namespace, attributes, content)\n");
+		  fprintf(ctxt->output, "\tdu [path]    show the structure of the subtree under path or the current node\n");
+		  fprintf(ctxt->output, "\texit         leave shell\n");
+		  fprintf(ctxt->output, "\thelp         display this help\n");
+		  fprintf(ctxt->output, "\tfree         display memory usage\n");
+		  fprintf(ctxt->output, "\tload [name]  load a new document with name\n");
+		  fprintf(ctxt->output, "\tls [path]    list contents of path or the current directory\n");
+		  fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n");
+#ifdef LIBXML_XPATH_ENABLED
+		  fprintf(ctxt->output, "\txpath expr   evaluate the XPath expression in that context and print the result\n");
+		  fprintf(ctxt->output, "\tsetns nsreg  register a namespace to a prefix in the XPath evaluation context\n");
+		  fprintf(ctxt->output, "\t             format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n");
+		  fprintf(ctxt->output, "\tsetrootns    register all namespace found on the root element\n");
+		  fprintf(ctxt->output, "\t             the default namespace if any uses 'defaultns' prefix\n");
+#endif /* LIBXML_XPATH_ENABLED */
+		  fprintf(ctxt->output, "\tpwd          display current working directory\n");
+		  fprintf(ctxt->output, "\tquit         leave shell\n");
+#ifdef LIBXML_OUTPUT_ENABLED
+		  fprintf(ctxt->output, "\tsave [name]  save this document to name or the original name\n");
+		  fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_VALID_ENABLED
+		  fprintf(ctxt->output, "\tvalidate     check the document for errors\n");
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+		  fprintf(ctxt->output, "\trelaxng rng  validate the document agaisnt the Relax-NG schemas\n");
+#endif
+		  fprintf(ctxt->output, "\tgrep string  search for a string in the subtree\n");
+#ifdef LIBXML_VALID_ENABLED
+        } else if (!strcmp(command, "validate")) {
+            xmlShellValidate(ctxt, arg, NULL, NULL);
+#endif /* LIBXML_VALID_ENABLED */
+        } else if (!strcmp(command, "load")) {
+            xmlShellLoad(ctxt, arg, NULL, NULL);
+#ifdef LIBXML_SCHEMAS_ENABLED
+        } else if (!strcmp(command, "relaxng")) {
+            xmlShellRNGValidate(ctxt, arg, NULL, NULL);
+#endif
+#ifdef LIBXML_OUTPUT_ENABLED
+        } else if (!strcmp(command, "save")) {
+            xmlShellSave(ctxt, arg, NULL, NULL);
+        } else if (!strcmp(command, "write")) {
+	    if ((arg == NULL) || (arg[0] == 0))
+		xmlGenericError(xmlGenericErrorContext,
+                        "Write command requires a filename argument\n");
+	    else
+		xmlShellWrite(ctxt, arg, NULL, NULL);
+#endif /* LIBXML_OUTPUT_ENABLED */
+        } else if (!strcmp(command, "grep")) {
+            xmlShellGrep(ctxt, arg, ctxt->node, NULL);
+        } else if (!strcmp(command, "free")) {
+            if (arg[0] == 0) {
+                xmlMemShow(ctxt->output, 0);
+            } else {
+                int len = 0;
+
+                sscanf(arg, "%d", &len);
+                xmlMemShow(ctxt->output, len);
+            }
+        } else if (!strcmp(command, "pwd")) {
+            char dir[500];
+
+            if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
+                fprintf(ctxt->output, "%s\n", dir);
+        } else if (!strcmp(command, "du")) {
+            xmlShellDu(ctxt, NULL, ctxt->node, NULL);
+        } else if (!strcmp(command, "base")) {
+            xmlShellBase(ctxt, NULL, ctxt->node, NULL);
+        } else if (!strcmp(command, "set")) {
+	    xmlShellSetContent(ctxt, arg, ctxt->node, NULL);
+#ifdef LIBXML_XPATH_ENABLED
+        } else if (!strcmp(command, "setns")) {
+            if (arg[0] == 0) {
+		xmlGenericError(xmlGenericErrorContext,
+				"setns: prefix=[nsuri] required\n");
+            } else {
+                xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
+            }
+        } else if (!strcmp(command, "setrootns")) {
+	    xmlNodePtr root;
+
+	    root = xmlDocGetRootElement(ctxt->doc);
+	    xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
+        } else if (!strcmp(command, "xpath")) {
+            if (arg[0] == 0) {
+		xmlGenericError(xmlGenericErrorContext,
+				"xpath: expression required\n");
+	    } else {
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+		xmlXPathDebugDumpObject(ctxt->output, list, 0);
+		xmlXPathFreeObject(list);
+	    }
+#endif /* LIBXML_XPATH_ENABLED */
+#ifdef LIBXML_TREE_ENABLED
+        } else if (!strcmp(command, "setbase")) {
+            xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
+#endif
+        } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
+            int dir = (!strcmp(command, "dir"));
+
+            if (arg[0] == 0) {
+                if (dir)
+                    xmlShellDir(ctxt, NULL, ctxt->node, NULL);
+                else
+                    xmlShellList(ctxt, NULL, ctxt->node, NULL);
+            } else {
+                ctxt->pctxt->node = ctxt->node;
+#ifdef LIBXML_XPATH_ENABLED
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:{
+                                int indx;
+
+				if (list->nodesetval == NULL)
+				    break;
+
+                                for (indx = 0;
+                                     indx < list->nodesetval->nodeNr;
+                                     indx++) {
+                                    if (dir)
+                                        xmlShellDir(ctxt, NULL,
+                                                    list->nodesetval->
+                                                    nodeTab[indx], NULL);
+                                    else
+                                        xmlShellList(ctxt, NULL,
+                                                     list->nodesetval->
+                                                     nodeTab[indx], NULL);
+                                }
+                                break;
+                            }
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
+#endif
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+        } else if (!strcmp(command, "cd")) {
+            if (arg[0] == 0) {
+                ctxt->node = (xmlNodePtr) ctxt->doc;
+            } else {
+#ifdef LIBXML_XPATH_ENABLED
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:
+                            if (list->nodesetval != NULL) {
+				if (list->nodesetval->nodeNr == 1) {
+				    ctxt->node = list->nodesetval->nodeTab[0];
+				    if ((ctxt->node != NULL) &&
+				        (ctxt->node->type ==
+					 XML_NAMESPACE_DECL)) {
+					xmlGenericError(xmlGenericErrorContext,
+						    "cannot cd to namespace\n");
+					ctxt->node = NULL;
+				    }
+				} else
+				    xmlGenericError(xmlGenericErrorContext,
+						    "%s is a %d Node Set\n",
+						    arg,
+						    list->nodesetval->nodeNr);
+                            } else
+                                xmlGenericError(xmlGenericErrorContext,
+                                                "%s is an empty Node Set\n",
+                                                arg);
+                            break;
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
+#endif
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+#ifdef LIBXML_OUTPUT_ENABLED
+        } else if (!strcmp(command, "cat")) {
+            if (arg[0] == 0) {
+                xmlShellCat(ctxt, NULL, ctxt->node, NULL);
+            } else {
+                ctxt->pctxt->node = ctxt->node;
+#ifdef LIBXML_XPATH_ENABLED
+                ctxt->pctxt->node = ctxt->node;
+                list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+#else
+                list = NULL;
+#endif /* LIBXML_XPATH_ENABLED */
+                if (list != NULL) {
+                    switch (list->type) {
+                        case XPATH_UNDEFINED:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s: no such node\n", arg);
+                            break;
+                        case XPATH_NODESET:{
+                                int indx;
+
+				if (list->nodesetval == NULL)
+				    break;
+
+                                for (indx = 0;
+                                     indx < list->nodesetval->nodeNr;
+                                     indx++) {
+                                    if (i > 0)
+                                        fprintf(ctxt->output, " -------\n");
+                                    xmlShellCat(ctxt, NULL,
+                                                list->nodesetval->
+                                                nodeTab[indx], NULL);
+                                }
+                                break;
+                            }
+                        case XPATH_BOOLEAN:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a Boolean\n", arg);
+                            break;
+                        case XPATH_NUMBER:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a number\n", arg);
+                            break;
+                        case XPATH_STRING:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a string\n", arg);
+                            break;
+                        case XPATH_POINT:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a point\n", arg);
+                            break;
+                        case XPATH_RANGE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_LOCATIONSET:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is a range\n", arg);
+                            break;
+                        case XPATH_USERS:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is user-defined\n", arg);
+                            break;
+                        case XPATH_XSLT_TREE:
+                            xmlGenericError(xmlGenericErrorContext,
+                                            "%s is an XSLT value tree\n",
+                                            arg);
+                            break;
+                    }
+#ifdef LIBXML_XPATH_ENABLED
+                    xmlXPathFreeObject(list);
+#endif
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "%s: no such node\n", arg);
+                }
+                ctxt->pctxt->node = NULL;
+            }
+#endif /* LIBXML_OUTPUT_ENABLED */
+        } else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "Unknown command %s\n", command);
+        }
+        free(cmdline);          /* not xmlFree here ! */
+	cmdline = NULL;
+    }
+#ifdef LIBXML_XPATH_ENABLED
+    xmlXPathFreeContext(ctxt->pctxt);
+#endif /* LIBXML_XPATH_ENABLED */
+    if (ctxt->loaded) {
+        xmlFreeDoc(ctxt->doc);
+    }
+    if (ctxt->filename != NULL)
+        xmlFree(ctxt->filename);
+    xmlFree(ctxt);
+    if (cmdline != NULL)
+        free(cmdline);          /* not xmlFree here ! */
+}
+
+#endif /* LIBXML_XPATH_ENABLED */
+#define bottom_debugXML
+#include "elfgcchack.h"
+#endif /* LIBXML_DEBUG_ENABLED */
diff --git a/src/depcomp b/src/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/src/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/dict.c b/src/dict.c
new file mode 100644
index 0000000..3eff231
--- /dev/null
+++ b/src/dict.c
@@ -0,0 +1,1100 @@
+/*
+ * dict.c: dictionary of reusable strings, just used to avoid allocation
+ *         and freeing operations.
+ *
+ * Copyright (C) 2003 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ * Author: daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif defined(WIN32)
+typedef unsigned __int32 uint32_t;
+#endif
+#endif
+#include <libxml/tree.h>
+#include <libxml/dict.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+
+/* #define DEBUG_GROW */
+/* #define DICT_DEBUG_PATTERNS */
+
+#define MAX_HASH_LEN 3
+#define MIN_DICT_SIZE 128
+#define MAX_DICT_HASH 8 * 2048
+#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 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)))
+
+#else /* !WITH_BIG_KEY */
+#define xmlDictComputeKey(dict, name, len)			\
+        xmlDictComputeFastKey(name, len)
+#define xmlDictComputeQKey(dict, prefix, plen, name, len)	\
+        xmlDictComputeFastQKey(prefix, plen, name, len)
+#endif /* WITH_BIG_KEY */
+
+/*
+ * An entry in the dictionnary
+ */
+typedef struct _xmlDictEntry xmlDictEntry;
+typedef xmlDictEntry *xmlDictEntryPtr;
+struct _xmlDictEntry {
+    struct _xmlDictEntry *next;
+    const xmlChar *name;
+    int len;
+    int valid;
+    unsigned long okey;
+};
+
+typedef struct _xmlDictStrings xmlDictStrings;
+typedef xmlDictStrings *xmlDictStringsPtr;
+struct _xmlDictStrings {
+    xmlDictStringsPtr next;
+    xmlChar *free;
+    xmlChar *end;
+    int size;
+    int nbStrings;
+    xmlChar array[1];
+};
+/*
+ * The entire dictionnary
+ */
+struct _xmlDict {
+    int ref_counter;
+
+    struct _xmlDictEntry *dict;
+    int size;
+    int nbElems;
+    xmlDictStringsPtr strings;
+
+    struct _xmlDict *subdict;
+};
+
+/*
+ * A mutex for modifying the reference counter for shared
+ * dictionaries.
+ */
+static xmlRMutexPtr xmlDictMutex = NULL;
+
+/*
+ * Whether the dictionary mutex was initialized.
+ */
+static int xmlDictInitialized = 0;
+
+/**
+ * xmlInitializeDict:
+ *
+ * Do the dictionary mutex initialization.
+ * this function is not thread safe, initialization should
+ * preferably be done once at startup
+ */
+static int xmlInitializeDict(void) {
+    if (xmlDictInitialized)
+        return(1);
+
+    if ((xmlDictMutex = xmlNewRMutex()) == NULL)
+        return(0);
+
+    xmlDictInitialized = 1;
+    return(1);
+}
+
+/**
+ * xmlDictCleanup:
+ *
+ * Free the dictionary mutex.
+ */
+void
+xmlDictCleanup(void) {
+    if (!xmlDictInitialized)
+        return;
+
+    xmlFreeRMutex(xmlDictMutex);
+
+    xmlDictInitialized = 0;
+}
+
+/*
+ * xmlDictAddString:
+ * @dict: the dictionnary
+ * @name: the name of the userdata
+ * @len: the length of the name, if -1 it is recomputed
+ *
+ * Add the string to the array[s]
+ *
+ * Returns the pointer of the local string, or NULL in case of error.
+ */
+static const xmlChar *
+xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
+    xmlDictStringsPtr pool;
+    const xmlChar *ret;
+    int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+
+#ifdef DICT_DEBUG_PATTERNS
+    fprintf(stderr, "-");
+#endif
+    pool = dict->strings;
+    while (pool != NULL) {
+	if (pool->end - pool->free > namelen)
+	    goto found_pool;
+	if (pool->size > size) size = pool->size;
+	pool = pool->next;
+    }
+    /*
+     * Not found, need to allocate
+     */
+    if (pool == NULL) {
+        if (size == 0) size = 1000;
+	else size *= 4; /* exponential growth */
+        if (size < 4 * namelen) 
+	    size = 4 * namelen; /* just in case ! */
+	pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
+	if (pool == NULL)
+	    return(NULL);
+	pool->size = size;
+	pool->nbStrings = 0;
+	pool->free = &pool->array[0];
+	pool->end = &pool->array[size];
+	pool->next = dict->strings;
+	dict->strings = pool;
+#ifdef DICT_DEBUG_PATTERNS
+        fprintf(stderr, "+");
+#endif
+    }
+found_pool:
+    ret = pool->free;
+    memcpy(pool->free, name, namelen);
+    pool->free += namelen;
+    *(pool->free++) = 0;
+    pool->nbStrings++;
+    return(ret);
+}
+
+/*
+ * xmlDictAddQString:
+ * @dict: the dictionnary
+ * @prefix: the prefix of the userdata
+ * @plen: the prefix length
+ * @name: the name of the userdata
+ * @len: the length of the name, if -1 it is recomputed
+ *
+ * Add the QName to the array[s]
+ *
+ * Returns the pointer of the local string, or NULL in case of error.
+ */
+static const xmlChar *
+xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
+                 const xmlChar *name, int namelen)
+{
+    xmlDictStringsPtr pool;
+    const xmlChar *ret;
+    int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+
+    if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
+
+#ifdef DICT_DEBUG_PATTERNS
+    fprintf(stderr, "=");
+#endif
+    pool = dict->strings;
+    while (pool != NULL) {
+	if (pool->end - pool->free > namelen + plen + 1)
+	    goto found_pool;
+	if (pool->size > size) size = pool->size;
+	pool = pool->next;
+    }
+    /*
+     * Not found, need to allocate
+     */
+    if (pool == NULL) {
+        if (size == 0) size = 1000;
+	else size *= 4; /* exponential growth */
+        if (size < 4 * (namelen + plen + 1))
+	    size = 4 * (namelen + plen + 1); /* just in case ! */
+	pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
+	if (pool == NULL)
+	    return(NULL);
+	pool->size = size;
+	pool->nbStrings = 0;
+	pool->free = &pool->array[0];
+	pool->end = &pool->array[size];
+	pool->next = dict->strings;
+	dict->strings = pool;
+#ifdef DICT_DEBUG_PATTERNS
+        fprintf(stderr, "+");
+#endif
+    }
+found_pool:
+    ret = pool->free;
+    memcpy(pool->free, prefix, plen);
+    pool->free += plen;
+    *(pool->free++) = ':';
+    memcpy(pool->free, name, namelen);
+    pool->free += namelen;
+    *(pool->free++) = 0;
+    pool->nbStrings++;
+    return(ret);
+}
+
+#ifdef WITH_BIG_KEY
+/*
+ * xmlDictComputeBigKey:
+ *
+ * Calculate a hash key using a good hash function that works well for
+ * larger hash table sizes.
+ *
+ * Hash function by "One-at-a-Time Hash" see
+ * http://burtleburtle.net/bob/hash/doobs.html
+ */
+
+static uint32_t
+xmlDictComputeBigKey(const xmlChar* data, int namelen) {
+    uint32_t hash;
+    int i;
+
+    if (namelen <= 0 || data == NULL) return(0);
+
+    hash = 0;
+
+    for (i = 0;i < namelen; i++) {
+        hash += data[i];
+	hash += (hash << 10);
+	hash ^= (hash >> 6);
+    }
+    hash += (hash << 3);
+    hash ^= (hash >> 11);
+    hash += (hash << 15);
+
+    return hash;
+}
+
+/*
+ * xmlDictComputeBigQKey:
+ *
+ * Calculate a hash key for two strings using a good hash function
+ * that works well for larger hash table sizes.
+ *
+ * Hash function by "One-at-a-Time Hash" see
+ * http://burtleburtle.net/bob/hash/doobs.html
+ *
+ * Neither of the two strings must be NULL.
+ */
+static unsigned long
+xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
+                      const xmlChar *name, int len)
+{
+    uint32_t hash;
+    int i;
+
+    hash = 0;
+
+    for (i = 0;i < plen; i++) {
+        hash += prefix[i];
+	hash += (hash << 10);
+	hash ^= (hash >> 6);
+    }
+    hash += ':';
+    hash += (hash << 10);
+    hash ^= (hash >> 6);
+
+    for (i = 0;i < len; i++) {
+        hash += name[i];
+	hash += (hash << 10);
+	hash ^= (hash >> 6);
+    }
+    hash += (hash << 3);
+    hash ^= (hash >> 11);
+    hash += (hash << 15);
+
+    return hash;
+}
+#endif /* WITH_BIG_KEY */
+
+/*
+ * xmlDictComputeFastKey:
+ *
+ * Calculate a hash key using a fast hash function that works well
+ * for low hash table fill.
+ */
+static unsigned long
+xmlDictComputeFastKey(const xmlChar *name, int namelen) {
+    unsigned long value = 0L;
+
+    if (name == NULL) return(0);
+    value = *name;
+    value <<= 5;
+    if (namelen > 10) {
+        value += name[namelen - 1];
+        namelen = 10;
+    }
+    switch (namelen) {
+        case 10: value += name[9];
+        case 9: value += name[8];
+        case 8: value += name[7];
+        case 7: value += name[6];
+        case 6: value += name[5];
+        case 5: value += name[4];
+        case 4: value += name[3];
+        case 3: value += name[2];
+        case 2: value += name[1];
+        default: break;
+    }
+    return(value);
+}
+
+/*
+ * xmlDictComputeFastQKey:
+ *
+ * Calculate a hash key for two strings using a fast hash function
+ * that works well for low hash table fill.
+ *
+ * Neither of the two strings must be NULL.
+ */
+static unsigned long
+xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
+                       const xmlChar *name, int len)
+{
+    unsigned long value = 0L;
+
+    if (plen == 0)
+	value += 30 * (unsigned long) ':';
+    else
+	value += 30 * (*prefix);
+
+    if (len > 10) {
+        value += name[len - (plen + 1 + 1)];
+        len = 10;
+	if (plen > 10)
+	    plen = 10;
+    }
+    switch (plen) {
+        case 10: value += prefix[9];
+        case 9: value += prefix[8];
+        case 8: value += prefix[7];
+        case 7: value += prefix[6];
+        case 6: value += prefix[5];
+        case 5: value += prefix[4];
+        case 4: value += prefix[3];
+        case 3: value += prefix[2];
+        case 2: value += prefix[1];
+        case 1: value += prefix[0];
+        default: break;
+    }
+    len -= plen;
+    if (len > 0) {
+        value += (unsigned long) ':';
+	len--;
+    }
+    switch (len) {
+        case 10: value += name[9];
+        case 9: value += name[8];
+        case 8: value += name[7];
+        case 7: value += name[6];
+        case 6: value += name[5];
+        case 5: value += name[4];
+        case 4: value += name[3];
+        case 3: value += name[2];
+        case 2: value += name[1];
+        case 1: value += name[0];
+        default: break;
+    }
+    return(value);
+}
+
+/**
+ * xmlDictCreate:
+ *
+ * Create a new dictionary
+ *
+ * Returns the newly created dictionnary, or NULL if an error occured.
+ */
+xmlDictPtr
+xmlDictCreate(void) {
+    xmlDictPtr dict;
+
+    if (!xmlDictInitialized)
+        if (!xmlInitializeDict())
+            return(NULL);
+
+#ifdef DICT_DEBUG_PATTERNS
+    fprintf(stderr, "C");
+#endif
+
+    dict = xmlMalloc(sizeof(xmlDict));
+    if (dict) {
+        dict->ref_counter = 1;
+
+        dict->size = MIN_DICT_SIZE;
+	dict->nbElems = 0;
+        dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry));
+	dict->strings = NULL;
+	dict->subdict = NULL;
+        if (dict->dict) {
+	    memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
+	    return(dict);
+        }
+        xmlFree(dict);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlDictCreateSub:
+ * @sub: an existing dictionnary
+ *
+ * Create a new dictionary, inheriting strings from the read-only
+ * dictionnary @sub. On lookup, strings are first searched in the
+ * new dictionnary, then in @sub, and if not found are created in the
+ * new dictionnary.
+ *
+ * Returns the newly created dictionnary, or NULL if an error occured.
+ */
+xmlDictPtr
+xmlDictCreateSub(xmlDictPtr sub) {
+    xmlDictPtr dict = xmlDictCreate();
+
+    if ((dict != NULL) && (sub != NULL)) {
+#ifdef DICT_DEBUG_PATTERNS
+        fprintf(stderr, "R");
+#endif
+        dict->subdict = sub;
+	xmlDictReference(dict->subdict);
+    }
+    return(dict);
+}
+
+/**
+ * xmlDictReference:
+ * @dict: the dictionnary
+ *
+ * Increment the reference counter of a dictionary
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+int
+xmlDictReference(xmlDictPtr dict) {
+    if (!xmlDictInitialized)
+        if (!xmlInitializeDict())
+            return(-1);
+
+    if (dict == NULL) return -1;
+    xmlRMutexLock(xmlDictMutex);
+    dict->ref_counter++;
+    xmlRMutexUnlock(xmlDictMutex);
+    return(0);
+}
+
+/**
+ * xmlDictGrow:
+ * @dict: the dictionnary
+ * @size: the new size of the dictionnary
+ *
+ * resize the dictionnary
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlDictGrow(xmlDictPtr dict, int size) {
+    unsigned long key, okey;
+    int oldsize, i;
+    xmlDictEntryPtr iter, next;
+    struct _xmlDictEntry *olddict;
+#ifdef DEBUG_GROW
+    unsigned long nbElem = 0;
+#endif
+    int ret = 0;
+    int keep_keys = 1;
+
+    if (dict == NULL)
+	return(-1);
+    if (size < 8)
+        return(-1);
+    if (size > 8 * 2048)
+	return(-1);
+
+#ifdef DICT_DEBUG_PATTERNS
+    fprintf(stderr, "*");
+#endif
+
+    oldsize = dict->size;
+    olddict = dict->dict;
+    if (olddict == NULL)
+        return(-1);
+    if (oldsize == MIN_DICT_SIZE)
+        keep_keys = 0;
+
+    dict->dict = xmlMalloc(size * sizeof(xmlDictEntry));
+    if (dict->dict == NULL) {
+	dict->dict = olddict;
+	return(-1);
+    }
+    memset(dict->dict, 0, size * sizeof(xmlDictEntry));
+    dict->size = size;
+
+    /*	If the two loops are merged, there would be situations where
+	a new entry needs to allocated and data copied into it from
+	the main dict. It is nicer to run through the array twice, first
+	copying all the elements in the main array (less probability of
+	allocate) and then the rest, so we only free in the second loop.
+    */
+    for (i = 0; i < oldsize; i++) {
+	if (olddict[i].valid == 0)
+	    continue;
+
+	if (keep_keys)
+	    okey = olddict[i].okey;
+	else
+	    okey = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len);
+	key = okey % dict->size;
+
+	if (dict->dict[key].valid == 0) {
+	    memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
+	    dict->dict[key].next = NULL;
+	    dict->dict[key].okey = okey;
+	} else {
+	    xmlDictEntryPtr entry;
+
+	    entry = xmlMalloc(sizeof(xmlDictEntry));
+	    if (entry != NULL) {
+		entry->name = olddict[i].name;
+		entry->len = olddict[i].len;
+		entry->okey = okey;
+		entry->next = dict->dict[key].next;
+		entry->valid = 1;
+		dict->dict[key].next = entry;
+	    } else {
+	        /*
+		 * we don't have much ways to alert from herei
+		 * result is loosing an entry and unicity garantee
+		 */
+	        ret = -1;
+	    }
+	}
+#ifdef DEBUG_GROW
+	nbElem++;
+#endif
+    }
+
+    for (i = 0; i < oldsize; i++) {
+	iter = olddict[i].next;
+	while (iter) {
+	    next = iter->next;
+
+	    /*
+	     * put back the entry in the new dict
+	     */
+
+	    if (keep_keys)
+		okey = iter->okey;
+	    else
+		okey = xmlDictComputeKey(dict, iter->name, iter->len);
+	    key = okey % dict->size;
+	    if (dict->dict[key].valid == 0) {
+		memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
+		dict->dict[key].next = NULL;
+		dict->dict[key].valid = 1;
+		dict->dict[key].okey = okey;
+		xmlFree(iter);
+	    } else {
+		iter->next = dict->dict[key].next;
+		iter->okey = okey;
+		dict->dict[key].next = iter;
+	    }
+
+#ifdef DEBUG_GROW
+	    nbElem++;
+#endif
+
+	    iter = next;
+	}
+    }
+
+    xmlFree(olddict);
+
+#ifdef DEBUG_GROW
+    xmlGenericError(xmlGenericErrorContext,
+	    "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
+#endif
+
+    return(ret);
+}
+
+/**
+ * xmlDictFree:
+ * @dict: the dictionnary
+ *
+ * Free the hash @dict and its contents. The userdata is
+ * deallocated with @f if provided.
+ */
+void
+xmlDictFree(xmlDictPtr dict) {
+    int i;
+    xmlDictEntryPtr iter;
+    xmlDictEntryPtr next;
+    int inside_dict = 0;
+    xmlDictStringsPtr pool, nextp;
+
+    if (dict == NULL)
+	return;
+
+    if (!xmlDictInitialized)
+        if (!xmlInitializeDict())
+            return;
+
+    /* decrement the counter, it may be shared by a parser and docs */
+    xmlRMutexLock(xmlDictMutex);
+    dict->ref_counter--;
+    if (dict->ref_counter > 0) {
+        xmlRMutexUnlock(xmlDictMutex);
+        return;
+    }
+
+    xmlRMutexUnlock(xmlDictMutex);
+
+    if (dict->subdict != NULL) {
+        xmlDictFree(dict->subdict);
+    }
+
+    if (dict->dict) {
+	for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) {
+	    iter = &(dict->dict[i]);
+	    if (iter->valid == 0)
+		continue;
+	    inside_dict = 1;
+	    while (iter) {
+		next = iter->next;
+		if (!inside_dict)
+		    xmlFree(iter);
+		dict->nbElems--;
+		inside_dict = 0;
+		iter = next;
+	    }
+	}
+	xmlFree(dict->dict);
+    }
+    pool = dict->strings;
+    while (pool != NULL) {
+        nextp = pool->next;
+	xmlFree(pool);
+	pool = nextp;
+    }
+    xmlFree(dict);
+}
+
+/**
+ * xmlDictLookup:
+ * @dict: the dictionnary
+ * @name: the name of the userdata
+ * @len: the length of the name, if -1 it is recomputed
+ *
+ * Add the @name to the dictionnary @dict if not present.
+ *
+ * Returns the internal copy of the name or NULL in case of internal error
+ */
+const xmlChar *
+xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+    unsigned long key, okey, nbi = 0;
+    xmlDictEntryPtr entry;
+    xmlDictEntryPtr insert;
+    const xmlChar *ret;
+
+    if ((dict == NULL) || (name == NULL))
+	return(NULL);
+
+    if (len < 0)
+        len = strlen((const char *) name);
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    okey = xmlDictComputeKey(dict, name, len);
+    key = okey % dict->size;
+    if (dict->dict[key].valid == 0) {
+	insert = NULL;
+    } else {
+	for (insert = &(dict->dict[key]); insert->next != NULL;
+	     insert = insert->next) {
+#ifdef __GNUC__
+	    if ((insert->okey == okey) && (insert->len == len)) {
+		if (!memcmp(insert->name, name, len))
+		    return(insert->name);
+	    }
+#else
+	    if ((insert->okey == okey) && (insert->len == len) &&
+	        (!xmlStrncmp(insert->name, name, len)))
+		return(insert->name);
+#endif
+	    nbi++;
+	}
+#ifdef __GNUC__
+	if ((insert->okey == okey) && (insert->len == len)) {
+	    if (!memcmp(insert->name, name, len))
+		return(insert->name);
+	}
+#else
+	if ((insert->okey == okey) && (insert->len == len) &&
+	    (!xmlStrncmp(insert->name, name, len)))
+	    return(insert->name);
+#endif
+    }
+
+    if (dict->subdict) {
+        unsigned long skey;
+
+        /* we cannot always reuse the same okey for the subdict */
+        if (((dict->size == MIN_DICT_SIZE) &&
+	     (dict->subdict->size != MIN_DICT_SIZE)) ||
+            ((dict->size != MIN_DICT_SIZE) &&
+	     (dict->subdict->size == MIN_DICT_SIZE)))
+	    skey = xmlDictComputeKey(dict->subdict, name, len);
+	else
+	    skey = okey;
+
+	key = skey % dict->subdict->size;
+	if (dict->subdict->dict[key].valid != 0) {
+	    xmlDictEntryPtr tmp;
+
+	    for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
+		 tmp = tmp->next) {
+#ifdef __GNUC__
+		if ((tmp->okey == skey) && (tmp->len == len)) {
+		    if (!memcmp(tmp->name, name, len))
+			return(tmp->name);
+		}
+#else
+		if ((tmp->okey == skey) && (tmp->len == len) &&
+		    (!xmlStrncmp(tmp->name, name, len)))
+		    return(tmp->name);
+#endif
+		nbi++;
+	    }
+#ifdef __GNUC__
+	    if ((tmp->okey == skey) && (tmp->len == len)) {
+		if (!memcmp(tmp->name, name, len))
+		    return(tmp->name);
+	    }
+#else
+	    if ((tmp->okey == skey) && (tmp->len == len) &&
+		(!xmlStrncmp(tmp->name, name, len)))
+		return(tmp->name);
+#endif
+	}
+	key = okey % dict->size;
+    }
+
+    ret = xmlDictAddString(dict, name, len);
+    if (ret == NULL)
+        return(NULL);
+    if (insert == NULL) {
+	entry = &(dict->dict[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlDictEntry));
+	if (entry == NULL)
+	     return(NULL);
+    }
+    entry->name = ret;
+    entry->len = len;
+    entry->next = NULL;
+    entry->valid = 1;
+    entry->okey = okey;
+
+
+    if (insert != NULL) 
+	insert->next = entry;
+
+    dict->nbElems++;
+
+    if ((nbi > MAX_HASH_LEN) &&
+        (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) {
+	if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0)
+	    return(NULL);
+    }
+    /* Note that entry may have been freed at this point by xmlDictGrow */
+
+    return(ret);
+}
+
+/**
+ * xmlDictExists:
+ * @dict: the dictionnary
+ * @name: the name of the userdata
+ * @len: the length of the name, if -1 it is recomputed
+ *
+ * Check if the @name exists in the dictionnary @dict.
+ *
+ * Returns the internal copy of the name or NULL if not found.
+ */
+const xmlChar *
+xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+    unsigned long key, okey, nbi = 0;
+    xmlDictEntryPtr insert;
+
+    if ((dict == NULL) || (name == NULL))
+	return(NULL);
+
+    if (len < 0)
+        len = strlen((const char *) name);
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    okey = xmlDictComputeKey(dict, name, len);
+    key = okey % dict->size;
+    if (dict->dict[key].valid == 0) {
+	insert = NULL;
+    } else {
+	for (insert = &(dict->dict[key]); insert->next != NULL;
+	     insert = insert->next) {
+#ifdef __GNUC__
+	    if ((insert->okey == okey) && (insert->len == len)) {
+		if (!memcmp(insert->name, name, len))
+		    return(insert->name);
+	    }
+#else
+	    if ((insert->okey == okey) && (insert->len == len) &&
+	        (!xmlStrncmp(insert->name, name, len)))
+		return(insert->name);
+#endif
+	    nbi++;
+	}
+#ifdef __GNUC__
+	if ((insert->okey == okey) && (insert->len == len)) {
+	    if (!memcmp(insert->name, name, len))
+		return(insert->name);
+	}
+#else
+	if ((insert->okey == okey) && (insert->len == len) &&
+	    (!xmlStrncmp(insert->name, name, len)))
+	    return(insert->name);
+#endif
+    }
+
+    if (dict->subdict) {
+        unsigned long skey;
+
+        /* we cannot always reuse the same okey for the subdict */
+        if (((dict->size == MIN_DICT_SIZE) &&
+	     (dict->subdict->size != MIN_DICT_SIZE)) ||
+            ((dict->size != MIN_DICT_SIZE) &&
+	     (dict->subdict->size == MIN_DICT_SIZE)))
+	    skey = xmlDictComputeKey(dict->subdict, name, len);
+	else
+	    skey = okey;
+
+	key = skey % dict->subdict->size;
+	if (dict->subdict->dict[key].valid != 0) {
+	    xmlDictEntryPtr tmp;
+
+	    for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
+		 tmp = tmp->next) {
+#ifdef __GNUC__
+		if ((tmp->okey == skey) && (tmp->len == len)) {
+		    if (!memcmp(tmp->name, name, len))
+			return(tmp->name);
+		}
+#else
+		if ((tmp->okey == skey) && (tmp->len == len) &&
+		    (!xmlStrncmp(tmp->name, name, len)))
+		    return(tmp->name);
+#endif
+		nbi++;
+	    }
+#ifdef __GNUC__
+	    if ((tmp->okey == skey) && (tmp->len == len)) {
+		if (!memcmp(tmp->name, name, len))
+		    return(tmp->name);
+	    }
+#else
+	    if ((tmp->okey == skey) && (tmp->len == len) &&
+		(!xmlStrncmp(tmp->name, name, len)))
+		return(tmp->name);
+#endif
+	}
+    }
+
+    /* not found */
+    return(NULL);
+}
+
+/**
+ * xmlDictQLookup:
+ * @dict: the dictionnary
+ * @prefix: the prefix
+ * @name: the name
+ *
+ * Add the QName @prefix:@name to the hash @dict if not present.
+ *
+ * Returns the internal copy of the QName or NULL in case of internal error
+ */
+const xmlChar *
+xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
+    unsigned long okey, key, nbi = 0;
+    xmlDictEntryPtr entry;
+    xmlDictEntryPtr insert;
+    const xmlChar *ret;
+    int len, plen, l;
+
+    if ((dict == NULL) || (name == NULL))
+	return(NULL);
+    if (prefix == NULL)
+        return(xmlDictLookup(dict, name, -1));
+
+    l = len = strlen((const char *) name);
+    plen = strlen((const char *) prefix);
+    len += 1 + plen;
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    okey = xmlDictComputeQKey(dict, prefix, plen, name, l);
+    key = okey % dict->size;
+    if (dict->dict[key].valid == 0) {
+	insert = NULL;
+    } else {
+	for (insert = &(dict->dict[key]); insert->next != NULL;
+	     insert = insert->next) {
+	    if ((insert->okey == okey) && (insert->len == len) &&
+	        (xmlStrQEqual(prefix, name, insert->name)))
+		return(insert->name);
+	    nbi++;
+	}
+	if ((insert->okey == okey) && (insert->len == len) &&
+	    (xmlStrQEqual(prefix, name, insert->name)))
+	    return(insert->name);
+    }
+
+    if (dict->subdict) {
+        unsigned long skey;
+
+        /* we cannot always reuse the same okey for the subdict */
+        if (((dict->size == MIN_DICT_SIZE) &&
+	     (dict->subdict->size != MIN_DICT_SIZE)) ||
+            ((dict->size != MIN_DICT_SIZE) &&
+	     (dict->subdict->size == MIN_DICT_SIZE)))
+	    skey = xmlDictComputeQKey(dict->subdict, prefix, plen, name, l);
+	else
+	    skey = okey;
+
+	key = skey % dict->subdict->size;
+	if (dict->subdict->dict[key].valid != 0) {
+	    xmlDictEntryPtr tmp;
+	    for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
+		 tmp = tmp->next) {
+		if ((tmp->okey == skey) && (tmp->len == len) &&
+		    (xmlStrQEqual(prefix, name, tmp->name)))
+		    return(tmp->name);
+		nbi++;
+	    }
+	    if ((tmp->okey == skey) && (tmp->len == len) &&
+		(xmlStrQEqual(prefix, name, tmp->name)))
+		return(tmp->name);
+	}
+	key = okey % dict->size;
+    }
+
+    ret = xmlDictAddQString(dict, prefix, plen, name, l);
+    if (ret == NULL)
+        return(NULL);
+    if (insert == NULL) {
+	entry = &(dict->dict[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlDictEntry));
+	if (entry == NULL)
+	     return(NULL);
+    }
+    entry->name = ret;
+    entry->len = len;
+    entry->next = NULL;
+    entry->valid = 1;
+    entry->okey = okey;
+
+    if (insert != NULL) 
+	insert->next = entry;
+
+    dict->nbElems++;
+
+    if ((nbi > MAX_HASH_LEN) &&
+        (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
+	xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
+    /* Note that entry may have been freed at this point by xmlDictGrow */
+
+    return(ret);
+}
+
+/**
+ * xmlDictOwns:
+ * @dict: the dictionnary
+ * @str: the string
+ *
+ * check if a string is owned by the disctionary
+ *
+ * Returns 1 if true, 0 if false and -1 in case of error
+ * -1 in case of error
+ */
+int
+xmlDictOwns(xmlDictPtr dict, const xmlChar *str) {
+    xmlDictStringsPtr pool;
+
+    if ((dict == NULL) || (str == NULL))
+	return(-1);
+    pool = dict->strings;
+    while (pool != NULL) {
+        if ((str >= &pool->array[0]) && (str <= pool->free))
+	    return(1);
+	pool = pool->next;
+    }
+    if (dict->subdict)
+        return(xmlDictOwns(dict->subdict, str));
+    return(0);
+}
+
+/**
+ * xmlDictSize:
+ * @dict: the dictionnary
+ *
+ * Query the number of elements installed in the hash @dict.
+ *
+ * Returns the number of elements in the dictionnary or
+ * -1 in case of error
+ */
+int
+xmlDictSize(xmlDictPtr dict) {
+    if (dict == NULL)
+	return(-1);
+    if (dict->subdict)
+        return(dict->nbElems + dict->subdict->nbElems);
+    return(dict->nbElems);
+}
+
+
+#define bottom_dict
+#include "elfgcchack.h"
diff --git a/src/elfgcchack.h b/src/elfgcchack.h
new file mode 100644
index 0000000..84e8151
--- /dev/null
+++ b/src/elfgcchack.h
@@ -0,0 +1,17610 @@
+/*
+ * elfgcchack.h: hack by Arjan van de Ven <arjanv@redhat.com> to speed
+ *               up the code when using gcc for call within the library.
+ *
+ * Based on the analysis http://people.redhat.com/drepper/dsohowto.pdf
+ * from Ulrich drepper. Rewritten to be generated from the XML description
+ * file for libxml2 API
+ * autogenerated with xsltproc doc/elfgcchack.xsl doc/libxml2-api.xml
+ */
+
+#ifdef IN_LIBXML
+#ifdef __GNUC__
+#ifdef PIC
+#ifdef linux
+#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
+
+#include "libxml/c14n.h"
+#include "libxml/catalog.h"
+#include "libxml/chvalid.h"
+#include "libxml/debugXML.h"
+#include "libxml/dict.h"
+#include "libxml/DOCBparser.h"
+#include "libxml/encoding.h"
+#include "libxml/entities.h"
+#include "libxml/globals.h"
+#include "libxml/hash.h"
+#include "libxml/HTMLparser.h"
+#include "libxml/HTMLtree.h"
+#include "libxml/list.h"
+#include "libxml/nanoftp.h"
+#include "libxml/nanohttp.h"
+#include "libxml/parser.h"
+#include "libxml/parserInternals.h"
+#include "libxml/pattern.h"
+#include "libxml/relaxng.h"
+#include "libxml/SAX2.h"
+#include "libxml/SAX.h"
+#include "libxml/schemasInternals.h"
+#include "libxml/schematron.h"
+#include "libxml/threads.h"
+#include "libxml/tree.h"
+#include "libxml/uri.h"
+#include "libxml/valid.h"
+#include "libxml/xinclude.h"
+#include "libxml/xlink.h"
+#include "libxml/xmlautomata.h"
+#include "libxml/xmlerror.h"
+#include "libxml/xmlexports.h"
+#include "libxml/xmlIO.h"
+#include "libxml/xmlmemory.h"
+#include "libxml/xmlreader.h"
+#include "libxml/xmlregexp.h"
+#include "libxml/xmlsave.h"
+#include "libxml/xmlschemas.h"
+#include "libxml/xmlschemastypes.h"
+#include "libxml/xmlstring.h"
+#include "libxml/xmlunicode.h"
+#include "libxml/xmlversion.h"
+#include "libxml/xmlwriter.h"
+#include "libxml/xpath.h"
+#include "libxml/xpathInternals.h"
+#include "libxml/xpointer.h"
+#include "libxml/xmlmodule.h"
+
+/* special hot spot not exported ones */
+
+#ifdef bottom_globals
+#undef __xmlGenericError
+extern __typeof (__xmlGenericError) __xmlGenericError __attribute((alias("__xmlGenericError__internal_alias")));
+#else
+#ifndef __xmlGenericError
+extern __typeof (__xmlGenericError) __xmlGenericError__internal_alias __attribute((visibility("hidden")));
+#define __xmlGenericError __xmlGenericError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef __xmlGenericErrorContext
+extern __typeof (__xmlGenericErrorContext) __xmlGenericErrorContext __attribute((alias("__xmlGenericErrorContext__internal_alias")));
+#else
+#ifndef __xmlGenericErrorContext
+extern __typeof (__xmlGenericErrorContext) __xmlGenericErrorContext__internal_alias __attribute((visibility("hidden")));
+#define __xmlGenericErrorContext __xmlGenericErrorContext__internal_alias
+#endif
+#endif
+
+/* list generated from libxml2-api.xml */
+#if defined(LIBXML_DOCB_ENABLED)
+#ifdef bottom_DOCBparser
+#undef docbCreatePushParserCtxt
+extern __typeof (docbCreatePushParserCtxt) docbCreatePushParserCtxt __attribute((alias("docbCreatePushParserCtxt__internal_alias")));
+#else
+#ifndef docbCreatePushParserCtxt
+extern __typeof (docbCreatePushParserCtxt) docbCreatePushParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define docbCreatePushParserCtxt docbCreatePushParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlAttrAllowed
+extern __typeof (htmlAttrAllowed) htmlAttrAllowed __attribute((alias("htmlAttrAllowed__internal_alias")));
+#else
+#ifndef htmlAttrAllowed
+extern __typeof (htmlAttrAllowed) htmlAttrAllowed__internal_alias __attribute((visibility("hidden")));
+#define htmlAttrAllowed htmlAttrAllowed__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlAutoCloseTag
+extern __typeof (htmlAutoCloseTag) htmlAutoCloseTag __attribute((alias("htmlAutoCloseTag__internal_alias")));
+#else
+#ifndef htmlAutoCloseTag
+extern __typeof (htmlAutoCloseTag) htmlAutoCloseTag__internal_alias __attribute((visibility("hidden")));
+#define htmlAutoCloseTag htmlAutoCloseTag__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCreateFileParserCtxt
+extern __typeof (htmlCreateFileParserCtxt) htmlCreateFileParserCtxt __attribute((alias("htmlCreateFileParserCtxt__internal_alias")));
+#else
+#ifndef htmlCreateFileParserCtxt
+extern __typeof (htmlCreateFileParserCtxt) htmlCreateFileParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define htmlCreateFileParserCtxt htmlCreateFileParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCreateMemoryParserCtxt
+extern __typeof (htmlCreateMemoryParserCtxt) htmlCreateMemoryParserCtxt __attribute((alias("htmlCreateMemoryParserCtxt__internal_alias")));
+#else
+#ifndef htmlCreateMemoryParserCtxt
+extern __typeof (htmlCreateMemoryParserCtxt) htmlCreateMemoryParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define htmlCreateMemoryParserCtxt htmlCreateMemoryParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCreatePushParserCtxt
+extern __typeof (htmlCreatePushParserCtxt) htmlCreatePushParserCtxt __attribute((alias("htmlCreatePushParserCtxt__internal_alias")));
+#else
+#ifndef htmlCreatePushParserCtxt
+extern __typeof (htmlCreatePushParserCtxt) htmlCreatePushParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define htmlCreatePushParserCtxt htmlCreatePushParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReadDoc
+extern __typeof (htmlCtxtReadDoc) htmlCtxtReadDoc __attribute((alias("htmlCtxtReadDoc__internal_alias")));
+#else
+#ifndef htmlCtxtReadDoc
+extern __typeof (htmlCtxtReadDoc) htmlCtxtReadDoc__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReadDoc htmlCtxtReadDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReadFd
+extern __typeof (htmlCtxtReadFd) htmlCtxtReadFd __attribute((alias("htmlCtxtReadFd__internal_alias")));
+#else
+#ifndef htmlCtxtReadFd
+extern __typeof (htmlCtxtReadFd) htmlCtxtReadFd__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReadFd htmlCtxtReadFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReadFile
+extern __typeof (htmlCtxtReadFile) htmlCtxtReadFile __attribute((alias("htmlCtxtReadFile__internal_alias")));
+#else
+#ifndef htmlCtxtReadFile
+extern __typeof (htmlCtxtReadFile) htmlCtxtReadFile__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReadFile htmlCtxtReadFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReadIO
+extern __typeof (htmlCtxtReadIO) htmlCtxtReadIO __attribute((alias("htmlCtxtReadIO__internal_alias")));
+#else
+#ifndef htmlCtxtReadIO
+extern __typeof (htmlCtxtReadIO) htmlCtxtReadIO__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReadIO htmlCtxtReadIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReadMemory
+extern __typeof (htmlCtxtReadMemory) htmlCtxtReadMemory __attribute((alias("htmlCtxtReadMemory__internal_alias")));
+#else
+#ifndef htmlCtxtReadMemory
+extern __typeof (htmlCtxtReadMemory) htmlCtxtReadMemory__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReadMemory htmlCtxtReadMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtReset
+extern __typeof (htmlCtxtReset) htmlCtxtReset __attribute((alias("htmlCtxtReset__internal_alias")));
+#else
+#ifndef htmlCtxtReset
+extern __typeof (htmlCtxtReset) htmlCtxtReset__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtReset htmlCtxtReset__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlCtxtUseOptions
+extern __typeof (htmlCtxtUseOptions) htmlCtxtUseOptions __attribute((alias("htmlCtxtUseOptions__internal_alias")));
+#else
+#ifndef htmlCtxtUseOptions
+extern __typeof (htmlCtxtUseOptions) htmlCtxtUseOptions__internal_alias __attribute((visibility("hidden")));
+#define htmlCtxtUseOptions htmlCtxtUseOptions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_SAX2
+#undef htmlDefaultSAXHandlerInit
+extern __typeof (htmlDefaultSAXHandlerInit) htmlDefaultSAXHandlerInit __attribute((alias("htmlDefaultSAXHandlerInit__internal_alias")));
+#else
+#ifndef htmlDefaultSAXHandlerInit
+extern __typeof (htmlDefaultSAXHandlerInit) htmlDefaultSAXHandlerInit__internal_alias __attribute((visibility("hidden")));
+#define htmlDefaultSAXHandlerInit htmlDefaultSAXHandlerInit__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlDocContentDumpFormatOutput
+extern __typeof (htmlDocContentDumpFormatOutput) htmlDocContentDumpFormatOutput __attribute((alias("htmlDocContentDumpFormatOutput__internal_alias")));
+#else
+#ifndef htmlDocContentDumpFormatOutput
+extern __typeof (htmlDocContentDumpFormatOutput) htmlDocContentDumpFormatOutput__internal_alias __attribute((visibility("hidden")));
+#define htmlDocContentDumpFormatOutput htmlDocContentDumpFormatOutput__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlDocContentDumpOutput
+extern __typeof (htmlDocContentDumpOutput) htmlDocContentDumpOutput __attribute((alias("htmlDocContentDumpOutput__internal_alias")));
+#else
+#ifndef htmlDocContentDumpOutput
+extern __typeof (htmlDocContentDumpOutput) htmlDocContentDumpOutput__internal_alias __attribute((visibility("hidden")));
+#define htmlDocContentDumpOutput htmlDocContentDumpOutput__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlDocDump
+extern __typeof (htmlDocDump) htmlDocDump __attribute((alias("htmlDocDump__internal_alias")));
+#else
+#ifndef htmlDocDump
+extern __typeof (htmlDocDump) htmlDocDump__internal_alias __attribute((visibility("hidden")));
+#define htmlDocDump htmlDocDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlDocDumpMemory
+extern __typeof (htmlDocDumpMemory) htmlDocDumpMemory __attribute((alias("htmlDocDumpMemory__internal_alias")));
+#else
+#ifndef htmlDocDumpMemory
+extern __typeof (htmlDocDumpMemory) htmlDocDumpMemory__internal_alias __attribute((visibility("hidden")));
+#define htmlDocDumpMemory htmlDocDumpMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlDocDumpMemoryFormat
+extern __typeof (htmlDocDumpMemoryFormat) htmlDocDumpMemoryFormat __attribute((alias("htmlDocDumpMemoryFormat__internal_alias")));
+#else
+#ifndef htmlDocDumpMemoryFormat
+extern __typeof (htmlDocDumpMemoryFormat) htmlDocDumpMemoryFormat__internal_alias __attribute((visibility("hidden")));
+#define htmlDocDumpMemoryFormat htmlDocDumpMemoryFormat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlElementAllowedHere
+extern __typeof (htmlElementAllowedHere) htmlElementAllowedHere __attribute((alias("htmlElementAllowedHere__internal_alias")));
+#else
+#ifndef htmlElementAllowedHere
+extern __typeof (htmlElementAllowedHere) htmlElementAllowedHere__internal_alias __attribute((visibility("hidden")));
+#define htmlElementAllowedHere htmlElementAllowedHere__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlElementStatusHere
+extern __typeof (htmlElementStatusHere) htmlElementStatusHere __attribute((alias("htmlElementStatusHere__internal_alias")));
+#else
+#ifndef htmlElementStatusHere
+extern __typeof (htmlElementStatusHere) htmlElementStatusHere__internal_alias __attribute((visibility("hidden")));
+#define htmlElementStatusHere htmlElementStatusHere__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlEncodeEntities
+extern __typeof (htmlEncodeEntities) htmlEncodeEntities __attribute((alias("htmlEncodeEntities__internal_alias")));
+#else
+#ifndef htmlEncodeEntities
+extern __typeof (htmlEncodeEntities) htmlEncodeEntities__internal_alias __attribute((visibility("hidden")));
+#define htmlEncodeEntities htmlEncodeEntities__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlEntityLookup
+extern __typeof (htmlEntityLookup) htmlEntityLookup __attribute((alias("htmlEntityLookup__internal_alias")));
+#else
+#ifndef htmlEntityLookup
+extern __typeof (htmlEntityLookup) htmlEntityLookup__internal_alias __attribute((visibility("hidden")));
+#define htmlEntityLookup htmlEntityLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlEntityValueLookup
+extern __typeof (htmlEntityValueLookup) htmlEntityValueLookup __attribute((alias("htmlEntityValueLookup__internal_alias")));
+#else
+#ifndef htmlEntityValueLookup
+extern __typeof (htmlEntityValueLookup) htmlEntityValueLookup__internal_alias __attribute((visibility("hidden")));
+#define htmlEntityValueLookup htmlEntityValueLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlFreeParserCtxt
+extern __typeof (htmlFreeParserCtxt) htmlFreeParserCtxt __attribute((alias("htmlFreeParserCtxt__internal_alias")));
+#else
+#ifndef htmlFreeParserCtxt
+extern __typeof (htmlFreeParserCtxt) htmlFreeParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define htmlFreeParserCtxt htmlFreeParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlGetMetaEncoding
+extern __typeof (htmlGetMetaEncoding) htmlGetMetaEncoding __attribute((alias("htmlGetMetaEncoding__internal_alias")));
+#else
+#ifndef htmlGetMetaEncoding
+extern __typeof (htmlGetMetaEncoding) htmlGetMetaEncoding__internal_alias __attribute((visibility("hidden")));
+#define htmlGetMetaEncoding htmlGetMetaEncoding__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlHandleOmittedElem
+extern __typeof (htmlHandleOmittedElem) htmlHandleOmittedElem __attribute((alias("htmlHandleOmittedElem__internal_alias")));
+#else
+#ifndef htmlHandleOmittedElem
+extern __typeof (htmlHandleOmittedElem) htmlHandleOmittedElem__internal_alias __attribute((visibility("hidden")));
+#define htmlHandleOmittedElem htmlHandleOmittedElem__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlInitAutoClose
+extern __typeof (htmlInitAutoClose) htmlInitAutoClose __attribute((alias("htmlInitAutoClose__internal_alias")));
+#else
+#ifndef htmlInitAutoClose
+extern __typeof (htmlInitAutoClose) htmlInitAutoClose__internal_alias __attribute((visibility("hidden")));
+#define htmlInitAutoClose htmlInitAutoClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlIsAutoClosed
+extern __typeof (htmlIsAutoClosed) htmlIsAutoClosed __attribute((alias("htmlIsAutoClosed__internal_alias")));
+#else
+#ifndef htmlIsAutoClosed
+extern __typeof (htmlIsAutoClosed) htmlIsAutoClosed__internal_alias __attribute((visibility("hidden")));
+#define htmlIsAutoClosed htmlIsAutoClosed__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlIsBooleanAttr
+extern __typeof (htmlIsBooleanAttr) htmlIsBooleanAttr __attribute((alias("htmlIsBooleanAttr__internal_alias")));
+#else
+#ifndef htmlIsBooleanAttr
+extern __typeof (htmlIsBooleanAttr) htmlIsBooleanAttr__internal_alias __attribute((visibility("hidden")));
+#define htmlIsBooleanAttr htmlIsBooleanAttr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlIsScriptAttribute
+extern __typeof (htmlIsScriptAttribute) htmlIsScriptAttribute __attribute((alias("htmlIsScriptAttribute__internal_alias")));
+#else
+#ifndef htmlIsScriptAttribute
+extern __typeof (htmlIsScriptAttribute) htmlIsScriptAttribute__internal_alias __attribute((visibility("hidden")));
+#define htmlIsScriptAttribute htmlIsScriptAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlNewDoc
+extern __typeof (htmlNewDoc) htmlNewDoc __attribute((alias("htmlNewDoc__internal_alias")));
+#else
+#ifndef htmlNewDoc
+extern __typeof (htmlNewDoc) htmlNewDoc__internal_alias __attribute((visibility("hidden")));
+#define htmlNewDoc htmlNewDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlNewDocNoDtD
+extern __typeof (htmlNewDocNoDtD) htmlNewDocNoDtD __attribute((alias("htmlNewDocNoDtD__internal_alias")));
+#else
+#ifndef htmlNewDocNoDtD
+extern __typeof (htmlNewDocNoDtD) htmlNewDocNoDtD__internal_alias __attribute((visibility("hidden")));
+#define htmlNewDocNoDtD htmlNewDocNoDtD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlNewParserCtxt
+extern __typeof (htmlNewParserCtxt) htmlNewParserCtxt __attribute((alias("htmlNewParserCtxt__internal_alias")));
+#else
+#ifndef htmlNewParserCtxt
+extern __typeof (htmlNewParserCtxt) htmlNewParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define htmlNewParserCtxt htmlNewParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlNodeDump
+extern __typeof (htmlNodeDump) htmlNodeDump __attribute((alias("htmlNodeDump__internal_alias")));
+#else
+#ifndef htmlNodeDump
+extern __typeof (htmlNodeDump) htmlNodeDump__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeDump htmlNodeDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlNodeDumpFile
+extern __typeof (htmlNodeDumpFile) htmlNodeDumpFile __attribute((alias("htmlNodeDumpFile__internal_alias")));
+#else
+#ifndef htmlNodeDumpFile
+extern __typeof (htmlNodeDumpFile) htmlNodeDumpFile__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeDumpFile htmlNodeDumpFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlNodeDumpFileFormat
+extern __typeof (htmlNodeDumpFileFormat) htmlNodeDumpFileFormat __attribute((alias("htmlNodeDumpFileFormat__internal_alias")));
+#else
+#ifndef htmlNodeDumpFileFormat
+extern __typeof (htmlNodeDumpFileFormat) htmlNodeDumpFileFormat__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeDumpFileFormat htmlNodeDumpFileFormat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlNodeDumpFormatOutput
+extern __typeof (htmlNodeDumpFormatOutput) htmlNodeDumpFormatOutput __attribute((alias("htmlNodeDumpFormatOutput__internal_alias")));
+#else
+#ifndef htmlNodeDumpFormatOutput
+extern __typeof (htmlNodeDumpFormatOutput) htmlNodeDumpFormatOutput__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeDumpFormatOutput htmlNodeDumpFormatOutput__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlNodeDumpOutput
+extern __typeof (htmlNodeDumpOutput) htmlNodeDumpOutput __attribute((alias("htmlNodeDumpOutput__internal_alias")));
+#else
+#ifndef htmlNodeDumpOutput
+extern __typeof (htmlNodeDumpOutput) htmlNodeDumpOutput__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeDumpOutput htmlNodeDumpOutput__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlNodeStatus
+extern __typeof (htmlNodeStatus) htmlNodeStatus __attribute((alias("htmlNodeStatus__internal_alias")));
+#else
+#ifndef htmlNodeStatus
+extern __typeof (htmlNodeStatus) htmlNodeStatus__internal_alias __attribute((visibility("hidden")));
+#define htmlNodeStatus htmlNodeStatus__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseCharRef
+extern __typeof (htmlParseCharRef) htmlParseCharRef __attribute((alias("htmlParseCharRef__internal_alias")));
+#else
+#ifndef htmlParseCharRef
+extern __typeof (htmlParseCharRef) htmlParseCharRef__internal_alias __attribute((visibility("hidden")));
+#define htmlParseCharRef htmlParseCharRef__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseChunk
+extern __typeof (htmlParseChunk) htmlParseChunk __attribute((alias("htmlParseChunk__internal_alias")));
+#else
+#ifndef htmlParseChunk
+extern __typeof (htmlParseChunk) htmlParseChunk__internal_alias __attribute((visibility("hidden")));
+#define htmlParseChunk htmlParseChunk__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseDoc
+extern __typeof (htmlParseDoc) htmlParseDoc __attribute((alias("htmlParseDoc__internal_alias")));
+#else
+#ifndef htmlParseDoc
+extern __typeof (htmlParseDoc) htmlParseDoc__internal_alias __attribute((visibility("hidden")));
+#define htmlParseDoc htmlParseDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseDocument
+extern __typeof (htmlParseDocument) htmlParseDocument __attribute((alias("htmlParseDocument__internal_alias")));
+#else
+#ifndef htmlParseDocument
+extern __typeof (htmlParseDocument) htmlParseDocument__internal_alias __attribute((visibility("hidden")));
+#define htmlParseDocument htmlParseDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseElement
+extern __typeof (htmlParseElement) htmlParseElement __attribute((alias("htmlParseElement__internal_alias")));
+#else
+#ifndef htmlParseElement
+extern __typeof (htmlParseElement) htmlParseElement__internal_alias __attribute((visibility("hidden")));
+#define htmlParseElement htmlParseElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseEntityRef
+extern __typeof (htmlParseEntityRef) htmlParseEntityRef __attribute((alias("htmlParseEntityRef__internal_alias")));
+#else
+#ifndef htmlParseEntityRef
+extern __typeof (htmlParseEntityRef) htmlParseEntityRef__internal_alias __attribute((visibility("hidden")));
+#define htmlParseEntityRef htmlParseEntityRef__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlParseFile
+extern __typeof (htmlParseFile) htmlParseFile __attribute((alias("htmlParseFile__internal_alias")));
+#else
+#ifndef htmlParseFile
+extern __typeof (htmlParseFile) htmlParseFile__internal_alias __attribute((visibility("hidden")));
+#define htmlParseFile htmlParseFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlReadDoc
+extern __typeof (htmlReadDoc) htmlReadDoc __attribute((alias("htmlReadDoc__internal_alias")));
+#else
+#ifndef htmlReadDoc
+extern __typeof (htmlReadDoc) htmlReadDoc__internal_alias __attribute((visibility("hidden")));
+#define htmlReadDoc htmlReadDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlReadFd
+extern __typeof (htmlReadFd) htmlReadFd __attribute((alias("htmlReadFd__internal_alias")));
+#else
+#ifndef htmlReadFd
+extern __typeof (htmlReadFd) htmlReadFd__internal_alias __attribute((visibility("hidden")));
+#define htmlReadFd htmlReadFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlReadFile
+extern __typeof (htmlReadFile) htmlReadFile __attribute((alias("htmlReadFile__internal_alias")));
+#else
+#ifndef htmlReadFile
+extern __typeof (htmlReadFile) htmlReadFile__internal_alias __attribute((visibility("hidden")));
+#define htmlReadFile htmlReadFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlReadIO
+extern __typeof (htmlReadIO) htmlReadIO __attribute((alias("htmlReadIO__internal_alias")));
+#else
+#ifndef htmlReadIO
+extern __typeof (htmlReadIO) htmlReadIO__internal_alias __attribute((visibility("hidden")));
+#define htmlReadIO htmlReadIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlReadMemory
+extern __typeof (htmlReadMemory) htmlReadMemory __attribute((alias("htmlReadMemory__internal_alias")));
+#else
+#ifndef htmlReadMemory
+extern __typeof (htmlReadMemory) htmlReadMemory__internal_alias __attribute((visibility("hidden")));
+#define htmlReadMemory htmlReadMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlSAXParseDoc
+extern __typeof (htmlSAXParseDoc) htmlSAXParseDoc __attribute((alias("htmlSAXParseDoc__internal_alias")));
+#else
+#ifndef htmlSAXParseDoc
+extern __typeof (htmlSAXParseDoc) htmlSAXParseDoc__internal_alias __attribute((visibility("hidden")));
+#define htmlSAXParseDoc htmlSAXParseDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlSAXParseFile
+extern __typeof (htmlSAXParseFile) htmlSAXParseFile __attribute((alias("htmlSAXParseFile__internal_alias")));
+#else
+#ifndef htmlSAXParseFile
+extern __typeof (htmlSAXParseFile) htmlSAXParseFile__internal_alias __attribute((visibility("hidden")));
+#define htmlSAXParseFile htmlSAXParseFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlSaveFile
+extern __typeof (htmlSaveFile) htmlSaveFile __attribute((alias("htmlSaveFile__internal_alias")));
+#else
+#ifndef htmlSaveFile
+extern __typeof (htmlSaveFile) htmlSaveFile__internal_alias __attribute((visibility("hidden")));
+#define htmlSaveFile htmlSaveFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlSaveFileEnc
+extern __typeof (htmlSaveFileEnc) htmlSaveFileEnc __attribute((alias("htmlSaveFileEnc__internal_alias")));
+#else
+#ifndef htmlSaveFileEnc
+extern __typeof (htmlSaveFileEnc) htmlSaveFileEnc__internal_alias __attribute((visibility("hidden")));
+#define htmlSaveFileEnc htmlSaveFileEnc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlSaveFileFormat
+extern __typeof (htmlSaveFileFormat) htmlSaveFileFormat __attribute((alias("htmlSaveFileFormat__internal_alias")));
+#else
+#ifndef htmlSaveFileFormat
+extern __typeof (htmlSaveFileFormat) htmlSaveFileFormat__internal_alias __attribute((visibility("hidden")));
+#define htmlSaveFileFormat htmlSaveFileFormat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLtree
+#undef htmlSetMetaEncoding
+extern __typeof (htmlSetMetaEncoding) htmlSetMetaEncoding __attribute((alias("htmlSetMetaEncoding__internal_alias")));
+#else
+#ifndef htmlSetMetaEncoding
+extern __typeof (htmlSetMetaEncoding) htmlSetMetaEncoding__internal_alias __attribute((visibility("hidden")));
+#define htmlSetMetaEncoding htmlSetMetaEncoding__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_HTMLparser
+#undef htmlTagLookup
+extern __typeof (htmlTagLookup) htmlTagLookup __attribute((alias("htmlTagLookup__internal_alias")));
+#else
+#ifndef htmlTagLookup
+extern __typeof (htmlTagLookup) htmlTagLookup__internal_alias __attribute((visibility("hidden")));
+#define htmlTagLookup htmlTagLookup__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef inputPop
+extern __typeof (inputPop) inputPop __attribute((alias("inputPop__internal_alias")));
+#else
+#ifndef inputPop
+extern __typeof (inputPop) inputPop__internal_alias __attribute((visibility("hidden")));
+#define inputPop inputPop__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef inputPush
+extern __typeof (inputPush) inputPush __attribute((alias("inputPush__internal_alias")));
+#else
+#ifndef inputPush
+extern __typeof (inputPush) inputPush__internal_alias __attribute((visibility("hidden")));
+#define inputPush inputPush__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef namePop
+extern __typeof (namePop) namePop __attribute((alias("namePop__internal_alias")));
+#else
+#ifndef namePop
+extern __typeof (namePop) namePop__internal_alias __attribute((visibility("hidden")));
+#define namePop namePop__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef namePush
+extern __typeof (namePush) namePush __attribute((alias("namePush__internal_alias")));
+#else
+#ifndef namePush
+extern __typeof (namePush) namePush__internal_alias __attribute((visibility("hidden")));
+#define namePush namePush__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef nodePop
+extern __typeof (nodePop) nodePop __attribute((alias("nodePop__internal_alias")));
+#else
+#ifndef nodePop
+extern __typeof (nodePop) nodePop__internal_alias __attribute((visibility("hidden")));
+#define nodePop nodePop__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef nodePush
+extern __typeof (nodePush) nodePush __attribute((alias("nodePush__internal_alias")));
+#else
+#ifndef nodePush
+extern __typeof (nodePush) nodePush__internal_alias __attribute((visibility("hidden")));
+#define nodePush nodePush__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef valuePop
+extern __typeof (valuePop) valuePop __attribute((alias("valuePop__internal_alias")));
+#else
+#ifndef valuePop
+extern __typeof (valuePop) valuePop__internal_alias __attribute((visibility("hidden")));
+#define valuePop valuePop__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef valuePush
+extern __typeof (valuePush) valuePush __attribute((alias("valuePush__internal_alias")));
+#else
+#ifndef valuePush
+extern __typeof (valuePush) valuePush__internal_alias __attribute((visibility("hidden")));
+#define valuePush valuePush__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogAdd
+extern __typeof (xmlACatalogAdd) xmlACatalogAdd __attribute((alias("xmlACatalogAdd__internal_alias")));
+#else
+#ifndef xmlACatalogAdd
+extern __typeof (xmlACatalogAdd) xmlACatalogAdd__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogAdd xmlACatalogAdd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogDump
+extern __typeof (xmlACatalogDump) xmlACatalogDump __attribute((alias("xmlACatalogDump__internal_alias")));
+#else
+#ifndef xmlACatalogDump
+extern __typeof (xmlACatalogDump) xmlACatalogDump__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogDump xmlACatalogDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogRemove
+extern __typeof (xmlACatalogRemove) xmlACatalogRemove __attribute((alias("xmlACatalogRemove__internal_alias")));
+#else
+#ifndef xmlACatalogRemove
+extern __typeof (xmlACatalogRemove) xmlACatalogRemove__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogRemove xmlACatalogRemove__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogResolve
+extern __typeof (xmlACatalogResolve) xmlACatalogResolve __attribute((alias("xmlACatalogResolve__internal_alias")));
+#else
+#ifndef xmlACatalogResolve
+extern __typeof (xmlACatalogResolve) xmlACatalogResolve__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogResolve xmlACatalogResolve__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogResolvePublic
+extern __typeof (xmlACatalogResolvePublic) xmlACatalogResolvePublic __attribute((alias("xmlACatalogResolvePublic__internal_alias")));
+#else
+#ifndef xmlACatalogResolvePublic
+extern __typeof (xmlACatalogResolvePublic) xmlACatalogResolvePublic__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogResolvePublic xmlACatalogResolvePublic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogResolveSystem
+extern __typeof (xmlACatalogResolveSystem) xmlACatalogResolveSystem __attribute((alias("xmlACatalogResolveSystem__internal_alias")));
+#else
+#ifndef xmlACatalogResolveSystem
+extern __typeof (xmlACatalogResolveSystem) xmlACatalogResolveSystem__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogResolveSystem xmlACatalogResolveSystem__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlACatalogResolveURI
+extern __typeof (xmlACatalogResolveURI) xmlACatalogResolveURI __attribute((alias("xmlACatalogResolveURI__internal_alias")));
+#else
+#ifndef xmlACatalogResolveURI
+extern __typeof (xmlACatalogResolveURI) xmlACatalogResolveURI__internal_alias __attribute((visibility("hidden")));
+#define xmlACatalogResolveURI xmlACatalogResolveURI__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlAddAttributeDecl
+extern __typeof (xmlAddAttributeDecl) xmlAddAttributeDecl __attribute((alias("xmlAddAttributeDecl__internal_alias")));
+#else
+#ifndef xmlAddAttributeDecl
+extern __typeof (xmlAddAttributeDecl) xmlAddAttributeDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlAddAttributeDecl xmlAddAttributeDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlAddChild
+extern __typeof (xmlAddChild) xmlAddChild __attribute((alias("xmlAddChild__internal_alias")));
+#else
+#ifndef xmlAddChild
+extern __typeof (xmlAddChild) xmlAddChild__internal_alias __attribute((visibility("hidden")));
+#define xmlAddChild xmlAddChild__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlAddChildList
+extern __typeof (xmlAddChildList) xmlAddChildList __attribute((alias("xmlAddChildList__internal_alias")));
+#else
+#ifndef xmlAddChildList
+extern __typeof (xmlAddChildList) xmlAddChildList__internal_alias __attribute((visibility("hidden")));
+#define xmlAddChildList xmlAddChildList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlAddDocEntity
+extern __typeof (xmlAddDocEntity) xmlAddDocEntity __attribute((alias("xmlAddDocEntity__internal_alias")));
+#else
+#ifndef xmlAddDocEntity
+extern __typeof (xmlAddDocEntity) xmlAddDocEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlAddDocEntity xmlAddDocEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlAddDtdEntity
+extern __typeof (xmlAddDtdEntity) xmlAddDtdEntity __attribute((alias("xmlAddDtdEntity__internal_alias")));
+#else
+#ifndef xmlAddDtdEntity
+extern __typeof (xmlAddDtdEntity) xmlAddDtdEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlAddDtdEntity xmlAddDtdEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlAddElementDecl
+extern __typeof (xmlAddElementDecl) xmlAddElementDecl __attribute((alias("xmlAddElementDecl__internal_alias")));
+#else
+#ifndef xmlAddElementDecl
+extern __typeof (xmlAddElementDecl) xmlAddElementDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlAddElementDecl xmlAddElementDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlAddEncodingAlias
+extern __typeof (xmlAddEncodingAlias) xmlAddEncodingAlias __attribute((alias("xmlAddEncodingAlias__internal_alias")));
+#else
+#ifndef xmlAddEncodingAlias
+extern __typeof (xmlAddEncodingAlias) xmlAddEncodingAlias__internal_alias __attribute((visibility("hidden")));
+#define xmlAddEncodingAlias xmlAddEncodingAlias__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlAddID
+extern __typeof (xmlAddID) xmlAddID __attribute((alias("xmlAddID__internal_alias")));
+#else
+#ifndef xmlAddID
+extern __typeof (xmlAddID) xmlAddID__internal_alias __attribute((visibility("hidden")));
+#define xmlAddID xmlAddID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlAddNextSibling
+extern __typeof (xmlAddNextSibling) xmlAddNextSibling __attribute((alias("xmlAddNextSibling__internal_alias")));
+#else
+#ifndef xmlAddNextSibling
+extern __typeof (xmlAddNextSibling) xmlAddNextSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlAddNextSibling xmlAddNextSibling__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlAddNotationDecl
+extern __typeof (xmlAddNotationDecl) xmlAddNotationDecl __attribute((alias("xmlAddNotationDecl__internal_alias")));
+#else
+#ifndef xmlAddNotationDecl
+extern __typeof (xmlAddNotationDecl) xmlAddNotationDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlAddNotationDecl xmlAddNotationDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlAddPrevSibling
+extern __typeof (xmlAddPrevSibling) xmlAddPrevSibling __attribute((alias("xmlAddPrevSibling__internal_alias")));
+#else
+#ifndef xmlAddPrevSibling
+extern __typeof (xmlAddPrevSibling) xmlAddPrevSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlAddPrevSibling xmlAddPrevSibling__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlAddRef
+extern __typeof (xmlAddRef) xmlAddRef __attribute((alias("xmlAddRef__internal_alias")));
+#else
+#ifndef xmlAddRef
+extern __typeof (xmlAddRef) xmlAddRef__internal_alias __attribute((visibility("hidden")));
+#define xmlAddRef xmlAddRef__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlAddSibling
+extern __typeof (xmlAddSibling) xmlAddSibling __attribute((alias("xmlAddSibling__internal_alias")));
+#else
+#ifndef xmlAddSibling
+extern __typeof (xmlAddSibling) xmlAddSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlAddSibling xmlAddSibling__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlAllocOutputBuffer
+extern __typeof (xmlAllocOutputBuffer) xmlAllocOutputBuffer __attribute((alias("xmlAllocOutputBuffer__internal_alias")));
+#else
+#ifndef xmlAllocOutputBuffer
+extern __typeof (xmlAllocOutputBuffer) xmlAllocOutputBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlAllocOutputBuffer xmlAllocOutputBuffer__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlAllocParserInputBuffer
+extern __typeof (xmlAllocParserInputBuffer) xmlAllocParserInputBuffer __attribute((alias("xmlAllocParserInputBuffer__internal_alias")));
+#else
+#ifndef xmlAllocParserInputBuffer
+extern __typeof (xmlAllocParserInputBuffer) xmlAllocParserInputBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlAllocParserInputBuffer xmlAllocParserInputBuffer__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlAttrSerializeTxtContent
+extern __typeof (xmlAttrSerializeTxtContent) xmlAttrSerializeTxtContent __attribute((alias("xmlAttrSerializeTxtContent__internal_alias")));
+#else
+#ifndef xmlAttrSerializeTxtContent
+extern __typeof (xmlAttrSerializeTxtContent) xmlAttrSerializeTxtContent__internal_alias __attribute((visibility("hidden")));
+#define xmlAttrSerializeTxtContent xmlAttrSerializeTxtContent__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataCompile
+extern __typeof (xmlAutomataCompile) xmlAutomataCompile __attribute((alias("xmlAutomataCompile__internal_alias")));
+#else
+#ifndef xmlAutomataCompile
+extern __typeof (xmlAutomataCompile) xmlAutomataCompile__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataCompile xmlAutomataCompile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataGetInitState
+extern __typeof (xmlAutomataGetInitState) xmlAutomataGetInitState __attribute((alias("xmlAutomataGetInitState__internal_alias")));
+#else
+#ifndef xmlAutomataGetInitState
+extern __typeof (xmlAutomataGetInitState) xmlAutomataGetInitState__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataGetInitState xmlAutomataGetInitState__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataIsDeterminist
+extern __typeof (xmlAutomataIsDeterminist) xmlAutomataIsDeterminist __attribute((alias("xmlAutomataIsDeterminist__internal_alias")));
+#else
+#ifndef xmlAutomataIsDeterminist
+extern __typeof (xmlAutomataIsDeterminist) xmlAutomataIsDeterminist__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataIsDeterminist xmlAutomataIsDeterminist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewAllTrans
+extern __typeof (xmlAutomataNewAllTrans) xmlAutomataNewAllTrans __attribute((alias("xmlAutomataNewAllTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewAllTrans
+extern __typeof (xmlAutomataNewAllTrans) xmlAutomataNewAllTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewAllTrans xmlAutomataNewAllTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewCountTrans
+extern __typeof (xmlAutomataNewCountTrans) xmlAutomataNewCountTrans __attribute((alias("xmlAutomataNewCountTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewCountTrans
+extern __typeof (xmlAutomataNewCountTrans) xmlAutomataNewCountTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewCountTrans xmlAutomataNewCountTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewCountTrans2
+extern __typeof (xmlAutomataNewCountTrans2) xmlAutomataNewCountTrans2 __attribute((alias("xmlAutomataNewCountTrans2__internal_alias")));
+#else
+#ifndef xmlAutomataNewCountTrans2
+extern __typeof (xmlAutomataNewCountTrans2) xmlAutomataNewCountTrans2__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewCountTrans2 xmlAutomataNewCountTrans2__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewCountedTrans
+extern __typeof (xmlAutomataNewCountedTrans) xmlAutomataNewCountedTrans __attribute((alias("xmlAutomataNewCountedTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewCountedTrans
+extern __typeof (xmlAutomataNewCountedTrans) xmlAutomataNewCountedTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewCountedTrans xmlAutomataNewCountedTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewCounter
+extern __typeof (xmlAutomataNewCounter) xmlAutomataNewCounter __attribute((alias("xmlAutomataNewCounter__internal_alias")));
+#else
+#ifndef xmlAutomataNewCounter
+extern __typeof (xmlAutomataNewCounter) xmlAutomataNewCounter__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewCounter xmlAutomataNewCounter__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewCounterTrans
+extern __typeof (xmlAutomataNewCounterTrans) xmlAutomataNewCounterTrans __attribute((alias("xmlAutomataNewCounterTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewCounterTrans
+extern __typeof (xmlAutomataNewCounterTrans) xmlAutomataNewCounterTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewCounterTrans xmlAutomataNewCounterTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewEpsilon
+extern __typeof (xmlAutomataNewEpsilon) xmlAutomataNewEpsilon __attribute((alias("xmlAutomataNewEpsilon__internal_alias")));
+#else
+#ifndef xmlAutomataNewEpsilon
+extern __typeof (xmlAutomataNewEpsilon) xmlAutomataNewEpsilon__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewEpsilon xmlAutomataNewEpsilon__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewNegTrans
+extern __typeof (xmlAutomataNewNegTrans) xmlAutomataNewNegTrans __attribute((alias("xmlAutomataNewNegTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewNegTrans
+extern __typeof (xmlAutomataNewNegTrans) xmlAutomataNewNegTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewNegTrans xmlAutomataNewNegTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewOnceTrans
+extern __typeof (xmlAutomataNewOnceTrans) xmlAutomataNewOnceTrans __attribute((alias("xmlAutomataNewOnceTrans__internal_alias")));
+#else
+#ifndef xmlAutomataNewOnceTrans
+extern __typeof (xmlAutomataNewOnceTrans) xmlAutomataNewOnceTrans__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewOnceTrans xmlAutomataNewOnceTrans__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewOnceTrans2
+extern __typeof (xmlAutomataNewOnceTrans2) xmlAutomataNewOnceTrans2 __attribute((alias("xmlAutomataNewOnceTrans2__internal_alias")));
+#else
+#ifndef xmlAutomataNewOnceTrans2
+extern __typeof (xmlAutomataNewOnceTrans2) xmlAutomataNewOnceTrans2__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewOnceTrans2 xmlAutomataNewOnceTrans2__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewState
+extern __typeof (xmlAutomataNewState) xmlAutomataNewState __attribute((alias("xmlAutomataNewState__internal_alias")));
+#else
+#ifndef xmlAutomataNewState
+extern __typeof (xmlAutomataNewState) xmlAutomataNewState__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewState xmlAutomataNewState__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewTransition
+extern __typeof (xmlAutomataNewTransition) xmlAutomataNewTransition __attribute((alias("xmlAutomataNewTransition__internal_alias")));
+#else
+#ifndef xmlAutomataNewTransition
+extern __typeof (xmlAutomataNewTransition) xmlAutomataNewTransition__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewTransition xmlAutomataNewTransition__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataNewTransition2
+extern __typeof (xmlAutomataNewTransition2) xmlAutomataNewTransition2 __attribute((alias("xmlAutomataNewTransition2__internal_alias")));
+#else
+#ifndef xmlAutomataNewTransition2
+extern __typeof (xmlAutomataNewTransition2) xmlAutomataNewTransition2__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataNewTransition2 xmlAutomataNewTransition2__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlAutomataSetFinalState
+extern __typeof (xmlAutomataSetFinalState) xmlAutomataSetFinalState __attribute((alias("xmlAutomataSetFinalState__internal_alias")));
+#else
+#ifndef xmlAutomataSetFinalState
+extern __typeof (xmlAutomataSetFinalState) xmlAutomataSetFinalState__internal_alias __attribute((visibility("hidden")));
+#define xmlAutomataSetFinalState xmlAutomataSetFinalState__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlBoolToText
+extern __typeof (xmlBoolToText) xmlBoolToText __attribute((alias("xmlBoolToText__internal_alias")));
+#else
+#ifndef xmlBoolToText
+extern __typeof (xmlBoolToText) xmlBoolToText__internal_alias __attribute((visibility("hidden")));
+#define xmlBoolToText xmlBoolToText__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferAdd
+extern __typeof (xmlBufferAdd) xmlBufferAdd __attribute((alias("xmlBufferAdd__internal_alias")));
+#else
+#ifndef xmlBufferAdd
+extern __typeof (xmlBufferAdd) xmlBufferAdd__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferAdd xmlBufferAdd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferAddHead
+extern __typeof (xmlBufferAddHead) xmlBufferAddHead __attribute((alias("xmlBufferAddHead__internal_alias")));
+#else
+#ifndef xmlBufferAddHead
+extern __typeof (xmlBufferAddHead) xmlBufferAddHead__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferAddHead xmlBufferAddHead__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferCCat
+extern __typeof (xmlBufferCCat) xmlBufferCCat __attribute((alias("xmlBufferCCat__internal_alias")));
+#else
+#ifndef xmlBufferCCat
+extern __typeof (xmlBufferCCat) xmlBufferCCat__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferCCat xmlBufferCCat__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferCat
+extern __typeof (xmlBufferCat) xmlBufferCat __attribute((alias("xmlBufferCat__internal_alias")));
+#else
+#ifndef xmlBufferCat
+extern __typeof (xmlBufferCat) xmlBufferCat__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferCat xmlBufferCat__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferContent
+extern __typeof (xmlBufferContent) xmlBufferContent __attribute((alias("xmlBufferContent__internal_alias")));
+#else
+#ifndef xmlBufferContent
+extern __typeof (xmlBufferContent) xmlBufferContent__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferContent xmlBufferContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferCreate
+extern __typeof (xmlBufferCreate) xmlBufferCreate __attribute((alias("xmlBufferCreate__internal_alias")));
+#else
+#ifndef xmlBufferCreate
+extern __typeof (xmlBufferCreate) xmlBufferCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferCreate xmlBufferCreate__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferCreateSize
+extern __typeof (xmlBufferCreateSize) xmlBufferCreateSize __attribute((alias("xmlBufferCreateSize__internal_alias")));
+#else
+#ifndef xmlBufferCreateSize
+extern __typeof (xmlBufferCreateSize) xmlBufferCreateSize__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferCreateSize xmlBufferCreateSize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferCreateStatic
+extern __typeof (xmlBufferCreateStatic) xmlBufferCreateStatic __attribute((alias("xmlBufferCreateStatic__internal_alias")));
+#else
+#ifndef xmlBufferCreateStatic
+extern __typeof (xmlBufferCreateStatic) xmlBufferCreateStatic__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferCreateStatic xmlBufferCreateStatic__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferDump
+extern __typeof (xmlBufferDump) xmlBufferDump __attribute((alias("xmlBufferDump__internal_alias")));
+#else
+#ifndef xmlBufferDump
+extern __typeof (xmlBufferDump) xmlBufferDump__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferDump xmlBufferDump__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferEmpty
+extern __typeof (xmlBufferEmpty) xmlBufferEmpty __attribute((alias("xmlBufferEmpty__internal_alias")));
+#else
+#ifndef xmlBufferEmpty
+extern __typeof (xmlBufferEmpty) xmlBufferEmpty__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferEmpty xmlBufferEmpty__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferFree
+extern __typeof (xmlBufferFree) xmlBufferFree __attribute((alias("xmlBufferFree__internal_alias")));
+#else
+#ifndef xmlBufferFree
+extern __typeof (xmlBufferFree) xmlBufferFree__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferFree xmlBufferFree__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferGrow
+extern __typeof (xmlBufferGrow) xmlBufferGrow __attribute((alias("xmlBufferGrow__internal_alias")));
+#else
+#ifndef xmlBufferGrow
+extern __typeof (xmlBufferGrow) xmlBufferGrow__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferGrow xmlBufferGrow__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferLength
+extern __typeof (xmlBufferLength) xmlBufferLength __attribute((alias("xmlBufferLength__internal_alias")));
+#else
+#ifndef xmlBufferLength
+extern __typeof (xmlBufferLength) xmlBufferLength__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferLength xmlBufferLength__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferResize
+extern __typeof (xmlBufferResize) xmlBufferResize __attribute((alias("xmlBufferResize__internal_alias")));
+#else
+#ifndef xmlBufferResize
+extern __typeof (xmlBufferResize) xmlBufferResize__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferResize xmlBufferResize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferSetAllocationScheme
+extern __typeof (xmlBufferSetAllocationScheme) xmlBufferSetAllocationScheme __attribute((alias("xmlBufferSetAllocationScheme__internal_alias")));
+#else
+#ifndef xmlBufferSetAllocationScheme
+extern __typeof (xmlBufferSetAllocationScheme) xmlBufferSetAllocationScheme__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferSetAllocationScheme xmlBufferSetAllocationScheme__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferShrink
+extern __typeof (xmlBufferShrink) xmlBufferShrink __attribute((alias("xmlBufferShrink__internal_alias")));
+#else
+#ifndef xmlBufferShrink
+extern __typeof (xmlBufferShrink) xmlBufferShrink__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferShrink xmlBufferShrink__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferWriteCHAR
+extern __typeof (xmlBufferWriteCHAR) xmlBufferWriteCHAR __attribute((alias("xmlBufferWriteCHAR__internal_alias")));
+#else
+#ifndef xmlBufferWriteCHAR
+extern __typeof (xmlBufferWriteCHAR) xmlBufferWriteCHAR__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferWriteCHAR xmlBufferWriteCHAR__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferWriteChar
+extern __typeof (xmlBufferWriteChar) xmlBufferWriteChar __attribute((alias("xmlBufferWriteChar__internal_alias")));
+#else
+#ifndef xmlBufferWriteChar
+extern __typeof (xmlBufferWriteChar) xmlBufferWriteChar__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferWriteChar xmlBufferWriteChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBufferWriteQuotedString
+extern __typeof (xmlBufferWriteQuotedString) xmlBufferWriteQuotedString __attribute((alias("xmlBufferWriteQuotedString__internal_alias")));
+#else
+#ifndef xmlBufferWriteQuotedString
+extern __typeof (xmlBufferWriteQuotedString) xmlBufferWriteQuotedString__internal_alias __attribute((visibility("hidden")));
+#define xmlBufferWriteQuotedString xmlBufferWriteQuotedString__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlBuildQName
+extern __typeof (xmlBuildQName) xmlBuildQName __attribute((alias("xmlBuildQName__internal_alias")));
+#else
+#ifndef xmlBuildQName
+extern __typeof (xmlBuildQName) xmlBuildQName__internal_alias __attribute((visibility("hidden")));
+#define xmlBuildQName xmlBuildQName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlBuildRelativeURI
+extern __typeof (xmlBuildRelativeURI) xmlBuildRelativeURI __attribute((alias("xmlBuildRelativeURI__internal_alias")));
+#else
+#ifndef xmlBuildRelativeURI
+extern __typeof (xmlBuildRelativeURI) xmlBuildRelativeURI__internal_alias __attribute((visibility("hidden")));
+#define xmlBuildRelativeURI xmlBuildRelativeURI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlBuildURI
+extern __typeof (xmlBuildURI) xmlBuildURI __attribute((alias("xmlBuildURI__internal_alias")));
+#else
+#ifndef xmlBuildURI
+extern __typeof (xmlBuildURI) xmlBuildURI__internal_alias __attribute((visibility("hidden")));
+#define xmlBuildURI xmlBuildURI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlByteConsumed
+extern __typeof (xmlByteConsumed) xmlByteConsumed __attribute((alias("xmlByteConsumed__internal_alias")));
+#else
+#ifndef xmlByteConsumed
+extern __typeof (xmlByteConsumed) xmlByteConsumed__internal_alias __attribute((visibility("hidden")));
+#define xmlByteConsumed xmlByteConsumed__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_c14n
+#undef xmlC14NDocDumpMemory
+extern __typeof (xmlC14NDocDumpMemory) xmlC14NDocDumpMemory __attribute((alias("xmlC14NDocDumpMemory__internal_alias")));
+#else
+#ifndef xmlC14NDocDumpMemory
+extern __typeof (xmlC14NDocDumpMemory) xmlC14NDocDumpMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlC14NDocDumpMemory xmlC14NDocDumpMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_c14n
+#undef xmlC14NDocSave
+extern __typeof (xmlC14NDocSave) xmlC14NDocSave __attribute((alias("xmlC14NDocSave__internal_alias")));
+#else
+#ifndef xmlC14NDocSave
+extern __typeof (xmlC14NDocSave) xmlC14NDocSave__internal_alias __attribute((visibility("hidden")));
+#define xmlC14NDocSave xmlC14NDocSave__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_c14n
+#undef xmlC14NDocSaveTo
+extern __typeof (xmlC14NDocSaveTo) xmlC14NDocSaveTo __attribute((alias("xmlC14NDocSaveTo__internal_alias")));
+#else
+#ifndef xmlC14NDocSaveTo
+extern __typeof (xmlC14NDocSaveTo) xmlC14NDocSaveTo__internal_alias __attribute((visibility("hidden")));
+#define xmlC14NDocSaveTo xmlC14NDocSaveTo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_c14n
+#undef xmlC14NExecute
+extern __typeof (xmlC14NExecute) xmlC14NExecute __attribute((alias("xmlC14NExecute__internal_alias")));
+#else
+#ifndef xmlC14NExecute
+extern __typeof (xmlC14NExecute) xmlC14NExecute__internal_alias __attribute((visibility("hidden")));
+#define xmlC14NExecute xmlC14NExecute__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlCanonicPath
+extern __typeof (xmlCanonicPath) xmlCanonicPath __attribute((alias("xmlCanonicPath__internal_alias")));
+#else
+#ifndef xmlCanonicPath
+extern __typeof (xmlCanonicPath) xmlCanonicPath__internal_alias __attribute((visibility("hidden")));
+#define xmlCanonicPath xmlCanonicPath__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogAdd
+extern __typeof (xmlCatalogAdd) xmlCatalogAdd __attribute((alias("xmlCatalogAdd__internal_alias")));
+#else
+#ifndef xmlCatalogAdd
+extern __typeof (xmlCatalogAdd) xmlCatalogAdd__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogAdd xmlCatalogAdd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogAddLocal
+extern __typeof (xmlCatalogAddLocal) xmlCatalogAddLocal __attribute((alias("xmlCatalogAddLocal__internal_alias")));
+#else
+#ifndef xmlCatalogAddLocal
+extern __typeof (xmlCatalogAddLocal) xmlCatalogAddLocal__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogAddLocal xmlCatalogAddLocal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogCleanup
+extern __typeof (xmlCatalogCleanup) xmlCatalogCleanup __attribute((alias("xmlCatalogCleanup__internal_alias")));
+#else
+#ifndef xmlCatalogCleanup
+extern __typeof (xmlCatalogCleanup) xmlCatalogCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogCleanup xmlCatalogCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogConvert
+extern __typeof (xmlCatalogConvert) xmlCatalogConvert __attribute((alias("xmlCatalogConvert__internal_alias")));
+#else
+#ifndef xmlCatalogConvert
+extern __typeof (xmlCatalogConvert) xmlCatalogConvert__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogConvert xmlCatalogConvert__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogDump
+extern __typeof (xmlCatalogDump) xmlCatalogDump __attribute((alias("xmlCatalogDump__internal_alias")));
+#else
+#ifndef xmlCatalogDump
+extern __typeof (xmlCatalogDump) xmlCatalogDump__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogDump xmlCatalogDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogFreeLocal
+extern __typeof (xmlCatalogFreeLocal) xmlCatalogFreeLocal __attribute((alias("xmlCatalogFreeLocal__internal_alias")));
+#else
+#ifndef xmlCatalogFreeLocal
+extern __typeof (xmlCatalogFreeLocal) xmlCatalogFreeLocal__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogFreeLocal xmlCatalogFreeLocal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogGetDefaults
+extern __typeof (xmlCatalogGetDefaults) xmlCatalogGetDefaults __attribute((alias("xmlCatalogGetDefaults__internal_alias")));
+#else
+#ifndef xmlCatalogGetDefaults
+extern __typeof (xmlCatalogGetDefaults) xmlCatalogGetDefaults__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogGetDefaults xmlCatalogGetDefaults__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogGetPublic
+extern __typeof (xmlCatalogGetPublic) xmlCatalogGetPublic __attribute((alias("xmlCatalogGetPublic__internal_alias")));
+#else
+#ifndef xmlCatalogGetPublic
+extern __typeof (xmlCatalogGetPublic) xmlCatalogGetPublic__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogGetPublic xmlCatalogGetPublic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogGetSystem
+extern __typeof (xmlCatalogGetSystem) xmlCatalogGetSystem __attribute((alias("xmlCatalogGetSystem__internal_alias")));
+#else
+#ifndef xmlCatalogGetSystem
+extern __typeof (xmlCatalogGetSystem) xmlCatalogGetSystem__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogGetSystem xmlCatalogGetSystem__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogIsEmpty
+extern __typeof (xmlCatalogIsEmpty) xmlCatalogIsEmpty __attribute((alias("xmlCatalogIsEmpty__internal_alias")));
+#else
+#ifndef xmlCatalogIsEmpty
+extern __typeof (xmlCatalogIsEmpty) xmlCatalogIsEmpty__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogIsEmpty xmlCatalogIsEmpty__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogLocalResolve
+extern __typeof (xmlCatalogLocalResolve) xmlCatalogLocalResolve __attribute((alias("xmlCatalogLocalResolve__internal_alias")));
+#else
+#ifndef xmlCatalogLocalResolve
+extern __typeof (xmlCatalogLocalResolve) xmlCatalogLocalResolve__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogLocalResolve xmlCatalogLocalResolve__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogLocalResolveURI
+extern __typeof (xmlCatalogLocalResolveURI) xmlCatalogLocalResolveURI __attribute((alias("xmlCatalogLocalResolveURI__internal_alias")));
+#else
+#ifndef xmlCatalogLocalResolveURI
+extern __typeof (xmlCatalogLocalResolveURI) xmlCatalogLocalResolveURI__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogLocalResolveURI xmlCatalogLocalResolveURI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogRemove
+extern __typeof (xmlCatalogRemove) xmlCatalogRemove __attribute((alias("xmlCatalogRemove__internal_alias")));
+#else
+#ifndef xmlCatalogRemove
+extern __typeof (xmlCatalogRemove) xmlCatalogRemove__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogRemove xmlCatalogRemove__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogResolve
+extern __typeof (xmlCatalogResolve) xmlCatalogResolve __attribute((alias("xmlCatalogResolve__internal_alias")));
+#else
+#ifndef xmlCatalogResolve
+extern __typeof (xmlCatalogResolve) xmlCatalogResolve__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogResolve xmlCatalogResolve__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogResolvePublic
+extern __typeof (xmlCatalogResolvePublic) xmlCatalogResolvePublic __attribute((alias("xmlCatalogResolvePublic__internal_alias")));
+#else
+#ifndef xmlCatalogResolvePublic
+extern __typeof (xmlCatalogResolvePublic) xmlCatalogResolvePublic__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogResolvePublic xmlCatalogResolvePublic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogResolveSystem
+extern __typeof (xmlCatalogResolveSystem) xmlCatalogResolveSystem __attribute((alias("xmlCatalogResolveSystem__internal_alias")));
+#else
+#ifndef xmlCatalogResolveSystem
+extern __typeof (xmlCatalogResolveSystem) xmlCatalogResolveSystem__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogResolveSystem xmlCatalogResolveSystem__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogResolveURI
+extern __typeof (xmlCatalogResolveURI) xmlCatalogResolveURI __attribute((alias("xmlCatalogResolveURI__internal_alias")));
+#else
+#ifndef xmlCatalogResolveURI
+extern __typeof (xmlCatalogResolveURI) xmlCatalogResolveURI__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogResolveURI xmlCatalogResolveURI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogSetDebug
+extern __typeof (xmlCatalogSetDebug) xmlCatalogSetDebug __attribute((alias("xmlCatalogSetDebug__internal_alias")));
+#else
+#ifndef xmlCatalogSetDebug
+extern __typeof (xmlCatalogSetDebug) xmlCatalogSetDebug__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogSetDebug xmlCatalogSetDebug__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogSetDefaultPrefer
+extern __typeof (xmlCatalogSetDefaultPrefer) xmlCatalogSetDefaultPrefer __attribute((alias("xmlCatalogSetDefaultPrefer__internal_alias")));
+#else
+#ifndef xmlCatalogSetDefaultPrefer
+extern __typeof (xmlCatalogSetDefaultPrefer) xmlCatalogSetDefaultPrefer__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogSetDefaultPrefer xmlCatalogSetDefaultPrefer__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlCatalogSetDefaults
+extern __typeof (xmlCatalogSetDefaults) xmlCatalogSetDefaults __attribute((alias("xmlCatalogSetDefaults__internal_alias")));
+#else
+#ifndef xmlCatalogSetDefaults
+extern __typeof (xmlCatalogSetDefaults) xmlCatalogSetDefaults__internal_alias __attribute((visibility("hidden")));
+#define xmlCatalogSetDefaults xmlCatalogSetDefaults__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCharEncCloseFunc
+extern __typeof (xmlCharEncCloseFunc) xmlCharEncCloseFunc __attribute((alias("xmlCharEncCloseFunc__internal_alias")));
+#else
+#ifndef xmlCharEncCloseFunc
+extern __typeof (xmlCharEncCloseFunc) xmlCharEncCloseFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlCharEncCloseFunc xmlCharEncCloseFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCharEncFirstLine
+extern __typeof (xmlCharEncFirstLine) xmlCharEncFirstLine __attribute((alias("xmlCharEncFirstLine__internal_alias")));
+#else
+#ifndef xmlCharEncFirstLine
+extern __typeof (xmlCharEncFirstLine) xmlCharEncFirstLine__internal_alias __attribute((visibility("hidden")));
+#define xmlCharEncFirstLine xmlCharEncFirstLine__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCharEncInFunc
+extern __typeof (xmlCharEncInFunc) xmlCharEncInFunc __attribute((alias("xmlCharEncInFunc__internal_alias")));
+#else
+#ifndef xmlCharEncInFunc
+extern __typeof (xmlCharEncInFunc) xmlCharEncInFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlCharEncInFunc xmlCharEncInFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCharEncOutFunc
+extern __typeof (xmlCharEncOutFunc) xmlCharEncOutFunc __attribute((alias("xmlCharEncOutFunc__internal_alias")));
+#else
+#ifndef xmlCharEncOutFunc
+extern __typeof (xmlCharEncOutFunc) xmlCharEncOutFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlCharEncOutFunc xmlCharEncOutFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlCharInRange
+extern __typeof (xmlCharInRange) xmlCharInRange __attribute((alias("xmlCharInRange__internal_alias")));
+#else
+#ifndef xmlCharInRange
+extern __typeof (xmlCharInRange) xmlCharInRange__internal_alias __attribute((visibility("hidden")));
+#define xmlCharInRange xmlCharInRange__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlCharStrdup
+extern __typeof (xmlCharStrdup) xmlCharStrdup __attribute((alias("xmlCharStrdup__internal_alias")));
+#else
+#ifndef xmlCharStrdup
+extern __typeof (xmlCharStrdup) xmlCharStrdup__internal_alias __attribute((visibility("hidden")));
+#define xmlCharStrdup xmlCharStrdup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlCharStrndup
+extern __typeof (xmlCharStrndup) xmlCharStrndup __attribute((alias("xmlCharStrndup__internal_alias")));
+#else
+#ifndef xmlCharStrndup
+extern __typeof (xmlCharStrndup) xmlCharStrndup__internal_alias __attribute((visibility("hidden")));
+#define xmlCharStrndup xmlCharStrndup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlCheckFilename
+extern __typeof (xmlCheckFilename) xmlCheckFilename __attribute((alias("xmlCheckFilename__internal_alias")));
+#else
+#ifndef xmlCheckFilename
+extern __typeof (xmlCheckFilename) xmlCheckFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlCheckFilename xmlCheckFilename__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlCheckHTTPInput
+extern __typeof (xmlCheckHTTPInput) xmlCheckHTTPInput __attribute((alias("xmlCheckHTTPInput__internal_alias")));
+#else
+#ifndef xmlCheckHTTPInput
+extern __typeof (xmlCheckHTTPInput) xmlCheckHTTPInput__internal_alias __attribute((visibility("hidden")));
+#define xmlCheckHTTPInput xmlCheckHTTPInput__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCheckLanguageID
+extern __typeof (xmlCheckLanguageID) xmlCheckLanguageID __attribute((alias("xmlCheckLanguageID__internal_alias")));
+#else
+#ifndef xmlCheckLanguageID
+extern __typeof (xmlCheckLanguageID) xmlCheckLanguageID__internal_alias __attribute((visibility("hidden")));
+#define xmlCheckLanguageID xmlCheckLanguageID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlCheckUTF8
+extern __typeof (xmlCheckUTF8) xmlCheckUTF8 __attribute((alias("xmlCheckUTF8__internal_alias")));
+#else
+#ifndef xmlCheckUTF8
+extern __typeof (xmlCheckUTF8) xmlCheckUTF8__internal_alias __attribute((visibility("hidden")));
+#define xmlCheckUTF8 xmlCheckUTF8__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlCheckVersion
+extern __typeof (xmlCheckVersion) xmlCheckVersion __attribute((alias("xmlCheckVersion__internal_alias")));
+#else
+#ifndef xmlCheckVersion
+extern __typeof (xmlCheckVersion) xmlCheckVersion__internal_alias __attribute((visibility("hidden")));
+#define xmlCheckVersion xmlCheckVersion__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlChildElementCount
+extern __typeof (xmlChildElementCount) xmlChildElementCount __attribute((alias("xmlChildElementCount__internal_alias")));
+#else
+#ifndef xmlChildElementCount
+extern __typeof (xmlChildElementCount) xmlChildElementCount__internal_alias __attribute((visibility("hidden")));
+#define xmlChildElementCount xmlChildElementCount__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCleanupCharEncodingHandlers
+extern __typeof (xmlCleanupCharEncodingHandlers) xmlCleanupCharEncodingHandlers __attribute((alias("xmlCleanupCharEncodingHandlers__internal_alias")));
+#else
+#ifndef xmlCleanupCharEncodingHandlers
+extern __typeof (xmlCleanupCharEncodingHandlers) xmlCleanupCharEncodingHandlers__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupCharEncodingHandlers xmlCleanupCharEncodingHandlers__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlCleanupEncodingAliases
+extern __typeof (xmlCleanupEncodingAliases) xmlCleanupEncodingAliases __attribute((alias("xmlCleanupEncodingAliases__internal_alias")));
+#else
+#ifndef xmlCleanupEncodingAliases
+extern __typeof (xmlCleanupEncodingAliases) xmlCleanupEncodingAliases__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupEncodingAliases xmlCleanupEncodingAliases__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlCleanupGlobals
+extern __typeof (xmlCleanupGlobals) xmlCleanupGlobals __attribute((alias("xmlCleanupGlobals__internal_alias")));
+#else
+#ifndef xmlCleanupGlobals
+extern __typeof (xmlCleanupGlobals) xmlCleanupGlobals__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupGlobals xmlCleanupGlobals__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlCleanupInputCallbacks
+extern __typeof (xmlCleanupInputCallbacks) xmlCleanupInputCallbacks __attribute((alias("xmlCleanupInputCallbacks__internal_alias")));
+#else
+#ifndef xmlCleanupInputCallbacks
+extern __typeof (xmlCleanupInputCallbacks) xmlCleanupInputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupInputCallbacks xmlCleanupInputCallbacks__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlCleanupMemory
+extern __typeof (xmlCleanupMemory) xmlCleanupMemory __attribute((alias("xmlCleanupMemory__internal_alias")));
+#else
+#ifndef xmlCleanupMemory
+extern __typeof (xmlCleanupMemory) xmlCleanupMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupMemory xmlCleanupMemory__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlCleanupOutputCallbacks
+extern __typeof (xmlCleanupOutputCallbacks) xmlCleanupOutputCallbacks __attribute((alias("xmlCleanupOutputCallbacks__internal_alias")));
+#else
+#ifndef xmlCleanupOutputCallbacks
+extern __typeof (xmlCleanupOutputCallbacks) xmlCleanupOutputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupOutputCallbacks xmlCleanupOutputCallbacks__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCleanupParser
+extern __typeof (xmlCleanupParser) xmlCleanupParser __attribute((alias("xmlCleanupParser__internal_alias")));
+#else
+#ifndef xmlCleanupParser
+extern __typeof (xmlCleanupParser) xmlCleanupParser__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupParser xmlCleanupParser__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlCleanupPredefinedEntities
+extern __typeof (xmlCleanupPredefinedEntities) xmlCleanupPredefinedEntities __attribute((alias("xmlCleanupPredefinedEntities__internal_alias")));
+#else
+#ifndef xmlCleanupPredefinedEntities
+extern __typeof (xmlCleanupPredefinedEntities) xmlCleanupPredefinedEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupPredefinedEntities xmlCleanupPredefinedEntities__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlCleanupThreads
+extern __typeof (xmlCleanupThreads) xmlCleanupThreads __attribute((alias("xmlCleanupThreads__internal_alias")));
+#else
+#ifndef xmlCleanupThreads
+extern __typeof (xmlCleanupThreads) xmlCleanupThreads__internal_alias __attribute((visibility("hidden")));
+#define xmlCleanupThreads xmlCleanupThreads__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlClearNodeInfoSeq
+extern __typeof (xmlClearNodeInfoSeq) xmlClearNodeInfoSeq __attribute((alias("xmlClearNodeInfoSeq__internal_alias")));
+#else
+#ifndef xmlClearNodeInfoSeq
+extern __typeof (xmlClearNodeInfoSeq) xmlClearNodeInfoSeq__internal_alias __attribute((visibility("hidden")));
+#define xmlClearNodeInfoSeq xmlClearNodeInfoSeq__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlClearParserCtxt
+extern __typeof (xmlClearParserCtxt) xmlClearParserCtxt __attribute((alias("xmlClearParserCtxt__internal_alias")));
+#else
+#ifndef xmlClearParserCtxt
+extern __typeof (xmlClearParserCtxt) xmlClearParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlClearParserCtxt xmlClearParserCtxt__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlConvertSGMLCatalog
+extern __typeof (xmlConvertSGMLCatalog) xmlConvertSGMLCatalog __attribute((alias("xmlConvertSGMLCatalog__internal_alias")));
+#else
+#ifndef xmlConvertSGMLCatalog
+extern __typeof (xmlConvertSGMLCatalog) xmlConvertSGMLCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlConvertSGMLCatalog xmlConvertSGMLCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_valid
+#undef xmlCopyAttributeTable
+extern __typeof (xmlCopyAttributeTable) xmlCopyAttributeTable __attribute((alias("xmlCopyAttributeTable__internal_alias")));
+#else
+#ifndef xmlCopyAttributeTable
+extern __typeof (xmlCopyAttributeTable) xmlCopyAttributeTable__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyAttributeTable xmlCopyAttributeTable__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlCopyChar
+extern __typeof (xmlCopyChar) xmlCopyChar __attribute((alias("xmlCopyChar__internal_alias")));
+#else
+#ifndef xmlCopyChar
+extern __typeof (xmlCopyChar) xmlCopyChar__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyChar xmlCopyChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlCopyCharMultiByte
+extern __typeof (xmlCopyCharMultiByte) xmlCopyCharMultiByte __attribute((alias("xmlCopyCharMultiByte__internal_alias")));
+#else
+#ifndef xmlCopyCharMultiByte
+extern __typeof (xmlCopyCharMultiByte) xmlCopyCharMultiByte__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyCharMultiByte xmlCopyCharMultiByte__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlCopyDoc
+extern __typeof (xmlCopyDoc) xmlCopyDoc __attribute((alias("xmlCopyDoc__internal_alias")));
+#else
+#ifndef xmlCopyDoc
+extern __typeof (xmlCopyDoc) xmlCopyDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyDoc xmlCopyDoc__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlCopyDocElementContent
+extern __typeof (xmlCopyDocElementContent) xmlCopyDocElementContent __attribute((alias("xmlCopyDocElementContent__internal_alias")));
+#else
+#ifndef xmlCopyDocElementContent
+extern __typeof (xmlCopyDocElementContent) xmlCopyDocElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyDocElementContent xmlCopyDocElementContent__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlCopyDtd
+extern __typeof (xmlCopyDtd) xmlCopyDtd __attribute((alias("xmlCopyDtd__internal_alias")));
+#else
+#ifndef xmlCopyDtd
+extern __typeof (xmlCopyDtd) xmlCopyDtd__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyDtd xmlCopyDtd__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlCopyElementContent
+extern __typeof (xmlCopyElementContent) xmlCopyElementContent __attribute((alias("xmlCopyElementContent__internal_alias")));
+#else
+#ifndef xmlCopyElementContent
+extern __typeof (xmlCopyElementContent) xmlCopyElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyElementContent xmlCopyElementContent__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_valid
+#undef xmlCopyElementTable
+extern __typeof (xmlCopyElementTable) xmlCopyElementTable __attribute((alias("xmlCopyElementTable__internal_alias")));
+#else
+#ifndef xmlCopyElementTable
+extern __typeof (xmlCopyElementTable) xmlCopyElementTable__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyElementTable xmlCopyElementTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_entities
+#undef xmlCopyEntitiesTable
+extern __typeof (xmlCopyEntitiesTable) xmlCopyEntitiesTable __attribute((alias("xmlCopyEntitiesTable__internal_alias")));
+#else
+#ifndef xmlCopyEntitiesTable
+extern __typeof (xmlCopyEntitiesTable) xmlCopyEntitiesTable__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyEntitiesTable xmlCopyEntitiesTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_valid
+#undef xmlCopyEnumeration
+extern __typeof (xmlCopyEnumeration) xmlCopyEnumeration __attribute((alias("xmlCopyEnumeration__internal_alias")));
+#else
+#ifndef xmlCopyEnumeration
+extern __typeof (xmlCopyEnumeration) xmlCopyEnumeration__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyEnumeration xmlCopyEnumeration__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlCopyError
+extern __typeof (xmlCopyError) xmlCopyError __attribute((alias("xmlCopyError__internal_alias")));
+#else
+#ifndef xmlCopyError
+extern __typeof (xmlCopyError) xmlCopyError__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyError xmlCopyError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyNamespace
+extern __typeof (xmlCopyNamespace) xmlCopyNamespace __attribute((alias("xmlCopyNamespace__internal_alias")));
+#else
+#ifndef xmlCopyNamespace
+extern __typeof (xmlCopyNamespace) xmlCopyNamespace__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyNamespace xmlCopyNamespace__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyNamespaceList
+extern __typeof (xmlCopyNamespaceList) xmlCopyNamespaceList __attribute((alias("xmlCopyNamespaceList__internal_alias")));
+#else
+#ifndef xmlCopyNamespaceList
+extern __typeof (xmlCopyNamespaceList) xmlCopyNamespaceList__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyNamespaceList xmlCopyNamespaceList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyNode
+extern __typeof (xmlCopyNode) xmlCopyNode __attribute((alias("xmlCopyNode__internal_alias")));
+#else
+#ifndef xmlCopyNode
+extern __typeof (xmlCopyNode) xmlCopyNode__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyNode xmlCopyNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyNodeList
+extern __typeof (xmlCopyNodeList) xmlCopyNodeList __attribute((alias("xmlCopyNodeList__internal_alias")));
+#else
+#ifndef xmlCopyNodeList
+extern __typeof (xmlCopyNodeList) xmlCopyNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyNodeList xmlCopyNodeList__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_valid
+#undef xmlCopyNotationTable
+extern __typeof (xmlCopyNotationTable) xmlCopyNotationTable __attribute((alias("xmlCopyNotationTable__internal_alias")));
+#else
+#ifndef xmlCopyNotationTable
+extern __typeof (xmlCopyNotationTable) xmlCopyNotationTable__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyNotationTable xmlCopyNotationTable__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyProp
+extern __typeof (xmlCopyProp) xmlCopyProp __attribute((alias("xmlCopyProp__internal_alias")));
+#else
+#ifndef xmlCopyProp
+extern __typeof (xmlCopyProp) xmlCopyProp__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyProp xmlCopyProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCopyPropList
+extern __typeof (xmlCopyPropList) xmlCopyPropList __attribute((alias("xmlCopyPropList__internal_alias")));
+#else
+#ifndef xmlCopyPropList
+extern __typeof (xmlCopyPropList) xmlCopyPropList__internal_alias __attribute((visibility("hidden")));
+#define xmlCopyPropList xmlCopyPropList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateDocParserCtxt
+extern __typeof (xmlCreateDocParserCtxt) xmlCreateDocParserCtxt __attribute((alias("xmlCreateDocParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateDocParserCtxt
+extern __typeof (xmlCreateDocParserCtxt) xmlCreateDocParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateDocParserCtxt xmlCreateDocParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlCreateEntitiesTable
+extern __typeof (xmlCreateEntitiesTable) xmlCreateEntitiesTable __attribute((alias("xmlCreateEntitiesTable__internal_alias")));
+#else
+#ifndef xmlCreateEntitiesTable
+extern __typeof (xmlCreateEntitiesTable) xmlCreateEntitiesTable__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateEntitiesTable xmlCreateEntitiesTable__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateEntityParserCtxt
+extern __typeof (xmlCreateEntityParserCtxt) xmlCreateEntityParserCtxt __attribute((alias("xmlCreateEntityParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateEntityParserCtxt
+extern __typeof (xmlCreateEntityParserCtxt) xmlCreateEntityParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateEntityParserCtxt xmlCreateEntityParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlCreateEnumeration
+extern __typeof (xmlCreateEnumeration) xmlCreateEnumeration __attribute((alias("xmlCreateEnumeration__internal_alias")));
+#else
+#ifndef xmlCreateEnumeration
+extern __typeof (xmlCreateEnumeration) xmlCreateEnumeration__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateEnumeration xmlCreateEnumeration__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateFileParserCtxt
+extern __typeof (xmlCreateFileParserCtxt) xmlCreateFileParserCtxt __attribute((alias("xmlCreateFileParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateFileParserCtxt
+extern __typeof (xmlCreateFileParserCtxt) xmlCreateFileParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateFileParserCtxt xmlCreateFileParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateIOParserCtxt
+extern __typeof (xmlCreateIOParserCtxt) xmlCreateIOParserCtxt __attribute((alias("xmlCreateIOParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateIOParserCtxt
+extern __typeof (xmlCreateIOParserCtxt) xmlCreateIOParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateIOParserCtxt xmlCreateIOParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlCreateIntSubset
+extern __typeof (xmlCreateIntSubset) xmlCreateIntSubset __attribute((alias("xmlCreateIntSubset__internal_alias")));
+#else
+#ifndef xmlCreateIntSubset
+extern __typeof (xmlCreateIntSubset) xmlCreateIntSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateIntSubset xmlCreateIntSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateMemoryParserCtxt
+extern __typeof (xmlCreateMemoryParserCtxt) xmlCreateMemoryParserCtxt __attribute((alias("xmlCreateMemoryParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateMemoryParserCtxt
+extern __typeof (xmlCreateMemoryParserCtxt) xmlCreateMemoryParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateMemoryParserCtxt xmlCreateMemoryParserCtxt__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PUSH_ENABLED)
+#ifdef bottom_parser
+#undef xmlCreatePushParserCtxt
+extern __typeof (xmlCreatePushParserCtxt) xmlCreatePushParserCtxt __attribute((alias("xmlCreatePushParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreatePushParserCtxt
+extern __typeof (xmlCreatePushParserCtxt) xmlCreatePushParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreatePushParserCtxt xmlCreatePushParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlCreateURI
+extern __typeof (xmlCreateURI) xmlCreateURI __attribute((alias("xmlCreateURI__internal_alias")));
+#else
+#ifndef xmlCreateURI
+extern __typeof (xmlCreateURI) xmlCreateURI__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateURI xmlCreateURI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCreateURLParserCtxt
+extern __typeof (xmlCreateURLParserCtxt) xmlCreateURLParserCtxt __attribute((alias("xmlCreateURLParserCtxt__internal_alias")));
+#else
+#ifndef xmlCreateURLParserCtxt
+extern __typeof (xmlCreateURLParserCtxt) xmlCreateURLParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlCreateURLParserCtxt xmlCreateURLParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlCtxtGetLastError
+extern __typeof (xmlCtxtGetLastError) xmlCtxtGetLastError __attribute((alias("xmlCtxtGetLastError__internal_alias")));
+#else
+#ifndef xmlCtxtGetLastError
+extern __typeof (xmlCtxtGetLastError) xmlCtxtGetLastError__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtGetLastError xmlCtxtGetLastError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReadDoc
+extern __typeof (xmlCtxtReadDoc) xmlCtxtReadDoc __attribute((alias("xmlCtxtReadDoc__internal_alias")));
+#else
+#ifndef xmlCtxtReadDoc
+extern __typeof (xmlCtxtReadDoc) xmlCtxtReadDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReadDoc xmlCtxtReadDoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReadFd
+extern __typeof (xmlCtxtReadFd) xmlCtxtReadFd __attribute((alias("xmlCtxtReadFd__internal_alias")));
+#else
+#ifndef xmlCtxtReadFd
+extern __typeof (xmlCtxtReadFd) xmlCtxtReadFd__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReadFd xmlCtxtReadFd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReadFile
+extern __typeof (xmlCtxtReadFile) xmlCtxtReadFile __attribute((alias("xmlCtxtReadFile__internal_alias")));
+#else
+#ifndef xmlCtxtReadFile
+extern __typeof (xmlCtxtReadFile) xmlCtxtReadFile__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReadFile xmlCtxtReadFile__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReadIO
+extern __typeof (xmlCtxtReadIO) xmlCtxtReadIO __attribute((alias("xmlCtxtReadIO__internal_alias")));
+#else
+#ifndef xmlCtxtReadIO
+extern __typeof (xmlCtxtReadIO) xmlCtxtReadIO__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReadIO xmlCtxtReadIO__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReadMemory
+extern __typeof (xmlCtxtReadMemory) xmlCtxtReadMemory __attribute((alias("xmlCtxtReadMemory__internal_alias")));
+#else
+#ifndef xmlCtxtReadMemory
+extern __typeof (xmlCtxtReadMemory) xmlCtxtReadMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReadMemory xmlCtxtReadMemory__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtReset
+extern __typeof (xmlCtxtReset) xmlCtxtReset __attribute((alias("xmlCtxtReset__internal_alias")));
+#else
+#ifndef xmlCtxtReset
+extern __typeof (xmlCtxtReset) xmlCtxtReset__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtReset xmlCtxtReset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlCtxtResetLastError
+extern __typeof (xmlCtxtResetLastError) xmlCtxtResetLastError __attribute((alias("xmlCtxtResetLastError__internal_alias")));
+#else
+#ifndef xmlCtxtResetLastError
+extern __typeof (xmlCtxtResetLastError) xmlCtxtResetLastError__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtResetLastError xmlCtxtResetLastError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtResetPush
+extern __typeof (xmlCtxtResetPush) xmlCtxtResetPush __attribute((alias("xmlCtxtResetPush__internal_alias")));
+#else
+#ifndef xmlCtxtResetPush
+extern __typeof (xmlCtxtResetPush) xmlCtxtResetPush__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtResetPush xmlCtxtResetPush__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlCtxtUseOptions
+extern __typeof (xmlCtxtUseOptions) xmlCtxtUseOptions __attribute((alias("xmlCtxtUseOptions__internal_alias")));
+#else
+#ifndef xmlCtxtUseOptions
+extern __typeof (xmlCtxtUseOptions) xmlCtxtUseOptions__internal_alias __attribute((visibility("hidden")));
+#define xmlCtxtUseOptions xmlCtxtUseOptions__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlCurrentChar
+extern __typeof (xmlCurrentChar) xmlCurrentChar __attribute((alias("xmlCurrentChar__internal_alias")));
+#else
+#ifndef xmlCurrentChar
+extern __typeof (xmlCurrentChar) xmlCurrentChar__internal_alias __attribute((visibility("hidden")));
+#define xmlCurrentChar xmlCurrentChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapAdoptNode
+extern __typeof (xmlDOMWrapAdoptNode) xmlDOMWrapAdoptNode __attribute((alias("xmlDOMWrapAdoptNode__internal_alias")));
+#else
+#ifndef xmlDOMWrapAdoptNode
+extern __typeof (xmlDOMWrapAdoptNode) xmlDOMWrapAdoptNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapAdoptNode xmlDOMWrapAdoptNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapCloneNode
+extern __typeof (xmlDOMWrapCloneNode) xmlDOMWrapCloneNode __attribute((alias("xmlDOMWrapCloneNode__internal_alias")));
+#else
+#ifndef xmlDOMWrapCloneNode
+extern __typeof (xmlDOMWrapCloneNode) xmlDOMWrapCloneNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapCloneNode xmlDOMWrapCloneNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapFreeCtxt
+extern __typeof (xmlDOMWrapFreeCtxt) xmlDOMWrapFreeCtxt __attribute((alias("xmlDOMWrapFreeCtxt__internal_alias")));
+#else
+#ifndef xmlDOMWrapFreeCtxt
+extern __typeof (xmlDOMWrapFreeCtxt) xmlDOMWrapFreeCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapFreeCtxt xmlDOMWrapFreeCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapNewCtxt
+extern __typeof (xmlDOMWrapNewCtxt) xmlDOMWrapNewCtxt __attribute((alias("xmlDOMWrapNewCtxt__internal_alias")));
+#else
+#ifndef xmlDOMWrapNewCtxt
+extern __typeof (xmlDOMWrapNewCtxt) xmlDOMWrapNewCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapNewCtxt xmlDOMWrapNewCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapReconcileNamespaces
+extern __typeof (xmlDOMWrapReconcileNamespaces) xmlDOMWrapReconcileNamespaces __attribute((alias("xmlDOMWrapReconcileNamespaces__internal_alias")));
+#else
+#ifndef xmlDOMWrapReconcileNamespaces
+extern __typeof (xmlDOMWrapReconcileNamespaces) xmlDOMWrapReconcileNamespaces__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapReconcileNamespaces xmlDOMWrapReconcileNamespaces__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDOMWrapRemoveNode
+extern __typeof (xmlDOMWrapRemoveNode) xmlDOMWrapRemoveNode __attribute((alias("xmlDOMWrapRemoveNode__internal_alias")));
+#else
+#ifndef xmlDOMWrapRemoveNode
+extern __typeof (xmlDOMWrapRemoveNode) xmlDOMWrapRemoveNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDOMWrapRemoveNode xmlDOMWrapRemoveNode__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugCheckDocument
+extern __typeof (xmlDebugCheckDocument) xmlDebugCheckDocument __attribute((alias("xmlDebugCheckDocument__internal_alias")));
+#else
+#ifndef xmlDebugCheckDocument
+extern __typeof (xmlDebugCheckDocument) xmlDebugCheckDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugCheckDocument xmlDebugCheckDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpAttr
+extern __typeof (xmlDebugDumpAttr) xmlDebugDumpAttr __attribute((alias("xmlDebugDumpAttr__internal_alias")));
+#else
+#ifndef xmlDebugDumpAttr
+extern __typeof (xmlDebugDumpAttr) xmlDebugDumpAttr__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpAttr xmlDebugDumpAttr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpAttrList
+extern __typeof (xmlDebugDumpAttrList) xmlDebugDumpAttrList __attribute((alias("xmlDebugDumpAttrList__internal_alias")));
+#else
+#ifndef xmlDebugDumpAttrList
+extern __typeof (xmlDebugDumpAttrList) xmlDebugDumpAttrList__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpAttrList xmlDebugDumpAttrList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpDTD
+extern __typeof (xmlDebugDumpDTD) xmlDebugDumpDTD __attribute((alias("xmlDebugDumpDTD__internal_alias")));
+#else
+#ifndef xmlDebugDumpDTD
+extern __typeof (xmlDebugDumpDTD) xmlDebugDumpDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpDTD xmlDebugDumpDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpDocument
+extern __typeof (xmlDebugDumpDocument) xmlDebugDumpDocument __attribute((alias("xmlDebugDumpDocument__internal_alias")));
+#else
+#ifndef xmlDebugDumpDocument
+extern __typeof (xmlDebugDumpDocument) xmlDebugDumpDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpDocument xmlDebugDumpDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpDocumentHead
+extern __typeof (xmlDebugDumpDocumentHead) xmlDebugDumpDocumentHead __attribute((alias("xmlDebugDumpDocumentHead__internal_alias")));
+#else
+#ifndef xmlDebugDumpDocumentHead
+extern __typeof (xmlDebugDumpDocumentHead) xmlDebugDumpDocumentHead__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpDocumentHead xmlDebugDumpDocumentHead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpEntities
+extern __typeof (xmlDebugDumpEntities) xmlDebugDumpEntities __attribute((alias("xmlDebugDumpEntities__internal_alias")));
+#else
+#ifndef xmlDebugDumpEntities
+extern __typeof (xmlDebugDumpEntities) xmlDebugDumpEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpEntities xmlDebugDumpEntities__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpNode
+extern __typeof (xmlDebugDumpNode) xmlDebugDumpNode __attribute((alias("xmlDebugDumpNode__internal_alias")));
+#else
+#ifndef xmlDebugDumpNode
+extern __typeof (xmlDebugDumpNode) xmlDebugDumpNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpNode xmlDebugDumpNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpNodeList
+extern __typeof (xmlDebugDumpNodeList) xmlDebugDumpNodeList __attribute((alias("xmlDebugDumpNodeList__internal_alias")));
+#else
+#ifndef xmlDebugDumpNodeList
+extern __typeof (xmlDebugDumpNodeList) xmlDebugDumpNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpNodeList xmlDebugDumpNodeList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpOneNode
+extern __typeof (xmlDebugDumpOneNode) xmlDebugDumpOneNode __attribute((alias("xmlDebugDumpOneNode__internal_alias")));
+#else
+#ifndef xmlDebugDumpOneNode
+extern __typeof (xmlDebugDumpOneNode) xmlDebugDumpOneNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpOneNode xmlDebugDumpOneNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlDebugDumpString
+extern __typeof (xmlDebugDumpString) xmlDebugDumpString __attribute((alias("xmlDebugDumpString__internal_alias")));
+#else
+#ifndef xmlDebugDumpString
+extern __typeof (xmlDebugDumpString) xmlDebugDumpString__internal_alias __attribute((visibility("hidden")));
+#define xmlDebugDumpString xmlDebugDumpString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlDecodeEntities
+extern __typeof (xmlDecodeEntities) xmlDecodeEntities __attribute((alias("xmlDecodeEntities__internal_alias")));
+#else
+#ifndef xmlDecodeEntities
+extern __typeof (xmlDecodeEntities) xmlDecodeEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlDecodeEntities xmlDecodeEntities__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlDefaultSAXHandlerInit
+extern __typeof (xmlDefaultSAXHandlerInit) xmlDefaultSAXHandlerInit __attribute((alias("xmlDefaultSAXHandlerInit__internal_alias")));
+#else
+#ifndef xmlDefaultSAXHandlerInit
+extern __typeof (xmlDefaultSAXHandlerInit) xmlDefaultSAXHandlerInit__internal_alias __attribute((visibility("hidden")));
+#define xmlDefaultSAXHandlerInit xmlDefaultSAXHandlerInit__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlDelEncodingAlias
+extern __typeof (xmlDelEncodingAlias) xmlDelEncodingAlias __attribute((alias("xmlDelEncodingAlias__internal_alias")));
+#else
+#ifndef xmlDelEncodingAlias
+extern __typeof (xmlDelEncodingAlias) xmlDelEncodingAlias__internal_alias __attribute((visibility("hidden")));
+#define xmlDelEncodingAlias xmlDelEncodingAlias__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlDeregisterNodeDefault
+extern __typeof (xmlDeregisterNodeDefault) xmlDeregisterNodeDefault __attribute((alias("xmlDeregisterNodeDefault__internal_alias")));
+#else
+#ifndef xmlDeregisterNodeDefault
+extern __typeof (xmlDeregisterNodeDefault) xmlDeregisterNodeDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlDeregisterNodeDefault xmlDeregisterNodeDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlDetectCharEncoding
+extern __typeof (xmlDetectCharEncoding) xmlDetectCharEncoding __attribute((alias("xmlDetectCharEncoding__internal_alias")));
+#else
+#ifndef xmlDetectCharEncoding
+extern __typeof (xmlDetectCharEncoding) xmlDetectCharEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlDetectCharEncoding xmlDetectCharEncoding__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictCleanup
+extern __typeof (xmlDictCleanup) xmlDictCleanup __attribute((alias("xmlDictCleanup__internal_alias")));
+#else
+#ifndef xmlDictCleanup
+extern __typeof (xmlDictCleanup) xmlDictCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlDictCleanup xmlDictCleanup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictCreate
+extern __typeof (xmlDictCreate) xmlDictCreate __attribute((alias("xmlDictCreate__internal_alias")));
+#else
+#ifndef xmlDictCreate
+extern __typeof (xmlDictCreate) xmlDictCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlDictCreate xmlDictCreate__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictCreateSub
+extern __typeof (xmlDictCreateSub) xmlDictCreateSub __attribute((alias("xmlDictCreateSub__internal_alias")));
+#else
+#ifndef xmlDictCreateSub
+extern __typeof (xmlDictCreateSub) xmlDictCreateSub__internal_alias __attribute((visibility("hidden")));
+#define xmlDictCreateSub xmlDictCreateSub__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictExists
+extern __typeof (xmlDictExists) xmlDictExists __attribute((alias("xmlDictExists__internal_alias")));
+#else
+#ifndef xmlDictExists
+extern __typeof (xmlDictExists) xmlDictExists__internal_alias __attribute((visibility("hidden")));
+#define xmlDictExists xmlDictExists__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictFree
+extern __typeof (xmlDictFree) xmlDictFree __attribute((alias("xmlDictFree__internal_alias")));
+#else
+#ifndef xmlDictFree
+extern __typeof (xmlDictFree) xmlDictFree__internal_alias __attribute((visibility("hidden")));
+#define xmlDictFree xmlDictFree__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictLookup
+extern __typeof (xmlDictLookup) xmlDictLookup __attribute((alias("xmlDictLookup__internal_alias")));
+#else
+#ifndef xmlDictLookup
+extern __typeof (xmlDictLookup) xmlDictLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlDictLookup xmlDictLookup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictOwns
+extern __typeof (xmlDictOwns) xmlDictOwns __attribute((alias("xmlDictOwns__internal_alias")));
+#else
+#ifndef xmlDictOwns
+extern __typeof (xmlDictOwns) xmlDictOwns__internal_alias __attribute((visibility("hidden")));
+#define xmlDictOwns xmlDictOwns__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictQLookup
+extern __typeof (xmlDictQLookup) xmlDictQLookup __attribute((alias("xmlDictQLookup__internal_alias")));
+#else
+#ifndef xmlDictQLookup
+extern __typeof (xmlDictQLookup) xmlDictQLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlDictQLookup xmlDictQLookup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictReference
+extern __typeof (xmlDictReference) xmlDictReference __attribute((alias("xmlDictReference__internal_alias")));
+#else
+#ifndef xmlDictReference
+extern __typeof (xmlDictReference) xmlDictReference__internal_alias __attribute((visibility("hidden")));
+#define xmlDictReference xmlDictReference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_dict
+#undef xmlDictSize
+extern __typeof (xmlDictSize) xmlDictSize __attribute((alias("xmlDictSize__internal_alias")));
+#else
+#ifndef xmlDictSize
+extern __typeof (xmlDictSize) xmlDictSize__internal_alias __attribute((visibility("hidden")));
+#define xmlDictSize xmlDictSize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDocCopyNode
+extern __typeof (xmlDocCopyNode) xmlDocCopyNode __attribute((alias("xmlDocCopyNode__internal_alias")));
+#else
+#ifndef xmlDocCopyNode
+extern __typeof (xmlDocCopyNode) xmlDocCopyNode__internal_alias __attribute((visibility("hidden")));
+#define xmlDocCopyNode xmlDocCopyNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDocCopyNodeList
+extern __typeof (xmlDocCopyNodeList) xmlDocCopyNodeList __attribute((alias("xmlDocCopyNodeList__internal_alias")));
+#else
+#ifndef xmlDocCopyNodeList
+extern __typeof (xmlDocCopyNodeList) xmlDocCopyNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlDocCopyNodeList xmlDocCopyNodeList__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocDump
+extern __typeof (xmlDocDump) xmlDocDump __attribute((alias("xmlDocDump__internal_alias")));
+#else
+#ifndef xmlDocDump
+extern __typeof (xmlDocDump) xmlDocDump__internal_alias __attribute((visibility("hidden")));
+#define xmlDocDump xmlDocDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocDumpFormatMemory
+extern __typeof (xmlDocDumpFormatMemory) xmlDocDumpFormatMemory __attribute((alias("xmlDocDumpFormatMemory__internal_alias")));
+#else
+#ifndef xmlDocDumpFormatMemory
+extern __typeof (xmlDocDumpFormatMemory) xmlDocDumpFormatMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlDocDumpFormatMemory xmlDocDumpFormatMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocDumpFormatMemoryEnc
+extern __typeof (xmlDocDumpFormatMemoryEnc) xmlDocDumpFormatMemoryEnc __attribute((alias("xmlDocDumpFormatMemoryEnc__internal_alias")));
+#else
+#ifndef xmlDocDumpFormatMemoryEnc
+extern __typeof (xmlDocDumpFormatMemoryEnc) xmlDocDumpFormatMemoryEnc__internal_alias __attribute((visibility("hidden")));
+#define xmlDocDumpFormatMemoryEnc xmlDocDumpFormatMemoryEnc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocDumpMemory
+extern __typeof (xmlDocDumpMemory) xmlDocDumpMemory __attribute((alias("xmlDocDumpMemory__internal_alias")));
+#else
+#ifndef xmlDocDumpMemory
+extern __typeof (xmlDocDumpMemory) xmlDocDumpMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlDocDumpMemory xmlDocDumpMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocDumpMemoryEnc
+extern __typeof (xmlDocDumpMemoryEnc) xmlDocDumpMemoryEnc __attribute((alias("xmlDocDumpMemoryEnc__internal_alias")));
+#else
+#ifndef xmlDocDumpMemoryEnc
+extern __typeof (xmlDocDumpMemoryEnc) xmlDocDumpMemoryEnc__internal_alias __attribute((visibility("hidden")));
+#define xmlDocDumpMemoryEnc xmlDocDumpMemoryEnc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlDocFormatDump
+extern __typeof (xmlDocFormatDump) xmlDocFormatDump __attribute((alias("xmlDocFormatDump__internal_alias")));
+#else
+#ifndef xmlDocFormatDump
+extern __typeof (xmlDocFormatDump) xmlDocFormatDump__internal_alias __attribute((visibility("hidden")));
+#define xmlDocFormatDump xmlDocFormatDump__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlDocGetRootElement
+extern __typeof (xmlDocGetRootElement) xmlDocGetRootElement __attribute((alias("xmlDocGetRootElement__internal_alias")));
+#else
+#ifndef xmlDocGetRootElement
+extern __typeof (xmlDocGetRootElement) xmlDocGetRootElement__internal_alias __attribute((visibility("hidden")));
+#define xmlDocGetRootElement xmlDocGetRootElement__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_tree
+#undef xmlDocSetRootElement
+extern __typeof (xmlDocSetRootElement) xmlDocSetRootElement __attribute((alias("xmlDocSetRootElement__internal_alias")));
+#else
+#ifndef xmlDocSetRootElement
+extern __typeof (xmlDocSetRootElement) xmlDocSetRootElement__internal_alias __attribute((visibility("hidden")));
+#define xmlDocSetRootElement xmlDocSetRootElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpAttributeDecl
+extern __typeof (xmlDumpAttributeDecl) xmlDumpAttributeDecl __attribute((alias("xmlDumpAttributeDecl__internal_alias")));
+#else
+#ifndef xmlDumpAttributeDecl
+extern __typeof (xmlDumpAttributeDecl) xmlDumpAttributeDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpAttributeDecl xmlDumpAttributeDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpAttributeTable
+extern __typeof (xmlDumpAttributeTable) xmlDumpAttributeTable __attribute((alias("xmlDumpAttributeTable__internal_alias")));
+#else
+#ifndef xmlDumpAttributeTable
+extern __typeof (xmlDumpAttributeTable) xmlDumpAttributeTable__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpAttributeTable xmlDumpAttributeTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpElementDecl
+extern __typeof (xmlDumpElementDecl) xmlDumpElementDecl __attribute((alias("xmlDumpElementDecl__internal_alias")));
+#else
+#ifndef xmlDumpElementDecl
+extern __typeof (xmlDumpElementDecl) xmlDumpElementDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpElementDecl xmlDumpElementDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpElementTable
+extern __typeof (xmlDumpElementTable) xmlDumpElementTable __attribute((alias("xmlDumpElementTable__internal_alias")));
+#else
+#ifndef xmlDumpElementTable
+extern __typeof (xmlDumpElementTable) xmlDumpElementTable__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpElementTable xmlDumpElementTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_entities
+#undef xmlDumpEntitiesTable
+extern __typeof (xmlDumpEntitiesTable) xmlDumpEntitiesTable __attribute((alias("xmlDumpEntitiesTable__internal_alias")));
+#else
+#ifndef xmlDumpEntitiesTable
+extern __typeof (xmlDumpEntitiesTable) xmlDumpEntitiesTable__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpEntitiesTable xmlDumpEntitiesTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_entities
+#undef xmlDumpEntityDecl
+extern __typeof (xmlDumpEntityDecl) xmlDumpEntityDecl __attribute((alias("xmlDumpEntityDecl__internal_alias")));
+#else
+#ifndef xmlDumpEntityDecl
+extern __typeof (xmlDumpEntityDecl) xmlDumpEntityDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpEntityDecl xmlDumpEntityDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpNotationDecl
+extern __typeof (xmlDumpNotationDecl) xmlDumpNotationDecl __attribute((alias("xmlDumpNotationDecl__internal_alias")));
+#else
+#ifndef xmlDumpNotationDecl
+extern __typeof (xmlDumpNotationDecl) xmlDumpNotationDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpNotationDecl xmlDumpNotationDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlDumpNotationTable
+extern __typeof (xmlDumpNotationTable) xmlDumpNotationTable __attribute((alias("xmlDumpNotationTable__internal_alias")));
+#else
+#ifndef xmlDumpNotationTable
+extern __typeof (xmlDumpNotationTable) xmlDumpNotationTable__internal_alias __attribute((visibility("hidden")));
+#define xmlDumpNotationTable xmlDumpNotationTable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlElemDump
+extern __typeof (xmlElemDump) xmlElemDump __attribute((alias("xmlElemDump__internal_alias")));
+#else
+#ifndef xmlElemDump
+extern __typeof (xmlElemDump) xmlElemDump__internal_alias __attribute((visibility("hidden")));
+#define xmlElemDump xmlElemDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlEncodeEntities
+extern __typeof (xmlEncodeEntities) xmlEncodeEntities __attribute((alias("xmlEncodeEntities__internal_alias")));
+#else
+#ifndef xmlEncodeEntities
+extern __typeof (xmlEncodeEntities) xmlEncodeEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlEncodeEntities xmlEncodeEntities__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlEncodeEntitiesReentrant
+extern __typeof (xmlEncodeEntitiesReentrant) xmlEncodeEntitiesReentrant __attribute((alias("xmlEncodeEntitiesReentrant__internal_alias")));
+#else
+#ifndef xmlEncodeEntitiesReentrant
+extern __typeof (xmlEncodeEntitiesReentrant) xmlEncodeEntitiesReentrant__internal_alias __attribute((visibility("hidden")));
+#define xmlEncodeEntitiesReentrant xmlEncodeEntitiesReentrant__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlEncodeSpecialChars
+extern __typeof (xmlEncodeSpecialChars) xmlEncodeSpecialChars __attribute((alias("xmlEncodeSpecialChars__internal_alias")));
+#else
+#ifndef xmlEncodeSpecialChars
+extern __typeof (xmlEncodeSpecialChars) xmlEncodeSpecialChars__internal_alias __attribute((visibility("hidden")));
+#define xmlEncodeSpecialChars xmlEncodeSpecialChars__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlErrMemory
+extern __typeof (xmlErrMemory) xmlErrMemory __attribute((alias("xmlErrMemory__internal_alias")));
+#else
+#ifndef xmlErrMemory
+extern __typeof (xmlErrMemory) xmlErrMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlErrMemory xmlErrMemory__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpCtxtNbCons
+extern __typeof (xmlExpCtxtNbCons) xmlExpCtxtNbCons __attribute((alias("xmlExpCtxtNbCons__internal_alias")));
+#else
+#ifndef xmlExpCtxtNbCons
+extern __typeof (xmlExpCtxtNbCons) xmlExpCtxtNbCons__internal_alias __attribute((visibility("hidden")));
+#define xmlExpCtxtNbCons xmlExpCtxtNbCons__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpCtxtNbNodes
+extern __typeof (xmlExpCtxtNbNodes) xmlExpCtxtNbNodes __attribute((alias("xmlExpCtxtNbNodes__internal_alias")));
+#else
+#ifndef xmlExpCtxtNbNodes
+extern __typeof (xmlExpCtxtNbNodes) xmlExpCtxtNbNodes__internal_alias __attribute((visibility("hidden")));
+#define xmlExpCtxtNbNodes xmlExpCtxtNbNodes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpDump
+extern __typeof (xmlExpDump) xmlExpDump __attribute((alias("xmlExpDump__internal_alias")));
+#else
+#ifndef xmlExpDump
+extern __typeof (xmlExpDump) xmlExpDump__internal_alias __attribute((visibility("hidden")));
+#define xmlExpDump xmlExpDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpExpDerive
+extern __typeof (xmlExpExpDerive) xmlExpExpDerive __attribute((alias("xmlExpExpDerive__internal_alias")));
+#else
+#ifndef xmlExpExpDerive
+extern __typeof (xmlExpExpDerive) xmlExpExpDerive__internal_alias __attribute((visibility("hidden")));
+#define xmlExpExpDerive xmlExpExpDerive__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpFree
+extern __typeof (xmlExpFree) xmlExpFree __attribute((alias("xmlExpFree__internal_alias")));
+#else
+#ifndef xmlExpFree
+extern __typeof (xmlExpFree) xmlExpFree__internal_alias __attribute((visibility("hidden")));
+#define xmlExpFree xmlExpFree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpFreeCtxt
+extern __typeof (xmlExpFreeCtxt) xmlExpFreeCtxt __attribute((alias("xmlExpFreeCtxt__internal_alias")));
+#else
+#ifndef xmlExpFreeCtxt
+extern __typeof (xmlExpFreeCtxt) xmlExpFreeCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlExpFreeCtxt xmlExpFreeCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpGetLanguage
+extern __typeof (xmlExpGetLanguage) xmlExpGetLanguage __attribute((alias("xmlExpGetLanguage__internal_alias")));
+#else
+#ifndef xmlExpGetLanguage
+extern __typeof (xmlExpGetLanguage) xmlExpGetLanguage__internal_alias __attribute((visibility("hidden")));
+#define xmlExpGetLanguage xmlExpGetLanguage__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpGetStart
+extern __typeof (xmlExpGetStart) xmlExpGetStart __attribute((alias("xmlExpGetStart__internal_alias")));
+#else
+#ifndef xmlExpGetStart
+extern __typeof (xmlExpGetStart) xmlExpGetStart__internal_alias __attribute((visibility("hidden")));
+#define xmlExpGetStart xmlExpGetStart__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpIsNillable
+extern __typeof (xmlExpIsNillable) xmlExpIsNillable __attribute((alias("xmlExpIsNillable__internal_alias")));
+#else
+#ifndef xmlExpIsNillable
+extern __typeof (xmlExpIsNillable) xmlExpIsNillable__internal_alias __attribute((visibility("hidden")));
+#define xmlExpIsNillable xmlExpIsNillable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpMaxToken
+extern __typeof (xmlExpMaxToken) xmlExpMaxToken __attribute((alias("xmlExpMaxToken__internal_alias")));
+#else
+#ifndef xmlExpMaxToken
+extern __typeof (xmlExpMaxToken) xmlExpMaxToken__internal_alias __attribute((visibility("hidden")));
+#define xmlExpMaxToken xmlExpMaxToken__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpNewAtom
+extern __typeof (xmlExpNewAtom) xmlExpNewAtom __attribute((alias("xmlExpNewAtom__internal_alias")));
+#else
+#ifndef xmlExpNewAtom
+extern __typeof (xmlExpNewAtom) xmlExpNewAtom__internal_alias __attribute((visibility("hidden")));
+#define xmlExpNewAtom xmlExpNewAtom__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpNewCtxt
+extern __typeof (xmlExpNewCtxt) xmlExpNewCtxt __attribute((alias("xmlExpNewCtxt__internal_alias")));
+#else
+#ifndef xmlExpNewCtxt
+extern __typeof (xmlExpNewCtxt) xmlExpNewCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlExpNewCtxt xmlExpNewCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpNewOr
+extern __typeof (xmlExpNewOr) xmlExpNewOr __attribute((alias("xmlExpNewOr__internal_alias")));
+#else
+#ifndef xmlExpNewOr
+extern __typeof (xmlExpNewOr) xmlExpNewOr__internal_alias __attribute((visibility("hidden")));
+#define xmlExpNewOr xmlExpNewOr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpNewRange
+extern __typeof (xmlExpNewRange) xmlExpNewRange __attribute((alias("xmlExpNewRange__internal_alias")));
+#else
+#ifndef xmlExpNewRange
+extern __typeof (xmlExpNewRange) xmlExpNewRange__internal_alias __attribute((visibility("hidden")));
+#define xmlExpNewRange xmlExpNewRange__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpNewSeq
+extern __typeof (xmlExpNewSeq) xmlExpNewSeq __attribute((alias("xmlExpNewSeq__internal_alias")));
+#else
+#ifndef xmlExpNewSeq
+extern __typeof (xmlExpNewSeq) xmlExpNewSeq__internal_alias __attribute((visibility("hidden")));
+#define xmlExpNewSeq xmlExpNewSeq__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpParse
+extern __typeof (xmlExpParse) xmlExpParse __attribute((alias("xmlExpParse__internal_alias")));
+#else
+#ifndef xmlExpParse
+extern __typeof (xmlExpParse) xmlExpParse__internal_alias __attribute((visibility("hidden")));
+#define xmlExpParse xmlExpParse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpRef
+extern __typeof (xmlExpRef) xmlExpRef __attribute((alias("xmlExpRef__internal_alias")));
+#else
+#ifndef xmlExpRef
+extern __typeof (xmlExpRef) xmlExpRef__internal_alias __attribute((visibility("hidden")));
+#define xmlExpRef xmlExpRef__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpStringDerive
+extern __typeof (xmlExpStringDerive) xmlExpStringDerive __attribute((alias("xmlExpStringDerive__internal_alias")));
+#else
+#ifndef xmlExpStringDerive
+extern __typeof (xmlExpStringDerive) xmlExpStringDerive__internal_alias __attribute((visibility("hidden")));
+#define xmlExpStringDerive xmlExpStringDerive__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlExpSubsume
+extern __typeof (xmlExpSubsume) xmlExpSubsume __attribute((alias("xmlExpSubsume__internal_alias")));
+#else
+#ifndef xmlExpSubsume
+extern __typeof (xmlExpSubsume) xmlExpSubsume__internal_alias __attribute((visibility("hidden")));
+#define xmlExpSubsume xmlExpSubsume__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlFileClose
+extern __typeof (xmlFileClose) xmlFileClose __attribute((alias("xmlFileClose__internal_alias")));
+#else
+#ifndef xmlFileClose
+extern __typeof (xmlFileClose) xmlFileClose__internal_alias __attribute((visibility("hidden")));
+#define xmlFileClose xmlFileClose__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlFileMatch
+extern __typeof (xmlFileMatch) xmlFileMatch __attribute((alias("xmlFileMatch__internal_alias")));
+#else
+#ifndef xmlFileMatch
+extern __typeof (xmlFileMatch) xmlFileMatch__internal_alias __attribute((visibility("hidden")));
+#define xmlFileMatch xmlFileMatch__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlFileOpen
+extern __typeof (xmlFileOpen) xmlFileOpen __attribute((alias("xmlFileOpen__internal_alias")));
+#else
+#ifndef xmlFileOpen
+extern __typeof (xmlFileOpen) xmlFileOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlFileOpen xmlFileOpen__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlFileRead
+extern __typeof (xmlFileRead) xmlFileRead __attribute((alias("xmlFileRead__internal_alias")));
+#else
+#ifndef xmlFileRead
+extern __typeof (xmlFileRead) xmlFileRead__internal_alias __attribute((visibility("hidden")));
+#define xmlFileRead xmlFileRead__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlFindCharEncodingHandler
+extern __typeof (xmlFindCharEncodingHandler) xmlFindCharEncodingHandler __attribute((alias("xmlFindCharEncodingHandler__internal_alias")));
+#else
+#ifndef xmlFindCharEncodingHandler
+extern __typeof (xmlFindCharEncodingHandler) xmlFindCharEncodingHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlFindCharEncodingHandler xmlFindCharEncodingHandler__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlFirstElementChild
+extern __typeof (xmlFirstElementChild) xmlFirstElementChild __attribute((alias("xmlFirstElementChild__internal_alias")));
+#else
+#ifndef xmlFirstElementChild
+extern __typeof (xmlFirstElementChild) xmlFirstElementChild__internal_alias __attribute((visibility("hidden")));
+#define xmlFirstElementChild xmlFirstElementChild__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeAttributeTable
+extern __typeof (xmlFreeAttributeTable) xmlFreeAttributeTable __attribute((alias("xmlFreeAttributeTable__internal_alias")));
+#else
+#ifndef xmlFreeAttributeTable
+extern __typeof (xmlFreeAttributeTable) xmlFreeAttributeTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeAttributeTable xmlFreeAttributeTable__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlFreeAutomata
+extern __typeof (xmlFreeAutomata) xmlFreeAutomata __attribute((alias("xmlFreeAutomata__internal_alias")));
+#else
+#ifndef xmlFreeAutomata
+extern __typeof (xmlFreeAutomata) xmlFreeAutomata__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeAutomata xmlFreeAutomata__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlFreeCatalog
+extern __typeof (xmlFreeCatalog) xmlFreeCatalog __attribute((alias("xmlFreeCatalog__internal_alias")));
+#else
+#ifndef xmlFreeCatalog
+extern __typeof (xmlFreeCatalog) xmlFreeCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeCatalog xmlFreeCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeDoc
+extern __typeof (xmlFreeDoc) xmlFreeDoc __attribute((alias("xmlFreeDoc__internal_alias")));
+#else
+#ifndef xmlFreeDoc
+extern __typeof (xmlFreeDoc) xmlFreeDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeDoc xmlFreeDoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeDocElementContent
+extern __typeof (xmlFreeDocElementContent) xmlFreeDocElementContent __attribute((alias("xmlFreeDocElementContent__internal_alias")));
+#else
+#ifndef xmlFreeDocElementContent
+extern __typeof (xmlFreeDocElementContent) xmlFreeDocElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeDocElementContent xmlFreeDocElementContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeDtd
+extern __typeof (xmlFreeDtd) xmlFreeDtd __attribute((alias("xmlFreeDtd__internal_alias")));
+#else
+#ifndef xmlFreeDtd
+extern __typeof (xmlFreeDtd) xmlFreeDtd__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeDtd xmlFreeDtd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeElementContent
+extern __typeof (xmlFreeElementContent) xmlFreeElementContent __attribute((alias("xmlFreeElementContent__internal_alias")));
+#else
+#ifndef xmlFreeElementContent
+extern __typeof (xmlFreeElementContent) xmlFreeElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeElementContent xmlFreeElementContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeElementTable
+extern __typeof (xmlFreeElementTable) xmlFreeElementTable __attribute((alias("xmlFreeElementTable__internal_alias")));
+#else
+#ifndef xmlFreeElementTable
+extern __typeof (xmlFreeElementTable) xmlFreeElementTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeElementTable xmlFreeElementTable__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlFreeEntitiesTable
+extern __typeof (xmlFreeEntitiesTable) xmlFreeEntitiesTable __attribute((alias("xmlFreeEntitiesTable__internal_alias")));
+#else
+#ifndef xmlFreeEntitiesTable
+extern __typeof (xmlFreeEntitiesTable) xmlFreeEntitiesTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeEntitiesTable xmlFreeEntitiesTable__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeEnumeration
+extern __typeof (xmlFreeEnumeration) xmlFreeEnumeration __attribute((alias("xmlFreeEnumeration__internal_alias")));
+#else
+#ifndef xmlFreeEnumeration
+extern __typeof (xmlFreeEnumeration) xmlFreeEnumeration__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeEnumeration xmlFreeEnumeration__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeIDTable
+extern __typeof (xmlFreeIDTable) xmlFreeIDTable __attribute((alias("xmlFreeIDTable__internal_alias")));
+#else
+#ifndef xmlFreeIDTable
+extern __typeof (xmlFreeIDTable) xmlFreeIDTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeIDTable xmlFreeIDTable__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlFreeInputStream
+extern __typeof (xmlFreeInputStream) xmlFreeInputStream __attribute((alias("xmlFreeInputStream__internal_alias")));
+#else
+#ifndef xmlFreeInputStream
+extern __typeof (xmlFreeInputStream) xmlFreeInputStream__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeInputStream xmlFreeInputStream__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlFreeMutex
+extern __typeof (xmlFreeMutex) xmlFreeMutex __attribute((alias("xmlFreeMutex__internal_alias")));
+#else
+#ifndef xmlFreeMutex
+extern __typeof (xmlFreeMutex) xmlFreeMutex__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeMutex xmlFreeMutex__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeNode
+extern __typeof (xmlFreeNode) xmlFreeNode __attribute((alias("xmlFreeNode__internal_alias")));
+#else
+#ifndef xmlFreeNode
+extern __typeof (xmlFreeNode) xmlFreeNode__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeNode xmlFreeNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeNodeList
+extern __typeof (xmlFreeNodeList) xmlFreeNodeList __attribute((alias("xmlFreeNodeList__internal_alias")));
+#else
+#ifndef xmlFreeNodeList
+extern __typeof (xmlFreeNodeList) xmlFreeNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeNodeList xmlFreeNodeList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeNotationTable
+extern __typeof (xmlFreeNotationTable) xmlFreeNotationTable __attribute((alias("xmlFreeNotationTable__internal_alias")));
+#else
+#ifndef xmlFreeNotationTable
+extern __typeof (xmlFreeNotationTable) xmlFreeNotationTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeNotationTable xmlFreeNotationTable__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeNs
+extern __typeof (xmlFreeNs) xmlFreeNs __attribute((alias("xmlFreeNs__internal_alias")));
+#else
+#ifndef xmlFreeNs
+extern __typeof (xmlFreeNs) xmlFreeNs__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeNs xmlFreeNs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeNsList
+extern __typeof (xmlFreeNsList) xmlFreeNsList __attribute((alias("xmlFreeNsList__internal_alias")));
+#else
+#ifndef xmlFreeNsList
+extern __typeof (xmlFreeNsList) xmlFreeNsList__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeNsList xmlFreeNsList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlFreeParserCtxt
+extern __typeof (xmlFreeParserCtxt) xmlFreeParserCtxt __attribute((alias("xmlFreeParserCtxt__internal_alias")));
+#else
+#ifndef xmlFreeParserCtxt
+extern __typeof (xmlFreeParserCtxt) xmlFreeParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeParserCtxt xmlFreeParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlFreeParserInputBuffer
+extern __typeof (xmlFreeParserInputBuffer) xmlFreeParserInputBuffer __attribute((alias("xmlFreeParserInputBuffer__internal_alias")));
+#else
+#ifndef xmlFreeParserInputBuffer
+extern __typeof (xmlFreeParserInputBuffer) xmlFreeParserInputBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeParserInputBuffer xmlFreeParserInputBuffer__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlFreePattern
+extern __typeof (xmlFreePattern) xmlFreePattern __attribute((alias("xmlFreePattern__internal_alias")));
+#else
+#ifndef xmlFreePattern
+extern __typeof (xmlFreePattern) xmlFreePattern__internal_alias __attribute((visibility("hidden")));
+#define xmlFreePattern xmlFreePattern__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlFreePatternList
+extern __typeof (xmlFreePatternList) xmlFreePatternList __attribute((alias("xmlFreePatternList__internal_alias")));
+#else
+#ifndef xmlFreePatternList
+extern __typeof (xmlFreePatternList) xmlFreePatternList__internal_alias __attribute((visibility("hidden")));
+#define xmlFreePatternList xmlFreePatternList__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreeProp
+extern __typeof (xmlFreeProp) xmlFreeProp __attribute((alias("xmlFreeProp__internal_alias")));
+#else
+#ifndef xmlFreeProp
+extern __typeof (xmlFreeProp) xmlFreeProp__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeProp xmlFreeProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlFreePropList
+extern __typeof (xmlFreePropList) xmlFreePropList __attribute((alias("xmlFreePropList__internal_alias")));
+#else
+#ifndef xmlFreePropList
+extern __typeof (xmlFreePropList) xmlFreePropList__internal_alias __attribute((visibility("hidden")));
+#define xmlFreePropList xmlFreePropList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlFreeRMutex
+extern __typeof (xmlFreeRMutex) xmlFreeRMutex __attribute((alias("xmlFreeRMutex__internal_alias")));
+#else
+#ifndef xmlFreeRMutex
+extern __typeof (xmlFreeRMutex) xmlFreeRMutex__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeRMutex xmlFreeRMutex__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlFreeRefTable
+extern __typeof (xmlFreeRefTable) xmlFreeRefTable __attribute((alias("xmlFreeRefTable__internal_alias")));
+#else
+#ifndef xmlFreeRefTable
+extern __typeof (xmlFreeRefTable) xmlFreeRefTable__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeRefTable xmlFreeRefTable__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlFreeStreamCtxt
+extern __typeof (xmlFreeStreamCtxt) xmlFreeStreamCtxt __attribute((alias("xmlFreeStreamCtxt__internal_alias")));
+#else
+#ifndef xmlFreeStreamCtxt
+extern __typeof (xmlFreeStreamCtxt) xmlFreeStreamCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeStreamCtxt xmlFreeStreamCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlFreeTextReader
+extern __typeof (xmlFreeTextReader) xmlFreeTextReader __attribute((alias("xmlFreeTextReader__internal_alias")));
+#else
+#ifndef xmlFreeTextReader
+extern __typeof (xmlFreeTextReader) xmlFreeTextReader__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeTextReader xmlFreeTextReader__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlFreeTextWriter
+extern __typeof (xmlFreeTextWriter) xmlFreeTextWriter __attribute((alias("xmlFreeTextWriter__internal_alias")));
+#else
+#ifndef xmlFreeTextWriter
+extern __typeof (xmlFreeTextWriter) xmlFreeTextWriter__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeTextWriter xmlFreeTextWriter__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlFreeURI
+extern __typeof (xmlFreeURI) xmlFreeURI __attribute((alias("xmlFreeURI__internal_alias")));
+#else
+#ifndef xmlFreeURI
+extern __typeof (xmlFreeURI) xmlFreeURI__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeURI xmlFreeURI__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlFreeValidCtxt
+extern __typeof (xmlFreeValidCtxt) xmlFreeValidCtxt __attribute((alias("xmlFreeValidCtxt__internal_alias")));
+#else
+#ifndef xmlFreeValidCtxt
+extern __typeof (xmlFreeValidCtxt) xmlFreeValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlFreeValidCtxt xmlFreeValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlGcMemGet
+extern __typeof (xmlGcMemGet) xmlGcMemGet __attribute((alias("xmlGcMemGet__internal_alias")));
+#else
+#ifndef xmlGcMemGet
+extern __typeof (xmlGcMemGet) xmlGcMemGet__internal_alias __attribute((visibility("hidden")));
+#define xmlGcMemGet xmlGcMemGet__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlGcMemSetup
+extern __typeof (xmlGcMemSetup) xmlGcMemSetup __attribute((alias("xmlGcMemSetup__internal_alias")));
+#else
+#ifndef xmlGcMemSetup
+extern __typeof (xmlGcMemSetup) xmlGcMemSetup__internal_alias __attribute((visibility("hidden")));
+#define xmlGcMemSetup xmlGcMemSetup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetBufferAllocationScheme
+extern __typeof (xmlGetBufferAllocationScheme) xmlGetBufferAllocationScheme __attribute((alias("xmlGetBufferAllocationScheme__internal_alias")));
+#else
+#ifndef xmlGetBufferAllocationScheme
+extern __typeof (xmlGetBufferAllocationScheme) xmlGetBufferAllocationScheme__internal_alias __attribute((visibility("hidden")));
+#define xmlGetBufferAllocationScheme xmlGetBufferAllocationScheme__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlGetCharEncodingHandler
+extern __typeof (xmlGetCharEncodingHandler) xmlGetCharEncodingHandler __attribute((alias("xmlGetCharEncodingHandler__internal_alias")));
+#else
+#ifndef xmlGetCharEncodingHandler
+extern __typeof (xmlGetCharEncodingHandler) xmlGetCharEncodingHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlGetCharEncodingHandler xmlGetCharEncodingHandler__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlGetCharEncodingName
+extern __typeof (xmlGetCharEncodingName) xmlGetCharEncodingName __attribute((alias("xmlGetCharEncodingName__internal_alias")));
+#else
+#ifndef xmlGetCharEncodingName
+extern __typeof (xmlGetCharEncodingName) xmlGetCharEncodingName__internal_alias __attribute((visibility("hidden")));
+#define xmlGetCharEncodingName xmlGetCharEncodingName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetCompressMode
+extern __typeof (xmlGetCompressMode) xmlGetCompressMode __attribute((alias("xmlGetCompressMode__internal_alias")));
+#else
+#ifndef xmlGetCompressMode
+extern __typeof (xmlGetCompressMode) xmlGetCompressMode__internal_alias __attribute((visibility("hidden")));
+#define xmlGetCompressMode xmlGetCompressMode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetDocCompressMode
+extern __typeof (xmlGetDocCompressMode) xmlGetDocCompressMode __attribute((alias("xmlGetDocCompressMode__internal_alias")));
+#else
+#ifndef xmlGetDocCompressMode
+extern __typeof (xmlGetDocCompressMode) xmlGetDocCompressMode__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDocCompressMode xmlGetDocCompressMode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlGetDocEntity
+extern __typeof (xmlGetDocEntity) xmlGetDocEntity __attribute((alias("xmlGetDocEntity__internal_alias")));
+#else
+#ifndef xmlGetDocEntity
+extern __typeof (xmlGetDocEntity) xmlGetDocEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDocEntity xmlGetDocEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetDtdAttrDesc
+extern __typeof (xmlGetDtdAttrDesc) xmlGetDtdAttrDesc __attribute((alias("xmlGetDtdAttrDesc__internal_alias")));
+#else
+#ifndef xmlGetDtdAttrDesc
+extern __typeof (xmlGetDtdAttrDesc) xmlGetDtdAttrDesc__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdAttrDesc xmlGetDtdAttrDesc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetDtdElementDesc
+extern __typeof (xmlGetDtdElementDesc) xmlGetDtdElementDesc __attribute((alias("xmlGetDtdElementDesc__internal_alias")));
+#else
+#ifndef xmlGetDtdElementDesc
+extern __typeof (xmlGetDtdElementDesc) xmlGetDtdElementDesc__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdElementDesc xmlGetDtdElementDesc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlGetDtdEntity
+extern __typeof (xmlGetDtdEntity) xmlGetDtdEntity __attribute((alias("xmlGetDtdEntity__internal_alias")));
+#else
+#ifndef xmlGetDtdEntity
+extern __typeof (xmlGetDtdEntity) xmlGetDtdEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdEntity xmlGetDtdEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetDtdNotationDesc
+extern __typeof (xmlGetDtdNotationDesc) xmlGetDtdNotationDesc __attribute((alias("xmlGetDtdNotationDesc__internal_alias")));
+#else
+#ifndef xmlGetDtdNotationDesc
+extern __typeof (xmlGetDtdNotationDesc) xmlGetDtdNotationDesc__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdNotationDesc xmlGetDtdNotationDesc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetDtdQAttrDesc
+extern __typeof (xmlGetDtdQAttrDesc) xmlGetDtdQAttrDesc __attribute((alias("xmlGetDtdQAttrDesc__internal_alias")));
+#else
+#ifndef xmlGetDtdQAttrDesc
+extern __typeof (xmlGetDtdQAttrDesc) xmlGetDtdQAttrDesc__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdQAttrDesc xmlGetDtdQAttrDesc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetDtdQElementDesc
+extern __typeof (xmlGetDtdQElementDesc) xmlGetDtdQElementDesc __attribute((alias("xmlGetDtdQElementDesc__internal_alias")));
+#else
+#ifndef xmlGetDtdQElementDesc
+extern __typeof (xmlGetDtdQElementDesc) xmlGetDtdQElementDesc__internal_alias __attribute((visibility("hidden")));
+#define xmlGetDtdQElementDesc xmlGetDtdQElementDesc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlGetEncodingAlias
+extern __typeof (xmlGetEncodingAlias) xmlGetEncodingAlias __attribute((alias("xmlGetEncodingAlias__internal_alias")));
+#else
+#ifndef xmlGetEncodingAlias
+extern __typeof (xmlGetEncodingAlias) xmlGetEncodingAlias__internal_alias __attribute((visibility("hidden")));
+#define xmlGetEncodingAlias xmlGetEncodingAlias__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlGetExternalEntityLoader
+extern __typeof (xmlGetExternalEntityLoader) xmlGetExternalEntityLoader __attribute((alias("xmlGetExternalEntityLoader__internal_alias")));
+#else
+#ifndef xmlGetExternalEntityLoader
+extern __typeof (xmlGetExternalEntityLoader) xmlGetExternalEntityLoader__internal_alias __attribute((visibility("hidden")));
+#define xmlGetExternalEntityLoader xmlGetExternalEntityLoader__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlGetFeature
+extern __typeof (xmlGetFeature) xmlGetFeature __attribute((alias("xmlGetFeature__internal_alias")));
+#else
+#ifndef xmlGetFeature
+extern __typeof (xmlGetFeature) xmlGetFeature__internal_alias __attribute((visibility("hidden")));
+#define xmlGetFeature xmlGetFeature__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlGetFeaturesList
+extern __typeof (xmlGetFeaturesList) xmlGetFeaturesList __attribute((alias("xmlGetFeaturesList__internal_alias")));
+#else
+#ifndef xmlGetFeaturesList
+extern __typeof (xmlGetFeaturesList) xmlGetFeaturesList__internal_alias __attribute((visibility("hidden")));
+#define xmlGetFeaturesList xmlGetFeaturesList__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlGetGlobalState
+extern __typeof (xmlGetGlobalState) xmlGetGlobalState __attribute((alias("xmlGetGlobalState__internal_alias")));
+#else
+#ifndef xmlGetGlobalState
+extern __typeof (xmlGetGlobalState) xmlGetGlobalState__internal_alias __attribute((visibility("hidden")));
+#define xmlGetGlobalState xmlGetGlobalState__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetID
+extern __typeof (xmlGetID) xmlGetID __attribute((alias("xmlGetID__internal_alias")));
+#else
+#ifndef xmlGetID
+extern __typeof (xmlGetID) xmlGetID__internal_alias __attribute((visibility("hidden")));
+#define xmlGetID xmlGetID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetIntSubset
+extern __typeof (xmlGetIntSubset) xmlGetIntSubset __attribute((alias("xmlGetIntSubset__internal_alias")));
+#else
+#ifndef xmlGetIntSubset
+extern __typeof (xmlGetIntSubset) xmlGetIntSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlGetIntSubset xmlGetIntSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetLastChild
+extern __typeof (xmlGetLastChild) xmlGetLastChild __attribute((alias("xmlGetLastChild__internal_alias")));
+#else
+#ifndef xmlGetLastChild
+extern __typeof (xmlGetLastChild) xmlGetLastChild__internal_alias __attribute((visibility("hidden")));
+#define xmlGetLastChild xmlGetLastChild__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlGetLastError
+extern __typeof (xmlGetLastError) xmlGetLastError __attribute((alias("xmlGetLastError__internal_alias")));
+#else
+#ifndef xmlGetLastError
+extern __typeof (xmlGetLastError) xmlGetLastError__internal_alias __attribute((visibility("hidden")));
+#define xmlGetLastError xmlGetLastError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetLineNo
+extern __typeof (xmlGetLineNo) xmlGetLineNo __attribute((alias("xmlGetLineNo__internal_alias")));
+#else
+#ifndef xmlGetLineNo
+extern __typeof (xmlGetLineNo) xmlGetLineNo__internal_alias __attribute((visibility("hidden")));
+#define xmlGetLineNo xmlGetLineNo__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetNoNsProp
+extern __typeof (xmlGetNoNsProp) xmlGetNoNsProp __attribute((alias("xmlGetNoNsProp__internal_alias")));
+#else
+#ifndef xmlGetNoNsProp
+extern __typeof (xmlGetNoNsProp) xmlGetNoNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlGetNoNsProp xmlGetNoNsProp__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_tree
+#undef xmlGetNodePath
+extern __typeof (xmlGetNodePath) xmlGetNodePath __attribute((alias("xmlGetNodePath__internal_alias")));
+#else
+#ifndef xmlGetNodePath
+extern __typeof (xmlGetNodePath) xmlGetNodePath__internal_alias __attribute((visibility("hidden")));
+#define xmlGetNodePath xmlGetNodePath__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlGetNsList
+extern __typeof (xmlGetNsList) xmlGetNsList __attribute((alias("xmlGetNsList__internal_alias")));
+#else
+#ifndef xmlGetNsList
+extern __typeof (xmlGetNsList) xmlGetNsList__internal_alias __attribute((visibility("hidden")));
+#define xmlGetNsList xmlGetNsList__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetNsProp
+extern __typeof (xmlGetNsProp) xmlGetNsProp __attribute((alias("xmlGetNsProp__internal_alias")));
+#else
+#ifndef xmlGetNsProp
+extern __typeof (xmlGetNsProp) xmlGetNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlGetNsProp xmlGetNsProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlGetParameterEntity
+extern __typeof (xmlGetParameterEntity) xmlGetParameterEntity __attribute((alias("xmlGetParameterEntity__internal_alias")));
+#else
+#ifndef xmlGetParameterEntity
+extern __typeof (xmlGetParameterEntity) xmlGetParameterEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlGetParameterEntity xmlGetParameterEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlGetPredefinedEntity
+extern __typeof (xmlGetPredefinedEntity) xmlGetPredefinedEntity __attribute((alias("xmlGetPredefinedEntity__internal_alias")));
+#else
+#ifndef xmlGetPredefinedEntity
+extern __typeof (xmlGetPredefinedEntity) xmlGetPredefinedEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlGetPredefinedEntity xmlGetPredefinedEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlGetProp
+extern __typeof (xmlGetProp) xmlGetProp __attribute((alias("xmlGetProp__internal_alias")));
+#else
+#ifndef xmlGetProp
+extern __typeof (xmlGetProp) xmlGetProp__internal_alias __attribute((visibility("hidden")));
+#define xmlGetProp xmlGetProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlGetRefs
+extern __typeof (xmlGetRefs) xmlGetRefs __attribute((alias("xmlGetRefs__internal_alias")));
+#else
+#ifndef xmlGetRefs
+extern __typeof (xmlGetRefs) xmlGetRefs__internal_alias __attribute((visibility("hidden")));
+#define xmlGetRefs xmlGetRefs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlGetThreadId
+extern __typeof (xmlGetThreadId) xmlGetThreadId __attribute((alias("xmlGetThreadId__internal_alias")));
+#else
+#ifndef xmlGetThreadId
+extern __typeof (xmlGetThreadId) xmlGetThreadId__internal_alias __attribute((visibility("hidden")));
+#define xmlGetThreadId xmlGetThreadId__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlGetUTF8Char
+extern __typeof (xmlGetUTF8Char) xmlGetUTF8Char __attribute((alias("xmlGetUTF8Char__internal_alias")));
+#else
+#ifndef xmlGetUTF8Char
+extern __typeof (xmlGetUTF8Char) xmlGetUTF8Char__internal_alias __attribute((visibility("hidden")));
+#define xmlGetUTF8Char xmlGetUTF8Char__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlHandleEntity
+extern __typeof (xmlHandleEntity) xmlHandleEntity __attribute((alias("xmlHandleEntity__internal_alias")));
+#else
+#ifndef xmlHandleEntity
+extern __typeof (xmlHandleEntity) xmlHandleEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlHandleEntity xmlHandleEntity__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlHasFeature
+extern __typeof (xmlHasFeature) xmlHasFeature __attribute((alias("xmlHasFeature__internal_alias")));
+#else
+#ifndef xmlHasFeature
+extern __typeof (xmlHasFeature) xmlHasFeature__internal_alias __attribute((visibility("hidden")));
+#define xmlHasFeature xmlHasFeature__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlHasNsProp
+extern __typeof (xmlHasNsProp) xmlHasNsProp __attribute((alias("xmlHasNsProp__internal_alias")));
+#else
+#ifndef xmlHasNsProp
+extern __typeof (xmlHasNsProp) xmlHasNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlHasNsProp xmlHasNsProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlHasProp
+extern __typeof (xmlHasProp) xmlHasProp __attribute((alias("xmlHasProp__internal_alias")));
+#else
+#ifndef xmlHasProp
+extern __typeof (xmlHasProp) xmlHasProp__internal_alias __attribute((visibility("hidden")));
+#define xmlHasProp xmlHasProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashAddEntry
+extern __typeof (xmlHashAddEntry) xmlHashAddEntry __attribute((alias("xmlHashAddEntry__internal_alias")));
+#else
+#ifndef xmlHashAddEntry
+extern __typeof (xmlHashAddEntry) xmlHashAddEntry__internal_alias __attribute((visibility("hidden")));
+#define xmlHashAddEntry xmlHashAddEntry__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashAddEntry2
+extern __typeof (xmlHashAddEntry2) xmlHashAddEntry2 __attribute((alias("xmlHashAddEntry2__internal_alias")));
+#else
+#ifndef xmlHashAddEntry2
+extern __typeof (xmlHashAddEntry2) xmlHashAddEntry2__internal_alias __attribute((visibility("hidden")));
+#define xmlHashAddEntry2 xmlHashAddEntry2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashAddEntry3
+extern __typeof (xmlHashAddEntry3) xmlHashAddEntry3 __attribute((alias("xmlHashAddEntry3__internal_alias")));
+#else
+#ifndef xmlHashAddEntry3
+extern __typeof (xmlHashAddEntry3) xmlHashAddEntry3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashAddEntry3 xmlHashAddEntry3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashCopy
+extern __typeof (xmlHashCopy) xmlHashCopy __attribute((alias("xmlHashCopy__internal_alias")));
+#else
+#ifndef xmlHashCopy
+extern __typeof (xmlHashCopy) xmlHashCopy__internal_alias __attribute((visibility("hidden")));
+#define xmlHashCopy xmlHashCopy__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashCreate
+extern __typeof (xmlHashCreate) xmlHashCreate __attribute((alias("xmlHashCreate__internal_alias")));
+#else
+#ifndef xmlHashCreate
+extern __typeof (xmlHashCreate) xmlHashCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlHashCreate xmlHashCreate__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashCreateDict
+extern __typeof (xmlHashCreateDict) xmlHashCreateDict __attribute((alias("xmlHashCreateDict__internal_alias")));
+#else
+#ifndef xmlHashCreateDict
+extern __typeof (xmlHashCreateDict) xmlHashCreateDict__internal_alias __attribute((visibility("hidden")));
+#define xmlHashCreateDict xmlHashCreateDict__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashFree
+extern __typeof (xmlHashFree) xmlHashFree __attribute((alias("xmlHashFree__internal_alias")));
+#else
+#ifndef xmlHashFree
+extern __typeof (xmlHashFree) xmlHashFree__internal_alias __attribute((visibility("hidden")));
+#define xmlHashFree xmlHashFree__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashLookup
+extern __typeof (xmlHashLookup) xmlHashLookup __attribute((alias("xmlHashLookup__internal_alias")));
+#else
+#ifndef xmlHashLookup
+extern __typeof (xmlHashLookup) xmlHashLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlHashLookup xmlHashLookup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashLookup2
+extern __typeof (xmlHashLookup2) xmlHashLookup2 __attribute((alias("xmlHashLookup2__internal_alias")));
+#else
+#ifndef xmlHashLookup2
+extern __typeof (xmlHashLookup2) xmlHashLookup2__internal_alias __attribute((visibility("hidden")));
+#define xmlHashLookup2 xmlHashLookup2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashLookup3
+extern __typeof (xmlHashLookup3) xmlHashLookup3 __attribute((alias("xmlHashLookup3__internal_alias")));
+#else
+#ifndef xmlHashLookup3
+extern __typeof (xmlHashLookup3) xmlHashLookup3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashLookup3 xmlHashLookup3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashQLookup
+extern __typeof (xmlHashQLookup) xmlHashQLookup __attribute((alias("xmlHashQLookup__internal_alias")));
+#else
+#ifndef xmlHashQLookup
+extern __typeof (xmlHashQLookup) xmlHashQLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlHashQLookup xmlHashQLookup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashQLookup2
+extern __typeof (xmlHashQLookup2) xmlHashQLookup2 __attribute((alias("xmlHashQLookup2__internal_alias")));
+#else
+#ifndef xmlHashQLookup2
+extern __typeof (xmlHashQLookup2) xmlHashQLookup2__internal_alias __attribute((visibility("hidden")));
+#define xmlHashQLookup2 xmlHashQLookup2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashQLookup3
+extern __typeof (xmlHashQLookup3) xmlHashQLookup3 __attribute((alias("xmlHashQLookup3__internal_alias")));
+#else
+#ifndef xmlHashQLookup3
+extern __typeof (xmlHashQLookup3) xmlHashQLookup3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashQLookup3 xmlHashQLookup3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashRemoveEntry
+extern __typeof (xmlHashRemoveEntry) xmlHashRemoveEntry __attribute((alias("xmlHashRemoveEntry__internal_alias")));
+#else
+#ifndef xmlHashRemoveEntry
+extern __typeof (xmlHashRemoveEntry) xmlHashRemoveEntry__internal_alias __attribute((visibility("hidden")));
+#define xmlHashRemoveEntry xmlHashRemoveEntry__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashRemoveEntry2
+extern __typeof (xmlHashRemoveEntry2) xmlHashRemoveEntry2 __attribute((alias("xmlHashRemoveEntry2__internal_alias")));
+#else
+#ifndef xmlHashRemoveEntry2
+extern __typeof (xmlHashRemoveEntry2) xmlHashRemoveEntry2__internal_alias __attribute((visibility("hidden")));
+#define xmlHashRemoveEntry2 xmlHashRemoveEntry2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashRemoveEntry3
+extern __typeof (xmlHashRemoveEntry3) xmlHashRemoveEntry3 __attribute((alias("xmlHashRemoveEntry3__internal_alias")));
+#else
+#ifndef xmlHashRemoveEntry3
+extern __typeof (xmlHashRemoveEntry3) xmlHashRemoveEntry3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashRemoveEntry3 xmlHashRemoveEntry3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashScan
+extern __typeof (xmlHashScan) xmlHashScan __attribute((alias("xmlHashScan__internal_alias")));
+#else
+#ifndef xmlHashScan
+extern __typeof (xmlHashScan) xmlHashScan__internal_alias __attribute((visibility("hidden")));
+#define xmlHashScan xmlHashScan__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashScan3
+extern __typeof (xmlHashScan3) xmlHashScan3 __attribute((alias("xmlHashScan3__internal_alias")));
+#else
+#ifndef xmlHashScan3
+extern __typeof (xmlHashScan3) xmlHashScan3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashScan3 xmlHashScan3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashScanFull
+extern __typeof (xmlHashScanFull) xmlHashScanFull __attribute((alias("xmlHashScanFull__internal_alias")));
+#else
+#ifndef xmlHashScanFull
+extern __typeof (xmlHashScanFull) xmlHashScanFull__internal_alias __attribute((visibility("hidden")));
+#define xmlHashScanFull xmlHashScanFull__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashScanFull3
+extern __typeof (xmlHashScanFull3) xmlHashScanFull3 __attribute((alias("xmlHashScanFull3__internal_alias")));
+#else
+#ifndef xmlHashScanFull3
+extern __typeof (xmlHashScanFull3) xmlHashScanFull3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashScanFull3 xmlHashScanFull3__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashSize
+extern __typeof (xmlHashSize) xmlHashSize __attribute((alias("xmlHashSize__internal_alias")));
+#else
+#ifndef xmlHashSize
+extern __typeof (xmlHashSize) xmlHashSize__internal_alias __attribute((visibility("hidden")));
+#define xmlHashSize xmlHashSize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashUpdateEntry
+extern __typeof (xmlHashUpdateEntry) xmlHashUpdateEntry __attribute((alias("xmlHashUpdateEntry__internal_alias")));
+#else
+#ifndef xmlHashUpdateEntry
+extern __typeof (xmlHashUpdateEntry) xmlHashUpdateEntry__internal_alias __attribute((visibility("hidden")));
+#define xmlHashUpdateEntry xmlHashUpdateEntry__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashUpdateEntry2
+extern __typeof (xmlHashUpdateEntry2) xmlHashUpdateEntry2 __attribute((alias("xmlHashUpdateEntry2__internal_alias")));
+#else
+#ifndef xmlHashUpdateEntry2
+extern __typeof (xmlHashUpdateEntry2) xmlHashUpdateEntry2__internal_alias __attribute((visibility("hidden")));
+#define xmlHashUpdateEntry2 xmlHashUpdateEntry2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
+#undef xmlHashUpdateEntry3
+extern __typeof (xmlHashUpdateEntry3) xmlHashUpdateEntry3 __attribute((alias("xmlHashUpdateEntry3__internal_alias")));
+#else
+#ifndef xmlHashUpdateEntry3
+extern __typeof (xmlHashUpdateEntry3) xmlHashUpdateEntry3__internal_alias __attribute((visibility("hidden")));
+#define xmlHashUpdateEntry3 xmlHashUpdateEntry3__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOFTPClose
+extern __typeof (xmlIOFTPClose) xmlIOFTPClose __attribute((alias("xmlIOFTPClose__internal_alias")));
+#else
+#ifndef xmlIOFTPClose
+extern __typeof (xmlIOFTPClose) xmlIOFTPClose__internal_alias __attribute((visibility("hidden")));
+#define xmlIOFTPClose xmlIOFTPClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOFTPMatch
+extern __typeof (xmlIOFTPMatch) xmlIOFTPMatch __attribute((alias("xmlIOFTPMatch__internal_alias")));
+#else
+#ifndef xmlIOFTPMatch
+extern __typeof (xmlIOFTPMatch) xmlIOFTPMatch__internal_alias __attribute((visibility("hidden")));
+#define xmlIOFTPMatch xmlIOFTPMatch__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOFTPOpen
+extern __typeof (xmlIOFTPOpen) xmlIOFTPOpen __attribute((alias("xmlIOFTPOpen__internal_alias")));
+#else
+#ifndef xmlIOFTPOpen
+extern __typeof (xmlIOFTPOpen) xmlIOFTPOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlIOFTPOpen xmlIOFTPOpen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOFTPRead
+extern __typeof (xmlIOFTPRead) xmlIOFTPRead __attribute((alias("xmlIOFTPRead__internal_alias")));
+#else
+#ifndef xmlIOFTPRead
+extern __typeof (xmlIOFTPRead) xmlIOFTPRead__internal_alias __attribute((visibility("hidden")));
+#define xmlIOFTPRead xmlIOFTPRead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOHTTPClose
+extern __typeof (xmlIOHTTPClose) xmlIOHTTPClose __attribute((alias("xmlIOHTTPClose__internal_alias")));
+#else
+#ifndef xmlIOHTTPClose
+extern __typeof (xmlIOHTTPClose) xmlIOHTTPClose__internal_alias __attribute((visibility("hidden")));
+#define xmlIOHTTPClose xmlIOHTTPClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOHTTPMatch
+extern __typeof (xmlIOHTTPMatch) xmlIOHTTPMatch __attribute((alias("xmlIOHTTPMatch__internal_alias")));
+#else
+#ifndef xmlIOHTTPMatch
+extern __typeof (xmlIOHTTPMatch) xmlIOHTTPMatch__internal_alias __attribute((visibility("hidden")));
+#define xmlIOHTTPMatch xmlIOHTTPMatch__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOHTTPOpen
+extern __typeof (xmlIOHTTPOpen) xmlIOHTTPOpen __attribute((alias("xmlIOHTTPOpen__internal_alias")));
+#else
+#ifndef xmlIOHTTPOpen
+extern __typeof (xmlIOHTTPOpen) xmlIOHTTPOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlIOHTTPOpen xmlIOHTTPOpen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOHTTPOpenW
+extern __typeof (xmlIOHTTPOpenW) xmlIOHTTPOpenW __attribute((alias("xmlIOHTTPOpenW__internal_alias")));
+#else
+#ifndef xmlIOHTTPOpenW
+extern __typeof (xmlIOHTTPOpenW) xmlIOHTTPOpenW__internal_alias __attribute((visibility("hidden")));
+#define xmlIOHTTPOpenW xmlIOHTTPOpenW__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlIOHTTPRead
+extern __typeof (xmlIOHTTPRead) xmlIOHTTPRead __attribute((alias("xmlIOHTTPRead__internal_alias")));
+#else
+#ifndef xmlIOHTTPRead
+extern __typeof (xmlIOHTTPRead) xmlIOHTTPRead__internal_alias __attribute((visibility("hidden")));
+#define xmlIOHTTPRead xmlIOHTTPRead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_parser
+#undef xmlIOParseDTD
+extern __typeof (xmlIOParseDTD) xmlIOParseDTD __attribute((alias("xmlIOParseDTD__internal_alias")));
+#else
+#ifndef xmlIOParseDTD
+extern __typeof (xmlIOParseDTD) xmlIOParseDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlIOParseDTD xmlIOParseDTD__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlInitCharEncodingHandlers
+extern __typeof (xmlInitCharEncodingHandlers) xmlInitCharEncodingHandlers __attribute((alias("xmlInitCharEncodingHandlers__internal_alias")));
+#else
+#ifndef xmlInitCharEncodingHandlers
+extern __typeof (xmlInitCharEncodingHandlers) xmlInitCharEncodingHandlers__internal_alias __attribute((visibility("hidden")));
+#define xmlInitCharEncodingHandlers xmlInitCharEncodingHandlers__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlInitGlobals
+extern __typeof (xmlInitGlobals) xmlInitGlobals __attribute((alias("xmlInitGlobals__internal_alias")));
+#else
+#ifndef xmlInitGlobals
+extern __typeof (xmlInitGlobals) xmlInitGlobals__internal_alias __attribute((visibility("hidden")));
+#define xmlInitGlobals xmlInitGlobals__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlInitMemory
+extern __typeof (xmlInitMemory) xmlInitMemory __attribute((alias("xmlInitMemory__internal_alias")));
+#else
+#ifndef xmlInitMemory
+extern __typeof (xmlInitMemory) xmlInitMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlInitMemory xmlInitMemory__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlInitNodeInfoSeq
+extern __typeof (xmlInitNodeInfoSeq) xmlInitNodeInfoSeq __attribute((alias("xmlInitNodeInfoSeq__internal_alias")));
+#else
+#ifndef xmlInitNodeInfoSeq
+extern __typeof (xmlInitNodeInfoSeq) xmlInitNodeInfoSeq__internal_alias __attribute((visibility("hidden")));
+#define xmlInitNodeInfoSeq xmlInitNodeInfoSeq__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlInitParser
+extern __typeof (xmlInitParser) xmlInitParser __attribute((alias("xmlInitParser__internal_alias")));
+#else
+#ifndef xmlInitParser
+extern __typeof (xmlInitParser) xmlInitParser__internal_alias __attribute((visibility("hidden")));
+#define xmlInitParser xmlInitParser__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlInitParserCtxt
+extern __typeof (xmlInitParserCtxt) xmlInitParserCtxt __attribute((alias("xmlInitParserCtxt__internal_alias")));
+#else
+#ifndef xmlInitParserCtxt
+extern __typeof (xmlInitParserCtxt) xmlInitParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlInitParserCtxt xmlInitParserCtxt__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlInitThreads
+extern __typeof (xmlInitThreads) xmlInitThreads __attribute((alias("xmlInitThreads__internal_alias")));
+#else
+#ifndef xmlInitThreads
+extern __typeof (xmlInitThreads) xmlInitThreads__internal_alias __attribute((visibility("hidden")));
+#define xmlInitThreads xmlInitThreads__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlInitializeCatalog
+extern __typeof (xmlInitializeCatalog) xmlInitializeCatalog __attribute((alias("xmlInitializeCatalog__internal_alias")));
+#else
+#ifndef xmlInitializeCatalog
+extern __typeof (xmlInitializeCatalog) xmlInitializeCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlInitializeCatalog xmlInitializeCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlInitializeGlobalState
+extern __typeof (xmlInitializeGlobalState) xmlInitializeGlobalState __attribute((alias("xmlInitializeGlobalState__internal_alias")));
+#else
+#ifndef xmlInitializeGlobalState
+extern __typeof (xmlInitializeGlobalState) xmlInitializeGlobalState__internal_alias __attribute((visibility("hidden")));
+#define xmlInitializeGlobalState xmlInitializeGlobalState__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlInitializePredefinedEntities
+extern __typeof (xmlInitializePredefinedEntities) xmlInitializePredefinedEntities __attribute((alias("xmlInitializePredefinedEntities__internal_alias")));
+#else
+#ifndef xmlInitializePredefinedEntities
+extern __typeof (xmlInitializePredefinedEntities) xmlInitializePredefinedEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlInitializePredefinedEntities xmlInitializePredefinedEntities__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsBaseChar
+extern __typeof (xmlIsBaseChar) xmlIsBaseChar __attribute((alias("xmlIsBaseChar__internal_alias")));
+#else
+#ifndef xmlIsBaseChar
+extern __typeof (xmlIsBaseChar) xmlIsBaseChar__internal_alias __attribute((visibility("hidden")));
+#define xmlIsBaseChar xmlIsBaseChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsBlank
+extern __typeof (xmlIsBlank) xmlIsBlank __attribute((alias("xmlIsBlank__internal_alias")));
+#else
+#ifndef xmlIsBlank
+extern __typeof (xmlIsBlank) xmlIsBlank__internal_alias __attribute((visibility("hidden")));
+#define xmlIsBlank xmlIsBlank__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlIsBlankNode
+extern __typeof (xmlIsBlankNode) xmlIsBlankNode __attribute((alias("xmlIsBlankNode__internal_alias")));
+#else
+#ifndef xmlIsBlankNode
+extern __typeof (xmlIsBlankNode) xmlIsBlankNode__internal_alias __attribute((visibility("hidden")));
+#define xmlIsBlankNode xmlIsBlankNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsChar
+extern __typeof (xmlIsChar) xmlIsChar __attribute((alias("xmlIsChar__internal_alias")));
+#else
+#ifndef xmlIsChar
+extern __typeof (xmlIsChar) xmlIsChar__internal_alias __attribute((visibility("hidden")));
+#define xmlIsChar xmlIsChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsCombining
+extern __typeof (xmlIsCombining) xmlIsCombining __attribute((alias("xmlIsCombining__internal_alias")));
+#else
+#ifndef xmlIsCombining
+extern __typeof (xmlIsCombining) xmlIsCombining__internal_alias __attribute((visibility("hidden")));
+#define xmlIsCombining xmlIsCombining__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsDigit
+extern __typeof (xmlIsDigit) xmlIsDigit __attribute((alias("xmlIsDigit__internal_alias")));
+#else
+#ifndef xmlIsDigit
+extern __typeof (xmlIsDigit) xmlIsDigit__internal_alias __attribute((visibility("hidden")));
+#define xmlIsDigit xmlIsDigit__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsExtender
+extern __typeof (xmlIsExtender) xmlIsExtender __attribute((alias("xmlIsExtender__internal_alias")));
+#else
+#ifndef xmlIsExtender
+extern __typeof (xmlIsExtender) xmlIsExtender__internal_alias __attribute((visibility("hidden")));
+#define xmlIsExtender xmlIsExtender__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlIsID
+extern __typeof (xmlIsID) xmlIsID __attribute((alias("xmlIsID__internal_alias")));
+#else
+#ifndef xmlIsID
+extern __typeof (xmlIsID) xmlIsID__internal_alias __attribute((visibility("hidden")));
+#define xmlIsID xmlIsID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsIdeographic
+extern __typeof (xmlIsIdeographic) xmlIsIdeographic __attribute((alias("xmlIsIdeographic__internal_alias")));
+#else
+#ifndef xmlIsIdeographic
+extern __typeof (xmlIsIdeographic) xmlIsIdeographic__internal_alias __attribute((visibility("hidden")));
+#define xmlIsIdeographic xmlIsIdeographic__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlIsLetter
+extern __typeof (xmlIsLetter) xmlIsLetter __attribute((alias("xmlIsLetter__internal_alias")));
+#else
+#ifndef xmlIsLetter
+extern __typeof (xmlIsLetter) xmlIsLetter__internal_alias __attribute((visibility("hidden")));
+#define xmlIsLetter xmlIsLetter__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlIsMainThread
+extern __typeof (xmlIsMainThread) xmlIsMainThread __attribute((alias("xmlIsMainThread__internal_alias")));
+#else
+#ifndef xmlIsMainThread
+extern __typeof (xmlIsMainThread) xmlIsMainThread__internal_alias __attribute((visibility("hidden")));
+#define xmlIsMainThread xmlIsMainThread__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlIsMixedElement
+extern __typeof (xmlIsMixedElement) xmlIsMixedElement __attribute((alias("xmlIsMixedElement__internal_alias")));
+#else
+#ifndef xmlIsMixedElement
+extern __typeof (xmlIsMixedElement) xmlIsMixedElement__internal_alias __attribute((visibility("hidden")));
+#define xmlIsMixedElement xmlIsMixedElement__internal_alias
+#endif
+#endif
+
+#ifdef bottom_chvalid
+#undef xmlIsPubidChar
+extern __typeof (xmlIsPubidChar) xmlIsPubidChar __attribute((alias("xmlIsPubidChar__internal_alias")));
+#else
+#ifndef xmlIsPubidChar
+extern __typeof (xmlIsPubidChar) xmlIsPubidChar__internal_alias __attribute((visibility("hidden")));
+#define xmlIsPubidChar xmlIsPubidChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlIsRef
+extern __typeof (xmlIsRef) xmlIsRef __attribute((alias("xmlIsRef__internal_alias")));
+#else
+#ifndef xmlIsRef
+extern __typeof (xmlIsRef) xmlIsRef__internal_alias __attribute((visibility("hidden")));
+#define xmlIsRef xmlIsRef__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlsave
+#undef xmlIsXHTML
+extern __typeof (xmlIsXHTML) xmlIsXHTML __attribute((alias("xmlIsXHTML__internal_alias")));
+#else
+#ifndef xmlIsXHTML
+extern __typeof (xmlIsXHTML) xmlIsXHTML__internal_alias __attribute((visibility("hidden")));
+#define xmlIsXHTML xmlIsXHTML__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlKeepBlanksDefault
+extern __typeof (xmlKeepBlanksDefault) xmlKeepBlanksDefault __attribute((alias("xmlKeepBlanksDefault__internal_alias")));
+#else
+#ifndef xmlKeepBlanksDefault
+extern __typeof (xmlKeepBlanksDefault) xmlKeepBlanksDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlKeepBlanksDefault xmlKeepBlanksDefault__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlLastElementChild
+extern __typeof (xmlLastElementChild) xmlLastElementChild __attribute((alias("xmlLastElementChild__internal_alias")));
+#else
+#ifndef xmlLastElementChild
+extern __typeof (xmlLastElementChild) xmlLastElementChild__internal_alias __attribute((visibility("hidden")));
+#define xmlLastElementChild xmlLastElementChild__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlLineNumbersDefault
+extern __typeof (xmlLineNumbersDefault) xmlLineNumbersDefault __attribute((alias("xmlLineNumbersDefault__internal_alias")));
+#else
+#ifndef xmlLineNumbersDefault
+extern __typeof (xmlLineNumbersDefault) xmlLineNumbersDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlLineNumbersDefault xmlLineNumbersDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlLinkGetData
+extern __typeof (xmlLinkGetData) xmlLinkGetData __attribute((alias("xmlLinkGetData__internal_alias")));
+#else
+#ifndef xmlLinkGetData
+extern __typeof (xmlLinkGetData) xmlLinkGetData__internal_alias __attribute((visibility("hidden")));
+#define xmlLinkGetData xmlLinkGetData__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListAppend
+extern __typeof (xmlListAppend) xmlListAppend __attribute((alias("xmlListAppend__internal_alias")));
+#else
+#ifndef xmlListAppend
+extern __typeof (xmlListAppend) xmlListAppend__internal_alias __attribute((visibility("hidden")));
+#define xmlListAppend xmlListAppend__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListClear
+extern __typeof (xmlListClear) xmlListClear __attribute((alias("xmlListClear__internal_alias")));
+#else
+#ifndef xmlListClear
+extern __typeof (xmlListClear) xmlListClear__internal_alias __attribute((visibility("hidden")));
+#define xmlListClear xmlListClear__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListCopy
+extern __typeof (xmlListCopy) xmlListCopy __attribute((alias("xmlListCopy__internal_alias")));
+#else
+#ifndef xmlListCopy
+extern __typeof (xmlListCopy) xmlListCopy__internal_alias __attribute((visibility("hidden")));
+#define xmlListCopy xmlListCopy__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListCreate
+extern __typeof (xmlListCreate) xmlListCreate __attribute((alias("xmlListCreate__internal_alias")));
+#else
+#ifndef xmlListCreate
+extern __typeof (xmlListCreate) xmlListCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlListCreate xmlListCreate__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListDelete
+extern __typeof (xmlListDelete) xmlListDelete __attribute((alias("xmlListDelete__internal_alias")));
+#else
+#ifndef xmlListDelete
+extern __typeof (xmlListDelete) xmlListDelete__internal_alias __attribute((visibility("hidden")));
+#define xmlListDelete xmlListDelete__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListDup
+extern __typeof (xmlListDup) xmlListDup __attribute((alias("xmlListDup__internal_alias")));
+#else
+#ifndef xmlListDup
+extern __typeof (xmlListDup) xmlListDup__internal_alias __attribute((visibility("hidden")));
+#define xmlListDup xmlListDup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListEmpty
+extern __typeof (xmlListEmpty) xmlListEmpty __attribute((alias("xmlListEmpty__internal_alias")));
+#else
+#ifndef xmlListEmpty
+extern __typeof (xmlListEmpty) xmlListEmpty__internal_alias __attribute((visibility("hidden")));
+#define xmlListEmpty xmlListEmpty__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListEnd
+extern __typeof (xmlListEnd) xmlListEnd __attribute((alias("xmlListEnd__internal_alias")));
+#else
+#ifndef xmlListEnd
+extern __typeof (xmlListEnd) xmlListEnd__internal_alias __attribute((visibility("hidden")));
+#define xmlListEnd xmlListEnd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListFront
+extern __typeof (xmlListFront) xmlListFront __attribute((alias("xmlListFront__internal_alias")));
+#else
+#ifndef xmlListFront
+extern __typeof (xmlListFront) xmlListFront__internal_alias __attribute((visibility("hidden")));
+#define xmlListFront xmlListFront__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListInsert
+extern __typeof (xmlListInsert) xmlListInsert __attribute((alias("xmlListInsert__internal_alias")));
+#else
+#ifndef xmlListInsert
+extern __typeof (xmlListInsert) xmlListInsert__internal_alias __attribute((visibility("hidden")));
+#define xmlListInsert xmlListInsert__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListMerge
+extern __typeof (xmlListMerge) xmlListMerge __attribute((alias("xmlListMerge__internal_alias")));
+#else
+#ifndef xmlListMerge
+extern __typeof (xmlListMerge) xmlListMerge__internal_alias __attribute((visibility("hidden")));
+#define xmlListMerge xmlListMerge__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListPopBack
+extern __typeof (xmlListPopBack) xmlListPopBack __attribute((alias("xmlListPopBack__internal_alias")));
+#else
+#ifndef xmlListPopBack
+extern __typeof (xmlListPopBack) xmlListPopBack__internal_alias __attribute((visibility("hidden")));
+#define xmlListPopBack xmlListPopBack__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListPopFront
+extern __typeof (xmlListPopFront) xmlListPopFront __attribute((alias("xmlListPopFront__internal_alias")));
+#else
+#ifndef xmlListPopFront
+extern __typeof (xmlListPopFront) xmlListPopFront__internal_alias __attribute((visibility("hidden")));
+#define xmlListPopFront xmlListPopFront__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListPushBack
+extern __typeof (xmlListPushBack) xmlListPushBack __attribute((alias("xmlListPushBack__internal_alias")));
+#else
+#ifndef xmlListPushBack
+extern __typeof (xmlListPushBack) xmlListPushBack__internal_alias __attribute((visibility("hidden")));
+#define xmlListPushBack xmlListPushBack__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListPushFront
+extern __typeof (xmlListPushFront) xmlListPushFront __attribute((alias("xmlListPushFront__internal_alias")));
+#else
+#ifndef xmlListPushFront
+extern __typeof (xmlListPushFront) xmlListPushFront__internal_alias __attribute((visibility("hidden")));
+#define xmlListPushFront xmlListPushFront__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListRemoveAll
+extern __typeof (xmlListRemoveAll) xmlListRemoveAll __attribute((alias("xmlListRemoveAll__internal_alias")));
+#else
+#ifndef xmlListRemoveAll
+extern __typeof (xmlListRemoveAll) xmlListRemoveAll__internal_alias __attribute((visibility("hidden")));
+#define xmlListRemoveAll xmlListRemoveAll__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListRemoveFirst
+extern __typeof (xmlListRemoveFirst) xmlListRemoveFirst __attribute((alias("xmlListRemoveFirst__internal_alias")));
+#else
+#ifndef xmlListRemoveFirst
+extern __typeof (xmlListRemoveFirst) xmlListRemoveFirst__internal_alias __attribute((visibility("hidden")));
+#define xmlListRemoveFirst xmlListRemoveFirst__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListRemoveLast
+extern __typeof (xmlListRemoveLast) xmlListRemoveLast __attribute((alias("xmlListRemoveLast__internal_alias")));
+#else
+#ifndef xmlListRemoveLast
+extern __typeof (xmlListRemoveLast) xmlListRemoveLast__internal_alias __attribute((visibility("hidden")));
+#define xmlListRemoveLast xmlListRemoveLast__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListReverse
+extern __typeof (xmlListReverse) xmlListReverse __attribute((alias("xmlListReverse__internal_alias")));
+#else
+#ifndef xmlListReverse
+extern __typeof (xmlListReverse) xmlListReverse__internal_alias __attribute((visibility("hidden")));
+#define xmlListReverse xmlListReverse__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListReverseSearch
+extern __typeof (xmlListReverseSearch) xmlListReverseSearch __attribute((alias("xmlListReverseSearch__internal_alias")));
+#else
+#ifndef xmlListReverseSearch
+extern __typeof (xmlListReverseSearch) xmlListReverseSearch__internal_alias __attribute((visibility("hidden")));
+#define xmlListReverseSearch xmlListReverseSearch__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListReverseWalk
+extern __typeof (xmlListReverseWalk) xmlListReverseWalk __attribute((alias("xmlListReverseWalk__internal_alias")));
+#else
+#ifndef xmlListReverseWalk
+extern __typeof (xmlListReverseWalk) xmlListReverseWalk__internal_alias __attribute((visibility("hidden")));
+#define xmlListReverseWalk xmlListReverseWalk__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListSearch
+extern __typeof (xmlListSearch) xmlListSearch __attribute((alias("xmlListSearch__internal_alias")));
+#else
+#ifndef xmlListSearch
+extern __typeof (xmlListSearch) xmlListSearch__internal_alias __attribute((visibility("hidden")));
+#define xmlListSearch xmlListSearch__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListSize
+extern __typeof (xmlListSize) xmlListSize __attribute((alias("xmlListSize__internal_alias")));
+#else
+#ifndef xmlListSize
+extern __typeof (xmlListSize) xmlListSize__internal_alias __attribute((visibility("hidden")));
+#define xmlListSize xmlListSize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListSort
+extern __typeof (xmlListSort) xmlListSort __attribute((alias("xmlListSort__internal_alias")));
+#else
+#ifndef xmlListSort
+extern __typeof (xmlListSort) xmlListSort__internal_alias __attribute((visibility("hidden")));
+#define xmlListSort xmlListSort__internal_alias
+#endif
+#endif
+
+#ifdef bottom_list
+#undef xmlListWalk
+extern __typeof (xmlListWalk) xmlListWalk __attribute((alias("xmlListWalk__internal_alias")));
+#else
+#ifndef xmlListWalk
+extern __typeof (xmlListWalk) xmlListWalk__internal_alias __attribute((visibility("hidden")));
+#define xmlListWalk xmlListWalk__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlLoadACatalog
+extern __typeof (xmlLoadACatalog) xmlLoadACatalog __attribute((alias("xmlLoadACatalog__internal_alias")));
+#else
+#ifndef xmlLoadACatalog
+extern __typeof (xmlLoadACatalog) xmlLoadACatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlLoadACatalog xmlLoadACatalog__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlLoadCatalog
+extern __typeof (xmlLoadCatalog) xmlLoadCatalog __attribute((alias("xmlLoadCatalog__internal_alias")));
+#else
+#ifndef xmlLoadCatalog
+extern __typeof (xmlLoadCatalog) xmlLoadCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlLoadCatalog xmlLoadCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlLoadCatalogs
+extern __typeof (xmlLoadCatalogs) xmlLoadCatalogs __attribute((alias("xmlLoadCatalogs__internal_alias")));
+#else
+#ifndef xmlLoadCatalogs
+extern __typeof (xmlLoadCatalogs) xmlLoadCatalogs__internal_alias __attribute((visibility("hidden")));
+#define xmlLoadCatalogs xmlLoadCatalogs__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlLoadExternalEntity
+extern __typeof (xmlLoadExternalEntity) xmlLoadExternalEntity __attribute((alias("xmlLoadExternalEntity__internal_alias")));
+#else
+#ifndef xmlLoadExternalEntity
+extern __typeof (xmlLoadExternalEntity) xmlLoadExternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlLoadExternalEntity xmlLoadExternalEntity__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlLoadSGMLSuperCatalog
+extern __typeof (xmlLoadSGMLSuperCatalog) xmlLoadSGMLSuperCatalog __attribute((alias("xmlLoadSGMLSuperCatalog__internal_alias")));
+#else
+#ifndef xmlLoadSGMLSuperCatalog
+extern __typeof (xmlLoadSGMLSuperCatalog) xmlLoadSGMLSuperCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlLoadSGMLSuperCatalog xmlLoadSGMLSuperCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlLockLibrary
+extern __typeof (xmlLockLibrary) xmlLockLibrary __attribute((alias("xmlLockLibrary__internal_alias")));
+#else
+#ifndef xmlLockLibrary
+extern __typeof (xmlLockLibrary) xmlLockLibrary__internal_alias __attribute((visibility("hidden")));
+#define xmlLockLibrary xmlLockLibrary__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlLsCountNode
+extern __typeof (xmlLsCountNode) xmlLsCountNode __attribute((alias("xmlLsCountNode__internal_alias")));
+#else
+#ifndef xmlLsCountNode
+extern __typeof (xmlLsCountNode) xmlLsCountNode__internal_alias __attribute((visibility("hidden")));
+#define xmlLsCountNode xmlLsCountNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlLsOneNode
+extern __typeof (xmlLsOneNode) xmlLsOneNode __attribute((alias("xmlLsOneNode__internal_alias")));
+#else
+#ifndef xmlLsOneNode
+extern __typeof (xmlLsOneNode) xmlLsOneNode__internal_alias __attribute((visibility("hidden")));
+#define xmlLsOneNode xmlLsOneNode__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMallocAtomicLoc
+extern __typeof (xmlMallocAtomicLoc) xmlMallocAtomicLoc __attribute((alias("xmlMallocAtomicLoc__internal_alias")));
+#else
+#ifndef xmlMallocAtomicLoc
+extern __typeof (xmlMallocAtomicLoc) xmlMallocAtomicLoc__internal_alias __attribute((visibility("hidden")));
+#define xmlMallocAtomicLoc xmlMallocAtomicLoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMallocLoc
+extern __typeof (xmlMallocLoc) xmlMallocLoc __attribute((alias("xmlMallocLoc__internal_alias")));
+#else
+#ifndef xmlMallocLoc
+extern __typeof (xmlMallocLoc) xmlMallocLoc__internal_alias __attribute((visibility("hidden")));
+#define xmlMallocLoc xmlMallocLoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemBlocks
+extern __typeof (xmlMemBlocks) xmlMemBlocks __attribute((alias("xmlMemBlocks__internal_alias")));
+#else
+#ifndef xmlMemBlocks
+extern __typeof (xmlMemBlocks) xmlMemBlocks__internal_alias __attribute((visibility("hidden")));
+#define xmlMemBlocks xmlMemBlocks__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemDisplay
+extern __typeof (xmlMemDisplay) xmlMemDisplay __attribute((alias("xmlMemDisplay__internal_alias")));
+#else
+#ifndef xmlMemDisplay
+extern __typeof (xmlMemDisplay) xmlMemDisplay__internal_alias __attribute((visibility("hidden")));
+#define xmlMemDisplay xmlMemDisplay__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemDisplayLast
+extern __typeof (xmlMemDisplayLast) xmlMemDisplayLast __attribute((alias("xmlMemDisplayLast__internal_alias")));
+#else
+#ifndef xmlMemDisplayLast
+extern __typeof (xmlMemDisplayLast) xmlMemDisplayLast__internal_alias __attribute((visibility("hidden")));
+#define xmlMemDisplayLast xmlMemDisplayLast__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemFree
+extern __typeof (xmlMemFree) xmlMemFree __attribute((alias("xmlMemFree__internal_alias")));
+#else
+#ifndef xmlMemFree
+extern __typeof (xmlMemFree) xmlMemFree__internal_alias __attribute((visibility("hidden")));
+#define xmlMemFree xmlMemFree__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemGet
+extern __typeof (xmlMemGet) xmlMemGet __attribute((alias("xmlMemGet__internal_alias")));
+#else
+#ifndef xmlMemGet
+extern __typeof (xmlMemGet) xmlMemGet__internal_alias __attribute((visibility("hidden")));
+#define xmlMemGet xmlMemGet__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemMalloc
+extern __typeof (xmlMemMalloc) xmlMemMalloc __attribute((alias("xmlMemMalloc__internal_alias")));
+#else
+#ifndef xmlMemMalloc
+extern __typeof (xmlMemMalloc) xmlMemMalloc__internal_alias __attribute((visibility("hidden")));
+#define xmlMemMalloc xmlMemMalloc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemRealloc
+extern __typeof (xmlMemRealloc) xmlMemRealloc __attribute((alias("xmlMemRealloc__internal_alias")));
+#else
+#ifndef xmlMemRealloc
+extern __typeof (xmlMemRealloc) xmlMemRealloc__internal_alias __attribute((visibility("hidden")));
+#define xmlMemRealloc xmlMemRealloc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemSetup
+extern __typeof (xmlMemSetup) xmlMemSetup __attribute((alias("xmlMemSetup__internal_alias")));
+#else
+#ifndef xmlMemSetup
+extern __typeof (xmlMemSetup) xmlMemSetup__internal_alias __attribute((visibility("hidden")));
+#define xmlMemSetup xmlMemSetup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemShow
+extern __typeof (xmlMemShow) xmlMemShow __attribute((alias("xmlMemShow__internal_alias")));
+#else
+#ifndef xmlMemShow
+extern __typeof (xmlMemShow) xmlMemShow__internal_alias __attribute((visibility("hidden")));
+#define xmlMemShow xmlMemShow__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemStrdupLoc
+extern __typeof (xmlMemStrdupLoc) xmlMemStrdupLoc __attribute((alias("xmlMemStrdupLoc__internal_alias")));
+#else
+#ifndef xmlMemStrdupLoc
+extern __typeof (xmlMemStrdupLoc) xmlMemStrdupLoc__internal_alias __attribute((visibility("hidden")));
+#define xmlMemStrdupLoc xmlMemStrdupLoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemUsed
+extern __typeof (xmlMemUsed) xmlMemUsed __attribute((alias("xmlMemUsed__internal_alias")));
+#else
+#ifndef xmlMemUsed
+extern __typeof (xmlMemUsed) xmlMemUsed__internal_alias __attribute((visibility("hidden")));
+#define xmlMemUsed xmlMemUsed__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemoryDump
+extern __typeof (xmlMemoryDump) xmlMemoryDump __attribute((alias("xmlMemoryDump__internal_alias")));
+#else
+#ifndef xmlMemoryDump
+extern __typeof (xmlMemoryDump) xmlMemoryDump__internal_alias __attribute((visibility("hidden")));
+#define xmlMemoryDump xmlMemoryDump__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlMemoryStrdup
+extern __typeof (xmlMemoryStrdup) xmlMemoryStrdup __attribute((alias("xmlMemoryStrdup__internal_alias")));
+#else
+#ifndef xmlMemoryStrdup
+extern __typeof (xmlMemoryStrdup) xmlMemoryStrdup__internal_alias __attribute((visibility("hidden")));
+#define xmlMemoryStrdup xmlMemoryStrdup__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_MODULES_ENABLED)
+#ifdef bottom_xmlmodule
+#undef xmlModuleClose
+extern __typeof (xmlModuleClose) xmlModuleClose __attribute((alias("xmlModuleClose__internal_alias")));
+#else
+#ifndef xmlModuleClose
+extern __typeof (xmlModuleClose) xmlModuleClose__internal_alias __attribute((visibility("hidden")));
+#define xmlModuleClose xmlModuleClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_MODULES_ENABLED)
+#ifdef bottom_xmlmodule
+#undef xmlModuleFree
+extern __typeof (xmlModuleFree) xmlModuleFree __attribute((alias("xmlModuleFree__internal_alias")));
+#else
+#ifndef xmlModuleFree
+extern __typeof (xmlModuleFree) xmlModuleFree__internal_alias __attribute((visibility("hidden")));
+#define xmlModuleFree xmlModuleFree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_MODULES_ENABLED)
+#ifdef bottom_xmlmodule
+#undef xmlModuleOpen
+extern __typeof (xmlModuleOpen) xmlModuleOpen __attribute((alias("xmlModuleOpen__internal_alias")));
+#else
+#ifndef xmlModuleOpen
+extern __typeof (xmlModuleOpen) xmlModuleOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlModuleOpen xmlModuleOpen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_MODULES_ENABLED)
+#ifdef bottom_xmlmodule
+#undef xmlModuleSymbol
+extern __typeof (xmlModuleSymbol) xmlModuleSymbol __attribute((alias("xmlModuleSymbol__internal_alias")));
+#else
+#ifndef xmlModuleSymbol
+extern __typeof (xmlModuleSymbol) xmlModuleSymbol__internal_alias __attribute((visibility("hidden")));
+#define xmlModuleSymbol xmlModuleSymbol__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlMutexLock
+extern __typeof (xmlMutexLock) xmlMutexLock __attribute((alias("xmlMutexLock__internal_alias")));
+#else
+#ifndef xmlMutexLock
+extern __typeof (xmlMutexLock) xmlMutexLock__internal_alias __attribute((visibility("hidden")));
+#define xmlMutexLock xmlMutexLock__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlMutexUnlock
+extern __typeof (xmlMutexUnlock) xmlMutexUnlock __attribute((alias("xmlMutexUnlock__internal_alias")));
+#else
+#ifndef xmlMutexUnlock
+extern __typeof (xmlMutexUnlock) xmlMutexUnlock__internal_alias __attribute((visibility("hidden")));
+#define xmlMutexUnlock xmlMutexUnlock__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlNamespaceParseNCName
+extern __typeof (xmlNamespaceParseNCName) xmlNamespaceParseNCName __attribute((alias("xmlNamespaceParseNCName__internal_alias")));
+#else
+#ifndef xmlNamespaceParseNCName
+extern __typeof (xmlNamespaceParseNCName) xmlNamespaceParseNCName__internal_alias __attribute((visibility("hidden")));
+#define xmlNamespaceParseNCName xmlNamespaceParseNCName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlNamespaceParseNSDef
+extern __typeof (xmlNamespaceParseNSDef) xmlNamespaceParseNSDef __attribute((alias("xmlNamespaceParseNSDef__internal_alias")));
+#else
+#ifndef xmlNamespaceParseNSDef
+extern __typeof (xmlNamespaceParseNSDef) xmlNamespaceParseNSDef__internal_alias __attribute((visibility("hidden")));
+#define xmlNamespaceParseNSDef xmlNamespaceParseNSDef__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlNamespaceParseQName
+extern __typeof (xmlNamespaceParseQName) xmlNamespaceParseQName __attribute((alias("xmlNamespaceParseQName__internal_alias")));
+#else
+#ifndef xmlNamespaceParseQName
+extern __typeof (xmlNamespaceParseQName) xmlNamespaceParseQName__internal_alias __attribute((visibility("hidden")));
+#define xmlNamespaceParseQName xmlNamespaceParseQName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPCheckResponse
+extern __typeof (xmlNanoFTPCheckResponse) xmlNanoFTPCheckResponse __attribute((alias("xmlNanoFTPCheckResponse__internal_alias")));
+#else
+#ifndef xmlNanoFTPCheckResponse
+extern __typeof (xmlNanoFTPCheckResponse) xmlNanoFTPCheckResponse__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPCheckResponse xmlNanoFTPCheckResponse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPCleanup
+extern __typeof (xmlNanoFTPCleanup) xmlNanoFTPCleanup __attribute((alias("xmlNanoFTPCleanup__internal_alias")));
+#else
+#ifndef xmlNanoFTPCleanup
+extern __typeof (xmlNanoFTPCleanup) xmlNanoFTPCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPCleanup xmlNanoFTPCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPClose
+extern __typeof (xmlNanoFTPClose) xmlNanoFTPClose __attribute((alias("xmlNanoFTPClose__internal_alias")));
+#else
+#ifndef xmlNanoFTPClose
+extern __typeof (xmlNanoFTPClose) xmlNanoFTPClose__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPClose xmlNanoFTPClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPCloseConnection
+extern __typeof (xmlNanoFTPCloseConnection) xmlNanoFTPCloseConnection __attribute((alias("xmlNanoFTPCloseConnection__internal_alias")));
+#else
+#ifndef xmlNanoFTPCloseConnection
+extern __typeof (xmlNanoFTPCloseConnection) xmlNanoFTPCloseConnection__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPCloseConnection xmlNanoFTPCloseConnection__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPConnect
+extern __typeof (xmlNanoFTPConnect) xmlNanoFTPConnect __attribute((alias("xmlNanoFTPConnect__internal_alias")));
+#else
+#ifndef xmlNanoFTPConnect
+extern __typeof (xmlNanoFTPConnect) xmlNanoFTPConnect__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPConnect xmlNanoFTPConnect__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPConnectTo
+extern __typeof (xmlNanoFTPConnectTo) xmlNanoFTPConnectTo __attribute((alias("xmlNanoFTPConnectTo__internal_alias")));
+#else
+#ifndef xmlNanoFTPConnectTo
+extern __typeof (xmlNanoFTPConnectTo) xmlNanoFTPConnectTo__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPConnectTo xmlNanoFTPConnectTo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPCwd
+extern __typeof (xmlNanoFTPCwd) xmlNanoFTPCwd __attribute((alias("xmlNanoFTPCwd__internal_alias")));
+#else
+#ifndef xmlNanoFTPCwd
+extern __typeof (xmlNanoFTPCwd) xmlNanoFTPCwd__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPCwd xmlNanoFTPCwd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPDele
+extern __typeof (xmlNanoFTPDele) xmlNanoFTPDele __attribute((alias("xmlNanoFTPDele__internal_alias")));
+#else
+#ifndef xmlNanoFTPDele
+extern __typeof (xmlNanoFTPDele) xmlNanoFTPDele__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPDele xmlNanoFTPDele__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPFreeCtxt
+extern __typeof (xmlNanoFTPFreeCtxt) xmlNanoFTPFreeCtxt __attribute((alias("xmlNanoFTPFreeCtxt__internal_alias")));
+#else
+#ifndef xmlNanoFTPFreeCtxt
+extern __typeof (xmlNanoFTPFreeCtxt) xmlNanoFTPFreeCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPFreeCtxt xmlNanoFTPFreeCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPGet
+extern __typeof (xmlNanoFTPGet) xmlNanoFTPGet __attribute((alias("xmlNanoFTPGet__internal_alias")));
+#else
+#ifndef xmlNanoFTPGet
+extern __typeof (xmlNanoFTPGet) xmlNanoFTPGet__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPGet xmlNanoFTPGet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPGetConnection
+extern __typeof (xmlNanoFTPGetConnection) xmlNanoFTPGetConnection __attribute((alias("xmlNanoFTPGetConnection__internal_alias")));
+#else
+#ifndef xmlNanoFTPGetConnection
+extern __typeof (xmlNanoFTPGetConnection) xmlNanoFTPGetConnection__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPGetConnection xmlNanoFTPGetConnection__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPGetResponse
+extern __typeof (xmlNanoFTPGetResponse) xmlNanoFTPGetResponse __attribute((alias("xmlNanoFTPGetResponse__internal_alias")));
+#else
+#ifndef xmlNanoFTPGetResponse
+extern __typeof (xmlNanoFTPGetResponse) xmlNanoFTPGetResponse__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPGetResponse xmlNanoFTPGetResponse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPGetSocket
+extern __typeof (xmlNanoFTPGetSocket) xmlNanoFTPGetSocket __attribute((alias("xmlNanoFTPGetSocket__internal_alias")));
+#else
+#ifndef xmlNanoFTPGetSocket
+extern __typeof (xmlNanoFTPGetSocket) xmlNanoFTPGetSocket__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPGetSocket xmlNanoFTPGetSocket__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPInit
+extern __typeof (xmlNanoFTPInit) xmlNanoFTPInit __attribute((alias("xmlNanoFTPInit__internal_alias")));
+#else
+#ifndef xmlNanoFTPInit
+extern __typeof (xmlNanoFTPInit) xmlNanoFTPInit__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPInit xmlNanoFTPInit__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPList
+extern __typeof (xmlNanoFTPList) xmlNanoFTPList __attribute((alias("xmlNanoFTPList__internal_alias")));
+#else
+#ifndef xmlNanoFTPList
+extern __typeof (xmlNanoFTPList) xmlNanoFTPList__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPList xmlNanoFTPList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPNewCtxt
+extern __typeof (xmlNanoFTPNewCtxt) xmlNanoFTPNewCtxt __attribute((alias("xmlNanoFTPNewCtxt__internal_alias")));
+#else
+#ifndef xmlNanoFTPNewCtxt
+extern __typeof (xmlNanoFTPNewCtxt) xmlNanoFTPNewCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPNewCtxt xmlNanoFTPNewCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPOpen
+extern __typeof (xmlNanoFTPOpen) xmlNanoFTPOpen __attribute((alias("xmlNanoFTPOpen__internal_alias")));
+#else
+#ifndef xmlNanoFTPOpen
+extern __typeof (xmlNanoFTPOpen) xmlNanoFTPOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPOpen xmlNanoFTPOpen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPProxy
+extern __typeof (xmlNanoFTPProxy) xmlNanoFTPProxy __attribute((alias("xmlNanoFTPProxy__internal_alias")));
+#else
+#ifndef xmlNanoFTPProxy
+extern __typeof (xmlNanoFTPProxy) xmlNanoFTPProxy__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPProxy xmlNanoFTPProxy__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPQuit
+extern __typeof (xmlNanoFTPQuit) xmlNanoFTPQuit __attribute((alias("xmlNanoFTPQuit__internal_alias")));
+#else
+#ifndef xmlNanoFTPQuit
+extern __typeof (xmlNanoFTPQuit) xmlNanoFTPQuit__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPQuit xmlNanoFTPQuit__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPRead
+extern __typeof (xmlNanoFTPRead) xmlNanoFTPRead __attribute((alias("xmlNanoFTPRead__internal_alias")));
+#else
+#ifndef xmlNanoFTPRead
+extern __typeof (xmlNanoFTPRead) xmlNanoFTPRead__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPRead xmlNanoFTPRead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPScanProxy
+extern __typeof (xmlNanoFTPScanProxy) xmlNanoFTPScanProxy __attribute((alias("xmlNanoFTPScanProxy__internal_alias")));
+#else
+#ifndef xmlNanoFTPScanProxy
+extern __typeof (xmlNanoFTPScanProxy) xmlNanoFTPScanProxy__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPScanProxy xmlNanoFTPScanProxy__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_FTP_ENABLED)
+#ifdef bottom_nanoftp
+#undef xmlNanoFTPUpdateURL
+extern __typeof (xmlNanoFTPUpdateURL) xmlNanoFTPUpdateURL __attribute((alias("xmlNanoFTPUpdateURL__internal_alias")));
+#else
+#ifndef xmlNanoFTPUpdateURL
+extern __typeof (xmlNanoFTPUpdateURL) xmlNanoFTPUpdateURL__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoFTPUpdateURL xmlNanoFTPUpdateURL__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPAuthHeader
+extern __typeof (xmlNanoHTTPAuthHeader) xmlNanoHTTPAuthHeader __attribute((alias("xmlNanoHTTPAuthHeader__internal_alias")));
+#else
+#ifndef xmlNanoHTTPAuthHeader
+extern __typeof (xmlNanoHTTPAuthHeader) xmlNanoHTTPAuthHeader__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPAuthHeader xmlNanoHTTPAuthHeader__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPCleanup
+extern __typeof (xmlNanoHTTPCleanup) xmlNanoHTTPCleanup __attribute((alias("xmlNanoHTTPCleanup__internal_alias")));
+#else
+#ifndef xmlNanoHTTPCleanup
+extern __typeof (xmlNanoHTTPCleanup) xmlNanoHTTPCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPCleanup xmlNanoHTTPCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPClose
+extern __typeof (xmlNanoHTTPClose) xmlNanoHTTPClose __attribute((alias("xmlNanoHTTPClose__internal_alias")));
+#else
+#ifndef xmlNanoHTTPClose
+extern __typeof (xmlNanoHTTPClose) xmlNanoHTTPClose__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPClose xmlNanoHTTPClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPContentLength
+extern __typeof (xmlNanoHTTPContentLength) xmlNanoHTTPContentLength __attribute((alias("xmlNanoHTTPContentLength__internal_alias")));
+#else
+#ifndef xmlNanoHTTPContentLength
+extern __typeof (xmlNanoHTTPContentLength) xmlNanoHTTPContentLength__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPContentLength xmlNanoHTTPContentLength__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPEncoding
+extern __typeof (xmlNanoHTTPEncoding) xmlNanoHTTPEncoding __attribute((alias("xmlNanoHTTPEncoding__internal_alias")));
+#else
+#ifndef xmlNanoHTTPEncoding
+extern __typeof (xmlNanoHTTPEncoding) xmlNanoHTTPEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPEncoding xmlNanoHTTPEncoding__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPFetch
+extern __typeof (xmlNanoHTTPFetch) xmlNanoHTTPFetch __attribute((alias("xmlNanoHTTPFetch__internal_alias")));
+#else
+#ifndef xmlNanoHTTPFetch
+extern __typeof (xmlNanoHTTPFetch) xmlNanoHTTPFetch__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPFetch xmlNanoHTTPFetch__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPInit
+extern __typeof (xmlNanoHTTPInit) xmlNanoHTTPInit __attribute((alias("xmlNanoHTTPInit__internal_alias")));
+#else
+#ifndef xmlNanoHTTPInit
+extern __typeof (xmlNanoHTTPInit) xmlNanoHTTPInit__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPInit xmlNanoHTTPInit__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPMethod
+extern __typeof (xmlNanoHTTPMethod) xmlNanoHTTPMethod __attribute((alias("xmlNanoHTTPMethod__internal_alias")));
+#else
+#ifndef xmlNanoHTTPMethod
+extern __typeof (xmlNanoHTTPMethod) xmlNanoHTTPMethod__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPMethod xmlNanoHTTPMethod__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPMethodRedir
+extern __typeof (xmlNanoHTTPMethodRedir) xmlNanoHTTPMethodRedir __attribute((alias("xmlNanoHTTPMethodRedir__internal_alias")));
+#else
+#ifndef xmlNanoHTTPMethodRedir
+extern __typeof (xmlNanoHTTPMethodRedir) xmlNanoHTTPMethodRedir__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPMethodRedir xmlNanoHTTPMethodRedir__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPMimeType
+extern __typeof (xmlNanoHTTPMimeType) xmlNanoHTTPMimeType __attribute((alias("xmlNanoHTTPMimeType__internal_alias")));
+#else
+#ifndef xmlNanoHTTPMimeType
+extern __typeof (xmlNanoHTTPMimeType) xmlNanoHTTPMimeType__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPMimeType xmlNanoHTTPMimeType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPOpen
+extern __typeof (xmlNanoHTTPOpen) xmlNanoHTTPOpen __attribute((alias("xmlNanoHTTPOpen__internal_alias")));
+#else
+#ifndef xmlNanoHTTPOpen
+extern __typeof (xmlNanoHTTPOpen) xmlNanoHTTPOpen__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPOpen xmlNanoHTTPOpen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPOpenRedir
+extern __typeof (xmlNanoHTTPOpenRedir) xmlNanoHTTPOpenRedir __attribute((alias("xmlNanoHTTPOpenRedir__internal_alias")));
+#else
+#ifndef xmlNanoHTTPOpenRedir
+extern __typeof (xmlNanoHTTPOpenRedir) xmlNanoHTTPOpenRedir__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPOpenRedir xmlNanoHTTPOpenRedir__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPRead
+extern __typeof (xmlNanoHTTPRead) xmlNanoHTTPRead __attribute((alias("xmlNanoHTTPRead__internal_alias")));
+#else
+#ifndef xmlNanoHTTPRead
+extern __typeof (xmlNanoHTTPRead) xmlNanoHTTPRead__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPRead xmlNanoHTTPRead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPRedir
+extern __typeof (xmlNanoHTTPRedir) xmlNanoHTTPRedir __attribute((alias("xmlNanoHTTPRedir__internal_alias")));
+#else
+#ifndef xmlNanoHTTPRedir
+extern __typeof (xmlNanoHTTPRedir) xmlNanoHTTPRedir__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPRedir xmlNanoHTTPRedir__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPReturnCode
+extern __typeof (xmlNanoHTTPReturnCode) xmlNanoHTTPReturnCode __attribute((alias("xmlNanoHTTPReturnCode__internal_alias")));
+#else
+#ifndef xmlNanoHTTPReturnCode
+extern __typeof (xmlNanoHTTPReturnCode) xmlNanoHTTPReturnCode__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPReturnCode xmlNanoHTTPReturnCode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPSave
+extern __typeof (xmlNanoHTTPSave) xmlNanoHTTPSave __attribute((alias("xmlNanoHTTPSave__internal_alias")));
+#else
+#ifndef xmlNanoHTTPSave
+extern __typeof (xmlNanoHTTPSave) xmlNanoHTTPSave__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPSave xmlNanoHTTPSave__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_nanohttp
+#undef xmlNanoHTTPScanProxy
+extern __typeof (xmlNanoHTTPScanProxy) xmlNanoHTTPScanProxy __attribute((alias("xmlNanoHTTPScanProxy__internal_alias")));
+#else
+#ifndef xmlNanoHTTPScanProxy
+extern __typeof (xmlNanoHTTPScanProxy) xmlNanoHTTPScanProxy__internal_alias __attribute((visibility("hidden")));
+#define xmlNanoHTTPScanProxy xmlNanoHTTPScanProxy__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlNewAutomata
+extern __typeof (xmlNewAutomata) xmlNewAutomata __attribute((alias("xmlNewAutomata__internal_alias")));
+#else
+#ifndef xmlNewAutomata
+extern __typeof (xmlNewAutomata) xmlNewAutomata__internal_alias __attribute((visibility("hidden")));
+#define xmlNewAutomata xmlNewAutomata__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewCDataBlock
+extern __typeof (xmlNewCDataBlock) xmlNewCDataBlock __attribute((alias("xmlNewCDataBlock__internal_alias")));
+#else
+#ifndef xmlNewCDataBlock
+extern __typeof (xmlNewCDataBlock) xmlNewCDataBlock__internal_alias __attribute((visibility("hidden")));
+#define xmlNewCDataBlock xmlNewCDataBlock__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlNewCatalog
+extern __typeof (xmlNewCatalog) xmlNewCatalog __attribute((alias("xmlNewCatalog__internal_alias")));
+#else
+#ifndef xmlNewCatalog
+extern __typeof (xmlNewCatalog) xmlNewCatalog__internal_alias __attribute((visibility("hidden")));
+#define xmlNewCatalog xmlNewCatalog__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlNewCharEncodingHandler
+extern __typeof (xmlNewCharEncodingHandler) xmlNewCharEncodingHandler __attribute((alias("xmlNewCharEncodingHandler__internal_alias")));
+#else
+#ifndef xmlNewCharEncodingHandler
+extern __typeof (xmlNewCharEncodingHandler) xmlNewCharEncodingHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlNewCharEncodingHandler xmlNewCharEncodingHandler__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewCharRef
+extern __typeof (xmlNewCharRef) xmlNewCharRef __attribute((alias("xmlNewCharRef__internal_alias")));
+#else
+#ifndef xmlNewCharRef
+extern __typeof (xmlNewCharRef) xmlNewCharRef__internal_alias __attribute((visibility("hidden")));
+#define xmlNewCharRef xmlNewCharRef__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlNewChild
+extern __typeof (xmlNewChild) xmlNewChild __attribute((alias("xmlNewChild__internal_alias")));
+#else
+#ifndef xmlNewChild
+extern __typeof (xmlNewChild) xmlNewChild__internal_alias __attribute((visibility("hidden")));
+#define xmlNewChild xmlNewChild__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewComment
+extern __typeof (xmlNewComment) xmlNewComment __attribute((alias("xmlNewComment__internal_alias")));
+#else
+#ifndef xmlNewComment
+extern __typeof (xmlNewComment) xmlNewComment__internal_alias __attribute((visibility("hidden")));
+#define xmlNewComment xmlNewComment__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDoc
+extern __typeof (xmlNewDoc) xmlNewDoc __attribute((alias("xmlNewDoc__internal_alias")));
+#else
+#ifndef xmlNewDoc
+extern __typeof (xmlNewDoc) xmlNewDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDoc xmlNewDoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocComment
+extern __typeof (xmlNewDocComment) xmlNewDocComment __attribute((alias("xmlNewDocComment__internal_alias")));
+#else
+#ifndef xmlNewDocComment
+extern __typeof (xmlNewDocComment) xmlNewDocComment__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocComment xmlNewDocComment__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlNewDocElementContent
+extern __typeof (xmlNewDocElementContent) xmlNewDocElementContent __attribute((alias("xmlNewDocElementContent__internal_alias")));
+#else
+#ifndef xmlNewDocElementContent
+extern __typeof (xmlNewDocElementContent) xmlNewDocElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocElementContent xmlNewDocElementContent__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNewDocFragment
+extern __typeof (xmlNewDocFragment) xmlNewDocFragment __attribute((alias("xmlNewDocFragment__internal_alias")));
+#else
+#ifndef xmlNewDocFragment
+extern __typeof (xmlNewDocFragment) xmlNewDocFragment__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocFragment xmlNewDocFragment__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocNode
+extern __typeof (xmlNewDocNode) xmlNewDocNode __attribute((alias("xmlNewDocNode__internal_alias")));
+#else
+#ifndef xmlNewDocNode
+extern __typeof (xmlNewDocNode) xmlNewDocNode__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocNode xmlNewDocNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocNodeEatName
+extern __typeof (xmlNewDocNodeEatName) xmlNewDocNodeEatName __attribute((alias("xmlNewDocNodeEatName__internal_alias")));
+#else
+#ifndef xmlNewDocNodeEatName
+extern __typeof (xmlNewDocNodeEatName) xmlNewDocNodeEatName__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocNodeEatName xmlNewDocNodeEatName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocPI
+extern __typeof (xmlNewDocPI) xmlNewDocPI __attribute((alias("xmlNewDocPI__internal_alias")));
+#else
+#ifndef xmlNewDocPI
+extern __typeof (xmlNewDocPI) xmlNewDocPI__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocPI xmlNewDocPI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocProp
+extern __typeof (xmlNewDocProp) xmlNewDocProp __attribute((alias("xmlNewDocProp__internal_alias")));
+#else
+#ifndef xmlNewDocProp
+extern __typeof (xmlNewDocProp) xmlNewDocProp__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocProp xmlNewDocProp__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNewDocRawNode
+extern __typeof (xmlNewDocRawNode) xmlNewDocRawNode __attribute((alias("xmlNewDocRawNode__internal_alias")));
+#else
+#ifndef xmlNewDocRawNode
+extern __typeof (xmlNewDocRawNode) xmlNewDocRawNode__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocRawNode xmlNewDocRawNode__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocText
+extern __typeof (xmlNewDocText) xmlNewDocText __attribute((alias("xmlNewDocText__internal_alias")));
+#else
+#ifndef xmlNewDocText
+extern __typeof (xmlNewDocText) xmlNewDocText__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocText xmlNewDocText__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDocTextLen
+extern __typeof (xmlNewDocTextLen) xmlNewDocTextLen __attribute((alias("xmlNewDocTextLen__internal_alias")));
+#else
+#ifndef xmlNewDocTextLen
+extern __typeof (xmlNewDocTextLen) xmlNewDocTextLen__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDocTextLen xmlNewDocTextLen__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewDtd
+extern __typeof (xmlNewDtd) xmlNewDtd __attribute((alias("xmlNewDtd__internal_alias")));
+#else
+#ifndef xmlNewDtd
+extern __typeof (xmlNewDtd) xmlNewDtd__internal_alias __attribute((visibility("hidden")));
+#define xmlNewDtd xmlNewDtd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlNewElementContent
+extern __typeof (xmlNewElementContent) xmlNewElementContent __attribute((alias("xmlNewElementContent__internal_alias")));
+#else
+#ifndef xmlNewElementContent
+extern __typeof (xmlNewElementContent) xmlNewElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNewElementContent xmlNewElementContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_entities
+#undef xmlNewEntity
+extern __typeof (xmlNewEntity) xmlNewEntity __attribute((alias("xmlNewEntity__internal_alias")));
+#else
+#ifndef xmlNewEntity
+extern __typeof (xmlNewEntity) xmlNewEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlNewEntity xmlNewEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewEntityInputStream
+extern __typeof (xmlNewEntityInputStream) xmlNewEntityInputStream __attribute((alias("xmlNewEntityInputStream__internal_alias")));
+#else
+#ifndef xmlNewEntityInputStream
+extern __typeof (xmlNewEntityInputStream) xmlNewEntityInputStream__internal_alias __attribute((visibility("hidden")));
+#define xmlNewEntityInputStream xmlNewEntityInputStream__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlNewGlobalNs
+extern __typeof (xmlNewGlobalNs) xmlNewGlobalNs __attribute((alias("xmlNewGlobalNs__internal_alias")));
+#else
+#ifndef xmlNewGlobalNs
+extern __typeof (xmlNewGlobalNs) xmlNewGlobalNs__internal_alias __attribute((visibility("hidden")));
+#define xmlNewGlobalNs xmlNewGlobalNs__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewIOInputStream
+extern __typeof (xmlNewIOInputStream) xmlNewIOInputStream __attribute((alias("xmlNewIOInputStream__internal_alias")));
+#else
+#ifndef xmlNewIOInputStream
+extern __typeof (xmlNewIOInputStream) xmlNewIOInputStream__internal_alias __attribute((visibility("hidden")));
+#define xmlNewIOInputStream xmlNewIOInputStream__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewInputFromFile
+extern __typeof (xmlNewInputFromFile) xmlNewInputFromFile __attribute((alias("xmlNewInputFromFile__internal_alias")));
+#else
+#ifndef xmlNewInputFromFile
+extern __typeof (xmlNewInputFromFile) xmlNewInputFromFile__internal_alias __attribute((visibility("hidden")));
+#define xmlNewInputFromFile xmlNewInputFromFile__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewInputStream
+extern __typeof (xmlNewInputStream) xmlNewInputStream __attribute((alias("xmlNewInputStream__internal_alias")));
+#else
+#ifndef xmlNewInputStream
+extern __typeof (xmlNewInputStream) xmlNewInputStream__internal_alias __attribute((visibility("hidden")));
+#define xmlNewInputStream xmlNewInputStream__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlNewMutex
+extern __typeof (xmlNewMutex) xmlNewMutex __attribute((alias("xmlNewMutex__internal_alias")));
+#else
+#ifndef xmlNewMutex
+extern __typeof (xmlNewMutex) xmlNewMutex__internal_alias __attribute((visibility("hidden")));
+#define xmlNewMutex xmlNewMutex__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewNode
+extern __typeof (xmlNewNode) xmlNewNode __attribute((alias("xmlNewNode__internal_alias")));
+#else
+#ifndef xmlNewNode
+extern __typeof (xmlNewNode) xmlNewNode__internal_alias __attribute((visibility("hidden")));
+#define xmlNewNode xmlNewNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewNodeEatName
+extern __typeof (xmlNewNodeEatName) xmlNewNodeEatName __attribute((alias("xmlNewNodeEatName__internal_alias")));
+#else
+#ifndef xmlNewNodeEatName
+extern __typeof (xmlNewNodeEatName) xmlNewNodeEatName__internal_alias __attribute((visibility("hidden")));
+#define xmlNewNodeEatName xmlNewNodeEatName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewNs
+extern __typeof (xmlNewNs) xmlNewNs __attribute((alias("xmlNewNs__internal_alias")));
+#else
+#ifndef xmlNewNs
+extern __typeof (xmlNewNs) xmlNewNs__internal_alias __attribute((visibility("hidden")));
+#define xmlNewNs xmlNewNs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewNsProp
+extern __typeof (xmlNewNsProp) xmlNewNsProp __attribute((alias("xmlNewNsProp__internal_alias")));
+#else
+#ifndef xmlNewNsProp
+extern __typeof (xmlNewNsProp) xmlNewNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlNewNsProp xmlNewNsProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewNsPropEatName
+extern __typeof (xmlNewNsPropEatName) xmlNewNsPropEatName __attribute((alias("xmlNewNsPropEatName__internal_alias")));
+#else
+#ifndef xmlNewNsPropEatName
+extern __typeof (xmlNewNsPropEatName) xmlNewNsPropEatName__internal_alias __attribute((visibility("hidden")));
+#define xmlNewNsPropEatName xmlNewNsPropEatName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewPI
+extern __typeof (xmlNewPI) xmlNewPI __attribute((alias("xmlNewPI__internal_alias")));
+#else
+#ifndef xmlNewPI
+extern __typeof (xmlNewPI) xmlNewPI__internal_alias __attribute((visibility("hidden")));
+#define xmlNewPI xmlNewPI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewParserCtxt
+extern __typeof (xmlNewParserCtxt) xmlNewParserCtxt __attribute((alias("xmlNewParserCtxt__internal_alias")));
+#else
+#ifndef xmlNewParserCtxt
+extern __typeof (xmlNewParserCtxt) xmlNewParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlNewParserCtxt xmlNewParserCtxt__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlNewProp
+extern __typeof (xmlNewProp) xmlNewProp __attribute((alias("xmlNewProp__internal_alias")));
+#else
+#ifndef xmlNewProp
+extern __typeof (xmlNewProp) xmlNewProp__internal_alias __attribute((visibility("hidden")));
+#define xmlNewProp xmlNewProp__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlNewRMutex
+extern __typeof (xmlNewRMutex) xmlNewRMutex __attribute((alias("xmlNewRMutex__internal_alias")));
+#else
+#ifndef xmlNewRMutex
+extern __typeof (xmlNewRMutex) xmlNewRMutex__internal_alias __attribute((visibility("hidden")));
+#define xmlNewRMutex xmlNewRMutex__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewReference
+extern __typeof (xmlNewReference) xmlNewReference __attribute((alias("xmlNewReference__internal_alias")));
+#else
+#ifndef xmlNewReference
+extern __typeof (xmlNewReference) xmlNewReference__internal_alias __attribute((visibility("hidden")));
+#define xmlNewReference xmlNewReference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNewStringInputStream
+extern __typeof (xmlNewStringInputStream) xmlNewStringInputStream __attribute((alias("xmlNewStringInputStream__internal_alias")));
+#else
+#ifndef xmlNewStringInputStream
+extern __typeof (xmlNewStringInputStream) xmlNewStringInputStream__internal_alias __attribute((visibility("hidden")));
+#define xmlNewStringInputStream xmlNewStringInputStream__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewText
+extern __typeof (xmlNewText) xmlNewText __attribute((alias("xmlNewText__internal_alias")));
+#else
+#ifndef xmlNewText
+extern __typeof (xmlNewText) xmlNewText__internal_alias __attribute((visibility("hidden")));
+#define xmlNewText xmlNewText__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNewTextChild
+extern __typeof (xmlNewTextChild) xmlNewTextChild __attribute((alias("xmlNewTextChild__internal_alias")));
+#else
+#ifndef xmlNewTextChild
+extern __typeof (xmlNewTextChild) xmlNewTextChild__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextChild xmlNewTextChild__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNewTextLen
+extern __typeof (xmlNewTextLen) xmlNewTextLen __attribute((alias("xmlNewTextLen__internal_alias")));
+#else
+#ifndef xmlNewTextLen
+extern __typeof (xmlNewTextLen) xmlNewTextLen__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextLen xmlNewTextLen__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlNewTextReader
+extern __typeof (xmlNewTextReader) xmlNewTextReader __attribute((alias("xmlNewTextReader__internal_alias")));
+#else
+#ifndef xmlNewTextReader
+extern __typeof (xmlNewTextReader) xmlNewTextReader__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextReader xmlNewTextReader__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlNewTextReaderFilename
+extern __typeof (xmlNewTextReaderFilename) xmlNewTextReaderFilename __attribute((alias("xmlNewTextReaderFilename__internal_alias")));
+#else
+#ifndef xmlNewTextReaderFilename
+extern __typeof (xmlNewTextReaderFilename) xmlNewTextReaderFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextReaderFilename xmlNewTextReaderFilename__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriter
+extern __typeof (xmlNewTextWriter) xmlNewTextWriter __attribute((alias("xmlNewTextWriter__internal_alias")));
+#else
+#ifndef xmlNewTextWriter
+extern __typeof (xmlNewTextWriter) xmlNewTextWriter__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriter xmlNewTextWriter__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriterDoc
+extern __typeof (xmlNewTextWriterDoc) xmlNewTextWriterDoc __attribute((alias("xmlNewTextWriterDoc__internal_alias")));
+#else
+#ifndef xmlNewTextWriterDoc
+extern __typeof (xmlNewTextWriterDoc) xmlNewTextWriterDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriterDoc xmlNewTextWriterDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriterFilename
+extern __typeof (xmlNewTextWriterFilename) xmlNewTextWriterFilename __attribute((alias("xmlNewTextWriterFilename__internal_alias")));
+#else
+#ifndef xmlNewTextWriterFilename
+extern __typeof (xmlNewTextWriterFilename) xmlNewTextWriterFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriterFilename xmlNewTextWriterFilename__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriterMemory
+extern __typeof (xmlNewTextWriterMemory) xmlNewTextWriterMemory __attribute((alias("xmlNewTextWriterMemory__internal_alias")));
+#else
+#ifndef xmlNewTextWriterMemory
+extern __typeof (xmlNewTextWriterMemory) xmlNewTextWriterMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriterMemory xmlNewTextWriterMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriterPushParser
+extern __typeof (xmlNewTextWriterPushParser) xmlNewTextWriterPushParser __attribute((alias("xmlNewTextWriterPushParser__internal_alias")));
+#else
+#ifndef xmlNewTextWriterPushParser
+extern __typeof (xmlNewTextWriterPushParser) xmlNewTextWriterPushParser__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriterPushParser xmlNewTextWriterPushParser__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlNewTextWriterTree
+extern __typeof (xmlNewTextWriterTree) xmlNewTextWriterTree __attribute((alias("xmlNewTextWriterTree__internal_alias")));
+#else
+#ifndef xmlNewTextWriterTree
+extern __typeof (xmlNewTextWriterTree) xmlNewTextWriterTree__internal_alias __attribute((visibility("hidden")));
+#define xmlNewTextWriterTree xmlNewTextWriterTree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlNewValidCtxt
+extern __typeof (xmlNewValidCtxt) xmlNewValidCtxt __attribute((alias("xmlNewValidCtxt__internal_alias")));
+#else
+#ifndef xmlNewValidCtxt
+extern __typeof (xmlNewValidCtxt) xmlNewValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlNewValidCtxt xmlNewValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlNextChar
+extern __typeof (xmlNextChar) xmlNextChar __attribute((alias("xmlNextChar__internal_alias")));
+#else
+#ifndef xmlNextChar
+extern __typeof (xmlNextChar) xmlNextChar__internal_alias __attribute((visibility("hidden")));
+#define xmlNextChar xmlNextChar__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNextElementSibling
+extern __typeof (xmlNextElementSibling) xmlNextElementSibling __attribute((alias("xmlNextElementSibling__internal_alias")));
+#else
+#ifndef xmlNextElementSibling
+extern __typeof (xmlNextElementSibling) xmlNextElementSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlNextElementSibling xmlNextElementSibling__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlNoNetExternalEntityLoader
+extern __typeof (xmlNoNetExternalEntityLoader) xmlNoNetExternalEntityLoader __attribute((alias("xmlNoNetExternalEntityLoader__internal_alias")));
+#else
+#ifndef xmlNoNetExternalEntityLoader
+extern __typeof (xmlNoNetExternalEntityLoader) xmlNoNetExternalEntityLoader__internal_alias __attribute((visibility("hidden")));
+#define xmlNoNetExternalEntityLoader xmlNoNetExternalEntityLoader__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeAddContent
+extern __typeof (xmlNodeAddContent) xmlNodeAddContent __attribute((alias("xmlNodeAddContent__internal_alias")));
+#else
+#ifndef xmlNodeAddContent
+extern __typeof (xmlNodeAddContent) xmlNodeAddContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeAddContent xmlNodeAddContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeAddContentLen
+extern __typeof (xmlNodeAddContentLen) xmlNodeAddContentLen __attribute((alias("xmlNodeAddContentLen__internal_alias")));
+#else
+#ifndef xmlNodeAddContentLen
+extern __typeof (xmlNodeAddContentLen) xmlNodeAddContentLen__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeAddContentLen xmlNodeAddContentLen__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeBufGetContent
+extern __typeof (xmlNodeBufGetContent) xmlNodeBufGetContent __attribute((alias("xmlNodeBufGetContent__internal_alias")));
+#else
+#ifndef xmlNodeBufGetContent
+extern __typeof (xmlNodeBufGetContent) xmlNodeBufGetContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeBufGetContent xmlNodeBufGetContent__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlNodeDump
+extern __typeof (xmlNodeDump) xmlNodeDump __attribute((alias("xmlNodeDump__internal_alias")));
+#else
+#ifndef xmlNodeDump
+extern __typeof (xmlNodeDump) xmlNodeDump__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeDump xmlNodeDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlNodeDumpOutput
+extern __typeof (xmlNodeDumpOutput) xmlNodeDumpOutput __attribute((alias("xmlNodeDumpOutput__internal_alias")));
+#else
+#ifndef xmlNodeDumpOutput
+extern __typeof (xmlNodeDumpOutput) xmlNodeDumpOutput__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeDumpOutput xmlNodeDumpOutput__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeGetBase
+extern __typeof (xmlNodeGetBase) xmlNodeGetBase __attribute((alias("xmlNodeGetBase__internal_alias")));
+#else
+#ifndef xmlNodeGetBase
+extern __typeof (xmlNodeGetBase) xmlNodeGetBase__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeGetBase xmlNodeGetBase__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeGetContent
+extern __typeof (xmlNodeGetContent) xmlNodeGetContent __attribute((alias("xmlNodeGetContent__internal_alias")));
+#else
+#ifndef xmlNodeGetContent
+extern __typeof (xmlNodeGetContent) xmlNodeGetContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeGetContent xmlNodeGetContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeGetLang
+extern __typeof (xmlNodeGetLang) xmlNodeGetLang __attribute((alias("xmlNodeGetLang__internal_alias")));
+#else
+#ifndef xmlNodeGetLang
+extern __typeof (xmlNodeGetLang) xmlNodeGetLang__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeGetLang xmlNodeGetLang__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeGetSpacePreserve
+extern __typeof (xmlNodeGetSpacePreserve) xmlNodeGetSpacePreserve __attribute((alias("xmlNodeGetSpacePreserve__internal_alias")));
+#else
+#ifndef xmlNodeGetSpacePreserve
+extern __typeof (xmlNodeGetSpacePreserve) xmlNodeGetSpacePreserve__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeGetSpacePreserve xmlNodeGetSpacePreserve__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeIsText
+extern __typeof (xmlNodeIsText) xmlNodeIsText __attribute((alias("xmlNodeIsText__internal_alias")));
+#else
+#ifndef xmlNodeIsText
+extern __typeof (xmlNodeIsText) xmlNodeIsText__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeIsText xmlNodeIsText__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeListGetRawString
+extern __typeof (xmlNodeListGetRawString) xmlNodeListGetRawString __attribute((alias("xmlNodeListGetRawString__internal_alias")));
+#else
+#ifndef xmlNodeListGetRawString
+extern __typeof (xmlNodeListGetRawString) xmlNodeListGetRawString__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeListGetRawString xmlNodeListGetRawString__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeListGetString
+extern __typeof (xmlNodeListGetString) xmlNodeListGetString __attribute((alias("xmlNodeListGetString__internal_alias")));
+#else
+#ifndef xmlNodeListGetString
+extern __typeof (xmlNodeListGetString) xmlNodeListGetString__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeListGetString xmlNodeListGetString__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeSetBase
+extern __typeof (xmlNodeSetBase) xmlNodeSetBase __attribute((alias("xmlNodeSetBase__internal_alias")));
+#else
+#ifndef xmlNodeSetBase
+extern __typeof (xmlNodeSetBase) xmlNodeSetBase__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetBase xmlNodeSetBase__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlNodeSetContent
+extern __typeof (xmlNodeSetContent) xmlNodeSetContent __attribute((alias("xmlNodeSetContent__internal_alias")));
+#else
+#ifndef xmlNodeSetContent
+extern __typeof (xmlNodeSetContent) xmlNodeSetContent__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetContent xmlNodeSetContent__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeSetContentLen
+extern __typeof (xmlNodeSetContentLen) xmlNodeSetContentLen __attribute((alias("xmlNodeSetContentLen__internal_alias")));
+#else
+#ifndef xmlNodeSetContentLen
+extern __typeof (xmlNodeSetContentLen) xmlNodeSetContentLen__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetContentLen xmlNodeSetContentLen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeSetLang
+extern __typeof (xmlNodeSetLang) xmlNodeSetLang __attribute((alias("xmlNodeSetLang__internal_alias")));
+#else
+#ifndef xmlNodeSetLang
+extern __typeof (xmlNodeSetLang) xmlNodeSetLang__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetLang xmlNodeSetLang__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeSetName
+extern __typeof (xmlNodeSetName) xmlNodeSetName __attribute((alias("xmlNodeSetName__internal_alias")));
+#else
+#ifndef xmlNodeSetName
+extern __typeof (xmlNodeSetName) xmlNodeSetName__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetName xmlNodeSetName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlNodeSetSpacePreserve
+extern __typeof (xmlNodeSetSpacePreserve) xmlNodeSetSpacePreserve __attribute((alias("xmlNodeSetSpacePreserve__internal_alias")));
+#else
+#ifndef xmlNodeSetSpacePreserve
+extern __typeof (xmlNodeSetSpacePreserve) xmlNodeSetSpacePreserve__internal_alias __attribute((visibility("hidden")));
+#define xmlNodeSetSpacePreserve xmlNodeSetSpacePreserve__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlNormalizeURIPath
+extern __typeof (xmlNormalizeURIPath) xmlNormalizeURIPath __attribute((alias("xmlNormalizeURIPath__internal_alias")));
+#else
+#ifndef xmlNormalizeURIPath
+extern __typeof (xmlNormalizeURIPath) xmlNormalizeURIPath__internal_alias __attribute((visibility("hidden")));
+#define xmlNormalizeURIPath xmlNormalizeURIPath__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlNormalizeWindowsPath
+extern __typeof (xmlNormalizeWindowsPath) xmlNormalizeWindowsPath __attribute((alias("xmlNormalizeWindowsPath__internal_alias")));
+#else
+#ifndef xmlNormalizeWindowsPath
+extern __typeof (xmlNormalizeWindowsPath) xmlNormalizeWindowsPath__internal_alias __attribute((visibility("hidden")));
+#define xmlNormalizeWindowsPath xmlNormalizeWindowsPath__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferClose
+extern __typeof (xmlOutputBufferClose) xmlOutputBufferClose __attribute((alias("xmlOutputBufferClose__internal_alias")));
+#else
+#ifndef xmlOutputBufferClose
+extern __typeof (xmlOutputBufferClose) xmlOutputBufferClose__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferClose xmlOutputBufferClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateBuffer
+extern __typeof (xmlOutputBufferCreateBuffer) xmlOutputBufferCreateBuffer __attribute((alias("xmlOutputBufferCreateBuffer__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateBuffer
+extern __typeof (xmlOutputBufferCreateBuffer) xmlOutputBufferCreateBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateBuffer xmlOutputBufferCreateBuffer__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateFd
+extern __typeof (xmlOutputBufferCreateFd) xmlOutputBufferCreateFd __attribute((alias("xmlOutputBufferCreateFd__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateFd
+extern __typeof (xmlOutputBufferCreateFd) xmlOutputBufferCreateFd__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateFd xmlOutputBufferCreateFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateFile
+extern __typeof (xmlOutputBufferCreateFile) xmlOutputBufferCreateFile __attribute((alias("xmlOutputBufferCreateFile__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateFile
+extern __typeof (xmlOutputBufferCreateFile) xmlOutputBufferCreateFile__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateFile xmlOutputBufferCreateFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateFilename
+extern __typeof (xmlOutputBufferCreateFilename) xmlOutputBufferCreateFilename __attribute((alias("xmlOutputBufferCreateFilename__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateFilename
+extern __typeof (xmlOutputBufferCreateFilename) xmlOutputBufferCreateFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateFilename xmlOutputBufferCreateFilename__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateFilenameDefault
+extern __typeof (xmlOutputBufferCreateFilenameDefault) xmlOutputBufferCreateFilenameDefault __attribute((alias("xmlOutputBufferCreateFilenameDefault__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateFilenameDefault
+extern __typeof (xmlOutputBufferCreateFilenameDefault) xmlOutputBufferCreateFilenameDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateFilenameDefault xmlOutputBufferCreateFilenameDefault__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferCreateIO
+extern __typeof (xmlOutputBufferCreateIO) xmlOutputBufferCreateIO __attribute((alias("xmlOutputBufferCreateIO__internal_alias")));
+#else
+#ifndef xmlOutputBufferCreateIO
+extern __typeof (xmlOutputBufferCreateIO) xmlOutputBufferCreateIO__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferCreateIO xmlOutputBufferCreateIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferFlush
+extern __typeof (xmlOutputBufferFlush) xmlOutputBufferFlush __attribute((alias("xmlOutputBufferFlush__internal_alias")));
+#else
+#ifndef xmlOutputBufferFlush
+extern __typeof (xmlOutputBufferFlush) xmlOutputBufferFlush__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferFlush xmlOutputBufferFlush__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferWrite
+extern __typeof (xmlOutputBufferWrite) xmlOutputBufferWrite __attribute((alias("xmlOutputBufferWrite__internal_alias")));
+#else
+#ifndef xmlOutputBufferWrite
+extern __typeof (xmlOutputBufferWrite) xmlOutputBufferWrite__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferWrite xmlOutputBufferWrite__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferWriteEscape
+extern __typeof (xmlOutputBufferWriteEscape) xmlOutputBufferWriteEscape __attribute((alias("xmlOutputBufferWriteEscape__internal_alias")));
+#else
+#ifndef xmlOutputBufferWriteEscape
+extern __typeof (xmlOutputBufferWriteEscape) xmlOutputBufferWriteEscape__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferWriteEscape xmlOutputBufferWriteEscape__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlOutputBufferWriteString
+extern __typeof (xmlOutputBufferWriteString) xmlOutputBufferWriteString __attribute((alias("xmlOutputBufferWriteString__internal_alias")));
+#else
+#ifndef xmlOutputBufferWriteString
+extern __typeof (xmlOutputBufferWriteString) xmlOutputBufferWriteString__internal_alias __attribute((visibility("hidden")));
+#define xmlOutputBufferWriteString xmlOutputBufferWriteString__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseAttValue
+extern __typeof (xmlParseAttValue) xmlParseAttValue __attribute((alias("xmlParseAttValue__internal_alias")));
+#else
+#ifndef xmlParseAttValue
+extern __typeof (xmlParseAttValue) xmlParseAttValue__internal_alias __attribute((visibility("hidden")));
+#define xmlParseAttValue xmlParseAttValue__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseAttribute
+extern __typeof (xmlParseAttribute) xmlParseAttribute __attribute((alias("xmlParseAttribute__internal_alias")));
+#else
+#ifndef xmlParseAttribute
+extern __typeof (xmlParseAttribute) xmlParseAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlParseAttribute xmlParseAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseAttributeListDecl
+extern __typeof (xmlParseAttributeListDecl) xmlParseAttributeListDecl __attribute((alias("xmlParseAttributeListDecl__internal_alias")));
+#else
+#ifndef xmlParseAttributeListDecl
+extern __typeof (xmlParseAttributeListDecl) xmlParseAttributeListDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseAttributeListDecl xmlParseAttributeListDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseAttributeType
+extern __typeof (xmlParseAttributeType) xmlParseAttributeType __attribute((alias("xmlParseAttributeType__internal_alias")));
+#else
+#ifndef xmlParseAttributeType
+extern __typeof (xmlParseAttributeType) xmlParseAttributeType__internal_alias __attribute((visibility("hidden")));
+#define xmlParseAttributeType xmlParseAttributeType__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseBalancedChunkMemory
+extern __typeof (xmlParseBalancedChunkMemory) xmlParseBalancedChunkMemory __attribute((alias("xmlParseBalancedChunkMemory__internal_alias")));
+#else
+#ifndef xmlParseBalancedChunkMemory
+extern __typeof (xmlParseBalancedChunkMemory) xmlParseBalancedChunkMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlParseBalancedChunkMemory xmlParseBalancedChunkMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseBalancedChunkMemoryRecover
+extern __typeof (xmlParseBalancedChunkMemoryRecover) xmlParseBalancedChunkMemoryRecover __attribute((alias("xmlParseBalancedChunkMemoryRecover__internal_alias")));
+#else
+#ifndef xmlParseBalancedChunkMemoryRecover
+extern __typeof (xmlParseBalancedChunkMemoryRecover) xmlParseBalancedChunkMemoryRecover__internal_alias __attribute((visibility("hidden")));
+#define xmlParseBalancedChunkMemoryRecover xmlParseBalancedChunkMemoryRecover__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseCDSect
+extern __typeof (xmlParseCDSect) xmlParseCDSect __attribute((alias("xmlParseCDSect__internal_alias")));
+#else
+#ifndef xmlParseCDSect
+extern __typeof (xmlParseCDSect) xmlParseCDSect__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCDSect xmlParseCDSect__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_CATALOG_ENABLED)
+#ifdef bottom_catalog
+#undef xmlParseCatalogFile
+extern __typeof (xmlParseCatalogFile) xmlParseCatalogFile __attribute((alias("xmlParseCatalogFile__internal_alias")));
+#else
+#ifndef xmlParseCatalogFile
+extern __typeof (xmlParseCatalogFile) xmlParseCatalogFile__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCatalogFile xmlParseCatalogFile__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseCharData
+extern __typeof (xmlParseCharData) xmlParseCharData __attribute((alias("xmlParseCharData__internal_alias")));
+#else
+#ifndef xmlParseCharData
+extern __typeof (xmlParseCharData) xmlParseCharData__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCharData xmlParseCharData__internal_alias
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlParseCharEncoding
+extern __typeof (xmlParseCharEncoding) xmlParseCharEncoding __attribute((alias("xmlParseCharEncoding__internal_alias")));
+#else
+#ifndef xmlParseCharEncoding
+extern __typeof (xmlParseCharEncoding) xmlParseCharEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCharEncoding xmlParseCharEncoding__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseCharRef
+extern __typeof (xmlParseCharRef) xmlParseCharRef __attribute((alias("xmlParseCharRef__internal_alias")));
+#else
+#ifndef xmlParseCharRef
+extern __typeof (xmlParseCharRef) xmlParseCharRef__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCharRef xmlParseCharRef__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PUSH_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseChunk
+extern __typeof (xmlParseChunk) xmlParseChunk __attribute((alias("xmlParseChunk__internal_alias")));
+#else
+#ifndef xmlParseChunk
+extern __typeof (xmlParseChunk) xmlParseChunk__internal_alias __attribute((visibility("hidden")));
+#define xmlParseChunk xmlParseChunk__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseComment
+extern __typeof (xmlParseComment) xmlParseComment __attribute((alias("xmlParseComment__internal_alias")));
+#else
+#ifndef xmlParseComment
+extern __typeof (xmlParseComment) xmlParseComment__internal_alias __attribute((visibility("hidden")));
+#define xmlParseComment xmlParseComment__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseContent
+extern __typeof (xmlParseContent) xmlParseContent __attribute((alias("xmlParseContent__internal_alias")));
+#else
+#ifndef xmlParseContent
+extern __typeof (xmlParseContent) xmlParseContent__internal_alias __attribute((visibility("hidden")));
+#define xmlParseContent xmlParseContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseCtxtExternalEntity
+extern __typeof (xmlParseCtxtExternalEntity) xmlParseCtxtExternalEntity __attribute((alias("xmlParseCtxtExternalEntity__internal_alias")));
+#else
+#ifndef xmlParseCtxtExternalEntity
+extern __typeof (xmlParseCtxtExternalEntity) xmlParseCtxtExternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlParseCtxtExternalEntity xmlParseCtxtExternalEntity__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseDTD
+extern __typeof (xmlParseDTD) xmlParseDTD __attribute((alias("xmlParseDTD__internal_alias")));
+#else
+#ifndef xmlParseDTD
+extern __typeof (xmlParseDTD) xmlParseDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlParseDTD xmlParseDTD__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseDefaultDecl
+extern __typeof (xmlParseDefaultDecl) xmlParseDefaultDecl __attribute((alias("xmlParseDefaultDecl__internal_alias")));
+#else
+#ifndef xmlParseDefaultDecl
+extern __typeof (xmlParseDefaultDecl) xmlParseDefaultDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseDefaultDecl xmlParseDefaultDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseDoc
+extern __typeof (xmlParseDoc) xmlParseDoc __attribute((alias("xmlParseDoc__internal_alias")));
+#else
+#ifndef xmlParseDoc
+extern __typeof (xmlParseDoc) xmlParseDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlParseDoc xmlParseDoc__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseDocTypeDecl
+extern __typeof (xmlParseDocTypeDecl) xmlParseDocTypeDecl __attribute((alias("xmlParseDocTypeDecl__internal_alias")));
+#else
+#ifndef xmlParseDocTypeDecl
+extern __typeof (xmlParseDocTypeDecl) xmlParseDocTypeDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseDocTypeDecl xmlParseDocTypeDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseDocument
+extern __typeof (xmlParseDocument) xmlParseDocument __attribute((alias("xmlParseDocument__internal_alias")));
+#else
+#ifndef xmlParseDocument
+extern __typeof (xmlParseDocument) xmlParseDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlParseDocument xmlParseDocument__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseElement
+extern __typeof (xmlParseElement) xmlParseElement __attribute((alias("xmlParseElement__internal_alias")));
+#else
+#ifndef xmlParseElement
+extern __typeof (xmlParseElement) xmlParseElement__internal_alias __attribute((visibility("hidden")));
+#define xmlParseElement xmlParseElement__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseElementChildrenContentDecl
+extern __typeof (xmlParseElementChildrenContentDecl) xmlParseElementChildrenContentDecl __attribute((alias("xmlParseElementChildrenContentDecl__internal_alias")));
+#else
+#ifndef xmlParseElementChildrenContentDecl
+extern __typeof (xmlParseElementChildrenContentDecl) xmlParseElementChildrenContentDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseElementChildrenContentDecl xmlParseElementChildrenContentDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseElementContentDecl
+extern __typeof (xmlParseElementContentDecl) xmlParseElementContentDecl __attribute((alias("xmlParseElementContentDecl__internal_alias")));
+#else
+#ifndef xmlParseElementContentDecl
+extern __typeof (xmlParseElementContentDecl) xmlParseElementContentDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseElementContentDecl xmlParseElementContentDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseElementDecl
+extern __typeof (xmlParseElementDecl) xmlParseElementDecl __attribute((alias("xmlParseElementDecl__internal_alias")));
+#else
+#ifndef xmlParseElementDecl
+extern __typeof (xmlParseElementDecl) xmlParseElementDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseElementDecl xmlParseElementDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseElementMixedContentDecl
+extern __typeof (xmlParseElementMixedContentDecl) xmlParseElementMixedContentDecl __attribute((alias("xmlParseElementMixedContentDecl__internal_alias")));
+#else
+#ifndef xmlParseElementMixedContentDecl
+extern __typeof (xmlParseElementMixedContentDecl) xmlParseElementMixedContentDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseElementMixedContentDecl xmlParseElementMixedContentDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEncName
+extern __typeof (xmlParseEncName) xmlParseEncName __attribute((alias("xmlParseEncName__internal_alias")));
+#else
+#ifndef xmlParseEncName
+extern __typeof (xmlParseEncName) xmlParseEncName__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEncName xmlParseEncName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEncodingDecl
+extern __typeof (xmlParseEncodingDecl) xmlParseEncodingDecl __attribute((alias("xmlParseEncodingDecl__internal_alias")));
+#else
+#ifndef xmlParseEncodingDecl
+extern __typeof (xmlParseEncodingDecl) xmlParseEncodingDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEncodingDecl xmlParseEncodingDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseEndTag
+extern __typeof (xmlParseEndTag) xmlParseEndTag __attribute((alias("xmlParseEndTag__internal_alias")));
+#else
+#ifndef xmlParseEndTag
+extern __typeof (xmlParseEndTag) xmlParseEndTag__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEndTag xmlParseEndTag__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseEntity
+extern __typeof (xmlParseEntity) xmlParseEntity __attribute((alias("xmlParseEntity__internal_alias")));
+#else
+#ifndef xmlParseEntity
+extern __typeof (xmlParseEntity) xmlParseEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEntity xmlParseEntity__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEntityDecl
+extern __typeof (xmlParseEntityDecl) xmlParseEntityDecl __attribute((alias("xmlParseEntityDecl__internal_alias")));
+#else
+#ifndef xmlParseEntityDecl
+extern __typeof (xmlParseEntityDecl) xmlParseEntityDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEntityDecl xmlParseEntityDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEntityRef
+extern __typeof (xmlParseEntityRef) xmlParseEntityRef __attribute((alias("xmlParseEntityRef__internal_alias")));
+#else
+#ifndef xmlParseEntityRef
+extern __typeof (xmlParseEntityRef) xmlParseEntityRef__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEntityRef xmlParseEntityRef__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEntityValue
+extern __typeof (xmlParseEntityValue) xmlParseEntityValue __attribute((alias("xmlParseEntityValue__internal_alias")));
+#else
+#ifndef xmlParseEntityValue
+extern __typeof (xmlParseEntityValue) xmlParseEntityValue__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEntityValue xmlParseEntityValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEnumeratedType
+extern __typeof (xmlParseEnumeratedType) xmlParseEnumeratedType __attribute((alias("xmlParseEnumeratedType__internal_alias")));
+#else
+#ifndef xmlParseEnumeratedType
+extern __typeof (xmlParseEnumeratedType) xmlParseEnumeratedType__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEnumeratedType xmlParseEnumeratedType__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseEnumerationType
+extern __typeof (xmlParseEnumerationType) xmlParseEnumerationType __attribute((alias("xmlParseEnumerationType__internal_alias")));
+#else
+#ifndef xmlParseEnumerationType
+extern __typeof (xmlParseEnumerationType) xmlParseEnumerationType__internal_alias __attribute((visibility("hidden")));
+#define xmlParseEnumerationType xmlParseEnumerationType__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseExtParsedEnt
+extern __typeof (xmlParseExtParsedEnt) xmlParseExtParsedEnt __attribute((alias("xmlParseExtParsedEnt__internal_alias")));
+#else
+#ifndef xmlParseExtParsedEnt
+extern __typeof (xmlParseExtParsedEnt) xmlParseExtParsedEnt__internal_alias __attribute((visibility("hidden")));
+#define xmlParseExtParsedEnt xmlParseExtParsedEnt__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseExternalEntity
+extern __typeof (xmlParseExternalEntity) xmlParseExternalEntity __attribute((alias("xmlParseExternalEntity__internal_alias")));
+#else
+#ifndef xmlParseExternalEntity
+extern __typeof (xmlParseExternalEntity) xmlParseExternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlParseExternalEntity xmlParseExternalEntity__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseExternalID
+extern __typeof (xmlParseExternalID) xmlParseExternalID __attribute((alias("xmlParseExternalID__internal_alias")));
+#else
+#ifndef xmlParseExternalID
+extern __typeof (xmlParseExternalID) xmlParseExternalID__internal_alias __attribute((visibility("hidden")));
+#define xmlParseExternalID xmlParseExternalID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseExternalSubset
+extern __typeof (xmlParseExternalSubset) xmlParseExternalSubset __attribute((alias("xmlParseExternalSubset__internal_alias")));
+#else
+#ifndef xmlParseExternalSubset
+extern __typeof (xmlParseExternalSubset) xmlParseExternalSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlParseExternalSubset xmlParseExternalSubset__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseFile
+extern __typeof (xmlParseFile) xmlParseFile __attribute((alias("xmlParseFile__internal_alias")));
+#else
+#ifndef xmlParseFile
+extern __typeof (xmlParseFile) xmlParseFile__internal_alias __attribute((visibility("hidden")));
+#define xmlParseFile xmlParseFile__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseInNodeContext
+extern __typeof (xmlParseInNodeContext) xmlParseInNodeContext __attribute((alias("xmlParseInNodeContext__internal_alias")));
+#else
+#ifndef xmlParseInNodeContext
+extern __typeof (xmlParseInNodeContext) xmlParseInNodeContext__internal_alias __attribute((visibility("hidden")));
+#define xmlParseInNodeContext xmlParseInNodeContext__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseMarkupDecl
+extern __typeof (xmlParseMarkupDecl) xmlParseMarkupDecl __attribute((alias("xmlParseMarkupDecl__internal_alias")));
+#else
+#ifndef xmlParseMarkupDecl
+extern __typeof (xmlParseMarkupDecl) xmlParseMarkupDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseMarkupDecl xmlParseMarkupDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseMemory
+extern __typeof (xmlParseMemory) xmlParseMemory __attribute((alias("xmlParseMemory__internal_alias")));
+#else
+#ifndef xmlParseMemory
+extern __typeof (xmlParseMemory) xmlParseMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlParseMemory xmlParseMemory__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseMisc
+extern __typeof (xmlParseMisc) xmlParseMisc __attribute((alias("xmlParseMisc__internal_alias")));
+#else
+#ifndef xmlParseMisc
+extern __typeof (xmlParseMisc) xmlParseMisc__internal_alias __attribute((visibility("hidden")));
+#define xmlParseMisc xmlParseMisc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseName
+extern __typeof (xmlParseName) xmlParseName __attribute((alias("xmlParseName__internal_alias")));
+#else
+#ifndef xmlParseName
+extern __typeof (xmlParseName) xmlParseName__internal_alias __attribute((visibility("hidden")));
+#define xmlParseName xmlParseName__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlParseNamespace
+extern __typeof (xmlParseNamespace) xmlParseNamespace __attribute((alias("xmlParseNamespace__internal_alias")));
+#else
+#ifndef xmlParseNamespace
+extern __typeof (xmlParseNamespace) xmlParseNamespace__internal_alias __attribute((visibility("hidden")));
+#define xmlParseNamespace xmlParseNamespace__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseNmtoken
+extern __typeof (xmlParseNmtoken) xmlParseNmtoken __attribute((alias("xmlParseNmtoken__internal_alias")));
+#else
+#ifndef xmlParseNmtoken
+extern __typeof (xmlParseNmtoken) xmlParseNmtoken__internal_alias __attribute((visibility("hidden")));
+#define xmlParseNmtoken xmlParseNmtoken__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseNotationDecl
+extern __typeof (xmlParseNotationDecl) xmlParseNotationDecl __attribute((alias("xmlParseNotationDecl__internal_alias")));
+#else
+#ifndef xmlParseNotationDecl
+extern __typeof (xmlParseNotationDecl) xmlParseNotationDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseNotationDecl xmlParseNotationDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseNotationType
+extern __typeof (xmlParseNotationType) xmlParseNotationType __attribute((alias("xmlParseNotationType__internal_alias")));
+#else
+#ifndef xmlParseNotationType
+extern __typeof (xmlParseNotationType) xmlParseNotationType__internal_alias __attribute((visibility("hidden")));
+#define xmlParseNotationType xmlParseNotationType__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParsePEReference
+extern __typeof (xmlParsePEReference) xmlParsePEReference __attribute((alias("xmlParsePEReference__internal_alias")));
+#else
+#ifndef xmlParsePEReference
+extern __typeof (xmlParsePEReference) xmlParsePEReference__internal_alias __attribute((visibility("hidden")));
+#define xmlParsePEReference xmlParsePEReference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParsePI
+extern __typeof (xmlParsePI) xmlParsePI __attribute((alias("xmlParsePI__internal_alias")));
+#else
+#ifndef xmlParsePI
+extern __typeof (xmlParsePI) xmlParsePI__internal_alias __attribute((visibility("hidden")));
+#define xmlParsePI xmlParsePI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParsePITarget
+extern __typeof (xmlParsePITarget) xmlParsePITarget __attribute((alias("xmlParsePITarget__internal_alias")));
+#else
+#ifndef xmlParsePITarget
+extern __typeof (xmlParsePITarget) xmlParsePITarget__internal_alias __attribute((visibility("hidden")));
+#define xmlParsePITarget xmlParsePITarget__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParsePubidLiteral
+extern __typeof (xmlParsePubidLiteral) xmlParsePubidLiteral __attribute((alias("xmlParsePubidLiteral__internal_alias")));
+#else
+#ifndef xmlParsePubidLiteral
+extern __typeof (xmlParsePubidLiteral) xmlParsePubidLiteral__internal_alias __attribute((visibility("hidden")));
+#define xmlParsePubidLiteral xmlParsePubidLiteral__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlParseQuotedString
+extern __typeof (xmlParseQuotedString) xmlParseQuotedString __attribute((alias("xmlParseQuotedString__internal_alias")));
+#else
+#ifndef xmlParseQuotedString
+extern __typeof (xmlParseQuotedString) xmlParseQuotedString__internal_alias __attribute((visibility("hidden")));
+#define xmlParseQuotedString xmlParseQuotedString__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseReference
+extern __typeof (xmlParseReference) xmlParseReference __attribute((alias("xmlParseReference__internal_alias")));
+#else
+#ifndef xmlParseReference
+extern __typeof (xmlParseReference) xmlParseReference__internal_alias __attribute((visibility("hidden")));
+#define xmlParseReference xmlParseReference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseSDDecl
+extern __typeof (xmlParseSDDecl) xmlParseSDDecl __attribute((alias("xmlParseSDDecl__internal_alias")));
+#else
+#ifndef xmlParseSDDecl
+extern __typeof (xmlParseSDDecl) xmlParseSDDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseSDDecl xmlParseSDDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlParseStartTag
+extern __typeof (xmlParseStartTag) xmlParseStartTag __attribute((alias("xmlParseStartTag__internal_alias")));
+#else
+#ifndef xmlParseStartTag
+extern __typeof (xmlParseStartTag) xmlParseStartTag__internal_alias __attribute((visibility("hidden")));
+#define xmlParseStartTag xmlParseStartTag__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseSystemLiteral
+extern __typeof (xmlParseSystemLiteral) xmlParseSystemLiteral __attribute((alias("xmlParseSystemLiteral__internal_alias")));
+#else
+#ifndef xmlParseSystemLiteral
+extern __typeof (xmlParseSystemLiteral) xmlParseSystemLiteral__internal_alias __attribute((visibility("hidden")));
+#define xmlParseSystemLiteral xmlParseSystemLiteral__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseTextDecl
+extern __typeof (xmlParseTextDecl) xmlParseTextDecl __attribute((alias("xmlParseTextDecl__internal_alias")));
+#else
+#ifndef xmlParseTextDecl
+extern __typeof (xmlParseTextDecl) xmlParseTextDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseTextDecl xmlParseTextDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlParseURI
+extern __typeof (xmlParseURI) xmlParseURI __attribute((alias("xmlParseURI__internal_alias")));
+#else
+#ifndef xmlParseURI
+extern __typeof (xmlParseURI) xmlParseURI__internal_alias __attribute((visibility("hidden")));
+#define xmlParseURI xmlParseURI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlParseURIRaw
+extern __typeof (xmlParseURIRaw) xmlParseURIRaw __attribute((alias("xmlParseURIRaw__internal_alias")));
+#else
+#ifndef xmlParseURIRaw
+extern __typeof (xmlParseURIRaw) xmlParseURIRaw__internal_alias __attribute((visibility("hidden")));
+#define xmlParseURIRaw xmlParseURIRaw__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlParseURIReference
+extern __typeof (xmlParseURIReference) xmlParseURIReference __attribute((alias("xmlParseURIReference__internal_alias")));
+#else
+#ifndef xmlParseURIReference
+extern __typeof (xmlParseURIReference) xmlParseURIReference__internal_alias __attribute((visibility("hidden")));
+#define xmlParseURIReference xmlParseURIReference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseVersionInfo
+extern __typeof (xmlParseVersionInfo) xmlParseVersionInfo __attribute((alias("xmlParseVersionInfo__internal_alias")));
+#else
+#ifndef xmlParseVersionInfo
+extern __typeof (xmlParseVersionInfo) xmlParseVersionInfo__internal_alias __attribute((visibility("hidden")));
+#define xmlParseVersionInfo xmlParseVersionInfo__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseVersionNum
+extern __typeof (xmlParseVersionNum) xmlParseVersionNum __attribute((alias("xmlParseVersionNum__internal_alias")));
+#else
+#ifndef xmlParseVersionNum
+extern __typeof (xmlParseVersionNum) xmlParseVersionNum__internal_alias __attribute((visibility("hidden")));
+#define xmlParseVersionNum xmlParseVersionNum__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParseXMLDecl
+extern __typeof (xmlParseXMLDecl) xmlParseXMLDecl __attribute((alias("xmlParseXMLDecl__internal_alias")));
+#else
+#ifndef xmlParseXMLDecl
+extern __typeof (xmlParseXMLDecl) xmlParseXMLDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlParseXMLDecl xmlParseXMLDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserAddNodeInfo
+extern __typeof (xmlParserAddNodeInfo) xmlParserAddNodeInfo __attribute((alias("xmlParserAddNodeInfo__internal_alias")));
+#else
+#ifndef xmlParserAddNodeInfo
+extern __typeof (xmlParserAddNodeInfo) xmlParserAddNodeInfo__internal_alias __attribute((visibility("hidden")));
+#define xmlParserAddNodeInfo xmlParserAddNodeInfo__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserError
+extern __typeof (xmlParserError) xmlParserError __attribute((alias("xmlParserError__internal_alias")));
+#else
+#ifndef xmlParserError
+extern __typeof (xmlParserError) xmlParserError__internal_alias __attribute((visibility("hidden")));
+#define xmlParserError xmlParserError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserFindNodeInfo
+extern __typeof (xmlParserFindNodeInfo) xmlParserFindNodeInfo __attribute((alias("xmlParserFindNodeInfo__internal_alias")));
+#else
+#ifndef xmlParserFindNodeInfo
+extern __typeof (xmlParserFindNodeInfo) xmlParserFindNodeInfo__internal_alias __attribute((visibility("hidden")));
+#define xmlParserFindNodeInfo xmlParserFindNodeInfo__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserFindNodeInfoIndex
+extern __typeof (xmlParserFindNodeInfoIndex) xmlParserFindNodeInfoIndex __attribute((alias("xmlParserFindNodeInfoIndex__internal_alias")));
+#else
+#ifndef xmlParserFindNodeInfoIndex
+extern __typeof (xmlParserFindNodeInfoIndex) xmlParserFindNodeInfoIndex__internal_alias __attribute((visibility("hidden")));
+#define xmlParserFindNodeInfoIndex xmlParserFindNodeInfoIndex__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserGetDirectory
+extern __typeof (xmlParserGetDirectory) xmlParserGetDirectory __attribute((alias("xmlParserGetDirectory__internal_alias")));
+#else
+#ifndef xmlParserGetDirectory
+extern __typeof (xmlParserGetDirectory) xmlParserGetDirectory__internal_alias __attribute((visibility("hidden")));
+#define xmlParserGetDirectory xmlParserGetDirectory__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlParserHandlePEReference
+extern __typeof (xmlParserHandlePEReference) xmlParserHandlePEReference __attribute((alias("xmlParserHandlePEReference__internal_alias")));
+#else
+#ifndef xmlParserHandlePEReference
+extern __typeof (xmlParserHandlePEReference) xmlParserHandlePEReference__internal_alias __attribute((visibility("hidden")));
+#define xmlParserHandlePEReference xmlParserHandlePEReference__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlParserHandleReference
+extern __typeof (xmlParserHandleReference) xmlParserHandleReference __attribute((alias("xmlParserHandleReference__internal_alias")));
+#else
+#ifndef xmlParserHandleReference
+extern __typeof (xmlParserHandleReference) xmlParserHandleReference__internal_alias __attribute((visibility("hidden")));
+#define xmlParserHandleReference xmlParserHandleReference__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateFd
+extern __typeof (xmlParserInputBufferCreateFd) xmlParserInputBufferCreateFd __attribute((alias("xmlParserInputBufferCreateFd__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateFd
+extern __typeof (xmlParserInputBufferCreateFd) xmlParserInputBufferCreateFd__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateFd xmlParserInputBufferCreateFd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateFile
+extern __typeof (xmlParserInputBufferCreateFile) xmlParserInputBufferCreateFile __attribute((alias("xmlParserInputBufferCreateFile__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateFile
+extern __typeof (xmlParserInputBufferCreateFile) xmlParserInputBufferCreateFile__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateFile xmlParserInputBufferCreateFile__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateFilename
+extern __typeof (xmlParserInputBufferCreateFilename) xmlParserInputBufferCreateFilename __attribute((alias("xmlParserInputBufferCreateFilename__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateFilename
+extern __typeof (xmlParserInputBufferCreateFilename) xmlParserInputBufferCreateFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateFilename xmlParserInputBufferCreateFilename__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateFilenameDefault
+extern __typeof (xmlParserInputBufferCreateFilenameDefault) xmlParserInputBufferCreateFilenameDefault __attribute((alias("xmlParserInputBufferCreateFilenameDefault__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateFilenameDefault
+extern __typeof (xmlParserInputBufferCreateFilenameDefault) xmlParserInputBufferCreateFilenameDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateFilenameDefault xmlParserInputBufferCreateFilenameDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateIO
+extern __typeof (xmlParserInputBufferCreateIO) xmlParserInputBufferCreateIO __attribute((alias("xmlParserInputBufferCreateIO__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateIO
+extern __typeof (xmlParserInputBufferCreateIO) xmlParserInputBufferCreateIO__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateIO xmlParserInputBufferCreateIO__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateMem
+extern __typeof (xmlParserInputBufferCreateMem) xmlParserInputBufferCreateMem __attribute((alias("xmlParserInputBufferCreateMem__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateMem
+extern __typeof (xmlParserInputBufferCreateMem) xmlParserInputBufferCreateMem__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateMem xmlParserInputBufferCreateMem__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferCreateStatic
+extern __typeof (xmlParserInputBufferCreateStatic) xmlParserInputBufferCreateStatic __attribute((alias("xmlParserInputBufferCreateStatic__internal_alias")));
+#else
+#ifndef xmlParserInputBufferCreateStatic
+extern __typeof (xmlParserInputBufferCreateStatic) xmlParserInputBufferCreateStatic__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferCreateStatic xmlParserInputBufferCreateStatic__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferGrow
+extern __typeof (xmlParserInputBufferGrow) xmlParserInputBufferGrow __attribute((alias("xmlParserInputBufferGrow__internal_alias")));
+#else
+#ifndef xmlParserInputBufferGrow
+extern __typeof (xmlParserInputBufferGrow) xmlParserInputBufferGrow__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferGrow xmlParserInputBufferGrow__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferPush
+extern __typeof (xmlParserInputBufferPush) xmlParserInputBufferPush __attribute((alias("xmlParserInputBufferPush__internal_alias")));
+#else
+#ifndef xmlParserInputBufferPush
+extern __typeof (xmlParserInputBufferPush) xmlParserInputBufferPush__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferPush xmlParserInputBufferPush__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlParserInputBufferRead
+extern __typeof (xmlParserInputBufferRead) xmlParserInputBufferRead __attribute((alias("xmlParserInputBufferRead__internal_alias")));
+#else
+#ifndef xmlParserInputBufferRead
+extern __typeof (xmlParserInputBufferRead) xmlParserInputBufferRead__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputBufferRead xmlParserInputBufferRead__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserInputGrow
+extern __typeof (xmlParserInputGrow) xmlParserInputGrow __attribute((alias("xmlParserInputGrow__internal_alias")));
+#else
+#ifndef xmlParserInputGrow
+extern __typeof (xmlParserInputGrow) xmlParserInputGrow__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputGrow xmlParserInputGrow__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserInputRead
+extern __typeof (xmlParserInputRead) xmlParserInputRead __attribute((alias("xmlParserInputRead__internal_alias")));
+#else
+#ifndef xmlParserInputRead
+extern __typeof (xmlParserInputRead) xmlParserInputRead__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputRead xmlParserInputRead__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlParserInputShrink
+extern __typeof (xmlParserInputShrink) xmlParserInputShrink __attribute((alias("xmlParserInputShrink__internal_alias")));
+#else
+#ifndef xmlParserInputShrink
+extern __typeof (xmlParserInputShrink) xmlParserInputShrink__internal_alias __attribute((visibility("hidden")));
+#define xmlParserInputShrink xmlParserInputShrink__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserPrintFileContext
+extern __typeof (xmlParserPrintFileContext) xmlParserPrintFileContext __attribute((alias("xmlParserPrintFileContext__internal_alias")));
+#else
+#ifndef xmlParserPrintFileContext
+extern __typeof (xmlParserPrintFileContext) xmlParserPrintFileContext__internal_alias __attribute((visibility("hidden")));
+#define xmlParserPrintFileContext xmlParserPrintFileContext__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserPrintFileInfo
+extern __typeof (xmlParserPrintFileInfo) xmlParserPrintFileInfo __attribute((alias("xmlParserPrintFileInfo__internal_alias")));
+#else
+#ifndef xmlParserPrintFileInfo
+extern __typeof (xmlParserPrintFileInfo) xmlParserPrintFileInfo__internal_alias __attribute((visibility("hidden")));
+#define xmlParserPrintFileInfo xmlParserPrintFileInfo__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserValidityError
+extern __typeof (xmlParserValidityError) xmlParserValidityError __attribute((alias("xmlParserValidityError__internal_alias")));
+#else
+#ifndef xmlParserValidityError
+extern __typeof (xmlParserValidityError) xmlParserValidityError__internal_alias __attribute((visibility("hidden")));
+#define xmlParserValidityError xmlParserValidityError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserValidityWarning
+extern __typeof (xmlParserValidityWarning) xmlParserValidityWarning __attribute((alias("xmlParserValidityWarning__internal_alias")));
+#else
+#ifndef xmlParserValidityWarning
+extern __typeof (xmlParserValidityWarning) xmlParserValidityWarning__internal_alias __attribute((visibility("hidden")));
+#define xmlParserValidityWarning xmlParserValidityWarning__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlParserWarning
+extern __typeof (xmlParserWarning) xmlParserWarning __attribute((alias("xmlParserWarning__internal_alias")));
+#else
+#ifndef xmlParserWarning
+extern __typeof (xmlParserWarning) xmlParserWarning__internal_alias __attribute((visibility("hidden")));
+#define xmlParserWarning xmlParserWarning__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlPathToURI
+extern __typeof (xmlPathToURI) xmlPathToURI __attribute((alias("xmlPathToURI__internal_alias")));
+#else
+#ifndef xmlPathToURI
+extern __typeof (xmlPathToURI) xmlPathToURI__internal_alias __attribute((visibility("hidden")));
+#define xmlPathToURI xmlPathToURI__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternFromRoot
+extern __typeof (xmlPatternFromRoot) xmlPatternFromRoot __attribute((alias("xmlPatternFromRoot__internal_alias")));
+#else
+#ifndef xmlPatternFromRoot
+extern __typeof (xmlPatternFromRoot) xmlPatternFromRoot__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternFromRoot xmlPatternFromRoot__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternGetStreamCtxt
+extern __typeof (xmlPatternGetStreamCtxt) xmlPatternGetStreamCtxt __attribute((alias("xmlPatternGetStreamCtxt__internal_alias")));
+#else
+#ifndef xmlPatternGetStreamCtxt
+extern __typeof (xmlPatternGetStreamCtxt) xmlPatternGetStreamCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternGetStreamCtxt xmlPatternGetStreamCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternMatch
+extern __typeof (xmlPatternMatch) xmlPatternMatch __attribute((alias("xmlPatternMatch__internal_alias")));
+#else
+#ifndef xmlPatternMatch
+extern __typeof (xmlPatternMatch) xmlPatternMatch__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternMatch xmlPatternMatch__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternMaxDepth
+extern __typeof (xmlPatternMaxDepth) xmlPatternMaxDepth __attribute((alias("xmlPatternMaxDepth__internal_alias")));
+#else
+#ifndef xmlPatternMaxDepth
+extern __typeof (xmlPatternMaxDepth) xmlPatternMaxDepth__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternMaxDepth xmlPatternMaxDepth__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternMinDepth
+extern __typeof (xmlPatternMinDepth) xmlPatternMinDepth __attribute((alias("xmlPatternMinDepth__internal_alias")));
+#else
+#ifndef xmlPatternMinDepth
+extern __typeof (xmlPatternMinDepth) xmlPatternMinDepth__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternMinDepth xmlPatternMinDepth__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatternStreamable
+extern __typeof (xmlPatternStreamable) xmlPatternStreamable __attribute((alias("xmlPatternStreamable__internal_alias")));
+#else
+#ifndef xmlPatternStreamable
+extern __typeof (xmlPatternStreamable) xmlPatternStreamable__internal_alias __attribute((visibility("hidden")));
+#define xmlPatternStreamable xmlPatternStreamable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlPatterncompile
+extern __typeof (xmlPatterncompile) xmlPatterncompile __attribute((alias("xmlPatterncompile__internal_alias")));
+#else
+#ifndef xmlPatterncompile
+extern __typeof (xmlPatterncompile) xmlPatterncompile__internal_alias __attribute((visibility("hidden")));
+#define xmlPatterncompile xmlPatterncompile__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlPedanticParserDefault
+extern __typeof (xmlPedanticParserDefault) xmlPedanticParserDefault __attribute((alias("xmlPedanticParserDefault__internal_alias")));
+#else
+#ifndef xmlPedanticParserDefault
+extern __typeof (xmlPedanticParserDefault) xmlPedanticParserDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlPedanticParserDefault xmlPedanticParserDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlPopInput
+extern __typeof (xmlPopInput) xmlPopInput __attribute((alias("xmlPopInput__internal_alias")));
+#else
+#ifndef xmlPopInput
+extern __typeof (xmlPopInput) xmlPopInput__internal_alias __attribute((visibility("hidden")));
+#define xmlPopInput xmlPopInput__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlPopInputCallbacks
+extern __typeof (xmlPopInputCallbacks) xmlPopInputCallbacks __attribute((alias("xmlPopInputCallbacks__internal_alias")));
+#else
+#ifndef xmlPopInputCallbacks
+extern __typeof (xmlPopInputCallbacks) xmlPopInputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlPopInputCallbacks xmlPopInputCallbacks__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlPreviousElementSibling
+extern __typeof (xmlPreviousElementSibling) xmlPreviousElementSibling __attribute((alias("xmlPreviousElementSibling__internal_alias")));
+#else
+#ifndef xmlPreviousElementSibling
+extern __typeof (xmlPreviousElementSibling) xmlPreviousElementSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlPreviousElementSibling xmlPreviousElementSibling__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlPrintURI
+extern __typeof (xmlPrintURI) xmlPrintURI __attribute((alias("xmlPrintURI__internal_alias")));
+#else
+#ifndef xmlPrintURI
+extern __typeof (xmlPrintURI) xmlPrintURI__internal_alias __attribute((visibility("hidden")));
+#define xmlPrintURI xmlPrintURI__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlPushInput
+extern __typeof (xmlPushInput) xmlPushInput __attribute((alias("xmlPushInput__internal_alias")));
+#else
+#ifndef xmlPushInput
+extern __typeof (xmlPushInput) xmlPushInput__internal_alias __attribute((visibility("hidden")));
+#define xmlPushInput xmlPushInput__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlRMutexLock
+extern __typeof (xmlRMutexLock) xmlRMutexLock __attribute((alias("xmlRMutexLock__internal_alias")));
+#else
+#ifndef xmlRMutexLock
+extern __typeof (xmlRMutexLock) xmlRMutexLock__internal_alias __attribute((visibility("hidden")));
+#define xmlRMutexLock xmlRMutexLock__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlRMutexUnlock
+extern __typeof (xmlRMutexUnlock) xmlRMutexUnlock __attribute((alias("xmlRMutexUnlock__internal_alias")));
+#else
+#ifndef xmlRMutexUnlock
+extern __typeof (xmlRMutexUnlock) xmlRMutexUnlock__internal_alias __attribute((visibility("hidden")));
+#define xmlRMutexUnlock xmlRMutexUnlock__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlReadDoc
+extern __typeof (xmlReadDoc) xmlReadDoc __attribute((alias("xmlReadDoc__internal_alias")));
+#else
+#ifndef xmlReadDoc
+extern __typeof (xmlReadDoc) xmlReadDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlReadDoc xmlReadDoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlReadFd
+extern __typeof (xmlReadFd) xmlReadFd __attribute((alias("xmlReadFd__internal_alias")));
+#else
+#ifndef xmlReadFd
+extern __typeof (xmlReadFd) xmlReadFd__internal_alias __attribute((visibility("hidden")));
+#define xmlReadFd xmlReadFd__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlReadFile
+extern __typeof (xmlReadFile) xmlReadFile __attribute((alias("xmlReadFile__internal_alias")));
+#else
+#ifndef xmlReadFile
+extern __typeof (xmlReadFile) xmlReadFile__internal_alias __attribute((visibility("hidden")));
+#define xmlReadFile xmlReadFile__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlReadIO
+extern __typeof (xmlReadIO) xmlReadIO __attribute((alias("xmlReadIO__internal_alias")));
+#else
+#ifndef xmlReadIO
+extern __typeof (xmlReadIO) xmlReadIO__internal_alias __attribute((visibility("hidden")));
+#define xmlReadIO xmlReadIO__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlReadMemory
+extern __typeof (xmlReadMemory) xmlReadMemory __attribute((alias("xmlReadMemory__internal_alias")));
+#else
+#ifndef xmlReadMemory
+extern __typeof (xmlReadMemory) xmlReadMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlReadMemory xmlReadMemory__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderForDoc
+extern __typeof (xmlReaderForDoc) xmlReaderForDoc __attribute((alias("xmlReaderForDoc__internal_alias")));
+#else
+#ifndef xmlReaderForDoc
+extern __typeof (xmlReaderForDoc) xmlReaderForDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderForDoc xmlReaderForDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderForFd
+extern __typeof (xmlReaderForFd) xmlReaderForFd __attribute((alias("xmlReaderForFd__internal_alias")));
+#else
+#ifndef xmlReaderForFd
+extern __typeof (xmlReaderForFd) xmlReaderForFd__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderForFd xmlReaderForFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderForFile
+extern __typeof (xmlReaderForFile) xmlReaderForFile __attribute((alias("xmlReaderForFile__internal_alias")));
+#else
+#ifndef xmlReaderForFile
+extern __typeof (xmlReaderForFile) xmlReaderForFile__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderForFile xmlReaderForFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderForIO
+extern __typeof (xmlReaderForIO) xmlReaderForIO __attribute((alias("xmlReaderForIO__internal_alias")));
+#else
+#ifndef xmlReaderForIO
+extern __typeof (xmlReaderForIO) xmlReaderForIO__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderForIO xmlReaderForIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderForMemory
+extern __typeof (xmlReaderForMemory) xmlReaderForMemory __attribute((alias("xmlReaderForMemory__internal_alias")));
+#else
+#ifndef xmlReaderForMemory
+extern __typeof (xmlReaderForMemory) xmlReaderForMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderForMemory xmlReaderForMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewDoc
+extern __typeof (xmlReaderNewDoc) xmlReaderNewDoc __attribute((alias("xmlReaderNewDoc__internal_alias")));
+#else
+#ifndef xmlReaderNewDoc
+extern __typeof (xmlReaderNewDoc) xmlReaderNewDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewDoc xmlReaderNewDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewFd
+extern __typeof (xmlReaderNewFd) xmlReaderNewFd __attribute((alias("xmlReaderNewFd__internal_alias")));
+#else
+#ifndef xmlReaderNewFd
+extern __typeof (xmlReaderNewFd) xmlReaderNewFd__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewFd xmlReaderNewFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewFile
+extern __typeof (xmlReaderNewFile) xmlReaderNewFile __attribute((alias("xmlReaderNewFile__internal_alias")));
+#else
+#ifndef xmlReaderNewFile
+extern __typeof (xmlReaderNewFile) xmlReaderNewFile__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewFile xmlReaderNewFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewIO
+extern __typeof (xmlReaderNewIO) xmlReaderNewIO __attribute((alias("xmlReaderNewIO__internal_alias")));
+#else
+#ifndef xmlReaderNewIO
+extern __typeof (xmlReaderNewIO) xmlReaderNewIO__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewIO xmlReaderNewIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewMemory
+extern __typeof (xmlReaderNewMemory) xmlReaderNewMemory __attribute((alias("xmlReaderNewMemory__internal_alias")));
+#else
+#ifndef xmlReaderNewMemory
+extern __typeof (xmlReaderNewMemory) xmlReaderNewMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewMemory xmlReaderNewMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderNewWalker
+extern __typeof (xmlReaderNewWalker) xmlReaderNewWalker __attribute((alias("xmlReaderNewWalker__internal_alias")));
+#else
+#ifndef xmlReaderNewWalker
+extern __typeof (xmlReaderNewWalker) xmlReaderNewWalker__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderNewWalker xmlReaderNewWalker__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlReaderWalker
+extern __typeof (xmlReaderWalker) xmlReaderWalker __attribute((alias("xmlReaderWalker__internal_alias")));
+#else
+#ifndef xmlReaderWalker
+extern __typeof (xmlReaderWalker) xmlReaderWalker__internal_alias __attribute((visibility("hidden")));
+#define xmlReaderWalker xmlReaderWalker__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlmemory
+#undef xmlReallocLoc
+extern __typeof (xmlReallocLoc) xmlReallocLoc __attribute((alias("xmlReallocLoc__internal_alias")));
+#else
+#ifndef xmlReallocLoc
+extern __typeof (xmlReallocLoc) xmlReallocLoc__internal_alias __attribute((visibility("hidden")));
+#define xmlReallocLoc xmlReallocLoc__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef bottom_tree
+#undef xmlReconciliateNs
+extern __typeof (xmlReconciliateNs) xmlReconciliateNs __attribute((alias("xmlReconciliateNs__internal_alias")));
+#else
+#ifndef xmlReconciliateNs
+extern __typeof (xmlReconciliateNs) xmlReconciliateNs__internal_alias __attribute((visibility("hidden")));
+#define xmlReconciliateNs xmlReconciliateNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlRecoverDoc
+extern __typeof (xmlRecoverDoc) xmlRecoverDoc __attribute((alias("xmlRecoverDoc__internal_alias")));
+#else
+#ifndef xmlRecoverDoc
+extern __typeof (xmlRecoverDoc) xmlRecoverDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlRecoverDoc xmlRecoverDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlRecoverFile
+extern __typeof (xmlRecoverFile) xmlRecoverFile __attribute((alias("xmlRecoverFile__internal_alias")));
+#else
+#ifndef xmlRecoverFile
+extern __typeof (xmlRecoverFile) xmlRecoverFile__internal_alias __attribute((visibility("hidden")));
+#define xmlRecoverFile xmlRecoverFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlRecoverMemory
+extern __typeof (xmlRecoverMemory) xmlRecoverMemory __attribute((alias("xmlRecoverMemory__internal_alias")));
+#else
+#ifndef xmlRecoverMemory
+extern __typeof (xmlRecoverMemory) xmlRecoverMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlRecoverMemory xmlRecoverMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegExecErrInfo
+extern __typeof (xmlRegExecErrInfo) xmlRegExecErrInfo __attribute((alias("xmlRegExecErrInfo__internal_alias")));
+#else
+#ifndef xmlRegExecErrInfo
+extern __typeof (xmlRegExecErrInfo) xmlRegExecErrInfo__internal_alias __attribute((visibility("hidden")));
+#define xmlRegExecErrInfo xmlRegExecErrInfo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegExecNextValues
+extern __typeof (xmlRegExecNextValues) xmlRegExecNextValues __attribute((alias("xmlRegExecNextValues__internal_alias")));
+#else
+#ifndef xmlRegExecNextValues
+extern __typeof (xmlRegExecNextValues) xmlRegExecNextValues__internal_alias __attribute((visibility("hidden")));
+#define xmlRegExecNextValues xmlRegExecNextValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegExecPushString
+extern __typeof (xmlRegExecPushString) xmlRegExecPushString __attribute((alias("xmlRegExecPushString__internal_alias")));
+#else
+#ifndef xmlRegExecPushString
+extern __typeof (xmlRegExecPushString) xmlRegExecPushString__internal_alias __attribute((visibility("hidden")));
+#define xmlRegExecPushString xmlRegExecPushString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegExecPushString2
+extern __typeof (xmlRegExecPushString2) xmlRegExecPushString2 __attribute((alias("xmlRegExecPushString2__internal_alias")));
+#else
+#ifndef xmlRegExecPushString2
+extern __typeof (xmlRegExecPushString2) xmlRegExecPushString2__internal_alias __attribute((visibility("hidden")));
+#define xmlRegExecPushString2 xmlRegExecPushString2__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegFreeExecCtxt
+extern __typeof (xmlRegFreeExecCtxt) xmlRegFreeExecCtxt __attribute((alias("xmlRegFreeExecCtxt__internal_alias")));
+#else
+#ifndef xmlRegFreeExecCtxt
+extern __typeof (xmlRegFreeExecCtxt) xmlRegFreeExecCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRegFreeExecCtxt xmlRegFreeExecCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegFreeRegexp
+extern __typeof (xmlRegFreeRegexp) xmlRegFreeRegexp __attribute((alias("xmlRegFreeRegexp__internal_alias")));
+#else
+#ifndef xmlRegFreeRegexp
+extern __typeof (xmlRegFreeRegexp) xmlRegFreeRegexp__internal_alias __attribute((visibility("hidden")));
+#define xmlRegFreeRegexp xmlRegFreeRegexp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegNewExecCtxt
+extern __typeof (xmlRegNewExecCtxt) xmlRegNewExecCtxt __attribute((alias("xmlRegNewExecCtxt__internal_alias")));
+#else
+#ifndef xmlRegNewExecCtxt
+extern __typeof (xmlRegNewExecCtxt) xmlRegNewExecCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRegNewExecCtxt xmlRegNewExecCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegexpCompile
+extern __typeof (xmlRegexpCompile) xmlRegexpCompile __attribute((alias("xmlRegexpCompile__internal_alias")));
+#else
+#ifndef xmlRegexpCompile
+extern __typeof (xmlRegexpCompile) xmlRegexpCompile__internal_alias __attribute((visibility("hidden")));
+#define xmlRegexpCompile xmlRegexpCompile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegexpExec
+extern __typeof (xmlRegexpExec) xmlRegexpExec __attribute((alias("xmlRegexpExec__internal_alias")));
+#else
+#ifndef xmlRegexpExec
+extern __typeof (xmlRegexpExec) xmlRegexpExec__internal_alias __attribute((visibility("hidden")));
+#define xmlRegexpExec xmlRegexpExec__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegexpIsDeterminist
+extern __typeof (xmlRegexpIsDeterminist) xmlRegexpIsDeterminist __attribute((alias("xmlRegexpIsDeterminist__internal_alias")));
+#else
+#ifndef xmlRegexpIsDeterminist
+extern __typeof (xmlRegexpIsDeterminist) xmlRegexpIsDeterminist__internal_alias __attribute((visibility("hidden")));
+#define xmlRegexpIsDeterminist xmlRegexpIsDeterminist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_xmlregexp
+#undef xmlRegexpPrint
+extern __typeof (xmlRegexpPrint) xmlRegexpPrint __attribute((alias("xmlRegexpPrint__internal_alias")));
+#else
+#ifndef xmlRegexpPrint
+extern __typeof (xmlRegexpPrint) xmlRegexpPrint__internal_alias __attribute((visibility("hidden")));
+#define xmlRegexpPrint xmlRegexpPrint__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_encoding
+#undef xmlRegisterCharEncodingHandler
+extern __typeof (xmlRegisterCharEncodingHandler) xmlRegisterCharEncodingHandler __attribute((alias("xmlRegisterCharEncodingHandler__internal_alias")));
+#else
+#ifndef xmlRegisterCharEncodingHandler
+extern __typeof (xmlRegisterCharEncodingHandler) xmlRegisterCharEncodingHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterCharEncodingHandler xmlRegisterCharEncodingHandler__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlRegisterDefaultInputCallbacks
+extern __typeof (xmlRegisterDefaultInputCallbacks) xmlRegisterDefaultInputCallbacks __attribute((alias("xmlRegisterDefaultInputCallbacks__internal_alias")));
+#else
+#ifndef xmlRegisterDefaultInputCallbacks
+extern __typeof (xmlRegisterDefaultInputCallbacks) xmlRegisterDefaultInputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterDefaultInputCallbacks xmlRegisterDefaultInputCallbacks__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlRegisterDefaultOutputCallbacks
+extern __typeof (xmlRegisterDefaultOutputCallbacks) xmlRegisterDefaultOutputCallbacks __attribute((alias("xmlRegisterDefaultOutputCallbacks__internal_alias")));
+#else
+#ifndef xmlRegisterDefaultOutputCallbacks
+extern __typeof (xmlRegisterDefaultOutputCallbacks) xmlRegisterDefaultOutputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterDefaultOutputCallbacks xmlRegisterDefaultOutputCallbacks__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED) && defined(LIBXML_HTTP_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlRegisterHTTPPostCallbacks
+extern __typeof (xmlRegisterHTTPPostCallbacks) xmlRegisterHTTPPostCallbacks __attribute((alias("xmlRegisterHTTPPostCallbacks__internal_alias")));
+#else
+#ifndef xmlRegisterHTTPPostCallbacks
+extern __typeof (xmlRegisterHTTPPostCallbacks) xmlRegisterHTTPPostCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterHTTPPostCallbacks xmlRegisterHTTPPostCallbacks__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlRegisterInputCallbacks
+extern __typeof (xmlRegisterInputCallbacks) xmlRegisterInputCallbacks __attribute((alias("xmlRegisterInputCallbacks__internal_alias")));
+#else
+#ifndef xmlRegisterInputCallbacks
+extern __typeof (xmlRegisterInputCallbacks) xmlRegisterInputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterInputCallbacks xmlRegisterInputCallbacks__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlRegisterNodeDefault
+extern __typeof (xmlRegisterNodeDefault) xmlRegisterNodeDefault __attribute((alias("xmlRegisterNodeDefault__internal_alias")));
+#else
+#ifndef xmlRegisterNodeDefault
+extern __typeof (xmlRegisterNodeDefault) xmlRegisterNodeDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterNodeDefault xmlRegisterNodeDefault__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlIO
+#undef xmlRegisterOutputCallbacks
+extern __typeof (xmlRegisterOutputCallbacks) xmlRegisterOutputCallbacks __attribute((alias("xmlRegisterOutputCallbacks__internal_alias")));
+#else
+#ifndef xmlRegisterOutputCallbacks
+extern __typeof (xmlRegisterOutputCallbacks) xmlRegisterOutputCallbacks__internal_alias __attribute((visibility("hidden")));
+#define xmlRegisterOutputCallbacks xmlRegisterOutputCallbacks__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGCleanupTypes
+extern __typeof (xmlRelaxNGCleanupTypes) xmlRelaxNGCleanupTypes __attribute((alias("xmlRelaxNGCleanupTypes__internal_alias")));
+#else
+#ifndef xmlRelaxNGCleanupTypes
+extern __typeof (xmlRelaxNGCleanupTypes) xmlRelaxNGCleanupTypes__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGCleanupTypes xmlRelaxNGCleanupTypes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGDump
+extern __typeof (xmlRelaxNGDump) xmlRelaxNGDump __attribute((alias("xmlRelaxNGDump__internal_alias")));
+#else
+#ifndef xmlRelaxNGDump
+extern __typeof (xmlRelaxNGDump) xmlRelaxNGDump__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGDump xmlRelaxNGDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGDumpTree
+extern __typeof (xmlRelaxNGDumpTree) xmlRelaxNGDumpTree __attribute((alias("xmlRelaxNGDumpTree__internal_alias")));
+#else
+#ifndef xmlRelaxNGDumpTree
+extern __typeof (xmlRelaxNGDumpTree) xmlRelaxNGDumpTree__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGDumpTree xmlRelaxNGDumpTree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGFree
+extern __typeof (xmlRelaxNGFree) xmlRelaxNGFree __attribute((alias("xmlRelaxNGFree__internal_alias")));
+#else
+#ifndef xmlRelaxNGFree
+extern __typeof (xmlRelaxNGFree) xmlRelaxNGFree__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGFree xmlRelaxNGFree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGFreeParserCtxt
+extern __typeof (xmlRelaxNGFreeParserCtxt) xmlRelaxNGFreeParserCtxt __attribute((alias("xmlRelaxNGFreeParserCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGFreeParserCtxt
+extern __typeof (xmlRelaxNGFreeParserCtxt) xmlRelaxNGFreeParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGFreeParserCtxt xmlRelaxNGFreeParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGFreeValidCtxt
+extern __typeof (xmlRelaxNGFreeValidCtxt) xmlRelaxNGFreeValidCtxt __attribute((alias("xmlRelaxNGFreeValidCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGFreeValidCtxt
+extern __typeof (xmlRelaxNGFreeValidCtxt) xmlRelaxNGFreeValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGFreeValidCtxt xmlRelaxNGFreeValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGGetParserErrors
+extern __typeof (xmlRelaxNGGetParserErrors) xmlRelaxNGGetParserErrors __attribute((alias("xmlRelaxNGGetParserErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGGetParserErrors
+extern __typeof (xmlRelaxNGGetParserErrors) xmlRelaxNGGetParserErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGGetParserErrors xmlRelaxNGGetParserErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGGetValidErrors
+extern __typeof (xmlRelaxNGGetValidErrors) xmlRelaxNGGetValidErrors __attribute((alias("xmlRelaxNGGetValidErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGGetValidErrors
+extern __typeof (xmlRelaxNGGetValidErrors) xmlRelaxNGGetValidErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGGetValidErrors xmlRelaxNGGetValidErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGInitTypes
+extern __typeof (xmlRelaxNGInitTypes) xmlRelaxNGInitTypes __attribute((alias("xmlRelaxNGInitTypes__internal_alias")));
+#else
+#ifndef xmlRelaxNGInitTypes
+extern __typeof (xmlRelaxNGInitTypes) xmlRelaxNGInitTypes__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGInitTypes xmlRelaxNGInitTypes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGNewDocParserCtxt
+extern __typeof (xmlRelaxNGNewDocParserCtxt) xmlRelaxNGNewDocParserCtxt __attribute((alias("xmlRelaxNGNewDocParserCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGNewDocParserCtxt
+extern __typeof (xmlRelaxNGNewDocParserCtxt) xmlRelaxNGNewDocParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGNewDocParserCtxt xmlRelaxNGNewDocParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGNewMemParserCtxt
+extern __typeof (xmlRelaxNGNewMemParserCtxt) xmlRelaxNGNewMemParserCtxt __attribute((alias("xmlRelaxNGNewMemParserCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGNewMemParserCtxt
+extern __typeof (xmlRelaxNGNewMemParserCtxt) xmlRelaxNGNewMemParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGNewMemParserCtxt xmlRelaxNGNewMemParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGNewParserCtxt
+extern __typeof (xmlRelaxNGNewParserCtxt) xmlRelaxNGNewParserCtxt __attribute((alias("xmlRelaxNGNewParserCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGNewParserCtxt
+extern __typeof (xmlRelaxNGNewParserCtxt) xmlRelaxNGNewParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGNewParserCtxt xmlRelaxNGNewParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGNewValidCtxt
+extern __typeof (xmlRelaxNGNewValidCtxt) xmlRelaxNGNewValidCtxt __attribute((alias("xmlRelaxNGNewValidCtxt__internal_alias")));
+#else
+#ifndef xmlRelaxNGNewValidCtxt
+extern __typeof (xmlRelaxNGNewValidCtxt) xmlRelaxNGNewValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGNewValidCtxt xmlRelaxNGNewValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGParse
+extern __typeof (xmlRelaxNGParse) xmlRelaxNGParse __attribute((alias("xmlRelaxNGParse__internal_alias")));
+#else
+#ifndef xmlRelaxNGParse
+extern __typeof (xmlRelaxNGParse) xmlRelaxNGParse__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGParse xmlRelaxNGParse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGSetParserErrors
+extern __typeof (xmlRelaxNGSetParserErrors) xmlRelaxNGSetParserErrors __attribute((alias("xmlRelaxNGSetParserErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGSetParserErrors
+extern __typeof (xmlRelaxNGSetParserErrors) xmlRelaxNGSetParserErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGSetParserErrors xmlRelaxNGSetParserErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGSetParserStructuredErrors
+extern __typeof (xmlRelaxNGSetParserStructuredErrors) xmlRelaxNGSetParserStructuredErrors __attribute((alias("xmlRelaxNGSetParserStructuredErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGSetParserStructuredErrors
+extern __typeof (xmlRelaxNGSetParserStructuredErrors) xmlRelaxNGSetParserStructuredErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGSetParserStructuredErrors xmlRelaxNGSetParserStructuredErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGSetValidErrors
+extern __typeof (xmlRelaxNGSetValidErrors) xmlRelaxNGSetValidErrors __attribute((alias("xmlRelaxNGSetValidErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGSetValidErrors
+extern __typeof (xmlRelaxNGSetValidErrors) xmlRelaxNGSetValidErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGSetValidErrors xmlRelaxNGSetValidErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGSetValidStructuredErrors
+extern __typeof (xmlRelaxNGSetValidStructuredErrors) xmlRelaxNGSetValidStructuredErrors __attribute((alias("xmlRelaxNGSetValidStructuredErrors__internal_alias")));
+#else
+#ifndef xmlRelaxNGSetValidStructuredErrors
+extern __typeof (xmlRelaxNGSetValidStructuredErrors) xmlRelaxNGSetValidStructuredErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGSetValidStructuredErrors xmlRelaxNGSetValidStructuredErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGValidateDoc
+extern __typeof (xmlRelaxNGValidateDoc) xmlRelaxNGValidateDoc __attribute((alias("xmlRelaxNGValidateDoc__internal_alias")));
+#else
+#ifndef xmlRelaxNGValidateDoc
+extern __typeof (xmlRelaxNGValidateDoc) xmlRelaxNGValidateDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGValidateDoc xmlRelaxNGValidateDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGValidateFullElement
+extern __typeof (xmlRelaxNGValidateFullElement) xmlRelaxNGValidateFullElement __attribute((alias("xmlRelaxNGValidateFullElement__internal_alias")));
+#else
+#ifndef xmlRelaxNGValidateFullElement
+extern __typeof (xmlRelaxNGValidateFullElement) xmlRelaxNGValidateFullElement__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGValidateFullElement xmlRelaxNGValidateFullElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGValidatePopElement
+extern __typeof (xmlRelaxNGValidatePopElement) xmlRelaxNGValidatePopElement __attribute((alias("xmlRelaxNGValidatePopElement__internal_alias")));
+#else
+#ifndef xmlRelaxNGValidatePopElement
+extern __typeof (xmlRelaxNGValidatePopElement) xmlRelaxNGValidatePopElement__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGValidatePopElement xmlRelaxNGValidatePopElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGValidatePushCData
+extern __typeof (xmlRelaxNGValidatePushCData) xmlRelaxNGValidatePushCData __attribute((alias("xmlRelaxNGValidatePushCData__internal_alias")));
+#else
+#ifndef xmlRelaxNGValidatePushCData
+extern __typeof (xmlRelaxNGValidatePushCData) xmlRelaxNGValidatePushCData__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGValidatePushCData xmlRelaxNGValidatePushCData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxNGValidatePushElement
+extern __typeof (xmlRelaxNGValidatePushElement) xmlRelaxNGValidatePushElement __attribute((alias("xmlRelaxNGValidatePushElement__internal_alias")));
+#else
+#ifndef xmlRelaxNGValidatePushElement
+extern __typeof (xmlRelaxNGValidatePushElement) xmlRelaxNGValidatePushElement__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxNGValidatePushElement xmlRelaxNGValidatePushElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_relaxng
+#undef xmlRelaxParserSetFlag
+extern __typeof (xmlRelaxParserSetFlag) xmlRelaxParserSetFlag __attribute((alias("xmlRelaxParserSetFlag__internal_alias")));
+#else
+#ifndef xmlRelaxParserSetFlag
+extern __typeof (xmlRelaxParserSetFlag) xmlRelaxParserSetFlag__internal_alias __attribute((visibility("hidden")));
+#define xmlRelaxParserSetFlag xmlRelaxParserSetFlag__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlRemoveID
+extern __typeof (xmlRemoveID) xmlRemoveID __attribute((alias("xmlRemoveID__internal_alias")));
+#else
+#ifndef xmlRemoveID
+extern __typeof (xmlRemoveID) xmlRemoveID__internal_alias __attribute((visibility("hidden")));
+#define xmlRemoveID xmlRemoveID__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlRemoveProp
+extern __typeof (xmlRemoveProp) xmlRemoveProp __attribute((alias("xmlRemoveProp__internal_alias")));
+#else
+#ifndef xmlRemoveProp
+extern __typeof (xmlRemoveProp) xmlRemoveProp__internal_alias __attribute((visibility("hidden")));
+#define xmlRemoveProp xmlRemoveProp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlRemoveRef
+extern __typeof (xmlRemoveRef) xmlRemoveRef __attribute((alias("xmlRemoveRef__internal_alias")));
+#else
+#ifndef xmlRemoveRef
+extern __typeof (xmlRemoveRef) xmlRemoveRef__internal_alias __attribute((visibility("hidden")));
+#define xmlRemoveRef xmlRemoveRef__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_tree
+#undef xmlReplaceNode
+extern __typeof (xmlReplaceNode) xmlReplaceNode __attribute((alias("xmlReplaceNode__internal_alias")));
+#else
+#ifndef xmlReplaceNode
+extern __typeof (xmlReplaceNode) xmlReplaceNode__internal_alias __attribute((visibility("hidden")));
+#define xmlReplaceNode xmlReplaceNode__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlResetError
+extern __typeof (xmlResetError) xmlResetError __attribute((alias("xmlResetError__internal_alias")));
+#else
+#ifndef xmlResetError
+extern __typeof (xmlResetError) xmlResetError__internal_alias __attribute((visibility("hidden")));
+#define xmlResetError xmlResetError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlResetLastError
+extern __typeof (xmlResetLastError) xmlResetLastError __attribute((alias("xmlResetLastError__internal_alias")));
+#else
+#ifndef xmlResetLastError
+extern __typeof (xmlResetLastError) xmlResetLastError__internal_alias __attribute((visibility("hidden")));
+#define xmlResetLastError xmlResetLastError__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2AttributeDecl
+extern __typeof (xmlSAX2AttributeDecl) xmlSAX2AttributeDecl __attribute((alias("xmlSAX2AttributeDecl__internal_alias")));
+#else
+#ifndef xmlSAX2AttributeDecl
+extern __typeof (xmlSAX2AttributeDecl) xmlSAX2AttributeDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2AttributeDecl xmlSAX2AttributeDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2CDataBlock
+extern __typeof (xmlSAX2CDataBlock) xmlSAX2CDataBlock __attribute((alias("xmlSAX2CDataBlock__internal_alias")));
+#else
+#ifndef xmlSAX2CDataBlock
+extern __typeof (xmlSAX2CDataBlock) xmlSAX2CDataBlock__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2CDataBlock xmlSAX2CDataBlock__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2Characters
+extern __typeof (xmlSAX2Characters) xmlSAX2Characters __attribute((alias("xmlSAX2Characters__internal_alias")));
+#else
+#ifndef xmlSAX2Characters
+extern __typeof (xmlSAX2Characters) xmlSAX2Characters__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2Characters xmlSAX2Characters__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2Comment
+extern __typeof (xmlSAX2Comment) xmlSAX2Comment __attribute((alias("xmlSAX2Comment__internal_alias")));
+#else
+#ifndef xmlSAX2Comment
+extern __typeof (xmlSAX2Comment) xmlSAX2Comment__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2Comment xmlSAX2Comment__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2ElementDecl
+extern __typeof (xmlSAX2ElementDecl) xmlSAX2ElementDecl __attribute((alias("xmlSAX2ElementDecl__internal_alias")));
+#else
+#ifndef xmlSAX2ElementDecl
+extern __typeof (xmlSAX2ElementDecl) xmlSAX2ElementDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2ElementDecl xmlSAX2ElementDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2EndDocument
+extern __typeof (xmlSAX2EndDocument) xmlSAX2EndDocument __attribute((alias("xmlSAX2EndDocument__internal_alias")));
+#else
+#ifndef xmlSAX2EndDocument
+extern __typeof (xmlSAX2EndDocument) xmlSAX2EndDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2EndDocument xmlSAX2EndDocument__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef bottom_SAX2
+#undef xmlSAX2EndElement
+extern __typeof (xmlSAX2EndElement) xmlSAX2EndElement __attribute((alias("xmlSAX2EndElement__internal_alias")));
+#else
+#ifndef xmlSAX2EndElement
+extern __typeof (xmlSAX2EndElement) xmlSAX2EndElement__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2EndElement xmlSAX2EndElement__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2EndElementNs
+extern __typeof (xmlSAX2EndElementNs) xmlSAX2EndElementNs __attribute((alias("xmlSAX2EndElementNs__internal_alias")));
+#else
+#ifndef xmlSAX2EndElementNs
+extern __typeof (xmlSAX2EndElementNs) xmlSAX2EndElementNs__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2EndElementNs xmlSAX2EndElementNs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2EntityDecl
+extern __typeof (xmlSAX2EntityDecl) xmlSAX2EntityDecl __attribute((alias("xmlSAX2EntityDecl__internal_alias")));
+#else
+#ifndef xmlSAX2EntityDecl
+extern __typeof (xmlSAX2EntityDecl) xmlSAX2EntityDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2EntityDecl xmlSAX2EntityDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2ExternalSubset
+extern __typeof (xmlSAX2ExternalSubset) xmlSAX2ExternalSubset __attribute((alias("xmlSAX2ExternalSubset__internal_alias")));
+#else
+#ifndef xmlSAX2ExternalSubset
+extern __typeof (xmlSAX2ExternalSubset) xmlSAX2ExternalSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2ExternalSubset xmlSAX2ExternalSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetColumnNumber
+extern __typeof (xmlSAX2GetColumnNumber) xmlSAX2GetColumnNumber __attribute((alias("xmlSAX2GetColumnNumber__internal_alias")));
+#else
+#ifndef xmlSAX2GetColumnNumber
+extern __typeof (xmlSAX2GetColumnNumber) xmlSAX2GetColumnNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetColumnNumber xmlSAX2GetColumnNumber__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetEntity
+extern __typeof (xmlSAX2GetEntity) xmlSAX2GetEntity __attribute((alias("xmlSAX2GetEntity__internal_alias")));
+#else
+#ifndef xmlSAX2GetEntity
+extern __typeof (xmlSAX2GetEntity) xmlSAX2GetEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetEntity xmlSAX2GetEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetLineNumber
+extern __typeof (xmlSAX2GetLineNumber) xmlSAX2GetLineNumber __attribute((alias("xmlSAX2GetLineNumber__internal_alias")));
+#else
+#ifndef xmlSAX2GetLineNumber
+extern __typeof (xmlSAX2GetLineNumber) xmlSAX2GetLineNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetLineNumber xmlSAX2GetLineNumber__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetParameterEntity
+extern __typeof (xmlSAX2GetParameterEntity) xmlSAX2GetParameterEntity __attribute((alias("xmlSAX2GetParameterEntity__internal_alias")));
+#else
+#ifndef xmlSAX2GetParameterEntity
+extern __typeof (xmlSAX2GetParameterEntity) xmlSAX2GetParameterEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetParameterEntity xmlSAX2GetParameterEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetPublicId
+extern __typeof (xmlSAX2GetPublicId) xmlSAX2GetPublicId __attribute((alias("xmlSAX2GetPublicId__internal_alias")));
+#else
+#ifndef xmlSAX2GetPublicId
+extern __typeof (xmlSAX2GetPublicId) xmlSAX2GetPublicId__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetPublicId xmlSAX2GetPublicId__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2GetSystemId
+extern __typeof (xmlSAX2GetSystemId) xmlSAX2GetSystemId __attribute((alias("xmlSAX2GetSystemId__internal_alias")));
+#else
+#ifndef xmlSAX2GetSystemId
+extern __typeof (xmlSAX2GetSystemId) xmlSAX2GetSystemId__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2GetSystemId xmlSAX2GetSystemId__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2HasExternalSubset
+extern __typeof (xmlSAX2HasExternalSubset) xmlSAX2HasExternalSubset __attribute((alias("xmlSAX2HasExternalSubset__internal_alias")));
+#else
+#ifndef xmlSAX2HasExternalSubset
+extern __typeof (xmlSAX2HasExternalSubset) xmlSAX2HasExternalSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2HasExternalSubset xmlSAX2HasExternalSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2HasInternalSubset
+extern __typeof (xmlSAX2HasInternalSubset) xmlSAX2HasInternalSubset __attribute((alias("xmlSAX2HasInternalSubset__internal_alias")));
+#else
+#ifndef xmlSAX2HasInternalSubset
+extern __typeof (xmlSAX2HasInternalSubset) xmlSAX2HasInternalSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2HasInternalSubset xmlSAX2HasInternalSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2IgnorableWhitespace
+extern __typeof (xmlSAX2IgnorableWhitespace) xmlSAX2IgnorableWhitespace __attribute((alias("xmlSAX2IgnorableWhitespace__internal_alias")));
+#else
+#ifndef xmlSAX2IgnorableWhitespace
+extern __typeof (xmlSAX2IgnorableWhitespace) xmlSAX2IgnorableWhitespace__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2IgnorableWhitespace xmlSAX2IgnorableWhitespace__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2InitDefaultSAXHandler
+extern __typeof (xmlSAX2InitDefaultSAXHandler) xmlSAX2InitDefaultSAXHandler __attribute((alias("xmlSAX2InitDefaultSAXHandler__internal_alias")));
+#else
+#ifndef xmlSAX2InitDefaultSAXHandler
+extern __typeof (xmlSAX2InitDefaultSAXHandler) xmlSAX2InitDefaultSAXHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2InitDefaultSAXHandler xmlSAX2InitDefaultSAXHandler__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_DOCB_ENABLED)
+#ifdef bottom_SAX2
+#undef xmlSAX2InitDocbDefaultSAXHandler
+extern __typeof (xmlSAX2InitDocbDefaultSAXHandler) xmlSAX2InitDocbDefaultSAXHandler __attribute((alias("xmlSAX2InitDocbDefaultSAXHandler__internal_alias")));
+#else
+#ifndef xmlSAX2InitDocbDefaultSAXHandler
+extern __typeof (xmlSAX2InitDocbDefaultSAXHandler) xmlSAX2InitDocbDefaultSAXHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2InitDocbDefaultSAXHandler xmlSAX2InitDocbDefaultSAXHandler__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_SAX2
+#undef xmlSAX2InitHtmlDefaultSAXHandler
+extern __typeof (xmlSAX2InitHtmlDefaultSAXHandler) xmlSAX2InitHtmlDefaultSAXHandler __attribute((alias("xmlSAX2InitHtmlDefaultSAXHandler__internal_alias")));
+#else
+#ifndef xmlSAX2InitHtmlDefaultSAXHandler
+extern __typeof (xmlSAX2InitHtmlDefaultSAXHandler) xmlSAX2InitHtmlDefaultSAXHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2InitHtmlDefaultSAXHandler xmlSAX2InitHtmlDefaultSAXHandler__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2InternalSubset
+extern __typeof (xmlSAX2InternalSubset) xmlSAX2InternalSubset __attribute((alias("xmlSAX2InternalSubset__internal_alias")));
+#else
+#ifndef xmlSAX2InternalSubset
+extern __typeof (xmlSAX2InternalSubset) xmlSAX2InternalSubset__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2InternalSubset xmlSAX2InternalSubset__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2IsStandalone
+extern __typeof (xmlSAX2IsStandalone) xmlSAX2IsStandalone __attribute((alias("xmlSAX2IsStandalone__internal_alias")));
+#else
+#ifndef xmlSAX2IsStandalone
+extern __typeof (xmlSAX2IsStandalone) xmlSAX2IsStandalone__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2IsStandalone xmlSAX2IsStandalone__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2NotationDecl
+extern __typeof (xmlSAX2NotationDecl) xmlSAX2NotationDecl __attribute((alias("xmlSAX2NotationDecl__internal_alias")));
+#else
+#ifndef xmlSAX2NotationDecl
+extern __typeof (xmlSAX2NotationDecl) xmlSAX2NotationDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2NotationDecl xmlSAX2NotationDecl__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2ProcessingInstruction
+extern __typeof (xmlSAX2ProcessingInstruction) xmlSAX2ProcessingInstruction __attribute((alias("xmlSAX2ProcessingInstruction__internal_alias")));
+#else
+#ifndef xmlSAX2ProcessingInstruction
+extern __typeof (xmlSAX2ProcessingInstruction) xmlSAX2ProcessingInstruction__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2ProcessingInstruction xmlSAX2ProcessingInstruction__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2Reference
+extern __typeof (xmlSAX2Reference) xmlSAX2Reference __attribute((alias("xmlSAX2Reference__internal_alias")));
+#else
+#ifndef xmlSAX2Reference
+extern __typeof (xmlSAX2Reference) xmlSAX2Reference__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2Reference xmlSAX2Reference__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2ResolveEntity
+extern __typeof (xmlSAX2ResolveEntity) xmlSAX2ResolveEntity __attribute((alias("xmlSAX2ResolveEntity__internal_alias")));
+#else
+#ifndef xmlSAX2ResolveEntity
+extern __typeof (xmlSAX2ResolveEntity) xmlSAX2ResolveEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2ResolveEntity xmlSAX2ResolveEntity__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2SetDocumentLocator
+extern __typeof (xmlSAX2SetDocumentLocator) xmlSAX2SetDocumentLocator __attribute((alias("xmlSAX2SetDocumentLocator__internal_alias")));
+#else
+#ifndef xmlSAX2SetDocumentLocator
+extern __typeof (xmlSAX2SetDocumentLocator) xmlSAX2SetDocumentLocator__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2SetDocumentLocator xmlSAX2SetDocumentLocator__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2StartDocument
+extern __typeof (xmlSAX2StartDocument) xmlSAX2StartDocument __attribute((alias("xmlSAX2StartDocument__internal_alias")));
+#else
+#ifndef xmlSAX2StartDocument
+extern __typeof (xmlSAX2StartDocument) xmlSAX2StartDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2StartDocument xmlSAX2StartDocument__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef bottom_SAX2
+#undef xmlSAX2StartElement
+extern __typeof (xmlSAX2StartElement) xmlSAX2StartElement __attribute((alias("xmlSAX2StartElement__internal_alias")));
+#else
+#ifndef xmlSAX2StartElement
+extern __typeof (xmlSAX2StartElement) xmlSAX2StartElement__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2StartElement xmlSAX2StartElement__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2StartElementNs
+extern __typeof (xmlSAX2StartElementNs) xmlSAX2StartElementNs __attribute((alias("xmlSAX2StartElementNs__internal_alias")));
+#else
+#ifndef xmlSAX2StartElementNs
+extern __typeof (xmlSAX2StartElementNs) xmlSAX2StartElementNs__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2StartElementNs xmlSAX2StartElementNs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAX2UnparsedEntityDecl
+extern __typeof (xmlSAX2UnparsedEntityDecl) xmlSAX2UnparsedEntityDecl __attribute((alias("xmlSAX2UnparsedEntityDecl__internal_alias")));
+#else
+#ifndef xmlSAX2UnparsedEntityDecl
+extern __typeof (xmlSAX2UnparsedEntityDecl) xmlSAX2UnparsedEntityDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlSAX2UnparsedEntityDecl xmlSAX2UnparsedEntityDecl__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_SAX2
+#undef xmlSAXDefaultVersion
+extern __typeof (xmlSAXDefaultVersion) xmlSAXDefaultVersion __attribute((alias("xmlSAXDefaultVersion__internal_alias")));
+#else
+#ifndef xmlSAXDefaultVersion
+extern __typeof (xmlSAXDefaultVersion) xmlSAXDefaultVersion__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXDefaultVersion xmlSAXDefaultVersion__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseDTD
+extern __typeof (xmlSAXParseDTD) xmlSAXParseDTD __attribute((alias("xmlSAXParseDTD__internal_alias")));
+#else
+#ifndef xmlSAXParseDTD
+extern __typeof (xmlSAXParseDTD) xmlSAXParseDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseDTD xmlSAXParseDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseDoc
+extern __typeof (xmlSAXParseDoc) xmlSAXParseDoc __attribute((alias("xmlSAXParseDoc__internal_alias")));
+#else
+#ifndef xmlSAXParseDoc
+extern __typeof (xmlSAXParseDoc) xmlSAXParseDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseDoc xmlSAXParseDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseEntity
+extern __typeof (xmlSAXParseEntity) xmlSAXParseEntity __attribute((alias("xmlSAXParseEntity__internal_alias")));
+#else
+#ifndef xmlSAXParseEntity
+extern __typeof (xmlSAXParseEntity) xmlSAXParseEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseEntity xmlSAXParseEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseFile
+extern __typeof (xmlSAXParseFile) xmlSAXParseFile __attribute((alias("xmlSAXParseFile__internal_alias")));
+#else
+#ifndef xmlSAXParseFile
+extern __typeof (xmlSAXParseFile) xmlSAXParseFile__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseFile xmlSAXParseFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseFileWithData
+extern __typeof (xmlSAXParseFileWithData) xmlSAXParseFileWithData __attribute((alias("xmlSAXParseFileWithData__internal_alias")));
+#else
+#ifndef xmlSAXParseFileWithData
+extern __typeof (xmlSAXParseFileWithData) xmlSAXParseFileWithData__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseFileWithData xmlSAXParseFileWithData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseMemory
+extern __typeof (xmlSAXParseMemory) xmlSAXParseMemory __attribute((alias("xmlSAXParseMemory__internal_alias")));
+#else
+#ifndef xmlSAXParseMemory
+extern __typeof (xmlSAXParseMemory) xmlSAXParseMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseMemory xmlSAXParseMemory__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXParseMemoryWithData
+extern __typeof (xmlSAXParseMemoryWithData) xmlSAXParseMemoryWithData __attribute((alias("xmlSAXParseMemoryWithData__internal_alias")));
+#else
+#ifndef xmlSAXParseMemoryWithData
+extern __typeof (xmlSAXParseMemoryWithData) xmlSAXParseMemoryWithData__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXParseMemoryWithData xmlSAXParseMemoryWithData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXUserParseFile
+extern __typeof (xmlSAXUserParseFile) xmlSAXUserParseFile __attribute((alias("xmlSAXUserParseFile__internal_alias")));
+#else
+#ifndef xmlSAXUserParseFile
+extern __typeof (xmlSAXUserParseFile) xmlSAXUserParseFile__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXUserParseFile xmlSAXUserParseFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSAXUserParseMemory
+extern __typeof (xmlSAXUserParseMemory) xmlSAXUserParseMemory __attribute((alias("xmlSAXUserParseMemory__internal_alias")));
+#else
+#ifndef xmlSAXUserParseMemory
+extern __typeof (xmlSAXUserParseMemory) xmlSAXUserParseMemory__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXUserParseMemory xmlSAXUserParseMemory__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_SAX2
+#undef xmlSAXVersion
+extern __typeof (xmlSAXVersion) xmlSAXVersion __attribute((alias("xmlSAXVersion__internal_alias")));
+#else
+#ifndef xmlSAXVersion
+extern __typeof (xmlSAXVersion) xmlSAXVersion__internal_alias __attribute((visibility("hidden")));
+#define xmlSAXVersion xmlSAXVersion__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveClose
+extern __typeof (xmlSaveClose) xmlSaveClose __attribute((alias("xmlSaveClose__internal_alias")));
+#else
+#ifndef xmlSaveClose
+extern __typeof (xmlSaveClose) xmlSaveClose__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveClose xmlSaveClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveDoc
+extern __typeof (xmlSaveDoc) xmlSaveDoc __attribute((alias("xmlSaveDoc__internal_alias")));
+#else
+#ifndef xmlSaveDoc
+extern __typeof (xmlSaveDoc) xmlSaveDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveDoc xmlSaveDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFile
+extern __typeof (xmlSaveFile) xmlSaveFile __attribute((alias("xmlSaveFile__internal_alias")));
+#else
+#ifndef xmlSaveFile
+extern __typeof (xmlSaveFile) xmlSaveFile__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFile xmlSaveFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFileEnc
+extern __typeof (xmlSaveFileEnc) xmlSaveFileEnc __attribute((alias("xmlSaveFileEnc__internal_alias")));
+#else
+#ifndef xmlSaveFileEnc
+extern __typeof (xmlSaveFileEnc) xmlSaveFileEnc__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFileEnc xmlSaveFileEnc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFileTo
+extern __typeof (xmlSaveFileTo) xmlSaveFileTo __attribute((alias("xmlSaveFileTo__internal_alias")));
+#else
+#ifndef xmlSaveFileTo
+extern __typeof (xmlSaveFileTo) xmlSaveFileTo__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFileTo xmlSaveFileTo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFlush
+extern __typeof (xmlSaveFlush) xmlSaveFlush __attribute((alias("xmlSaveFlush__internal_alias")));
+#else
+#ifndef xmlSaveFlush
+extern __typeof (xmlSaveFlush) xmlSaveFlush__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFlush xmlSaveFlush__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFormatFile
+extern __typeof (xmlSaveFormatFile) xmlSaveFormatFile __attribute((alias("xmlSaveFormatFile__internal_alias")));
+#else
+#ifndef xmlSaveFormatFile
+extern __typeof (xmlSaveFormatFile) xmlSaveFormatFile__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFormatFile xmlSaveFormatFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFormatFileEnc
+extern __typeof (xmlSaveFormatFileEnc) xmlSaveFormatFileEnc __attribute((alias("xmlSaveFormatFileEnc__internal_alias")));
+#else
+#ifndef xmlSaveFormatFileEnc
+extern __typeof (xmlSaveFormatFileEnc) xmlSaveFormatFileEnc__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFormatFileEnc xmlSaveFormatFileEnc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveFormatFileTo
+extern __typeof (xmlSaveFormatFileTo) xmlSaveFormatFileTo __attribute((alias("xmlSaveFormatFileTo__internal_alias")));
+#else
+#ifndef xmlSaveFormatFileTo
+extern __typeof (xmlSaveFormatFileTo) xmlSaveFormatFileTo__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveFormatFileTo xmlSaveFormatFileTo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveSetAttrEscape
+extern __typeof (xmlSaveSetAttrEscape) xmlSaveSetAttrEscape __attribute((alias("xmlSaveSetAttrEscape__internal_alias")));
+#else
+#ifndef xmlSaveSetAttrEscape
+extern __typeof (xmlSaveSetAttrEscape) xmlSaveSetAttrEscape__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveSetAttrEscape xmlSaveSetAttrEscape__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveSetEscape
+extern __typeof (xmlSaveSetEscape) xmlSaveSetEscape __attribute((alias("xmlSaveSetEscape__internal_alias")));
+#else
+#ifndef xmlSaveSetEscape
+extern __typeof (xmlSaveSetEscape) xmlSaveSetEscape__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveSetEscape xmlSaveSetEscape__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveToBuffer
+extern __typeof (xmlSaveToBuffer) xmlSaveToBuffer __attribute((alias("xmlSaveToBuffer__internal_alias")));
+#else
+#ifndef xmlSaveToBuffer
+extern __typeof (xmlSaveToBuffer) xmlSaveToBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveToBuffer xmlSaveToBuffer__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveToFd
+extern __typeof (xmlSaveToFd) xmlSaveToFd __attribute((alias("xmlSaveToFd__internal_alias")));
+#else
+#ifndef xmlSaveToFd
+extern __typeof (xmlSaveToFd) xmlSaveToFd__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveToFd xmlSaveToFd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveToFilename
+extern __typeof (xmlSaveToFilename) xmlSaveToFilename __attribute((alias("xmlSaveToFilename__internal_alias")));
+#else
+#ifndef xmlSaveToFilename
+extern __typeof (xmlSaveToFilename) xmlSaveToFilename__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveToFilename xmlSaveToFilename__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveToIO
+extern __typeof (xmlSaveToIO) xmlSaveToIO __attribute((alias("xmlSaveToIO__internal_alias")));
+#else
+#ifndef xmlSaveToIO
+extern __typeof (xmlSaveToIO) xmlSaveToIO__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveToIO xmlSaveToIO__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlsave
+#undef xmlSaveTree
+extern __typeof (xmlSaveTree) xmlSaveTree __attribute((alias("xmlSaveTree__internal_alias")));
+#else
+#ifndef xmlSaveTree
+extern __typeof (xmlSaveTree) xmlSaveTree__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveTree xmlSaveTree__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlSaveUri
+extern __typeof (xmlSaveUri) xmlSaveUri __attribute((alias("xmlSaveUri__internal_alias")));
+#else
+#ifndef xmlSaveUri
+extern __typeof (xmlSaveUri) xmlSaveUri__internal_alias __attribute((visibility("hidden")));
+#define xmlSaveUri xmlSaveUri__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlScanName
+extern __typeof (xmlScanName) xmlScanName __attribute((alias("xmlScanName__internal_alias")));
+#else
+#ifndef xmlScanName
+extern __typeof (xmlScanName) xmlScanName__internal_alias __attribute((visibility("hidden")));
+#define xmlScanName xmlScanName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaCheckFacet
+extern __typeof (xmlSchemaCheckFacet) xmlSchemaCheckFacet __attribute((alias("xmlSchemaCheckFacet__internal_alias")));
+#else
+#ifndef xmlSchemaCheckFacet
+extern __typeof (xmlSchemaCheckFacet) xmlSchemaCheckFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCheckFacet xmlSchemaCheckFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaCleanupTypes
+extern __typeof (xmlSchemaCleanupTypes) xmlSchemaCleanupTypes __attribute((alias("xmlSchemaCleanupTypes__internal_alias")));
+#else
+#ifndef xmlSchemaCleanupTypes
+extern __typeof (xmlSchemaCleanupTypes) xmlSchemaCleanupTypes__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCleanupTypes xmlSchemaCleanupTypes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaCollapseString
+extern __typeof (xmlSchemaCollapseString) xmlSchemaCollapseString __attribute((alias("xmlSchemaCollapseString__internal_alias")));
+#else
+#ifndef xmlSchemaCollapseString
+extern __typeof (xmlSchemaCollapseString) xmlSchemaCollapseString__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCollapseString xmlSchemaCollapseString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaCompareValues
+extern __typeof (xmlSchemaCompareValues) xmlSchemaCompareValues __attribute((alias("xmlSchemaCompareValues__internal_alias")));
+#else
+#ifndef xmlSchemaCompareValues
+extern __typeof (xmlSchemaCompareValues) xmlSchemaCompareValues__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCompareValues xmlSchemaCompareValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaCompareValuesWhtsp
+extern __typeof (xmlSchemaCompareValuesWhtsp) xmlSchemaCompareValuesWhtsp __attribute((alias("xmlSchemaCompareValuesWhtsp__internal_alias")));
+#else
+#ifndef xmlSchemaCompareValuesWhtsp
+extern __typeof (xmlSchemaCompareValuesWhtsp) xmlSchemaCompareValuesWhtsp__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCompareValuesWhtsp xmlSchemaCompareValuesWhtsp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaCopyValue
+extern __typeof (xmlSchemaCopyValue) xmlSchemaCopyValue __attribute((alias("xmlSchemaCopyValue__internal_alias")));
+#else
+#ifndef xmlSchemaCopyValue
+extern __typeof (xmlSchemaCopyValue) xmlSchemaCopyValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaCopyValue xmlSchemaCopyValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaDump
+extern __typeof (xmlSchemaDump) xmlSchemaDump __attribute((alias("xmlSchemaDump__internal_alias")));
+#else
+#ifndef xmlSchemaDump
+extern __typeof (xmlSchemaDump) xmlSchemaDump__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaDump xmlSchemaDump__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFree
+extern __typeof (xmlSchemaFree) xmlSchemaFree __attribute((alias("xmlSchemaFree__internal_alias")));
+#else
+#ifndef xmlSchemaFree
+extern __typeof (xmlSchemaFree) xmlSchemaFree__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFree xmlSchemaFree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFreeFacet
+extern __typeof (xmlSchemaFreeFacet) xmlSchemaFreeFacet __attribute((alias("xmlSchemaFreeFacet__internal_alias")));
+#else
+#ifndef xmlSchemaFreeFacet
+extern __typeof (xmlSchemaFreeFacet) xmlSchemaFreeFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeFacet xmlSchemaFreeFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFreeParserCtxt
+extern __typeof (xmlSchemaFreeParserCtxt) xmlSchemaFreeParserCtxt __attribute((alias("xmlSchemaFreeParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaFreeParserCtxt
+extern __typeof (xmlSchemaFreeParserCtxt) xmlSchemaFreeParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeParserCtxt xmlSchemaFreeParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFreeType
+extern __typeof (xmlSchemaFreeType) xmlSchemaFreeType __attribute((alias("xmlSchemaFreeType__internal_alias")));
+#else
+#ifndef xmlSchemaFreeType
+extern __typeof (xmlSchemaFreeType) xmlSchemaFreeType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeType xmlSchemaFreeType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFreeValidCtxt
+extern __typeof (xmlSchemaFreeValidCtxt) xmlSchemaFreeValidCtxt __attribute((alias("xmlSchemaFreeValidCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaFreeValidCtxt
+extern __typeof (xmlSchemaFreeValidCtxt) xmlSchemaFreeValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeValidCtxt xmlSchemaFreeValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaFreeValue
+extern __typeof (xmlSchemaFreeValue) xmlSchemaFreeValue __attribute((alias("xmlSchemaFreeValue__internal_alias")));
+#else
+#ifndef xmlSchemaFreeValue
+extern __typeof (xmlSchemaFreeValue) xmlSchemaFreeValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeValue xmlSchemaFreeValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaFreeWildcard
+extern __typeof (xmlSchemaFreeWildcard) xmlSchemaFreeWildcard __attribute((alias("xmlSchemaFreeWildcard__internal_alias")));
+#else
+#ifndef xmlSchemaFreeWildcard
+extern __typeof (xmlSchemaFreeWildcard) xmlSchemaFreeWildcard__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaFreeWildcard xmlSchemaFreeWildcard__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetBuiltInListSimpleTypeItemType
+extern __typeof (xmlSchemaGetBuiltInListSimpleTypeItemType) xmlSchemaGetBuiltInListSimpleTypeItemType __attribute((alias("xmlSchemaGetBuiltInListSimpleTypeItemType__internal_alias")));
+#else
+#ifndef xmlSchemaGetBuiltInListSimpleTypeItemType
+extern __typeof (xmlSchemaGetBuiltInListSimpleTypeItemType) xmlSchemaGetBuiltInListSimpleTypeItemType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetBuiltInListSimpleTypeItemType xmlSchemaGetBuiltInListSimpleTypeItemType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetBuiltInType
+extern __typeof (xmlSchemaGetBuiltInType) xmlSchemaGetBuiltInType __attribute((alias("xmlSchemaGetBuiltInType__internal_alias")));
+#else
+#ifndef xmlSchemaGetBuiltInType
+extern __typeof (xmlSchemaGetBuiltInType) xmlSchemaGetBuiltInType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetBuiltInType xmlSchemaGetBuiltInType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetCanonValue
+extern __typeof (xmlSchemaGetCanonValue) xmlSchemaGetCanonValue __attribute((alias("xmlSchemaGetCanonValue__internal_alias")));
+#else
+#ifndef xmlSchemaGetCanonValue
+extern __typeof (xmlSchemaGetCanonValue) xmlSchemaGetCanonValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetCanonValue xmlSchemaGetCanonValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetCanonValueWhtsp
+extern __typeof (xmlSchemaGetCanonValueWhtsp) xmlSchemaGetCanonValueWhtsp __attribute((alias("xmlSchemaGetCanonValueWhtsp__internal_alias")));
+#else
+#ifndef xmlSchemaGetCanonValueWhtsp
+extern __typeof (xmlSchemaGetCanonValueWhtsp) xmlSchemaGetCanonValueWhtsp__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetCanonValueWhtsp xmlSchemaGetCanonValueWhtsp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetFacetValueAsULong
+extern __typeof (xmlSchemaGetFacetValueAsULong) xmlSchemaGetFacetValueAsULong __attribute((alias("xmlSchemaGetFacetValueAsULong__internal_alias")));
+#else
+#ifndef xmlSchemaGetFacetValueAsULong
+extern __typeof (xmlSchemaGetFacetValueAsULong) xmlSchemaGetFacetValueAsULong__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetFacetValueAsULong xmlSchemaGetFacetValueAsULong__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaGetParserErrors
+extern __typeof (xmlSchemaGetParserErrors) xmlSchemaGetParserErrors __attribute((alias("xmlSchemaGetParserErrors__internal_alias")));
+#else
+#ifndef xmlSchemaGetParserErrors
+extern __typeof (xmlSchemaGetParserErrors) xmlSchemaGetParserErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetParserErrors xmlSchemaGetParserErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetPredefinedType
+extern __typeof (xmlSchemaGetPredefinedType) xmlSchemaGetPredefinedType __attribute((alias("xmlSchemaGetPredefinedType__internal_alias")));
+#else
+#ifndef xmlSchemaGetPredefinedType
+extern __typeof (xmlSchemaGetPredefinedType) xmlSchemaGetPredefinedType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetPredefinedType xmlSchemaGetPredefinedType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaGetValType
+extern __typeof (xmlSchemaGetValType) xmlSchemaGetValType __attribute((alias("xmlSchemaGetValType__internal_alias")));
+#else
+#ifndef xmlSchemaGetValType
+extern __typeof (xmlSchemaGetValType) xmlSchemaGetValType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetValType xmlSchemaGetValType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaGetValidErrors
+extern __typeof (xmlSchemaGetValidErrors) xmlSchemaGetValidErrors __attribute((alias("xmlSchemaGetValidErrors__internal_alias")));
+#else
+#ifndef xmlSchemaGetValidErrors
+extern __typeof (xmlSchemaGetValidErrors) xmlSchemaGetValidErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaGetValidErrors xmlSchemaGetValidErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaInitTypes
+extern __typeof (xmlSchemaInitTypes) xmlSchemaInitTypes __attribute((alias("xmlSchemaInitTypes__internal_alias")));
+#else
+#ifndef xmlSchemaInitTypes
+extern __typeof (xmlSchemaInitTypes) xmlSchemaInitTypes__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaInitTypes xmlSchemaInitTypes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaIsBuiltInTypeFacet
+extern __typeof (xmlSchemaIsBuiltInTypeFacet) xmlSchemaIsBuiltInTypeFacet __attribute((alias("xmlSchemaIsBuiltInTypeFacet__internal_alias")));
+#else
+#ifndef xmlSchemaIsBuiltInTypeFacet
+extern __typeof (xmlSchemaIsBuiltInTypeFacet) xmlSchemaIsBuiltInTypeFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaIsBuiltInTypeFacet xmlSchemaIsBuiltInTypeFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaIsValid
+extern __typeof (xmlSchemaIsValid) xmlSchemaIsValid __attribute((alias("xmlSchemaIsValid__internal_alias")));
+#else
+#ifndef xmlSchemaIsValid
+extern __typeof (xmlSchemaIsValid) xmlSchemaIsValid__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaIsValid xmlSchemaIsValid__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaNewDocParserCtxt
+extern __typeof (xmlSchemaNewDocParserCtxt) xmlSchemaNewDocParserCtxt __attribute((alias("xmlSchemaNewDocParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaNewDocParserCtxt
+extern __typeof (xmlSchemaNewDocParserCtxt) xmlSchemaNewDocParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewDocParserCtxt xmlSchemaNewDocParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaNewFacet
+extern __typeof (xmlSchemaNewFacet) xmlSchemaNewFacet __attribute((alias("xmlSchemaNewFacet__internal_alias")));
+#else
+#ifndef xmlSchemaNewFacet
+extern __typeof (xmlSchemaNewFacet) xmlSchemaNewFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewFacet xmlSchemaNewFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaNewMemParserCtxt
+extern __typeof (xmlSchemaNewMemParserCtxt) xmlSchemaNewMemParserCtxt __attribute((alias("xmlSchemaNewMemParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaNewMemParserCtxt
+extern __typeof (xmlSchemaNewMemParserCtxt) xmlSchemaNewMemParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewMemParserCtxt xmlSchemaNewMemParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaNewNOTATIONValue
+extern __typeof (xmlSchemaNewNOTATIONValue) xmlSchemaNewNOTATIONValue __attribute((alias("xmlSchemaNewNOTATIONValue__internal_alias")));
+#else
+#ifndef xmlSchemaNewNOTATIONValue
+extern __typeof (xmlSchemaNewNOTATIONValue) xmlSchemaNewNOTATIONValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewNOTATIONValue xmlSchemaNewNOTATIONValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaNewParserCtxt
+extern __typeof (xmlSchemaNewParserCtxt) xmlSchemaNewParserCtxt __attribute((alias("xmlSchemaNewParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaNewParserCtxt
+extern __typeof (xmlSchemaNewParserCtxt) xmlSchemaNewParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewParserCtxt xmlSchemaNewParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaNewQNameValue
+extern __typeof (xmlSchemaNewQNameValue) xmlSchemaNewQNameValue __attribute((alias("xmlSchemaNewQNameValue__internal_alias")));
+#else
+#ifndef xmlSchemaNewQNameValue
+extern __typeof (xmlSchemaNewQNameValue) xmlSchemaNewQNameValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewQNameValue xmlSchemaNewQNameValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaNewStringValue
+extern __typeof (xmlSchemaNewStringValue) xmlSchemaNewStringValue __attribute((alias("xmlSchemaNewStringValue__internal_alias")));
+#else
+#ifndef xmlSchemaNewStringValue
+extern __typeof (xmlSchemaNewStringValue) xmlSchemaNewStringValue__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewStringValue xmlSchemaNewStringValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaNewValidCtxt
+extern __typeof (xmlSchemaNewValidCtxt) xmlSchemaNewValidCtxt __attribute((alias("xmlSchemaNewValidCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaNewValidCtxt
+extern __typeof (xmlSchemaNewValidCtxt) xmlSchemaNewValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaNewValidCtxt xmlSchemaNewValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaParse
+extern __typeof (xmlSchemaParse) xmlSchemaParse __attribute((alias("xmlSchemaParse__internal_alias")));
+#else
+#ifndef xmlSchemaParse
+extern __typeof (xmlSchemaParse) xmlSchemaParse__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaParse xmlSchemaParse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSAXPlug
+extern __typeof (xmlSchemaSAXPlug) xmlSchemaSAXPlug __attribute((alias("xmlSchemaSAXPlug__internal_alias")));
+#else
+#ifndef xmlSchemaSAXPlug
+extern __typeof (xmlSchemaSAXPlug) xmlSchemaSAXPlug__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSAXPlug xmlSchemaSAXPlug__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSAXUnplug
+extern __typeof (xmlSchemaSAXUnplug) xmlSchemaSAXUnplug __attribute((alias("xmlSchemaSAXUnplug__internal_alias")));
+#else
+#ifndef xmlSchemaSAXUnplug
+extern __typeof (xmlSchemaSAXUnplug) xmlSchemaSAXUnplug__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSAXUnplug xmlSchemaSAXUnplug__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSetParserErrors
+extern __typeof (xmlSchemaSetParserErrors) xmlSchemaSetParserErrors __attribute((alias("xmlSchemaSetParserErrors__internal_alias")));
+#else
+#ifndef xmlSchemaSetParserErrors
+extern __typeof (xmlSchemaSetParserErrors) xmlSchemaSetParserErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSetParserErrors xmlSchemaSetParserErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSetParserStructuredErrors
+extern __typeof (xmlSchemaSetParserStructuredErrors) xmlSchemaSetParserStructuredErrors __attribute((alias("xmlSchemaSetParserStructuredErrors__internal_alias")));
+#else
+#ifndef xmlSchemaSetParserStructuredErrors
+extern __typeof (xmlSchemaSetParserStructuredErrors) xmlSchemaSetParserStructuredErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSetParserStructuredErrors xmlSchemaSetParserStructuredErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSetValidErrors
+extern __typeof (xmlSchemaSetValidErrors) xmlSchemaSetValidErrors __attribute((alias("xmlSchemaSetValidErrors__internal_alias")));
+#else
+#ifndef xmlSchemaSetValidErrors
+extern __typeof (xmlSchemaSetValidErrors) xmlSchemaSetValidErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSetValidErrors xmlSchemaSetValidErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSetValidOptions
+extern __typeof (xmlSchemaSetValidOptions) xmlSchemaSetValidOptions __attribute((alias("xmlSchemaSetValidOptions__internal_alias")));
+#else
+#ifndef xmlSchemaSetValidOptions
+extern __typeof (xmlSchemaSetValidOptions) xmlSchemaSetValidOptions__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSetValidOptions xmlSchemaSetValidOptions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaSetValidStructuredErrors
+extern __typeof (xmlSchemaSetValidStructuredErrors) xmlSchemaSetValidStructuredErrors __attribute((alias("xmlSchemaSetValidStructuredErrors__internal_alias")));
+#else
+#ifndef xmlSchemaSetValidStructuredErrors
+extern __typeof (xmlSchemaSetValidStructuredErrors) xmlSchemaSetValidStructuredErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaSetValidStructuredErrors xmlSchemaSetValidStructuredErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValPredefTypeNode
+extern __typeof (xmlSchemaValPredefTypeNode) xmlSchemaValPredefTypeNode __attribute((alias("xmlSchemaValPredefTypeNode__internal_alias")));
+#else
+#ifndef xmlSchemaValPredefTypeNode
+extern __typeof (xmlSchemaValPredefTypeNode) xmlSchemaValPredefTypeNode__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValPredefTypeNode xmlSchemaValPredefTypeNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValPredefTypeNodeNoNorm
+extern __typeof (xmlSchemaValPredefTypeNodeNoNorm) xmlSchemaValPredefTypeNodeNoNorm __attribute((alias("xmlSchemaValPredefTypeNodeNoNorm__internal_alias")));
+#else
+#ifndef xmlSchemaValPredefTypeNodeNoNorm
+extern __typeof (xmlSchemaValPredefTypeNodeNoNorm) xmlSchemaValPredefTypeNodeNoNorm__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValPredefTypeNodeNoNorm xmlSchemaValPredefTypeNodeNoNorm__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidCtxtGetOptions
+extern __typeof (xmlSchemaValidCtxtGetOptions) xmlSchemaValidCtxtGetOptions __attribute((alias("xmlSchemaValidCtxtGetOptions__internal_alias")));
+#else
+#ifndef xmlSchemaValidCtxtGetOptions
+extern __typeof (xmlSchemaValidCtxtGetOptions) xmlSchemaValidCtxtGetOptions__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidCtxtGetOptions xmlSchemaValidCtxtGetOptions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidCtxtGetParserCtxt
+extern __typeof (xmlSchemaValidCtxtGetParserCtxt) xmlSchemaValidCtxtGetParserCtxt __attribute((alias("xmlSchemaValidCtxtGetParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchemaValidCtxtGetParserCtxt
+extern __typeof (xmlSchemaValidCtxtGetParserCtxt) xmlSchemaValidCtxtGetParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidCtxtGetParserCtxt xmlSchemaValidCtxtGetParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidateDoc
+extern __typeof (xmlSchemaValidateDoc) xmlSchemaValidateDoc __attribute((alias("xmlSchemaValidateDoc__internal_alias")));
+#else
+#ifndef xmlSchemaValidateDoc
+extern __typeof (xmlSchemaValidateDoc) xmlSchemaValidateDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateDoc xmlSchemaValidateDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidateFacet
+extern __typeof (xmlSchemaValidateFacet) xmlSchemaValidateFacet __attribute((alias("xmlSchemaValidateFacet__internal_alias")));
+#else
+#ifndef xmlSchemaValidateFacet
+extern __typeof (xmlSchemaValidateFacet) xmlSchemaValidateFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateFacet xmlSchemaValidateFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidateFacetWhtsp
+extern __typeof (xmlSchemaValidateFacetWhtsp) xmlSchemaValidateFacetWhtsp __attribute((alias("xmlSchemaValidateFacetWhtsp__internal_alias")));
+#else
+#ifndef xmlSchemaValidateFacetWhtsp
+extern __typeof (xmlSchemaValidateFacetWhtsp) xmlSchemaValidateFacetWhtsp__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateFacetWhtsp xmlSchemaValidateFacetWhtsp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidateFile
+extern __typeof (xmlSchemaValidateFile) xmlSchemaValidateFile __attribute((alias("xmlSchemaValidateFile__internal_alias")));
+#else
+#ifndef xmlSchemaValidateFile
+extern __typeof (xmlSchemaValidateFile) xmlSchemaValidateFile__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateFile xmlSchemaValidateFile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidateLengthFacet
+extern __typeof (xmlSchemaValidateLengthFacet) xmlSchemaValidateLengthFacet __attribute((alias("xmlSchemaValidateLengthFacet__internal_alias")));
+#else
+#ifndef xmlSchemaValidateLengthFacet
+extern __typeof (xmlSchemaValidateLengthFacet) xmlSchemaValidateLengthFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateLengthFacet xmlSchemaValidateLengthFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidateLengthFacetWhtsp
+extern __typeof (xmlSchemaValidateLengthFacetWhtsp) xmlSchemaValidateLengthFacetWhtsp __attribute((alias("xmlSchemaValidateLengthFacetWhtsp__internal_alias")));
+#else
+#ifndef xmlSchemaValidateLengthFacetWhtsp
+extern __typeof (xmlSchemaValidateLengthFacetWhtsp) xmlSchemaValidateLengthFacetWhtsp__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateLengthFacetWhtsp xmlSchemaValidateLengthFacetWhtsp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidateListSimpleTypeFacet
+extern __typeof (xmlSchemaValidateListSimpleTypeFacet) xmlSchemaValidateListSimpleTypeFacet __attribute((alias("xmlSchemaValidateListSimpleTypeFacet__internal_alias")));
+#else
+#ifndef xmlSchemaValidateListSimpleTypeFacet
+extern __typeof (xmlSchemaValidateListSimpleTypeFacet) xmlSchemaValidateListSimpleTypeFacet__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateListSimpleTypeFacet xmlSchemaValidateListSimpleTypeFacet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidateOneElement
+extern __typeof (xmlSchemaValidateOneElement) xmlSchemaValidateOneElement __attribute((alias("xmlSchemaValidateOneElement__internal_alias")));
+#else
+#ifndef xmlSchemaValidateOneElement
+extern __typeof (xmlSchemaValidateOneElement) xmlSchemaValidateOneElement__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateOneElement xmlSchemaValidateOneElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValidatePredefinedType
+extern __typeof (xmlSchemaValidatePredefinedType) xmlSchemaValidatePredefinedType __attribute((alias("xmlSchemaValidatePredefinedType__internal_alias")));
+#else
+#ifndef xmlSchemaValidatePredefinedType
+extern __typeof (xmlSchemaValidatePredefinedType) xmlSchemaValidatePredefinedType__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidatePredefinedType xmlSchemaValidatePredefinedType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemas
+#undef xmlSchemaValidateStream
+extern __typeof (xmlSchemaValidateStream) xmlSchemaValidateStream __attribute((alias("xmlSchemaValidateStream__internal_alias")));
+#else
+#ifndef xmlSchemaValidateStream
+extern __typeof (xmlSchemaValidateStream) xmlSchemaValidateStream__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValidateStream xmlSchemaValidateStream__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValueAppend
+extern __typeof (xmlSchemaValueAppend) xmlSchemaValueAppend __attribute((alias("xmlSchemaValueAppend__internal_alias")));
+#else
+#ifndef xmlSchemaValueAppend
+extern __typeof (xmlSchemaValueAppend) xmlSchemaValueAppend__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValueAppend xmlSchemaValueAppend__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValueGetAsBoolean
+extern __typeof (xmlSchemaValueGetAsBoolean) xmlSchemaValueGetAsBoolean __attribute((alias("xmlSchemaValueGetAsBoolean__internal_alias")));
+#else
+#ifndef xmlSchemaValueGetAsBoolean
+extern __typeof (xmlSchemaValueGetAsBoolean) xmlSchemaValueGetAsBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValueGetAsBoolean xmlSchemaValueGetAsBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValueGetAsString
+extern __typeof (xmlSchemaValueGetAsString) xmlSchemaValueGetAsString __attribute((alias("xmlSchemaValueGetAsString__internal_alias")));
+#else
+#ifndef xmlSchemaValueGetAsString
+extern __typeof (xmlSchemaValueGetAsString) xmlSchemaValueGetAsString__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValueGetAsString xmlSchemaValueGetAsString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaValueGetNext
+extern __typeof (xmlSchemaValueGetNext) xmlSchemaValueGetNext __attribute((alias("xmlSchemaValueGetNext__internal_alias")));
+#else
+#ifndef xmlSchemaValueGetNext
+extern __typeof (xmlSchemaValueGetNext) xmlSchemaValueGetNext__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaValueGetNext xmlSchemaValueGetNext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlschemastypes
+#undef xmlSchemaWhiteSpaceReplace
+extern __typeof (xmlSchemaWhiteSpaceReplace) xmlSchemaWhiteSpaceReplace __attribute((alias("xmlSchemaWhiteSpaceReplace__internal_alias")));
+#else
+#ifndef xmlSchemaWhiteSpaceReplace
+extern __typeof (xmlSchemaWhiteSpaceReplace) xmlSchemaWhiteSpaceReplace__internal_alias __attribute((visibility("hidden")));
+#define xmlSchemaWhiteSpaceReplace xmlSchemaWhiteSpaceReplace__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronFree
+extern __typeof (xmlSchematronFree) xmlSchematronFree __attribute((alias("xmlSchematronFree__internal_alias")));
+#else
+#ifndef xmlSchematronFree
+extern __typeof (xmlSchematronFree) xmlSchematronFree__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronFree xmlSchematronFree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronFreeParserCtxt
+extern __typeof (xmlSchematronFreeParserCtxt) xmlSchematronFreeParserCtxt __attribute((alias("xmlSchematronFreeParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronFreeParserCtxt
+extern __typeof (xmlSchematronFreeParserCtxt) xmlSchematronFreeParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronFreeParserCtxt xmlSchematronFreeParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronFreeValidCtxt
+extern __typeof (xmlSchematronFreeValidCtxt) xmlSchematronFreeValidCtxt __attribute((alias("xmlSchematronFreeValidCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronFreeValidCtxt
+extern __typeof (xmlSchematronFreeValidCtxt) xmlSchematronFreeValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronFreeValidCtxt xmlSchematronFreeValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronNewDocParserCtxt
+extern __typeof (xmlSchematronNewDocParserCtxt) xmlSchematronNewDocParserCtxt __attribute((alias("xmlSchematronNewDocParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronNewDocParserCtxt
+extern __typeof (xmlSchematronNewDocParserCtxt) xmlSchematronNewDocParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronNewDocParserCtxt xmlSchematronNewDocParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronNewMemParserCtxt
+extern __typeof (xmlSchematronNewMemParserCtxt) xmlSchematronNewMemParserCtxt __attribute((alias("xmlSchematronNewMemParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronNewMemParserCtxt
+extern __typeof (xmlSchematronNewMemParserCtxt) xmlSchematronNewMemParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronNewMemParserCtxt xmlSchematronNewMemParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronNewParserCtxt
+extern __typeof (xmlSchematronNewParserCtxt) xmlSchematronNewParserCtxt __attribute((alias("xmlSchematronNewParserCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronNewParserCtxt
+extern __typeof (xmlSchematronNewParserCtxt) xmlSchematronNewParserCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronNewParserCtxt xmlSchematronNewParserCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronNewValidCtxt
+extern __typeof (xmlSchematronNewValidCtxt) xmlSchematronNewValidCtxt __attribute((alias("xmlSchematronNewValidCtxt__internal_alias")));
+#else
+#ifndef xmlSchematronNewValidCtxt
+extern __typeof (xmlSchematronNewValidCtxt) xmlSchematronNewValidCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronNewValidCtxt xmlSchematronNewValidCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronParse
+extern __typeof (xmlSchematronParse) xmlSchematronParse __attribute((alias("xmlSchematronParse__internal_alias")));
+#else
+#ifndef xmlSchematronParse
+extern __typeof (xmlSchematronParse) xmlSchematronParse__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronParse xmlSchematronParse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronSetValidStructuredErrors
+extern __typeof (xmlSchematronSetValidStructuredErrors) xmlSchematronSetValidStructuredErrors __attribute((alias("xmlSchematronSetValidStructuredErrors__internal_alias")));
+#else
+#ifndef xmlSchematronSetValidStructuredErrors
+extern __typeof (xmlSchematronSetValidStructuredErrors) xmlSchematronSetValidStructuredErrors__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronSetValidStructuredErrors xmlSchematronSetValidStructuredErrors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+#ifdef bottom_schematron
+#undef xmlSchematronValidateDoc
+extern __typeof (xmlSchematronValidateDoc) xmlSchematronValidateDoc __attribute((alias("xmlSchematronValidateDoc__internal_alias")));
+#else
+#ifndef xmlSchematronValidateDoc
+extern __typeof (xmlSchematronValidateDoc) xmlSchematronValidateDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSchematronValidateDoc xmlSchematronValidateDoc__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSearchNs
+extern __typeof (xmlSearchNs) xmlSearchNs __attribute((alias("xmlSearchNs__internal_alias")));
+#else
+#ifndef xmlSearchNs
+extern __typeof (xmlSearchNs) xmlSearchNs__internal_alias __attribute((visibility("hidden")));
+#define xmlSearchNs xmlSearchNs__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSearchNsByHref
+extern __typeof (xmlSearchNsByHref) xmlSearchNsByHref __attribute((alias("xmlSearchNsByHref__internal_alias")));
+#else
+#ifndef xmlSearchNsByHref
+extern __typeof (xmlSearchNsByHref) xmlSearchNsByHref__internal_alias __attribute((visibility("hidden")));
+#define xmlSearchNsByHref xmlSearchNsByHref__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetBufferAllocationScheme
+extern __typeof (xmlSetBufferAllocationScheme) xmlSetBufferAllocationScheme __attribute((alias("xmlSetBufferAllocationScheme__internal_alias")));
+#else
+#ifndef xmlSetBufferAllocationScheme
+extern __typeof (xmlSetBufferAllocationScheme) xmlSetBufferAllocationScheme__internal_alias __attribute((visibility("hidden")));
+#define xmlSetBufferAllocationScheme xmlSetBufferAllocationScheme__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetCompressMode
+extern __typeof (xmlSetCompressMode) xmlSetCompressMode __attribute((alias("xmlSetCompressMode__internal_alias")));
+#else
+#ifndef xmlSetCompressMode
+extern __typeof (xmlSetCompressMode) xmlSetCompressMode__internal_alias __attribute((visibility("hidden")));
+#define xmlSetCompressMode xmlSetCompressMode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetDocCompressMode
+extern __typeof (xmlSetDocCompressMode) xmlSetDocCompressMode __attribute((alias("xmlSetDocCompressMode__internal_alias")));
+#else
+#ifndef xmlSetDocCompressMode
+extern __typeof (xmlSetDocCompressMode) xmlSetDocCompressMode__internal_alias __attribute((visibility("hidden")));
+#define xmlSetDocCompressMode xmlSetDocCompressMode__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_parser
+#undef xmlSetEntityReferenceFunc
+extern __typeof (xmlSetEntityReferenceFunc) xmlSetEntityReferenceFunc __attribute((alias("xmlSetEntityReferenceFunc__internal_alias")));
+#else
+#ifndef xmlSetEntityReferenceFunc
+extern __typeof (xmlSetEntityReferenceFunc) xmlSetEntityReferenceFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlSetEntityReferenceFunc xmlSetEntityReferenceFunc__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_xmlIO
+#undef xmlSetExternalEntityLoader
+extern __typeof (xmlSetExternalEntityLoader) xmlSetExternalEntityLoader __attribute((alias("xmlSetExternalEntityLoader__internal_alias")));
+#else
+#ifndef xmlSetExternalEntityLoader
+extern __typeof (xmlSetExternalEntityLoader) xmlSetExternalEntityLoader__internal_alias __attribute((visibility("hidden")));
+#define xmlSetExternalEntityLoader xmlSetExternalEntityLoader__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef bottom_legacy
+#undef xmlSetFeature
+extern __typeof (xmlSetFeature) xmlSetFeature __attribute((alias("xmlSetFeature__internal_alias")));
+#else
+#ifndef xmlSetFeature
+extern __typeof (xmlSetFeature) xmlSetFeature__internal_alias __attribute((visibility("hidden")));
+#define xmlSetFeature xmlSetFeature__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlSetGenericErrorFunc
+extern __typeof (xmlSetGenericErrorFunc) xmlSetGenericErrorFunc __attribute((alias("xmlSetGenericErrorFunc__internal_alias")));
+#else
+#ifndef xmlSetGenericErrorFunc
+extern __typeof (xmlSetGenericErrorFunc) xmlSetGenericErrorFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlSetGenericErrorFunc xmlSetGenericErrorFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetListDoc
+extern __typeof (xmlSetListDoc) xmlSetListDoc __attribute((alias("xmlSetListDoc__internal_alias")));
+#else
+#ifndef xmlSetListDoc
+extern __typeof (xmlSetListDoc) xmlSetListDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSetListDoc xmlSetListDoc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetNs
+extern __typeof (xmlSetNs) xmlSetNs __attribute((alias("xmlSetNs__internal_alias")));
+#else
+#ifndef xmlSetNs
+extern __typeof (xmlSetNs) xmlSetNs__internal_alias __attribute((visibility("hidden")));
+#define xmlSetNs xmlSetNs__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_tree
+#undef xmlSetNsProp
+extern __typeof (xmlSetNsProp) xmlSetNsProp __attribute((alias("xmlSetNsProp__internal_alias")));
+#else
+#ifndef xmlSetNsProp
+extern __typeof (xmlSetNsProp) xmlSetNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlSetNsProp xmlSetNsProp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+#ifdef bottom_tree
+#undef xmlSetProp
+extern __typeof (xmlSetProp) xmlSetProp __attribute((alias("xmlSetProp__internal_alias")));
+#else
+#ifndef xmlSetProp
+extern __typeof (xmlSetProp) xmlSetProp__internal_alias __attribute((visibility("hidden")));
+#define xmlSetProp xmlSetProp__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_error
+#undef xmlSetStructuredErrorFunc
+extern __typeof (xmlSetStructuredErrorFunc) xmlSetStructuredErrorFunc __attribute((alias("xmlSetStructuredErrorFunc__internal_alias")));
+#else
+#ifndef xmlSetStructuredErrorFunc
+extern __typeof (xmlSetStructuredErrorFunc) xmlSetStructuredErrorFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlSetStructuredErrorFunc xmlSetStructuredErrorFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSetTreeDoc
+extern __typeof (xmlSetTreeDoc) xmlSetTreeDoc __attribute((alias("xmlSetTreeDoc__internal_alias")));
+#else
+#ifndef xmlSetTreeDoc
+extern __typeof (xmlSetTreeDoc) xmlSetTreeDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlSetTreeDoc xmlSetTreeDoc__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef bottom_parser
+#undef xmlSetupParserForBuffer
+extern __typeof (xmlSetupParserForBuffer) xmlSetupParserForBuffer __attribute((alias("xmlSetupParserForBuffer__internal_alias")));
+#else
+#ifndef xmlSetupParserForBuffer
+extern __typeof (xmlSetupParserForBuffer) xmlSetupParserForBuffer__internal_alias __attribute((visibility("hidden")));
+#define xmlSetupParserForBuffer xmlSetupParserForBuffer__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShell
+extern __typeof (xmlShell) xmlShell __attribute((alias("xmlShell__internal_alias")));
+#else
+#ifndef xmlShell
+extern __typeof (xmlShell) xmlShell__internal_alias __attribute((visibility("hidden")));
+#define xmlShell xmlShell__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellBase
+extern __typeof (xmlShellBase) xmlShellBase __attribute((alias("xmlShellBase__internal_alias")));
+#else
+#ifndef xmlShellBase
+extern __typeof (xmlShellBase) xmlShellBase__internal_alias __attribute((visibility("hidden")));
+#define xmlShellBase xmlShellBase__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellCat
+extern __typeof (xmlShellCat) xmlShellCat __attribute((alias("xmlShellCat__internal_alias")));
+#else
+#ifndef xmlShellCat
+extern __typeof (xmlShellCat) xmlShellCat__internal_alias __attribute((visibility("hidden")));
+#define xmlShellCat xmlShellCat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellDir
+extern __typeof (xmlShellDir) xmlShellDir __attribute((alias("xmlShellDir__internal_alias")));
+#else
+#ifndef xmlShellDir
+extern __typeof (xmlShellDir) xmlShellDir__internal_alias __attribute((visibility("hidden")));
+#define xmlShellDir xmlShellDir__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellDu
+extern __typeof (xmlShellDu) xmlShellDu __attribute((alias("xmlShellDu__internal_alias")));
+#else
+#ifndef xmlShellDu
+extern __typeof (xmlShellDu) xmlShellDu__internal_alias __attribute((visibility("hidden")));
+#define xmlShellDu xmlShellDu__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellList
+extern __typeof (xmlShellList) xmlShellList __attribute((alias("xmlShellList__internal_alias")));
+#else
+#ifndef xmlShellList
+extern __typeof (xmlShellList) xmlShellList__internal_alias __attribute((visibility("hidden")));
+#define xmlShellList xmlShellList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellLoad
+extern __typeof (xmlShellLoad) xmlShellLoad __attribute((alias("xmlShellLoad__internal_alias")));
+#else
+#ifndef xmlShellLoad
+extern __typeof (xmlShellLoad) xmlShellLoad__internal_alias __attribute((visibility("hidden")));
+#define xmlShellLoad xmlShellLoad__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellPrintNode
+extern __typeof (xmlShellPrintNode) xmlShellPrintNode __attribute((alias("xmlShellPrintNode__internal_alias")));
+#else
+#ifndef xmlShellPrintNode
+extern __typeof (xmlShellPrintNode) xmlShellPrintNode__internal_alias __attribute((visibility("hidden")));
+#define xmlShellPrintNode xmlShellPrintNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellPrintXPathError
+extern __typeof (xmlShellPrintXPathError) xmlShellPrintXPathError __attribute((alias("xmlShellPrintXPathError__internal_alias")));
+#else
+#ifndef xmlShellPrintXPathError
+extern __typeof (xmlShellPrintXPathError) xmlShellPrintXPathError__internal_alias __attribute((visibility("hidden")));
+#define xmlShellPrintXPathError xmlShellPrintXPathError__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellPrintXPathResult
+extern __typeof (xmlShellPrintXPathResult) xmlShellPrintXPathResult __attribute((alias("xmlShellPrintXPathResult__internal_alias")));
+#else
+#ifndef xmlShellPrintXPathResult
+extern __typeof (xmlShellPrintXPathResult) xmlShellPrintXPathResult__internal_alias __attribute((visibility("hidden")));
+#define xmlShellPrintXPathResult xmlShellPrintXPathResult__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellPwd
+extern __typeof (xmlShellPwd) xmlShellPwd __attribute((alias("xmlShellPwd__internal_alias")));
+#else
+#ifndef xmlShellPwd
+extern __typeof (xmlShellPwd) xmlShellPwd__internal_alias __attribute((visibility("hidden")));
+#define xmlShellPwd xmlShellPwd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellSave
+extern __typeof (xmlShellSave) xmlShellSave __attribute((alias("xmlShellSave__internal_alias")));
+#else
+#ifndef xmlShellSave
+extern __typeof (xmlShellSave) xmlShellSave__internal_alias __attribute((visibility("hidden")));
+#define xmlShellSave xmlShellSave__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellValidate
+extern __typeof (xmlShellValidate) xmlShellValidate __attribute((alias("xmlShellValidate__internal_alias")));
+#else
+#ifndef xmlShellValidate
+extern __typeof (xmlShellValidate) xmlShellValidate__internal_alias __attribute((visibility("hidden")));
+#define xmlShellValidate xmlShellValidate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_debugXML
+#undef xmlShellWrite
+extern __typeof (xmlShellWrite) xmlShellWrite __attribute((alias("xmlShellWrite__internal_alias")));
+#else
+#ifndef xmlShellWrite
+extern __typeof (xmlShellWrite) xmlShellWrite__internal_alias __attribute((visibility("hidden")));
+#define xmlShellWrite xmlShellWrite__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlSkipBlankChars
+extern __typeof (xmlSkipBlankChars) xmlSkipBlankChars __attribute((alias("xmlSkipBlankChars__internal_alias")));
+#else
+#ifndef xmlSkipBlankChars
+extern __typeof (xmlSkipBlankChars) xmlSkipBlankChars__internal_alias __attribute((visibility("hidden")));
+#define xmlSkipBlankChars xmlSkipBlankChars__internal_alias
+#endif
+#endif
+
+#ifdef bottom_valid
+#undef xmlSnprintfElementContent
+extern __typeof (xmlSnprintfElementContent) xmlSnprintfElementContent __attribute((alias("xmlSnprintfElementContent__internal_alias")));
+#else
+#ifndef xmlSnprintfElementContent
+extern __typeof (xmlSnprintfElementContent) xmlSnprintfElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlSnprintfElementContent xmlSnprintfElementContent__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlSplitQName
+extern __typeof (xmlSplitQName) xmlSplitQName __attribute((alias("xmlSplitQName__internal_alias")));
+#else
+#ifndef xmlSplitQName
+extern __typeof (xmlSplitQName) xmlSplitQName__internal_alias __attribute((visibility("hidden")));
+#define xmlSplitQName xmlSplitQName__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSplitQName2
+extern __typeof (xmlSplitQName2) xmlSplitQName2 __attribute((alias("xmlSplitQName2__internal_alias")));
+#else
+#ifndef xmlSplitQName2
+extern __typeof (xmlSplitQName2) xmlSplitQName2__internal_alias __attribute((visibility("hidden")));
+#define xmlSplitQName2 xmlSplitQName2__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlSplitQName3
+extern __typeof (xmlSplitQName3) xmlSplitQName3 __attribute((alias("xmlSplitQName3__internal_alias")));
+#else
+#ifndef xmlSplitQName3
+extern __typeof (xmlSplitQName3) xmlSplitQName3__internal_alias __attribute((visibility("hidden")));
+#define xmlSplitQName3 xmlSplitQName3__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef bottom_valid
+#undef xmlSprintfElementContent
+extern __typeof (xmlSprintfElementContent) xmlSprintfElementContent __attribute((alias("xmlSprintfElementContent__internal_alias")));
+#else
+#ifndef xmlSprintfElementContent
+extern __typeof (xmlSprintfElementContent) xmlSprintfElementContent__internal_alias __attribute((visibility("hidden")));
+#define xmlSprintfElementContent xmlSprintfElementContent__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlStopParser
+extern __typeof (xmlStopParser) xmlStopParser __attribute((alias("xmlStopParser__internal_alias")));
+#else
+#ifndef xmlStopParser
+extern __typeof (xmlStopParser) xmlStopParser__internal_alias __attribute((visibility("hidden")));
+#define xmlStopParser xmlStopParser__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrEqual
+extern __typeof (xmlStrEqual) xmlStrEqual __attribute((alias("xmlStrEqual__internal_alias")));
+#else
+#ifndef xmlStrEqual
+extern __typeof (xmlStrEqual) xmlStrEqual__internal_alias __attribute((visibility("hidden")));
+#define xmlStrEqual xmlStrEqual__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrPrintf
+extern __typeof (xmlStrPrintf) xmlStrPrintf __attribute((alias("xmlStrPrintf__internal_alias")));
+#else
+#ifndef xmlStrPrintf
+extern __typeof (xmlStrPrintf) xmlStrPrintf__internal_alias __attribute((visibility("hidden")));
+#define xmlStrPrintf xmlStrPrintf__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrQEqual
+extern __typeof (xmlStrQEqual) xmlStrQEqual __attribute((alias("xmlStrQEqual__internal_alias")));
+#else
+#ifndef xmlStrQEqual
+extern __typeof (xmlStrQEqual) xmlStrQEqual__internal_alias __attribute((visibility("hidden")));
+#define xmlStrQEqual xmlStrQEqual__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrVPrintf
+extern __typeof (xmlStrVPrintf) xmlStrVPrintf __attribute((alias("xmlStrVPrintf__internal_alias")));
+#else
+#ifndef xmlStrVPrintf
+extern __typeof (xmlStrVPrintf) xmlStrVPrintf__internal_alias __attribute((visibility("hidden")));
+#define xmlStrVPrintf xmlStrVPrintf__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrcasecmp
+extern __typeof (xmlStrcasecmp) xmlStrcasecmp __attribute((alias("xmlStrcasecmp__internal_alias")));
+#else
+#ifndef xmlStrcasecmp
+extern __typeof (xmlStrcasecmp) xmlStrcasecmp__internal_alias __attribute((visibility("hidden")));
+#define xmlStrcasecmp xmlStrcasecmp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrcasestr
+extern __typeof (xmlStrcasestr) xmlStrcasestr __attribute((alias("xmlStrcasestr__internal_alias")));
+#else
+#ifndef xmlStrcasestr
+extern __typeof (xmlStrcasestr) xmlStrcasestr__internal_alias __attribute((visibility("hidden")));
+#define xmlStrcasestr xmlStrcasestr__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrcat
+extern __typeof (xmlStrcat) xmlStrcat __attribute((alias("xmlStrcat__internal_alias")));
+#else
+#ifndef xmlStrcat
+extern __typeof (xmlStrcat) xmlStrcat__internal_alias __attribute((visibility("hidden")));
+#define xmlStrcat xmlStrcat__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrchr
+extern __typeof (xmlStrchr) xmlStrchr __attribute((alias("xmlStrchr__internal_alias")));
+#else
+#ifndef xmlStrchr
+extern __typeof (xmlStrchr) xmlStrchr__internal_alias __attribute((visibility("hidden")));
+#define xmlStrchr xmlStrchr__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrcmp
+extern __typeof (xmlStrcmp) xmlStrcmp __attribute((alias("xmlStrcmp__internal_alias")));
+#else
+#ifndef xmlStrcmp
+extern __typeof (xmlStrcmp) xmlStrcmp__internal_alias __attribute((visibility("hidden")));
+#define xmlStrcmp xmlStrcmp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrdup
+extern __typeof (xmlStrdup) xmlStrdup __attribute((alias("xmlStrdup__internal_alias")));
+#else
+#ifndef xmlStrdup
+extern __typeof (xmlStrdup) xmlStrdup__internal_alias __attribute((visibility("hidden")));
+#define xmlStrdup xmlStrdup__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlStreamPop
+extern __typeof (xmlStreamPop) xmlStreamPop __attribute((alias("xmlStreamPop__internal_alias")));
+#else
+#ifndef xmlStreamPop
+extern __typeof (xmlStreamPop) xmlStreamPop__internal_alias __attribute((visibility("hidden")));
+#define xmlStreamPop xmlStreamPop__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlStreamPush
+extern __typeof (xmlStreamPush) xmlStreamPush __attribute((alias("xmlStreamPush__internal_alias")));
+#else
+#ifndef xmlStreamPush
+extern __typeof (xmlStreamPush) xmlStreamPush__internal_alias __attribute((visibility("hidden")));
+#define xmlStreamPush xmlStreamPush__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlStreamPushAttr
+extern __typeof (xmlStreamPushAttr) xmlStreamPushAttr __attribute((alias("xmlStreamPushAttr__internal_alias")));
+#else
+#ifndef xmlStreamPushAttr
+extern __typeof (xmlStreamPushAttr) xmlStreamPushAttr__internal_alias __attribute((visibility("hidden")));
+#define xmlStreamPushAttr xmlStreamPushAttr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlStreamPushNode
+extern __typeof (xmlStreamPushNode) xmlStreamPushNode __attribute((alias("xmlStreamPushNode__internal_alias")));
+#else
+#ifndef xmlStreamPushNode
+extern __typeof (xmlStreamPushNode) xmlStreamPushNode__internal_alias __attribute((visibility("hidden")));
+#define xmlStreamPushNode xmlStreamPushNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_pattern
+#undef xmlStreamWantsAnyNode
+extern __typeof (xmlStreamWantsAnyNode) xmlStreamWantsAnyNode __attribute((alias("xmlStreamWantsAnyNode__internal_alias")));
+#else
+#ifndef xmlStreamWantsAnyNode
+extern __typeof (xmlStreamWantsAnyNode) xmlStreamWantsAnyNode__internal_alias __attribute((visibility("hidden")));
+#define xmlStreamWantsAnyNode xmlStreamWantsAnyNode__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlStringCurrentChar
+extern __typeof (xmlStringCurrentChar) xmlStringCurrentChar __attribute((alias("xmlStringCurrentChar__internal_alias")));
+#else
+#ifndef xmlStringCurrentChar
+extern __typeof (xmlStringCurrentChar) xmlStringCurrentChar__internal_alias __attribute((visibility("hidden")));
+#define xmlStringCurrentChar xmlStringCurrentChar__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlStringDecodeEntities
+extern __typeof (xmlStringDecodeEntities) xmlStringDecodeEntities __attribute((alias("xmlStringDecodeEntities__internal_alias")));
+#else
+#ifndef xmlStringDecodeEntities
+extern __typeof (xmlStringDecodeEntities) xmlStringDecodeEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlStringDecodeEntities xmlStringDecodeEntities__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlStringGetNodeList
+extern __typeof (xmlStringGetNodeList) xmlStringGetNodeList __attribute((alias("xmlStringGetNodeList__internal_alias")));
+#else
+#ifndef xmlStringGetNodeList
+extern __typeof (xmlStringGetNodeList) xmlStringGetNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlStringGetNodeList xmlStringGetNodeList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parser
+#undef xmlStringLenDecodeEntities
+extern __typeof (xmlStringLenDecodeEntities) xmlStringLenDecodeEntities __attribute((alias("xmlStringLenDecodeEntities__internal_alias")));
+#else
+#ifndef xmlStringLenDecodeEntities
+extern __typeof (xmlStringLenDecodeEntities) xmlStringLenDecodeEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlStringLenDecodeEntities xmlStringLenDecodeEntities__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlStringLenGetNodeList
+extern __typeof (xmlStringLenGetNodeList) xmlStringLenGetNodeList __attribute((alias("xmlStringLenGetNodeList__internal_alias")));
+#else
+#ifndef xmlStringLenGetNodeList
+extern __typeof (xmlStringLenGetNodeList) xmlStringLenGetNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlStringLenGetNodeList xmlStringLenGetNodeList__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrlen
+extern __typeof (xmlStrlen) xmlStrlen __attribute((alias("xmlStrlen__internal_alias")));
+#else
+#ifndef xmlStrlen
+extern __typeof (xmlStrlen) xmlStrlen__internal_alias __attribute((visibility("hidden")));
+#define xmlStrlen xmlStrlen__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrncasecmp
+extern __typeof (xmlStrncasecmp) xmlStrncasecmp __attribute((alias("xmlStrncasecmp__internal_alias")));
+#else
+#ifndef xmlStrncasecmp
+extern __typeof (xmlStrncasecmp) xmlStrncasecmp__internal_alias __attribute((visibility("hidden")));
+#define xmlStrncasecmp xmlStrncasecmp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrncat
+extern __typeof (xmlStrncat) xmlStrncat __attribute((alias("xmlStrncat__internal_alias")));
+#else
+#ifndef xmlStrncat
+extern __typeof (xmlStrncat) xmlStrncat__internal_alias __attribute((visibility("hidden")));
+#define xmlStrncat xmlStrncat__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrncatNew
+extern __typeof (xmlStrncatNew) xmlStrncatNew __attribute((alias("xmlStrncatNew__internal_alias")));
+#else
+#ifndef xmlStrncatNew
+extern __typeof (xmlStrncatNew) xmlStrncatNew__internal_alias __attribute((visibility("hidden")));
+#define xmlStrncatNew xmlStrncatNew__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrncmp
+extern __typeof (xmlStrncmp) xmlStrncmp __attribute((alias("xmlStrncmp__internal_alias")));
+#else
+#ifndef xmlStrncmp
+extern __typeof (xmlStrncmp) xmlStrncmp__internal_alias __attribute((visibility("hidden")));
+#define xmlStrncmp xmlStrncmp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrndup
+extern __typeof (xmlStrndup) xmlStrndup __attribute((alias("xmlStrndup__internal_alias")));
+#else
+#ifndef xmlStrndup
+extern __typeof (xmlStrndup) xmlStrndup__internal_alias __attribute((visibility("hidden")));
+#define xmlStrndup xmlStrndup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrstr
+extern __typeof (xmlStrstr) xmlStrstr __attribute((alias("xmlStrstr__internal_alias")));
+#else
+#ifndef xmlStrstr
+extern __typeof (xmlStrstr) xmlStrstr__internal_alias __attribute((visibility("hidden")));
+#define xmlStrstr xmlStrstr__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlStrsub
+extern __typeof (xmlStrsub) xmlStrsub __attribute((alias("xmlStrsub__internal_alias")));
+#else
+#ifndef xmlStrsub
+extern __typeof (xmlStrsub) xmlStrsub__internal_alias __attribute((visibility("hidden")));
+#define xmlStrsub xmlStrsub__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlSubstituteEntitiesDefault
+extern __typeof (xmlSubstituteEntitiesDefault) xmlSubstituteEntitiesDefault __attribute((alias("xmlSubstituteEntitiesDefault__internal_alias")));
+#else
+#ifndef xmlSubstituteEntitiesDefault
+extern __typeof (xmlSubstituteEntitiesDefault) xmlSubstituteEntitiesDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlSubstituteEntitiesDefault xmlSubstituteEntitiesDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlSwitchEncoding
+extern __typeof (xmlSwitchEncoding) xmlSwitchEncoding __attribute((alias("xmlSwitchEncoding__internal_alias")));
+#else
+#ifndef xmlSwitchEncoding
+extern __typeof (xmlSwitchEncoding) xmlSwitchEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlSwitchEncoding xmlSwitchEncoding__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlSwitchInputEncoding
+extern __typeof (xmlSwitchInputEncoding) xmlSwitchInputEncoding __attribute((alias("xmlSwitchInputEncoding__internal_alias")));
+#else
+#ifndef xmlSwitchInputEncoding
+extern __typeof (xmlSwitchInputEncoding) xmlSwitchInputEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlSwitchInputEncoding xmlSwitchInputEncoding__internal_alias
+#endif
+#endif
+
+#ifdef bottom_parserInternals
+#undef xmlSwitchToEncoding
+extern __typeof (xmlSwitchToEncoding) xmlSwitchToEncoding __attribute((alias("xmlSwitchToEncoding__internal_alias")));
+#else
+#ifndef xmlSwitchToEncoding
+extern __typeof (xmlSwitchToEncoding) xmlSwitchToEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlSwitchToEncoding xmlSwitchToEncoding__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlTextConcat
+extern __typeof (xmlTextConcat) xmlTextConcat __attribute((alias("xmlTextConcat__internal_alias")));
+#else
+#ifndef xmlTextConcat
+extern __typeof (xmlTextConcat) xmlTextConcat__internal_alias __attribute((visibility("hidden")));
+#define xmlTextConcat xmlTextConcat__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlTextMerge
+extern __typeof (xmlTextMerge) xmlTextMerge __attribute((alias("xmlTextMerge__internal_alias")));
+#else
+#ifndef xmlTextMerge
+extern __typeof (xmlTextMerge) xmlTextMerge__internal_alias __attribute((visibility("hidden")));
+#define xmlTextMerge xmlTextMerge__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderAttributeCount
+extern __typeof (xmlTextReaderAttributeCount) xmlTextReaderAttributeCount __attribute((alias("xmlTextReaderAttributeCount__internal_alias")));
+#else
+#ifndef xmlTextReaderAttributeCount
+extern __typeof (xmlTextReaderAttributeCount) xmlTextReaderAttributeCount__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderAttributeCount xmlTextReaderAttributeCount__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderBaseUri
+extern __typeof (xmlTextReaderBaseUri) xmlTextReaderBaseUri __attribute((alias("xmlTextReaderBaseUri__internal_alias")));
+#else
+#ifndef xmlTextReaderBaseUri
+extern __typeof (xmlTextReaderBaseUri) xmlTextReaderBaseUri__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderBaseUri xmlTextReaderBaseUri__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderByteConsumed
+extern __typeof (xmlTextReaderByteConsumed) xmlTextReaderByteConsumed __attribute((alias("xmlTextReaderByteConsumed__internal_alias")));
+#else
+#ifndef xmlTextReaderByteConsumed
+extern __typeof (xmlTextReaderByteConsumed) xmlTextReaderByteConsumed__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderByteConsumed xmlTextReaderByteConsumed__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderClose
+extern __typeof (xmlTextReaderClose) xmlTextReaderClose __attribute((alias("xmlTextReaderClose__internal_alias")));
+#else
+#ifndef xmlTextReaderClose
+extern __typeof (xmlTextReaderClose) xmlTextReaderClose__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderClose xmlTextReaderClose__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstBaseUri
+extern __typeof (xmlTextReaderConstBaseUri) xmlTextReaderConstBaseUri __attribute((alias("xmlTextReaderConstBaseUri__internal_alias")));
+#else
+#ifndef xmlTextReaderConstBaseUri
+extern __typeof (xmlTextReaderConstBaseUri) xmlTextReaderConstBaseUri__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstBaseUri xmlTextReaderConstBaseUri__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstEncoding
+extern __typeof (xmlTextReaderConstEncoding) xmlTextReaderConstEncoding __attribute((alias("xmlTextReaderConstEncoding__internal_alias")));
+#else
+#ifndef xmlTextReaderConstEncoding
+extern __typeof (xmlTextReaderConstEncoding) xmlTextReaderConstEncoding__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstEncoding xmlTextReaderConstEncoding__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstLocalName
+extern __typeof (xmlTextReaderConstLocalName) xmlTextReaderConstLocalName __attribute((alias("xmlTextReaderConstLocalName__internal_alias")));
+#else
+#ifndef xmlTextReaderConstLocalName
+extern __typeof (xmlTextReaderConstLocalName) xmlTextReaderConstLocalName__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstLocalName xmlTextReaderConstLocalName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstName
+extern __typeof (xmlTextReaderConstName) xmlTextReaderConstName __attribute((alias("xmlTextReaderConstName__internal_alias")));
+#else
+#ifndef xmlTextReaderConstName
+extern __typeof (xmlTextReaderConstName) xmlTextReaderConstName__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstName xmlTextReaderConstName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstNamespaceUri
+extern __typeof (xmlTextReaderConstNamespaceUri) xmlTextReaderConstNamespaceUri __attribute((alias("xmlTextReaderConstNamespaceUri__internal_alias")));
+#else
+#ifndef xmlTextReaderConstNamespaceUri
+extern __typeof (xmlTextReaderConstNamespaceUri) xmlTextReaderConstNamespaceUri__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstNamespaceUri xmlTextReaderConstNamespaceUri__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstPrefix
+extern __typeof (xmlTextReaderConstPrefix) xmlTextReaderConstPrefix __attribute((alias("xmlTextReaderConstPrefix__internal_alias")));
+#else
+#ifndef xmlTextReaderConstPrefix
+extern __typeof (xmlTextReaderConstPrefix) xmlTextReaderConstPrefix__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstPrefix xmlTextReaderConstPrefix__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstString
+extern __typeof (xmlTextReaderConstString) xmlTextReaderConstString __attribute((alias("xmlTextReaderConstString__internal_alias")));
+#else
+#ifndef xmlTextReaderConstString
+extern __typeof (xmlTextReaderConstString) xmlTextReaderConstString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstString xmlTextReaderConstString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstValue
+extern __typeof (xmlTextReaderConstValue) xmlTextReaderConstValue __attribute((alias("xmlTextReaderConstValue__internal_alias")));
+#else
+#ifndef xmlTextReaderConstValue
+extern __typeof (xmlTextReaderConstValue) xmlTextReaderConstValue__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstValue xmlTextReaderConstValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstXmlLang
+extern __typeof (xmlTextReaderConstXmlLang) xmlTextReaderConstXmlLang __attribute((alias("xmlTextReaderConstXmlLang__internal_alias")));
+#else
+#ifndef xmlTextReaderConstXmlLang
+extern __typeof (xmlTextReaderConstXmlLang) xmlTextReaderConstXmlLang__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstXmlLang xmlTextReaderConstXmlLang__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderConstXmlVersion
+extern __typeof (xmlTextReaderConstXmlVersion) xmlTextReaderConstXmlVersion __attribute((alias("xmlTextReaderConstXmlVersion__internal_alias")));
+#else
+#ifndef xmlTextReaderConstXmlVersion
+extern __typeof (xmlTextReaderConstXmlVersion) xmlTextReaderConstXmlVersion__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderConstXmlVersion xmlTextReaderConstXmlVersion__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderCurrentDoc
+extern __typeof (xmlTextReaderCurrentDoc) xmlTextReaderCurrentDoc __attribute((alias("xmlTextReaderCurrentDoc__internal_alias")));
+#else
+#ifndef xmlTextReaderCurrentDoc
+extern __typeof (xmlTextReaderCurrentDoc) xmlTextReaderCurrentDoc__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderCurrentDoc xmlTextReaderCurrentDoc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderCurrentNode
+extern __typeof (xmlTextReaderCurrentNode) xmlTextReaderCurrentNode __attribute((alias("xmlTextReaderCurrentNode__internal_alias")));
+#else
+#ifndef xmlTextReaderCurrentNode
+extern __typeof (xmlTextReaderCurrentNode) xmlTextReaderCurrentNode__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderCurrentNode xmlTextReaderCurrentNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderDepth
+extern __typeof (xmlTextReaderDepth) xmlTextReaderDepth __attribute((alias("xmlTextReaderDepth__internal_alias")));
+#else
+#ifndef xmlTextReaderDepth
+extern __typeof (xmlTextReaderDepth) xmlTextReaderDepth__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderDepth xmlTextReaderDepth__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderExpand
+extern __typeof (xmlTextReaderExpand) xmlTextReaderExpand __attribute((alias("xmlTextReaderExpand__internal_alias")));
+#else
+#ifndef xmlTextReaderExpand
+extern __typeof (xmlTextReaderExpand) xmlTextReaderExpand__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderExpand xmlTextReaderExpand__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetAttribute
+extern __typeof (xmlTextReaderGetAttribute) xmlTextReaderGetAttribute __attribute((alias("xmlTextReaderGetAttribute__internal_alias")));
+#else
+#ifndef xmlTextReaderGetAttribute
+extern __typeof (xmlTextReaderGetAttribute) xmlTextReaderGetAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetAttribute xmlTextReaderGetAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetAttributeNo
+extern __typeof (xmlTextReaderGetAttributeNo) xmlTextReaderGetAttributeNo __attribute((alias("xmlTextReaderGetAttributeNo__internal_alias")));
+#else
+#ifndef xmlTextReaderGetAttributeNo
+extern __typeof (xmlTextReaderGetAttributeNo) xmlTextReaderGetAttributeNo__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetAttributeNo xmlTextReaderGetAttributeNo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetAttributeNs
+extern __typeof (xmlTextReaderGetAttributeNs) xmlTextReaderGetAttributeNs __attribute((alias("xmlTextReaderGetAttributeNs__internal_alias")));
+#else
+#ifndef xmlTextReaderGetAttributeNs
+extern __typeof (xmlTextReaderGetAttributeNs) xmlTextReaderGetAttributeNs__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetAttributeNs xmlTextReaderGetAttributeNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetErrorHandler
+extern __typeof (xmlTextReaderGetErrorHandler) xmlTextReaderGetErrorHandler __attribute((alias("xmlTextReaderGetErrorHandler__internal_alias")));
+#else
+#ifndef xmlTextReaderGetErrorHandler
+extern __typeof (xmlTextReaderGetErrorHandler) xmlTextReaderGetErrorHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetErrorHandler xmlTextReaderGetErrorHandler__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetParserColumnNumber
+extern __typeof (xmlTextReaderGetParserColumnNumber) xmlTextReaderGetParserColumnNumber __attribute((alias("xmlTextReaderGetParserColumnNumber__internal_alias")));
+#else
+#ifndef xmlTextReaderGetParserColumnNumber
+extern __typeof (xmlTextReaderGetParserColumnNumber) xmlTextReaderGetParserColumnNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetParserColumnNumber xmlTextReaderGetParserColumnNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetParserLineNumber
+extern __typeof (xmlTextReaderGetParserLineNumber) xmlTextReaderGetParserLineNumber __attribute((alias("xmlTextReaderGetParserLineNumber__internal_alias")));
+#else
+#ifndef xmlTextReaderGetParserLineNumber
+extern __typeof (xmlTextReaderGetParserLineNumber) xmlTextReaderGetParserLineNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetParserLineNumber xmlTextReaderGetParserLineNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetParserProp
+extern __typeof (xmlTextReaderGetParserProp) xmlTextReaderGetParserProp __attribute((alias("xmlTextReaderGetParserProp__internal_alias")));
+#else
+#ifndef xmlTextReaderGetParserProp
+extern __typeof (xmlTextReaderGetParserProp) xmlTextReaderGetParserProp__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetParserProp xmlTextReaderGetParserProp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderGetRemainder
+extern __typeof (xmlTextReaderGetRemainder) xmlTextReaderGetRemainder __attribute((alias("xmlTextReaderGetRemainder__internal_alias")));
+#else
+#ifndef xmlTextReaderGetRemainder
+extern __typeof (xmlTextReaderGetRemainder) xmlTextReaderGetRemainder__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderGetRemainder xmlTextReaderGetRemainder__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderHasAttributes
+extern __typeof (xmlTextReaderHasAttributes) xmlTextReaderHasAttributes __attribute((alias("xmlTextReaderHasAttributes__internal_alias")));
+#else
+#ifndef xmlTextReaderHasAttributes
+extern __typeof (xmlTextReaderHasAttributes) xmlTextReaderHasAttributes__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderHasAttributes xmlTextReaderHasAttributes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderHasValue
+extern __typeof (xmlTextReaderHasValue) xmlTextReaderHasValue __attribute((alias("xmlTextReaderHasValue__internal_alias")));
+#else
+#ifndef xmlTextReaderHasValue
+extern __typeof (xmlTextReaderHasValue) xmlTextReaderHasValue__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderHasValue xmlTextReaderHasValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderIsDefault
+extern __typeof (xmlTextReaderIsDefault) xmlTextReaderIsDefault __attribute((alias("xmlTextReaderIsDefault__internal_alias")));
+#else
+#ifndef xmlTextReaderIsDefault
+extern __typeof (xmlTextReaderIsDefault) xmlTextReaderIsDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderIsDefault xmlTextReaderIsDefault__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderIsEmptyElement
+extern __typeof (xmlTextReaderIsEmptyElement) xmlTextReaderIsEmptyElement __attribute((alias("xmlTextReaderIsEmptyElement__internal_alias")));
+#else
+#ifndef xmlTextReaderIsEmptyElement
+extern __typeof (xmlTextReaderIsEmptyElement) xmlTextReaderIsEmptyElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderIsEmptyElement xmlTextReaderIsEmptyElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderIsNamespaceDecl
+extern __typeof (xmlTextReaderIsNamespaceDecl) xmlTextReaderIsNamespaceDecl __attribute((alias("xmlTextReaderIsNamespaceDecl__internal_alias")));
+#else
+#ifndef xmlTextReaderIsNamespaceDecl
+extern __typeof (xmlTextReaderIsNamespaceDecl) xmlTextReaderIsNamespaceDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderIsNamespaceDecl xmlTextReaderIsNamespaceDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderIsValid
+extern __typeof (xmlTextReaderIsValid) xmlTextReaderIsValid __attribute((alias("xmlTextReaderIsValid__internal_alias")));
+#else
+#ifndef xmlTextReaderIsValid
+extern __typeof (xmlTextReaderIsValid) xmlTextReaderIsValid__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderIsValid xmlTextReaderIsValid__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderLocalName
+extern __typeof (xmlTextReaderLocalName) xmlTextReaderLocalName __attribute((alias("xmlTextReaderLocalName__internal_alias")));
+#else
+#ifndef xmlTextReaderLocalName
+extern __typeof (xmlTextReaderLocalName) xmlTextReaderLocalName__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderLocalName xmlTextReaderLocalName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderLocatorBaseURI
+extern __typeof (xmlTextReaderLocatorBaseURI) xmlTextReaderLocatorBaseURI __attribute((alias("xmlTextReaderLocatorBaseURI__internal_alias")));
+#else
+#ifndef xmlTextReaderLocatorBaseURI
+extern __typeof (xmlTextReaderLocatorBaseURI) xmlTextReaderLocatorBaseURI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderLocatorBaseURI xmlTextReaderLocatorBaseURI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderLocatorLineNumber
+extern __typeof (xmlTextReaderLocatorLineNumber) xmlTextReaderLocatorLineNumber __attribute((alias("xmlTextReaderLocatorLineNumber__internal_alias")));
+#else
+#ifndef xmlTextReaderLocatorLineNumber
+extern __typeof (xmlTextReaderLocatorLineNumber) xmlTextReaderLocatorLineNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderLocatorLineNumber xmlTextReaderLocatorLineNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderLookupNamespace
+extern __typeof (xmlTextReaderLookupNamespace) xmlTextReaderLookupNamespace __attribute((alias("xmlTextReaderLookupNamespace__internal_alias")));
+#else
+#ifndef xmlTextReaderLookupNamespace
+extern __typeof (xmlTextReaderLookupNamespace) xmlTextReaderLookupNamespace__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderLookupNamespace xmlTextReaderLookupNamespace__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToAttribute
+extern __typeof (xmlTextReaderMoveToAttribute) xmlTextReaderMoveToAttribute __attribute((alias("xmlTextReaderMoveToAttribute__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToAttribute
+extern __typeof (xmlTextReaderMoveToAttribute) xmlTextReaderMoveToAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToAttribute xmlTextReaderMoveToAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToAttributeNo
+extern __typeof (xmlTextReaderMoveToAttributeNo) xmlTextReaderMoveToAttributeNo __attribute((alias("xmlTextReaderMoveToAttributeNo__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToAttributeNo
+extern __typeof (xmlTextReaderMoveToAttributeNo) xmlTextReaderMoveToAttributeNo__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToAttributeNo xmlTextReaderMoveToAttributeNo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToAttributeNs
+extern __typeof (xmlTextReaderMoveToAttributeNs) xmlTextReaderMoveToAttributeNs __attribute((alias("xmlTextReaderMoveToAttributeNs__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToAttributeNs
+extern __typeof (xmlTextReaderMoveToAttributeNs) xmlTextReaderMoveToAttributeNs__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToAttributeNs xmlTextReaderMoveToAttributeNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToElement
+extern __typeof (xmlTextReaderMoveToElement) xmlTextReaderMoveToElement __attribute((alias("xmlTextReaderMoveToElement__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToElement
+extern __typeof (xmlTextReaderMoveToElement) xmlTextReaderMoveToElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToElement xmlTextReaderMoveToElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToFirstAttribute
+extern __typeof (xmlTextReaderMoveToFirstAttribute) xmlTextReaderMoveToFirstAttribute __attribute((alias("xmlTextReaderMoveToFirstAttribute__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToFirstAttribute
+extern __typeof (xmlTextReaderMoveToFirstAttribute) xmlTextReaderMoveToFirstAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToFirstAttribute xmlTextReaderMoveToFirstAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderMoveToNextAttribute
+extern __typeof (xmlTextReaderMoveToNextAttribute) xmlTextReaderMoveToNextAttribute __attribute((alias("xmlTextReaderMoveToNextAttribute__internal_alias")));
+#else
+#ifndef xmlTextReaderMoveToNextAttribute
+extern __typeof (xmlTextReaderMoveToNextAttribute) xmlTextReaderMoveToNextAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderMoveToNextAttribute xmlTextReaderMoveToNextAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderName
+extern __typeof (xmlTextReaderName) xmlTextReaderName __attribute((alias("xmlTextReaderName__internal_alias")));
+#else
+#ifndef xmlTextReaderName
+extern __typeof (xmlTextReaderName) xmlTextReaderName__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderName xmlTextReaderName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderNamespaceUri
+extern __typeof (xmlTextReaderNamespaceUri) xmlTextReaderNamespaceUri __attribute((alias("xmlTextReaderNamespaceUri__internal_alias")));
+#else
+#ifndef xmlTextReaderNamespaceUri
+extern __typeof (xmlTextReaderNamespaceUri) xmlTextReaderNamespaceUri__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderNamespaceUri xmlTextReaderNamespaceUri__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderNext
+extern __typeof (xmlTextReaderNext) xmlTextReaderNext __attribute((alias("xmlTextReaderNext__internal_alias")));
+#else
+#ifndef xmlTextReaderNext
+extern __typeof (xmlTextReaderNext) xmlTextReaderNext__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderNext xmlTextReaderNext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderNextSibling
+extern __typeof (xmlTextReaderNextSibling) xmlTextReaderNextSibling __attribute((alias("xmlTextReaderNextSibling__internal_alias")));
+#else
+#ifndef xmlTextReaderNextSibling
+extern __typeof (xmlTextReaderNextSibling) xmlTextReaderNextSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderNextSibling xmlTextReaderNextSibling__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderNodeType
+extern __typeof (xmlTextReaderNodeType) xmlTextReaderNodeType __attribute((alias("xmlTextReaderNodeType__internal_alias")));
+#else
+#ifndef xmlTextReaderNodeType
+extern __typeof (xmlTextReaderNodeType) xmlTextReaderNodeType__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderNodeType xmlTextReaderNodeType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderNormalization
+extern __typeof (xmlTextReaderNormalization) xmlTextReaderNormalization __attribute((alias("xmlTextReaderNormalization__internal_alias")));
+#else
+#ifndef xmlTextReaderNormalization
+extern __typeof (xmlTextReaderNormalization) xmlTextReaderNormalization__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderNormalization xmlTextReaderNormalization__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderPrefix
+extern __typeof (xmlTextReaderPrefix) xmlTextReaderPrefix __attribute((alias("xmlTextReaderPrefix__internal_alias")));
+#else
+#ifndef xmlTextReaderPrefix
+extern __typeof (xmlTextReaderPrefix) xmlTextReaderPrefix__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderPrefix xmlTextReaderPrefix__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderPreserve
+extern __typeof (xmlTextReaderPreserve) xmlTextReaderPreserve __attribute((alias("xmlTextReaderPreserve__internal_alias")));
+#else
+#ifndef xmlTextReaderPreserve
+extern __typeof (xmlTextReaderPreserve) xmlTextReaderPreserve__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderPreserve xmlTextReaderPreserve__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderPreservePattern
+extern __typeof (xmlTextReaderPreservePattern) xmlTextReaderPreservePattern __attribute((alias("xmlTextReaderPreservePattern__internal_alias")));
+#else
+#ifndef xmlTextReaderPreservePattern
+extern __typeof (xmlTextReaderPreservePattern) xmlTextReaderPreservePattern__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderPreservePattern xmlTextReaderPreservePattern__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderQuoteChar
+extern __typeof (xmlTextReaderQuoteChar) xmlTextReaderQuoteChar __attribute((alias("xmlTextReaderQuoteChar__internal_alias")));
+#else
+#ifndef xmlTextReaderQuoteChar
+extern __typeof (xmlTextReaderQuoteChar) xmlTextReaderQuoteChar__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderQuoteChar xmlTextReaderQuoteChar__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderRead
+extern __typeof (xmlTextReaderRead) xmlTextReaderRead __attribute((alias("xmlTextReaderRead__internal_alias")));
+#else
+#ifndef xmlTextReaderRead
+extern __typeof (xmlTextReaderRead) xmlTextReaderRead__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderRead xmlTextReaderRead__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderReadAttributeValue
+extern __typeof (xmlTextReaderReadAttributeValue) xmlTextReaderReadAttributeValue __attribute((alias("xmlTextReaderReadAttributeValue__internal_alias")));
+#else
+#ifndef xmlTextReaderReadAttributeValue
+extern __typeof (xmlTextReaderReadAttributeValue) xmlTextReaderReadAttributeValue__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderReadAttributeValue xmlTextReaderReadAttributeValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderReadInnerXml
+extern __typeof (xmlTextReaderReadInnerXml) xmlTextReaderReadInnerXml __attribute((alias("xmlTextReaderReadInnerXml__internal_alias")));
+#else
+#ifndef xmlTextReaderReadInnerXml
+extern __typeof (xmlTextReaderReadInnerXml) xmlTextReaderReadInnerXml__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderReadInnerXml xmlTextReaderReadInnerXml__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderReadOuterXml
+extern __typeof (xmlTextReaderReadOuterXml) xmlTextReaderReadOuterXml __attribute((alias("xmlTextReaderReadOuterXml__internal_alias")));
+#else
+#ifndef xmlTextReaderReadOuterXml
+extern __typeof (xmlTextReaderReadOuterXml) xmlTextReaderReadOuterXml__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderReadOuterXml xmlTextReaderReadOuterXml__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderReadState
+extern __typeof (xmlTextReaderReadState) xmlTextReaderReadState __attribute((alias("xmlTextReaderReadState__internal_alias")));
+#else
+#ifndef xmlTextReaderReadState
+extern __typeof (xmlTextReaderReadState) xmlTextReaderReadState__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderReadState xmlTextReaderReadState__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderReadString
+extern __typeof (xmlTextReaderReadString) xmlTextReaderReadString __attribute((alias("xmlTextReaderReadString__internal_alias")));
+#else
+#ifndef xmlTextReaderReadString
+extern __typeof (xmlTextReaderReadString) xmlTextReaderReadString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderReadString xmlTextReaderReadString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderRelaxNGSetSchema
+extern __typeof (xmlTextReaderRelaxNGSetSchema) xmlTextReaderRelaxNGSetSchema __attribute((alias("xmlTextReaderRelaxNGSetSchema__internal_alias")));
+#else
+#ifndef xmlTextReaderRelaxNGSetSchema
+extern __typeof (xmlTextReaderRelaxNGSetSchema) xmlTextReaderRelaxNGSetSchema__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderRelaxNGSetSchema xmlTextReaderRelaxNGSetSchema__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderRelaxNGValidate
+extern __typeof (xmlTextReaderRelaxNGValidate) xmlTextReaderRelaxNGValidate __attribute((alias("xmlTextReaderRelaxNGValidate__internal_alias")));
+#else
+#ifndef xmlTextReaderRelaxNGValidate
+extern __typeof (xmlTextReaderRelaxNGValidate) xmlTextReaderRelaxNGValidate__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderRelaxNGValidate xmlTextReaderRelaxNGValidate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSchemaValidate
+extern __typeof (xmlTextReaderSchemaValidate) xmlTextReaderSchemaValidate __attribute((alias("xmlTextReaderSchemaValidate__internal_alias")));
+#else
+#ifndef xmlTextReaderSchemaValidate
+extern __typeof (xmlTextReaderSchemaValidate) xmlTextReaderSchemaValidate__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSchemaValidate xmlTextReaderSchemaValidate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSchemaValidateCtxt
+extern __typeof (xmlTextReaderSchemaValidateCtxt) xmlTextReaderSchemaValidateCtxt __attribute((alias("xmlTextReaderSchemaValidateCtxt__internal_alias")));
+#else
+#ifndef xmlTextReaderSchemaValidateCtxt
+extern __typeof (xmlTextReaderSchemaValidateCtxt) xmlTextReaderSchemaValidateCtxt__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSchemaValidateCtxt xmlTextReaderSchemaValidateCtxt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSetErrorHandler
+extern __typeof (xmlTextReaderSetErrorHandler) xmlTextReaderSetErrorHandler __attribute((alias("xmlTextReaderSetErrorHandler__internal_alias")));
+#else
+#ifndef xmlTextReaderSetErrorHandler
+extern __typeof (xmlTextReaderSetErrorHandler) xmlTextReaderSetErrorHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSetErrorHandler xmlTextReaderSetErrorHandler__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSetParserProp
+extern __typeof (xmlTextReaderSetParserProp) xmlTextReaderSetParserProp __attribute((alias("xmlTextReaderSetParserProp__internal_alias")));
+#else
+#ifndef xmlTextReaderSetParserProp
+extern __typeof (xmlTextReaderSetParserProp) xmlTextReaderSetParserProp__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSetParserProp xmlTextReaderSetParserProp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSetSchema
+extern __typeof (xmlTextReaderSetSchema) xmlTextReaderSetSchema __attribute((alias("xmlTextReaderSetSchema__internal_alias")));
+#else
+#ifndef xmlTextReaderSetSchema
+extern __typeof (xmlTextReaderSetSchema) xmlTextReaderSetSchema__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSetSchema xmlTextReaderSetSchema__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSetStructuredErrorHandler
+extern __typeof (xmlTextReaderSetStructuredErrorHandler) xmlTextReaderSetStructuredErrorHandler __attribute((alias("xmlTextReaderSetStructuredErrorHandler__internal_alias")));
+#else
+#ifndef xmlTextReaderSetStructuredErrorHandler
+extern __typeof (xmlTextReaderSetStructuredErrorHandler) xmlTextReaderSetStructuredErrorHandler__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSetStructuredErrorHandler xmlTextReaderSetStructuredErrorHandler__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderSetup
+extern __typeof (xmlTextReaderSetup) xmlTextReaderSetup __attribute((alias("xmlTextReaderSetup__internal_alias")));
+#else
+#ifndef xmlTextReaderSetup
+extern __typeof (xmlTextReaderSetup) xmlTextReaderSetup__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderSetup xmlTextReaderSetup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderStandalone
+extern __typeof (xmlTextReaderStandalone) xmlTextReaderStandalone __attribute((alias("xmlTextReaderStandalone__internal_alias")));
+#else
+#ifndef xmlTextReaderStandalone
+extern __typeof (xmlTextReaderStandalone) xmlTextReaderStandalone__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderStandalone xmlTextReaderStandalone__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderValue
+extern __typeof (xmlTextReaderValue) xmlTextReaderValue __attribute((alias("xmlTextReaderValue__internal_alias")));
+#else
+#ifndef xmlTextReaderValue
+extern __typeof (xmlTextReaderValue) xmlTextReaderValue__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderValue xmlTextReaderValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_READER_ENABLED)
+#ifdef bottom_xmlreader
+#undef xmlTextReaderXmlLang
+extern __typeof (xmlTextReaderXmlLang) xmlTextReaderXmlLang __attribute((alias("xmlTextReaderXmlLang__internal_alias")));
+#else
+#ifndef xmlTextReaderXmlLang
+extern __typeof (xmlTextReaderXmlLang) xmlTextReaderXmlLang__internal_alias __attribute((visibility("hidden")));
+#define xmlTextReaderXmlLang xmlTextReaderXmlLang__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndAttribute
+extern __typeof (xmlTextWriterEndAttribute) xmlTextWriterEndAttribute __attribute((alias("xmlTextWriterEndAttribute__internal_alias")));
+#else
+#ifndef xmlTextWriterEndAttribute
+extern __typeof (xmlTextWriterEndAttribute) xmlTextWriterEndAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndAttribute xmlTextWriterEndAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndCDATA
+extern __typeof (xmlTextWriterEndCDATA) xmlTextWriterEndCDATA __attribute((alias("xmlTextWriterEndCDATA__internal_alias")));
+#else
+#ifndef xmlTextWriterEndCDATA
+extern __typeof (xmlTextWriterEndCDATA) xmlTextWriterEndCDATA__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndCDATA xmlTextWriterEndCDATA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndComment
+extern __typeof (xmlTextWriterEndComment) xmlTextWriterEndComment __attribute((alias("xmlTextWriterEndComment__internal_alias")));
+#else
+#ifndef xmlTextWriterEndComment
+extern __typeof (xmlTextWriterEndComment) xmlTextWriterEndComment__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndComment xmlTextWriterEndComment__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndDTD
+extern __typeof (xmlTextWriterEndDTD) xmlTextWriterEndDTD __attribute((alias("xmlTextWriterEndDTD__internal_alias")));
+#else
+#ifndef xmlTextWriterEndDTD
+extern __typeof (xmlTextWriterEndDTD) xmlTextWriterEndDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndDTD xmlTextWriterEndDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndDTDAttlist
+extern __typeof (xmlTextWriterEndDTDAttlist) xmlTextWriterEndDTDAttlist __attribute((alias("xmlTextWriterEndDTDAttlist__internal_alias")));
+#else
+#ifndef xmlTextWriterEndDTDAttlist
+extern __typeof (xmlTextWriterEndDTDAttlist) xmlTextWriterEndDTDAttlist__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndDTDAttlist xmlTextWriterEndDTDAttlist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndDTDElement
+extern __typeof (xmlTextWriterEndDTDElement) xmlTextWriterEndDTDElement __attribute((alias("xmlTextWriterEndDTDElement__internal_alias")));
+#else
+#ifndef xmlTextWriterEndDTDElement
+extern __typeof (xmlTextWriterEndDTDElement) xmlTextWriterEndDTDElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndDTDElement xmlTextWriterEndDTDElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndDTDEntity
+extern __typeof (xmlTextWriterEndDTDEntity) xmlTextWriterEndDTDEntity __attribute((alias("xmlTextWriterEndDTDEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterEndDTDEntity
+extern __typeof (xmlTextWriterEndDTDEntity) xmlTextWriterEndDTDEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndDTDEntity xmlTextWriterEndDTDEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndDocument
+extern __typeof (xmlTextWriterEndDocument) xmlTextWriterEndDocument __attribute((alias("xmlTextWriterEndDocument__internal_alias")));
+#else
+#ifndef xmlTextWriterEndDocument
+extern __typeof (xmlTextWriterEndDocument) xmlTextWriterEndDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndDocument xmlTextWriterEndDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndElement
+extern __typeof (xmlTextWriterEndElement) xmlTextWriterEndElement __attribute((alias("xmlTextWriterEndElement__internal_alias")));
+#else
+#ifndef xmlTextWriterEndElement
+extern __typeof (xmlTextWriterEndElement) xmlTextWriterEndElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndElement xmlTextWriterEndElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterEndPI
+extern __typeof (xmlTextWriterEndPI) xmlTextWriterEndPI __attribute((alias("xmlTextWriterEndPI__internal_alias")));
+#else
+#ifndef xmlTextWriterEndPI
+extern __typeof (xmlTextWriterEndPI) xmlTextWriterEndPI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterEndPI xmlTextWriterEndPI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterFlush
+extern __typeof (xmlTextWriterFlush) xmlTextWriterFlush __attribute((alias("xmlTextWriterFlush__internal_alias")));
+#else
+#ifndef xmlTextWriterFlush
+extern __typeof (xmlTextWriterFlush) xmlTextWriterFlush__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterFlush xmlTextWriterFlush__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterFullEndElement
+extern __typeof (xmlTextWriterFullEndElement) xmlTextWriterFullEndElement __attribute((alias("xmlTextWriterFullEndElement__internal_alias")));
+#else
+#ifndef xmlTextWriterFullEndElement
+extern __typeof (xmlTextWriterFullEndElement) xmlTextWriterFullEndElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterFullEndElement xmlTextWriterFullEndElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterSetIndent
+extern __typeof (xmlTextWriterSetIndent) xmlTextWriterSetIndent __attribute((alias("xmlTextWriterSetIndent__internal_alias")));
+#else
+#ifndef xmlTextWriterSetIndent
+extern __typeof (xmlTextWriterSetIndent) xmlTextWriterSetIndent__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterSetIndent xmlTextWriterSetIndent__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterSetIndentString
+extern __typeof (xmlTextWriterSetIndentString) xmlTextWriterSetIndentString __attribute((alias("xmlTextWriterSetIndentString__internal_alias")));
+#else
+#ifndef xmlTextWriterSetIndentString
+extern __typeof (xmlTextWriterSetIndentString) xmlTextWriterSetIndentString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterSetIndentString xmlTextWriterSetIndentString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartAttribute
+extern __typeof (xmlTextWriterStartAttribute) xmlTextWriterStartAttribute __attribute((alias("xmlTextWriterStartAttribute__internal_alias")));
+#else
+#ifndef xmlTextWriterStartAttribute
+extern __typeof (xmlTextWriterStartAttribute) xmlTextWriterStartAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartAttribute xmlTextWriterStartAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartAttributeNS
+extern __typeof (xmlTextWriterStartAttributeNS) xmlTextWriterStartAttributeNS __attribute((alias("xmlTextWriterStartAttributeNS__internal_alias")));
+#else
+#ifndef xmlTextWriterStartAttributeNS
+extern __typeof (xmlTextWriterStartAttributeNS) xmlTextWriterStartAttributeNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartAttributeNS xmlTextWriterStartAttributeNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartCDATA
+extern __typeof (xmlTextWriterStartCDATA) xmlTextWriterStartCDATA __attribute((alias("xmlTextWriterStartCDATA__internal_alias")));
+#else
+#ifndef xmlTextWriterStartCDATA
+extern __typeof (xmlTextWriterStartCDATA) xmlTextWriterStartCDATA__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartCDATA xmlTextWriterStartCDATA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartComment
+extern __typeof (xmlTextWriterStartComment) xmlTextWriterStartComment __attribute((alias("xmlTextWriterStartComment__internal_alias")));
+#else
+#ifndef xmlTextWriterStartComment
+extern __typeof (xmlTextWriterStartComment) xmlTextWriterStartComment__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartComment xmlTextWriterStartComment__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartDTD
+extern __typeof (xmlTextWriterStartDTD) xmlTextWriterStartDTD __attribute((alias("xmlTextWriterStartDTD__internal_alias")));
+#else
+#ifndef xmlTextWriterStartDTD
+extern __typeof (xmlTextWriterStartDTD) xmlTextWriterStartDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartDTD xmlTextWriterStartDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartDTDAttlist
+extern __typeof (xmlTextWriterStartDTDAttlist) xmlTextWriterStartDTDAttlist __attribute((alias("xmlTextWriterStartDTDAttlist__internal_alias")));
+#else
+#ifndef xmlTextWriterStartDTDAttlist
+extern __typeof (xmlTextWriterStartDTDAttlist) xmlTextWriterStartDTDAttlist__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartDTDAttlist xmlTextWriterStartDTDAttlist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartDTDElement
+extern __typeof (xmlTextWriterStartDTDElement) xmlTextWriterStartDTDElement __attribute((alias("xmlTextWriterStartDTDElement__internal_alias")));
+#else
+#ifndef xmlTextWriterStartDTDElement
+extern __typeof (xmlTextWriterStartDTDElement) xmlTextWriterStartDTDElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartDTDElement xmlTextWriterStartDTDElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartDTDEntity
+extern __typeof (xmlTextWriterStartDTDEntity) xmlTextWriterStartDTDEntity __attribute((alias("xmlTextWriterStartDTDEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterStartDTDEntity
+extern __typeof (xmlTextWriterStartDTDEntity) xmlTextWriterStartDTDEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartDTDEntity xmlTextWriterStartDTDEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartDocument
+extern __typeof (xmlTextWriterStartDocument) xmlTextWriterStartDocument __attribute((alias("xmlTextWriterStartDocument__internal_alias")));
+#else
+#ifndef xmlTextWriterStartDocument
+extern __typeof (xmlTextWriterStartDocument) xmlTextWriterStartDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartDocument xmlTextWriterStartDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartElement
+extern __typeof (xmlTextWriterStartElement) xmlTextWriterStartElement __attribute((alias("xmlTextWriterStartElement__internal_alias")));
+#else
+#ifndef xmlTextWriterStartElement
+extern __typeof (xmlTextWriterStartElement) xmlTextWriterStartElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartElement xmlTextWriterStartElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartElementNS
+extern __typeof (xmlTextWriterStartElementNS) xmlTextWriterStartElementNS __attribute((alias("xmlTextWriterStartElementNS__internal_alias")));
+#else
+#ifndef xmlTextWriterStartElementNS
+extern __typeof (xmlTextWriterStartElementNS) xmlTextWriterStartElementNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartElementNS xmlTextWriterStartElementNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterStartPI
+extern __typeof (xmlTextWriterStartPI) xmlTextWriterStartPI __attribute((alias("xmlTextWriterStartPI__internal_alias")));
+#else
+#ifndef xmlTextWriterStartPI
+extern __typeof (xmlTextWriterStartPI) xmlTextWriterStartPI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterStartPI xmlTextWriterStartPI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteAttribute
+extern __typeof (xmlTextWriterWriteAttribute) xmlTextWriterWriteAttribute __attribute((alias("xmlTextWriterWriteAttribute__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteAttribute
+extern __typeof (xmlTextWriterWriteAttribute) xmlTextWriterWriteAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteAttribute xmlTextWriterWriteAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteAttributeNS
+extern __typeof (xmlTextWriterWriteAttributeNS) xmlTextWriterWriteAttributeNS __attribute((alias("xmlTextWriterWriteAttributeNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteAttributeNS
+extern __typeof (xmlTextWriterWriteAttributeNS) xmlTextWriterWriteAttributeNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteAttributeNS xmlTextWriterWriteAttributeNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteBase64
+extern __typeof (xmlTextWriterWriteBase64) xmlTextWriterWriteBase64 __attribute((alias("xmlTextWriterWriteBase64__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteBase64
+extern __typeof (xmlTextWriterWriteBase64) xmlTextWriterWriteBase64__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteBase64 xmlTextWriterWriteBase64__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteBinHex
+extern __typeof (xmlTextWriterWriteBinHex) xmlTextWriterWriteBinHex __attribute((alias("xmlTextWriterWriteBinHex__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteBinHex
+extern __typeof (xmlTextWriterWriteBinHex) xmlTextWriterWriteBinHex__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteBinHex xmlTextWriterWriteBinHex__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteCDATA
+extern __typeof (xmlTextWriterWriteCDATA) xmlTextWriterWriteCDATA __attribute((alias("xmlTextWriterWriteCDATA__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteCDATA
+extern __typeof (xmlTextWriterWriteCDATA) xmlTextWriterWriteCDATA__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteCDATA xmlTextWriterWriteCDATA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteComment
+extern __typeof (xmlTextWriterWriteComment) xmlTextWriterWriteComment __attribute((alias("xmlTextWriterWriteComment__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteComment
+extern __typeof (xmlTextWriterWriteComment) xmlTextWriterWriteComment__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteComment xmlTextWriterWriteComment__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTD
+extern __typeof (xmlTextWriterWriteDTD) xmlTextWriterWriteDTD __attribute((alias("xmlTextWriterWriteDTD__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTD
+extern __typeof (xmlTextWriterWriteDTD) xmlTextWriterWriteDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTD xmlTextWriterWriteDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDAttlist
+extern __typeof (xmlTextWriterWriteDTDAttlist) xmlTextWriterWriteDTDAttlist __attribute((alias("xmlTextWriterWriteDTDAttlist__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDAttlist
+extern __typeof (xmlTextWriterWriteDTDAttlist) xmlTextWriterWriteDTDAttlist__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDAttlist xmlTextWriterWriteDTDAttlist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDElement
+extern __typeof (xmlTextWriterWriteDTDElement) xmlTextWriterWriteDTDElement __attribute((alias("xmlTextWriterWriteDTDElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDElement
+extern __typeof (xmlTextWriterWriteDTDElement) xmlTextWriterWriteDTDElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDElement xmlTextWriterWriteDTDElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDEntity
+extern __typeof (xmlTextWriterWriteDTDEntity) xmlTextWriterWriteDTDEntity __attribute((alias("xmlTextWriterWriteDTDEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDEntity
+extern __typeof (xmlTextWriterWriteDTDEntity) xmlTextWriterWriteDTDEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDEntity xmlTextWriterWriteDTDEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDExternalEntity
+extern __typeof (xmlTextWriterWriteDTDExternalEntity) xmlTextWriterWriteDTDExternalEntity __attribute((alias("xmlTextWriterWriteDTDExternalEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDExternalEntity
+extern __typeof (xmlTextWriterWriteDTDExternalEntity) xmlTextWriterWriteDTDExternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDExternalEntity xmlTextWriterWriteDTDExternalEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDExternalEntityContents
+extern __typeof (xmlTextWriterWriteDTDExternalEntityContents) xmlTextWriterWriteDTDExternalEntityContents __attribute((alias("xmlTextWriterWriteDTDExternalEntityContents__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDExternalEntityContents
+extern __typeof (xmlTextWriterWriteDTDExternalEntityContents) xmlTextWriterWriteDTDExternalEntityContents__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDExternalEntityContents xmlTextWriterWriteDTDExternalEntityContents__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDInternalEntity
+extern __typeof (xmlTextWriterWriteDTDInternalEntity) xmlTextWriterWriteDTDInternalEntity __attribute((alias("xmlTextWriterWriteDTDInternalEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDInternalEntity
+extern __typeof (xmlTextWriterWriteDTDInternalEntity) xmlTextWriterWriteDTDInternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDInternalEntity xmlTextWriterWriteDTDInternalEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteDTDNotation
+extern __typeof (xmlTextWriterWriteDTDNotation) xmlTextWriterWriteDTDNotation __attribute((alias("xmlTextWriterWriteDTDNotation__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteDTDNotation
+extern __typeof (xmlTextWriterWriteDTDNotation) xmlTextWriterWriteDTDNotation__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteDTDNotation xmlTextWriterWriteDTDNotation__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteElement
+extern __typeof (xmlTextWriterWriteElement) xmlTextWriterWriteElement __attribute((alias("xmlTextWriterWriteElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteElement
+extern __typeof (xmlTextWriterWriteElement) xmlTextWriterWriteElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteElement xmlTextWriterWriteElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteElementNS
+extern __typeof (xmlTextWriterWriteElementNS) xmlTextWriterWriteElementNS __attribute((alias("xmlTextWriterWriteElementNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteElementNS
+extern __typeof (xmlTextWriterWriteElementNS) xmlTextWriterWriteElementNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteElementNS xmlTextWriterWriteElementNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatAttribute
+extern __typeof (xmlTextWriterWriteFormatAttribute) xmlTextWriterWriteFormatAttribute __attribute((alias("xmlTextWriterWriteFormatAttribute__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatAttribute
+extern __typeof (xmlTextWriterWriteFormatAttribute) xmlTextWriterWriteFormatAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatAttribute xmlTextWriterWriteFormatAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatAttributeNS
+extern __typeof (xmlTextWriterWriteFormatAttributeNS) xmlTextWriterWriteFormatAttributeNS __attribute((alias("xmlTextWriterWriteFormatAttributeNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatAttributeNS
+extern __typeof (xmlTextWriterWriteFormatAttributeNS) xmlTextWriterWriteFormatAttributeNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatAttributeNS xmlTextWriterWriteFormatAttributeNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatCDATA
+extern __typeof (xmlTextWriterWriteFormatCDATA) xmlTextWriterWriteFormatCDATA __attribute((alias("xmlTextWriterWriteFormatCDATA__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatCDATA
+extern __typeof (xmlTextWriterWriteFormatCDATA) xmlTextWriterWriteFormatCDATA__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatCDATA xmlTextWriterWriteFormatCDATA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatComment
+extern __typeof (xmlTextWriterWriteFormatComment) xmlTextWriterWriteFormatComment __attribute((alias("xmlTextWriterWriteFormatComment__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatComment
+extern __typeof (xmlTextWriterWriteFormatComment) xmlTextWriterWriteFormatComment__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatComment xmlTextWriterWriteFormatComment__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatDTD
+extern __typeof (xmlTextWriterWriteFormatDTD) xmlTextWriterWriteFormatDTD __attribute((alias("xmlTextWriterWriteFormatDTD__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatDTD
+extern __typeof (xmlTextWriterWriteFormatDTD) xmlTextWriterWriteFormatDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatDTD xmlTextWriterWriteFormatDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatDTDAttlist
+extern __typeof (xmlTextWriterWriteFormatDTDAttlist) xmlTextWriterWriteFormatDTDAttlist __attribute((alias("xmlTextWriterWriteFormatDTDAttlist__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatDTDAttlist
+extern __typeof (xmlTextWriterWriteFormatDTDAttlist) xmlTextWriterWriteFormatDTDAttlist__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatDTDAttlist xmlTextWriterWriteFormatDTDAttlist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatDTDElement
+extern __typeof (xmlTextWriterWriteFormatDTDElement) xmlTextWriterWriteFormatDTDElement __attribute((alias("xmlTextWriterWriteFormatDTDElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatDTDElement
+extern __typeof (xmlTextWriterWriteFormatDTDElement) xmlTextWriterWriteFormatDTDElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatDTDElement xmlTextWriterWriteFormatDTDElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatDTDInternalEntity
+extern __typeof (xmlTextWriterWriteFormatDTDInternalEntity) xmlTextWriterWriteFormatDTDInternalEntity __attribute((alias("xmlTextWriterWriteFormatDTDInternalEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatDTDInternalEntity
+extern __typeof (xmlTextWriterWriteFormatDTDInternalEntity) xmlTextWriterWriteFormatDTDInternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatDTDInternalEntity xmlTextWriterWriteFormatDTDInternalEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatElement
+extern __typeof (xmlTextWriterWriteFormatElement) xmlTextWriterWriteFormatElement __attribute((alias("xmlTextWriterWriteFormatElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatElement
+extern __typeof (xmlTextWriterWriteFormatElement) xmlTextWriterWriteFormatElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatElement xmlTextWriterWriteFormatElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatElementNS
+extern __typeof (xmlTextWriterWriteFormatElementNS) xmlTextWriterWriteFormatElementNS __attribute((alias("xmlTextWriterWriteFormatElementNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatElementNS
+extern __typeof (xmlTextWriterWriteFormatElementNS) xmlTextWriterWriteFormatElementNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatElementNS xmlTextWriterWriteFormatElementNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatPI
+extern __typeof (xmlTextWriterWriteFormatPI) xmlTextWriterWriteFormatPI __attribute((alias("xmlTextWriterWriteFormatPI__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatPI
+extern __typeof (xmlTextWriterWriteFormatPI) xmlTextWriterWriteFormatPI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatPI xmlTextWriterWriteFormatPI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatRaw
+extern __typeof (xmlTextWriterWriteFormatRaw) xmlTextWriterWriteFormatRaw __attribute((alias("xmlTextWriterWriteFormatRaw__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatRaw
+extern __typeof (xmlTextWriterWriteFormatRaw) xmlTextWriterWriteFormatRaw__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatRaw xmlTextWriterWriteFormatRaw__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteFormatString
+extern __typeof (xmlTextWriterWriteFormatString) xmlTextWriterWriteFormatString __attribute((alias("xmlTextWriterWriteFormatString__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteFormatString
+extern __typeof (xmlTextWriterWriteFormatString) xmlTextWriterWriteFormatString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteFormatString xmlTextWriterWriteFormatString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWritePI
+extern __typeof (xmlTextWriterWritePI) xmlTextWriterWritePI __attribute((alias("xmlTextWriterWritePI__internal_alias")));
+#else
+#ifndef xmlTextWriterWritePI
+extern __typeof (xmlTextWriterWritePI) xmlTextWriterWritePI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWritePI xmlTextWriterWritePI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteRaw
+extern __typeof (xmlTextWriterWriteRaw) xmlTextWriterWriteRaw __attribute((alias("xmlTextWriterWriteRaw__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteRaw
+extern __typeof (xmlTextWriterWriteRaw) xmlTextWriterWriteRaw__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteRaw xmlTextWriterWriteRaw__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteRawLen
+extern __typeof (xmlTextWriterWriteRawLen) xmlTextWriterWriteRawLen __attribute((alias("xmlTextWriterWriteRawLen__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteRawLen
+extern __typeof (xmlTextWriterWriteRawLen) xmlTextWriterWriteRawLen__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteRawLen xmlTextWriterWriteRawLen__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteString
+extern __typeof (xmlTextWriterWriteString) xmlTextWriterWriteString __attribute((alias("xmlTextWriterWriteString__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteString
+extern __typeof (xmlTextWriterWriteString) xmlTextWriterWriteString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteString xmlTextWriterWriteString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatAttribute
+extern __typeof (xmlTextWriterWriteVFormatAttribute) xmlTextWriterWriteVFormatAttribute __attribute((alias("xmlTextWriterWriteVFormatAttribute__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatAttribute
+extern __typeof (xmlTextWriterWriteVFormatAttribute) xmlTextWriterWriteVFormatAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatAttribute xmlTextWriterWriteVFormatAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatAttributeNS
+extern __typeof (xmlTextWriterWriteVFormatAttributeNS) xmlTextWriterWriteVFormatAttributeNS __attribute((alias("xmlTextWriterWriteVFormatAttributeNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatAttributeNS
+extern __typeof (xmlTextWriterWriteVFormatAttributeNS) xmlTextWriterWriteVFormatAttributeNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatAttributeNS xmlTextWriterWriteVFormatAttributeNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatCDATA
+extern __typeof (xmlTextWriterWriteVFormatCDATA) xmlTextWriterWriteVFormatCDATA __attribute((alias("xmlTextWriterWriteVFormatCDATA__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatCDATA
+extern __typeof (xmlTextWriterWriteVFormatCDATA) xmlTextWriterWriteVFormatCDATA__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatCDATA xmlTextWriterWriteVFormatCDATA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatComment
+extern __typeof (xmlTextWriterWriteVFormatComment) xmlTextWriterWriteVFormatComment __attribute((alias("xmlTextWriterWriteVFormatComment__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatComment
+extern __typeof (xmlTextWriterWriteVFormatComment) xmlTextWriterWriteVFormatComment__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatComment xmlTextWriterWriteVFormatComment__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatDTD
+extern __typeof (xmlTextWriterWriteVFormatDTD) xmlTextWriterWriteVFormatDTD __attribute((alias("xmlTextWriterWriteVFormatDTD__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatDTD
+extern __typeof (xmlTextWriterWriteVFormatDTD) xmlTextWriterWriteVFormatDTD__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatDTD xmlTextWriterWriteVFormatDTD__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatDTDAttlist
+extern __typeof (xmlTextWriterWriteVFormatDTDAttlist) xmlTextWriterWriteVFormatDTDAttlist __attribute((alias("xmlTextWriterWriteVFormatDTDAttlist__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatDTDAttlist
+extern __typeof (xmlTextWriterWriteVFormatDTDAttlist) xmlTextWriterWriteVFormatDTDAttlist__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatDTDAttlist xmlTextWriterWriteVFormatDTDAttlist__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatDTDElement
+extern __typeof (xmlTextWriterWriteVFormatDTDElement) xmlTextWriterWriteVFormatDTDElement __attribute((alias("xmlTextWriterWriteVFormatDTDElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatDTDElement
+extern __typeof (xmlTextWriterWriteVFormatDTDElement) xmlTextWriterWriteVFormatDTDElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatDTDElement xmlTextWriterWriteVFormatDTDElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatDTDInternalEntity
+extern __typeof (xmlTextWriterWriteVFormatDTDInternalEntity) xmlTextWriterWriteVFormatDTDInternalEntity __attribute((alias("xmlTextWriterWriteVFormatDTDInternalEntity__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatDTDInternalEntity
+extern __typeof (xmlTextWriterWriteVFormatDTDInternalEntity) xmlTextWriterWriteVFormatDTDInternalEntity__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatDTDInternalEntity xmlTextWriterWriteVFormatDTDInternalEntity__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatElement
+extern __typeof (xmlTextWriterWriteVFormatElement) xmlTextWriterWriteVFormatElement __attribute((alias("xmlTextWriterWriteVFormatElement__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatElement
+extern __typeof (xmlTextWriterWriteVFormatElement) xmlTextWriterWriteVFormatElement__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatElement xmlTextWriterWriteVFormatElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatElementNS
+extern __typeof (xmlTextWriterWriteVFormatElementNS) xmlTextWriterWriteVFormatElementNS __attribute((alias("xmlTextWriterWriteVFormatElementNS__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatElementNS
+extern __typeof (xmlTextWriterWriteVFormatElementNS) xmlTextWriterWriteVFormatElementNS__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatElementNS xmlTextWriterWriteVFormatElementNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatPI
+extern __typeof (xmlTextWriterWriteVFormatPI) xmlTextWriterWriteVFormatPI __attribute((alias("xmlTextWriterWriteVFormatPI__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatPI
+extern __typeof (xmlTextWriterWriteVFormatPI) xmlTextWriterWriteVFormatPI__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatPI xmlTextWriterWriteVFormatPI__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatRaw
+extern __typeof (xmlTextWriterWriteVFormatRaw) xmlTextWriterWriteVFormatRaw __attribute((alias("xmlTextWriterWriteVFormatRaw__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatRaw
+extern __typeof (xmlTextWriterWriteVFormatRaw) xmlTextWriterWriteVFormatRaw__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatRaw xmlTextWriterWriteVFormatRaw__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_WRITER_ENABLED)
+#ifdef bottom_xmlwriter
+#undef xmlTextWriterWriteVFormatString
+extern __typeof (xmlTextWriterWriteVFormatString) xmlTextWriterWriteVFormatString __attribute((alias("xmlTextWriterWriteVFormatString__internal_alias")));
+#else
+#ifndef xmlTextWriterWriteVFormatString
+extern __typeof (xmlTextWriterWriteVFormatString) xmlTextWriterWriteVFormatString__internal_alias __attribute((visibility("hidden")));
+#define xmlTextWriterWriteVFormatString xmlTextWriterWriteVFormatString__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefBufferAllocScheme
+extern __typeof (xmlThrDefBufferAllocScheme) xmlThrDefBufferAllocScheme __attribute((alias("xmlThrDefBufferAllocScheme__internal_alias")));
+#else
+#ifndef xmlThrDefBufferAllocScheme
+extern __typeof (xmlThrDefBufferAllocScheme) xmlThrDefBufferAllocScheme__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefBufferAllocScheme xmlThrDefBufferAllocScheme__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefDefaultBufferSize
+extern __typeof (xmlThrDefDefaultBufferSize) xmlThrDefDefaultBufferSize __attribute((alias("xmlThrDefDefaultBufferSize__internal_alias")));
+#else
+#ifndef xmlThrDefDefaultBufferSize
+extern __typeof (xmlThrDefDefaultBufferSize) xmlThrDefDefaultBufferSize__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefDefaultBufferSize xmlThrDefDefaultBufferSize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefDeregisterNodeDefault
+extern __typeof (xmlThrDefDeregisterNodeDefault) xmlThrDefDeregisterNodeDefault __attribute((alias("xmlThrDefDeregisterNodeDefault__internal_alias")));
+#else
+#ifndef xmlThrDefDeregisterNodeDefault
+extern __typeof (xmlThrDefDeregisterNodeDefault) xmlThrDefDeregisterNodeDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefDeregisterNodeDefault xmlThrDefDeregisterNodeDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefDoValidityCheckingDefaultValue
+extern __typeof (xmlThrDefDoValidityCheckingDefaultValue) xmlThrDefDoValidityCheckingDefaultValue __attribute((alias("xmlThrDefDoValidityCheckingDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefDoValidityCheckingDefaultValue
+extern __typeof (xmlThrDefDoValidityCheckingDefaultValue) xmlThrDefDoValidityCheckingDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefDoValidityCheckingDefaultValue xmlThrDefDoValidityCheckingDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefGetWarningsDefaultValue
+extern __typeof (xmlThrDefGetWarningsDefaultValue) xmlThrDefGetWarningsDefaultValue __attribute((alias("xmlThrDefGetWarningsDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefGetWarningsDefaultValue
+extern __typeof (xmlThrDefGetWarningsDefaultValue) xmlThrDefGetWarningsDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefGetWarningsDefaultValue xmlThrDefGetWarningsDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefIndentTreeOutput
+extern __typeof (xmlThrDefIndentTreeOutput) xmlThrDefIndentTreeOutput __attribute((alias("xmlThrDefIndentTreeOutput__internal_alias")));
+#else
+#ifndef xmlThrDefIndentTreeOutput
+extern __typeof (xmlThrDefIndentTreeOutput) xmlThrDefIndentTreeOutput__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefIndentTreeOutput xmlThrDefIndentTreeOutput__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefKeepBlanksDefaultValue
+extern __typeof (xmlThrDefKeepBlanksDefaultValue) xmlThrDefKeepBlanksDefaultValue __attribute((alias("xmlThrDefKeepBlanksDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefKeepBlanksDefaultValue
+extern __typeof (xmlThrDefKeepBlanksDefaultValue) xmlThrDefKeepBlanksDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefKeepBlanksDefaultValue xmlThrDefKeepBlanksDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefLineNumbersDefaultValue
+extern __typeof (xmlThrDefLineNumbersDefaultValue) xmlThrDefLineNumbersDefaultValue __attribute((alias("xmlThrDefLineNumbersDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefLineNumbersDefaultValue
+extern __typeof (xmlThrDefLineNumbersDefaultValue) xmlThrDefLineNumbersDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefLineNumbersDefaultValue xmlThrDefLineNumbersDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefLoadExtDtdDefaultValue
+extern __typeof (xmlThrDefLoadExtDtdDefaultValue) xmlThrDefLoadExtDtdDefaultValue __attribute((alias("xmlThrDefLoadExtDtdDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefLoadExtDtdDefaultValue
+extern __typeof (xmlThrDefLoadExtDtdDefaultValue) xmlThrDefLoadExtDtdDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefLoadExtDtdDefaultValue xmlThrDefLoadExtDtdDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefOutputBufferCreateFilenameDefault
+extern __typeof (xmlThrDefOutputBufferCreateFilenameDefault) xmlThrDefOutputBufferCreateFilenameDefault __attribute((alias("xmlThrDefOutputBufferCreateFilenameDefault__internal_alias")));
+#else
+#ifndef xmlThrDefOutputBufferCreateFilenameDefault
+extern __typeof (xmlThrDefOutputBufferCreateFilenameDefault) xmlThrDefOutputBufferCreateFilenameDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefOutputBufferCreateFilenameDefault xmlThrDefOutputBufferCreateFilenameDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefParserDebugEntities
+extern __typeof (xmlThrDefParserDebugEntities) xmlThrDefParserDebugEntities __attribute((alias("xmlThrDefParserDebugEntities__internal_alias")));
+#else
+#ifndef xmlThrDefParserDebugEntities
+extern __typeof (xmlThrDefParserDebugEntities) xmlThrDefParserDebugEntities__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefParserDebugEntities xmlThrDefParserDebugEntities__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefParserInputBufferCreateFilenameDefault
+extern __typeof (xmlThrDefParserInputBufferCreateFilenameDefault) xmlThrDefParserInputBufferCreateFilenameDefault __attribute((alias("xmlThrDefParserInputBufferCreateFilenameDefault__internal_alias")));
+#else
+#ifndef xmlThrDefParserInputBufferCreateFilenameDefault
+extern __typeof (xmlThrDefParserInputBufferCreateFilenameDefault) xmlThrDefParserInputBufferCreateFilenameDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefParserInputBufferCreateFilenameDefault xmlThrDefParserInputBufferCreateFilenameDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefPedanticParserDefaultValue
+extern __typeof (xmlThrDefPedanticParserDefaultValue) xmlThrDefPedanticParserDefaultValue __attribute((alias("xmlThrDefPedanticParserDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefPedanticParserDefaultValue
+extern __typeof (xmlThrDefPedanticParserDefaultValue) xmlThrDefPedanticParserDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefPedanticParserDefaultValue xmlThrDefPedanticParserDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefRegisterNodeDefault
+extern __typeof (xmlThrDefRegisterNodeDefault) xmlThrDefRegisterNodeDefault __attribute((alias("xmlThrDefRegisterNodeDefault__internal_alias")));
+#else
+#ifndef xmlThrDefRegisterNodeDefault
+extern __typeof (xmlThrDefRegisterNodeDefault) xmlThrDefRegisterNodeDefault__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefRegisterNodeDefault xmlThrDefRegisterNodeDefault__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefSaveNoEmptyTags
+extern __typeof (xmlThrDefSaveNoEmptyTags) xmlThrDefSaveNoEmptyTags __attribute((alias("xmlThrDefSaveNoEmptyTags__internal_alias")));
+#else
+#ifndef xmlThrDefSaveNoEmptyTags
+extern __typeof (xmlThrDefSaveNoEmptyTags) xmlThrDefSaveNoEmptyTags__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefSaveNoEmptyTags xmlThrDefSaveNoEmptyTags__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefSetGenericErrorFunc
+extern __typeof (xmlThrDefSetGenericErrorFunc) xmlThrDefSetGenericErrorFunc __attribute((alias("xmlThrDefSetGenericErrorFunc__internal_alias")));
+#else
+#ifndef xmlThrDefSetGenericErrorFunc
+extern __typeof (xmlThrDefSetGenericErrorFunc) xmlThrDefSetGenericErrorFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefSetGenericErrorFunc xmlThrDefSetGenericErrorFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefSetStructuredErrorFunc
+extern __typeof (xmlThrDefSetStructuredErrorFunc) xmlThrDefSetStructuredErrorFunc __attribute((alias("xmlThrDefSetStructuredErrorFunc__internal_alias")));
+#else
+#ifndef xmlThrDefSetStructuredErrorFunc
+extern __typeof (xmlThrDefSetStructuredErrorFunc) xmlThrDefSetStructuredErrorFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefSetStructuredErrorFunc xmlThrDefSetStructuredErrorFunc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefSubstituteEntitiesDefaultValue
+extern __typeof (xmlThrDefSubstituteEntitiesDefaultValue) xmlThrDefSubstituteEntitiesDefaultValue __attribute((alias("xmlThrDefSubstituteEntitiesDefaultValue__internal_alias")));
+#else
+#ifndef xmlThrDefSubstituteEntitiesDefaultValue
+extern __typeof (xmlThrDefSubstituteEntitiesDefaultValue) xmlThrDefSubstituteEntitiesDefaultValue__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefSubstituteEntitiesDefaultValue xmlThrDefSubstituteEntitiesDefaultValue__internal_alias
+#endif
+#endif
+
+#ifdef bottom_globals
+#undef xmlThrDefTreeIndentString
+extern __typeof (xmlThrDefTreeIndentString) xmlThrDefTreeIndentString __attribute((alias("xmlThrDefTreeIndentString__internal_alias")));
+#else
+#ifndef xmlThrDefTreeIndentString
+extern __typeof (xmlThrDefTreeIndentString) xmlThrDefTreeIndentString__internal_alias __attribute((visibility("hidden")));
+#define xmlThrDefTreeIndentString xmlThrDefTreeIndentString__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsAegeanNumbers
+extern __typeof (xmlUCSIsAegeanNumbers) xmlUCSIsAegeanNumbers __attribute((alias("xmlUCSIsAegeanNumbers__internal_alias")));
+#else
+#ifndef xmlUCSIsAegeanNumbers
+extern __typeof (xmlUCSIsAegeanNumbers) xmlUCSIsAegeanNumbers__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsAegeanNumbers xmlUCSIsAegeanNumbers__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsAlphabeticPresentationForms
+extern __typeof (xmlUCSIsAlphabeticPresentationForms) xmlUCSIsAlphabeticPresentationForms __attribute((alias("xmlUCSIsAlphabeticPresentationForms__internal_alias")));
+#else
+#ifndef xmlUCSIsAlphabeticPresentationForms
+extern __typeof (xmlUCSIsAlphabeticPresentationForms) xmlUCSIsAlphabeticPresentationForms__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsAlphabeticPresentationForms xmlUCSIsAlphabeticPresentationForms__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsArabic
+extern __typeof (xmlUCSIsArabic) xmlUCSIsArabic __attribute((alias("xmlUCSIsArabic__internal_alias")));
+#else
+#ifndef xmlUCSIsArabic
+extern __typeof (xmlUCSIsArabic) xmlUCSIsArabic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsArabic xmlUCSIsArabic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsArabicPresentationFormsA
+extern __typeof (xmlUCSIsArabicPresentationFormsA) xmlUCSIsArabicPresentationFormsA __attribute((alias("xmlUCSIsArabicPresentationFormsA__internal_alias")));
+#else
+#ifndef xmlUCSIsArabicPresentationFormsA
+extern __typeof (xmlUCSIsArabicPresentationFormsA) xmlUCSIsArabicPresentationFormsA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsArabicPresentationFormsA xmlUCSIsArabicPresentationFormsA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsArabicPresentationFormsB
+extern __typeof (xmlUCSIsArabicPresentationFormsB) xmlUCSIsArabicPresentationFormsB __attribute((alias("xmlUCSIsArabicPresentationFormsB__internal_alias")));
+#else
+#ifndef xmlUCSIsArabicPresentationFormsB
+extern __typeof (xmlUCSIsArabicPresentationFormsB) xmlUCSIsArabicPresentationFormsB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsArabicPresentationFormsB xmlUCSIsArabicPresentationFormsB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsArmenian
+extern __typeof (xmlUCSIsArmenian) xmlUCSIsArmenian __attribute((alias("xmlUCSIsArmenian__internal_alias")));
+#else
+#ifndef xmlUCSIsArmenian
+extern __typeof (xmlUCSIsArmenian) xmlUCSIsArmenian__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsArmenian xmlUCSIsArmenian__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsArrows
+extern __typeof (xmlUCSIsArrows) xmlUCSIsArrows __attribute((alias("xmlUCSIsArrows__internal_alias")));
+#else
+#ifndef xmlUCSIsArrows
+extern __typeof (xmlUCSIsArrows) xmlUCSIsArrows__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsArrows xmlUCSIsArrows__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBasicLatin
+extern __typeof (xmlUCSIsBasicLatin) xmlUCSIsBasicLatin __attribute((alias("xmlUCSIsBasicLatin__internal_alias")));
+#else
+#ifndef xmlUCSIsBasicLatin
+extern __typeof (xmlUCSIsBasicLatin) xmlUCSIsBasicLatin__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBasicLatin xmlUCSIsBasicLatin__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBengali
+extern __typeof (xmlUCSIsBengali) xmlUCSIsBengali __attribute((alias("xmlUCSIsBengali__internal_alias")));
+#else
+#ifndef xmlUCSIsBengali
+extern __typeof (xmlUCSIsBengali) xmlUCSIsBengali__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBengali xmlUCSIsBengali__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBlock
+extern __typeof (xmlUCSIsBlock) xmlUCSIsBlock __attribute((alias("xmlUCSIsBlock__internal_alias")));
+#else
+#ifndef xmlUCSIsBlock
+extern __typeof (xmlUCSIsBlock) xmlUCSIsBlock__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBlock xmlUCSIsBlock__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBlockElements
+extern __typeof (xmlUCSIsBlockElements) xmlUCSIsBlockElements __attribute((alias("xmlUCSIsBlockElements__internal_alias")));
+#else
+#ifndef xmlUCSIsBlockElements
+extern __typeof (xmlUCSIsBlockElements) xmlUCSIsBlockElements__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBlockElements xmlUCSIsBlockElements__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBopomofo
+extern __typeof (xmlUCSIsBopomofo) xmlUCSIsBopomofo __attribute((alias("xmlUCSIsBopomofo__internal_alias")));
+#else
+#ifndef xmlUCSIsBopomofo
+extern __typeof (xmlUCSIsBopomofo) xmlUCSIsBopomofo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBopomofo xmlUCSIsBopomofo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBopomofoExtended
+extern __typeof (xmlUCSIsBopomofoExtended) xmlUCSIsBopomofoExtended __attribute((alias("xmlUCSIsBopomofoExtended__internal_alias")));
+#else
+#ifndef xmlUCSIsBopomofoExtended
+extern __typeof (xmlUCSIsBopomofoExtended) xmlUCSIsBopomofoExtended__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBopomofoExtended xmlUCSIsBopomofoExtended__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBoxDrawing
+extern __typeof (xmlUCSIsBoxDrawing) xmlUCSIsBoxDrawing __attribute((alias("xmlUCSIsBoxDrawing__internal_alias")));
+#else
+#ifndef xmlUCSIsBoxDrawing
+extern __typeof (xmlUCSIsBoxDrawing) xmlUCSIsBoxDrawing__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBoxDrawing xmlUCSIsBoxDrawing__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBraillePatterns
+extern __typeof (xmlUCSIsBraillePatterns) xmlUCSIsBraillePatterns __attribute((alias("xmlUCSIsBraillePatterns__internal_alias")));
+#else
+#ifndef xmlUCSIsBraillePatterns
+extern __typeof (xmlUCSIsBraillePatterns) xmlUCSIsBraillePatterns__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBraillePatterns xmlUCSIsBraillePatterns__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsBuhid
+extern __typeof (xmlUCSIsBuhid) xmlUCSIsBuhid __attribute((alias("xmlUCSIsBuhid__internal_alias")));
+#else
+#ifndef xmlUCSIsBuhid
+extern __typeof (xmlUCSIsBuhid) xmlUCSIsBuhid__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsBuhid xmlUCSIsBuhid__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsByzantineMusicalSymbols
+extern __typeof (xmlUCSIsByzantineMusicalSymbols) xmlUCSIsByzantineMusicalSymbols __attribute((alias("xmlUCSIsByzantineMusicalSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsByzantineMusicalSymbols
+extern __typeof (xmlUCSIsByzantineMusicalSymbols) xmlUCSIsByzantineMusicalSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsByzantineMusicalSymbols xmlUCSIsByzantineMusicalSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKCompatibility
+extern __typeof (xmlUCSIsCJKCompatibility) xmlUCSIsCJKCompatibility __attribute((alias("xmlUCSIsCJKCompatibility__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKCompatibility
+extern __typeof (xmlUCSIsCJKCompatibility) xmlUCSIsCJKCompatibility__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKCompatibility xmlUCSIsCJKCompatibility__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKCompatibilityForms
+extern __typeof (xmlUCSIsCJKCompatibilityForms) xmlUCSIsCJKCompatibilityForms __attribute((alias("xmlUCSIsCJKCompatibilityForms__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKCompatibilityForms
+extern __typeof (xmlUCSIsCJKCompatibilityForms) xmlUCSIsCJKCompatibilityForms__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKCompatibilityForms xmlUCSIsCJKCompatibilityForms__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKCompatibilityIdeographs
+extern __typeof (xmlUCSIsCJKCompatibilityIdeographs) xmlUCSIsCJKCompatibilityIdeographs __attribute((alias("xmlUCSIsCJKCompatibilityIdeographs__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKCompatibilityIdeographs
+extern __typeof (xmlUCSIsCJKCompatibilityIdeographs) xmlUCSIsCJKCompatibilityIdeographs__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKCompatibilityIdeographs xmlUCSIsCJKCompatibilityIdeographs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKCompatibilityIdeographsSupplement
+extern __typeof (xmlUCSIsCJKCompatibilityIdeographsSupplement) xmlUCSIsCJKCompatibilityIdeographsSupplement __attribute((alias("xmlUCSIsCJKCompatibilityIdeographsSupplement__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKCompatibilityIdeographsSupplement
+extern __typeof (xmlUCSIsCJKCompatibilityIdeographsSupplement) xmlUCSIsCJKCompatibilityIdeographsSupplement__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKCompatibilityIdeographsSupplement xmlUCSIsCJKCompatibilityIdeographsSupplement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKRadicalsSupplement
+extern __typeof (xmlUCSIsCJKRadicalsSupplement) xmlUCSIsCJKRadicalsSupplement __attribute((alias("xmlUCSIsCJKRadicalsSupplement__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKRadicalsSupplement
+extern __typeof (xmlUCSIsCJKRadicalsSupplement) xmlUCSIsCJKRadicalsSupplement__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKRadicalsSupplement xmlUCSIsCJKRadicalsSupplement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKSymbolsandPunctuation
+extern __typeof (xmlUCSIsCJKSymbolsandPunctuation) xmlUCSIsCJKSymbolsandPunctuation __attribute((alias("xmlUCSIsCJKSymbolsandPunctuation__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKSymbolsandPunctuation
+extern __typeof (xmlUCSIsCJKSymbolsandPunctuation) xmlUCSIsCJKSymbolsandPunctuation__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKSymbolsandPunctuation xmlUCSIsCJKSymbolsandPunctuation__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKUnifiedIdeographs
+extern __typeof (xmlUCSIsCJKUnifiedIdeographs) xmlUCSIsCJKUnifiedIdeographs __attribute((alias("xmlUCSIsCJKUnifiedIdeographs__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKUnifiedIdeographs
+extern __typeof (xmlUCSIsCJKUnifiedIdeographs) xmlUCSIsCJKUnifiedIdeographs__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKUnifiedIdeographs xmlUCSIsCJKUnifiedIdeographs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKUnifiedIdeographsExtensionA
+extern __typeof (xmlUCSIsCJKUnifiedIdeographsExtensionA) xmlUCSIsCJKUnifiedIdeographsExtensionA __attribute((alias("xmlUCSIsCJKUnifiedIdeographsExtensionA__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKUnifiedIdeographsExtensionA
+extern __typeof (xmlUCSIsCJKUnifiedIdeographsExtensionA) xmlUCSIsCJKUnifiedIdeographsExtensionA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKUnifiedIdeographsExtensionA xmlUCSIsCJKUnifiedIdeographsExtensionA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCJKUnifiedIdeographsExtensionB
+extern __typeof (xmlUCSIsCJKUnifiedIdeographsExtensionB) xmlUCSIsCJKUnifiedIdeographsExtensionB __attribute((alias("xmlUCSIsCJKUnifiedIdeographsExtensionB__internal_alias")));
+#else
+#ifndef xmlUCSIsCJKUnifiedIdeographsExtensionB
+extern __typeof (xmlUCSIsCJKUnifiedIdeographsExtensionB) xmlUCSIsCJKUnifiedIdeographsExtensionB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCJKUnifiedIdeographsExtensionB xmlUCSIsCJKUnifiedIdeographsExtensionB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCat
+extern __typeof (xmlUCSIsCat) xmlUCSIsCat __attribute((alias("xmlUCSIsCat__internal_alias")));
+#else
+#ifndef xmlUCSIsCat
+extern __typeof (xmlUCSIsCat) xmlUCSIsCat__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCat xmlUCSIsCat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatC
+extern __typeof (xmlUCSIsCatC) xmlUCSIsCatC __attribute((alias("xmlUCSIsCatC__internal_alias")));
+#else
+#ifndef xmlUCSIsCatC
+extern __typeof (xmlUCSIsCatC) xmlUCSIsCatC__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatC xmlUCSIsCatC__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatCc
+extern __typeof (xmlUCSIsCatCc) xmlUCSIsCatCc __attribute((alias("xmlUCSIsCatCc__internal_alias")));
+#else
+#ifndef xmlUCSIsCatCc
+extern __typeof (xmlUCSIsCatCc) xmlUCSIsCatCc__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatCc xmlUCSIsCatCc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatCf
+extern __typeof (xmlUCSIsCatCf) xmlUCSIsCatCf __attribute((alias("xmlUCSIsCatCf__internal_alias")));
+#else
+#ifndef xmlUCSIsCatCf
+extern __typeof (xmlUCSIsCatCf) xmlUCSIsCatCf__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatCf xmlUCSIsCatCf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatCo
+extern __typeof (xmlUCSIsCatCo) xmlUCSIsCatCo __attribute((alias("xmlUCSIsCatCo__internal_alias")));
+#else
+#ifndef xmlUCSIsCatCo
+extern __typeof (xmlUCSIsCatCo) xmlUCSIsCatCo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatCo xmlUCSIsCatCo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatCs
+extern __typeof (xmlUCSIsCatCs) xmlUCSIsCatCs __attribute((alias("xmlUCSIsCatCs__internal_alias")));
+#else
+#ifndef xmlUCSIsCatCs
+extern __typeof (xmlUCSIsCatCs) xmlUCSIsCatCs__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatCs xmlUCSIsCatCs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatL
+extern __typeof (xmlUCSIsCatL) xmlUCSIsCatL __attribute((alias("xmlUCSIsCatL__internal_alias")));
+#else
+#ifndef xmlUCSIsCatL
+extern __typeof (xmlUCSIsCatL) xmlUCSIsCatL__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatL xmlUCSIsCatL__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatLl
+extern __typeof (xmlUCSIsCatLl) xmlUCSIsCatLl __attribute((alias("xmlUCSIsCatLl__internal_alias")));
+#else
+#ifndef xmlUCSIsCatLl
+extern __typeof (xmlUCSIsCatLl) xmlUCSIsCatLl__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatLl xmlUCSIsCatLl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatLm
+extern __typeof (xmlUCSIsCatLm) xmlUCSIsCatLm __attribute((alias("xmlUCSIsCatLm__internal_alias")));
+#else
+#ifndef xmlUCSIsCatLm
+extern __typeof (xmlUCSIsCatLm) xmlUCSIsCatLm__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatLm xmlUCSIsCatLm__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatLo
+extern __typeof (xmlUCSIsCatLo) xmlUCSIsCatLo __attribute((alias("xmlUCSIsCatLo__internal_alias")));
+#else
+#ifndef xmlUCSIsCatLo
+extern __typeof (xmlUCSIsCatLo) xmlUCSIsCatLo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatLo xmlUCSIsCatLo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatLt
+extern __typeof (xmlUCSIsCatLt) xmlUCSIsCatLt __attribute((alias("xmlUCSIsCatLt__internal_alias")));
+#else
+#ifndef xmlUCSIsCatLt
+extern __typeof (xmlUCSIsCatLt) xmlUCSIsCatLt__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatLt xmlUCSIsCatLt__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatLu
+extern __typeof (xmlUCSIsCatLu) xmlUCSIsCatLu __attribute((alias("xmlUCSIsCatLu__internal_alias")));
+#else
+#ifndef xmlUCSIsCatLu
+extern __typeof (xmlUCSIsCatLu) xmlUCSIsCatLu__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatLu xmlUCSIsCatLu__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatM
+extern __typeof (xmlUCSIsCatM) xmlUCSIsCatM __attribute((alias("xmlUCSIsCatM__internal_alias")));
+#else
+#ifndef xmlUCSIsCatM
+extern __typeof (xmlUCSIsCatM) xmlUCSIsCatM__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatM xmlUCSIsCatM__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatMc
+extern __typeof (xmlUCSIsCatMc) xmlUCSIsCatMc __attribute((alias("xmlUCSIsCatMc__internal_alias")));
+#else
+#ifndef xmlUCSIsCatMc
+extern __typeof (xmlUCSIsCatMc) xmlUCSIsCatMc__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatMc xmlUCSIsCatMc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatMe
+extern __typeof (xmlUCSIsCatMe) xmlUCSIsCatMe __attribute((alias("xmlUCSIsCatMe__internal_alias")));
+#else
+#ifndef xmlUCSIsCatMe
+extern __typeof (xmlUCSIsCatMe) xmlUCSIsCatMe__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatMe xmlUCSIsCatMe__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatMn
+extern __typeof (xmlUCSIsCatMn) xmlUCSIsCatMn __attribute((alias("xmlUCSIsCatMn__internal_alias")));
+#else
+#ifndef xmlUCSIsCatMn
+extern __typeof (xmlUCSIsCatMn) xmlUCSIsCatMn__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatMn xmlUCSIsCatMn__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatN
+extern __typeof (xmlUCSIsCatN) xmlUCSIsCatN __attribute((alias("xmlUCSIsCatN__internal_alias")));
+#else
+#ifndef xmlUCSIsCatN
+extern __typeof (xmlUCSIsCatN) xmlUCSIsCatN__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatN xmlUCSIsCatN__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatNd
+extern __typeof (xmlUCSIsCatNd) xmlUCSIsCatNd __attribute((alias("xmlUCSIsCatNd__internal_alias")));
+#else
+#ifndef xmlUCSIsCatNd
+extern __typeof (xmlUCSIsCatNd) xmlUCSIsCatNd__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatNd xmlUCSIsCatNd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatNl
+extern __typeof (xmlUCSIsCatNl) xmlUCSIsCatNl __attribute((alias("xmlUCSIsCatNl__internal_alias")));
+#else
+#ifndef xmlUCSIsCatNl
+extern __typeof (xmlUCSIsCatNl) xmlUCSIsCatNl__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatNl xmlUCSIsCatNl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatNo
+extern __typeof (xmlUCSIsCatNo) xmlUCSIsCatNo __attribute((alias("xmlUCSIsCatNo__internal_alias")));
+#else
+#ifndef xmlUCSIsCatNo
+extern __typeof (xmlUCSIsCatNo) xmlUCSIsCatNo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatNo xmlUCSIsCatNo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatP
+extern __typeof (xmlUCSIsCatP) xmlUCSIsCatP __attribute((alias("xmlUCSIsCatP__internal_alias")));
+#else
+#ifndef xmlUCSIsCatP
+extern __typeof (xmlUCSIsCatP) xmlUCSIsCatP__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatP xmlUCSIsCatP__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPc
+extern __typeof (xmlUCSIsCatPc) xmlUCSIsCatPc __attribute((alias("xmlUCSIsCatPc__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPc
+extern __typeof (xmlUCSIsCatPc) xmlUCSIsCatPc__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPc xmlUCSIsCatPc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPd
+extern __typeof (xmlUCSIsCatPd) xmlUCSIsCatPd __attribute((alias("xmlUCSIsCatPd__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPd
+extern __typeof (xmlUCSIsCatPd) xmlUCSIsCatPd__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPd xmlUCSIsCatPd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPe
+extern __typeof (xmlUCSIsCatPe) xmlUCSIsCatPe __attribute((alias("xmlUCSIsCatPe__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPe
+extern __typeof (xmlUCSIsCatPe) xmlUCSIsCatPe__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPe xmlUCSIsCatPe__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPf
+extern __typeof (xmlUCSIsCatPf) xmlUCSIsCatPf __attribute((alias("xmlUCSIsCatPf__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPf
+extern __typeof (xmlUCSIsCatPf) xmlUCSIsCatPf__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPf xmlUCSIsCatPf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPi
+extern __typeof (xmlUCSIsCatPi) xmlUCSIsCatPi __attribute((alias("xmlUCSIsCatPi__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPi
+extern __typeof (xmlUCSIsCatPi) xmlUCSIsCatPi__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPi xmlUCSIsCatPi__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPo
+extern __typeof (xmlUCSIsCatPo) xmlUCSIsCatPo __attribute((alias("xmlUCSIsCatPo__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPo
+extern __typeof (xmlUCSIsCatPo) xmlUCSIsCatPo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPo xmlUCSIsCatPo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatPs
+extern __typeof (xmlUCSIsCatPs) xmlUCSIsCatPs __attribute((alias("xmlUCSIsCatPs__internal_alias")));
+#else
+#ifndef xmlUCSIsCatPs
+extern __typeof (xmlUCSIsCatPs) xmlUCSIsCatPs__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatPs xmlUCSIsCatPs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatS
+extern __typeof (xmlUCSIsCatS) xmlUCSIsCatS __attribute((alias("xmlUCSIsCatS__internal_alias")));
+#else
+#ifndef xmlUCSIsCatS
+extern __typeof (xmlUCSIsCatS) xmlUCSIsCatS__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatS xmlUCSIsCatS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatSc
+extern __typeof (xmlUCSIsCatSc) xmlUCSIsCatSc __attribute((alias("xmlUCSIsCatSc__internal_alias")));
+#else
+#ifndef xmlUCSIsCatSc
+extern __typeof (xmlUCSIsCatSc) xmlUCSIsCatSc__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatSc xmlUCSIsCatSc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatSk
+extern __typeof (xmlUCSIsCatSk) xmlUCSIsCatSk __attribute((alias("xmlUCSIsCatSk__internal_alias")));
+#else
+#ifndef xmlUCSIsCatSk
+extern __typeof (xmlUCSIsCatSk) xmlUCSIsCatSk__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatSk xmlUCSIsCatSk__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatSm
+extern __typeof (xmlUCSIsCatSm) xmlUCSIsCatSm __attribute((alias("xmlUCSIsCatSm__internal_alias")));
+#else
+#ifndef xmlUCSIsCatSm
+extern __typeof (xmlUCSIsCatSm) xmlUCSIsCatSm__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatSm xmlUCSIsCatSm__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatSo
+extern __typeof (xmlUCSIsCatSo) xmlUCSIsCatSo __attribute((alias("xmlUCSIsCatSo__internal_alias")));
+#else
+#ifndef xmlUCSIsCatSo
+extern __typeof (xmlUCSIsCatSo) xmlUCSIsCatSo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatSo xmlUCSIsCatSo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatZ
+extern __typeof (xmlUCSIsCatZ) xmlUCSIsCatZ __attribute((alias("xmlUCSIsCatZ__internal_alias")));
+#else
+#ifndef xmlUCSIsCatZ
+extern __typeof (xmlUCSIsCatZ) xmlUCSIsCatZ__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatZ xmlUCSIsCatZ__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatZl
+extern __typeof (xmlUCSIsCatZl) xmlUCSIsCatZl __attribute((alias("xmlUCSIsCatZl__internal_alias")));
+#else
+#ifndef xmlUCSIsCatZl
+extern __typeof (xmlUCSIsCatZl) xmlUCSIsCatZl__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatZl xmlUCSIsCatZl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatZp
+extern __typeof (xmlUCSIsCatZp) xmlUCSIsCatZp __attribute((alias("xmlUCSIsCatZp__internal_alias")));
+#else
+#ifndef xmlUCSIsCatZp
+extern __typeof (xmlUCSIsCatZp) xmlUCSIsCatZp__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatZp xmlUCSIsCatZp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCatZs
+extern __typeof (xmlUCSIsCatZs) xmlUCSIsCatZs __attribute((alias("xmlUCSIsCatZs__internal_alias")));
+#else
+#ifndef xmlUCSIsCatZs
+extern __typeof (xmlUCSIsCatZs) xmlUCSIsCatZs__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCatZs xmlUCSIsCatZs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCherokee
+extern __typeof (xmlUCSIsCherokee) xmlUCSIsCherokee __attribute((alias("xmlUCSIsCherokee__internal_alias")));
+#else
+#ifndef xmlUCSIsCherokee
+extern __typeof (xmlUCSIsCherokee) xmlUCSIsCherokee__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCherokee xmlUCSIsCherokee__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCombiningDiacriticalMarks
+extern __typeof (xmlUCSIsCombiningDiacriticalMarks) xmlUCSIsCombiningDiacriticalMarks __attribute((alias("xmlUCSIsCombiningDiacriticalMarks__internal_alias")));
+#else
+#ifndef xmlUCSIsCombiningDiacriticalMarks
+extern __typeof (xmlUCSIsCombiningDiacriticalMarks) xmlUCSIsCombiningDiacriticalMarks__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCombiningDiacriticalMarks xmlUCSIsCombiningDiacriticalMarks__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCombiningDiacriticalMarksforSymbols
+extern __typeof (xmlUCSIsCombiningDiacriticalMarksforSymbols) xmlUCSIsCombiningDiacriticalMarksforSymbols __attribute((alias("xmlUCSIsCombiningDiacriticalMarksforSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsCombiningDiacriticalMarksforSymbols
+extern __typeof (xmlUCSIsCombiningDiacriticalMarksforSymbols) xmlUCSIsCombiningDiacriticalMarksforSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCombiningDiacriticalMarksforSymbols xmlUCSIsCombiningDiacriticalMarksforSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCombiningHalfMarks
+extern __typeof (xmlUCSIsCombiningHalfMarks) xmlUCSIsCombiningHalfMarks __attribute((alias("xmlUCSIsCombiningHalfMarks__internal_alias")));
+#else
+#ifndef xmlUCSIsCombiningHalfMarks
+extern __typeof (xmlUCSIsCombiningHalfMarks) xmlUCSIsCombiningHalfMarks__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCombiningHalfMarks xmlUCSIsCombiningHalfMarks__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCombiningMarksforSymbols
+extern __typeof (xmlUCSIsCombiningMarksforSymbols) xmlUCSIsCombiningMarksforSymbols __attribute((alias("xmlUCSIsCombiningMarksforSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsCombiningMarksforSymbols
+extern __typeof (xmlUCSIsCombiningMarksforSymbols) xmlUCSIsCombiningMarksforSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCombiningMarksforSymbols xmlUCSIsCombiningMarksforSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsControlPictures
+extern __typeof (xmlUCSIsControlPictures) xmlUCSIsControlPictures __attribute((alias("xmlUCSIsControlPictures__internal_alias")));
+#else
+#ifndef xmlUCSIsControlPictures
+extern __typeof (xmlUCSIsControlPictures) xmlUCSIsControlPictures__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsControlPictures xmlUCSIsControlPictures__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCurrencySymbols
+extern __typeof (xmlUCSIsCurrencySymbols) xmlUCSIsCurrencySymbols __attribute((alias("xmlUCSIsCurrencySymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsCurrencySymbols
+extern __typeof (xmlUCSIsCurrencySymbols) xmlUCSIsCurrencySymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCurrencySymbols xmlUCSIsCurrencySymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCypriotSyllabary
+extern __typeof (xmlUCSIsCypriotSyllabary) xmlUCSIsCypriotSyllabary __attribute((alias("xmlUCSIsCypriotSyllabary__internal_alias")));
+#else
+#ifndef xmlUCSIsCypriotSyllabary
+extern __typeof (xmlUCSIsCypriotSyllabary) xmlUCSIsCypriotSyllabary__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCypriotSyllabary xmlUCSIsCypriotSyllabary__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCyrillic
+extern __typeof (xmlUCSIsCyrillic) xmlUCSIsCyrillic __attribute((alias("xmlUCSIsCyrillic__internal_alias")));
+#else
+#ifndef xmlUCSIsCyrillic
+extern __typeof (xmlUCSIsCyrillic) xmlUCSIsCyrillic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCyrillic xmlUCSIsCyrillic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsCyrillicSupplement
+extern __typeof (xmlUCSIsCyrillicSupplement) xmlUCSIsCyrillicSupplement __attribute((alias("xmlUCSIsCyrillicSupplement__internal_alias")));
+#else
+#ifndef xmlUCSIsCyrillicSupplement
+extern __typeof (xmlUCSIsCyrillicSupplement) xmlUCSIsCyrillicSupplement__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsCyrillicSupplement xmlUCSIsCyrillicSupplement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsDeseret
+extern __typeof (xmlUCSIsDeseret) xmlUCSIsDeseret __attribute((alias("xmlUCSIsDeseret__internal_alias")));
+#else
+#ifndef xmlUCSIsDeseret
+extern __typeof (xmlUCSIsDeseret) xmlUCSIsDeseret__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsDeseret xmlUCSIsDeseret__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsDevanagari
+extern __typeof (xmlUCSIsDevanagari) xmlUCSIsDevanagari __attribute((alias("xmlUCSIsDevanagari__internal_alias")));
+#else
+#ifndef xmlUCSIsDevanagari
+extern __typeof (xmlUCSIsDevanagari) xmlUCSIsDevanagari__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsDevanagari xmlUCSIsDevanagari__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsDingbats
+extern __typeof (xmlUCSIsDingbats) xmlUCSIsDingbats __attribute((alias("xmlUCSIsDingbats__internal_alias")));
+#else
+#ifndef xmlUCSIsDingbats
+extern __typeof (xmlUCSIsDingbats) xmlUCSIsDingbats__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsDingbats xmlUCSIsDingbats__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsEnclosedAlphanumerics
+extern __typeof (xmlUCSIsEnclosedAlphanumerics) xmlUCSIsEnclosedAlphanumerics __attribute((alias("xmlUCSIsEnclosedAlphanumerics__internal_alias")));
+#else
+#ifndef xmlUCSIsEnclosedAlphanumerics
+extern __typeof (xmlUCSIsEnclosedAlphanumerics) xmlUCSIsEnclosedAlphanumerics__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsEnclosedAlphanumerics xmlUCSIsEnclosedAlphanumerics__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsEnclosedCJKLettersandMonths
+extern __typeof (xmlUCSIsEnclosedCJKLettersandMonths) xmlUCSIsEnclosedCJKLettersandMonths __attribute((alias("xmlUCSIsEnclosedCJKLettersandMonths__internal_alias")));
+#else
+#ifndef xmlUCSIsEnclosedCJKLettersandMonths
+extern __typeof (xmlUCSIsEnclosedCJKLettersandMonths) xmlUCSIsEnclosedCJKLettersandMonths__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsEnclosedCJKLettersandMonths xmlUCSIsEnclosedCJKLettersandMonths__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsEthiopic
+extern __typeof (xmlUCSIsEthiopic) xmlUCSIsEthiopic __attribute((alias("xmlUCSIsEthiopic__internal_alias")));
+#else
+#ifndef xmlUCSIsEthiopic
+extern __typeof (xmlUCSIsEthiopic) xmlUCSIsEthiopic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsEthiopic xmlUCSIsEthiopic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGeneralPunctuation
+extern __typeof (xmlUCSIsGeneralPunctuation) xmlUCSIsGeneralPunctuation __attribute((alias("xmlUCSIsGeneralPunctuation__internal_alias")));
+#else
+#ifndef xmlUCSIsGeneralPunctuation
+extern __typeof (xmlUCSIsGeneralPunctuation) xmlUCSIsGeneralPunctuation__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGeneralPunctuation xmlUCSIsGeneralPunctuation__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGeometricShapes
+extern __typeof (xmlUCSIsGeometricShapes) xmlUCSIsGeometricShapes __attribute((alias("xmlUCSIsGeometricShapes__internal_alias")));
+#else
+#ifndef xmlUCSIsGeometricShapes
+extern __typeof (xmlUCSIsGeometricShapes) xmlUCSIsGeometricShapes__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGeometricShapes xmlUCSIsGeometricShapes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGeorgian
+extern __typeof (xmlUCSIsGeorgian) xmlUCSIsGeorgian __attribute((alias("xmlUCSIsGeorgian__internal_alias")));
+#else
+#ifndef xmlUCSIsGeorgian
+extern __typeof (xmlUCSIsGeorgian) xmlUCSIsGeorgian__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGeorgian xmlUCSIsGeorgian__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGothic
+extern __typeof (xmlUCSIsGothic) xmlUCSIsGothic __attribute((alias("xmlUCSIsGothic__internal_alias")));
+#else
+#ifndef xmlUCSIsGothic
+extern __typeof (xmlUCSIsGothic) xmlUCSIsGothic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGothic xmlUCSIsGothic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGreek
+extern __typeof (xmlUCSIsGreek) xmlUCSIsGreek __attribute((alias("xmlUCSIsGreek__internal_alias")));
+#else
+#ifndef xmlUCSIsGreek
+extern __typeof (xmlUCSIsGreek) xmlUCSIsGreek__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGreek xmlUCSIsGreek__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGreekExtended
+extern __typeof (xmlUCSIsGreekExtended) xmlUCSIsGreekExtended __attribute((alias("xmlUCSIsGreekExtended__internal_alias")));
+#else
+#ifndef xmlUCSIsGreekExtended
+extern __typeof (xmlUCSIsGreekExtended) xmlUCSIsGreekExtended__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGreekExtended xmlUCSIsGreekExtended__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGreekandCoptic
+extern __typeof (xmlUCSIsGreekandCoptic) xmlUCSIsGreekandCoptic __attribute((alias("xmlUCSIsGreekandCoptic__internal_alias")));
+#else
+#ifndef xmlUCSIsGreekandCoptic
+extern __typeof (xmlUCSIsGreekandCoptic) xmlUCSIsGreekandCoptic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGreekandCoptic xmlUCSIsGreekandCoptic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGujarati
+extern __typeof (xmlUCSIsGujarati) xmlUCSIsGujarati __attribute((alias("xmlUCSIsGujarati__internal_alias")));
+#else
+#ifndef xmlUCSIsGujarati
+extern __typeof (xmlUCSIsGujarati) xmlUCSIsGujarati__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGujarati xmlUCSIsGujarati__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsGurmukhi
+extern __typeof (xmlUCSIsGurmukhi) xmlUCSIsGurmukhi __attribute((alias("xmlUCSIsGurmukhi__internal_alias")));
+#else
+#ifndef xmlUCSIsGurmukhi
+extern __typeof (xmlUCSIsGurmukhi) xmlUCSIsGurmukhi__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsGurmukhi xmlUCSIsGurmukhi__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHalfwidthandFullwidthForms
+extern __typeof (xmlUCSIsHalfwidthandFullwidthForms) xmlUCSIsHalfwidthandFullwidthForms __attribute((alias("xmlUCSIsHalfwidthandFullwidthForms__internal_alias")));
+#else
+#ifndef xmlUCSIsHalfwidthandFullwidthForms
+extern __typeof (xmlUCSIsHalfwidthandFullwidthForms) xmlUCSIsHalfwidthandFullwidthForms__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHalfwidthandFullwidthForms xmlUCSIsHalfwidthandFullwidthForms__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHangulCompatibilityJamo
+extern __typeof (xmlUCSIsHangulCompatibilityJamo) xmlUCSIsHangulCompatibilityJamo __attribute((alias("xmlUCSIsHangulCompatibilityJamo__internal_alias")));
+#else
+#ifndef xmlUCSIsHangulCompatibilityJamo
+extern __typeof (xmlUCSIsHangulCompatibilityJamo) xmlUCSIsHangulCompatibilityJamo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHangulCompatibilityJamo xmlUCSIsHangulCompatibilityJamo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHangulJamo
+extern __typeof (xmlUCSIsHangulJamo) xmlUCSIsHangulJamo __attribute((alias("xmlUCSIsHangulJamo__internal_alias")));
+#else
+#ifndef xmlUCSIsHangulJamo
+extern __typeof (xmlUCSIsHangulJamo) xmlUCSIsHangulJamo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHangulJamo xmlUCSIsHangulJamo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHangulSyllables
+extern __typeof (xmlUCSIsHangulSyllables) xmlUCSIsHangulSyllables __attribute((alias("xmlUCSIsHangulSyllables__internal_alias")));
+#else
+#ifndef xmlUCSIsHangulSyllables
+extern __typeof (xmlUCSIsHangulSyllables) xmlUCSIsHangulSyllables__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHangulSyllables xmlUCSIsHangulSyllables__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHanunoo
+extern __typeof (xmlUCSIsHanunoo) xmlUCSIsHanunoo __attribute((alias("xmlUCSIsHanunoo__internal_alias")));
+#else
+#ifndef xmlUCSIsHanunoo
+extern __typeof (xmlUCSIsHanunoo) xmlUCSIsHanunoo__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHanunoo xmlUCSIsHanunoo__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHebrew
+extern __typeof (xmlUCSIsHebrew) xmlUCSIsHebrew __attribute((alias("xmlUCSIsHebrew__internal_alias")));
+#else
+#ifndef xmlUCSIsHebrew
+extern __typeof (xmlUCSIsHebrew) xmlUCSIsHebrew__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHebrew xmlUCSIsHebrew__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHighPrivateUseSurrogates
+extern __typeof (xmlUCSIsHighPrivateUseSurrogates) xmlUCSIsHighPrivateUseSurrogates __attribute((alias("xmlUCSIsHighPrivateUseSurrogates__internal_alias")));
+#else
+#ifndef xmlUCSIsHighPrivateUseSurrogates
+extern __typeof (xmlUCSIsHighPrivateUseSurrogates) xmlUCSIsHighPrivateUseSurrogates__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHighPrivateUseSurrogates xmlUCSIsHighPrivateUseSurrogates__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHighSurrogates
+extern __typeof (xmlUCSIsHighSurrogates) xmlUCSIsHighSurrogates __attribute((alias("xmlUCSIsHighSurrogates__internal_alias")));
+#else
+#ifndef xmlUCSIsHighSurrogates
+extern __typeof (xmlUCSIsHighSurrogates) xmlUCSIsHighSurrogates__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHighSurrogates xmlUCSIsHighSurrogates__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsHiragana
+extern __typeof (xmlUCSIsHiragana) xmlUCSIsHiragana __attribute((alias("xmlUCSIsHiragana__internal_alias")));
+#else
+#ifndef xmlUCSIsHiragana
+extern __typeof (xmlUCSIsHiragana) xmlUCSIsHiragana__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsHiragana xmlUCSIsHiragana__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsIPAExtensions
+extern __typeof (xmlUCSIsIPAExtensions) xmlUCSIsIPAExtensions __attribute((alias("xmlUCSIsIPAExtensions__internal_alias")));
+#else
+#ifndef xmlUCSIsIPAExtensions
+extern __typeof (xmlUCSIsIPAExtensions) xmlUCSIsIPAExtensions__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsIPAExtensions xmlUCSIsIPAExtensions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsIdeographicDescriptionCharacters
+extern __typeof (xmlUCSIsIdeographicDescriptionCharacters) xmlUCSIsIdeographicDescriptionCharacters __attribute((alias("xmlUCSIsIdeographicDescriptionCharacters__internal_alias")));
+#else
+#ifndef xmlUCSIsIdeographicDescriptionCharacters
+extern __typeof (xmlUCSIsIdeographicDescriptionCharacters) xmlUCSIsIdeographicDescriptionCharacters__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsIdeographicDescriptionCharacters xmlUCSIsIdeographicDescriptionCharacters__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKanbun
+extern __typeof (xmlUCSIsKanbun) xmlUCSIsKanbun __attribute((alias("xmlUCSIsKanbun__internal_alias")));
+#else
+#ifndef xmlUCSIsKanbun
+extern __typeof (xmlUCSIsKanbun) xmlUCSIsKanbun__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKanbun xmlUCSIsKanbun__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKangxiRadicals
+extern __typeof (xmlUCSIsKangxiRadicals) xmlUCSIsKangxiRadicals __attribute((alias("xmlUCSIsKangxiRadicals__internal_alias")));
+#else
+#ifndef xmlUCSIsKangxiRadicals
+extern __typeof (xmlUCSIsKangxiRadicals) xmlUCSIsKangxiRadicals__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKangxiRadicals xmlUCSIsKangxiRadicals__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKannada
+extern __typeof (xmlUCSIsKannada) xmlUCSIsKannada __attribute((alias("xmlUCSIsKannada__internal_alias")));
+#else
+#ifndef xmlUCSIsKannada
+extern __typeof (xmlUCSIsKannada) xmlUCSIsKannada__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKannada xmlUCSIsKannada__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKatakana
+extern __typeof (xmlUCSIsKatakana) xmlUCSIsKatakana __attribute((alias("xmlUCSIsKatakana__internal_alias")));
+#else
+#ifndef xmlUCSIsKatakana
+extern __typeof (xmlUCSIsKatakana) xmlUCSIsKatakana__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKatakana xmlUCSIsKatakana__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKatakanaPhoneticExtensions
+extern __typeof (xmlUCSIsKatakanaPhoneticExtensions) xmlUCSIsKatakanaPhoneticExtensions __attribute((alias("xmlUCSIsKatakanaPhoneticExtensions__internal_alias")));
+#else
+#ifndef xmlUCSIsKatakanaPhoneticExtensions
+extern __typeof (xmlUCSIsKatakanaPhoneticExtensions) xmlUCSIsKatakanaPhoneticExtensions__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKatakanaPhoneticExtensions xmlUCSIsKatakanaPhoneticExtensions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKhmer
+extern __typeof (xmlUCSIsKhmer) xmlUCSIsKhmer __attribute((alias("xmlUCSIsKhmer__internal_alias")));
+#else
+#ifndef xmlUCSIsKhmer
+extern __typeof (xmlUCSIsKhmer) xmlUCSIsKhmer__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKhmer xmlUCSIsKhmer__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsKhmerSymbols
+extern __typeof (xmlUCSIsKhmerSymbols) xmlUCSIsKhmerSymbols __attribute((alias("xmlUCSIsKhmerSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsKhmerSymbols
+extern __typeof (xmlUCSIsKhmerSymbols) xmlUCSIsKhmerSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsKhmerSymbols xmlUCSIsKhmerSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLao
+extern __typeof (xmlUCSIsLao) xmlUCSIsLao __attribute((alias("xmlUCSIsLao__internal_alias")));
+#else
+#ifndef xmlUCSIsLao
+extern __typeof (xmlUCSIsLao) xmlUCSIsLao__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLao xmlUCSIsLao__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLatin1Supplement
+extern __typeof (xmlUCSIsLatin1Supplement) xmlUCSIsLatin1Supplement __attribute((alias("xmlUCSIsLatin1Supplement__internal_alias")));
+#else
+#ifndef xmlUCSIsLatin1Supplement
+extern __typeof (xmlUCSIsLatin1Supplement) xmlUCSIsLatin1Supplement__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLatin1Supplement xmlUCSIsLatin1Supplement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLatinExtendedA
+extern __typeof (xmlUCSIsLatinExtendedA) xmlUCSIsLatinExtendedA __attribute((alias("xmlUCSIsLatinExtendedA__internal_alias")));
+#else
+#ifndef xmlUCSIsLatinExtendedA
+extern __typeof (xmlUCSIsLatinExtendedA) xmlUCSIsLatinExtendedA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLatinExtendedA xmlUCSIsLatinExtendedA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLatinExtendedAdditional
+extern __typeof (xmlUCSIsLatinExtendedAdditional) xmlUCSIsLatinExtendedAdditional __attribute((alias("xmlUCSIsLatinExtendedAdditional__internal_alias")));
+#else
+#ifndef xmlUCSIsLatinExtendedAdditional
+extern __typeof (xmlUCSIsLatinExtendedAdditional) xmlUCSIsLatinExtendedAdditional__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLatinExtendedAdditional xmlUCSIsLatinExtendedAdditional__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLatinExtendedB
+extern __typeof (xmlUCSIsLatinExtendedB) xmlUCSIsLatinExtendedB __attribute((alias("xmlUCSIsLatinExtendedB__internal_alias")));
+#else
+#ifndef xmlUCSIsLatinExtendedB
+extern __typeof (xmlUCSIsLatinExtendedB) xmlUCSIsLatinExtendedB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLatinExtendedB xmlUCSIsLatinExtendedB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLetterlikeSymbols
+extern __typeof (xmlUCSIsLetterlikeSymbols) xmlUCSIsLetterlikeSymbols __attribute((alias("xmlUCSIsLetterlikeSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsLetterlikeSymbols
+extern __typeof (xmlUCSIsLetterlikeSymbols) xmlUCSIsLetterlikeSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLetterlikeSymbols xmlUCSIsLetterlikeSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLimbu
+extern __typeof (xmlUCSIsLimbu) xmlUCSIsLimbu __attribute((alias("xmlUCSIsLimbu__internal_alias")));
+#else
+#ifndef xmlUCSIsLimbu
+extern __typeof (xmlUCSIsLimbu) xmlUCSIsLimbu__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLimbu xmlUCSIsLimbu__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLinearBIdeograms
+extern __typeof (xmlUCSIsLinearBIdeograms) xmlUCSIsLinearBIdeograms __attribute((alias("xmlUCSIsLinearBIdeograms__internal_alias")));
+#else
+#ifndef xmlUCSIsLinearBIdeograms
+extern __typeof (xmlUCSIsLinearBIdeograms) xmlUCSIsLinearBIdeograms__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLinearBIdeograms xmlUCSIsLinearBIdeograms__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLinearBSyllabary
+extern __typeof (xmlUCSIsLinearBSyllabary) xmlUCSIsLinearBSyllabary __attribute((alias("xmlUCSIsLinearBSyllabary__internal_alias")));
+#else
+#ifndef xmlUCSIsLinearBSyllabary
+extern __typeof (xmlUCSIsLinearBSyllabary) xmlUCSIsLinearBSyllabary__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLinearBSyllabary xmlUCSIsLinearBSyllabary__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsLowSurrogates
+extern __typeof (xmlUCSIsLowSurrogates) xmlUCSIsLowSurrogates __attribute((alias("xmlUCSIsLowSurrogates__internal_alias")));
+#else
+#ifndef xmlUCSIsLowSurrogates
+extern __typeof (xmlUCSIsLowSurrogates) xmlUCSIsLowSurrogates__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsLowSurrogates xmlUCSIsLowSurrogates__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMalayalam
+extern __typeof (xmlUCSIsMalayalam) xmlUCSIsMalayalam __attribute((alias("xmlUCSIsMalayalam__internal_alias")));
+#else
+#ifndef xmlUCSIsMalayalam
+extern __typeof (xmlUCSIsMalayalam) xmlUCSIsMalayalam__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMalayalam xmlUCSIsMalayalam__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMathematicalAlphanumericSymbols
+extern __typeof (xmlUCSIsMathematicalAlphanumericSymbols) xmlUCSIsMathematicalAlphanumericSymbols __attribute((alias("xmlUCSIsMathematicalAlphanumericSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsMathematicalAlphanumericSymbols
+extern __typeof (xmlUCSIsMathematicalAlphanumericSymbols) xmlUCSIsMathematicalAlphanumericSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMathematicalAlphanumericSymbols xmlUCSIsMathematicalAlphanumericSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMathematicalOperators
+extern __typeof (xmlUCSIsMathematicalOperators) xmlUCSIsMathematicalOperators __attribute((alias("xmlUCSIsMathematicalOperators__internal_alias")));
+#else
+#ifndef xmlUCSIsMathematicalOperators
+extern __typeof (xmlUCSIsMathematicalOperators) xmlUCSIsMathematicalOperators__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMathematicalOperators xmlUCSIsMathematicalOperators__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMiscellaneousMathematicalSymbolsA
+extern __typeof (xmlUCSIsMiscellaneousMathematicalSymbolsA) xmlUCSIsMiscellaneousMathematicalSymbolsA __attribute((alias("xmlUCSIsMiscellaneousMathematicalSymbolsA__internal_alias")));
+#else
+#ifndef xmlUCSIsMiscellaneousMathematicalSymbolsA
+extern __typeof (xmlUCSIsMiscellaneousMathematicalSymbolsA) xmlUCSIsMiscellaneousMathematicalSymbolsA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMiscellaneousMathematicalSymbolsA xmlUCSIsMiscellaneousMathematicalSymbolsA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMiscellaneousMathematicalSymbolsB
+extern __typeof (xmlUCSIsMiscellaneousMathematicalSymbolsB) xmlUCSIsMiscellaneousMathematicalSymbolsB __attribute((alias("xmlUCSIsMiscellaneousMathematicalSymbolsB__internal_alias")));
+#else
+#ifndef xmlUCSIsMiscellaneousMathematicalSymbolsB
+extern __typeof (xmlUCSIsMiscellaneousMathematicalSymbolsB) xmlUCSIsMiscellaneousMathematicalSymbolsB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMiscellaneousMathematicalSymbolsB xmlUCSIsMiscellaneousMathematicalSymbolsB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMiscellaneousSymbols
+extern __typeof (xmlUCSIsMiscellaneousSymbols) xmlUCSIsMiscellaneousSymbols __attribute((alias("xmlUCSIsMiscellaneousSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsMiscellaneousSymbols
+extern __typeof (xmlUCSIsMiscellaneousSymbols) xmlUCSIsMiscellaneousSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMiscellaneousSymbols xmlUCSIsMiscellaneousSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMiscellaneousSymbolsandArrows
+extern __typeof (xmlUCSIsMiscellaneousSymbolsandArrows) xmlUCSIsMiscellaneousSymbolsandArrows __attribute((alias("xmlUCSIsMiscellaneousSymbolsandArrows__internal_alias")));
+#else
+#ifndef xmlUCSIsMiscellaneousSymbolsandArrows
+extern __typeof (xmlUCSIsMiscellaneousSymbolsandArrows) xmlUCSIsMiscellaneousSymbolsandArrows__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMiscellaneousSymbolsandArrows xmlUCSIsMiscellaneousSymbolsandArrows__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMiscellaneousTechnical
+extern __typeof (xmlUCSIsMiscellaneousTechnical) xmlUCSIsMiscellaneousTechnical __attribute((alias("xmlUCSIsMiscellaneousTechnical__internal_alias")));
+#else
+#ifndef xmlUCSIsMiscellaneousTechnical
+extern __typeof (xmlUCSIsMiscellaneousTechnical) xmlUCSIsMiscellaneousTechnical__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMiscellaneousTechnical xmlUCSIsMiscellaneousTechnical__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMongolian
+extern __typeof (xmlUCSIsMongolian) xmlUCSIsMongolian __attribute((alias("xmlUCSIsMongolian__internal_alias")));
+#else
+#ifndef xmlUCSIsMongolian
+extern __typeof (xmlUCSIsMongolian) xmlUCSIsMongolian__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMongolian xmlUCSIsMongolian__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMusicalSymbols
+extern __typeof (xmlUCSIsMusicalSymbols) xmlUCSIsMusicalSymbols __attribute((alias("xmlUCSIsMusicalSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsMusicalSymbols
+extern __typeof (xmlUCSIsMusicalSymbols) xmlUCSIsMusicalSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMusicalSymbols xmlUCSIsMusicalSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsMyanmar
+extern __typeof (xmlUCSIsMyanmar) xmlUCSIsMyanmar __attribute((alias("xmlUCSIsMyanmar__internal_alias")));
+#else
+#ifndef xmlUCSIsMyanmar
+extern __typeof (xmlUCSIsMyanmar) xmlUCSIsMyanmar__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsMyanmar xmlUCSIsMyanmar__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsNumberForms
+extern __typeof (xmlUCSIsNumberForms) xmlUCSIsNumberForms __attribute((alias("xmlUCSIsNumberForms__internal_alias")));
+#else
+#ifndef xmlUCSIsNumberForms
+extern __typeof (xmlUCSIsNumberForms) xmlUCSIsNumberForms__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsNumberForms xmlUCSIsNumberForms__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsOgham
+extern __typeof (xmlUCSIsOgham) xmlUCSIsOgham __attribute((alias("xmlUCSIsOgham__internal_alias")));
+#else
+#ifndef xmlUCSIsOgham
+extern __typeof (xmlUCSIsOgham) xmlUCSIsOgham__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsOgham xmlUCSIsOgham__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsOldItalic
+extern __typeof (xmlUCSIsOldItalic) xmlUCSIsOldItalic __attribute((alias("xmlUCSIsOldItalic__internal_alias")));
+#else
+#ifndef xmlUCSIsOldItalic
+extern __typeof (xmlUCSIsOldItalic) xmlUCSIsOldItalic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsOldItalic xmlUCSIsOldItalic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsOpticalCharacterRecognition
+extern __typeof (xmlUCSIsOpticalCharacterRecognition) xmlUCSIsOpticalCharacterRecognition __attribute((alias("xmlUCSIsOpticalCharacterRecognition__internal_alias")));
+#else
+#ifndef xmlUCSIsOpticalCharacterRecognition
+extern __typeof (xmlUCSIsOpticalCharacterRecognition) xmlUCSIsOpticalCharacterRecognition__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsOpticalCharacterRecognition xmlUCSIsOpticalCharacterRecognition__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsOriya
+extern __typeof (xmlUCSIsOriya) xmlUCSIsOriya __attribute((alias("xmlUCSIsOriya__internal_alias")));
+#else
+#ifndef xmlUCSIsOriya
+extern __typeof (xmlUCSIsOriya) xmlUCSIsOriya__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsOriya xmlUCSIsOriya__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsOsmanya
+extern __typeof (xmlUCSIsOsmanya) xmlUCSIsOsmanya __attribute((alias("xmlUCSIsOsmanya__internal_alias")));
+#else
+#ifndef xmlUCSIsOsmanya
+extern __typeof (xmlUCSIsOsmanya) xmlUCSIsOsmanya__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsOsmanya xmlUCSIsOsmanya__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsPhoneticExtensions
+extern __typeof (xmlUCSIsPhoneticExtensions) xmlUCSIsPhoneticExtensions __attribute((alias("xmlUCSIsPhoneticExtensions__internal_alias")));
+#else
+#ifndef xmlUCSIsPhoneticExtensions
+extern __typeof (xmlUCSIsPhoneticExtensions) xmlUCSIsPhoneticExtensions__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsPhoneticExtensions xmlUCSIsPhoneticExtensions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsPrivateUse
+extern __typeof (xmlUCSIsPrivateUse) xmlUCSIsPrivateUse __attribute((alias("xmlUCSIsPrivateUse__internal_alias")));
+#else
+#ifndef xmlUCSIsPrivateUse
+extern __typeof (xmlUCSIsPrivateUse) xmlUCSIsPrivateUse__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsPrivateUse xmlUCSIsPrivateUse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsPrivateUseArea
+extern __typeof (xmlUCSIsPrivateUseArea) xmlUCSIsPrivateUseArea __attribute((alias("xmlUCSIsPrivateUseArea__internal_alias")));
+#else
+#ifndef xmlUCSIsPrivateUseArea
+extern __typeof (xmlUCSIsPrivateUseArea) xmlUCSIsPrivateUseArea__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsPrivateUseArea xmlUCSIsPrivateUseArea__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsRunic
+extern __typeof (xmlUCSIsRunic) xmlUCSIsRunic __attribute((alias("xmlUCSIsRunic__internal_alias")));
+#else
+#ifndef xmlUCSIsRunic
+extern __typeof (xmlUCSIsRunic) xmlUCSIsRunic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsRunic xmlUCSIsRunic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsShavian
+extern __typeof (xmlUCSIsShavian) xmlUCSIsShavian __attribute((alias("xmlUCSIsShavian__internal_alias")));
+#else
+#ifndef xmlUCSIsShavian
+extern __typeof (xmlUCSIsShavian) xmlUCSIsShavian__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsShavian xmlUCSIsShavian__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSinhala
+extern __typeof (xmlUCSIsSinhala) xmlUCSIsSinhala __attribute((alias("xmlUCSIsSinhala__internal_alias")));
+#else
+#ifndef xmlUCSIsSinhala
+extern __typeof (xmlUCSIsSinhala) xmlUCSIsSinhala__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSinhala xmlUCSIsSinhala__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSmallFormVariants
+extern __typeof (xmlUCSIsSmallFormVariants) xmlUCSIsSmallFormVariants __attribute((alias("xmlUCSIsSmallFormVariants__internal_alias")));
+#else
+#ifndef xmlUCSIsSmallFormVariants
+extern __typeof (xmlUCSIsSmallFormVariants) xmlUCSIsSmallFormVariants__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSmallFormVariants xmlUCSIsSmallFormVariants__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSpacingModifierLetters
+extern __typeof (xmlUCSIsSpacingModifierLetters) xmlUCSIsSpacingModifierLetters __attribute((alias("xmlUCSIsSpacingModifierLetters__internal_alias")));
+#else
+#ifndef xmlUCSIsSpacingModifierLetters
+extern __typeof (xmlUCSIsSpacingModifierLetters) xmlUCSIsSpacingModifierLetters__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSpacingModifierLetters xmlUCSIsSpacingModifierLetters__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSpecials
+extern __typeof (xmlUCSIsSpecials) xmlUCSIsSpecials __attribute((alias("xmlUCSIsSpecials__internal_alias")));
+#else
+#ifndef xmlUCSIsSpecials
+extern __typeof (xmlUCSIsSpecials) xmlUCSIsSpecials__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSpecials xmlUCSIsSpecials__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSuperscriptsandSubscripts
+extern __typeof (xmlUCSIsSuperscriptsandSubscripts) xmlUCSIsSuperscriptsandSubscripts __attribute((alias("xmlUCSIsSuperscriptsandSubscripts__internal_alias")));
+#else
+#ifndef xmlUCSIsSuperscriptsandSubscripts
+extern __typeof (xmlUCSIsSuperscriptsandSubscripts) xmlUCSIsSuperscriptsandSubscripts__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSuperscriptsandSubscripts xmlUCSIsSuperscriptsandSubscripts__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSupplementalArrowsA
+extern __typeof (xmlUCSIsSupplementalArrowsA) xmlUCSIsSupplementalArrowsA __attribute((alias("xmlUCSIsSupplementalArrowsA__internal_alias")));
+#else
+#ifndef xmlUCSIsSupplementalArrowsA
+extern __typeof (xmlUCSIsSupplementalArrowsA) xmlUCSIsSupplementalArrowsA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSupplementalArrowsA xmlUCSIsSupplementalArrowsA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSupplementalArrowsB
+extern __typeof (xmlUCSIsSupplementalArrowsB) xmlUCSIsSupplementalArrowsB __attribute((alias("xmlUCSIsSupplementalArrowsB__internal_alias")));
+#else
+#ifndef xmlUCSIsSupplementalArrowsB
+extern __typeof (xmlUCSIsSupplementalArrowsB) xmlUCSIsSupplementalArrowsB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSupplementalArrowsB xmlUCSIsSupplementalArrowsB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSupplementalMathematicalOperators
+extern __typeof (xmlUCSIsSupplementalMathematicalOperators) xmlUCSIsSupplementalMathematicalOperators __attribute((alias("xmlUCSIsSupplementalMathematicalOperators__internal_alias")));
+#else
+#ifndef xmlUCSIsSupplementalMathematicalOperators
+extern __typeof (xmlUCSIsSupplementalMathematicalOperators) xmlUCSIsSupplementalMathematicalOperators__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSupplementalMathematicalOperators xmlUCSIsSupplementalMathematicalOperators__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSupplementaryPrivateUseAreaA
+extern __typeof (xmlUCSIsSupplementaryPrivateUseAreaA) xmlUCSIsSupplementaryPrivateUseAreaA __attribute((alias("xmlUCSIsSupplementaryPrivateUseAreaA__internal_alias")));
+#else
+#ifndef xmlUCSIsSupplementaryPrivateUseAreaA
+extern __typeof (xmlUCSIsSupplementaryPrivateUseAreaA) xmlUCSIsSupplementaryPrivateUseAreaA__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSupplementaryPrivateUseAreaA xmlUCSIsSupplementaryPrivateUseAreaA__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSupplementaryPrivateUseAreaB
+extern __typeof (xmlUCSIsSupplementaryPrivateUseAreaB) xmlUCSIsSupplementaryPrivateUseAreaB __attribute((alias("xmlUCSIsSupplementaryPrivateUseAreaB__internal_alias")));
+#else
+#ifndef xmlUCSIsSupplementaryPrivateUseAreaB
+extern __typeof (xmlUCSIsSupplementaryPrivateUseAreaB) xmlUCSIsSupplementaryPrivateUseAreaB__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSupplementaryPrivateUseAreaB xmlUCSIsSupplementaryPrivateUseAreaB__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsSyriac
+extern __typeof (xmlUCSIsSyriac) xmlUCSIsSyriac __attribute((alias("xmlUCSIsSyriac__internal_alias")));
+#else
+#ifndef xmlUCSIsSyriac
+extern __typeof (xmlUCSIsSyriac) xmlUCSIsSyriac__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsSyriac xmlUCSIsSyriac__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTagalog
+extern __typeof (xmlUCSIsTagalog) xmlUCSIsTagalog __attribute((alias("xmlUCSIsTagalog__internal_alias")));
+#else
+#ifndef xmlUCSIsTagalog
+extern __typeof (xmlUCSIsTagalog) xmlUCSIsTagalog__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTagalog xmlUCSIsTagalog__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTagbanwa
+extern __typeof (xmlUCSIsTagbanwa) xmlUCSIsTagbanwa __attribute((alias("xmlUCSIsTagbanwa__internal_alias")));
+#else
+#ifndef xmlUCSIsTagbanwa
+extern __typeof (xmlUCSIsTagbanwa) xmlUCSIsTagbanwa__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTagbanwa xmlUCSIsTagbanwa__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTags
+extern __typeof (xmlUCSIsTags) xmlUCSIsTags __attribute((alias("xmlUCSIsTags__internal_alias")));
+#else
+#ifndef xmlUCSIsTags
+extern __typeof (xmlUCSIsTags) xmlUCSIsTags__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTags xmlUCSIsTags__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTaiLe
+extern __typeof (xmlUCSIsTaiLe) xmlUCSIsTaiLe __attribute((alias("xmlUCSIsTaiLe__internal_alias")));
+#else
+#ifndef xmlUCSIsTaiLe
+extern __typeof (xmlUCSIsTaiLe) xmlUCSIsTaiLe__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTaiLe xmlUCSIsTaiLe__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTaiXuanJingSymbols
+extern __typeof (xmlUCSIsTaiXuanJingSymbols) xmlUCSIsTaiXuanJingSymbols __attribute((alias("xmlUCSIsTaiXuanJingSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsTaiXuanJingSymbols
+extern __typeof (xmlUCSIsTaiXuanJingSymbols) xmlUCSIsTaiXuanJingSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTaiXuanJingSymbols xmlUCSIsTaiXuanJingSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTamil
+extern __typeof (xmlUCSIsTamil) xmlUCSIsTamil __attribute((alias("xmlUCSIsTamil__internal_alias")));
+#else
+#ifndef xmlUCSIsTamil
+extern __typeof (xmlUCSIsTamil) xmlUCSIsTamil__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTamil xmlUCSIsTamil__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTelugu
+extern __typeof (xmlUCSIsTelugu) xmlUCSIsTelugu __attribute((alias("xmlUCSIsTelugu__internal_alias")));
+#else
+#ifndef xmlUCSIsTelugu
+extern __typeof (xmlUCSIsTelugu) xmlUCSIsTelugu__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTelugu xmlUCSIsTelugu__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsThaana
+extern __typeof (xmlUCSIsThaana) xmlUCSIsThaana __attribute((alias("xmlUCSIsThaana__internal_alias")));
+#else
+#ifndef xmlUCSIsThaana
+extern __typeof (xmlUCSIsThaana) xmlUCSIsThaana__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsThaana xmlUCSIsThaana__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsThai
+extern __typeof (xmlUCSIsThai) xmlUCSIsThai __attribute((alias("xmlUCSIsThai__internal_alias")));
+#else
+#ifndef xmlUCSIsThai
+extern __typeof (xmlUCSIsThai) xmlUCSIsThai__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsThai xmlUCSIsThai__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsTibetan
+extern __typeof (xmlUCSIsTibetan) xmlUCSIsTibetan __attribute((alias("xmlUCSIsTibetan__internal_alias")));
+#else
+#ifndef xmlUCSIsTibetan
+extern __typeof (xmlUCSIsTibetan) xmlUCSIsTibetan__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsTibetan xmlUCSIsTibetan__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsUgaritic
+extern __typeof (xmlUCSIsUgaritic) xmlUCSIsUgaritic __attribute((alias("xmlUCSIsUgaritic__internal_alias")));
+#else
+#ifndef xmlUCSIsUgaritic
+extern __typeof (xmlUCSIsUgaritic) xmlUCSIsUgaritic__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsUgaritic xmlUCSIsUgaritic__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsUnifiedCanadianAboriginalSyllabics
+extern __typeof (xmlUCSIsUnifiedCanadianAboriginalSyllabics) xmlUCSIsUnifiedCanadianAboriginalSyllabics __attribute((alias("xmlUCSIsUnifiedCanadianAboriginalSyllabics__internal_alias")));
+#else
+#ifndef xmlUCSIsUnifiedCanadianAboriginalSyllabics
+extern __typeof (xmlUCSIsUnifiedCanadianAboriginalSyllabics) xmlUCSIsUnifiedCanadianAboriginalSyllabics__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsUnifiedCanadianAboriginalSyllabics xmlUCSIsUnifiedCanadianAboriginalSyllabics__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsVariationSelectors
+extern __typeof (xmlUCSIsVariationSelectors) xmlUCSIsVariationSelectors __attribute((alias("xmlUCSIsVariationSelectors__internal_alias")));
+#else
+#ifndef xmlUCSIsVariationSelectors
+extern __typeof (xmlUCSIsVariationSelectors) xmlUCSIsVariationSelectors__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsVariationSelectors xmlUCSIsVariationSelectors__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsVariationSelectorsSupplement
+extern __typeof (xmlUCSIsVariationSelectorsSupplement) xmlUCSIsVariationSelectorsSupplement __attribute((alias("xmlUCSIsVariationSelectorsSupplement__internal_alias")));
+#else
+#ifndef xmlUCSIsVariationSelectorsSupplement
+extern __typeof (xmlUCSIsVariationSelectorsSupplement) xmlUCSIsVariationSelectorsSupplement__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsVariationSelectorsSupplement xmlUCSIsVariationSelectorsSupplement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsYiRadicals
+extern __typeof (xmlUCSIsYiRadicals) xmlUCSIsYiRadicals __attribute((alias("xmlUCSIsYiRadicals__internal_alias")));
+#else
+#ifndef xmlUCSIsYiRadicals
+extern __typeof (xmlUCSIsYiRadicals) xmlUCSIsYiRadicals__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsYiRadicals xmlUCSIsYiRadicals__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsYiSyllables
+extern __typeof (xmlUCSIsYiSyllables) xmlUCSIsYiSyllables __attribute((alias("xmlUCSIsYiSyllables__internal_alias")));
+#else
+#ifndef xmlUCSIsYiSyllables
+extern __typeof (xmlUCSIsYiSyllables) xmlUCSIsYiSyllables__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsYiSyllables xmlUCSIsYiSyllables__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_UNICODE_ENABLED)
+#ifdef bottom_xmlunicode
+#undef xmlUCSIsYijingHexagramSymbols
+extern __typeof (xmlUCSIsYijingHexagramSymbols) xmlUCSIsYijingHexagramSymbols __attribute((alias("xmlUCSIsYijingHexagramSymbols__internal_alias")));
+#else
+#ifndef xmlUCSIsYijingHexagramSymbols
+extern __typeof (xmlUCSIsYijingHexagramSymbols) xmlUCSIsYijingHexagramSymbols__internal_alias __attribute((visibility("hidden")));
+#define xmlUCSIsYijingHexagramSymbols xmlUCSIsYijingHexagramSymbols__internal_alias
+#endif
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlURIEscape
+extern __typeof (xmlURIEscape) xmlURIEscape __attribute((alias("xmlURIEscape__internal_alias")));
+#else
+#ifndef xmlURIEscape
+extern __typeof (xmlURIEscape) xmlURIEscape__internal_alias __attribute((visibility("hidden")));
+#define xmlURIEscape xmlURIEscape__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlURIEscapeStr
+extern __typeof (xmlURIEscapeStr) xmlURIEscapeStr __attribute((alias("xmlURIEscapeStr__internal_alias")));
+#else
+#ifndef xmlURIEscapeStr
+extern __typeof (xmlURIEscapeStr) xmlURIEscapeStr__internal_alias __attribute((visibility("hidden")));
+#define xmlURIEscapeStr xmlURIEscapeStr__internal_alias
+#endif
+#endif
+
+#ifdef bottom_uri
+#undef xmlURIUnescapeString
+extern __typeof (xmlURIUnescapeString) xmlURIUnescapeString __attribute((alias("xmlURIUnescapeString__internal_alias")));
+#else
+#ifndef xmlURIUnescapeString
+extern __typeof (xmlURIUnescapeString) xmlURIUnescapeString__internal_alias __attribute((visibility("hidden")));
+#define xmlURIUnescapeString xmlURIUnescapeString__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Charcmp
+extern __typeof (xmlUTF8Charcmp) xmlUTF8Charcmp __attribute((alias("xmlUTF8Charcmp__internal_alias")));
+#else
+#ifndef xmlUTF8Charcmp
+extern __typeof (xmlUTF8Charcmp) xmlUTF8Charcmp__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Charcmp xmlUTF8Charcmp__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Size
+extern __typeof (xmlUTF8Size) xmlUTF8Size __attribute((alias("xmlUTF8Size__internal_alias")));
+#else
+#ifndef xmlUTF8Size
+extern __typeof (xmlUTF8Size) xmlUTF8Size__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Size xmlUTF8Size__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strlen
+extern __typeof (xmlUTF8Strlen) xmlUTF8Strlen __attribute((alias("xmlUTF8Strlen__internal_alias")));
+#else
+#ifndef xmlUTF8Strlen
+extern __typeof (xmlUTF8Strlen) xmlUTF8Strlen__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strlen xmlUTF8Strlen__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strloc
+extern __typeof (xmlUTF8Strloc) xmlUTF8Strloc __attribute((alias("xmlUTF8Strloc__internal_alias")));
+#else
+#ifndef xmlUTF8Strloc
+extern __typeof (xmlUTF8Strloc) xmlUTF8Strloc__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strloc xmlUTF8Strloc__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strndup
+extern __typeof (xmlUTF8Strndup) xmlUTF8Strndup __attribute((alias("xmlUTF8Strndup__internal_alias")));
+#else
+#ifndef xmlUTF8Strndup
+extern __typeof (xmlUTF8Strndup) xmlUTF8Strndup__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strndup xmlUTF8Strndup__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strpos
+extern __typeof (xmlUTF8Strpos) xmlUTF8Strpos __attribute((alias("xmlUTF8Strpos__internal_alias")));
+#else
+#ifndef xmlUTF8Strpos
+extern __typeof (xmlUTF8Strpos) xmlUTF8Strpos__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strpos xmlUTF8Strpos__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strsize
+extern __typeof (xmlUTF8Strsize) xmlUTF8Strsize __attribute((alias("xmlUTF8Strsize__internal_alias")));
+#else
+#ifndef xmlUTF8Strsize
+extern __typeof (xmlUTF8Strsize) xmlUTF8Strsize__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strsize xmlUTF8Strsize__internal_alias
+#endif
+#endif
+
+#ifdef bottom_xmlstring
+#undef xmlUTF8Strsub
+extern __typeof (xmlUTF8Strsub) xmlUTF8Strsub __attribute((alias("xmlUTF8Strsub__internal_alias")));
+#else
+#ifndef xmlUTF8Strsub
+extern __typeof (xmlUTF8Strsub) xmlUTF8Strsub__internal_alias __attribute((visibility("hidden")));
+#define xmlUTF8Strsub xmlUTF8Strsub__internal_alias
+#endif
+#endif
+
+#ifdef bottom_tree
+#undef xmlUnlinkNode
+extern __typeof (xmlUnlinkNode) xmlUnlinkNode __attribute((alias("xmlUnlinkNode__internal_alias")));
+#else
+#ifndef xmlUnlinkNode
+extern __typeof (xmlUnlinkNode) xmlUnlinkNode__internal_alias __attribute((visibility("hidden")));
+#define xmlUnlinkNode xmlUnlinkNode__internal_alias
+#endif
+#endif
+
+#ifdef bottom_threads
+#undef xmlUnlockLibrary
+extern __typeof (xmlUnlockLibrary) xmlUnlockLibrary __attribute((alias("xmlUnlockLibrary__internal_alias")));
+#else
+#ifndef xmlUnlockLibrary
+extern __typeof (xmlUnlockLibrary) xmlUnlockLibrary__internal_alias __attribute((visibility("hidden")));
+#define xmlUnlockLibrary xmlUnlockLibrary__internal_alias
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlUnsetNsProp
+extern __typeof (xmlUnsetNsProp) xmlUnsetNsProp __attribute((alias("xmlUnsetNsProp__internal_alias")));
+#else
+#ifndef xmlUnsetNsProp
+extern __typeof (xmlUnsetNsProp) xmlUnsetNsProp__internal_alias __attribute((visibility("hidden")));
+#define xmlUnsetNsProp xmlUnsetNsProp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlUnsetProp
+extern __typeof (xmlUnsetProp) xmlUnsetProp __attribute((alias("xmlUnsetProp__internal_alias")));
+#else
+#ifndef xmlUnsetProp
+extern __typeof (xmlUnsetProp) xmlUnsetProp__internal_alias __attribute((visibility("hidden")));
+#define xmlUnsetProp xmlUnsetProp__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidBuildContentModel
+extern __typeof (xmlValidBuildContentModel) xmlValidBuildContentModel __attribute((alias("xmlValidBuildContentModel__internal_alias")));
+#else
+#ifndef xmlValidBuildContentModel
+extern __typeof (xmlValidBuildContentModel) xmlValidBuildContentModel__internal_alias __attribute((visibility("hidden")));
+#define xmlValidBuildContentModel xmlValidBuildContentModel__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidCtxtNormalizeAttributeValue
+extern __typeof (xmlValidCtxtNormalizeAttributeValue) xmlValidCtxtNormalizeAttributeValue __attribute((alias("xmlValidCtxtNormalizeAttributeValue__internal_alias")));
+#else
+#ifndef xmlValidCtxtNormalizeAttributeValue
+extern __typeof (xmlValidCtxtNormalizeAttributeValue) xmlValidCtxtNormalizeAttributeValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidCtxtNormalizeAttributeValue xmlValidCtxtNormalizeAttributeValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidGetPotentialChildren
+extern __typeof (xmlValidGetPotentialChildren) xmlValidGetPotentialChildren __attribute((alias("xmlValidGetPotentialChildren__internal_alias")));
+#else
+#ifndef xmlValidGetPotentialChildren
+extern __typeof (xmlValidGetPotentialChildren) xmlValidGetPotentialChildren__internal_alias __attribute((visibility("hidden")));
+#define xmlValidGetPotentialChildren xmlValidGetPotentialChildren__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidGetValidElements
+extern __typeof (xmlValidGetValidElements) xmlValidGetValidElements __attribute((alias("xmlValidGetValidElements__internal_alias")));
+#else
+#ifndef xmlValidGetValidElements
+extern __typeof (xmlValidGetValidElements) xmlValidGetValidElements__internal_alias __attribute((visibility("hidden")));
+#define xmlValidGetValidElements xmlValidGetValidElements__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidNormalizeAttributeValue
+extern __typeof (xmlValidNormalizeAttributeValue) xmlValidNormalizeAttributeValue __attribute((alias("xmlValidNormalizeAttributeValue__internal_alias")));
+#else
+#ifndef xmlValidNormalizeAttributeValue
+extern __typeof (xmlValidNormalizeAttributeValue) xmlValidNormalizeAttributeValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidNormalizeAttributeValue xmlValidNormalizeAttributeValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateAttributeDecl
+extern __typeof (xmlValidateAttributeDecl) xmlValidateAttributeDecl __attribute((alias("xmlValidateAttributeDecl__internal_alias")));
+#else
+#ifndef xmlValidateAttributeDecl
+extern __typeof (xmlValidateAttributeDecl) xmlValidateAttributeDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateAttributeDecl xmlValidateAttributeDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateAttributeValue
+extern __typeof (xmlValidateAttributeValue) xmlValidateAttributeValue __attribute((alias("xmlValidateAttributeValue__internal_alias")));
+#else
+#ifndef xmlValidateAttributeValue
+extern __typeof (xmlValidateAttributeValue) xmlValidateAttributeValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateAttributeValue xmlValidateAttributeValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateDocument
+extern __typeof (xmlValidateDocument) xmlValidateDocument __attribute((alias("xmlValidateDocument__internal_alias")));
+#else
+#ifndef xmlValidateDocument
+extern __typeof (xmlValidateDocument) xmlValidateDocument__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateDocument xmlValidateDocument__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateDocumentFinal
+extern __typeof (xmlValidateDocumentFinal) xmlValidateDocumentFinal __attribute((alias("xmlValidateDocumentFinal__internal_alias")));
+#else
+#ifndef xmlValidateDocumentFinal
+extern __typeof (xmlValidateDocumentFinal) xmlValidateDocumentFinal__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateDocumentFinal xmlValidateDocumentFinal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateDtd
+extern __typeof (xmlValidateDtd) xmlValidateDtd __attribute((alias("xmlValidateDtd__internal_alias")));
+#else
+#ifndef xmlValidateDtd
+extern __typeof (xmlValidateDtd) xmlValidateDtd__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateDtd xmlValidateDtd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateDtdFinal
+extern __typeof (xmlValidateDtdFinal) xmlValidateDtdFinal __attribute((alias("xmlValidateDtdFinal__internal_alias")));
+#else
+#ifndef xmlValidateDtdFinal
+extern __typeof (xmlValidateDtdFinal) xmlValidateDtdFinal__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateDtdFinal xmlValidateDtdFinal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateElement
+extern __typeof (xmlValidateElement) xmlValidateElement __attribute((alias("xmlValidateElement__internal_alias")));
+#else
+#ifndef xmlValidateElement
+extern __typeof (xmlValidateElement) xmlValidateElement__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateElement xmlValidateElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateElementDecl
+extern __typeof (xmlValidateElementDecl) xmlValidateElementDecl __attribute((alias("xmlValidateElementDecl__internal_alias")));
+#else
+#ifndef xmlValidateElementDecl
+extern __typeof (xmlValidateElementDecl) xmlValidateElementDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateElementDecl xmlValidateElementDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef bottom_tree
+#undef xmlValidateNCName
+extern __typeof (xmlValidateNCName) xmlValidateNCName __attribute((alias("xmlValidateNCName__internal_alias")));
+#else
+#ifndef xmlValidateNCName
+extern __typeof (xmlValidateNCName) xmlValidateNCName__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNCName xmlValidateNCName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlValidateNMToken
+extern __typeof (xmlValidateNMToken) xmlValidateNMToken __attribute((alias("xmlValidateNMToken__internal_alias")));
+#else
+#ifndef xmlValidateNMToken
+extern __typeof (xmlValidateNMToken) xmlValidateNMToken__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNMToken xmlValidateNMToken__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlValidateName
+extern __typeof (xmlValidateName) xmlValidateName __attribute((alias("xmlValidateName__internal_alias")));
+#else
+#ifndef xmlValidateName
+extern __typeof (xmlValidateName) xmlValidateName__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateName xmlValidateName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNameValue
+extern __typeof (xmlValidateNameValue) xmlValidateNameValue __attribute((alias("xmlValidateNameValue__internal_alias")));
+#else
+#ifndef xmlValidateNameValue
+extern __typeof (xmlValidateNameValue) xmlValidateNameValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNameValue xmlValidateNameValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNamesValue
+extern __typeof (xmlValidateNamesValue) xmlValidateNamesValue __attribute((alias("xmlValidateNamesValue__internal_alias")));
+#else
+#ifndef xmlValidateNamesValue
+extern __typeof (xmlValidateNamesValue) xmlValidateNamesValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNamesValue xmlValidateNamesValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNmtokenValue
+extern __typeof (xmlValidateNmtokenValue) xmlValidateNmtokenValue __attribute((alias("xmlValidateNmtokenValue__internal_alias")));
+#else
+#ifndef xmlValidateNmtokenValue
+extern __typeof (xmlValidateNmtokenValue) xmlValidateNmtokenValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNmtokenValue xmlValidateNmtokenValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNmtokensValue
+extern __typeof (xmlValidateNmtokensValue) xmlValidateNmtokensValue __attribute((alias("xmlValidateNmtokensValue__internal_alias")));
+#else
+#ifndef xmlValidateNmtokensValue
+extern __typeof (xmlValidateNmtokensValue) xmlValidateNmtokensValue__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNmtokensValue xmlValidateNmtokensValue__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNotationDecl
+extern __typeof (xmlValidateNotationDecl) xmlValidateNotationDecl __attribute((alias("xmlValidateNotationDecl__internal_alias")));
+#else
+#ifndef xmlValidateNotationDecl
+extern __typeof (xmlValidateNotationDecl) xmlValidateNotationDecl__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNotationDecl xmlValidateNotationDecl__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateNotationUse
+extern __typeof (xmlValidateNotationUse) xmlValidateNotationUse __attribute((alias("xmlValidateNotationUse__internal_alias")));
+#else
+#ifndef xmlValidateNotationUse
+extern __typeof (xmlValidateNotationUse) xmlValidateNotationUse__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateNotationUse xmlValidateNotationUse__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateOneAttribute
+extern __typeof (xmlValidateOneAttribute) xmlValidateOneAttribute __attribute((alias("xmlValidateOneAttribute__internal_alias")));
+#else
+#ifndef xmlValidateOneAttribute
+extern __typeof (xmlValidateOneAttribute) xmlValidateOneAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateOneAttribute xmlValidateOneAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateOneElement
+extern __typeof (xmlValidateOneElement) xmlValidateOneElement __attribute((alias("xmlValidateOneElement__internal_alias")));
+#else
+#ifndef xmlValidateOneElement
+extern __typeof (xmlValidateOneElement) xmlValidateOneElement__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateOneElement xmlValidateOneElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateOneNamespace
+extern __typeof (xmlValidateOneNamespace) xmlValidateOneNamespace __attribute((alias("xmlValidateOneNamespace__internal_alias")));
+#else
+#ifndef xmlValidateOneNamespace
+extern __typeof (xmlValidateOneNamespace) xmlValidateOneNamespace__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateOneNamespace xmlValidateOneNamespace__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidatePopElement
+extern __typeof (xmlValidatePopElement) xmlValidatePopElement __attribute((alias("xmlValidatePopElement__internal_alias")));
+#else
+#ifndef xmlValidatePopElement
+extern __typeof (xmlValidatePopElement) xmlValidatePopElement__internal_alias __attribute((visibility("hidden")));
+#define xmlValidatePopElement xmlValidatePopElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidatePushCData
+extern __typeof (xmlValidatePushCData) xmlValidatePushCData __attribute((alias("xmlValidatePushCData__internal_alias")));
+#else
+#ifndef xmlValidatePushCData
+extern __typeof (xmlValidatePushCData) xmlValidatePushCData__internal_alias __attribute((visibility("hidden")));
+#define xmlValidatePushCData xmlValidatePushCData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidatePushElement
+extern __typeof (xmlValidatePushElement) xmlValidatePushElement __attribute((alias("xmlValidatePushElement__internal_alias")));
+#else
+#ifndef xmlValidatePushElement
+extern __typeof (xmlValidatePushElement) xmlValidatePushElement__internal_alias __attribute((visibility("hidden")));
+#define xmlValidatePushElement xmlValidatePushElement__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_tree
+#undef xmlValidateQName
+extern __typeof (xmlValidateQName) xmlValidateQName __attribute((alias("xmlValidateQName__internal_alias")));
+#else
+#ifndef xmlValidateQName
+extern __typeof (xmlValidateQName) xmlValidateQName__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateQName xmlValidateQName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef bottom_valid
+#undef xmlValidateRoot
+extern __typeof (xmlValidateRoot) xmlValidateRoot __attribute((alias("xmlValidateRoot__internal_alias")));
+#else
+#ifndef xmlValidateRoot
+extern __typeof (xmlValidateRoot) xmlValidateRoot__internal_alias __attribute((visibility("hidden")));
+#define xmlValidateRoot xmlValidateRoot__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeFreeContext
+extern __typeof (xmlXIncludeFreeContext) xmlXIncludeFreeContext __attribute((alias("xmlXIncludeFreeContext__internal_alias")));
+#else
+#ifndef xmlXIncludeFreeContext
+extern __typeof (xmlXIncludeFreeContext) xmlXIncludeFreeContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeFreeContext xmlXIncludeFreeContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeNewContext
+extern __typeof (xmlXIncludeNewContext) xmlXIncludeNewContext __attribute((alias("xmlXIncludeNewContext__internal_alias")));
+#else
+#ifndef xmlXIncludeNewContext
+extern __typeof (xmlXIncludeNewContext) xmlXIncludeNewContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeNewContext xmlXIncludeNewContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcess
+extern __typeof (xmlXIncludeProcess) xmlXIncludeProcess __attribute((alias("xmlXIncludeProcess__internal_alias")));
+#else
+#ifndef xmlXIncludeProcess
+extern __typeof (xmlXIncludeProcess) xmlXIncludeProcess__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcess xmlXIncludeProcess__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcessFlags
+extern __typeof (xmlXIncludeProcessFlags) xmlXIncludeProcessFlags __attribute((alias("xmlXIncludeProcessFlags__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessFlags
+extern __typeof (xmlXIncludeProcessFlags) xmlXIncludeProcessFlags__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessFlags xmlXIncludeProcessFlags__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcessFlagsData
+extern __typeof (xmlXIncludeProcessFlagsData) xmlXIncludeProcessFlagsData __attribute((alias("xmlXIncludeProcessFlagsData__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessFlagsData
+extern __typeof (xmlXIncludeProcessFlagsData) xmlXIncludeProcessFlagsData__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessFlagsData xmlXIncludeProcessFlagsData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcessNode
+extern __typeof (xmlXIncludeProcessNode) xmlXIncludeProcessNode __attribute((alias("xmlXIncludeProcessNode__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessNode
+extern __typeof (xmlXIncludeProcessNode) xmlXIncludeProcessNode__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessNode xmlXIncludeProcessNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcessTree
+extern __typeof (xmlXIncludeProcessTree) xmlXIncludeProcessTree __attribute((alias("xmlXIncludeProcessTree__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessTree
+extern __typeof (xmlXIncludeProcessTree) xmlXIncludeProcessTree__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessTree xmlXIncludeProcessTree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
+#undef xmlXIncludeProcessTreeFlags
+extern __typeof (xmlXIncludeProcessTreeFlags) xmlXIncludeProcessTreeFlags __attribute((alias("xmlXIncludeProcessTreeFlags__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessTreeFlags
+extern __typeof (xmlXIncludeProcessTreeFlags) xmlXIncludeProcessTreeFlags__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessTreeFlags xmlXIncludeProcessTreeFlags__internal_alias
+#endif
+#endif
+#endif
+
+#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
+#ifndef xmlXIncludeSetFlags
+extern __typeof (xmlXIncludeSetFlags) xmlXIncludeSetFlags__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeSetFlags xmlXIncludeSetFlags__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathAddValues
+extern __typeof (xmlXPathAddValues) xmlXPathAddValues __attribute((alias("xmlXPathAddValues__internal_alias")));
+#else
+#ifndef xmlXPathAddValues
+extern __typeof (xmlXPathAddValues) xmlXPathAddValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathAddValues xmlXPathAddValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathBooleanFunction
+extern __typeof (xmlXPathBooleanFunction) xmlXPathBooleanFunction __attribute((alias("xmlXPathBooleanFunction__internal_alias")));
+#else
+#ifndef xmlXPathBooleanFunction
+extern __typeof (xmlXPathBooleanFunction) xmlXPathBooleanFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathBooleanFunction xmlXPathBooleanFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastBooleanToNumber
+extern __typeof (xmlXPathCastBooleanToNumber) xmlXPathCastBooleanToNumber __attribute((alias("xmlXPathCastBooleanToNumber__internal_alias")));
+#else
+#ifndef xmlXPathCastBooleanToNumber
+extern __typeof (xmlXPathCastBooleanToNumber) xmlXPathCastBooleanToNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastBooleanToNumber xmlXPathCastBooleanToNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastBooleanToString
+extern __typeof (xmlXPathCastBooleanToString) xmlXPathCastBooleanToString __attribute((alias("xmlXPathCastBooleanToString__internal_alias")));
+#else
+#ifndef xmlXPathCastBooleanToString
+extern __typeof (xmlXPathCastBooleanToString) xmlXPathCastBooleanToString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastBooleanToString xmlXPathCastBooleanToString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNodeSetToBoolean
+extern __typeof (xmlXPathCastNodeSetToBoolean) xmlXPathCastNodeSetToBoolean __attribute((alias("xmlXPathCastNodeSetToBoolean__internal_alias")));
+#else
+#ifndef xmlXPathCastNodeSetToBoolean
+extern __typeof (xmlXPathCastNodeSetToBoolean) xmlXPathCastNodeSetToBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNodeSetToBoolean xmlXPathCastNodeSetToBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNodeSetToNumber
+extern __typeof (xmlXPathCastNodeSetToNumber) xmlXPathCastNodeSetToNumber __attribute((alias("xmlXPathCastNodeSetToNumber__internal_alias")));
+#else
+#ifndef xmlXPathCastNodeSetToNumber
+extern __typeof (xmlXPathCastNodeSetToNumber) xmlXPathCastNodeSetToNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNodeSetToNumber xmlXPathCastNodeSetToNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNodeSetToString
+extern __typeof (xmlXPathCastNodeSetToString) xmlXPathCastNodeSetToString __attribute((alias("xmlXPathCastNodeSetToString__internal_alias")));
+#else
+#ifndef xmlXPathCastNodeSetToString
+extern __typeof (xmlXPathCastNodeSetToString) xmlXPathCastNodeSetToString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNodeSetToString xmlXPathCastNodeSetToString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNodeToNumber
+extern __typeof (xmlXPathCastNodeToNumber) xmlXPathCastNodeToNumber __attribute((alias("xmlXPathCastNodeToNumber__internal_alias")));
+#else
+#ifndef xmlXPathCastNodeToNumber
+extern __typeof (xmlXPathCastNodeToNumber) xmlXPathCastNodeToNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNodeToNumber xmlXPathCastNodeToNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNodeToString
+extern __typeof (xmlXPathCastNodeToString) xmlXPathCastNodeToString __attribute((alias("xmlXPathCastNodeToString__internal_alias")));
+#else
+#ifndef xmlXPathCastNodeToString
+extern __typeof (xmlXPathCastNodeToString) xmlXPathCastNodeToString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNodeToString xmlXPathCastNodeToString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNumberToBoolean
+extern __typeof (xmlXPathCastNumberToBoolean) xmlXPathCastNumberToBoolean __attribute((alias("xmlXPathCastNumberToBoolean__internal_alias")));
+#else
+#ifndef xmlXPathCastNumberToBoolean
+extern __typeof (xmlXPathCastNumberToBoolean) xmlXPathCastNumberToBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNumberToBoolean xmlXPathCastNumberToBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastNumberToString
+extern __typeof (xmlXPathCastNumberToString) xmlXPathCastNumberToString __attribute((alias("xmlXPathCastNumberToString__internal_alias")));
+#else
+#ifndef xmlXPathCastNumberToString
+extern __typeof (xmlXPathCastNumberToString) xmlXPathCastNumberToString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastNumberToString xmlXPathCastNumberToString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastStringToBoolean
+extern __typeof (xmlXPathCastStringToBoolean) xmlXPathCastStringToBoolean __attribute((alias("xmlXPathCastStringToBoolean__internal_alias")));
+#else
+#ifndef xmlXPathCastStringToBoolean
+extern __typeof (xmlXPathCastStringToBoolean) xmlXPathCastStringToBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastStringToBoolean xmlXPathCastStringToBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastStringToNumber
+extern __typeof (xmlXPathCastStringToNumber) xmlXPathCastStringToNumber __attribute((alias("xmlXPathCastStringToNumber__internal_alias")));
+#else
+#ifndef xmlXPathCastStringToNumber
+extern __typeof (xmlXPathCastStringToNumber) xmlXPathCastStringToNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastStringToNumber xmlXPathCastStringToNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastToBoolean
+extern __typeof (xmlXPathCastToBoolean) xmlXPathCastToBoolean __attribute((alias("xmlXPathCastToBoolean__internal_alias")));
+#else
+#ifndef xmlXPathCastToBoolean
+extern __typeof (xmlXPathCastToBoolean) xmlXPathCastToBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastToBoolean xmlXPathCastToBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastToNumber
+extern __typeof (xmlXPathCastToNumber) xmlXPathCastToNumber __attribute((alias("xmlXPathCastToNumber__internal_alias")));
+#else
+#ifndef xmlXPathCastToNumber
+extern __typeof (xmlXPathCastToNumber) xmlXPathCastToNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastToNumber xmlXPathCastToNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCastToString
+extern __typeof (xmlXPathCastToString) xmlXPathCastToString __attribute((alias("xmlXPathCastToString__internal_alias")));
+#else
+#ifndef xmlXPathCastToString
+extern __typeof (xmlXPathCastToString) xmlXPathCastToString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCastToString xmlXPathCastToString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCeilingFunction
+extern __typeof (xmlXPathCeilingFunction) xmlXPathCeilingFunction __attribute((alias("xmlXPathCeilingFunction__internal_alias")));
+#else
+#ifndef xmlXPathCeilingFunction
+extern __typeof (xmlXPathCeilingFunction) xmlXPathCeilingFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCeilingFunction xmlXPathCeilingFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCmpNodes
+extern __typeof (xmlXPathCmpNodes) xmlXPathCmpNodes __attribute((alias("xmlXPathCmpNodes__internal_alias")));
+#else
+#ifndef xmlXPathCmpNodes
+extern __typeof (xmlXPathCmpNodes) xmlXPathCmpNodes__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCmpNodes xmlXPathCmpNodes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCompareValues
+extern __typeof (xmlXPathCompareValues) xmlXPathCompareValues __attribute((alias("xmlXPathCompareValues__internal_alias")));
+#else
+#ifndef xmlXPathCompareValues
+extern __typeof (xmlXPathCompareValues) xmlXPathCompareValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCompareValues xmlXPathCompareValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCompile
+extern __typeof (xmlXPathCompile) xmlXPathCompile __attribute((alias("xmlXPathCompile__internal_alias")));
+#else
+#ifndef xmlXPathCompile
+extern __typeof (xmlXPathCompile) xmlXPathCompile__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCompile xmlXPathCompile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCompiledEval
+extern __typeof (xmlXPathCompiledEval) xmlXPathCompiledEval __attribute((alias("xmlXPathCompiledEval__internal_alias")));
+#else
+#ifndef xmlXPathCompiledEval
+extern __typeof (xmlXPathCompiledEval) xmlXPathCompiledEval__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCompiledEval xmlXPathCompiledEval__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCompiledEvalToBoolean
+extern __typeof (xmlXPathCompiledEvalToBoolean) xmlXPathCompiledEvalToBoolean __attribute((alias("xmlXPathCompiledEvalToBoolean__internal_alias")));
+#else
+#ifndef xmlXPathCompiledEvalToBoolean
+extern __typeof (xmlXPathCompiledEvalToBoolean) xmlXPathCompiledEvalToBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCompiledEvalToBoolean xmlXPathCompiledEvalToBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathConcatFunction
+extern __typeof (xmlXPathConcatFunction) xmlXPathConcatFunction __attribute((alias("xmlXPathConcatFunction__internal_alias")));
+#else
+#ifndef xmlXPathConcatFunction
+extern __typeof (xmlXPathConcatFunction) xmlXPathConcatFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathConcatFunction xmlXPathConcatFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathContainsFunction
+extern __typeof (xmlXPathContainsFunction) xmlXPathContainsFunction __attribute((alias("xmlXPathContainsFunction__internal_alias")));
+#else
+#ifndef xmlXPathContainsFunction
+extern __typeof (xmlXPathContainsFunction) xmlXPathContainsFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathContainsFunction xmlXPathContainsFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathContextSetCache
+extern __typeof (xmlXPathContextSetCache) xmlXPathContextSetCache __attribute((alias("xmlXPathContextSetCache__internal_alias")));
+#else
+#ifndef xmlXPathContextSetCache
+extern __typeof (xmlXPathContextSetCache) xmlXPathContextSetCache__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathContextSetCache xmlXPathContextSetCache__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathConvertBoolean
+extern __typeof (xmlXPathConvertBoolean) xmlXPathConvertBoolean __attribute((alias("xmlXPathConvertBoolean__internal_alias")));
+#else
+#ifndef xmlXPathConvertBoolean
+extern __typeof (xmlXPathConvertBoolean) xmlXPathConvertBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathConvertBoolean xmlXPathConvertBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathConvertNumber
+extern __typeof (xmlXPathConvertNumber) xmlXPathConvertNumber __attribute((alias("xmlXPathConvertNumber__internal_alias")));
+#else
+#ifndef xmlXPathConvertNumber
+extern __typeof (xmlXPathConvertNumber) xmlXPathConvertNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathConvertNumber xmlXPathConvertNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathConvertString
+extern __typeof (xmlXPathConvertString) xmlXPathConvertString __attribute((alias("xmlXPathConvertString__internal_alias")));
+#else
+#ifndef xmlXPathConvertString
+extern __typeof (xmlXPathConvertString) xmlXPathConvertString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathConvertString xmlXPathConvertString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCountFunction
+extern __typeof (xmlXPathCountFunction) xmlXPathCountFunction __attribute((alias("xmlXPathCountFunction__internal_alias")));
+#else
+#ifndef xmlXPathCountFunction
+extern __typeof (xmlXPathCountFunction) xmlXPathCountFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCountFunction xmlXPathCountFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathCtxtCompile
+extern __typeof (xmlXPathCtxtCompile) xmlXPathCtxtCompile __attribute((alias("xmlXPathCtxtCompile__internal_alias")));
+#else
+#ifndef xmlXPathCtxtCompile
+extern __typeof (xmlXPathCtxtCompile) xmlXPathCtxtCompile__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathCtxtCompile xmlXPathCtxtCompile__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDebugDumpCompExpr
+extern __typeof (xmlXPathDebugDumpCompExpr) xmlXPathDebugDumpCompExpr __attribute((alias("xmlXPathDebugDumpCompExpr__internal_alias")));
+#else
+#ifndef xmlXPathDebugDumpCompExpr
+extern __typeof (xmlXPathDebugDumpCompExpr) xmlXPathDebugDumpCompExpr__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDebugDumpCompExpr xmlXPathDebugDumpCompExpr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDebugDumpObject
+extern __typeof (xmlXPathDebugDumpObject) xmlXPathDebugDumpObject __attribute((alias("xmlXPathDebugDumpObject__internal_alias")));
+#else
+#ifndef xmlXPathDebugDumpObject
+extern __typeof (xmlXPathDebugDumpObject) xmlXPathDebugDumpObject__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDebugDumpObject xmlXPathDebugDumpObject__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDifference
+extern __typeof (xmlXPathDifference) xmlXPathDifference __attribute((alias("xmlXPathDifference__internal_alias")));
+#else
+#ifndef xmlXPathDifference
+extern __typeof (xmlXPathDifference) xmlXPathDifference__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDifference xmlXPathDifference__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDistinct
+extern __typeof (xmlXPathDistinct) xmlXPathDistinct __attribute((alias("xmlXPathDistinct__internal_alias")));
+#else
+#ifndef xmlXPathDistinct
+extern __typeof (xmlXPathDistinct) xmlXPathDistinct__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDistinct xmlXPathDistinct__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDistinctSorted
+extern __typeof (xmlXPathDistinctSorted) xmlXPathDistinctSorted __attribute((alias("xmlXPathDistinctSorted__internal_alias")));
+#else
+#ifndef xmlXPathDistinctSorted
+extern __typeof (xmlXPathDistinctSorted) xmlXPathDistinctSorted__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDistinctSorted xmlXPathDistinctSorted__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathDivValues
+extern __typeof (xmlXPathDivValues) xmlXPathDivValues __attribute((alias("xmlXPathDivValues__internal_alias")));
+#else
+#ifndef xmlXPathDivValues
+extern __typeof (xmlXPathDivValues) xmlXPathDivValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathDivValues xmlXPathDivValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEqualValues
+extern __typeof (xmlXPathEqualValues) xmlXPathEqualValues __attribute((alias("xmlXPathEqualValues__internal_alias")));
+#else
+#ifndef xmlXPathEqualValues
+extern __typeof (xmlXPathEqualValues) xmlXPathEqualValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEqualValues xmlXPathEqualValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathErr
+extern __typeof (xmlXPathErr) xmlXPathErr __attribute((alias("xmlXPathErr__internal_alias")));
+#else
+#ifndef xmlXPathErr
+extern __typeof (xmlXPathErr) xmlXPathErr__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathErr xmlXPathErr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEval
+extern __typeof (xmlXPathEval) xmlXPathEval __attribute((alias("xmlXPathEval__internal_alias")));
+#else
+#ifndef xmlXPathEval
+extern __typeof (xmlXPathEval) xmlXPathEval__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEval xmlXPathEval__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEvalExpr
+extern __typeof (xmlXPathEvalExpr) xmlXPathEvalExpr __attribute((alias("xmlXPathEvalExpr__internal_alias")));
+#else
+#ifndef xmlXPathEvalExpr
+extern __typeof (xmlXPathEvalExpr) xmlXPathEvalExpr__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEvalExpr xmlXPathEvalExpr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEvalExpression
+extern __typeof (xmlXPathEvalExpression) xmlXPathEvalExpression __attribute((alias("xmlXPathEvalExpression__internal_alias")));
+#else
+#ifndef xmlXPathEvalExpression
+extern __typeof (xmlXPathEvalExpression) xmlXPathEvalExpression__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEvalExpression xmlXPathEvalExpression__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEvalPredicate
+extern __typeof (xmlXPathEvalPredicate) xmlXPathEvalPredicate __attribute((alias("xmlXPathEvalPredicate__internal_alias")));
+#else
+#ifndef xmlXPathEvalPredicate
+extern __typeof (xmlXPathEvalPredicate) xmlXPathEvalPredicate__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEvalPredicate xmlXPathEvalPredicate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathEvaluatePredicateResult
+extern __typeof (xmlXPathEvaluatePredicateResult) xmlXPathEvaluatePredicateResult __attribute((alias("xmlXPathEvaluatePredicateResult__internal_alias")));
+#else
+#ifndef xmlXPathEvaluatePredicateResult
+extern __typeof (xmlXPathEvaluatePredicateResult) xmlXPathEvaluatePredicateResult__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathEvaluatePredicateResult xmlXPathEvaluatePredicateResult__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFalseFunction
+extern __typeof (xmlXPathFalseFunction) xmlXPathFalseFunction __attribute((alias("xmlXPathFalseFunction__internal_alias")));
+#else
+#ifndef xmlXPathFalseFunction
+extern __typeof (xmlXPathFalseFunction) xmlXPathFalseFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFalseFunction xmlXPathFalseFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFloorFunction
+extern __typeof (xmlXPathFloorFunction) xmlXPathFloorFunction __attribute((alias("xmlXPathFloorFunction__internal_alias")));
+#else
+#ifndef xmlXPathFloorFunction
+extern __typeof (xmlXPathFloorFunction) xmlXPathFloorFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFloorFunction xmlXPathFloorFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeCompExpr
+extern __typeof (xmlXPathFreeCompExpr) xmlXPathFreeCompExpr __attribute((alias("xmlXPathFreeCompExpr__internal_alias")));
+#else
+#ifndef xmlXPathFreeCompExpr
+extern __typeof (xmlXPathFreeCompExpr) xmlXPathFreeCompExpr__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeCompExpr xmlXPathFreeCompExpr__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeContext
+extern __typeof (xmlXPathFreeContext) xmlXPathFreeContext __attribute((alias("xmlXPathFreeContext__internal_alias")));
+#else
+#ifndef xmlXPathFreeContext
+extern __typeof (xmlXPathFreeContext) xmlXPathFreeContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeContext xmlXPathFreeContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeNodeSet
+extern __typeof (xmlXPathFreeNodeSet) xmlXPathFreeNodeSet __attribute((alias("xmlXPathFreeNodeSet__internal_alias")));
+#else
+#ifndef xmlXPathFreeNodeSet
+extern __typeof (xmlXPathFreeNodeSet) xmlXPathFreeNodeSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeNodeSet xmlXPathFreeNodeSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeNodeSetList
+extern __typeof (xmlXPathFreeNodeSetList) xmlXPathFreeNodeSetList __attribute((alias("xmlXPathFreeNodeSetList__internal_alias")));
+#else
+#ifndef xmlXPathFreeNodeSetList
+extern __typeof (xmlXPathFreeNodeSetList) xmlXPathFreeNodeSetList__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeNodeSetList xmlXPathFreeNodeSetList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeObject
+extern __typeof (xmlXPathFreeObject) xmlXPathFreeObject __attribute((alias("xmlXPathFreeObject__internal_alias")));
+#else
+#ifndef xmlXPathFreeObject
+extern __typeof (xmlXPathFreeObject) xmlXPathFreeObject__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeObject xmlXPathFreeObject__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFreeParserContext
+extern __typeof (xmlXPathFreeParserContext) xmlXPathFreeParserContext __attribute((alias("xmlXPathFreeParserContext__internal_alias")));
+#else
+#ifndef xmlXPathFreeParserContext
+extern __typeof (xmlXPathFreeParserContext) xmlXPathFreeParserContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFreeParserContext xmlXPathFreeParserContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFunctionLookup
+extern __typeof (xmlXPathFunctionLookup) xmlXPathFunctionLookup __attribute((alias("xmlXPathFunctionLookup__internal_alias")));
+#else
+#ifndef xmlXPathFunctionLookup
+extern __typeof (xmlXPathFunctionLookup) xmlXPathFunctionLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFunctionLookup xmlXPathFunctionLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathFunctionLookupNS
+extern __typeof (xmlXPathFunctionLookupNS) xmlXPathFunctionLookupNS __attribute((alias("xmlXPathFunctionLookupNS__internal_alias")));
+#else
+#ifndef xmlXPathFunctionLookupNS
+extern __typeof (xmlXPathFunctionLookupNS) xmlXPathFunctionLookupNS__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathFunctionLookupNS xmlXPathFunctionLookupNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathHasSameNodes
+extern __typeof (xmlXPathHasSameNodes) xmlXPathHasSameNodes __attribute((alias("xmlXPathHasSameNodes__internal_alias")));
+#else
+#ifndef xmlXPathHasSameNodes
+extern __typeof (xmlXPathHasSameNodes) xmlXPathHasSameNodes__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathHasSameNodes xmlXPathHasSameNodes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathIdFunction
+extern __typeof (xmlXPathIdFunction) xmlXPathIdFunction __attribute((alias("xmlXPathIdFunction__internal_alias")));
+#else
+#ifndef xmlXPathIdFunction
+extern __typeof (xmlXPathIdFunction) xmlXPathIdFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathIdFunction xmlXPathIdFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathInit
+extern __typeof (xmlXPathInit) xmlXPathInit __attribute((alias("xmlXPathInit__internal_alias")));
+#else
+#ifndef xmlXPathInit
+extern __typeof (xmlXPathInit) xmlXPathInit__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathInit xmlXPathInit__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathIntersection
+extern __typeof (xmlXPathIntersection) xmlXPathIntersection __attribute((alias("xmlXPathIntersection__internal_alias")));
+#else
+#ifndef xmlXPathIntersection
+extern __typeof (xmlXPathIntersection) xmlXPathIntersection__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathIntersection xmlXPathIntersection__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathIsInf
+extern __typeof (xmlXPathIsInf) xmlXPathIsInf __attribute((alias("xmlXPathIsInf__internal_alias")));
+#else
+#ifndef xmlXPathIsInf
+extern __typeof (xmlXPathIsInf) xmlXPathIsInf__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathIsInf xmlXPathIsInf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathIsNaN
+extern __typeof (xmlXPathIsNaN) xmlXPathIsNaN __attribute((alias("xmlXPathIsNaN__internal_alias")));
+#else
+#ifndef xmlXPathIsNaN
+extern __typeof (xmlXPathIsNaN) xmlXPathIsNaN__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathIsNaN xmlXPathIsNaN__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathIsNodeType
+extern __typeof (xmlXPathIsNodeType) xmlXPathIsNodeType __attribute((alias("xmlXPathIsNodeType__internal_alias")));
+#else
+#ifndef xmlXPathIsNodeType
+extern __typeof (xmlXPathIsNodeType) xmlXPathIsNodeType__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathIsNodeType xmlXPathIsNodeType__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathLangFunction
+extern __typeof (xmlXPathLangFunction) xmlXPathLangFunction __attribute((alias("xmlXPathLangFunction__internal_alias")));
+#else
+#ifndef xmlXPathLangFunction
+extern __typeof (xmlXPathLangFunction) xmlXPathLangFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathLangFunction xmlXPathLangFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathLastFunction
+extern __typeof (xmlXPathLastFunction) xmlXPathLastFunction __attribute((alias("xmlXPathLastFunction__internal_alias")));
+#else
+#ifndef xmlXPathLastFunction
+extern __typeof (xmlXPathLastFunction) xmlXPathLastFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathLastFunction xmlXPathLastFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathLeading
+extern __typeof (xmlXPathLeading) xmlXPathLeading __attribute((alias("xmlXPathLeading__internal_alias")));
+#else
+#ifndef xmlXPathLeading
+extern __typeof (xmlXPathLeading) xmlXPathLeading__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathLeading xmlXPathLeading__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathLeadingSorted
+extern __typeof (xmlXPathLeadingSorted) xmlXPathLeadingSorted __attribute((alias("xmlXPathLeadingSorted__internal_alias")));
+#else
+#ifndef xmlXPathLeadingSorted
+extern __typeof (xmlXPathLeadingSorted) xmlXPathLeadingSorted__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathLeadingSorted xmlXPathLeadingSorted__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathLocalNameFunction
+extern __typeof (xmlXPathLocalNameFunction) xmlXPathLocalNameFunction __attribute((alias("xmlXPathLocalNameFunction__internal_alias")));
+#else
+#ifndef xmlXPathLocalNameFunction
+extern __typeof (xmlXPathLocalNameFunction) xmlXPathLocalNameFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathLocalNameFunction xmlXPathLocalNameFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathModValues
+extern __typeof (xmlXPathModValues) xmlXPathModValues __attribute((alias("xmlXPathModValues__internal_alias")));
+#else
+#ifndef xmlXPathModValues
+extern __typeof (xmlXPathModValues) xmlXPathModValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathModValues xmlXPathModValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathMultValues
+extern __typeof (xmlXPathMultValues) xmlXPathMultValues __attribute((alias("xmlXPathMultValues__internal_alias")));
+#else
+#ifndef xmlXPathMultValues
+extern __typeof (xmlXPathMultValues) xmlXPathMultValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathMultValues xmlXPathMultValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNamespaceURIFunction
+extern __typeof (xmlXPathNamespaceURIFunction) xmlXPathNamespaceURIFunction __attribute((alias("xmlXPathNamespaceURIFunction__internal_alias")));
+#else
+#ifndef xmlXPathNamespaceURIFunction
+extern __typeof (xmlXPathNamespaceURIFunction) xmlXPathNamespaceURIFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNamespaceURIFunction xmlXPathNamespaceURIFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewBoolean
+extern __typeof (xmlXPathNewBoolean) xmlXPathNewBoolean __attribute((alias("xmlXPathNewBoolean__internal_alias")));
+#else
+#ifndef xmlXPathNewBoolean
+extern __typeof (xmlXPathNewBoolean) xmlXPathNewBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewBoolean xmlXPathNewBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewCString
+extern __typeof (xmlXPathNewCString) xmlXPathNewCString __attribute((alias("xmlXPathNewCString__internal_alias")));
+#else
+#ifndef xmlXPathNewCString
+extern __typeof (xmlXPathNewCString) xmlXPathNewCString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewCString xmlXPathNewCString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewContext
+extern __typeof (xmlXPathNewContext) xmlXPathNewContext __attribute((alias("xmlXPathNewContext__internal_alias")));
+#else
+#ifndef xmlXPathNewContext
+extern __typeof (xmlXPathNewContext) xmlXPathNewContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewContext xmlXPathNewContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewFloat
+extern __typeof (xmlXPathNewFloat) xmlXPathNewFloat __attribute((alias("xmlXPathNewFloat__internal_alias")));
+#else
+#ifndef xmlXPathNewFloat
+extern __typeof (xmlXPathNewFloat) xmlXPathNewFloat__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewFloat xmlXPathNewFloat__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewNodeSet
+extern __typeof (xmlXPathNewNodeSet) xmlXPathNewNodeSet __attribute((alias("xmlXPathNewNodeSet__internal_alias")));
+#else
+#ifndef xmlXPathNewNodeSet
+extern __typeof (xmlXPathNewNodeSet) xmlXPathNewNodeSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewNodeSet xmlXPathNewNodeSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewNodeSetList
+extern __typeof (xmlXPathNewNodeSetList) xmlXPathNewNodeSetList __attribute((alias("xmlXPathNewNodeSetList__internal_alias")));
+#else
+#ifndef xmlXPathNewNodeSetList
+extern __typeof (xmlXPathNewNodeSetList) xmlXPathNewNodeSetList__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewNodeSetList xmlXPathNewNodeSetList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewParserContext
+extern __typeof (xmlXPathNewParserContext) xmlXPathNewParserContext __attribute((alias("xmlXPathNewParserContext__internal_alias")));
+#else
+#ifndef xmlXPathNewParserContext
+extern __typeof (xmlXPathNewParserContext) xmlXPathNewParserContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewParserContext xmlXPathNewParserContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewString
+extern __typeof (xmlXPathNewString) xmlXPathNewString __attribute((alias("xmlXPathNewString__internal_alias")));
+#else
+#ifndef xmlXPathNewString
+extern __typeof (xmlXPathNewString) xmlXPathNewString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewString xmlXPathNewString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNewValueTree
+extern __typeof (xmlXPathNewValueTree) xmlXPathNewValueTree __attribute((alias("xmlXPathNewValueTree__internal_alias")));
+#else
+#ifndef xmlXPathNewValueTree
+extern __typeof (xmlXPathNewValueTree) xmlXPathNewValueTree__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNewValueTree xmlXPathNewValueTree__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextAncestor
+extern __typeof (xmlXPathNextAncestor) xmlXPathNextAncestor __attribute((alias("xmlXPathNextAncestor__internal_alias")));
+#else
+#ifndef xmlXPathNextAncestor
+extern __typeof (xmlXPathNextAncestor) xmlXPathNextAncestor__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextAncestor xmlXPathNextAncestor__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextAncestorOrSelf
+extern __typeof (xmlXPathNextAncestorOrSelf) xmlXPathNextAncestorOrSelf __attribute((alias("xmlXPathNextAncestorOrSelf__internal_alias")));
+#else
+#ifndef xmlXPathNextAncestorOrSelf
+extern __typeof (xmlXPathNextAncestorOrSelf) xmlXPathNextAncestorOrSelf__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextAncestorOrSelf xmlXPathNextAncestorOrSelf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextAttribute
+extern __typeof (xmlXPathNextAttribute) xmlXPathNextAttribute __attribute((alias("xmlXPathNextAttribute__internal_alias")));
+#else
+#ifndef xmlXPathNextAttribute
+extern __typeof (xmlXPathNextAttribute) xmlXPathNextAttribute__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextAttribute xmlXPathNextAttribute__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextChild
+extern __typeof (xmlXPathNextChild) xmlXPathNextChild __attribute((alias("xmlXPathNextChild__internal_alias")));
+#else
+#ifndef xmlXPathNextChild
+extern __typeof (xmlXPathNextChild) xmlXPathNextChild__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextChild xmlXPathNextChild__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextDescendant
+extern __typeof (xmlXPathNextDescendant) xmlXPathNextDescendant __attribute((alias("xmlXPathNextDescendant__internal_alias")));
+#else
+#ifndef xmlXPathNextDescendant
+extern __typeof (xmlXPathNextDescendant) xmlXPathNextDescendant__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextDescendant xmlXPathNextDescendant__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextDescendantOrSelf
+extern __typeof (xmlXPathNextDescendantOrSelf) xmlXPathNextDescendantOrSelf __attribute((alias("xmlXPathNextDescendantOrSelf__internal_alias")));
+#else
+#ifndef xmlXPathNextDescendantOrSelf
+extern __typeof (xmlXPathNextDescendantOrSelf) xmlXPathNextDescendantOrSelf__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextDescendantOrSelf xmlXPathNextDescendantOrSelf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextFollowing
+extern __typeof (xmlXPathNextFollowing) xmlXPathNextFollowing __attribute((alias("xmlXPathNextFollowing__internal_alias")));
+#else
+#ifndef xmlXPathNextFollowing
+extern __typeof (xmlXPathNextFollowing) xmlXPathNextFollowing__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextFollowing xmlXPathNextFollowing__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextFollowingSibling
+extern __typeof (xmlXPathNextFollowingSibling) xmlXPathNextFollowingSibling __attribute((alias("xmlXPathNextFollowingSibling__internal_alias")));
+#else
+#ifndef xmlXPathNextFollowingSibling
+extern __typeof (xmlXPathNextFollowingSibling) xmlXPathNextFollowingSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextFollowingSibling xmlXPathNextFollowingSibling__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextNamespace
+extern __typeof (xmlXPathNextNamespace) xmlXPathNextNamespace __attribute((alias("xmlXPathNextNamespace__internal_alias")));
+#else
+#ifndef xmlXPathNextNamespace
+extern __typeof (xmlXPathNextNamespace) xmlXPathNextNamespace__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextNamespace xmlXPathNextNamespace__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextParent
+extern __typeof (xmlXPathNextParent) xmlXPathNextParent __attribute((alias("xmlXPathNextParent__internal_alias")));
+#else
+#ifndef xmlXPathNextParent
+extern __typeof (xmlXPathNextParent) xmlXPathNextParent__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextParent xmlXPathNextParent__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextPreceding
+extern __typeof (xmlXPathNextPreceding) xmlXPathNextPreceding __attribute((alias("xmlXPathNextPreceding__internal_alias")));
+#else
+#ifndef xmlXPathNextPreceding
+extern __typeof (xmlXPathNextPreceding) xmlXPathNextPreceding__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextPreceding xmlXPathNextPreceding__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextPrecedingSibling
+extern __typeof (xmlXPathNextPrecedingSibling) xmlXPathNextPrecedingSibling __attribute((alias("xmlXPathNextPrecedingSibling__internal_alias")));
+#else
+#ifndef xmlXPathNextPrecedingSibling
+extern __typeof (xmlXPathNextPrecedingSibling) xmlXPathNextPrecedingSibling__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextPrecedingSibling xmlXPathNextPrecedingSibling__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNextSelf
+extern __typeof (xmlXPathNextSelf) xmlXPathNextSelf __attribute((alias("xmlXPathNextSelf__internal_alias")));
+#else
+#ifndef xmlXPathNextSelf
+extern __typeof (xmlXPathNextSelf) xmlXPathNextSelf__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNextSelf xmlXPathNextSelf__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeLeading
+extern __typeof (xmlXPathNodeLeading) xmlXPathNodeLeading __attribute((alias("xmlXPathNodeLeading__internal_alias")));
+#else
+#ifndef xmlXPathNodeLeading
+extern __typeof (xmlXPathNodeLeading) xmlXPathNodeLeading__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeLeading xmlXPathNodeLeading__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeLeadingSorted
+extern __typeof (xmlXPathNodeLeadingSorted) xmlXPathNodeLeadingSorted __attribute((alias("xmlXPathNodeLeadingSorted__internal_alias")));
+#else
+#ifndef xmlXPathNodeLeadingSorted
+extern __typeof (xmlXPathNodeLeadingSorted) xmlXPathNodeLeadingSorted__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeLeadingSorted xmlXPathNodeLeadingSorted__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetAdd
+extern __typeof (xmlXPathNodeSetAdd) xmlXPathNodeSetAdd __attribute((alias("xmlXPathNodeSetAdd__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetAdd
+extern __typeof (xmlXPathNodeSetAdd) xmlXPathNodeSetAdd__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetAdd xmlXPathNodeSetAdd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetAddNs
+extern __typeof (xmlXPathNodeSetAddNs) xmlXPathNodeSetAddNs __attribute((alias("xmlXPathNodeSetAddNs__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetAddNs
+extern __typeof (xmlXPathNodeSetAddNs) xmlXPathNodeSetAddNs__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetAddNs xmlXPathNodeSetAddNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetAddUnique
+extern __typeof (xmlXPathNodeSetAddUnique) xmlXPathNodeSetAddUnique __attribute((alias("xmlXPathNodeSetAddUnique__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetAddUnique
+extern __typeof (xmlXPathNodeSetAddUnique) xmlXPathNodeSetAddUnique__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetAddUnique xmlXPathNodeSetAddUnique__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetContains
+extern __typeof (xmlXPathNodeSetContains) xmlXPathNodeSetContains __attribute((alias("xmlXPathNodeSetContains__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetContains
+extern __typeof (xmlXPathNodeSetContains) xmlXPathNodeSetContains__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetContains xmlXPathNodeSetContains__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetCreate
+extern __typeof (xmlXPathNodeSetCreate) xmlXPathNodeSetCreate __attribute((alias("xmlXPathNodeSetCreate__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetCreate
+extern __typeof (xmlXPathNodeSetCreate) xmlXPathNodeSetCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetCreate xmlXPathNodeSetCreate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetDel
+extern __typeof (xmlXPathNodeSetDel) xmlXPathNodeSetDel __attribute((alias("xmlXPathNodeSetDel__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetDel
+extern __typeof (xmlXPathNodeSetDel) xmlXPathNodeSetDel__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetDel xmlXPathNodeSetDel__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetFreeNs
+extern __typeof (xmlXPathNodeSetFreeNs) xmlXPathNodeSetFreeNs __attribute((alias("xmlXPathNodeSetFreeNs__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetFreeNs
+extern __typeof (xmlXPathNodeSetFreeNs) xmlXPathNodeSetFreeNs__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetFreeNs xmlXPathNodeSetFreeNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetMerge
+extern __typeof (xmlXPathNodeSetMerge) xmlXPathNodeSetMerge __attribute((alias("xmlXPathNodeSetMerge__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetMerge
+extern __typeof (xmlXPathNodeSetMerge) xmlXPathNodeSetMerge__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetMerge xmlXPathNodeSetMerge__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetRemove
+extern __typeof (xmlXPathNodeSetRemove) xmlXPathNodeSetRemove __attribute((alias("xmlXPathNodeSetRemove__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetRemove
+extern __typeof (xmlXPathNodeSetRemove) xmlXPathNodeSetRemove__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetRemove xmlXPathNodeSetRemove__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeSetSort
+extern __typeof (xmlXPathNodeSetSort) xmlXPathNodeSetSort __attribute((alias("xmlXPathNodeSetSort__internal_alias")));
+#else
+#ifndef xmlXPathNodeSetSort
+extern __typeof (xmlXPathNodeSetSort) xmlXPathNodeSetSort__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeSetSort xmlXPathNodeSetSort__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeTrailing
+extern __typeof (xmlXPathNodeTrailing) xmlXPathNodeTrailing __attribute((alias("xmlXPathNodeTrailing__internal_alias")));
+#else
+#ifndef xmlXPathNodeTrailing
+extern __typeof (xmlXPathNodeTrailing) xmlXPathNodeTrailing__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeTrailing xmlXPathNodeTrailing__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNodeTrailingSorted
+extern __typeof (xmlXPathNodeTrailingSorted) xmlXPathNodeTrailingSorted __attribute((alias("xmlXPathNodeTrailingSorted__internal_alias")));
+#else
+#ifndef xmlXPathNodeTrailingSorted
+extern __typeof (xmlXPathNodeTrailingSorted) xmlXPathNodeTrailingSorted__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeTrailingSorted xmlXPathNodeTrailingSorted__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNormalizeFunction
+extern __typeof (xmlXPathNormalizeFunction) xmlXPathNormalizeFunction __attribute((alias("xmlXPathNormalizeFunction__internal_alias")));
+#else
+#ifndef xmlXPathNormalizeFunction
+extern __typeof (xmlXPathNormalizeFunction) xmlXPathNormalizeFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNormalizeFunction xmlXPathNormalizeFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNotEqualValues
+extern __typeof (xmlXPathNotEqualValues) xmlXPathNotEqualValues __attribute((alias("xmlXPathNotEqualValues__internal_alias")));
+#else
+#ifndef xmlXPathNotEqualValues
+extern __typeof (xmlXPathNotEqualValues) xmlXPathNotEqualValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNotEqualValues xmlXPathNotEqualValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNotFunction
+extern __typeof (xmlXPathNotFunction) xmlXPathNotFunction __attribute((alias("xmlXPathNotFunction__internal_alias")));
+#else
+#ifndef xmlXPathNotFunction
+extern __typeof (xmlXPathNotFunction) xmlXPathNotFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNotFunction xmlXPathNotFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNsLookup
+extern __typeof (xmlXPathNsLookup) xmlXPathNsLookup __attribute((alias("xmlXPathNsLookup__internal_alias")));
+#else
+#ifndef xmlXPathNsLookup
+extern __typeof (xmlXPathNsLookup) xmlXPathNsLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNsLookup xmlXPathNsLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathNumberFunction
+extern __typeof (xmlXPathNumberFunction) xmlXPathNumberFunction __attribute((alias("xmlXPathNumberFunction__internal_alias")));
+#else
+#ifndef xmlXPathNumberFunction
+extern __typeof (xmlXPathNumberFunction) xmlXPathNumberFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNumberFunction xmlXPathNumberFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathObjectCopy
+extern __typeof (xmlXPathObjectCopy) xmlXPathObjectCopy __attribute((alias("xmlXPathObjectCopy__internal_alias")));
+#else
+#ifndef xmlXPathObjectCopy
+extern __typeof (xmlXPathObjectCopy) xmlXPathObjectCopy__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathObjectCopy xmlXPathObjectCopy__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathOrderDocElems
+extern __typeof (xmlXPathOrderDocElems) xmlXPathOrderDocElems __attribute((alias("xmlXPathOrderDocElems__internal_alias")));
+#else
+#ifndef xmlXPathOrderDocElems
+extern __typeof (xmlXPathOrderDocElems) xmlXPathOrderDocElems__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathOrderDocElems xmlXPathOrderDocElems__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathParseNCName
+extern __typeof (xmlXPathParseNCName) xmlXPathParseNCName __attribute((alias("xmlXPathParseNCName__internal_alias")));
+#else
+#ifndef xmlXPathParseNCName
+extern __typeof (xmlXPathParseNCName) xmlXPathParseNCName__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathParseNCName xmlXPathParseNCName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathParseName
+extern __typeof (xmlXPathParseName) xmlXPathParseName __attribute((alias("xmlXPathParseName__internal_alias")));
+#else
+#ifndef xmlXPathParseName
+extern __typeof (xmlXPathParseName) xmlXPathParseName__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathParseName xmlXPathParseName__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPopBoolean
+extern __typeof (xmlXPathPopBoolean) xmlXPathPopBoolean __attribute((alias("xmlXPathPopBoolean__internal_alias")));
+#else
+#ifndef xmlXPathPopBoolean
+extern __typeof (xmlXPathPopBoolean) xmlXPathPopBoolean__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPopBoolean xmlXPathPopBoolean__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPopExternal
+extern __typeof (xmlXPathPopExternal) xmlXPathPopExternal __attribute((alias("xmlXPathPopExternal__internal_alias")));
+#else
+#ifndef xmlXPathPopExternal
+extern __typeof (xmlXPathPopExternal) xmlXPathPopExternal__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPopExternal xmlXPathPopExternal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPopNodeSet
+extern __typeof (xmlXPathPopNodeSet) xmlXPathPopNodeSet __attribute((alias("xmlXPathPopNodeSet__internal_alias")));
+#else
+#ifndef xmlXPathPopNodeSet
+extern __typeof (xmlXPathPopNodeSet) xmlXPathPopNodeSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPopNodeSet xmlXPathPopNodeSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPopNumber
+extern __typeof (xmlXPathPopNumber) xmlXPathPopNumber __attribute((alias("xmlXPathPopNumber__internal_alias")));
+#else
+#ifndef xmlXPathPopNumber
+extern __typeof (xmlXPathPopNumber) xmlXPathPopNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPopNumber xmlXPathPopNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPopString
+extern __typeof (xmlXPathPopString) xmlXPathPopString __attribute((alias("xmlXPathPopString__internal_alias")));
+#else
+#ifndef xmlXPathPopString
+extern __typeof (xmlXPathPopString) xmlXPathPopString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPopString xmlXPathPopString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathPositionFunction
+extern __typeof (xmlXPathPositionFunction) xmlXPathPositionFunction __attribute((alias("xmlXPathPositionFunction__internal_alias")));
+#else
+#ifndef xmlXPathPositionFunction
+extern __typeof (xmlXPathPositionFunction) xmlXPathPositionFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathPositionFunction xmlXPathPositionFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterAllFunctions
+extern __typeof (xmlXPathRegisterAllFunctions) xmlXPathRegisterAllFunctions __attribute((alias("xmlXPathRegisterAllFunctions__internal_alias")));
+#else
+#ifndef xmlXPathRegisterAllFunctions
+extern __typeof (xmlXPathRegisterAllFunctions) xmlXPathRegisterAllFunctions__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterAllFunctions xmlXPathRegisterAllFunctions__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterFunc
+extern __typeof (xmlXPathRegisterFunc) xmlXPathRegisterFunc __attribute((alias("xmlXPathRegisterFunc__internal_alias")));
+#else
+#ifndef xmlXPathRegisterFunc
+extern __typeof (xmlXPathRegisterFunc) xmlXPathRegisterFunc__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterFunc xmlXPathRegisterFunc__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterFuncLookup
+extern __typeof (xmlXPathRegisterFuncLookup) xmlXPathRegisterFuncLookup __attribute((alias("xmlXPathRegisterFuncLookup__internal_alias")));
+#else
+#ifndef xmlXPathRegisterFuncLookup
+extern __typeof (xmlXPathRegisterFuncLookup) xmlXPathRegisterFuncLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterFuncLookup xmlXPathRegisterFuncLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterFuncNS
+extern __typeof (xmlXPathRegisterFuncNS) xmlXPathRegisterFuncNS __attribute((alias("xmlXPathRegisterFuncNS__internal_alias")));
+#else
+#ifndef xmlXPathRegisterFuncNS
+extern __typeof (xmlXPathRegisterFuncNS) xmlXPathRegisterFuncNS__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterFuncNS xmlXPathRegisterFuncNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterNs
+extern __typeof (xmlXPathRegisterNs) xmlXPathRegisterNs __attribute((alias("xmlXPathRegisterNs__internal_alias")));
+#else
+#ifndef xmlXPathRegisterNs
+extern __typeof (xmlXPathRegisterNs) xmlXPathRegisterNs__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterNs xmlXPathRegisterNs__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterVariable
+extern __typeof (xmlXPathRegisterVariable) xmlXPathRegisterVariable __attribute((alias("xmlXPathRegisterVariable__internal_alias")));
+#else
+#ifndef xmlXPathRegisterVariable
+extern __typeof (xmlXPathRegisterVariable) xmlXPathRegisterVariable__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterVariable xmlXPathRegisterVariable__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterVariableLookup
+extern __typeof (xmlXPathRegisterVariableLookup) xmlXPathRegisterVariableLookup __attribute((alias("xmlXPathRegisterVariableLookup__internal_alias")));
+#else
+#ifndef xmlXPathRegisterVariableLookup
+extern __typeof (xmlXPathRegisterVariableLookup) xmlXPathRegisterVariableLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterVariableLookup xmlXPathRegisterVariableLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisterVariableNS
+extern __typeof (xmlXPathRegisterVariableNS) xmlXPathRegisterVariableNS __attribute((alias("xmlXPathRegisterVariableNS__internal_alias")));
+#else
+#ifndef xmlXPathRegisterVariableNS
+extern __typeof (xmlXPathRegisterVariableNS) xmlXPathRegisterVariableNS__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisterVariableNS xmlXPathRegisterVariableNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisteredFuncsCleanup
+extern __typeof (xmlXPathRegisteredFuncsCleanup) xmlXPathRegisteredFuncsCleanup __attribute((alias("xmlXPathRegisteredFuncsCleanup__internal_alias")));
+#else
+#ifndef xmlXPathRegisteredFuncsCleanup
+extern __typeof (xmlXPathRegisteredFuncsCleanup) xmlXPathRegisteredFuncsCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisteredFuncsCleanup xmlXPathRegisteredFuncsCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisteredNsCleanup
+extern __typeof (xmlXPathRegisteredNsCleanup) xmlXPathRegisteredNsCleanup __attribute((alias("xmlXPathRegisteredNsCleanup__internal_alias")));
+#else
+#ifndef xmlXPathRegisteredNsCleanup
+extern __typeof (xmlXPathRegisteredNsCleanup) xmlXPathRegisteredNsCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisteredNsCleanup xmlXPathRegisteredNsCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRegisteredVariablesCleanup
+extern __typeof (xmlXPathRegisteredVariablesCleanup) xmlXPathRegisteredVariablesCleanup __attribute((alias("xmlXPathRegisteredVariablesCleanup__internal_alias")));
+#else
+#ifndef xmlXPathRegisteredVariablesCleanup
+extern __typeof (xmlXPathRegisteredVariablesCleanup) xmlXPathRegisteredVariablesCleanup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRegisteredVariablesCleanup xmlXPathRegisteredVariablesCleanup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRoot
+extern __typeof (xmlXPathRoot) xmlXPathRoot __attribute((alias("xmlXPathRoot__internal_alias")));
+#else
+#ifndef xmlXPathRoot
+extern __typeof (xmlXPathRoot) xmlXPathRoot__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRoot xmlXPathRoot__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathRoundFunction
+extern __typeof (xmlXPathRoundFunction) xmlXPathRoundFunction __attribute((alias("xmlXPathRoundFunction__internal_alias")));
+#else
+#ifndef xmlXPathRoundFunction
+extern __typeof (xmlXPathRoundFunction) xmlXPathRoundFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathRoundFunction xmlXPathRoundFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathStartsWithFunction
+extern __typeof (xmlXPathStartsWithFunction) xmlXPathStartsWithFunction __attribute((alias("xmlXPathStartsWithFunction__internal_alias")));
+#else
+#ifndef xmlXPathStartsWithFunction
+extern __typeof (xmlXPathStartsWithFunction) xmlXPathStartsWithFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathStartsWithFunction xmlXPathStartsWithFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathStringEvalNumber
+extern __typeof (xmlXPathStringEvalNumber) xmlXPathStringEvalNumber __attribute((alias("xmlXPathStringEvalNumber__internal_alias")));
+#else
+#ifndef xmlXPathStringEvalNumber
+extern __typeof (xmlXPathStringEvalNumber) xmlXPathStringEvalNumber__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathStringEvalNumber xmlXPathStringEvalNumber__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathStringFunction
+extern __typeof (xmlXPathStringFunction) xmlXPathStringFunction __attribute((alias("xmlXPathStringFunction__internal_alias")));
+#else
+#ifndef xmlXPathStringFunction
+extern __typeof (xmlXPathStringFunction) xmlXPathStringFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathStringFunction xmlXPathStringFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathStringLengthFunction
+extern __typeof (xmlXPathStringLengthFunction) xmlXPathStringLengthFunction __attribute((alias("xmlXPathStringLengthFunction__internal_alias")));
+#else
+#ifndef xmlXPathStringLengthFunction
+extern __typeof (xmlXPathStringLengthFunction) xmlXPathStringLengthFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathStringLengthFunction xmlXPathStringLengthFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathSubValues
+extern __typeof (xmlXPathSubValues) xmlXPathSubValues __attribute((alias("xmlXPathSubValues__internal_alias")));
+#else
+#ifndef xmlXPathSubValues
+extern __typeof (xmlXPathSubValues) xmlXPathSubValues__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSubValues xmlXPathSubValues__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathSubstringAfterFunction
+extern __typeof (xmlXPathSubstringAfterFunction) xmlXPathSubstringAfterFunction __attribute((alias("xmlXPathSubstringAfterFunction__internal_alias")));
+#else
+#ifndef xmlXPathSubstringAfterFunction
+extern __typeof (xmlXPathSubstringAfterFunction) xmlXPathSubstringAfterFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSubstringAfterFunction xmlXPathSubstringAfterFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathSubstringBeforeFunction
+extern __typeof (xmlXPathSubstringBeforeFunction) xmlXPathSubstringBeforeFunction __attribute((alias("xmlXPathSubstringBeforeFunction__internal_alias")));
+#else
+#ifndef xmlXPathSubstringBeforeFunction
+extern __typeof (xmlXPathSubstringBeforeFunction) xmlXPathSubstringBeforeFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSubstringBeforeFunction xmlXPathSubstringBeforeFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathSubstringFunction
+extern __typeof (xmlXPathSubstringFunction) xmlXPathSubstringFunction __attribute((alias("xmlXPathSubstringFunction__internal_alias")));
+#else
+#ifndef xmlXPathSubstringFunction
+extern __typeof (xmlXPathSubstringFunction) xmlXPathSubstringFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSubstringFunction xmlXPathSubstringFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathSumFunction
+extern __typeof (xmlXPathSumFunction) xmlXPathSumFunction __attribute((alias("xmlXPathSumFunction__internal_alias")));
+#else
+#ifndef xmlXPathSumFunction
+extern __typeof (xmlXPathSumFunction) xmlXPathSumFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSumFunction xmlXPathSumFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathTrailing
+extern __typeof (xmlXPathTrailing) xmlXPathTrailing __attribute((alias("xmlXPathTrailing__internal_alias")));
+#else
+#ifndef xmlXPathTrailing
+extern __typeof (xmlXPathTrailing) xmlXPathTrailing__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathTrailing xmlXPathTrailing__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathTrailingSorted
+extern __typeof (xmlXPathTrailingSorted) xmlXPathTrailingSorted __attribute((alias("xmlXPathTrailingSorted__internal_alias")));
+#else
+#ifndef xmlXPathTrailingSorted
+extern __typeof (xmlXPathTrailingSorted) xmlXPathTrailingSorted__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathTrailingSorted xmlXPathTrailingSorted__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathTranslateFunction
+extern __typeof (xmlXPathTranslateFunction) xmlXPathTranslateFunction __attribute((alias("xmlXPathTranslateFunction__internal_alias")));
+#else
+#ifndef xmlXPathTranslateFunction
+extern __typeof (xmlXPathTranslateFunction) xmlXPathTranslateFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathTranslateFunction xmlXPathTranslateFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathTrueFunction
+extern __typeof (xmlXPathTrueFunction) xmlXPathTrueFunction __attribute((alias("xmlXPathTrueFunction__internal_alias")));
+#else
+#ifndef xmlXPathTrueFunction
+extern __typeof (xmlXPathTrueFunction) xmlXPathTrueFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathTrueFunction xmlXPathTrueFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathValueFlipSign
+extern __typeof (xmlXPathValueFlipSign) xmlXPathValueFlipSign __attribute((alias("xmlXPathValueFlipSign__internal_alias")));
+#else
+#ifndef xmlXPathValueFlipSign
+extern __typeof (xmlXPathValueFlipSign) xmlXPathValueFlipSign__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathValueFlipSign xmlXPathValueFlipSign__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathVariableLookup
+extern __typeof (xmlXPathVariableLookup) xmlXPathVariableLookup __attribute((alias("xmlXPathVariableLookup__internal_alias")));
+#else
+#ifndef xmlXPathVariableLookup
+extern __typeof (xmlXPathVariableLookup) xmlXPathVariableLookup__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathVariableLookup xmlXPathVariableLookup__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathVariableLookupNS
+extern __typeof (xmlXPathVariableLookupNS) xmlXPathVariableLookupNS __attribute((alias("xmlXPathVariableLookupNS__internal_alias")));
+#else
+#ifndef xmlXPathVariableLookupNS
+extern __typeof (xmlXPathVariableLookupNS) xmlXPathVariableLookupNS__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathVariableLookupNS xmlXPathVariableLookupNS__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathWrapCString
+extern __typeof (xmlXPathWrapCString) xmlXPathWrapCString __attribute((alias("xmlXPathWrapCString__internal_alias")));
+#else
+#ifndef xmlXPathWrapCString
+extern __typeof (xmlXPathWrapCString) xmlXPathWrapCString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathWrapCString xmlXPathWrapCString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathWrapExternal
+extern __typeof (xmlXPathWrapExternal) xmlXPathWrapExternal __attribute((alias("xmlXPathWrapExternal__internal_alias")));
+#else
+#ifndef xmlXPathWrapExternal
+extern __typeof (xmlXPathWrapExternal) xmlXPathWrapExternal__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathWrapExternal xmlXPathWrapExternal__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathWrapNodeSet
+extern __typeof (xmlXPathWrapNodeSet) xmlXPathWrapNodeSet __attribute((alias("xmlXPathWrapNodeSet__internal_alias")));
+#else
+#ifndef xmlXPathWrapNodeSet
+extern __typeof (xmlXPathWrapNodeSet) xmlXPathWrapNodeSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathWrapNodeSet xmlXPathWrapNodeSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPathWrapString
+extern __typeof (xmlXPathWrapString) xmlXPathWrapString __attribute((alias("xmlXPathWrapString__internal_alias")));
+#else
+#ifndef xmlXPathWrapString
+extern __typeof (xmlXPathWrapString) xmlXPathWrapString__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathWrapString xmlXPathWrapString__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
+#undef xmlXPatherror
+extern __typeof (xmlXPatherror) xmlXPatherror __attribute((alias("xmlXPatherror__internal_alias")));
+#else
+#ifndef xmlXPatherror
+extern __typeof (xmlXPatherror) xmlXPatherror__internal_alias __attribute((visibility("hidden")));
+#define xmlXPatherror xmlXPatherror__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrBuildNodeList
+extern __typeof (xmlXPtrBuildNodeList) xmlXPtrBuildNodeList __attribute((alias("xmlXPtrBuildNodeList__internal_alias")));
+#else
+#ifndef xmlXPtrBuildNodeList
+extern __typeof (xmlXPtrBuildNodeList) xmlXPtrBuildNodeList__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrBuildNodeList xmlXPtrBuildNodeList__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrEval
+extern __typeof (xmlXPtrEval) xmlXPtrEval __attribute((alias("xmlXPtrEval__internal_alias")));
+#else
+#ifndef xmlXPtrEval
+extern __typeof (xmlXPtrEval) xmlXPtrEval__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrEval xmlXPtrEval__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrEvalRangePredicate
+extern __typeof (xmlXPtrEvalRangePredicate) xmlXPtrEvalRangePredicate __attribute((alias("xmlXPtrEvalRangePredicate__internal_alias")));
+#else
+#ifndef xmlXPtrEvalRangePredicate
+extern __typeof (xmlXPtrEvalRangePredicate) xmlXPtrEvalRangePredicate__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrEvalRangePredicate xmlXPtrEvalRangePredicate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrFreeLocationSet
+extern __typeof (xmlXPtrFreeLocationSet) xmlXPtrFreeLocationSet __attribute((alias("xmlXPtrFreeLocationSet__internal_alias")));
+#else
+#ifndef xmlXPtrFreeLocationSet
+extern __typeof (xmlXPtrFreeLocationSet) xmlXPtrFreeLocationSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrFreeLocationSet xmlXPtrFreeLocationSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrLocationSetAdd
+extern __typeof (xmlXPtrLocationSetAdd) xmlXPtrLocationSetAdd __attribute((alias("xmlXPtrLocationSetAdd__internal_alias")));
+#else
+#ifndef xmlXPtrLocationSetAdd
+extern __typeof (xmlXPtrLocationSetAdd) xmlXPtrLocationSetAdd__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrLocationSetAdd xmlXPtrLocationSetAdd__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrLocationSetCreate
+extern __typeof (xmlXPtrLocationSetCreate) xmlXPtrLocationSetCreate __attribute((alias("xmlXPtrLocationSetCreate__internal_alias")));
+#else
+#ifndef xmlXPtrLocationSetCreate
+extern __typeof (xmlXPtrLocationSetCreate) xmlXPtrLocationSetCreate__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrLocationSetCreate xmlXPtrLocationSetCreate__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrLocationSetDel
+extern __typeof (xmlXPtrLocationSetDel) xmlXPtrLocationSetDel __attribute((alias("xmlXPtrLocationSetDel__internal_alias")));
+#else
+#ifndef xmlXPtrLocationSetDel
+extern __typeof (xmlXPtrLocationSetDel) xmlXPtrLocationSetDel__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrLocationSetDel xmlXPtrLocationSetDel__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrLocationSetMerge
+extern __typeof (xmlXPtrLocationSetMerge) xmlXPtrLocationSetMerge __attribute((alias("xmlXPtrLocationSetMerge__internal_alias")));
+#else
+#ifndef xmlXPtrLocationSetMerge
+extern __typeof (xmlXPtrLocationSetMerge) xmlXPtrLocationSetMerge__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrLocationSetMerge xmlXPtrLocationSetMerge__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrLocationSetRemove
+extern __typeof (xmlXPtrLocationSetRemove) xmlXPtrLocationSetRemove __attribute((alias("xmlXPtrLocationSetRemove__internal_alias")));
+#else
+#ifndef xmlXPtrLocationSetRemove
+extern __typeof (xmlXPtrLocationSetRemove) xmlXPtrLocationSetRemove__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrLocationSetRemove xmlXPtrLocationSetRemove__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewCollapsedRange
+extern __typeof (xmlXPtrNewCollapsedRange) xmlXPtrNewCollapsedRange __attribute((alias("xmlXPtrNewCollapsedRange__internal_alias")));
+#else
+#ifndef xmlXPtrNewCollapsedRange
+extern __typeof (xmlXPtrNewCollapsedRange) xmlXPtrNewCollapsedRange__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewCollapsedRange xmlXPtrNewCollapsedRange__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewContext
+extern __typeof (xmlXPtrNewContext) xmlXPtrNewContext __attribute((alias("xmlXPtrNewContext__internal_alias")));
+#else
+#ifndef xmlXPtrNewContext
+extern __typeof (xmlXPtrNewContext) xmlXPtrNewContext__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewContext xmlXPtrNewContext__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewLocationSetNodeSet
+extern __typeof (xmlXPtrNewLocationSetNodeSet) xmlXPtrNewLocationSetNodeSet __attribute((alias("xmlXPtrNewLocationSetNodeSet__internal_alias")));
+#else
+#ifndef xmlXPtrNewLocationSetNodeSet
+extern __typeof (xmlXPtrNewLocationSetNodeSet) xmlXPtrNewLocationSetNodeSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewLocationSetNodeSet xmlXPtrNewLocationSetNodeSet__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewLocationSetNodes
+extern __typeof (xmlXPtrNewLocationSetNodes) xmlXPtrNewLocationSetNodes __attribute((alias("xmlXPtrNewLocationSetNodes__internal_alias")));
+#else
+#ifndef xmlXPtrNewLocationSetNodes
+extern __typeof (xmlXPtrNewLocationSetNodes) xmlXPtrNewLocationSetNodes__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewLocationSetNodes xmlXPtrNewLocationSetNodes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRange
+extern __typeof (xmlXPtrNewRange) xmlXPtrNewRange __attribute((alias("xmlXPtrNewRange__internal_alias")));
+#else
+#ifndef xmlXPtrNewRange
+extern __typeof (xmlXPtrNewRange) xmlXPtrNewRange__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRange xmlXPtrNewRange__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRangeNodeObject
+extern __typeof (xmlXPtrNewRangeNodeObject) xmlXPtrNewRangeNodeObject __attribute((alias("xmlXPtrNewRangeNodeObject__internal_alias")));
+#else
+#ifndef xmlXPtrNewRangeNodeObject
+extern __typeof (xmlXPtrNewRangeNodeObject) xmlXPtrNewRangeNodeObject__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRangeNodeObject xmlXPtrNewRangeNodeObject__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRangeNodePoint
+extern __typeof (xmlXPtrNewRangeNodePoint) xmlXPtrNewRangeNodePoint __attribute((alias("xmlXPtrNewRangeNodePoint__internal_alias")));
+#else
+#ifndef xmlXPtrNewRangeNodePoint
+extern __typeof (xmlXPtrNewRangeNodePoint) xmlXPtrNewRangeNodePoint__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRangeNodePoint xmlXPtrNewRangeNodePoint__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRangeNodes
+extern __typeof (xmlXPtrNewRangeNodes) xmlXPtrNewRangeNodes __attribute((alias("xmlXPtrNewRangeNodes__internal_alias")));
+#else
+#ifndef xmlXPtrNewRangeNodes
+extern __typeof (xmlXPtrNewRangeNodes) xmlXPtrNewRangeNodes__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRangeNodes xmlXPtrNewRangeNodes__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRangePointNode
+extern __typeof (xmlXPtrNewRangePointNode) xmlXPtrNewRangePointNode __attribute((alias("xmlXPtrNewRangePointNode__internal_alias")));
+#else
+#ifndef xmlXPtrNewRangePointNode
+extern __typeof (xmlXPtrNewRangePointNode) xmlXPtrNewRangePointNode__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRangePointNode xmlXPtrNewRangePointNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrNewRangePoints
+extern __typeof (xmlXPtrNewRangePoints) xmlXPtrNewRangePoints __attribute((alias("xmlXPtrNewRangePoints__internal_alias")));
+#else
+#ifndef xmlXPtrNewRangePoints
+extern __typeof (xmlXPtrNewRangePoints) xmlXPtrNewRangePoints__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrNewRangePoints xmlXPtrNewRangePoints__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrRangeToFunction
+extern __typeof (xmlXPtrRangeToFunction) xmlXPtrRangeToFunction __attribute((alias("xmlXPtrRangeToFunction__internal_alias")));
+#else
+#ifndef xmlXPtrRangeToFunction
+extern __typeof (xmlXPtrRangeToFunction) xmlXPtrRangeToFunction__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrRangeToFunction xmlXPtrRangeToFunction__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPTR_ENABLED)
+#ifdef bottom_xpointer
+#undef xmlXPtrWrapLocationSet
+extern __typeof (xmlXPtrWrapLocationSet) xmlXPtrWrapLocationSet __attribute((alias("xmlXPtrWrapLocationSet__internal_alias")));
+#else
+#ifndef xmlXPtrWrapLocationSet
+extern __typeof (xmlXPtrWrapLocationSet) xmlXPtrWrapLocationSet__internal_alias __attribute((visibility("hidden")));
+#define xmlXPtrWrapLocationSet xmlXPtrWrapLocationSet__internal_alias
+#endif
+#endif
+#endif
+
+
+#endif
+#endif
+#endif
+#endif
+#endif
+
diff --git a/src/encoding.c b/src/encoding.c
new file mode 100644
index 0000000..0a388ff
--- /dev/null
+++ b/src/encoding.c
@@ -0,0 +1,3572 @@
+/*
+ * encoding.c : implements the encoding conversion functions needed for XML
+ *
+ * Related specs: 
+ * rfc2044        (UTF-8 and UTF-16) F. Yergeau Alis Technologies
+ * rfc2781        UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
+ * [ISO-10646]    UTF-8 and UTF-16 in Annexes
+ * [ISO-8859-1]   ISO Latin-1 characters codes.
+ * [UNICODE]      The Unicode Consortium, "The Unicode Standard --
+ *                Worldwide Character Encoding -- Version 1.0", Addison-
+ *                Wesley, Volume 1, 1991, Volume 2, 1992.  UTF-8 is
+ *                described in Unicode Technical Report #4.
+ * [US-ASCII]     Coded Character Set--7-bit American Standard Code for
+ *                Information Interchange, ANSI X3.4-1986.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" <duerst@w3.org>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef LIBXML_ICONV_ENABLED
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#endif
+#include <libxml/encoding.h>
+#include <libxml/xmlmemory.h>
+#ifdef LIBXML_HTML_ENABLED
+#include <libxml/HTMLparser.h>
+#endif
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+
+static xmlCharEncodingHandlerPtr xmlUTF16LEHandler = NULL;
+static xmlCharEncodingHandlerPtr xmlUTF16BEHandler = NULL;
+
+typedef struct _xmlCharEncodingAlias xmlCharEncodingAlias;
+typedef xmlCharEncodingAlias *xmlCharEncodingAliasPtr;
+struct _xmlCharEncodingAlias {
+    const char *name;
+    const char *alias;
+};
+
+static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
+static int xmlCharEncodingAliasesNb = 0;
+static int xmlCharEncodingAliasesMax = 0;
+
+#if defined(LIBXML_ICONV_ENABLED) || defined(LIBXML_ICU_ENABLED)
+#if 0
+#define DEBUG_ENCODING  /* Define this to get encoding traces */
+#endif
+#else
+#ifdef LIBXML_ISO8859X_ENABLED
+static void xmlRegisterCharEncodingHandlersISO8859x (void);
+#endif
+#endif
+
+static int xmlLittleEndian = 1;
+
+/**
+ * xmlEncodingErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlEncodingErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_I18N, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * xmlErrEncoding:
+ * @error:  the error number
+ * @msg:  the error message
+ *
+ * n encoding error
+ */
+static void
+xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL,
+                    XML_FROM_I18N, error, XML_ERR_FATAL,
+                    NULL, 0, val, NULL, NULL, 0, 0, msg, val);
+}
+
+#ifdef LIBXML_ICU_ENABLED
+static uconv_t* 
+openIcuConverter(const char* name, int toUnicode)
+{
+  UErrorCode status = U_ZERO_ERROR;
+  uconv_t *conv = (uconv_t *) xmlMalloc(sizeof(uconv_t));
+  if (conv == NULL)
+    return NULL;
+
+  conv->uconv = ucnv_open(name, &status);
+  if (U_FAILURE(status))
+    goto error;
+
+  status = U_ZERO_ERROR;
+  if (toUnicode) {
+    ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP, 
+                        NULL, NULL, NULL, &status);
+  }
+  else {
+    ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP, 
+                        NULL, NULL, NULL, &status);
+  }
+  if (U_FAILURE(status))
+    goto error;
+
+  status = U_ZERO_ERROR;
+  conv->utf8 = ucnv_open("UTF-8", &status);
+  if (U_SUCCESS(status))
+    return conv;
+
+error:
+  if (conv->uconv) 
+    ucnv_close(conv->uconv);
+  xmlFree(conv);
+  return NULL;
+}
+
+static void
+closeIcuConverter(uconv_t *conv)
+{
+  if (conv != NULL) {
+    ucnv_close(conv->uconv);
+    ucnv_close(conv->utf8);
+    xmlFree(conv);
+  }
+}
+#endif /* LIBXML_ICU_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Conversions To/From UTF8 encoding			*
+ *									*
+ ************************************************************************/
+
+/**
+ * asciiToUTF8:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of ASCII chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of ASCII chars in and try to convert it to an UTF-8
+ * block of chars out.
+ * Returns 0 if success, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+static int
+asciiToUTF8(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen) {
+    unsigned char* outstart = out;
+    const unsigned char* base = in;
+    const unsigned char* processed = in;
+    unsigned char* outend = out + *outlen;
+    const unsigned char* inend;
+    unsigned int c;
+
+    inend = in + (*inlen);
+    while ((in < inend) && (out - outstart + 5 < *outlen)) {
+	c= *in++;
+
+        if (out >= outend)
+	    break;
+        if (c < 0x80) {
+	    *out++ = c;
+	} else { 
+	    *outlen = out - outstart;
+	    *inlen = processed - base;
+	    return(-1);
+	}
+ 
+	processed = (const unsigned char*) in;
+    }
+    *outlen = out - outstart;
+    *inlen = processed - base;
+    return(*outlen);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * UTF8Toascii:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ASCII
+ * block of chars out.
+ *
+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+static int
+UTF8Toascii(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen) {
+    const unsigned char* processed = in;
+    const unsigned char* outend;
+    const unsigned char* outstart = out;
+    const unsigned char* instart = in;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if (in == NULL) {
+        /*
+	 * initialization nothing to do
+	 */
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    inend = in + (*inlen);
+    outend = out + (*outlen);
+    while (in < inend) {
+	d = *in++;
+	if      (d < 0x80)  { c= d; trailing= 0; }
+	else if (d < 0xC0) {
+	    /* trailing byte in leading position */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+        } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+        else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+        else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+	else {
+	    /* no chance for this in Ascii */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+
+	if (inend - in < trailing) {
+	    break;
+	} 
+
+	for ( ; trailing; trailing--) {
+	    if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
+		break;
+	    c <<= 6;
+	    c |= d & 0x3F;
+	}
+
+	/* assertion: c is a single UTF-4 value */
+	if (c < 0x80) {
+	    if (out >= outend)
+		break;
+	    *out++ = c;
+	} else {
+	    /* no chance for this in Ascii */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+	processed = in;
+    }
+    *outlen = out - outstart;
+    *inlen = processed - instart;
+    return(*outlen);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * isolat1ToUTF8:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of ISO Latin 1 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8
+ * block of chars out.
+ * Returns the number of bytes written if success, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+int
+isolat1ToUTF8(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen) {
+    unsigned char* outstart = out;
+    const unsigned char* base = in;
+    unsigned char* outend;
+    const unsigned char* inend;
+    const unsigned char* instop;
+
+    if ((out == NULL) || (in == NULL) || (outlen == NULL) || (inlen == NULL))
+	return(-1);
+
+    outend = out + *outlen;
+    inend = in + (*inlen);
+    instop = inend;
+    
+    while (in < inend && out < outend - 1) {
+    	if (*in >= 0x80) {
+	    *out++ = (((*in) >>  6) & 0x1F) | 0xC0;
+        *out++ = ((*in) & 0x3F) | 0x80;
+	    ++in;
+	}
+	if (instop - in > outend - out) instop = in + (outend - out); 
+	while (in < instop && *in < 0x80) {
+	    *out++ = *in++;
+	}
+    }	
+    if (in < inend && out < outend && *in < 0x80) {
+        *out++ = *in++;
+    }
+    *outlen = out - outstart;
+    *inlen = in - base;
+    return(*outlen);
+}
+
+/**
+ * UTF8ToUTF8:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @inb:  a pointer to an array of UTF-8 chars
+ * @inlenb:  the length of @in in UTF-8 chars
+ *
+ * No op copy operation for UTF8 handling.
+ *
+ * Returns the number of bytes written, or -1 if lack of space.
+ *     The value of *inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ */
+static int
+UTF8ToUTF8(unsigned char* out, int *outlen,
+           const unsigned char* inb, int *inlenb)
+{
+    int len;
+
+    if ((out == NULL) || (inb == NULL) || (outlen == NULL) || (inlenb == NULL))
+	return(-1);
+    if (*outlen > *inlenb) {
+	len = *inlenb;
+    } else {
+	len = *outlen;
+    }
+    if (len < 0)
+	return(-1);
+
+    memcpy(out, inb, len);
+
+    *outlen = len;
+    *inlenb = len;
+    return(*outlen);
+}
+
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * UTF8Toisolat1:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1
+ * block of chars out.
+ *
+ * Returns the number of bytes written if success, -2 if the transcoding fails,
+           or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+int
+UTF8Toisolat1(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen) {
+    const unsigned char* processed = in;
+    const unsigned char* outend;
+    const unsigned char* outstart = out;
+    const unsigned char* instart = in;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if (in == NULL) {
+        /*
+	 * initialization nothing to do
+	 */
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    inend = in + (*inlen);
+    outend = out + (*outlen);
+    while (in < inend) {
+	d = *in++;
+	if      (d < 0x80)  { c= d; trailing= 0; }
+	else if (d < 0xC0) {
+	    /* trailing byte in leading position */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+        } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+        else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+        else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+	else {
+	    /* no chance for this in IsoLat1 */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+
+	if (inend - in < trailing) {
+	    break;
+	} 
+
+	for ( ; trailing; trailing--) {
+	    if (in >= inend)
+		break;
+	    if (((d= *in++) & 0xC0) != 0x80) {
+		*outlen = out - outstart;
+		*inlen = processed - instart;
+		return(-2);
+	    }
+	    c <<= 6;
+	    c |= d & 0x3F;
+	}
+
+	/* assertion: c is a single UTF-4 value */
+	if (c <= 0xFF) {
+	    if (out >= outend)
+		break;
+	    *out++ = c;
+	} else {
+	    /* no chance for this in IsoLat1 */
+	    *outlen = out - outstart;
+	    *inlen = processed - instart;
+	    return(-2);
+	}
+	processed = in;
+    }
+    *outlen = out - outstart;
+    *inlen = processed - instart;
+    return(*outlen);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * UTF16LEToUTF8:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @inb:  a pointer to an array of UTF-16LE passwd as a byte array
+ * @inlenb:  the length of @in in UTF-16LE chars
+ *
+ * Take a block of UTF-16LE ushorts in and try to convert it to an UTF-8
+ * block of chars out. This function assumes the endian property
+ * is the same between the native type of this machine and the
+ * inputed one.
+ *
+ * Returns the number of bytes written, or -1 if lack of space, or -2
+ *     if the transcoding fails (if *in is not a valid utf16 string)
+ *     The value of *inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ */
+static int
+UTF16LEToUTF8(unsigned char* out, int *outlen,
+            const unsigned char* inb, int *inlenb)
+{
+    unsigned char* outstart = out;
+    const unsigned char* processed = inb;
+    unsigned char* outend = out + *outlen;
+    unsigned short* in = (unsigned short*) inb;
+    unsigned short* inend;
+    unsigned int c, d, inlen;
+    unsigned char *tmp;
+    int bits;
+
+    if ((*inlenb % 2) == 1)
+        (*inlenb)--;
+    inlen = *inlenb / 2;
+    inend = in + inlen;
+    while ((in < inend) && (out - outstart + 5 < *outlen)) {
+        if (xmlLittleEndian) {
+	    c= *in++;
+	} else {
+	    tmp = (unsigned char *) in;
+	    c = *tmp++;
+	    c = c | (((unsigned int)*tmp) << 8);
+	    in++;
+	}
+        if ((c & 0xFC00) == 0xD800) {    /* surrogates */
+	    if (in >= inend) {           /* (in > inend) shouldn't happens */
+		break;
+	    }
+	    if (xmlLittleEndian) {
+		d = *in++;
+	    } else {
+		tmp = (unsigned char *) in;
+		d = *tmp++;
+		d = d | (((unsigned int)*tmp) << 8);
+		in++;
+	    }
+            if ((d & 0xFC00) == 0xDC00) {
+                c &= 0x03FF;
+                c <<= 10;
+                c |= d & 0x03FF;
+                c += 0x10000;
+            }
+            else {
+		*outlen = out - outstart;
+		*inlenb = processed - inb;
+	        return(-2);
+	    }
+        }
+
+	/* assertion: c is a single UTF-4 value */
+        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)
+	        break;
+            *out++= ((c >> bits) & 0x3F) | 0x80;
+        }
+	processed = (const unsigned char*) in;
+    }
+    *outlen = out - outstart;
+    *inlenb = processed - inb;
+    return(*outlen);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * UTF8ToUTF16LE:
+ * @outb:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @outb
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an UTF-16LE
+ * block of chars out.
+ *
+ * Returns the number of bytes written, or -1 if lack of space, or -2
+ *     if the transcoding failed. 
+ */
+static int
+UTF8ToUTF16LE(unsigned char* outb, int *outlen,
+            const unsigned char* in, int *inlen)
+{
+    unsigned short* out = (unsigned short*) outb;
+    const unsigned char* processed = in;
+    const unsigned char *const instart = in;
+    unsigned short* outstart= out;
+    unsigned short* outend;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+    unsigned char *tmp;
+    unsigned short tmp1, tmp2;
+
+    /* UTF16LE encoding has no BOM */
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if (in == NULL) {
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    inend= in + *inlen;
+    outend = out + (*outlen / 2);
+    while (in < inend) {
+      d= *in++;
+      if      (d < 0x80)  { c= d; trailing= 0; }
+      else if (d < 0xC0) {
+          /* trailing byte in leading position */
+	  *outlen = (out - outstart) * 2;
+	  *inlen = processed - instart;
+	  return(-2);
+      } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+      else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+      else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+      else {
+	/* no chance for this in UTF-16 */
+	*outlen = (out - outstart) * 2;
+	*inlen = processed - instart;
+	return(-2);
+      }
+
+      if (inend - in < trailing) {
+          break;
+      } 
+
+      for ( ; trailing; trailing--) {
+          if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
+	      break;
+          c <<= 6;
+          c |= d & 0x3F;
+      }
+
+      /* assertion: c is a single UTF-4 value */
+        if (c < 0x10000) {
+            if (out >= outend)
+	        break;
+	    if (xmlLittleEndian) {
+		*out++ = c;
+	    } else {
+		tmp = (unsigned char *) out;
+		*tmp = c ;
+		*(tmp + 1) = c >> 8 ;
+		out++;
+	    }
+        }
+        else if (c < 0x110000) {
+            if (out+1 >= outend)
+	        break;
+            c -= 0x10000;
+	    if (xmlLittleEndian) {
+		*out++ = 0xD800 | (c >> 10);
+		*out++ = 0xDC00 | (c & 0x03FF);
+	    } else {
+		tmp1 = 0xD800 | (c >> 10);
+		tmp = (unsigned char *) out;
+		*tmp = (unsigned char) tmp1;
+		*(tmp + 1) = tmp1 >> 8;
+		out++;
+
+		tmp2 = 0xDC00 | (c & 0x03FF);
+		tmp = (unsigned char *) out;
+		*tmp  = (unsigned char) tmp2;
+		*(tmp + 1) = tmp2 >> 8;
+		out++;
+	    }
+        }
+        else
+	    break;
+	processed = in;
+    }
+    *outlen = (out - outstart) * 2;
+    *inlen = processed - instart;
+    return(*outlen);
+}
+
+/**
+ * UTF8ToUTF16:
+ * @outb:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @outb
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an UTF-16
+ * block of chars out.
+ *
+ * Returns the number of bytes written, or -1 if lack of space, or -2
+ *     if the transcoding failed. 
+ */
+static int
+UTF8ToUTF16(unsigned char* outb, int *outlen,
+            const unsigned char* in, int *inlen)
+{
+    if (in == NULL) {
+	/*
+	 * initialization, add the Byte Order Mark for UTF-16LE
+	 */
+        if (*outlen >= 2) {
+	    outb[0] = 0xFF;
+	    outb[1] = 0xFE;
+	    *outlen = 2;
+	    *inlen = 0;
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+		    "Added FFFE Byte Order Mark\n");
+#endif
+	    return(2);
+	}
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    return (UTF8ToUTF16LE(outb, outlen, in, inlen));
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * UTF16BEToUTF8:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @inb:  a pointer to an array of UTF-16 passed as a byte array
+ * @inlenb:  the length of @in in UTF-16 chars
+ *
+ * Take a block of UTF-16 ushorts in and try to convert it to an UTF-8
+ * block of chars out. This function assumes the endian property
+ * is the same between the native type of this machine and the
+ * inputed one.
+ *
+ * Returns the number of bytes written, or -1 if lack of space, or -2
+ *     if the transcoding fails (if *in is not a valid utf16 string)
+ * The value of *inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ */
+static int
+UTF16BEToUTF8(unsigned char* out, int *outlen,
+            const unsigned char* inb, int *inlenb)
+{
+    unsigned char* outstart = out;
+    const unsigned char* processed = inb;
+    unsigned char* outend = out + *outlen;
+    unsigned short* in = (unsigned short*) inb;
+    unsigned short* inend;
+    unsigned int c, d, inlen;
+    unsigned char *tmp;
+    int bits;
+
+    if ((*inlenb % 2) == 1)
+        (*inlenb)--;
+    inlen = *inlenb / 2;
+    inend= in + inlen;
+    while (in < inend) {
+	if (xmlLittleEndian) {
+	    tmp = (unsigned char *) in;
+	    c = *tmp++;
+	    c = c << 8;
+	    c = c | (unsigned int) *tmp;
+	    in++;
+	} else {
+	    c= *in++;
+	} 
+        if ((c & 0xFC00) == 0xD800) {    /* surrogates */
+	    if (in >= inend) {           /* (in > inend) shouldn't happens */
+		*outlen = out - outstart;
+		*inlenb = processed - inb;
+	        return(-2);
+	    }
+	    if (xmlLittleEndian) {
+		tmp = (unsigned char *) in;
+		d = *tmp++;
+		d = d << 8;
+		d = d | (unsigned int) *tmp;
+		in++;
+	    } else {
+		d= *in++;
+	    }
+            if ((d & 0xFC00) == 0xDC00) {
+                c &= 0x03FF;
+                c <<= 10;
+                c |= d & 0x03FF;
+                c += 0x10000;
+            }
+            else {
+		*outlen = out - outstart;
+		*inlenb = processed - inb;
+	        return(-2);
+	    }
+        }
+
+	/* assertion: c is a single UTF-4 value */
+        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) 
+	        break;
+            *out++= ((c >> bits) & 0x3F) | 0x80;
+        }
+	processed = (const unsigned char*) in;
+    }
+    *outlen = out - outstart;
+    *inlenb = processed - inb;
+    return(*outlen);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * UTF8ToUTF16BE:
+ * @outb:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @outb
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an UTF-16BE
+ * block of chars out.
+ *
+ * Returns the number of byte written, or -1 by lack of space, or -2
+ *     if the transcoding failed. 
+ */
+static int
+UTF8ToUTF16BE(unsigned char* outb, int *outlen,
+            const unsigned char* in, int *inlen)
+{
+    unsigned short* out = (unsigned short*) outb;
+    const unsigned char* processed = in;
+    const unsigned char *const instart = in;
+    unsigned short* outstart= out;
+    unsigned short* outend;
+    const unsigned char* inend;
+    unsigned int c, d;
+    int trailing;
+    unsigned char *tmp;
+    unsigned short tmp1, tmp2;
+
+    /* UTF-16BE has no BOM */
+    if ((outb == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if (in == NULL) {
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
+    inend= in + *inlen;
+    outend = out + (*outlen / 2);
+    while (in < inend) {
+      d= *in++;
+      if      (d < 0x80)  { c= d; trailing= 0; }
+      else if (d < 0xC0)  {
+          /* trailing byte in leading position */
+	  *outlen = out - outstart;
+	  *inlen = processed - instart;
+	  return(-2);
+      } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
+      else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
+      else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
+      else {
+          /* no chance for this in UTF-16 */
+	  *outlen = out - outstart;
+	  *inlen = processed - instart;
+	  return(-2);
+      }
+
+      if (inend - in < trailing) {
+          break;
+      } 
+
+      for ( ; trailing; trailing--) {
+          if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))  break;
+          c <<= 6;
+          c |= d & 0x3F;
+      }
+
+      /* assertion: c is a single UTF-4 value */
+        if (c < 0x10000) {
+            if (out >= outend)  break;
+	    if (xmlLittleEndian) {
+		tmp = (unsigned char *) out;
+		*tmp = c >> 8;
+		*(tmp + 1) = c;
+		out++;
+	    } else {
+		*out++ = c;
+	    }
+        }
+        else if (c < 0x110000) {
+            if (out+1 >= outend)  break;
+            c -= 0x10000;
+	    if (xmlLittleEndian) {
+		tmp1 = 0xD800 | (c >> 10);
+		tmp = (unsigned char *) out;
+		*tmp = tmp1 >> 8;
+		*(tmp + 1) = (unsigned char) tmp1;
+		out++;
+
+		tmp2 = 0xDC00 | (c & 0x03FF);
+		tmp = (unsigned char *) out;
+		*tmp = tmp2 >> 8;
+		*(tmp + 1) = (unsigned char) tmp2;
+		out++;
+	    } else {
+		*out++ = 0xD800 | (c >> 10);
+		*out++ = 0xDC00 | (c & 0x03FF);
+	    }
+        }
+        else
+	    break;
+	processed = in;
+    }
+    *outlen = (out - outstart) * 2;
+    *inlen = processed - instart;
+    return(*outlen);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Generic encoding handling routines			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlDetectCharEncoding:
+ * @in:  a pointer to the first bytes of the XML entity, must be at least
+ *       2 bytes long (at least 4 if encoding is UTF4 variant).
+ * @len:  pointer to the length of the buffer
+ *
+ * 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) 
+        return(XML_CHAR_ENCODING_NONE);
+    if (len >= 4) {
+	if ((in[0] == 0x00) && (in[1] == 0x00) &&
+	    (in[2] == 0x00) && (in[3] == 0x3C))
+	    return(XML_CHAR_ENCODING_UCS4BE);
+	if ((in[0] == 0x3C) && (in[1] == 0x00) &&
+	    (in[2] == 0x00) && (in[3] == 0x00))
+	    return(XML_CHAR_ENCODING_UCS4LE);
+	if ((in[0] == 0x00) && (in[1] == 0x00) &&
+	    (in[2] == 0x3C) && (in[3] == 0x00))
+	    return(XML_CHAR_ENCODING_UCS4_2143);
+	if ((in[0] == 0x00) && (in[1] == 0x3C) &&
+	    (in[2] == 0x00) && (in[3] == 0x00))
+	    return(XML_CHAR_ENCODING_UCS4_3412);
+	if ((in[0] == 0x4C) && (in[1] == 0x6F) &&
+	    (in[2] == 0xA7) && (in[3] == 0x94))
+	    return(XML_CHAR_ENCODING_EBCDIC);
+	if ((in[0] == 0x3C) && (in[1] == 0x3F) &&
+	    (in[2] == 0x78) && (in[3] == 0x6D))
+	    return(XML_CHAR_ENCODING_UTF8);
+	/*
+	 * Although not part of the recommendation, we also
+	 * attempt an "auto-recognition" of UTF-16LE and
+	 * UTF-16BE encodings.
+	 */
+	if ((in[0] == 0x3C) && (in[1] == 0x00) &&
+	    (in[2] == 0x3F) && (in[3] == 0x00))
+	    return(XML_CHAR_ENCODING_UTF16LE);
+	if ((in[0] == 0x00) && (in[1] == 0x3C) &&
+	    (in[2] == 0x00) && (in[3] == 0x3F))
+	    return(XML_CHAR_ENCODING_UTF16BE);
+    }
+    if (len >= 3) {
+	/*
+	 * Errata on XML-1.0 June 20 2001
+	 * We now allow an UTF8 encoded BOM
+	 */
+	if ((in[0] == 0xEF) && (in[1] == 0xBB) &&
+	    (in[2] == 0xBF))
+	    return(XML_CHAR_ENCODING_UTF8);
+    }
+    /* For UTF-16 we can recognize by the BOM */
+    if (len >= 2) {
+	if ((in[0] == 0xFE) && (in[1] == 0xFF))
+	    return(XML_CHAR_ENCODING_UTF16BE);
+	if ((in[0] == 0xFF) && (in[1] == 0xFE))
+	    return(XML_CHAR_ENCODING_UTF16LE);
+    }
+    return(XML_CHAR_ENCODING_NONE);
+}
+
+/**
+ * xmlCleanupEncodingAliases:
+ *
+ * Unregisters all aliases
+ */
+void
+xmlCleanupEncodingAliases(void) {
+    int i;
+
+    if (xmlCharEncodingAliases == NULL)
+	return;
+
+    for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
+	if (xmlCharEncodingAliases[i].name != NULL)
+	    xmlFree((char *) xmlCharEncodingAliases[i].name);
+	if (xmlCharEncodingAliases[i].alias != NULL)
+	    xmlFree((char *) xmlCharEncodingAliases[i].alias);
+    }
+    xmlCharEncodingAliasesNb = 0;
+    xmlCharEncodingAliasesMax = 0;
+    xmlFree(xmlCharEncodingAliases);
+    xmlCharEncodingAliases = NULL;
+}
+
+/**
+ * xmlGetEncodingAlias:
+ * @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 *
+xmlGetEncodingAlias(const char *alias) {
+    int i;
+    char upper[100];
+
+    if (alias == NULL)
+	return(NULL);
+
+    if (xmlCharEncodingAliases == NULL)
+	return(NULL);
+
+    for (i = 0;i < 99;i++) {
+        upper[i] = toupper(alias[i]);
+	if (upper[i] == 0) break;
+    }
+    upper[i] = 0;
+
+    /*
+     * Walk down the list looking for a definition of the alias
+     */
+    for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
+	if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
+	    return(xmlCharEncodingAliases[i].name);
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * xmlAddEncodingAlias:
+ * @name:  the encoding name as parsed, in UTF-8 format (ASCII actually)
+ * @alias:  the alias name as parsed, in UTF-8 format (ASCII actually)
+ *
+ * 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
+xmlAddEncodingAlias(const char *name, const char *alias) {
+    int i;
+    char upper[100];
+
+    if ((name == NULL) || (alias == NULL))
+	return(-1);
+
+    for (i = 0;i < 99;i++) {
+        upper[i] = toupper(alias[i]);
+	if (upper[i] == 0) break;
+    }
+    upper[i] = 0;
+
+    if (xmlCharEncodingAliases == NULL) {
+	xmlCharEncodingAliasesNb = 0;
+	xmlCharEncodingAliasesMax = 20;
+	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr) 
+	      xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
+	if (xmlCharEncodingAliases == NULL)
+	    return(-1);
+    } else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
+	xmlCharEncodingAliasesMax *= 2;
+	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr) 
+	      xmlRealloc(xmlCharEncodingAliases,
+		         xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
+    }
+    /*
+     * Walk down the list looking for a definition of the alias
+     */
+    for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
+	if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
+	    /*
+	     * Replace the definition.
+	     */
+	    xmlFree((char *) xmlCharEncodingAliases[i].name);
+	    xmlCharEncodingAliases[i].name = xmlMemStrdup(name);
+	    return(0);
+	}
+    }
+    /*
+     * Add the definition
+     */
+    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = xmlMemStrdup(name);
+    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = xmlMemStrdup(upper);
+    xmlCharEncodingAliasesNb++;
+    return(0);
+}
+
+/**
+ * xmlDelEncodingAlias:
+ * @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
+xmlDelEncodingAlias(const char *alias) {
+    int i;
+
+    if (alias == NULL)
+	return(-1);
+
+    if (xmlCharEncodingAliases == NULL)
+	return(-1);
+    /*
+     * Walk down the list looking for a definition of the alias
+     */
+    for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
+	if (!strcmp(xmlCharEncodingAliases[i].alias, alias)) {
+	    xmlFree((char *) xmlCharEncodingAliases[i].name);
+	    xmlFree((char *) xmlCharEncodingAliases[i].alias);
+	    xmlCharEncodingAliasesNb--;
+	    memmove(&xmlCharEncodingAliases[i], &xmlCharEncodingAliases[i + 1],
+		    sizeof(xmlCharEncodingAlias) * (xmlCharEncodingAliasesNb - i));
+	    return(0);
+	}
+    }
+    return(-1);
+}
+
+/**
+ * xmlParseCharEncoding:
+ * @name:  the encoding name as parsed, in UTF-8 format (ASCII actually)
+ *
+ * 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.
+ */
+xmlCharEncoding
+xmlParseCharEncoding(const char* name)
+{
+    const char *alias;
+    char upper[500];
+    int i;
+
+    if (name == NULL)
+	return(XML_CHAR_ENCODING_NONE);
+
+    /*
+     * Do the alias resolution
+     */
+    alias = xmlGetEncodingAlias(name);
+    if (alias != NULL)
+	name = alias;
+
+    for (i = 0;i < 499;i++) {
+        upper[i] = toupper(name[i]);
+	if (upper[i] == 0) break;
+    }
+    upper[i] = 0;
+
+    if (!strcmp(upper, "")) return(XML_CHAR_ENCODING_NONE);
+    if (!strcmp(upper, "UTF-8")) return(XML_CHAR_ENCODING_UTF8);
+    if (!strcmp(upper, "UTF8")) return(XML_CHAR_ENCODING_UTF8);
+
+    /*
+     * NOTE: if we were able to parse this, the endianness of UTF16 is
+     *       already found and in use
+     */
+    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);
+
+    /*
+     * NOTE: if we were able to parse this, the endianness of UCS4 is
+     *       already found and in use
+     */
+    if (!strcmp(upper, "ISO-10646-UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
+    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);
+
+    if (!strcmp(upper,  "ISO-8859-2")) return(XML_CHAR_ENCODING_8859_2);
+    if (!strcmp(upper,  "ISO-LATIN-2")) return(XML_CHAR_ENCODING_8859_2);
+    if (!strcmp(upper,  "ISO LATIN 2")) return(XML_CHAR_ENCODING_8859_2);
+
+    if (!strcmp(upper,  "ISO-8859-3")) return(XML_CHAR_ENCODING_8859_3);
+    if (!strcmp(upper,  "ISO-8859-4")) return(XML_CHAR_ENCODING_8859_4);
+    if (!strcmp(upper,  "ISO-8859-5")) return(XML_CHAR_ENCODING_8859_5);
+    if (!strcmp(upper,  "ISO-8859-6")) return(XML_CHAR_ENCODING_8859_6);
+    if (!strcmp(upper,  "ISO-8859-7")) return(XML_CHAR_ENCODING_8859_7);
+    if (!strcmp(upper,  "ISO-8859-8")) return(XML_CHAR_ENCODING_8859_8);
+    if (!strcmp(upper,  "ISO-8859-9")) return(XML_CHAR_ENCODING_8859_9);
+
+    if (!strcmp(upper, "ISO-2022-JP")) return(XML_CHAR_ENCODING_2022_JP);
+    if (!strcmp(upper, "SHIFT_JIS")) return(XML_CHAR_ENCODING_SHIFT_JIS);
+    if (!strcmp(upper, "EUC-JP")) return(XML_CHAR_ENCODING_EUC_JP);
+
+#ifdef DEBUG_ENCODING
+    xmlGenericError(xmlGenericErrorContext, "Unknown encoding %s\n", name);
+#endif
+    return(XML_CHAR_ENCODING_ERROR);
+}
+
+/**
+ * xmlGetCharEncodingName:
+ * @enc:  the encoding
+ *
+ * The "canonical" name for XML encoding.
+ * C.f. http://www.w3.org/TR/REC-xml#charencoding
+ * Section 4.3.3  Character Encoding in Entities
+ *
+ * Returns the canonical name for the given encoding
+ */
+
+const char*
+xmlGetCharEncodingName(xmlCharEncoding enc) {
+    switch (enc) {
+        case XML_CHAR_ENCODING_ERROR:
+	    return(NULL);
+        case XML_CHAR_ENCODING_NONE:
+	    return(NULL);
+        case XML_CHAR_ENCODING_UTF8:
+	    return("UTF-8");
+        case XML_CHAR_ENCODING_UTF16LE:
+	    return("UTF-16");
+        case XML_CHAR_ENCODING_UTF16BE:
+	    return("UTF-16");
+        case XML_CHAR_ENCODING_EBCDIC:
+            return("EBCDIC");
+        case XML_CHAR_ENCODING_UCS4LE:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4BE:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4_2143:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4_3412:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS2:
+            return("ISO-10646-UCS-2");
+        case XML_CHAR_ENCODING_8859_1:
+	    return("ISO-8859-1");
+        case XML_CHAR_ENCODING_8859_2:
+	    return("ISO-8859-2");
+        case XML_CHAR_ENCODING_8859_3:
+	    return("ISO-8859-3");
+        case XML_CHAR_ENCODING_8859_4:
+	    return("ISO-8859-4");
+        case XML_CHAR_ENCODING_8859_5:
+	    return("ISO-8859-5");
+        case XML_CHAR_ENCODING_8859_6:
+	    return("ISO-8859-6");
+        case XML_CHAR_ENCODING_8859_7:
+	    return("ISO-8859-7");
+        case XML_CHAR_ENCODING_8859_8:
+	    return("ISO-8859-8");
+        case XML_CHAR_ENCODING_8859_9:
+	    return("ISO-8859-9");
+        case XML_CHAR_ENCODING_2022_JP:
+            return("ISO-2022-JP");
+        case XML_CHAR_ENCODING_SHIFT_JIS:
+            return("Shift-JIS");
+        case XML_CHAR_ENCODING_EUC_JP:
+            return("EUC-JP");
+	case XML_CHAR_ENCODING_ASCII:
+	    return(NULL);
+    }
+    return(NULL);
+}
+
+/************************************************************************
+ *									*
+ *			Char encoding handlers				*
+ *									*
+ ************************************************************************/
+
+
+/* the size should be growable, but it's not a big deal ... */
+#define MAX_ENCODING_HANDLERS 50
+static xmlCharEncodingHandlerPtr *handlers = NULL;
+static int nbCharEncodingHandler = 0;
+
+/*
+ * The default is UTF-8 for XML, that's also the default used for the
+ * parser internals, so the default encoding handler is NULL
+ */
+
+static xmlCharEncodingHandlerPtr xmlDefaultCharEncodingHandler = NULL;
+
+/**
+ * xmlNewCharEncodingHandler:
+ * @name:  the encoding name, in UTF-8 format (ASCII actually)
+ * @input:  the xmlCharEncodingInputFunc to read that encoding
+ * @output:  the xmlCharEncodingOutputFunc to write that encoding
+ *
+ * Create and registers an xmlCharEncodingHandler.
+ *
+ * Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
+ */
+xmlCharEncodingHandlerPtr
+xmlNewCharEncodingHandler(const char *name, 
+                          xmlCharEncodingInputFunc input,
+                          xmlCharEncodingOutputFunc output) {
+    xmlCharEncodingHandlerPtr handler;
+    const char *alias;
+    char upper[500];
+    int i;
+    char *up = NULL;
+
+    /*
+     * Do the alias resolution
+     */
+    alias = xmlGetEncodingAlias(name);
+    if (alias != NULL)
+	name = alias;
+
+    /*
+     * Keep only the uppercase version of the encoding.
+     */
+    if (name == NULL) {
+        xmlEncodingErr(XML_I18N_NO_NAME,
+		       "xmlNewCharEncodingHandler : no name !\n", NULL);
+	return(NULL);
+    }
+    for (i = 0;i < 499;i++) {
+        upper[i] = toupper(name[i]);
+	if (upper[i] == 0) break;
+    }
+    upper[i] = 0;
+    up = xmlMemStrdup(upper);
+    if (up == NULL) {
+        xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
+	return(NULL);
+    }
+
+    /*
+     * allocate and fill-up an handler block.
+     */
+    handler = (xmlCharEncodingHandlerPtr)
+              xmlMalloc(sizeof(xmlCharEncodingHandler));
+    if (handler == NULL) {
+        xmlFree(up);
+        xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
+	return(NULL);
+    }
+    handler->input = input;
+    handler->output = output;
+    handler->name = up;
+
+#ifdef LIBXML_ICONV_ENABLED
+    handler->iconv_in = NULL;
+    handler->iconv_out = NULL;
+#endif
+#ifdef LIBXML_ICU_ENABLED
+    handler->uconv_in = NULL;
+    handler->uconv_out = NULL;
+#endif
+
+    /*
+     * registers and returns the handler.
+     */
+    xmlRegisterCharEncodingHandler(handler);
+#ifdef DEBUG_ENCODING
+    xmlGenericError(xmlGenericErrorContext,
+	    "Registered encoding handler for %s\n", name);
+#endif
+    return(handler);
+}
+
+/**
+ * xmlInitCharEncodingHandlers:
+ *
+ * Initialize the char encoding support, it registers the default
+ * encoding supported.
+ * NOTE: while public, this function usually doesn't need to be called
+ *       in normal processing.
+ */
+void
+xmlInitCharEncodingHandlers(void) {
+    unsigned short int tst = 0x1234;
+    unsigned char *ptr = (unsigned char *) &tst; 
+
+    if (handlers != NULL) return;
+
+    handlers = (xmlCharEncodingHandlerPtr *)
+        xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr));
+
+    if (*ptr == 0x12) xmlLittleEndian = 0;
+    else if (*ptr == 0x34) xmlLittleEndian = 1;
+    else {
+        xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
+	               "Odd problem at endianness detection\n", NULL);
+    }
+
+    if (handlers == NULL) {
+        xmlEncodingErrMemory("xmlInitCharEncodingHandlers : out of memory !\n");
+	return;
+    }
+    xmlNewCharEncodingHandler("UTF-8", UTF8ToUTF8, UTF8ToUTF8);
+#ifdef LIBXML_OUTPUT_ENABLED
+    xmlUTF16LEHandler = 
+          xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
+    xmlUTF16BEHandler = 
+          xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
+    xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, UTF8ToUTF16);
+    xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
+    xmlNewCharEncodingHandler("ASCII", asciiToUTF8, UTF8Toascii);
+    xmlNewCharEncodingHandler("US-ASCII", asciiToUTF8, UTF8Toascii);
+#ifdef LIBXML_HTML_ENABLED
+    xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
+#endif
+#else
+    xmlUTF16LEHandler = 
+          xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, NULL);
+    xmlUTF16BEHandler = 
+          xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, NULL);
+    xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, NULL);
+    xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, NULL);
+    xmlNewCharEncodingHandler("ASCII", asciiToUTF8, NULL);
+    xmlNewCharEncodingHandler("US-ASCII", asciiToUTF8, NULL);
+#endif /* LIBXML_OUTPUT_ENABLED */
+#if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
+#ifdef LIBXML_ISO8859X_ENABLED
+    xmlRegisterCharEncodingHandlersISO8859x ();
+#endif
+#endif
+
+}
+
+/**
+ * xmlCleanupCharEncodingHandlers:
+ *
+ * Cleanup the memory allocated for the char encoding support, it
+ * unregisters all the encoding handlers and the aliases.
+ */
+void
+xmlCleanupCharEncodingHandlers(void) {
+    xmlCleanupEncodingAliases();
+
+    if (handlers == NULL) return;
+
+    for (;nbCharEncodingHandler > 0;) {
+        nbCharEncodingHandler--;
+	if (handlers[nbCharEncodingHandler] != NULL) {
+	    if (handlers[nbCharEncodingHandler]->name != NULL)
+		xmlFree(handlers[nbCharEncodingHandler]->name);
+	    xmlFree(handlers[nbCharEncodingHandler]);
+	}
+    }
+    xmlFree(handlers);
+    handlers = NULL;
+    nbCharEncodingHandler = 0;
+    xmlDefaultCharEncodingHandler = NULL;
+}
+
+/**
+ * xmlRegisterCharEncodingHandler:
+ * @handler:  the xmlCharEncodingHandlerPtr handler block
+ *
+ * Register the char encoding handler, surprising, isn't it ?
+ */
+void
+xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
+    if (handlers == NULL) xmlInitCharEncodingHandlers();
+    if ((handler == NULL) || (handlers == NULL)) {
+        xmlEncodingErr(XML_I18N_NO_HANDLER,
+		"xmlRegisterCharEncodingHandler: NULL handler !\n", NULL);
+	return;
+    }
+
+    if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) {
+        xmlEncodingErr(XML_I18N_EXCESS_HANDLER,
+	"xmlRegisterCharEncodingHandler: Too many handler registered, see %s\n",
+	               "MAX_ENCODING_HANDLERS");
+	return;
+    }
+    handlers[nbCharEncodingHandler++] = handler;
+}
+
+/**
+ * xmlGetCharEncodingHandler:
+ * @enc:  an xmlCharEncoding value.
+ *
+ * Search in the registered set the handler able to read/write that encoding.
+ *
+ * Returns the handler or NULL if not found
+ */
+xmlCharEncodingHandlerPtr
+xmlGetCharEncodingHandler(xmlCharEncoding enc) {
+    xmlCharEncodingHandlerPtr handler;
+
+    if (handlers == NULL) xmlInitCharEncodingHandlers();
+    switch (enc) {
+        case XML_CHAR_ENCODING_ERROR:
+	    return(NULL);
+        case XML_CHAR_ENCODING_NONE:
+	    return(NULL);
+        case XML_CHAR_ENCODING_UTF8:
+	    return(NULL);
+        case XML_CHAR_ENCODING_UTF16LE:
+	    return(xmlUTF16LEHandler);
+        case XML_CHAR_ENCODING_UTF16BE:
+	    return(xmlUTF16BEHandler);
+        case XML_CHAR_ENCODING_EBCDIC:
+            handler = xmlFindCharEncodingHandler("EBCDIC");
+            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");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS-4");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS4");
+            if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_UCS4LE:
+            handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS-4");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS4");
+            if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_UCS4_2143:
+	    break;
+        case XML_CHAR_ENCODING_UCS4_3412:
+	    break;
+        case XML_CHAR_ENCODING_UCS2:
+            handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS-2");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS2");
+            if (handler != NULL) return(handler);
+	    break;
+
+	    /*
+	     * We used to keep ISO Latin encodings native in the
+	     * generated data. This led to so many problems that
+	     * this has been removed. One can still change this
+	     * back by registering no-ops encoders for those
+	     */
+        case XML_CHAR_ENCODING_8859_1:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-1");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_2:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-2");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_3:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-3");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_4:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-4");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_5:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-5");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_6:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-6");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_7:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-7");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_8:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-8");
+	    if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_8859_9:
+	    handler = xmlFindCharEncodingHandler("ISO-8859-9");
+	    if (handler != NULL) return(handler);
+	    break;
+
+
+        case XML_CHAR_ENCODING_2022_JP:
+            handler = xmlFindCharEncodingHandler("ISO-2022-JP");
+            if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_SHIFT_JIS:
+            handler = xmlFindCharEncodingHandler("SHIFT-JIS");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("SHIFT_JIS");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("Shift_JIS");
+            if (handler != NULL) return(handler);
+	    break;
+        case XML_CHAR_ENCODING_EUC_JP:
+            handler = xmlFindCharEncodingHandler("EUC-JP");
+            if (handler != NULL) return(handler);
+	    break;
+	default: 
+	    break;
+    }
+    
+#ifdef DEBUG_ENCODING
+    xmlGenericError(xmlGenericErrorContext,
+	    "No handler found for encoding %d\n", enc);
+#endif
+    return(NULL);
+}
+
+/**
+ * xmlFindCharEncodingHandler:
+ * @name:  a string describing the char encoding.
+ *
+ * Search in the registered set the handler able to read/write that encoding.
+ *
+ * Returns the handler or NULL if not found
+ */
+xmlCharEncodingHandlerPtr
+xmlFindCharEncodingHandler(const char *name) {
+    const char *nalias;
+    const char *norig;
+    xmlCharEncoding alias;
+#ifdef LIBXML_ICONV_ENABLED
+    xmlCharEncodingHandlerPtr enc;
+    iconv_t icv_in, icv_out;
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    xmlCharEncodingHandlerPtr enc;
+    uconv_t *ucv_in, *ucv_out;
+#endif /* LIBXML_ICU_ENABLED */
+    char upper[100];
+    int i;
+
+    if (handlers == NULL) xmlInitCharEncodingHandlers();
+    if (name == NULL) return(xmlDefaultCharEncodingHandler);
+    if (name[0] == 0) return(xmlDefaultCharEncodingHandler);
+
+    /*
+     * Do the alias resolution
+     */
+    norig = name;
+    nalias = xmlGetEncodingAlias(name);
+    if (nalias != NULL)
+	name = nalias;
+
+    /*
+     * Check first for directly registered encoding names
+     */
+    for (i = 0;i < 99;i++) {
+        upper[i] = toupper(name[i]);
+	if (upper[i] == 0) break;
+    }
+    upper[i] = 0;
+
+    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);
+#endif
+                return(handlers[i]);
+            }
+        }
+    }
+
+#ifdef LIBXML_ICONV_ENABLED
+    /* check whether iconv can handle this */
+    icv_in = iconv_open("UTF-8", name);
+    icv_out = iconv_open(name, "UTF-8");
+    if (icv_in == (iconv_t) -1) {
+        icv_in = iconv_open("UTF-8", upper);
+    }
+    if (icv_out == (iconv_t) -1) {
+	icv_out = iconv_open(upper, "UTF-8");
+    }
+    if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
+	    enc = (xmlCharEncodingHandlerPtr)
+	          xmlMalloc(sizeof(xmlCharEncodingHandler));
+	    if (enc == NULL) {
+	        iconv_close(icv_in);
+	        iconv_close(icv_out);
+		return(NULL);
+	    }
+	    enc->name = xmlMemStrdup(name);
+	    enc->input = NULL;
+	    enc->output = NULL;
+	    enc->iconv_in = icv_in;
+	    enc->iconv_out = icv_out;
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+		    "Found iconv handler for encoding %s\n", name);
+#endif
+	    return enc;
+    } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
+	    xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
+		    "iconv : problems with filters for '%s'\n", name);
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    /* check whether icu can handle this */
+    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) {
+                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;
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+		    "Found ICU converter handler for encoding %s\n", name);
+#endif
+	    return enc;
+    } else if (ucv_in != NULL || ucv_out != NULL) {
+            closeIcuConverter(ucv_in);
+            closeIcuConverter(ucv_out);
+	    xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
+		    "ICU converter : problems with filters for '%s'\n", name);
+    }
+#endif /* LIBXML_ICU_ENABLED */
+
+#ifdef DEBUG_ENCODING
+    xmlGenericError(xmlGenericErrorContext,
+	    "No handler found for encoding %s\n", name);
+#endif
+
+    /*
+     * Fallback using the canonical names
+     */
+    alias = xmlParseCharEncoding(norig);
+    if (alias != XML_CHAR_ENCODING_ERROR) {
+        const char* canon;
+        canon = xmlGetCharEncodingName(alias);
+        if ((canon != NULL) && (strcmp(name, canon))) {
+	    return(xmlFindCharEncodingHandler(canon));
+        }
+    }
+
+    /* If "none of the above", give up */
+    return(NULL);
+}
+
+/************************************************************************
+ *									*
+ *		ICONV based generic conversion functions		*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_ICONV_ENABLED
+/**
+ * xmlIconvWrapper:
+ * @cd:		iconv converter data structure
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of ISO Latin 1 chars
+ * @inlen:  the length of @in
+ *
+ * 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.
+ */
+static int
+xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
+                const unsigned char *in, int *inlen) {
+    size_t icv_inlen, icv_outlen;
+    const char *icv_in = (const char *) in;
+    char *icv_out = (char *) out;
+    int ret;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
+        if (outlen != NULL) *outlen = 0;
+        return(-1);
+    }
+    icv_inlen = *inlen;
+    icv_outlen = *outlen;
+    ret = iconv(cd, (ICONV_CONST char **) &icv_in, &icv_inlen, &icv_out, &icv_outlen);
+    *inlen -= icv_inlen;
+    *outlen -= icv_outlen;
+    if ((icv_inlen != 0) || (ret == -1)) {
+#ifdef EILSEQ
+        if (errno == EILSEQ) {
+            return -2;
+        } else
+#endif
+#ifdef E2BIG
+        if (errno == E2BIG) {
+            return -1;
+        } else
+#endif
+#ifdef EINVAL
+        if (errno == EINVAL) {
+            return -3;
+        } else
+#endif
+        {
+            return -3;
+        }
+    }
+    return 0;
+}
+#endif /* LIBXML_ICONV_ENABLED */
+
+/************************************************************************
+ *									*
+ *		ICU based generic conversion functions	         	*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_ICU_ENABLED
+/**
+ * xmlUconvWrapper:
+ * @cd: ICU uconverter data structure
+ * @toUnicode : non-zero if toUnicode. 0 otherwise.
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of ISO Latin 1 chars
+ * @inlen:  the length of @in
+ *
+ * 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.
+ */
+static int
+xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
+                const unsigned char *in, int *inlen) {
+    const char *ucv_in = (const char *) in;
+    char *ucv_out = (char *) out;
+    UErrorCode err = U_ZERO_ERROR;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
+        if (outlen != NULL) *outlen = 0;
+        return(-1);
+    }
+
+    /* 
+     * TODO(jungshik)
+     * 1. is ucnv_convert(To|From)Algorithmic better?
+     * 2. had we better use an explicit pivot buffer?
+     * 3. error returned comes from 'fromUnicode' only even
+     *    when toUnicode is true !
+     */
+    if (toUnicode) {
+        /* encoding => UTF-16 => UTF-8 */
+        ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen,
+                       &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
+                       0, 1, &err);
+    } else {
+        /* UTF-8 => UTF-16 => encoding */
+        ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen,
+                       &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
+                       0, 1, &err);
+    }
+    *inlen = ucv_in - (const char*) in; 
+    *outlen = ucv_out - (char *) out;
+    if (U_SUCCESS(err))
+        return 0;
+    if (err == U_BUFFER_OVERFLOW_ERROR)
+        return -1;
+    if (err == U_INVALID_CHAR_FOUND || err == U_ILLEGAL_CHAR_FOUND)
+        return -2;
+    /* if (err == U_TRUNCATED_CHAR_FOUND) */
+    return -3;
+}
+#endif /* LIBXML_ICU_ENABLED */
+
+/************************************************************************
+ *									*
+ *		The real API used by libxml for on-the-fly conversion	*
+ *									*
+ ************************************************************************/
+int
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                       xmlBufferPtr in, int len);
+
+/**
+ * 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
+ *     -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
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                       xmlBufferPtr in, int len) {
+    int ret = -2;
+    int written;
+    int toconv;
+
+    if (handler == NULL) return(-1);
+    if (out == NULL) return(-1);
+    if (in == NULL) return(-1);
+
+    /* calculate space available */
+    written = out->size - out->use;
+    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 (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;
+    }
+
+    if (handler->input != NULL) {
+	ret = handler->input(&out->content[out->use], &written,
+	                     in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	out->content[out->use] = 0;
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_in != NULL) {
+	ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
+	                      &written, in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	out->content[out->use] = 0;
+	if (ret == -1) ret = -3;
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    else if (handler->uconv_in != NULL) {
+	ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
+	                      &written, in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	out->content[out->use] = 0;
+	if (ret == -1) ret = -3;
+    }
+#endif /* LIBXML_ICU_ENABLED */
+#ifdef DEBUG_ENCODING
+    switch (ret) {
+        case 0:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "converted %d bytes to %d bytes of input\n",
+	            toconv, written);
+	    break;
+        case -1:
+	    xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
+	            toconv, written, in->use);
+	    break;
+        case -2:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "input conversion failed due to input error\n");
+	    break;
+        case -3:
+	    xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
+	            toconv, written, in->use);
+	    break;
+	default:
+	    xmlGenericError(xmlGenericErrorContext,"Unknown input conversion failed %d\n", ret);
+    }
+#endif /* DEBUG_ENCODING */
+    /*
+     * Ignore when input buffer is not on a boundary
+     */
+    if (ret == -3) ret = 0;
+    if (ret == -1) ret = 0;
+    return(ret);
+}
+
+/**
+ * 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
+ *     -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
+xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
+                 xmlBufferPtr in)
+{
+    int ret = -2;
+    int written;
+    int toconv;
+
+    if (handler == NULL)
+        return (-1);
+    if (out == NULL)
+        return (-1);
+    if (in == NULL)
+        return (-1);
+
+    toconv = in->use;
+    if (toconv == 0)
+        return (0);
+    written = out->size - out->use;
+    if (toconv * 2 >= written) {
+        xmlBufferGrow(out, out->size + toconv * 2);
+        written = out->size - out->use - 1;
+    }
+    if (handler->input != NULL) {
+        ret = handler->input(&out->content[out->use], &written,
+                             in->content, &toconv);
+        xmlBufferShrink(in, toconv);
+        out->use += written;
+        out->content[out->use] = 0;
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_in != NULL) {
+        ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
+                              &written, in->content, &toconv);
+        xmlBufferShrink(in, toconv);
+        out->use += written;
+        out->content[out->use] = 0;
+        if (ret == -1)
+            ret = -3;
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    else if (handler->uconv_in != NULL) {
+        ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
+                              &written, in->content, &toconv);
+        xmlBufferShrink(in, toconv);
+        out->use += written;
+        out->content[out->use] = 0;
+        if (ret == -1)
+            ret = -3;
+    }
+#endif /* LIBXML_ICU_ENABLED */
+    switch (ret) {
+        case 0:
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+                            "converted %d bytes to %d bytes of input\n",
+                            toconv, written);
+#endif
+            break;
+        case -1:
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+                         "converted %d bytes to %d bytes of input, %d left\n",
+                            toconv, written, in->use);
+#endif
+            break;
+        case -3:
+#ifdef DEBUG_ENCODING
+            xmlGenericError(xmlGenericErrorContext,
+                        "converted %d bytes to %d bytes of input, %d left\n",
+                            toconv, written, in->use);
+#endif
+            break;
+        case -2: {
+            char buf[50];
+
+	    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;
+	    xmlEncodingErr(XML_I18N_CONV_FAILED,
+		    "input conversion failed due to input error, bytes %s\n",
+		           buf);
+        }
+    }
+    /*
+     * Ignore when input buffer is not on a boundary
+     */
+    if (ret == -3)
+        ret = 0;
+    return (written? written : ret);
+}
+
+/**
+ * xmlCharEncOutFunc:
+ * @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 
+ * output in case of non-stateless encoding needing to initiate their
+ * state or the output (like the BOM in UTF16).
+ * In case of UTF8 sequence conversion errors for the given encoder,
+ * the content will be automatically remapped to a CharRef sequence.
+ *     
+ * Returns the number of byte written if success, or 
+ *     -1 general error
+ *     -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
+xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                  xmlBufferPtr in) {
+    int ret = -2;
+    int written;
+    int writtentot = 0;
+    int toconv;
+    int output = 0;
+
+    if (handler == NULL) return(-1);
+    if (out == NULL) return(-1);
+
+retry:
+    
+    written = out->size - out->use;
+
+    if (written > 0)
+	written--; /* Gennady: count '/0' */
+
+    /*
+     * First specific handling of in = NULL, i.e. the initialization call
+     */
+    if (in == NULL) {
+        toconv = 0;
+	if (handler->output != NULL) {
+	    ret = handler->output(&out->content[out->use], &written,
+				  NULL, &toconv);
+	    if (ret >= 0) { /* Gennady: check return value */
+		out->use += written;
+		out->content[out->use] = 0;
+	    }
+	}
+#ifdef LIBXML_ICONV_ENABLED
+	else if (handler->iconv_out != NULL) {
+	    ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
+				  &written, NULL, &toconv);
+	    out->use += written;
+	    out->content[out->use] = 0;
+	}
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+	else if (handler->uconv_out != NULL) {
+	    ret = xmlUconvWrapper(handler->uconv_out, 0,
+                              &out->content[out->use],
+ 				              &written, NULL, &toconv);
+	    out->use += written;
+	    out->content[out->use] = 0;
+	}
+#endif /* LIBXML_ICU_ENABLED */
+#ifdef DEBUG_ENCODING
+	xmlGenericError(xmlGenericErrorContext,
+		"initialized encoder\n");
+#endif
+        return(0);
+    }
+
+    /*
+     * Conversion itself.
+     */
+    toconv = in->use;
+    if (toconv == 0)
+	return(0);
+    if (toconv * 4 >= written) {
+        xmlBufferGrow(out, toconv * 4);
+	written = out->size - out->use - 1;
+    }
+    if (handler->output != NULL) {
+	ret = handler->output(&out->content[out->use], &written,
+	                      in->content, &toconv);
+	if (written > 0) {
+	    xmlBufferShrink(in, toconv);
+	    out->use += written;
+	    writtentot += written;
+	} 
+	out->content[out->use] = 0;
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_out != NULL) {
+	ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
+	                      &written, in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	writtentot += written;
+	out->content[out->use] = 0;
+	if (ret == -1) {
+	    if (written > 0) {
+		/*
+		 * Can be a limitation of iconv
+		 */
+		goto retry;
+	    }
+	    ret = -3;
+	}
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    else if (handler->uconv_out != NULL) {
+	ret = xmlUconvWrapper(handler->uconv_out, 0,
+                              &out->content[out->use],
+	                      &written, in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	writtentot += written;
+	out->content[out->use] = 0;
+	if (ret == -1) {
+	    if (written > 0) {
+		/*
+		 * Can be a limitation of iconv
+		 */
+		goto retry;
+	    }
+	    ret = -3;
+	}
+    }
+#endif /* LIBXML_ICU_ENABLED */
+    else {
+	xmlEncodingErr(XML_I18N_NO_OUTPUT,
+		       "xmlCharEncOutFunc: no output function !\n", NULL);
+	return(-1);
+    }
+
+    if (ret >= 0) output += ret;
+
+    /*
+     * Attempt to handle error cases
+     */
+    switch (ret) {
+        case 0:
+#ifdef DEBUG_ENCODING
+	    xmlGenericError(xmlGenericErrorContext,
+		    "converted %d bytes to %d bytes of output\n",
+	            toconv, written);
+#endif
+	    break;
+        case -1:
+#ifdef DEBUG_ENCODING
+	    xmlGenericError(xmlGenericErrorContext,
+		    "output conversion failed by lack of space\n");
+#endif
+	    break;
+        case -3:
+#ifdef DEBUG_ENCODING
+	    xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
+	            toconv, written, in->use);
+#endif
+	    break;
+        case -2: {
+	    int len = in->use;
+	    const xmlChar *utf = (const xmlChar *) in->content;
+	    int cur;
+
+	    cur = xmlGetUTF8Char(utf, &len);
+	    if (cur > 0) {
+		xmlChar charref[20];
+
+#ifdef DEBUG_ENCODING
+		xmlGenericError(xmlGenericErrorContext,
+			"handling output conversion error\n");
+		xmlGenericError(xmlGenericErrorContext,
+			"Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			in->content[0], in->content[1],
+			in->content[2], in->content[3]);
+#endif
+		/*
+		 * Removes the UTF8 sequence, and replace it by a charref
+		 * and continue the transcoding phase, hoping the error
+		 * did not mangle the encoder state.
+		 */
+		snprintf((char *) &charref[0], sizeof(charref), "&#%d;", cur);
+		xmlBufferShrink(in, len);
+		xmlBufferAddHead(in, charref, -1);
+
+		goto retry;
+	    } else {
+		char buf[50];
+
+		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;
+		xmlEncodingErr(XML_I18N_CONV_FAILED,
+		    "output conversion failed due to conv error, bytes %s\n",
+			       buf);
+		if (in->alloc != XML_BUFFER_ALLOC_IMMUTABLE)
+		    in->content[0] = ' ';
+	    }
+	    break;
+	}
+    }
+    return(ret);
+}
+
+/**
+ * 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
+ */
+int
+xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
+    int ret = 0;
+    if (handler == NULL) return(-1);
+    if (handler->name == NULL) return(-1);
+#ifdef LIBXML_ICONV_ENABLED
+    /*
+     * Iconv handlers can be used only once, free the whole block.
+     * and the associated icon resources.
+     */
+    if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
+	if (handler->name != NULL)
+	    xmlFree(handler->name);
+	handler->name = NULL;
+	if (handler->iconv_out != NULL) {
+	    if (iconv_close(handler->iconv_out))
+		ret = -1;
+	    handler->iconv_out = NULL;
+	}
+	if (handler->iconv_in != NULL) {
+	    if (iconv_close(handler->iconv_in))
+		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;
+	if (handler->uconv_out != NULL) {
+	    closeIcuConverter(handler->uconv_out);
+	    handler->uconv_out = NULL;
+	}
+	if (handler->uconv_in != NULL) {
+	    closeIcuConverter(handler->uconv_in);
+	    handler->uconv_in = NULL;
+	}
+	xmlFree(handler);
+    }
+#endif
+#ifdef DEBUG_ENCODING
+    if (ret)
+        xmlGenericError(xmlGenericErrorContext,
+		"failed to close the encoding handler\n");
+    else
+        xmlGenericError(xmlGenericErrorContext,
+		"closed the encoding handler\n");
+#endif
+
+    return(ret);
+}
+
+/**
+ * xmlByteConsumed:
+ * @ctxt: an XML parser context
+ *
+ * This function provides the current index of the parser relative
+ * to the start of the current entity. This function is computed in
+ * bytes from the beginning starting at zero and finishing at the
+ * size in byte of the file if parsing a file. The function is
+ * of constant cost if the input is UTF-8 but can be costly if run
+ * on non-UTF-8 input.
+ *
+ * Returns the index in bytes from the beginning of the entity or -1
+ *         in case the index could not be computed.
+ */
+long
+xmlByteConsumed(xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr in;
+    
+    if (ctxt == NULL) return(-1);
+    in = ctxt->input;
+    if (in == NULL)  return(-1);
+    if ((in->buf != NULL) && (in->buf->encoder != NULL)) {
+        unsigned int unused = 0;
+	xmlCharEncodingHandler * handler = in->buf->encoder;
+        /*
+	 * Encoding conversion, compute the number of unused original
+	 * bytes from the input not consumed and substract that from
+	 * the raw consumed value, this is not a cheap operation
+	 */
+        if (in->end - in->cur > 0) {
+	    unsigned char convbuf[32000];
+	    const unsigned char *cur = (const unsigned char *)in->cur;
+	    int toconv = in->end - in->cur, written = 32000;
+
+	    int ret;
+
+	    if (handler->output != NULL) {
+	        do {
+		    toconv = in->end - cur;
+		    written = 32000;
+		    ret = handler->output(&convbuf[0], &written,
+				      cur, &toconv);
+		    if (ret == -1) return(-1);
+		    unused += written;
+		    cur += toconv;
+		} while (ret == -2);
+#ifdef LIBXML_ICONV_ENABLED
+	    } else if (handler->iconv_out != NULL) {
+	        do {
+		    toconv = in->end - cur;
+		    written = 32000;
+		    ret = xmlIconvWrapper(handler->iconv_out, &convbuf[0],
+	                      &written, cur, &toconv);
+		    if (ret < 0) {
+		        if (written > 0)
+			    ret = -2;
+			else
+			    return(-1);
+		    }
+		    unused += written;
+		    cur += toconv;
+		} while (ret == -2);
+#endif
+#ifdef LIBXML_ICU_ENABLED
+	    } else if (handler->uconv_out != NULL) {
+	        do {
+		    toconv = in->end - cur;
+		    written = 32000;
+		    ret = xmlUconvWrapper(handler->uconv_out, 0, &convbuf[0],
+	                      &written, cur, &toconv);
+		    if (ret < 0) {
+		        if (written > 0)
+			    ret = -2;
+			else
+			    return(-1);
+		    }
+		    unused += written;
+		    cur += toconv;
+		} while (ret == -2);
+            } else {
+	        /* could not find a converter */
+	        return(-1);
+	    }
+	}
+	if (in->buf->rawconsumed < unused)
+	    return(-1);
+	return(in->buf->rawconsumed - unused);
+    }
+    return(in->consumed + (in->cur - in->base));
+}
+#endif
+
+#if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
+#ifdef LIBXML_ISO8859X_ENABLED
+
+/**
+ * UTF8ToISO8859x:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ * @xlattable: the 2-level transcoding table
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an ISO 8859-*
+ * block of chars out.
+ *
+ * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * 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.
+ */
+static int
+UTF8ToISO8859x(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen,
+              unsigned char const *xlattable) {
+    const unsigned char* outstart = out;
+    const unsigned char* inend;
+    const unsigned char* instart = in;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
+        (xlattable == NULL))
+	return(-1);
+    if (in == NULL) {
+        /*
+        * initialization nothing to do
+        */
+        *outlen = 0;
+        *inlen = 0;
+        return(0);
+    }
+    inend = in + (*inlen);
+    while (in < inend) {
+        unsigned char d = *in++;
+        if  (d < 0x80)  {
+            *out++ = d; 
+        } else if (d < 0xC0) {
+            /* trailing byte in leading position */
+            *outlen = out - outstart;
+            *inlen = in - instart - 1;
+            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);
+            }
+            c = *in++;
+            if ((c & 0xC0) != 0x80) {
+                /* not a trailing byte */
+                *outlen = out - outstart;
+                *inlen = in - instart - 2;
+                return(-2);
+            }
+            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;
+                return(-2);
+            }
+            *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);
+            }
+            c1 = *in++;
+            if ((c1 & 0xC0) != 0x80) {
+                /* not a trailing byte (c1) */
+                *outlen = out - outstart;
+                *inlen = in - instart - 2;
+                return(-2);
+            }
+            c2 = *in++;
+            if ((c2 & 0xC0) != 0x80) {
+                /* not a trailing byte (c2) */
+                *outlen = out - outstart;
+                *inlen = in - instart - 2;
+                return(-2);
+            }
+            c1 = c1 & 0x3F; 
+            c2 = c2 & 0x3F; 
+	    d = d & 0x0F;
+	    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;
+                return(-2);
+            }
+            *out++ = d; 
+        } else {
+            /* cannot transcode >= U+010000 */
+            *outlen = out - outstart;
+            *inlen = in - instart - 1;
+            return(-2);
+        }
+    }
+    *outlen = out - outstart;
+    *inlen = in - instart;
+    return(*outlen);
+}
+
+/**
+ * ISO8859xToUTF8
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of ISO Latin 1 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of ISO 8859-* chars in and try to convert it to an UTF-8
+ * block of chars out.
+ * Returns 0 if success, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ * The value of @outlen after return is the number of ocetes produced.
+ */
+static int
+ISO8859xToUTF8(unsigned char* out, int *outlen,
+              const unsigned char* in, int *inlen,
+              unsigned short const *unicodetable) {
+    unsigned char* outstart = out;
+    unsigned char* outend;
+    const unsigned char* instart = in;
+    const unsigned char* inend;
+    const unsigned char* instop;
+    unsigned int c;
+
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
+        (in == NULL) || (unicodetable == NULL))
+	return(-1);
+    outend = out + *outlen;
+    inend = in + *inlen;
+    instop = inend;
+    c = *in;
+    while (in < inend && out < outend - 1) {
+        if (c >= 0x80) {
+            c = unicodetable [c - 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;
+            } else {
+                *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 (in < inend && out < outend && c < 0x80) {
+        *out++ =  c;
+        ++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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_2 [48 + 6 * 64] = {
+    "\x00\x00\x01\x05\x02\x04\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\xa4\x00\x00\xa7\xa8\x00\x00\x00\x00\xad\x00\x00"
+    "\xb0\x00\x00\x00\xb4\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xc3\xe3\xa1\xb1\xc6\xe6\x00\x00\x00\x00\xc8\xe8\xcf\xef"
+    "\xd0\xf0\x00\x00\x00\x00\x00\x00\xca\xea\xcc\xec\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xe5\x00\x00\xa5\xb5\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xff\x00\xb2\x00\xbd\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\xa3\xb3\xd1\xf1\x00\x00\xd2\xf2\x00\x00\x00\x00\x00\x00\x00"
+    "\xd5\xf5\x00\x00\xc0\xe0\x00\x00\xd8\xf8\xa6\xb6\x00\x00\xaa\xba"
+    "\xa9\xb9\xde\xfe\xab\xbb\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xf9"
+    "\xdb\xfb\x00\x00\x00\x00\x00\x00\x00\xac\xbc\xaf\xbf\xae\xbe\x00"
+    "\x00\xc1\xc2\x00\xc4\x00\x00\xc7\x00\xc9\x00\xcb\x00\xcd\xce\x00"
+    "\x00\x00\x00\xd3\xd4\x00\xd6\xd7\x00\x00\xda\x00\xdc\xdd\x00\xdf"
+    "\x00\xe1\xe2\x00\xe4\x00\x00\xe7\x00\xe9\x00\xeb\x00\xed\xee\x00"
+    "\x00\x00\x00\xf3\xf4\x00\xf6\xf7\x00\x00\xfa\x00\xfc\xfd\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_3 [48 + 7 * 64] = {
+    "\x04\x00\x01\x06\x02\x05\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\xa3\xa4\x00\x00\xa7\xa8\x00\x00\x00\x00\xad\x00\x00"
+    "\xb0\x00\xb2\xb3\xb4\xb5\x00\xb7\xb8\x00\x00\x00\x00\xbd\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\xc6\xe6\xc5\xe5\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xf8\xab\xbb"
+    "\xd5\xf5\x00\x00\xa6\xb6\xa1\xb1\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xa9\xb9\x00\x00\xac\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xff\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xfe\xaa\xba"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xfd\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xbf\x00\x00\x00"
+    "\xc0\xc1\xc2\x00\xc4\x00\x00\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\x00\xd1\xd2\xd3\xd4\x00\xd6\xd7\x00\xd9\xda\xdb\xdc\x00\x00\xdf"
+    "\xe0\xe1\xe2\x00\xe4\x00\x00\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\x00\xf1\xf2\xf3\xf4\x00\xf6\xf7\x00\xf9\xfa\xfb\xfc\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_4 [48 + 6 * 64] = {
+    "\x00\x00\x01\x05\x02\x03\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\xa4\x00\x00\xa7\xa8\x00\x00\x00\x00\xad\x00\xaf"
+    "\xb0\x00\x00\x00\xb4\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00"
+    "\xc0\xe0\x00\x00\xa1\xb1\x00\x00\x00\x00\x00\x00\xc8\xe8\x00\x00"
+    "\xd0\xf0\xaa\xba\x00\x00\xcc\xec\xca\xea\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xab\xbb\x00\x00\x00\x00\xa5\xb5\xcf\xef\x00\x00\xc7\xe7"
+    "\x00\x00\x00\x00\x00\x00\xd3\xf3\xa2\x00\x00\xa6\xb6\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\xd1\xf1\x00\x00\x00\xbd\xbf\xd2\xf2\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\xa3\xb3\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xa9\xb9\x00\x00\x00\x00\xac\xbc\xdd\xfd\xde\xfe\x00\x00\x00\x00"
+    "\x00\x00\xd9\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\xbe\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\xb2\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\xc1\xc2\xc3\xc4\xc5\xc6\x00\x00\xc9\x00\xcb\x00\xcd\xce\x00"
+    "\x00\x00\x00\x00\xd4\xd5\xd6\xd7\xd8\x00\xda\xdb\xdc\x00\x00\xdf"
+    "\x00\xe1\xe2\xe3\xe4\xe5\xe6\x00\x00\xe9\x00\xeb\x00\xed\xee\x00"
+    "\x00\x00\x00\x00\xf4\xf5\xf6\xf7\xf8\x00\xfa\xfb\xfc\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_5 [48 + 6 * 64] = {
+    "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\x00\x00\x00\xfd\x00\x00\x00\x00\x00\xad\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\x00\xae\xaf"
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\x00\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\x00\xfe\xff"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_6 [48 + 5 * 64] = {
+    "\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\xad\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\xbf"
+    "\x00\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\x00\x00\x00\x00\x00"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\xf0\xf1\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_7 [48 + 7 * 64] = {
+    "\x04\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x06"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\xa3\x00\x00\xa6\xa7\xa8\xa9\x00\xab\xac\xad\x00\x00"
+    "\xb0\xb1\xb2\xb3\x00\x00\x00\xb7\x00\x00\x00\xbb\x00\xbd\x00\x00"
+    "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\xaf\x00\x00\xa1\xa2\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\xb4\xb5\xb6\x00\xb8\xb9\xba\x00\xbc\x00\xbe\xbf"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\xd0\xd1\x00\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_8 [48 + 7 * 64] = {
+    "\x02\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\x00\xab\xac\xad\xae\xaf"
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\x00\xbb\xbc\xbd\xbe\x00"
+    "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xfe"
+    "\x00\x00\x00\x00\x00\x00\x00\xdf\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_9 [48 + 5 * 64] = {
+    "\x00\x00\x01\x02\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\x00\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\x00\x00\xdf"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\x00\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\x00\x00\xff"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xf0"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xdd\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xfe"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_10 [48 + 7 * 64] = {
+    "\x00\x00\x01\x06\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x00\x00\xad\x00\x00"
+    "\xb0\x00\x00\x00\x00\x00\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xc0\xe0\x00\x00\xa1\xb1\x00\x00\x00\x00\x00\x00\xc8\xe8\x00\x00"
+    "\xa9\xb9\xa2\xb2\x00\x00\xcc\xec\xca\xea\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xa3\xb3\x00\x00\x00\x00\xa5\xb5\xa4\xb4\x00\x00\xc7\xe7"
+    "\x00\x00\x00\x00\x00\x00\xa6\xb6\xff\x00\x00\xa8\xb8\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\xd1\xf1\x00\x00\x00\xaf\xbf\xd2\xf2\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xaa\xba\x00\x00\x00\x00\xab\xbb\xd7\xf7\xae\xbe\x00\x00\x00\x00"
+    "\x00\x00\xd9\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\xbc\x00"
+    "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\xc1\xc2\xc3\xc4\xc5\xc6\x00\x00\xc9\x00\xcb\x00\xcd\xce\xcf"
+    "\xd0\x00\x00\xd3\xd4\xd5\xd6\x00\xd8\x00\xda\xdb\xdc\xdd\xde\xdf"
+    "\x00\xe1\xe2\xe3\xe4\xe5\xe6\x00\x00\xe9\x00\xeb\x00\xed\xee\xef"
+    "\xf0\x00\x00\xf3\xf4\xf5\xf6\x00\xf8\x00\xfa\xfb\xfc\xfd\xfe\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_11 [48 + 6 * 64] = {
+    "\x04\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x05\x00\x00\x00\x00\x00\x00"
+    "\x00\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+    "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\x00\x00\x00\x00\xdf"
+    "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_13 [48 + 7 * 64] = {
+    "\x00\x00\x01\x04\x06\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\xa2\xa3\xa4\x00\xa6\xa7\x00\xa9\x00\xab\xac\xad\xae\x00"
+    "\xb0\xb1\xb2\xb3\x00\xb5\xb6\xb7\x00\xb9\x00\xbb\xbc\xbd\xbe\x00"
+    "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\xb4\xa1\xa5\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\xc4\xc5\xaf\x00\x00\xc9\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\xd3\x00\xd5\xd6\xd7\xa8\x00\x00\x00\xdc\x00\x00\xdf"
+    "\x00\x00\x00\x00\xe4\xe5\xbf\x00\x00\xe9\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\xf3\x00\xf5\xf6\xf7\xb8\x00\x00\x00\xfc\x00\x00\x00"
+    "\x00\xd9\xf9\xd1\xf1\xd2\xf2\x00\x00\x00\x00\x00\xd4\xf4\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\xaa\xba\x00\x00\xda\xfa\x00\x00\x00\x00"
+    "\xd0\xf0\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfb\x00\x00\x00\x00"
+    "\x00\x00\xd8\xf8\x00\x00\x00\x00\x00\xca\xea\xdd\xfd\xde\xfe\x00"
+    "\xc2\xe2\x00\x00\xc0\xe0\xc3\xe3\x00\x00\x00\x00\xc8\xe8\x00\x00"
+    "\x00\x00\xc7\xe7\x00\x00\xcb\xeb\xc6\xe6\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xcc\xec\x00\x00\x00\x00\x00\x00\xce\xee\x00\x00\xc1\xe1"
+    "\x00\x00\x00\x00\x00\x00\xcd\xed\x00\x00\x00\xcf\xef\x00\x00\x00"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_14 [48 + 10 * 64] = {
+    "\x00\x00\x01\x09\x04\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\xa3\x00\x00\x00\xa7\x00\xa9\x00\x00\x00\xad\xae\x00"
+    "\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x08\x05\x06\x00\x00\x00\x00"
+    "\x00\x00\xa1\xa2\x00\x00\x00\x00\x00\x00\xa6\xab\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb1"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\xa5\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xb2\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xa8\xb8\xaa\xba\xbd\xbe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xac\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\xd0\xf0\xde\xfe\xaf\x00\x00\x00\x00\x00\x00\x00"
+    "\xb4\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\xb7\xb9\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xbb\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xd7\xf7\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\x00\xd1\xd2\xd3\xd4\xd5\xd6\x00\xd8\xd9\xda\xdb\xdc\xdd\x00\xdf"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\x00\xf1\xf2\xf3\xf4\xf5\xf6\x00\xf8\xf9\xfa\xfb\xfc\xfd\x00\xff"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_15 [48 + 6 * 64] = {
+    "\x00\x00\x01\x05\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\xa1\xa2\xa3\x00\xa5\x00\xa7\x00\xa9\xaa\xab\xac\xad\xae\xaf"
+    "\xb0\xb1\xb2\xb3\x00\xb5\xb6\xb7\x00\xb9\xba\xbb\x00\x00\x00\xbf"
+    "\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\xbc\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xa6\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\xbe\x00\x00\x00\x00\xb4\xb8\x00"
+    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+};
+
+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, 
+};
+
+static unsigned char const xmltranscodetable_ISO8859_16 [48 + 9 * 64] = {
+    "\x00\x00\x01\x08\x02\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+    "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+    "\xa0\x00\x00\x00\x00\x00\x00\xa7\x00\xa9\x00\xab\x00\xad\x00\x00"
+    "\xb0\xb1\x00\x00\x00\x00\xb6\xb7\x00\x00\x00\xbb\x00\x00\x00\x00"
+    "\x00\x00\xc3\xe3\xa1\xa2\xc5\xe5\x00\x00\x00\x00\xb2\xb9\x00\x00"
+    "\xd0\xf0\x00\x00\x00\x00\x00\x00\xdd\xfd\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\xa3\xb3\xd1\xf1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xd5\xf5\xbc\xbd\x00\x00\x00\x00\x00\x00\xd7\xf7\x00\x00\x00\x00"
+    "\xa6\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xd8\xf8\x00\x00\x00\x00\x00\x00\xbe\xac\xae\xaf\xbf\xb4\xb8\x00"
+    "\x06\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\xa5\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xba\xde\xfe\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\xc0\xc1\xc2\x00\xc4\x00\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+    "\x00\x00\xd2\xd3\xd4\x00\xd6\x00\x00\xd9\xda\xdb\xdc\x00\x00\xdf"
+    "\xe0\xe1\xe2\x00\xe4\x00\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+    "\x00\x00\xf2\xf3\xf4\x00\xf6\x00\x00\xf9\xfa\xfb\xfc\x00\x00\xff"
+};
+
+
+/*
+ * auto-generated functions for ISO-8859-2 .. ISO-8859-16
+ */
+
+static int ISO8859_2ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_2);
+}
+static int UTF8ToISO8859_2 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_2);
+}
+
+static int ISO8859_3ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_3);
+}
+static int UTF8ToISO8859_3 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_3);
+}
+
+static int ISO8859_4ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_4);
+}
+static int UTF8ToISO8859_4 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_4);
+}
+
+static int ISO8859_5ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_5);
+}
+static int UTF8ToISO8859_5 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_5);
+}
+
+static int ISO8859_6ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_6);
+}
+static int UTF8ToISO8859_6 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_6);
+}
+
+static int ISO8859_7ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_7);
+}
+static int UTF8ToISO8859_7 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_7);
+}
+
+static int ISO8859_8ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_8);
+}
+static int UTF8ToISO8859_8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_8);
+}
+
+static int ISO8859_9ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_9);
+}
+static int UTF8ToISO8859_9 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_9);
+}
+
+static int ISO8859_10ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_10);
+}
+static int UTF8ToISO8859_10 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_10);
+}
+
+static int ISO8859_11ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_11);
+}
+static int UTF8ToISO8859_11 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_11);
+}
+
+static int ISO8859_13ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_13);
+}
+static int UTF8ToISO8859_13 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_13);
+}
+
+static int ISO8859_14ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_14);
+}
+static int UTF8ToISO8859_14 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_14);
+}
+
+static int ISO8859_15ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_15);
+}
+static int UTF8ToISO8859_15 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_15);
+}
+
+static int ISO8859_16ToUTF8 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return ISO8859xToUTF8 (out, outlen, in, inlen, xmlunicodetable_ISO8859_16);
+}
+static int UTF8ToISO8859_16 (unsigned char* out, int *outlen,
+    const unsigned char* in, int *inlen) {
+    return UTF8ToISO8859x (out, outlen, in, inlen, xmltranscodetable_ISO8859_16);
+}
+
+static void
+xmlRegisterCharEncodingHandlersISO8859x (void) {
+    xmlNewCharEncodingHandler ("ISO-8859-2", ISO8859_2ToUTF8, UTF8ToISO8859_2);
+    xmlNewCharEncodingHandler ("ISO-8859-3", ISO8859_3ToUTF8, UTF8ToISO8859_3);
+    xmlNewCharEncodingHandler ("ISO-8859-4", ISO8859_4ToUTF8, UTF8ToISO8859_4);
+    xmlNewCharEncodingHandler ("ISO-8859-5", ISO8859_5ToUTF8, UTF8ToISO8859_5);
+    xmlNewCharEncodingHandler ("ISO-8859-6", ISO8859_6ToUTF8, UTF8ToISO8859_6);
+    xmlNewCharEncodingHandler ("ISO-8859-7", ISO8859_7ToUTF8, UTF8ToISO8859_7);
+    xmlNewCharEncodingHandler ("ISO-8859-8", ISO8859_8ToUTF8, UTF8ToISO8859_8);
+    xmlNewCharEncodingHandler ("ISO-8859-9", ISO8859_9ToUTF8, UTF8ToISO8859_9);
+    xmlNewCharEncodingHandler ("ISO-8859-10", ISO8859_10ToUTF8, UTF8ToISO8859_10);
+    xmlNewCharEncodingHandler ("ISO-8859-11", ISO8859_11ToUTF8, UTF8ToISO8859_11);
+    xmlNewCharEncodingHandler ("ISO-8859-13", ISO8859_13ToUTF8, UTF8ToISO8859_13);
+    xmlNewCharEncodingHandler ("ISO-8859-14", ISO8859_14ToUTF8, UTF8ToISO8859_14);
+    xmlNewCharEncodingHandler ("ISO-8859-15", ISO8859_15ToUTF8, UTF8ToISO8859_15);
+    xmlNewCharEncodingHandler ("ISO-8859-16", ISO8859_16ToUTF8, UTF8ToISO8859_16);
+}
+
+#endif
+#endif
+
+#define bottom_encoding
+#include "elfgcchack.h"
+
diff --git a/src/entities.c b/src/entities.c
new file mode 100644
index 0000000..2aeef04
--- /dev/null
+++ b/src/entities.c
@@ -0,0 +1,1022 @@
+/*
+ * entities.c : implementation for the XML entities handling
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <libxml/xmlmemory.h>
+#include <libxml/hash.h>
+#include <libxml/entities.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+#include <libxml/dict.h>
+
+/*
+ * The XML predefined entities.
+ */
+
+static xmlEntity xmlEntityLt = {
+    NULL, XML_ENTITY_DECL, BAD_CAST "lt",
+    NULL, NULL, NULL, NULL, NULL, NULL, 
+    BAD_CAST "<", BAD_CAST "<", 1,
+    XML_INTERNAL_PREDEFINED_ENTITY,
+    NULL, NULL, NULL, NULL, 0, 1
+};
+static xmlEntity xmlEntityGt = {
+    NULL, XML_ENTITY_DECL, BAD_CAST "gt",
+    NULL, NULL, NULL, NULL, NULL, NULL, 
+    BAD_CAST ">", BAD_CAST ">", 1,
+    XML_INTERNAL_PREDEFINED_ENTITY,
+    NULL, NULL, NULL, NULL, 0, 1
+};
+static xmlEntity xmlEntityAmp = {
+    NULL, XML_ENTITY_DECL, BAD_CAST "amp",
+    NULL, NULL, NULL, NULL, NULL, NULL, 
+    BAD_CAST "&", BAD_CAST "&", 1,
+    XML_INTERNAL_PREDEFINED_ENTITY,
+    NULL, NULL, NULL, NULL, 0, 1
+};
+static xmlEntity xmlEntityQuot = {
+    NULL, XML_ENTITY_DECL, BAD_CAST "quot",
+    NULL, NULL, NULL, NULL, NULL, NULL, 
+    BAD_CAST "\"", BAD_CAST "\"", 1,
+    XML_INTERNAL_PREDEFINED_ENTITY,
+    NULL, NULL, NULL, NULL, 0, 1
+};
+static xmlEntity xmlEntityApos = {
+    NULL, XML_ENTITY_DECL, BAD_CAST "apos",
+    NULL, NULL, NULL, NULL, NULL, NULL, 
+    BAD_CAST "'", BAD_CAST "'", 1,
+    XML_INTERNAL_PREDEFINED_ENTITY,
+    NULL, NULL, NULL, NULL, 0, 1
+};
+
+/**
+ * xmlEntitiesErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlEntitiesErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * xmlEntitiesErr:
+ * @code:  the error code
+ * @msg:  the message
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlEntitiesErr(xmlParserErrors code, const char *msg)
+{
+    __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL);
+}
+
+/*
+ * xmlFreeEntity : clean-up an entity record.
+ */
+static void
+xmlFreeEntity(xmlEntityPtr entity)
+{
+    xmlDictPtr dict = NULL;
+
+    if (entity == NULL)
+        return;
+
+    if (entity->doc != NULL)
+        dict = entity->doc->dict;
+
+
+    if ((entity->children) && (entity->owner == 1) &&
+        (entity == (xmlEntityPtr) entity->children->parent))
+        xmlFreeNodeList(entity->children);
+    if (dict != NULL) {
+        if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name)))
+            xmlFree((char *) entity->name);
+        if ((entity->ExternalID != NULL) &&
+	    (!xmlDictOwns(dict, entity->ExternalID)))
+            xmlFree((char *) entity->ExternalID);
+        if ((entity->SystemID != NULL) &&
+	    (!xmlDictOwns(dict, entity->SystemID)))
+            xmlFree((char *) entity->SystemID);
+        if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI)))
+            xmlFree((char *) entity->URI);
+        if ((entity->content != NULL)
+            && (!xmlDictOwns(dict, entity->content)))
+            xmlFree((char *) entity->content);
+        if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig)))
+            xmlFree((char *) entity->orig);
+    } else {
+        if (entity->name != NULL)
+            xmlFree((char *) entity->name);
+        if (entity->ExternalID != NULL)
+            xmlFree((char *) entity->ExternalID);
+        if (entity->SystemID != NULL)
+            xmlFree((char *) entity->SystemID);
+        if (entity->URI != NULL)
+            xmlFree((char *) entity->URI);
+        if (entity->content != NULL)
+            xmlFree((char *) entity->content);
+        if (entity->orig != NULL)
+            xmlFree((char *) entity->orig);
+    }
+    xmlFree(entity);
+}
+
+/*
+ * xmlCreateEntity:
+ *
+ * internal routine doing the entity node strutures allocations
+ */
+static xmlEntityPtr
+xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
+	        const xmlChar *ExternalID, const xmlChar *SystemID,
+	        const xmlChar *content) {
+    xmlEntityPtr ret;
+
+    ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
+    if (ret == NULL) {
+        xmlEntitiesErrMemory("xmlCreateEntity: malloc failed");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlEntity));
+    ret->type = XML_ENTITY_DECL;
+    ret->checked = 0;
+
+    /*
+     * fill the structure.
+     */
+    ret->etype = (xmlEntityType) type;
+    if (dict == NULL) {
+	ret->name = xmlStrdup(name);
+	if (ExternalID != NULL)
+	    ret->ExternalID = xmlStrdup(ExternalID);
+	if (SystemID != NULL)
+	    ret->SystemID = xmlStrdup(SystemID);
+    } else {
+        ret->name = xmlDictLookup(dict, name, -1);
+	if (ExternalID != NULL)
+	    ret->ExternalID = xmlDictLookup(dict, ExternalID, -1);
+	if (SystemID != NULL)
+	    ret->SystemID = xmlDictLookup(dict, SystemID, -1);
+    }
+    if (content != NULL) {
+        ret->length = xmlStrlen(content);
+	if ((dict != NULL) && (ret->length < 5))
+	    ret->content = (xmlChar *)
+	                   xmlDictLookup(dict, content, ret->length);
+	else
+	    ret->content = xmlStrndup(content, ret->length);
+     } else {
+        ret->length = 0;
+        ret->content = NULL;
+    }
+    ret->URI = NULL; /* to be computed by the layer knowing
+			the defining entity */
+    ret->orig = NULL;
+    ret->owner = 0;
+
+    return(ret);
+}
+
+/*
+ * xmlAddEntity : register a new entity for an entities table.
+ */
+static xmlEntityPtr
+xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
+	  const xmlChar *ExternalID, const xmlChar *SystemID,
+	  const xmlChar *content) {
+    xmlDictPtr dict = NULL;
+    xmlEntitiesTablePtr table = NULL;
+    xmlEntityPtr ret;
+
+    if (name == NULL)
+	return(NULL);
+    if (dtd == NULL)
+	return(NULL);
+    if (dtd->doc != NULL)
+        dict = dtd->doc->dict;
+
+    switch (type) {
+        case XML_INTERNAL_GENERAL_ENTITY:
+        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	    if (dtd->entities == NULL)
+		dtd->entities = xmlHashCreateDict(0, dict);
+	    table = dtd->entities;
+	    break;
+        case XML_INTERNAL_PARAMETER_ENTITY:
+        case XML_EXTERNAL_PARAMETER_ENTITY:
+	    if (dtd->pentities == NULL)
+		dtd->pentities = xmlHashCreateDict(0, dict);
+	    table = dtd->pentities;
+	    break;
+        case XML_INTERNAL_PREDEFINED_ENTITY:
+	    return(NULL);
+    }
+    if (table == NULL)
+	return(NULL);
+    ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content);
+    if (ret == NULL)
+        return(NULL);
+    ret->doc = dtd->doc;
+
+    if (xmlHashAddEntry(table, name, ret)) {
+	/*
+	 * entity was already defined at another level.
+	 */
+        xmlFreeEntity(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlGetPredefinedEntity:
+ * @name:  the entity name
+ *
+ * Check whether this name is an predefined entity.
+ *
+ * Returns NULL if not, otherwise the entity
+ */
+xmlEntityPtr
+xmlGetPredefinedEntity(const xmlChar *name) {
+    if (name == NULL) return(NULL);
+    switch (name[0]) {
+        case 'l':
+	    if (xmlStrEqual(name, BAD_CAST "lt"))
+	        return(&xmlEntityLt);
+	    break;
+        case 'g':
+	    if (xmlStrEqual(name, BAD_CAST "gt"))
+	        return(&xmlEntityGt);
+	    break;
+        case 'a':
+	    if (xmlStrEqual(name, BAD_CAST "amp"))
+	        return(&xmlEntityAmp);
+	    if (xmlStrEqual(name, BAD_CAST "apos"))
+	        return(&xmlEntityApos);
+	    break;
+        case 'q':
+	    if (xmlStrEqual(name, BAD_CAST "quot"))
+	        return(&xmlEntityQuot);
+	    break;
+	default:
+	    break;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlAddDtdEntity:
+ * @doc:  the document
+ * @name:  the entity name
+ * @type:  the entity type XML_xxx_yyy_ENTITY
+ * @ExternalID:  the entity external ID if available
+ * @SystemID:  the entity system ID if available
+ * @content:  the entity content
+ *
+ * Register a new entity for this document DTD external subset.
+ *
+ * Returns a pointer to the entity or NULL in case of error
+ */
+xmlEntityPtr
+xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
+	        const xmlChar *ExternalID, const xmlChar *SystemID,
+		const xmlChar *content) {
+    xmlEntityPtr ret;
+    xmlDtdPtr dtd;
+
+    if (doc == NULL) {
+	xmlEntitiesErr(XML_DTD_NO_DOC,
+	        "xmlAddDtdEntity: document is NULL");
+	return(NULL);
+    }
+    if (doc->extSubset == NULL) {
+	xmlEntitiesErr(XML_DTD_NO_DTD,
+	        "xmlAddDtdEntity: document without external subset");
+	return(NULL);
+    }
+    dtd = doc->extSubset;
+    ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
+    if (ret == NULL) return(NULL);
+
+    /*
+     * Link it to the DTD
+     */
+    ret->parent = dtd;
+    ret->doc = dtd->doc;
+    if (dtd->last == NULL) {
+	dtd->children = dtd->last = (xmlNodePtr) ret;
+    } else {
+        dtd->last->next = (xmlNodePtr) ret;
+	ret->prev = dtd->last;
+	dtd->last = (xmlNodePtr) ret;
+    }
+    return(ret);
+}
+
+/**
+ * xmlAddDocEntity:
+ * @doc:  the document
+ * @name:  the entity name
+ * @type:  the entity type XML_xxx_yyy_ENTITY
+ * @ExternalID:  the entity external ID if available
+ * @SystemID:  the entity system ID if available
+ * @content:  the entity content
+ *
+ * Register a new entity for this document.
+ *
+ * Returns a pointer to the entity or NULL in case of error
+ */
+xmlEntityPtr
+xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
+	        const xmlChar *ExternalID, const xmlChar *SystemID,
+	        const xmlChar *content) {
+    xmlEntityPtr ret;
+    xmlDtdPtr dtd;
+
+    if (doc == NULL) {
+	xmlEntitiesErr(XML_DTD_NO_DOC,
+	        "xmlAddDocEntity: document is NULL");
+	return(NULL);
+    }
+    if (doc->intSubset == NULL) {
+	xmlEntitiesErr(XML_DTD_NO_DTD,
+	        "xmlAddDocEntity: document without internal subset");
+	return(NULL);
+    }
+    dtd = doc->intSubset;
+    ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
+    if (ret == NULL) return(NULL);
+
+    /*
+     * Link it to the DTD
+     */
+    ret->parent = dtd;
+    ret->doc = dtd->doc;
+    if (dtd->last == NULL) {
+	dtd->children = dtd->last = (xmlNodePtr) ret;
+    } else {
+	dtd->last->next = (xmlNodePtr) ret;
+	ret->prev = dtd->last;
+	dtd->last = (xmlNodePtr) ret;
+    }
+    return(ret);
+}
+
+/**
+ * xmlNewEntity:
+ * @doc:  the document
+ * @name:  the entity name
+ * @type:  the entity type XML_xxx_yyy_ENTITY
+ * @ExternalID:  the entity external ID if available
+ * @SystemID:  the entity system ID if available
+ * @content:  the entity content
+ *
+ * Create a new entity, this differs from xmlAddDocEntity() that if
+ * the document is NULL or has no internal subset defined, then an
+ * unlinked entity structure will be returned, it is then the responsability
+ * of the caller to link it to the document later or free it when not needed
+ * anymore.
+ *
+ * Returns a pointer to the entity or NULL in case of error
+ */
+xmlEntityPtr
+xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type,
+	     const xmlChar *ExternalID, const xmlChar *SystemID,
+	     const xmlChar *content) {
+    xmlEntityPtr ret;
+    xmlDictPtr dict;
+
+    if ((doc != NULL) && (doc->intSubset != NULL)) {
+	return(xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content));
+    }
+    if (doc != NULL)
+        dict = doc->dict;
+    else
+        dict = NULL;
+    ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content);
+    if (ret == NULL)
+        return(NULL);
+    ret->doc = doc;
+    return(ret);
+}
+
+/**
+ * xmlGetEntityFromTable:
+ * @table:  an entity table
+ * @name:  the entity name
+ * @parameter:  look for parameter entities
+ *
+ * Do an entity lookup in the table.
+ * returns the corresponding parameter entity, if found.
+ * 
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+static xmlEntityPtr
+xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
+    return((xmlEntityPtr) xmlHashLookup(table, name));
+}
+
+/**
+ * xmlGetParameterEntity:
+ * @doc:  the document referencing the entity
+ * @name:  the entity name
+ *
+ * Do an entity lookup in the internal and external subsets and
+ * returns the corresponding parameter entity, if found.
+ * 
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+xmlEntityPtr
+xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
+    xmlEntitiesTablePtr table;
+    xmlEntityPtr ret;
+
+    if (doc == NULL)
+	return(NULL);
+    if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
+	table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
+	ret = xmlGetEntityFromTable(table, name);
+	if (ret != NULL)
+	    return(ret);
+    }
+    if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
+	table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
+	return(xmlGetEntityFromTable(table, name));
+    }
+    return(NULL);
+}
+
+/**
+ * xmlGetDtdEntity:
+ * @doc:  the document referencing the entity
+ * @name:  the entity name
+ *
+ * Do an entity lookup in the DTD entity hash table and
+ * returns the corresponding entity, if found.
+ * Note: the first argument is the document node, not the DTD node.
+ * 
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+xmlEntityPtr
+xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
+    xmlEntitiesTablePtr table;
+
+    if (doc == NULL)
+	return(NULL);
+    if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
+	table = (xmlEntitiesTablePtr) doc->extSubset->entities;
+	return(xmlGetEntityFromTable(table, name));
+    }
+    return(NULL);
+}
+
+/**
+ * xmlGetDocEntity:
+ * @doc:  the document referencing the entity
+ * @name:  the entity name
+ *
+ * Do an entity lookup in the document entity hash table and
+ * returns the corresponding entity, otherwise a lookup is done
+ * in the predefined entities too.
+ * 
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+xmlEntityPtr
+xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
+    xmlEntityPtr cur;
+    xmlEntitiesTablePtr table;
+
+    if (doc != NULL) {
+	if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
+	    table = (xmlEntitiesTablePtr) doc->intSubset->entities;
+	    cur = xmlGetEntityFromTable(table, name);
+	    if (cur != NULL)
+		return(cur);
+	}
+	if (doc->standalone != 1) {
+	    if ((doc->extSubset != NULL) &&
+		(doc->extSubset->entities != NULL)) {
+		table = (xmlEntitiesTablePtr) doc->extSubset->entities;
+		cur = xmlGetEntityFromTable(table, name);
+		if (cur != NULL)
+		    return(cur);
+	    }
+	}
+    }
+    return(xmlGetPredefinedEntity(name));
+}
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define growBufferReentrant() {						\
+    buffer_size *= 2;							\
+    buffer = (xmlChar *)						\
+    		xmlRealloc(buffer, buffer_size * sizeof(xmlChar));	\
+    if (buffer == NULL) {						\
+        xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");\
+	return(NULL);							\
+    }									\
+}
+
+
+/**
+ * xmlEncodeEntitiesReentrant:
+ * @doc:  the document containing the string
+ * @input:  A string to convert to XML.
+ *
+ * Do a global encoding of a string, replacing the predefined entities
+ * and non ASCII values with their entities and CharRef counterparts.
+ * Contrary to xmlEncodeEntities, this routine is reentrant, and result
+ * must be deallocated.
+ *
+ * Returns A newly allocated string with the substitution done.
+ */
+xmlChar *
+xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
+    const xmlChar *cur = input;
+    xmlChar *buffer = NULL;
+    xmlChar *out = NULL;
+    int buffer_size = 0;
+    int html = 0;
+
+    if (input == NULL) return(NULL);
+    if (doc != NULL)
+        html = (doc->type == XML_HTML_DOCUMENT_NODE);
+
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) {
+        xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: malloc failed");
+	return(NULL);
+    }
+    out = buffer;
+
+    while (*cur != '\0') {
+        if (out - buffer > buffer_size - 100) {
+	    int indx = out - buffer;
+
+	    growBufferReentrant();
+	    out = &buffer[indx];
+	}
+
+	/*
+	 * By default one have to encode at least '<', '>', '"' and '&' !
+	 */
+	if (*cur == '<') {
+	    *out++ = '&';
+	    *out++ = 'l';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '>') {
+	    *out++ = '&';
+	    *out++ = 'g';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '&') {
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'm';
+	    *out++ = 'p';
+	    *out++ = ';';
+	} else if (((*cur >= 0x20) && (*cur < 0x80)) ||
+	    (*cur == '\n') || (*cur == '\t') || ((html) && (*cur == '\r'))) {
+	    /*
+	     * default case, just copy !
+	     */
+	    *out++ = *cur;
+	} else if (*cur >= 0x80) {
+	    if (((doc != NULL) && (doc->encoding != NULL)) || (html)) {
+		/*
+		 * Bjørn Reese <br@sseusa.com> provided the patch
+	        xmlChar xc;
+	        xc = (*cur & 0x3F) << 6;
+	        if (cur[1] != 0) {
+		    xc += *(++cur) & 0x3F;
+		    *out++ = xc;
+	        } else
+		 */
+		*out++ = *cur;
+	    } else {
+		/*
+		 * We assume we have UTF-8 input.
+		 */
+		char buf[11], *ptr;
+		int val = 0, l = 1;
+
+		if (*cur < 0xC0) {
+		    xmlEntitiesErr(XML_CHECK_NOT_UTF8,
+			    "xmlEncodeEntitiesReentrant : input not UTF-8");
+		    if (doc != NULL)
+			doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+		    snprintf(buf, sizeof(buf), "&#%d;", *cur);
+		    buf[sizeof(buf) - 1] = 0;
+		    ptr = buf;
+		    while (*ptr != 0) *out++ = *ptr++;
+		    cur++;
+		    continue;
+		} else if (*cur < 0xE0) {
+                    val = (cur[0]) & 0x1F;
+		    val <<= 6;
+		    val |= (cur[1]) & 0x3F;
+		    l = 2;
+		} else if (*cur < 0xF0) {
+                    val = (cur[0]) & 0x0F;
+		    val <<= 6;
+		    val |= (cur[1]) & 0x3F;
+		    val <<= 6;
+		    val |= (cur[2]) & 0x3F;
+		    l = 3;
+		} else if (*cur < 0xF8) {
+                    val = (cur[0]) & 0x07;
+		    val <<= 6;
+		    val |= (cur[1]) & 0x3F;
+		    val <<= 6;
+		    val |= (cur[2]) & 0x3F;
+		    val <<= 6;
+		    val |= (cur[3]) & 0x3F;
+		    l = 4;
+		}
+		if ((l == 1) || (!IS_CHAR(val))) {
+		    xmlEntitiesErr(XML_ERR_INVALID_CHAR,
+			"xmlEncodeEntitiesReentrant : char out of range\n");
+		    if (doc != NULL)
+			doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+		    snprintf(buf, sizeof(buf), "&#%d;", *cur);
+		    buf[sizeof(buf) - 1] = 0;
+		    ptr = buf;
+		    while (*ptr != 0) *out++ = *ptr++;
+		    cur++;
+		    continue;
+		}
+		/*
+		 * We could do multiple things here. Just save as a char ref
+		 */
+		snprintf(buf, sizeof(buf), "&#x%X;", val);
+		buf[sizeof(buf) - 1] = 0;
+		ptr = buf;
+		while (*ptr != 0) *out++ = *ptr++;
+		cur += l;
+		continue;
+	    }
+	} else if (IS_BYTE_CHAR(*cur)) {
+	    char buf[11], *ptr;
+
+	    snprintf(buf, sizeof(buf), "&#%d;", *cur);
+	    buf[sizeof(buf) - 1] = 0;
+            ptr = buf;
+	    while (*ptr != 0) *out++ = *ptr++;
+	}
+	cur++;
+    }
+    *out = 0;
+    return(buffer);
+}
+
+/**
+ * xmlEncodeSpecialChars:
+ * @doc:  the document containing the string
+ * @input:  A string to convert to XML.
+ *
+ * Do a global encoding of a string, replacing the predefined entities
+ * this routine is reentrant, and result must be deallocated.
+ *
+ * Returns A newly allocated string with the substitution done.
+ */
+xmlChar *
+xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+    const xmlChar *cur = input;
+    xmlChar *buffer = NULL;
+    xmlChar *out = NULL;
+    int buffer_size = 0;
+    if (input == NULL) return(NULL);
+
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) {
+        xmlEntitiesErrMemory("xmlEncodeSpecialChars: malloc failed");
+	return(NULL);
+    }
+    out = buffer;
+
+    while (*cur != '\0') {
+        if (out - buffer > buffer_size - 10) {
+	    int indx = out - buffer;
+
+	    growBufferReentrant();
+	    out = &buffer[indx];
+	}
+
+	/*
+	 * By default one have to encode at least '<', '>', '"' and '&' !
+	 */
+	if (*cur == '<') {
+	    *out++ = '&';
+	    *out++ = 'l';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '>') {
+	    *out++ = '&';
+	    *out++ = 'g';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '&') {
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'm';
+	    *out++ = 'p';
+	    *out++ = ';';
+	} else if (*cur == '"') {
+	    *out++ = '&';
+	    *out++ = 'q';
+	    *out++ = 'u';
+	    *out++ = 'o';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '\r') {
+	    *out++ = '&';
+	    *out++ = '#';
+	    *out++ = '1';
+	    *out++ = '3';
+	    *out++ = ';';
+	} else {
+	    /*
+	     * Works because on UTF-8, all extended sequences cannot
+	     * result in bytes in the ASCII range.
+	     */
+	    *out++ = *cur;
+	}
+	cur++;
+    }
+    *out = 0;
+    return(buffer);
+}
+
+/**
+ * xmlCreateEntitiesTable:
+ *
+ * create and initialize an empty entities hash table.
+ * This really doesn't make sense and should be deprecated
+ *
+ * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
+ */
+xmlEntitiesTablePtr
+xmlCreateEntitiesTable(void) {
+    return((xmlEntitiesTablePtr) xmlHashCreate(0));
+}
+
+/**
+ * xmlFreeEntityWrapper:
+ * @entity:  An entity
+ * @name:  its name
+ *
+ * Deallocate the memory used by an entities in the hash table.
+ */
+static void
+xmlFreeEntityWrapper(xmlEntityPtr entity,
+	               const xmlChar *name ATTRIBUTE_UNUSED) {
+    if (entity != NULL)
+	xmlFreeEntity(entity);
+}
+
+/**
+ * xmlFreeEntitiesTable:
+ * @table:  An entity table
+ *
+ * Deallocate the memory used by an entities hash table.
+ */
+void
+xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntityWrapper);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlCopyEntity:
+ * @ent:  An entity
+ *
+ * Build a copy of an entity
+ * 
+ * Returns the new xmlEntitiesPtr or NULL in case of error.
+ */
+static xmlEntityPtr
+xmlCopyEntity(xmlEntityPtr ent) {
+    xmlEntityPtr cur;
+
+    cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
+    if (cur == NULL) {
+        xmlEntitiesErrMemory("xmlCopyEntity:: malloc failed");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlEntity));
+    cur->type = XML_ENTITY_DECL;
+
+    cur->etype = ent->etype;
+    if (ent->name != NULL)
+	cur->name = xmlStrdup(ent->name);
+    if (ent->ExternalID != NULL)
+	cur->ExternalID = xmlStrdup(ent->ExternalID);
+    if (ent->SystemID != NULL)
+	cur->SystemID = xmlStrdup(ent->SystemID);
+    if (ent->content != NULL)
+	cur->content = xmlStrdup(ent->content);
+    if (ent->orig != NULL)
+	cur->orig = xmlStrdup(ent->orig);
+    if (ent->URI != NULL)
+	cur->URI = xmlStrdup(ent->URI);
+    return(cur);
+}
+
+/**
+ * xmlCopyEntitiesTable:
+ * @table:  An entity table
+ *
+ * Build a copy of an entity table.
+ * 
+ * Returns the new xmlEntitiesTablePtr or NULL in case of error.
+ */
+xmlEntitiesTablePtr
+xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
+    return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity));
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+
+/**
+ * xmlDumpEntityContent:
+ * @buf:  An XML buffer.
+ * @content:  The entity content.
+ *
+ * This will dump the quoted string value, taking care of the special
+ * treatment required by %
+ */
+static void
+xmlDumpEntityContent(xmlBufferPtr buf, const xmlChar *content) {
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+    if (xmlStrchr(content, '%')) {
+        const xmlChar * base, *cur;
+
+	xmlBufferCCat(buf, "\"");
+	base = cur = content;
+	while (*cur != 0) {
+	    if (*cur == '"') {
+		if (base != cur)
+		    xmlBufferAdd(buf, base, cur - base);
+		xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
+		cur++;
+		base = cur;
+	    } else if (*cur == '%') {
+		if (base != cur)
+		    xmlBufferAdd(buf, base, cur - base);
+		xmlBufferAdd(buf, BAD_CAST "&#x25;", 6);
+		cur++;
+		base = cur;
+	    } else {
+		cur++;
+	    }
+	}
+	if (base != cur)
+	    xmlBufferAdd(buf, base, cur - base);
+	xmlBufferCCat(buf, "\"");
+    } else {
+        xmlBufferWriteQuotedString(buf, content);
+    }
+}
+
+/**
+ * xmlDumpEntityDecl:
+ * @buf:  An XML buffer.
+ * @ent:  An entity table
+ *
+ * This will dump the content of the entity table as an XML DTD definition
+ */
+void
+xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
+    if ((buf == NULL) || (ent == NULL)) return;
+    switch (ent->etype) {
+	case XML_INTERNAL_GENERAL_ENTITY:
+	    xmlBufferWriteChar(buf, "<!ENTITY ");
+	    xmlBufferWriteCHAR(buf, ent->name);
+	    xmlBufferWriteChar(buf, " ");
+	    if (ent->orig != NULL)
+		xmlBufferWriteQuotedString(buf, ent->orig);
+	    else
+		xmlDumpEntityContent(buf, ent->content);
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+	    xmlBufferWriteChar(buf, "<!ENTITY ");
+	    xmlBufferWriteCHAR(buf, ent->name);
+	    if (ent->ExternalID != NULL) {
+		 xmlBufferWriteChar(buf, " PUBLIC ");
+		 xmlBufferWriteQuotedString(buf, ent->ExternalID);
+		 xmlBufferWriteChar(buf, " ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    } else {
+		 xmlBufferWriteChar(buf, " SYSTEM ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    }
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	    xmlBufferWriteChar(buf, "<!ENTITY ");
+	    xmlBufferWriteCHAR(buf, ent->name);
+	    if (ent->ExternalID != NULL) {
+		 xmlBufferWriteChar(buf, " PUBLIC ");
+		 xmlBufferWriteQuotedString(buf, ent->ExternalID);
+		 xmlBufferWriteChar(buf, " ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    } else {
+		 xmlBufferWriteChar(buf, " SYSTEM ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    }
+	    if (ent->content != NULL) { /* Should be true ! */
+		xmlBufferWriteChar(buf, " NDATA ");
+		if (ent->orig != NULL)
+		    xmlBufferWriteCHAR(buf, ent->orig);
+		else
+		    xmlBufferWriteCHAR(buf, ent->content);
+	    }
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	case XML_INTERNAL_PARAMETER_ENTITY:
+	    xmlBufferWriteChar(buf, "<!ENTITY % ");
+	    xmlBufferWriteCHAR(buf, ent->name);
+	    xmlBufferWriteChar(buf, " ");
+	    if (ent->orig == NULL)
+		xmlDumpEntityContent(buf, ent->content);
+	    else
+		xmlBufferWriteQuotedString(buf, ent->orig);
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	case XML_EXTERNAL_PARAMETER_ENTITY:
+	    xmlBufferWriteChar(buf, "<!ENTITY % ");
+	    xmlBufferWriteCHAR(buf, ent->name);
+	    if (ent->ExternalID != NULL) {
+		 xmlBufferWriteChar(buf, " PUBLIC ");
+		 xmlBufferWriteQuotedString(buf, ent->ExternalID);
+		 xmlBufferWriteChar(buf, " ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    } else {
+		 xmlBufferWriteChar(buf, " SYSTEM ");
+		 xmlBufferWriteQuotedString(buf, ent->SystemID);
+	    }
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	default:
+	    xmlEntitiesErr(XML_DTD_UNKNOWN_ENTITY,
+		"xmlDumpEntitiesDecl: internal: unknown type entity type");
+    }
+}
+
+/**
+ * xmlDumpEntityDeclScan:
+ * @ent:  An entity table
+ * @buf:  An XML buffer.
+ *
+ * When using the hash table scan function, arguments need to be reversed
+ */
+static void
+xmlDumpEntityDeclScan(xmlEntityPtr ent, xmlBufferPtr buf) {
+    xmlDumpEntityDecl(buf, ent);
+}
+      
+/**
+ * xmlDumpEntitiesTable:
+ * @buf:  An XML buffer.
+ * @table:  An entity table
+ *
+ * This will dump the content of the entity table as an XML DTD definition
+ */
+void
+xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
+    xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDeclScan, buf);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+#define bottom_entities
+#include "elfgcchack.h"
diff --git a/src/error.c b/src/error.c
new file mode 100644
index 0000000..7508d41
--- /dev/null
+++ b/src/error.c
@@ -0,0 +1,989 @@
+/*
+ * error.c: module displaying/handling XML parser errors
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <stdarg.h>
+#include <libxml/parser.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/globals.h>
+
+void XMLCDECL xmlGenericErrorDefaultFunc	(void *ctx ATTRIBUTE_UNUSED,
+				 const char *msg,
+				 ...);
+
+#define XML_GET_VAR_STR(msg, str) {				\
+    int       size, prev_size = -1;				\
+    int       chars;						\
+    char      *larger;						\
+    va_list   ap;						\
+								\
+    str = (char *) xmlMalloc(150);				\
+    if (str != NULL) {						\
+								\
+    size = 150;							\
+								\
+    while (size < 64000) {					\
+	va_start(ap, msg);					\
+  	chars = vsnprintf(str, size, msg, ap);			\
+	va_end(ap);						\
+	if ((chars > -1) && (chars < size)) {			\
+	    if (prev_size == chars) {				\
+		break;						\
+	    } else {						\
+		prev_size = chars;				\
+	    }							\
+	}							\
+	if (chars > -1)						\
+	    size += chars + 1;					\
+	else							\
+	    size += 100;					\
+	if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
+	    break;						\
+	}							\
+	str = larger;						\
+    }}								\
+}
+
+/************************************************************************
+ * 									*
+ * 			Handling of out of context errors		*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlGenericErrorDefaultFunc:
+ * @ctx:  an error context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Default handler for out of context error messages.
+ */
+void XMLCDECL
+xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
+    va_list args;
+
+    if (xmlGenericErrorContext == NULL)
+	xmlGenericErrorContext = (void *) stderr;
+
+    va_start(args, msg);
+    vfprintf((FILE *)xmlGenericErrorContext, msg, args);
+    va_end(args);
+}
+
+/**
+ * initGenericErrorDefaultFunc:
+ * @handler:  the handler
+ * 
+ * Set or reset (if NULL) the default handler for generic errors
+ * to the builtin error function.
+ */
+void
+initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler)
+{
+    if (handler == NULL)
+        xmlGenericError = xmlGenericErrorDefaultFunc;
+    else
+        xmlGenericError = (*handler);
+}
+
+/**
+ * xmlSetGenericErrorFunc:
+ * @ctx:  the new error handling context
+ * @handler:  the new handler function
+ *
+ * Function to reset the handler and the error context for out of
+ * context error messages.
+ * This simply means that @handler will be called for subsequent
+ * error messages while not parsing nor validating. And @ctx will
+ * be passed as first argument to @handler
+ * One can simply force messages to be emitted to another FILE * than
+ * stderr by setting @ctx to this file handle and @handler to NULL.
+ * For multi-threaded applications, this must be set separately for each thread.
+ */
+void
+xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xmlGenericErrorContext = ctx;
+    if (handler != NULL)
+	xmlGenericError = handler;
+    else
+	xmlGenericError = xmlGenericErrorDefaultFunc;
+}
+
+/**
+ * xmlSetStructuredErrorFunc:
+ * @ctx:  the new error handling context
+ * @handler:  the new handler function
+ *
+ * Function to reset the handler and the error context for out of
+ * context structured error messages.
+ * This simply means that @handler will be called for subsequent
+ * error messages while not parsing nor validating. And @ctx will
+ * be passed as first argument to @handler
+ * For multi-threaded applications, this must be set separately for each thread.
+ */
+void
+xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
+    xmlStructuredErrorContext = ctx;
+    xmlStructuredError = handler;
+}
+
+/************************************************************************
+ * 									*
+ * 			Handling of parsing errors			*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlParserPrintFileInfo:
+ * @input:  an xmlParserInputPtr input
+ * 
+ * Displays the associated file and line informations for the current input
+ */
+
+void
+xmlParserPrintFileInfo(xmlParserInputPtr input) {
+    if (input != NULL) {
+	if (input->filename)
+	    xmlGenericError(xmlGenericErrorContext,
+		    "%s:%d: ", input->filename,
+		    input->line);
+	else
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Entity: line %d: ", input->line);
+    }
+}
+
+/**
+ * xmlParserPrintFileContext:
+ * @input:  an xmlParserInputPtr input
+ * 
+ * Displays current context within the input content for error tracking
+ */
+
+static void
+xmlParserPrintFileContextInternal(xmlParserInputPtr input , 
+		xmlGenericErrorFunc channel, void *data ) {
+    const xmlChar *cur, *base;
+    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
+    xmlChar  content[81]; /* space for 80 chars + line terminator */
+    xmlChar *ctnt;
+
+    if (input == NULL) return;
+    cur = input->cur;
+    base = input->base;
+    /* skip backwards over any end-of-lines */
+    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
+	cur--;
+    }
+    n = 0;
+    /* search backwards for beginning-of-line (to max buff size) */
+    while ((n++ < (sizeof(content)-1)) && (cur > base) && 
+    	   (*(cur) != '\n') && (*(cur) != '\r'))
+        cur--;
+    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+    /* calculate the error position in terms of the current position */
+    col = input->cur - cur;
+    /* search forward for end-of-line (to max buff size) */
+    n = 0;
+    ctnt = content;
+    /* copy selected text to our buffer */
+    while ((*cur != 0) && (*(cur) != '\n') && 
+    	   (*(cur) != '\r') && (n < sizeof(content)-1)) {
+		*ctnt++ = *cur++;
+	n++;
+    }
+    *ctnt = 0;
+    /* print out the selected text */
+    channel(data ,"%s\n", content);
+    /* create blank line with problem pointer */
+    n = 0;
+    ctnt = content;
+    /* (leave buffer space for pointer + line terminator) */
+    while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
+	if (*(ctnt) != '\t')
+	    *(ctnt) = ' ';
+	ctnt++;
+    }
+    *ctnt++ = '^';
+    *ctnt = 0;
+    channel(data ,"%s\n", content);
+}
+
+/**
+ * xmlParserPrintFileContext:
+ * @input:  an xmlParserInputPtr input
+ * 
+ * Displays current context within the input content for error tracking
+ */
+void
+xmlParserPrintFileContext(xmlParserInputPtr input) {
+   xmlParserPrintFileContextInternal(input, xmlGenericError,
+                                     xmlGenericErrorContext);
+}
+
+/**
+ * xmlReportError:
+ * @err: the error
+ * @ctx: the parser context or NULL
+ * @str: the formatted error message
+ *
+ * Report an erro with its context, replace the 4 old error/warning
+ * routines.
+ */
+static void
+xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
+               xmlGenericErrorFunc channel, void *data)
+{
+    char *file = NULL;
+    int line = 0;
+    int code = -1;
+    int domain;
+    const xmlChar *name = NULL;
+    xmlNodePtr node;
+    xmlErrorLevel level;
+    xmlParserInputPtr input = NULL;
+    xmlParserInputPtr cur = NULL;
+
+    if (err == NULL)
+        return;
+
+    if (channel == NULL) {
+	channel = xmlGenericError;
+	data = xmlGenericErrorContext;
+    }
+    file = err->file;
+    line = err->line;
+    code = err->code;
+    domain = err->domain;
+    level = err->level;
+    node = err->node;
+
+    if (code == XML_ERR_OK)
+        return;
+
+    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+        name = node->name;
+
+    /*
+     * Maintain the compatibility with the legacy error handling
+     */
+    if (ctxt != NULL) {
+        input = ctxt->input;
+        if ((input != NULL) && (input->filename == NULL) &&
+            (ctxt->inputNr > 1)) {
+            cur = input;
+            input = ctxt->inputTab[ctxt->inputNr - 2];
+        }
+        if (input != NULL) {
+            if (input->filename)
+                channel(data, "%s:%d: ", input->filename, input->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: ", input->line);
+        }
+    } else {
+        if (file != NULL)
+            channel(data, "%s:%d: ", file, line);
+        else if ((line != 0) && (domain == XML_FROM_PARSER))
+            channel(data, "Entity: line %d: ", line);
+    }
+    if (name != NULL) {
+        channel(data, "element %s: ", name);
+    }
+    switch (domain) {
+        case XML_FROM_PARSER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_NAMESPACE:
+            channel(data, "namespace ");
+            break;
+        case XML_FROM_DTD:
+        case XML_FROM_VALID:
+            channel(data, "validity ");
+            break;
+        case XML_FROM_HTML:
+            channel(data, "HTML parser ");
+            break;
+        case XML_FROM_MEMORY:
+            channel(data, "memory ");
+            break;
+        case XML_FROM_OUTPUT:
+            channel(data, "output ");
+            break;
+        case XML_FROM_IO:
+            channel(data, "I/O ");
+            break;
+        case XML_FROM_XINCLUDE:
+            channel(data, "XInclude ");
+            break;
+        case XML_FROM_XPATH:
+            channel(data, "XPath ");
+            break;
+        case XML_FROM_XPOINTER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_REGEXP:
+            channel(data, "regexp ");
+            break;
+        case XML_FROM_MODULE:
+            channel(data, "module ");
+            break;
+        case XML_FROM_SCHEMASV:
+            channel(data, "Schemas validity ");
+            break;
+        case XML_FROM_SCHEMASP:
+            channel(data, "Schemas parser ");
+            break;
+        case XML_FROM_RELAXNGP:
+            channel(data, "Relax-NG parser ");
+            break;
+        case XML_FROM_RELAXNGV:
+            channel(data, "Relax-NG validity ");
+            break;
+        case XML_FROM_CATALOG:
+            channel(data, "Catalog ");
+            break;
+        case XML_FROM_C14N:
+            channel(data, "C14N ");
+            break;
+        case XML_FROM_XSLT:
+            channel(data, "XSLT ");
+            break;
+        case XML_FROM_I18N:
+            channel(data, "encoding ");
+            break;
+        default:
+            break;
+    }
+    switch (level) {
+        case XML_ERR_NONE:
+            channel(data, ": ");
+            break;
+        case XML_ERR_WARNING:
+            channel(data, "warning : ");
+            break;
+        case XML_ERR_ERROR:
+            channel(data, "error : ");
+            break;
+        case XML_ERR_FATAL:
+            channel(data, "error : ");
+            break;
+    }
+    if (str != NULL) {
+        int len;
+	len = xmlStrlen((const xmlChar *)str);
+	if ((len > 0) && (str[len - 1] != '\n'))
+	    channel(data, "%s\n", str);
+	else
+	    channel(data, "%s", str);
+    } else {
+        channel(data, "%s\n", "out of memory error");
+    }
+
+    if (ctxt != NULL) {
+        xmlParserPrintFileContextInternal(input, channel, data);
+        if (cur != NULL) {
+            if (cur->filename)
+                channel(data, "%s:%d: \n", cur->filename, cur->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: \n", cur->line);
+            xmlParserPrintFileContextInternal(cur, channel, data);
+        }
+    }
+    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
+        (err->int1 < 100) &&
+	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
+	xmlChar buf[150];
+	int i;
+
+	channel(data, "%s\n", err->str1);
+	for (i=0;i < err->int1;i++)
+	     buf[i] = ' ';
+	buf[i++] = '^';
+	buf[i] = 0;
+	channel(data, "%s\n", buf);
+    }
+}
+
+/**
+ * __xmlRaiseError:
+ * @schannel: the structured callback channel
+ * @channel: the old callback channel
+ * @data: the callback data
+ * @ctx: the parser context or NULL
+ * @ctx: the parser context or NULL
+ * @domain: the domain for the error
+ * @code: the code for the error
+ * @level: the xmlErrorLevel for the error
+ * @file: the file source of the error (or NULL)
+ * @line: the line of the error or 0 if N/A
+ * @str1: extra string info
+ * @str2: extra string info
+ * @str3: extra string info
+ * @int1: extra int info
+ * @col: column number of the error or 0 if N/A 
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Update the appropriate global or contextual error structure,
+ * then forward the error message down the parser or generic
+ * error callback handler
+ */
+void XMLCDECL
+__xmlRaiseError(xmlStructuredErrorFunc schannel,
+              xmlGenericErrorFunc channel, void *data, void *ctx,
+              void *nod, int domain, int code, xmlErrorLevel level,
+              const char *file, int line, const char *str1,
+              const char *str2, const char *str3, int int1, int col,
+	      const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlNodePtr node = (xmlNodePtr) nod;
+    char *str = NULL;
+    xmlParserInputPtr input = NULL;
+    xmlErrorPtr to = &xmlLastError;
+    xmlNodePtr baseptr = NULL;
+
+    if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
+        return;
+    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
+        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
+	(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))
+	    schannel = ctxt->sax->serror;
+    }
+    /*
+     * Check if structured error handler set
+     */
+    if (schannel == NULL) {
+	schannel = xmlStructuredError;
+	/*
+	 * if user has defined handler, change data ptr to user's choice
+	 */
+	if (schannel != NULL)
+	    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
+     */
+    if (msg == NULL) {
+        str = (char *) xmlStrdup(BAD_CAST "No error message provided");
+    } else {
+        XML_GET_VAR_STR(msg, str);
+    }
+
+    /*
+     * specific processing if a parser context is provided
+     */
+    if (ctxt != NULL) {
+        if (file == NULL) {
+            input = ctxt->input;
+            if ((input != NULL) && (input->filename == NULL) &&
+                (ctxt->inputNr > 1)) {
+                input = ctxt->inputTab[ctxt->inputNr - 2];
+            }
+            if (input != NULL) {
+                file = input->filename;
+                line = input->line;
+                col = input->col;
+            }
+        }
+        to = &ctxt->lastError;
+    } else if ((node != NULL) && (file == NULL)) {
+	int i;
+
+	if ((node->doc != NULL) && (node->doc->URL != NULL)) {
+	    baseptr = node;
+/*	    file = (const char *) node->doc->URL; */
+	}
+	for (i = 0;
+	     ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE));
+	     i++)
+	     node = node->parent;
+        if ((baseptr == NULL) && (node != NULL) &&
+	    (node->doc != NULL) && (node->doc->URL != NULL))
+	    baseptr = node;
+
+	if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+	    line = node->line;
+    }
+
+    /*
+     * Save the information about the error
+     */
+    xmlResetError(to);
+    to->domain = domain;
+    to->code = code;
+    to->message = str;
+    to->level = level;
+    if (file != NULL)
+        to->file = (char *) xmlStrdup((const xmlChar *) file);
+    else if (baseptr != NULL) {
+#ifdef LIBXML_XINCLUDE_ENABLED
+	/*
+	 * We check if the error is within an XInclude section and,
+	 * if so, attempt to print out the href of the XInclude instead
+	 * of the usual "base" (doc->URL) for the node (bug 152623).
+	 */
+        xmlNodePtr prev = baseptr;
+	int inclcount = 0;
+	while (prev != NULL) {
+	    if (prev->prev == NULL)
+	        prev = prev->parent;
+	    else {
+	        prev = prev->prev;
+		if (prev->type == XML_XINCLUDE_START) {
+		    if (--inclcount < 0)
+		        break;
+		} else if (prev->type == XML_XINCLUDE_END)
+		    inclcount++;
+	    }
+	}
+	if (prev != NULL) {
+	    if (prev->type == XML_XINCLUDE_START) {
+		prev->type = XML_ELEMENT_NODE;
+		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
+		prev->type = XML_XINCLUDE_START;
+	    } else {
+		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
+	    }
+	} else
+#endif
+	    to->file = (char *) xmlStrdup(baseptr->doc->URL);
+	if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
+	    to->file = (char *) xmlStrdup(node->doc->URL);
+	}
+    }
+    to->line = line;
+    if (str1 != NULL)
+        to->str1 = (char *) xmlStrdup((const xmlChar *) str1);
+    if (str2 != NULL)
+        to->str2 = (char *) xmlStrdup((const xmlChar *) str2);
+    if (str3 != NULL)
+        to->str3 = (char *) xmlStrdup((const xmlChar *) str3);
+    to->int1 = int1;
+    to->int2 = col;
+    to->node = node;
+    to->ctxt = ctx;
+
+    if (to != &xmlLastError)
+        xmlCopyError(to,&xmlLastError);
+
+    /*
+     * Find the callback channel if channel param is 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 ((schannel == NULL) && (xmlStructuredError != NULL)) {
+	    schannel = xmlStructuredError;
+	    data = xmlStructuredErrorContext;
+	} else {
+	    channel = xmlGenericError;
+	    if (!data) {
+		data = xmlGenericErrorContext;
+	    }
+	}
+    }
+    if (schannel != NULL) {
+        schannel(data, to);
+	return;
+    }
+    if (channel == NULL)
+        return;
+
+    if ((channel == xmlParserError) ||
+        (channel == xmlParserWarning) ||
+	(channel == xmlParserValidityError) ||
+	(channel == xmlParserValidityWarning))
+	xmlReportError(to, ctxt, str, NULL, NULL);
+    else if ((channel == (xmlGenericErrorFunc) fprintf) ||
+             (channel == xmlGenericErrorDefaultFunc))
+	xmlReportError(to, ctxt, str, channel, data);
+    else
+	channel(data, "%s", str);
+}
+
+/**
+ * __xmlSimpleError:
+ * @domain: where the error comes from
+ * @code: the error code
+ * @node: the context node
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+void
+__xmlSimpleError(int domain, int code, xmlNodePtr node,
+                 const char *msg, const char *extra)
+{
+
+    if (code == XML_ERR_NO_MEMORY) {
+	if (extra)
+	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
+			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+			    NULL, NULL, 0, 0,
+			    "Memory allocation failed : %s\n", extra);
+	else
+	    __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
+			    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
+			    NULL, NULL, 0, 0, "Memory allocation failed\n");
+    } else {
+	__xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
+			code, XML_ERR_ERROR, NULL, 0, extra,
+			NULL, NULL, 0, 0, msg, extra);
+    }
+}
+/**
+ * xmlParserError:
+ * @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.
+ */
+void XMLCDECL
+xmlParserError(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input = NULL;
+    xmlParserInputPtr cur = NULL;
+    char * str;
+
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input != NULL) && (input->filename == NULL) &&
+	    (ctxt->inputNr > 1)) {
+	    cur = input;
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+	}
+	xmlParserPrintFileInfo(input);
+    }
+
+    xmlGenericError(xmlGenericErrorContext, "error: ");
+    XML_GET_VAR_STR(msg, str);
+    xmlGenericError(xmlGenericErrorContext, "%s", str);
+    if (str != NULL)
+	xmlFree(str);
+
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+	if (cur != NULL) {
+	    xmlParserPrintFileInfo(cur);
+	    xmlGenericError(xmlGenericErrorContext, "\n");
+	    xmlParserPrintFileContext(cur);
+	}
+    }
+}
+
+/**
+ * xmlParserWarning:
+ * @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.
+ */
+void XMLCDECL
+xmlParserWarning(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input = NULL;
+    xmlParserInputPtr cur = NULL;
+    char * str;
+
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input != NULL) && (input->filename == NULL) &&
+	    (ctxt->inputNr > 1)) {
+	    cur = input;
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+	}
+	xmlParserPrintFileInfo(input);
+    }
+        
+    xmlGenericError(xmlGenericErrorContext, "warning: ");
+    XML_GET_VAR_STR(msg, str);
+    xmlGenericError(xmlGenericErrorContext, "%s", str);
+    if (str != NULL)
+	xmlFree(str);
+
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+	if (cur != NULL) {
+	    xmlParserPrintFileInfo(cur);
+	    xmlGenericError(xmlGenericErrorContext, "\n");
+	    xmlParserPrintFileContext(cur);
+	}
+    }
+}
+
+/************************************************************************
+ * 									*
+ * 			Handling of validation errors			*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlParserValidityError:
+ * @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.
+ */
+void XMLCDECL
+xmlParserValidityError(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input = NULL;
+    char * str;
+    int len = xmlStrlen((const xmlChar *) msg);
+    static int had_info = 0;
+
+    if ((len > 1) && (msg[len - 2] != ':')) {
+	if (ctxt != NULL) {
+	    input = ctxt->input;
+	    if ((input->filename == NULL) && (ctxt->inputNr > 1))
+		input = ctxt->inputTab[ctxt->inputNr - 2];
+		
+	    if (had_info == 0) {
+		xmlParserPrintFileInfo(input);
+	    }
+	}
+	xmlGenericError(xmlGenericErrorContext, "validity error: ");
+	had_info = 0;
+    } else {
+	had_info = 1;
+    }
+
+    XML_GET_VAR_STR(msg, str);
+    xmlGenericError(xmlGenericErrorContext, "%s", str);
+    if (str != NULL)
+	xmlFree(str);
+
+    if ((ctxt != NULL) && (input != NULL)) {
+	xmlParserPrintFileContext(input);
+    }
+}
+
+/**
+ * xmlParserValidityWarning:
+ * @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.
+ */
+void XMLCDECL
+xmlParserValidityWarning(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input = NULL;
+    char * str;
+    int len = xmlStrlen((const xmlChar *) msg);
+
+    if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
+	input = ctxt->input;
+	if ((input->filename == NULL) && (ctxt->inputNr > 1))
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+
+	xmlParserPrintFileInfo(input);
+    }
+        
+    xmlGenericError(xmlGenericErrorContext, "validity warning: ");
+    XML_GET_VAR_STR(msg, str);
+    xmlGenericError(xmlGenericErrorContext, "%s", str);
+    if (str != NULL)
+	xmlFree(str);
+
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+    }
+}
+
+
+/************************************************************************
+ *									*
+ *			Extended Error Handling				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlGetLastError:
+ *
+ * Get the last global error registered. This is per thread if compiled
+ * with thread support.
+ *
+ * Returns NULL if no error occured or a pointer to the error
+ */
+xmlErrorPtr
+xmlGetLastError(void)
+{
+    if (xmlLastError.code == XML_ERR_OK)
+        return (NULL);
+    return (&xmlLastError);
+}
+
+/**
+ * xmlResetError:
+ * @err: pointer to the error.
+ *
+ * Cleanup the error.
+ */
+void
+xmlResetError(xmlErrorPtr err)
+{
+    if (err == NULL)
+        return;
+    if (err->code == XML_ERR_OK)
+        return;
+    if (err->message != NULL)
+        xmlFree(err->message);
+    if (err->file != NULL)
+        xmlFree(err->file);
+    if (err->str1 != NULL)
+        xmlFree(err->str1);
+    if (err->str2 != NULL)
+        xmlFree(err->str2);
+    if (err->str3 != NULL)
+        xmlFree(err->str3);
+    memset(err, 0, sizeof(xmlError));
+    err->code = XML_ERR_OK;
+}
+
+/**
+ * xmlResetLastError:
+ *
+ * Cleanup the last global error registered. For parsing error
+ * this does not change the well-formedness result.
+ */
+void
+xmlResetLastError(void)
+{
+    if (xmlLastError.code == XML_ERR_OK)
+        return;
+    xmlResetError(&xmlLastError);
+}
+
+/**
+ * xmlCtxtGetLastError:
+ * @ctx:  an XML parser context
+ *
+ * Get the last parsing error registered.
+ *
+ * Returns NULL if no error occured or a pointer to the error
+ */
+xmlErrorPtr
+xmlCtxtGetLastError(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+    if (ctxt == NULL)
+        return (NULL);
+    if (ctxt->lastError.code == XML_ERR_OK)
+        return (NULL);
+    return (&ctxt->lastError);
+}
+
+/**
+ * xmlCtxtResetLastError:
+ * @ctx:  an XML parser context
+ *
+ * Cleanup the last global error registered. For parsing error
+ * this does not change the well-formedness result.
+ */
+void
+xmlCtxtResetLastError(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+    if (ctxt == NULL)
+        return;
+    ctxt->errNo = XML_ERR_OK;
+    if (ctxt->lastError.code == XML_ERR_OK)
+        return;
+    xmlResetError(&ctxt->lastError);
+}
+
+/**
+ * xmlCopyError:
+ * @from:  a source error
+ * @to:  a target error
+ *
+ * Save the original error to the new place.
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
+    char *message, *file, *str1, *str2, *str3;
+
+    if ((from == NULL) || (to == NULL))
+        return(-1);
+
+    message = (char *) xmlStrdup((xmlChar *) from->message);
+    file = (char *) xmlStrdup ((xmlChar *) from->file);
+    str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
+    str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
+    str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
+
+    if (to->message != NULL)
+        xmlFree(to->message);
+    if (to->file != NULL)
+        xmlFree(to->file);
+    if (to->str1 != NULL)
+        xmlFree(to->str1);
+    if (to->str2 != NULL)
+        xmlFree(to->str2);
+    if (to->str3 != NULL)
+        xmlFree(to->str3);
+    to->domain = from->domain;
+    to->code = from->code;
+    to->level = from->level;
+    to->line = from->line;
+    to->node = from->node;
+    to->int1 = from->int1;
+    to->int2 = from->int2;
+    to->node = from->node;
+    to->ctxt = from->ctxt;
+    to->message = message;
+    to->file = file;
+    to->str1 = str1;
+    to->str2 = str2;
+    to->str3 = str3;
+
+    return 0;
+}
+
+#define bottom_error
+#include "elfgcchack.h"
diff --git a/src/genUnicode.py b/src/genUnicode.py
new file mode 100755
index 0000000..6de68bd
--- /dev/null
+++ b/src/genUnicode.py
@@ -0,0 +1,478 @@
+#!/usr/bin/env python3 -u
+#
+# Original script modified in November 2003 to take advantage of
+# the character-validation range routines, and updated to the
+# current Unicode information (Version 4.0.1)
+#
+# NOTE: there is an 'alias' facility for blocks which are not present in
+#	the current release, but are needed for ABI compatibility.  This
+#	must be accomplished MANUALLY!  Please see the comments below under
+#     'blockAliases'
+#
+import sys
+import string
+import time
+
+webpage = "http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html"
+sources = "Blocks-4.0.1.txt UnicodeData-4.0.1.txt"
+
+#
+# blockAliases is a small hack - it is used for mapping block names which
+# were were used in the 3.1 release, but are missing or changed in the current
+# release.  The format is "OldBlockName:NewBlockName1[,NewBlockName2[,...]]"
+blockAliases = []
+blockAliases.append("CombiningMarksforSymbols:CombiningDiacriticalMarksforSymbols")
+blockAliases.append("Greek:GreekandCoptic")
+blockAliases.append("PrivateUse:PrivateUseArea,SupplementaryPrivateUseArea-A," + 
+	"SupplementaryPrivateUseArea-B")
+
+# minTableSize gives the minimum number of ranges which must be present
+# before a range table is produced.  If there are less than this
+# number, inline comparisons are generated
+minTableSize = 8
+
+(blockfile, catfile) = string.split(sources)
+
+
+#
+# Now process the "blocks" file, reducing it to a dictionary
+# indexed by blockname, containing a tuple with the applicable
+# block range
+#
+BlockNames = {}
+try:
+    blocks = open(blockfile, "r")
+except:
+    print("Missing %s, aborting ..." % blockfile)
+    sys.exit(1)
+
+for line in blocks.readlines():
+    if line[0] == '#':
+        continue
+    line = string.strip(line)
+    if line == '':
+        continue
+    try:
+        fields = string.split(line, ';')
+        range = string.strip(fields[0])
+        (start, end) = string.split(range, "..")
+        name = string.strip(fields[1])
+        name = string.replace(name, ' ', '')
+    except:
+        print("Failed to process line: %s" % (line))
+        continue
+    start = "0x" + start
+    end = "0x" + end
+    try:
+        BlockNames[name].append((start, end))
+    except:
+        BlockNames[name] = [(start, end)]
+blocks.close()
+print("Parsed %d blocks descriptions" % (len(list(BlockNames.keys()))))
+
+for block in blockAliases:
+    alias = string.split(block,':')
+    alist = string.split(alias[1],',')
+    for comp in alist:
+        if comp in BlockNames:
+            if alias[0] not in BlockNames:
+                BlockNames[alias[0]] = []
+            for r in BlockNames[comp]:
+                BlockNames[alias[0]].append(r)
+        else:
+            print("Alias %s: %s not in Blocks" % (alias[0], comp))
+            continue
+
+#
+# Next process the Categories file. This is more complex, since
+# the file is in code sequence, and we need to invert it.  We use
+# a dictionary with index category-name, with each entry containing
+# all the ranges (codepoints) of that category.  Note that category
+# names comprise two parts - the general category, and the "subclass"
+# within that category.  Therefore, both "general category" (which is
+# the first character of the 2-character category-name) and the full
+# (2-character) name are entered into this dictionary.
+#
+try:
+    data = open(catfile, "r")
+except:
+    print("Missing %s, aborting ..." % catfile)
+    sys.exit(1)
+
+nbchar = 0;
+Categories = {}
+for line in data.readlines():
+    if line[0] == '#':
+        continue
+    line = string.strip(line)
+    if line == '':
+        continue
+    try:
+        fields = string.split(line, ';')
+        point = string.strip(fields[0])
+        value = 0
+        while point != '':
+            value = value * 16
+            if point[0] >= '0' and point[0] <= '9':
+                value = value + ord(point[0]) - ord('0')
+            elif point[0] >= 'A' and point[0] <= 'F':
+                value = value + 10 + ord(point[0]) - ord('A')
+            elif point[0] >= 'a' and point[0] <= 'f':
+                value = value + 10 + ord(point[0]) - ord('a')
+            point = point[1:]
+        name = fields[2]
+    except:
+        print("Failed to process line: %s" % (line))
+        continue
+    
+    nbchar = nbchar + 1
+    # update entry for "full name"
+    try:
+        Categories[name].append(value)
+    except:
+        try:
+            Categories[name] = [value]
+        except:
+            print("Failed to process line: %s" % (line))
+    # update "general category" name
+    try:
+        Categories[name[0]].append(value)
+    except:
+        try:
+            Categories[name[0]] = [value]
+        except:
+            print("Failed to process line: %s" % (line))
+
+blocks.close()
+print("Parsed %d char generating %d categories" % (nbchar, len(list(Categories.keys()))))
+
+#
+# The data is now all read.  Time to process it into a more useful form.
+#
+# reduce the number list into ranges
+for cat in list(Categories.keys()):
+    list = Categories[cat]
+    start = -1
+    prev = -1
+    end = -1
+    ranges = []
+    for val in list:
+        if start == -1:
+            start = val
+            prev = val
+            continue
+        elif val == prev + 1:
+            prev = val
+            continue
+        elif prev == start:
+            ranges.append((prev, prev))
+            start = val
+            prev = val
+            continue
+        else:
+            ranges.append((start, prev))
+            start = val
+            prev = val
+            continue
+    if prev == start:
+        ranges.append((prev, prev))
+    else:
+        ranges.append((start, prev))
+    Categories[cat] = ranges
+
+#
+# Assure all data is in alphabetic order, since we will be doing binary
+# searches on the tables.
+#
+bkeys = list(BlockNames.keys())
+bkeys.sort()
+
+ckeys = list(Categories.keys())
+ckeys.sort()
+
+#
+# Generate the resulting files
+#
+try:
+    header = open("include/libxml/xmlunicode.h", "w")
+except:
+    print("Failed to open include/libxml/xmlunicode.h")
+    sys.exit(1)
+
+try:
+    output = open("xmlunicode.c", "w")
+except:
+    print("Failed to open xmlunicode.c")
+    sys.exit(1)
+
+date = time.asctime(time.localtime(time.time()))
+
+header.write(
+"""/*
+ * Summary: Unicode character APIs
+ * Description: API for the Unicode character APIs
+ *
+ * This file is automatically generated from the
+ * UCS description files of the Unicode Character Database
+ * %s
+ * using the genUnicode.py Python script.
+ *
+ * Generation date: %s
+ * Sources: %s
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_UNICODE_H__
+#define __XML_UNICODE_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_UNICODE_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+""" % (webpage, date, sources));
+
+output.write(
+"""/*
+ * xmlunicode.c: this module implements the Unicode character APIs
+ *
+ * This file is automatically generated from the
+ * UCS description files of the Unicode Character Database
+ * %s
+ * using the genUnicode.py Python script.
+ *
+ * Generation date: %s
+ * Sources: %s
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_UNICODE_ENABLED
+
+#include <string.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/chvalid.h>
+
+typedef int (xmlIntFunc)(int);	/* just to keep one's mind untwisted */
+
+typedef struct {
+    const char *rangename;
+    xmlIntFunc *func;
+} xmlUnicodeRange;
+
+typedef struct {
+    xmlUnicodeRange *table;
+    int		    numentries;
+} xmlUnicodeNameTable;
+
+
+static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname);
+
+static xmlUnicodeRange xmlUnicodeBlocks[] = {
+""" % (webpage, date, sources));
+
+flag = 0
+for block in bkeys:
+    name = string.replace(block, '-', '')
+    if flag:
+        output.write(',\n')
+    else:
+        flag = 1
+    output.write('  {"%s", xmlUCSIs%s}' % (block, name))
+output.write('};\n\n')
+
+output.write('static xmlUnicodeRange xmlUnicodeCats[] = {\n')
+flag = 0;
+for name in ckeys:
+    if flag:
+        output.write(',\n')
+    else:
+        flag = 1
+    output.write('  {"%s", xmlUCSIsCat%s}' % (name, name))
+output.write('};\n\n')
+
+#
+# For any categories with more than minTableSize ranges we generate
+# a range table suitable for xmlCharInRange
+#
+for name in ckeys:
+  if len(Categories[name]) > minTableSize:
+    numshort = 0
+    numlong = 0
+    ranges = Categories[name]
+    sptr = "NULL"
+    lptr = "NULL"
+    for range in ranges:
+      (low, high) = range
+      if high < 0x10000:
+        if numshort == 0:
+          pline = "static const xmlChSRange xml%sS[] = {" % name
+          sptr = "xml%sS" % name
+        else:
+          pline += ", "
+        numshort += 1
+      else:
+        if numlong == 0:
+          if numshort > 0:
+            output.write(pline + " };\n")
+          pline = "static const xmlChLRange xml%sL[] = {" % name
+          lptr = "xml%sL" % name
+        else:
+          pline += ", "
+        numlong += 1
+      if len(pline) > 60:
+        output.write(pline + "\n")
+        pline = "    "
+      pline += "{%s, %s}" % (hex(low), hex(high))
+    output.write(pline + " };\nstatic xmlChRangeGroup xml%sG = {%s,%s,%s,%s};\n\n"
+         % (name, numshort, numlong, sptr, lptr))
+
+
+output.write(
+"""static xmlUnicodeNameTable xmlUnicodeBlockTbl = {xmlUnicodeBlocks, %s};
+static xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, %s};
+
+/**
+ * xmlUnicodeLookup:
+ * @tptr: pointer to the name table
+ * @name: name to be found
+ *
+ * binary table lookup for user-supplied name
+ *
+ * Returns pointer to range function if found, otherwise NULL
+ */
+static xmlIntFunc
+*xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname) {
+    int low, high, mid, cmp;
+    xmlUnicodeRange *sptr;
+
+    if ((tptr == NULL) || (tname == NULL)) return(NULL);
+
+    low = 0;
+    high = tptr->numentries - 1;
+    sptr = tptr->table;
+    while (low <= high) {
+	mid = (low + high) / 2;
+	if ((cmp=strcmp(tname, sptr[mid].rangename)) == 0)
+	    return (sptr[mid].func);
+	if (cmp < 0)
+	    high = mid - 1;
+	else
+	    low = mid + 1;
+    }
+    return (NULL);    
+}
+
+""" % (len(BlockNames), len(Categories)) )
+
+for block in bkeys:
+    name = string.replace(block, '-', '')
+    header.write("XMLPUBFUN int XMLCALL xmlUCSIs%s\t(int code);\n" % name)
+    output.write("/**\n * xmlUCSIs%s:\n * @code: UCS code point\n" % (name))
+    output.write(" *\n * Check whether the character is part of %s UCS Block\n"%
+                 (block))
+    output.write(" *\n * Returns 1 if true 0 otherwise\n */\n");
+    output.write("int\nxmlUCSIs%s(int code) {\n    return(" % name)
+    flag = 0
+    for (start, end) in BlockNames[block]:
+        if flag:
+            output.write(" ||\n           ")
+        else:
+            flag = 1
+        output.write("((code >= %s) && (code <= %s))" % (start, end))
+    output.write(");\n}\n\n")
+
+header.write("\nXMLPUBFUN int XMLCALL xmlUCSIsBlock\t(int code, const char *block);\n\n")
+output.write(
+"""/**
+ * xmlUCSIsBlock:
+ * @code: UCS code point
+ * @block: UCS block name
+ *
+ * Check whether the character is part of the UCS Block
+ *
+ * Returns 1 if true, 0 if false and -1 on unknown block
+ */
+int
+xmlUCSIsBlock(int code, const char *block) {
+    xmlIntFunc *func;
+
+    func = xmlUnicodeLookup(&xmlUnicodeBlockTbl, block);
+    if (func == NULL)
+	return (-1);
+    return (func(code));
+}
+
+""")
+
+for name in ckeys:
+    ranges = Categories[name]
+    header.write("XMLPUBFUN int XMLCALL xmlUCSIsCat%s\t(int code);\n" % name)
+    output.write("/**\n * xmlUCSIsCat%s:\n * @code: UCS code point\n" % (name))
+    output.write(" *\n * Check whether the character is part of %s UCS Category\n"%
+                 (name))
+    output.write(" *\n * Returns 1 if true 0 otherwise\n */\n");
+    output.write("int\nxmlUCSIsCat%s(int code) {\n" % name)
+    if len(Categories[name]) > minTableSize:
+        output.write("    return(xmlCharInRange((unsigned int)code, &xml%sG)"
+            % name)
+    else:
+        start = 1
+        for range in ranges:
+            (begin, end) = range;
+            if start:
+                output.write("    return(");
+                start = 0
+            else:
+                output.write(" ||\n           ");
+            if (begin == end):
+                output.write("(code == %s)" % (hex(begin)))
+            else:
+                output.write("((code >= %s) && (code <= %s))" % (
+                         hex(begin), hex(end)))
+    output.write(");\n}\n\n")
+
+header.write("\nXMLPUBFUN int XMLCALL xmlUCSIsCat\t(int code, const char *cat);\n")
+output.write(
+"""/**
+ * xmlUCSIsCat:
+ * @code: UCS code point
+ * @cat: UCS Category name
+ *
+ * Check whether the character is part of the UCS Category
+ *
+ * Returns 1 if true, 0 if false and -1 on unknown category
+ */
+int
+xmlUCSIsCat(int code, const char *cat) {
+    xmlIntFunc *func;
+
+    func = xmlUnicodeLookup(&xmlUnicodeCatTbl, cat);
+    if (func == NULL)
+	return (-1);
+    return (func(code));
+}
+
+#define bottom_xmlunicode
+#include "elfgcchack.h"
+#endif /* LIBXML_UNICODE_ENABLED */
+""")
+
+header.write("""
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_UNICODE_ENABLED */
+
+#endif /* __XML_UNICODE_H__ */
+""");
+
+header.close()
+output.close()
diff --git a/src/gentest.py b/src/gentest.py
new file mode 100755
index 0000000..12e493d
--- /dev/null
+++ b/src/gentest.py
@@ -0,0 +1,963 @@
+#!/usr/bin/env python3 -u
+#
+# generate a tester program for the API
+#
+import sys
+import os
+import string
+try:
+    import libxml2
+except:
+    print("libxml2 python bindings not available, skipping testapi.c generation")
+    sys.exit(0)
+
+if len(sys.argv) > 1:
+    srcPref = sys.argv[1] + '/'
+else:
+    srcPref = ''
+
+#
+# Modules we want to skip in API test
+#
+skipped_modules = [ "SAX", "xlink", "threads", "globals",
+  "xmlmemory", "xmlversion", "xmlexports",
+  #deprecated
+  "DOCBparser",
+]
+
+#
+# defines for each module
+#
+modules_defines = {
+    "HTMLparser": "LIBXML_HTML_ENABLED",
+    "catalog": "LIBXML_CATALOG_ENABLED",
+    "xmlreader": "LIBXML_READER_ENABLED",
+    "relaxng": "LIBXML_SCHEMAS_ENABLED",
+    "schemasInternals": "LIBXML_SCHEMAS_ENABLED",
+    "xmlschemas": "LIBXML_SCHEMAS_ENABLED",
+    "xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
+    "xpath": "LIBXML_XPATH_ENABLED",
+    "xpathInternals": "LIBXML_XPATH_ENABLED",
+    "xinclude": "LIBXML_XINCLUDE_ENABLED",
+    "xpointer": "LIBXML_XPTR_ENABLED",
+    "xmlregexp" : "LIBXML_REGEXP_ENABLED",
+    "xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
+    "xmlsave" : "LIBXML_OUTPUT_ENABLED",
+    "DOCBparser" : "LIBXML_DOCB_ENABLED",
+    "xmlmodule" : "LIBXML_MODULES_ENABLED",
+    "pattern" : "LIBXML_PATTERN_ENABLED",
+    "schematron" : "LIBXML_SCHEMATRON_ENABLED",
+}
+
+#
+# defines for specific functions
+#
+function_defines = {
+    "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
+    "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
+    "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
+    "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
+    "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
+    "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
+    "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
+    "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
+    "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
+    "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
+    "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
+    "xmlParseDTD": "LIBXML_VALID_ENABLED",
+    "xmlParseDoc": "LIBXML_SAX1_ENABLED",
+    "xmlParseMemory": "LIBXML_SAX1_ENABLED",
+    "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
+    "xmlParseFile": "LIBXML_SAX1_ENABLED",
+    "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
+    "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
+    "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
+    "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
+    "xmlParseEntity": "LIBXML_SAX1_ENABLED",
+    "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
+    "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
+    "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
+    "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
+    "xmlStopParser": "LIBXML_PUSH_ENABLED",
+    "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
+    "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
+    "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
+    "xmlNewTextChild": "LIBXML_TREE_ENABLED",
+    "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
+    "xmlNewProp": "LIBXML_TREE_ENABLED",
+    "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
+    "xmlValidateNCName": "LIBXML_TREE_ENABLED",
+    "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
+    "xmlValidateName": "LIBXML_TREE_ENABLED",
+    "xmlNewChild": "LIBXML_TREE_ENABLED",
+    "xmlValidateQName": "LIBXML_TREE_ENABLED",
+    "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
+    "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
+    "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
+    "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
+    "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
+}
+
+#
+# Some functions really need to be skipped for the tests.
+#
+skipped_functions = [
+# block on I/O
+"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
+"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
+"xmlReaderNewFd", "xmlReaderForFd",
+"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
+"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
+"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
+"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
+# Complex I/O APIs
+"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
+"xmlRegisterInputCallbacks", "xmlReaderForIO",
+"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
+"xmlSaveToIO", "xmlIOHTTPOpenW",
+# library state cleanup, generate false leak informations and other
+# troubles, heavillyb tested otherwise.
+"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
+"xmlSetTreeDoc", "xmlUnlinkNode",
+# hard to avoid leaks in the tests
+"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
+"xmlXPathNewValueTree", "xmlXPathWrapString",
+# unimplemented
+"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
+"xmlTextReaderReadString",
+# destructor
+"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
+# deprecated
+"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
+"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
+"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
+"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
+"xmlScanName",
+"xmlDecodeEntities", 
+# allocators
+"xmlMemFree",
+# verbosity
+"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
+# Internal functions, no user space should really call them
+"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
+"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
+"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
+"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
+"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
+"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
+"xmlParseAttributeType", "xmlParseAttributeListDecl",
+"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
+"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
+"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
+"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
+"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
+"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
+"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
+"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
+"xmlParseExternalSubset", "xmlParserHandlePEReference",
+"xmlSkipBlankChars",
+]
+
+#
+# These functions have side effects on the global state
+# and hence generate errors on memory allocation tests
+#
+skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
+   "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
+   "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
+   "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
+   "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
+   "xmlSchemaGetBuiltInType",
+   "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
+   "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
+   "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
+]
+
+#
+# Extra code needed for some test cases
+#
+extra_pre_call = {
+   "xmlSAXUserParseFile": """
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+""",
+   "xmlSAXUserParseMemory": """
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+""",
+   "xmlParseBalancedChunkMemory": """
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+""",
+   "xmlParseBalancedChunkMemoryRecover": """
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+""",
+   "xmlParserInputBufferCreateFd":
+       "if (fd >= 0) fd = -1;",
+}
+extra_post_call = {
+   "xmlAddChild": 
+       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
+   "xmlAddEntity":
+       "if (ret_val != NULL) { xmlFreeNode(ret_val) ; ret_val = NULL; }",
+   "xmlAddChildList": 
+       "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
+   "xmlAddSibling":
+       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
+   "xmlAddNextSibling":
+       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
+   "xmlAddPrevSibling": 
+       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
+   "xmlDocSetRootElement": 
+       "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
+   "xmlReplaceNode": 
+       """if (cur != NULL) {
+              xmlUnlinkNode(cur);
+              xmlFreeNode(cur) ; cur = NULL ; }
+          if (old != NULL) {
+              xmlUnlinkNode(old);
+              xmlFreeNode(old) ; old = NULL ; }
+	  ret_val = NULL;""",
+   "xmlTextMerge": 
+       """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
+              xmlUnlinkNode(second);
+              xmlFreeNode(second) ; second = NULL ; }""",
+   "xmlBuildQName": 
+       """if ((ret_val != NULL) && (ret_val != ncname) &&
+              (ret_val != prefix) && (ret_val != memory))
+              xmlFree(ret_val);
+	  ret_val = NULL;""",
+   "xmlNewDocElementContent":
+       """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
+   "xmlDictReference": "xmlDictFree(dict);",
+   # Functions which deallocates one of their parameters
+   "xmlXPathConvertBoolean": """val = NULL;""",
+   "xmlXPathConvertNumber": """val = NULL;""",
+   "xmlXPathConvertString": """val = NULL;""",
+   "xmlSaveFileTo": """buf = NULL;""",
+   "xmlSaveFormatFileTo": """buf = NULL;""",
+   "xmlIOParseDTD": "input = NULL;",
+   "xmlRemoveProp": "cur = NULL;",
+   "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
+   "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
+   "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
+   "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
+   "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
+   "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
+   "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
+   "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
+   "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
+   "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
+   "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
+   "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
+   "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}"
+}
+
+modules = []
+
+def is_skipped_module(name):
+    for mod in skipped_modules:
+        if mod == name:
+	    return 1
+    return 0
+
+def is_skipped_function(name):
+    for fun in skipped_functions:
+        if fun == name:
+	    return 1
+    # Do not test destructors
+    if string.find(name, 'Free') != -1:
+        return 1
+    return 0
+
+def is_skipped_memcheck(name):
+    for fun in skipped_memcheck:
+        if fun == name:
+	    return 1
+    return 0
+
+missing_types = {}
+def add_missing_type(name, func):
+    try:
+        list = missing_types[name]
+	list.append(func)
+    except:
+        missing_types[name] = [func]
+
+generated_param_types = []
+def add_generated_param_type(name):
+    generated_param_types.append(name)
+
+generated_return_types = []
+def add_generated_return_type(name):
+    generated_return_types.append(name)
+
+missing_functions = {}
+missing_functions_nr = 0
+def add_missing_functions(name, module):
+    global missing_functions_nr
+
+    missing_functions_nr = missing_functions_nr + 1
+    try:
+        list = missing_functions[module]
+	list.append(name)
+    except:
+        missing_functions[module] = [name]
+
+#
+# Provide the type generators and destructors for the parameters
+#
+
+def type_convert(str, name, info, module, function, pos):
+#    res = string.replace(str, "    ", " ")
+#    res = string.replace(str, "   ", " ")
+#    res = string.replace(str, "  ", " ")
+    res = string.replace(str, " *", "_ptr")
+#    res = string.replace(str, "*", "_ptr")
+    res = string.replace(res, " ", "_")
+    if res == 'const_char_ptr':
+        if string.find(name, "file") != -1 or \
+           string.find(name, "uri") != -1 or \
+           string.find(name, "URI") != -1 or \
+           string.find(info, "filename") != -1 or \
+           string.find(info, "URI") != -1 or \
+           string.find(info, "URL") != -1:
+	    if string.find(function, "Save") != -1 or \
+	       string.find(function, "Create") != -1 or \
+	       string.find(function, "Write") != -1 or \
+	       string.find(function, "Fetch") != -1:
+	        return('fileoutput')
+	    return('filepath')
+    if res == 'void_ptr':
+        if module == 'nanoftp' and name == 'ctx':
+	    return('xmlNanoFTPCtxtPtr')
+        if function == 'xmlNanoFTPNewCtxt' or \
+	   function == 'xmlNanoFTPConnectTo' or \
+	   function == 'xmlNanoFTPOpen':
+	    return('xmlNanoFTPCtxtPtr')
+        if module == 'nanohttp' and name == 'ctx':
+	    return('xmlNanoHTTPCtxtPtr')
+	if function == 'xmlNanoHTTPMethod' or \
+	   function == 'xmlNanoHTTPMethodRedir' or \
+	   function == 'xmlNanoHTTPOpen' or \
+	   function == 'xmlNanoHTTPOpenRedir':
+	    return('xmlNanoHTTPCtxtPtr');
+        if function == 'xmlIOHTTPOpen':
+	    return('xmlNanoHTTPCtxtPtr')
+	if string.find(name, "data") != -1:
+	    return('userdata')
+	if string.find(name, "user") != -1:
+	    return('userdata')
+    if res == 'xmlDoc_ptr':
+        res = 'xmlDocPtr'
+    if res == 'xmlNode_ptr':
+        res = 'xmlNodePtr'
+    if res == 'xmlDict_ptr':
+        res = 'xmlDictPtr'
+    if res == 'xmlNodePtr' and pos != 0:
+        if (function == 'xmlAddChild' and pos == 2) or \
+	   (function == 'xmlAddChildList' and pos == 2) or \
+           (function == 'xmlAddNextSibling' and pos == 2) or \
+           (function == 'xmlAddSibling' and pos == 2) or \
+           (function == 'xmlDocSetRootElement' and pos == 2) or \
+           (function == 'xmlReplaceNode' and pos == 2) or \
+           (function == 'xmlTextMerge') or \
+	   (function == 'xmlAddPrevSibling' and pos == 2):
+	    return('xmlNodePtr_in');
+    if res == 'const xmlBufferPtr':
+        res = 'xmlBufferPtr'
+    if res == 'xmlChar_ptr' and name == 'name' and \
+       string.find(function, "EatName") != -1:
+        return('eaten_name')
+    if res == 'void_ptr*':
+        res = 'void_ptr_ptr'
+    if res == 'char_ptr*':
+        res = 'char_ptr_ptr'
+    if res == 'xmlChar_ptr*':
+        res = 'xmlChar_ptr_ptr'
+    if res == 'const_xmlChar_ptr*':
+        res = 'const_xmlChar_ptr_ptr'
+    if res == 'const_char_ptr*':
+        res = 'const_char_ptr_ptr'
+    if res == 'FILE_ptr' and module == 'debugXML':
+        res = 'debug_FILE_ptr';
+    if res == 'int' and name == 'options':
+        if module == 'parser' or module == 'xmlreader':
+	    res = 'parseroptions'
+
+    return res
+
+known_param_types = []
+
+def is_known_param_type(name, rtype):
+    global test
+    for type in known_param_types:
+        if type == name:
+	    return 1
+    for type in generated_param_types:
+        if type == name:
+	    return 1
+
+    if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
+        if rtype[0:6] == 'const ':
+	    crtype = rtype[6:]
+	else:
+	    crtype = rtype
+
+        define = 0
+	if module in modules_defines:
+	    test.write("#ifdef %s\n" % (modules_defines[module]))
+	    define = 1
+        test.write("""
+#define gen_nb_%s 1
+static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+""" % (name, crtype, name, name, rtype))
+        if define == 1:
+	    test.write("#endif\n\n")
+        add_generated_param_type(name)
+        return 1
+
+    return 0
+
+#
+# Provide the type destructors for the return values
+#
+
+known_return_types = []
+
+def is_known_return_type(name):
+    for type in known_return_types:
+        if type == name:
+	    return 1
+    return 0
+
+#
+# Copy the beginning of the C test program result
+#
+
+try:
+    input = open("testapi.c", "r")
+except:
+    input = open(srcPref + "testapi.c", "r")
+test = open('testapi.c.new', 'w')
+
+def compare_and_save():
+    global test
+
+    test.close()
+    try:
+        input = open("testapi.c", "r").read()
+    except:
+        input = ''
+    test = open('testapi.c.new', "r").read()
+    if input != test:
+        try:
+            os.system("rm testapi.c; mv testapi.c.new testapi.c")
+        except:
+	    os.system("mv testapi.c.new testapi.c")
+        print("Updated testapi.c")
+    else:
+        print("Generated testapi.c is identical")
+
+line = input.readline()
+while line != "":
+    if line == "/* CUT HERE: everything below that line is generated */\n":
+        break;
+    if line[0:15] == "#define gen_nb_":
+        type = string.split(line[15:])[0]
+	known_param_types.append(type)
+    if line[0:19] == "static void desret_":
+        type = string.split(line[19:], '(')[0]
+	known_return_types.append(type)
+    test.write(line)
+    line = input.readline()
+input.close()
+
+if line == "":
+    print("Could not find the CUT marker in testapi.c skipping generation")
+    test.close()
+    sys.exit(0)
+
+print(("Scanned testapi.c: found %d parameters types and %d return types\n" % (
+      len(known_param_types), len(known_return_types))))
+test.write("/* CUT HERE: everything below that line is generated */\n")
+
+
+#
+# Open the input API description
+#
+doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
+if doc == None:
+    print("Failed to load doc/libxml2-api.xml")
+    sys.exit(1)
+ctxt = doc.xpathNewContext()
+
+#
+# Generate a list of all function parameters and select only
+# those used in the api tests
+#
+argtypes = {}
+args = ctxt.xpathEval("/api/symbols/function/arg")
+for arg in args:
+    mod = arg.xpathEval('string(../@file)')
+    func = arg.xpathEval('string(../@name)')
+    if (mod not in skipped_modules) and (func not in skipped_functions):
+	type = arg.xpathEval('string(@type)')
+	if type not in argtypes:
+	    argtypes[type] = func
+
+# similarly for return types
+rettypes = {}
+rets = ctxt.xpathEval("/api/symbols/function/return")
+for ret in rets:
+    mod = ret.xpathEval('string(../@file)')
+    func = ret.xpathEval('string(../@name)')
+    if (mod not in skipped_modules) and (func not in skipped_functions):
+        type = ret.xpathEval('string(@type)')
+	if type not in rettypes:
+	    rettypes[type] = func
+
+#
+# Generate constructors and return type handling for all enums
+# which are used as function parameters
+#
+enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
+for enum in enums:
+    module = enum.xpathEval('string(@file)')
+    name = enum.xpathEval('string(@name)')
+    #
+    # Skip any enums which are not in our filtered lists
+    #
+    if (name == None) or ((name not in argtypes) and (name not in rettypes)):
+        continue;
+    define = 0
+
+    if name in argtypes and is_known_param_type(name, name) == 0:
+	values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
+	i = 0
+	vals = []
+	for value in values:
+	    vname = value.xpathEval('string(@name)')
+	    if vname == None:
+		continue;
+	    i = i + 1
+	    if i >= 5:
+		break;
+	    vals.append(vname)
+	if vals == []:
+	    print("Didn't find any value for enum %s" % (name))
+	    continue
+	if module in modules_defines:
+	    test.write("#ifdef %s\n" % (modules_defines[module]))
+	    define = 1
+	test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
+	test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
+	           (name, name))
+	i = 1
+	for value in vals:
+	    test.write("    if (no == %d) return(%s);\n" % (i, value))
+	    i = i + 1
+	test.write("""    return(0);
+}
+
+static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+""" % (name, name));
+	known_param_types.append(name)
+
+    if (is_known_return_type(name) == 0) and (name in rettypes):
+	if define == 0 and module in modules_defines:
+	    test.write("#ifdef %s\n" % (modules_defines[module]))
+	    define = 1
+        test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
+}
+
+""" % (name, name))
+	known_return_types.append(name)
+    if define == 1:
+        test.write("#endif\n\n")
+
+#
+# Load the interfaces
+# 
+headers = ctxt.xpathEval("/api/files/file")
+for file in headers:
+    name = file.xpathEval('string(@name)')
+    if (name == None) or (name == ''):
+        continue
+
+    #
+    # Some module may be skipped because they don't really consists
+    # of user callable APIs
+    #
+    if is_skipped_module(name):
+        continue
+
+    #
+    # do not test deprecated APIs
+    #
+    desc = file.xpathEval('string(description)')
+    if string.find(desc, 'DEPRECATED') != -1:
+        print("Skipping deprecated interface %s" % name)
+	continue;
+
+    test.write("#include <libxml/%s.h>\n" % name)
+    modules.append(name)
+        
+#
+# Generate the callers signatures
+# 
+for module in modules:
+    test.write("static int test_%s(void);\n" % module);
+
+#
+# Generate the top caller
+# 
+
+test.write("""
+/**
+ * testlibxml2:
+ *
+ * Main entry point of the tester for the full libxml2 module,
+ * it calls all the tester entry point for each module.
+ *
+ * Returns the number of error found
+ */
+static int
+testlibxml2(void)
+{
+    int test_ret = 0;
+
+""")
+
+for module in modules:
+    test.write("    test_ret += test_%s();\n" % module)
+
+test.write("""
+    printf("Total: %d functions, %d tests, %d errors\\n",
+           function_tests, call_tests, test_ret);
+    return(test_ret);
+}
+
+""")
+
+#
+# How to handle a function
+# 
+nb_tests = 0
+
+def generate_test(module, node):
+    global test
+    global nb_tests
+    nb_cond = 0
+    no_gen = 0
+
+    name = node.xpathEval('string(@name)')
+    if is_skipped_function(name):
+        return
+
+    #
+    # check we know how to handle the args and return values
+    # and store the informations for the generation
+    #
+    try:
+	args = node.xpathEval("arg")
+    except:
+        args = []
+    t_args = []
+    n = 0
+    for arg in args:
+        n = n + 1
+        rtype = arg.xpathEval("string(@type)")
+	if rtype == 'void':
+	    break;
+	info = arg.xpathEval("string(@info)")
+	nam = arg.xpathEval("string(@name)")
+        type = type_convert(rtype, nam, info, module, name, n)
+	if is_known_param_type(type, rtype) == 0:
+	    add_missing_type(type, name);
+	    no_gen = 1
+        if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
+	    rtype[0:6] == 'const ':
+	    crtype = rtype[6:]
+	else:
+	    crtype = rtype
+	t_args.append((nam, type, rtype, crtype, info))
+    
+    try:
+	rets = node.xpathEval("return")
+    except:
+        rets = []
+    t_ret = None
+    for ret in rets:
+        rtype = ret.xpathEval("string(@type)")
+	info = ret.xpathEval("string(@info)")
+        type = type_convert(rtype, 'return', info, module, name, 0)
+	if rtype == 'void':
+	    break
+	if is_known_return_type(type) == 0:
+	    add_missing_type(type, name);
+	    no_gen = 1
+	t_ret = (type, rtype, info)
+	break
+
+    test.write("""
+static int
+test_%s(void) {
+    int test_ret = 0;
+
+""" % (name))
+
+    if no_gen == 1:
+        add_missing_functions(name, module)
+	test.write("""
+    /* missing type support */
+    return(test_ret);
+}
+
+""")
+        return
+
+    try:
+	conds = node.xpathEval("cond")
+	for cond in conds:
+	    test.write("#if %s\n" % (cond.get_content()))
+	    nb_cond = nb_cond + 1
+    except:
+        pass
+
+    define = 0
+    if name in function_defines:
+        test.write("#ifdef %s\n" % (function_defines[name]))
+	define = 1
+    
+    # Declare the memory usage counter
+    no_mem = is_skipped_memcheck(name)
+    if no_mem == 0:
+	test.write("    int mem_base;\n");
+
+    # Declare the return value
+    if t_ret != None:
+        test.write("    %s ret_val;\n" % (t_ret[1]))
+
+    # Declare the arguments
+    for arg in t_args:
+        (nam, type, rtype, crtype, info) = arg;
+	# add declaration
+	test.write("    %s %s; /* %s */\n" % (crtype, nam, info))
+	test.write("    int n_%s;\n" % (nam))
+    test.write("\n")
+
+    # Cascade loop on of each argument list of values
+    for arg in t_args:
+        (nam, type, rtype, crtype, info) = arg;
+	#
+	test.write("    for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
+	           nam, nam, type, nam))
+    
+    # log the memory usage
+    if no_mem == 0:
+	test.write("        mem_base = xmlMemBlocks();\n");
+
+    # prepare the call
+    i = 0;
+    for arg in t_args:
+        (nam, type, rtype, crtype, info) = arg;
+	#
+	test.write("        %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
+	i = i + 1;
+
+    # do the call, and clanup the result
+    if name in extra_pre_call:
+	test.write("        %s\n"% (extra_pre_call[name]))
+    if t_ret != None:
+	test.write("\n        ret_val = %s(" % (name))
+	need = 0
+	for arg in t_args:
+	    (nam, type, rtype, crtype, info) = arg
+	    if need:
+	        test.write(", ")
+	    else:
+	        need = 1
+	    if rtype != crtype:
+	        test.write("(%s)" % rtype)
+	    test.write("%s" % nam);
+	test.write(");\n")
+	if name in extra_post_call:
+	    test.write("        %s\n"% (extra_post_call[name]))
+	test.write("        desret_%s(ret_val);\n" % t_ret[0])
+    else:
+	test.write("\n        %s(" % (name));
+	need = 0;
+	for arg in t_args:
+	    (nam, type, rtype, crtype, info) = arg;
+	    if need:
+	        test.write(", ")
+	    else:
+	        need = 1
+	    if rtype != crtype:
+	        test.write("(%s)" % rtype)
+	    test.write("%s" % nam)
+	test.write(");\n")
+	if name in extra_post_call:
+	    test.write("        %s\n"% (extra_post_call[name]))
+
+    test.write("        call_tests++;\n");
+
+    # Free the arguments
+    i = 0;
+    for arg in t_args:
+        (nam, type, rtype, crtype, info) = arg;
+	# This is a hack to prevent generating a destructor for the
+	# 'input' argument in xmlTextReaderSetup.  There should be
+	# a better, more generic way to do this!
+	if string.find(info, 'destroy') == -1:
+	    test.write("        des_%s(n_%s, " % (type, nam))
+	    if rtype != crtype:
+	        test.write("(%s)" % rtype)
+	    test.write("%s, %d);\n" % (nam, i))
+	i = i + 1;
+
+    test.write("        xmlResetLastError();\n");
+    # Check the memory usage
+    if no_mem == 0:
+	test.write("""        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %%d blocks found in %s",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+""" % (name));
+	for arg in t_args:
+	    (nam, type, rtype, crtype, info) = arg;
+	    test.write("""            printf(" %%d", n_%s);\n""" % (nam))
+	test.write("""            printf("\\n");\n""")
+	test.write("        }\n")
+
+    for arg in t_args:
+	test.write("    }\n")
+
+    test.write("    function_tests++;\n")
+    #
+    # end of conditional
+    #
+    while nb_cond > 0:
+        test.write("#endif\n")
+	nb_cond = nb_cond -1
+    if define == 1:
+        test.write("#endif\n")
+
+    nb_tests = nb_tests + 1;
+
+    test.write("""
+    return(test_ret);
+}
+
+""")
+    
+#
+# Generate all module callers
+#
+for module in modules:
+    # gather all the functions exported by that module
+    try:
+	functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
+    except:
+        print("Failed to gather functions from module %s" % (module))
+	continue;
+
+    # iterate over all functions in the module generating the test
+    i = 0
+    nb_tests_old = nb_tests
+    for function in functions:
+        i = i + 1
+        generate_test(module, function);
+
+    # header
+    test.write("""static int
+test_%s(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
+""" % (module, module, nb_tests - nb_tests_old, i))
+
+    # iterate over all functions in the module generating the call
+    for function in functions:
+        name = function.xpathEval('string(@name)')
+	if is_skipped_function(name):
+	    continue
+	test.write("    test_ret += test_%s();\n" % (name))
+
+    # footer
+    test.write("""
+    if (test_ret != 0)
+	printf("Module %s: %%d errors\\n", test_ret);
+    return(test_ret);
+}
+""" % (module))
+
+#
+# Generate direct module caller
+#
+test.write("""static int
+test_module(const char *module) {
+""");
+for module in modules:
+    test.write("""    if (!strcmp(module, "%s")) return(test_%s());\n""" % (
+        module, module))
+test.write("""    return(0);
+}
+""");
+
+print("Generated test for %d modules and %d functions" %(len(modules), nb_tests))
+
+compare_and_save()
+
+missing_list = []
+for missing in list(missing_types.keys()):
+    if missing == 'va_list' or missing == '...':
+        continue;
+
+    n = len(missing_types[missing])
+    missing_list.append((n, missing))
+
+def compare_missing(a, b):
+    return b[0] - a[0]
+
+missing_list.sort(compare_missing)
+print("Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list)))
+lst = open("missing.lst", "w")
+lst.write("Missing support for %d types" % (len(missing_list)))
+lst.write("\n")
+for miss in missing_list:
+    lst.write("%s: %d :" % (miss[1], miss[0]))
+    i = 0
+    for n in missing_types[miss[1]]:
+        i = i + 1
+        if i > 5:
+	    lst.write(" ...")
+	    break
+	lst.write(" %s" % (n))
+    lst.write("\n")
+lst.write("\n")
+lst.write("\n")
+lst.write("Missing support per module");
+for module in list(missing_functions.keys()):
+    lst.write("module %s:\n   %s\n" % (module, missing_functions[module]))
+
+lst.close()
+
+
diff --git a/src/globals.c b/src/globals.c
new file mode 100644
index 0000000..b369346
--- /dev/null
+++ b/src/globals.c
@@ -0,0 +1,1133 @@
+/*
+ * globals.c: definition and handling of the set of global variables
+ *            of the library
+ *
+ * The bottom of this file is automatically generated by build_glob.py
+ * based on the description file global.data
+ *
+ * See Copyright for the status of this software.
+ *
+ * Gary Pennington <Gary.Pennington@uk.sun.com>
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+#include <libxml/globals.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/threads.h>
+
+/* #define DEBUG_GLOBALS */
+
+/*
+ * Helpful Macro
+ */
+#ifdef LIBXML_THREAD_ENABLED
+#define IS_MAIN_THREAD (xmlIsMainThread())
+#else
+#define IS_MAIN_THREAD 1
+#endif
+
+/*
+ * Mutex to protect "ForNewThreads" variables
+ */
+static xmlMutexPtr xmlThrDefMutex = NULL;
+
+/**
+ * xmlInitGlobals:
+ *
+ * Additional initialisation for multi-threading
+ */
+void xmlInitGlobals(void)
+{
+    if (xmlThrDefMutex == NULL)
+        xmlThrDefMutex = xmlNewMutex();
+}
+
+/**
+ * xmlCleanupGlobals:
+ *
+ * Additional cleanup for multi-threading
+ */
+void xmlCleanupGlobals(void)
+{
+    if (xmlThrDefMutex != NULL) {
+	xmlFreeMutex(xmlThrDefMutex);
+	xmlThrDefMutex = NULL;
+    }
+    __xmlGlobalInitMutexDestroy();
+}
+
+/************************************************************************
+ * 									*
+ *	All the user accessible global variables of the library		*
+ * 									*
+ ************************************************************************/
+
+/*
+ * Memory allocation routines
+ */
+#undef	xmlFree
+#undef	xmlMalloc
+#undef	xmlMallocAtomic
+#undef	xmlMemStrdup
+#undef	xmlRealloc
+
+#if defined(DEBUG_MEMORY_LOCATION) || defined(DEBUG_MEMORY)
+xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
+xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
+xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
+xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
+xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
+#else
+
+#define MAX_LIBXML_MALLOC (1024*1024*512)
+
+static void* size_checked_malloc(size_t size) {
+  if (size > MAX_LIBXML_MALLOC) {
+    *(volatile char*)0 = '\0';
+    return NULL;
+  }
+  return malloc(size);
+}
+
+static void* size_checked_realloc(void* ptr, size_t size) {
+  if (size > MAX_LIBXML_MALLOC) {
+    *(volatile char*)0 = '\0';
+    return NULL;
+  }
+  return realloc(ptr, size);
+}
+
+/**
+ * xmlFree:
+ * @mem: an already allocated block of memory
+ *
+ * The variable holding the libxml free() implementation
+ */
+xmlFreeFunc xmlFree = (xmlFreeFunc) free;
+/**
+ * xmlMalloc:
+ * @size:  the size requested in bytes
+ *
+ * The variable holding the libxml malloc() implementation
+ *
+ * Returns a pointer to the newly allocated block or NULL in case of error
+ */
+xmlMallocFunc xmlMalloc = (xmlMallocFunc) size_checked_malloc;
+/**
+ * xmlMallocAtomic:
+ * @size:  the size requested in bytes
+ *
+ * The variable holding the libxml malloc() implementation for atomic
+ * data (i.e. blocks not containings pointers), useful when using a
+ * garbage collecting allocator.
+ *
+ * Returns a pointer to the newly allocated block or NULL in case of error
+ */
+xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) size_checked_malloc;
+/**
+ * xmlRealloc:
+ * @mem: an already allocated block of memory
+ * @size:  the new size requested in bytes
+ *
+ * The variable holding the libxml realloc() implementation
+ *
+ * Returns a pointer to the newly reallocated block or NULL in case of error
+ */
+xmlReallocFunc xmlRealloc = (xmlReallocFunc) size_checked_realloc;
+/**
+ * xmlMemStrdup:
+ * @str: a zero terminated string
+ *
+ * The variable holding the libxml strdup() implementation
+ *
+ * Returns the copy of the string or NULL in case of error
+ */
+xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
+#endif /* DEBUG_MEMORY_LOCATION || DEBUG_MEMORY */
+
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+#include <libxml/SAX.h>
+
+#undef	docbDefaultSAXHandler
+#undef	htmlDefaultSAXHandler
+#undef	oldXMLWDcompatibility
+#undef	xmlBufferAllocScheme
+#undef	xmlDefaultBufferSize
+#undef	xmlDefaultSAXHandler
+#undef	xmlDefaultSAXLocator
+#undef	xmlDoValidityCheckingDefaultValue
+#undef	xmlGenericError
+#undef	xmlStructuredError
+#undef	xmlGenericErrorContext
+#undef	xmlStructuredErrorContext
+#undef	xmlGetWarningsDefaultValue
+#undef	xmlIndentTreeOutput
+#undef  xmlTreeIndentString
+#undef	xmlKeepBlanksDefaultValue
+#undef	xmlLineNumbersDefaultValue
+#undef	xmlLoadExtDtdDefaultValue
+#undef	xmlParserDebugEntities
+#undef	xmlParserVersion
+#undef	xmlPedanticParserDefaultValue
+#undef	xmlSaveNoEmptyTags
+#undef	xmlSubstituteEntitiesDefaultValue
+#undef	xmlRegisterNodeDefaultValue
+#undef	xmlDeregisterNodeDefaultValue
+#undef	xmlLastError
+
+#undef  xmlParserInputBufferCreateFilenameValue
+#undef  xmlOutputBufferCreateFilenameValue
+/**
+ * xmlParserVersion:
+ *
+ * Constant string describing the internal version of the library
+ */
+const char *xmlParserVersion = LIBXML_VERSION_STRING LIBXML_VERSION_EXTRA;
+
+/**
+ * xmlBufferAllocScheme:
+ *
+ * Global setting, default allocation policy for buffers, default is
+ * XML_BUFFER_ALLOC_EXACT
+ */
+xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
+static xmlBufferAllocationScheme xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT;
+/**
+ * xmlDefaultBufferSize:
+ *
+ * Global setting, default buffer size. Default value is BASE_BUFFER_SIZE
+ */
+int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
+static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE;
+
+/*
+ * Parser defaults
+ */
+
+/**
+ * oldXMLWDcompatibility:
+ *
+ * Global setting, DEPRECATED.
+ */
+int oldXMLWDcompatibility = 0; /* DEPRECATED */
+/**
+ * xmlParserDebugEntities:
+ *
+ * Global setting, asking the parser to print out debugging informations.
+ * while handling entities.
+ * Disabled by default
+ */
+int xmlParserDebugEntities = 0;
+static int xmlParserDebugEntitiesThrDef = 0;
+/**
+ * xmlDoValidityCheckingDefaultValue:
+ *
+ * Global setting, indicate that the parser should work in validating mode.
+ * Disabled by default.
+ */
+int xmlDoValidityCheckingDefaultValue = 0;
+static int xmlDoValidityCheckingDefaultValueThrDef = 0;
+/**
+ * xmlGetWarningsDefaultValue:
+ *
+ * Global setting, indicate that the parser should provide warnings.
+ * Activated by default.
+ */
+int xmlGetWarningsDefaultValue = 1;
+static int xmlGetWarningsDefaultValueThrDef = 1;
+/**
+ * xmlLoadExtDtdDefaultValue:
+ *
+ * Global setting, indicate that the parser should load DTD while not
+ * validating.
+ * Disabled by default.
+ */
+int xmlLoadExtDtdDefaultValue = 0;
+static int xmlLoadExtDtdDefaultValueThrDef = 0;
+/**
+ * xmlPedanticParserDefaultValue:
+ *
+ * Global setting, indicate that the parser be pedantic
+ * Disabled by default.
+ */
+int xmlPedanticParserDefaultValue = 0;
+static int xmlPedanticParserDefaultValueThrDef = 0;
+/**
+ * xmlLineNumbersDefaultValue:
+ *
+ * Global setting, indicate that the parser should store the line number
+ * in the content field of elements in the DOM tree. 
+ * Disabled by default since this may not be safe for old classes of
+ * applicaton.
+ */
+int xmlLineNumbersDefaultValue = 0;
+static int xmlLineNumbersDefaultValueThrDef = 0;
+/**
+ * xmlKeepBlanksDefaultValue:
+ *
+ * Global setting, indicate that the parser should keep all blanks
+ * nodes found in the content
+ * Activated by default, this is actually needed to have the parser
+ * conformant to the XML Recommendation, however the option is kept
+ * for some applications since this was libxml1 default behaviour.
+ */
+int xmlKeepBlanksDefaultValue = 1;
+static int xmlKeepBlanksDefaultValueThrDef = 1;
+/**
+ * xmlSubstituteEntitiesDefaultValue:
+ *
+ * Global setting, indicate that the parser should not generate entity
+ * references but replace them with the actual content of the entity
+ * Disabled by default, this should be activated when using XPath since
+ * the XPath data model requires entities replacement and the XPath
+ * engine does not handle entities references transparently.
+ */
+int xmlSubstituteEntitiesDefaultValue = 0;
+static int xmlSubstituteEntitiesDefaultValueThrDef = 0;
+
+xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL;
+static xmlRegisterNodeFunc xmlRegisterNodeDefaultValueThrDef = NULL;
+xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL;
+static xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValueThrDef = NULL;
+
+xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue = NULL;
+static xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValueThrDef = NULL;
+
+xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue = NULL;
+static xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValueThrDef = NULL;
+
+/*
+ * Error handling
+ */
+
+/* xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc; */
+/* Must initialize xmlGenericError in xmlInitParser */
+void XMLCDECL xmlGenericErrorDefaultFunc	(void *ctx ATTRIBUTE_UNUSED,
+				 const char *msg,
+				 ...);
+/**
+ * xmlGenericError:
+ *
+ * Global setting: function used for generic error callbacks
+ */
+xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
+static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
+/**
+ * xmlStructuredError:
+ *
+ * Global setting: function used for structured error callbacks
+ */
+xmlStructuredErrorFunc xmlStructuredError = NULL;
+static xmlStructuredErrorFunc xmlStructuredErrorThrDef = NULL;
+/**
+ * xmlGenericErrorContext:
+ *
+ * Global setting passed to generic error callbacks
+ */
+void *xmlGenericErrorContext = NULL;
+static void *xmlGenericErrorContextThrDef = NULL;
+/**
+ * xmlStructuredErrorContext:
+ *
+ * Global setting passed to structured error callbacks
+ */
+void *xmlStructuredErrorContext = NULL;
+static void *xmlStructuredErrorContextThrDef = NULL;
+xmlError xmlLastError;
+
+/*
+ * output defaults
+ */
+/**
+ * xmlIndentTreeOutput:
+ *
+ * Global setting, asking the serializer to indent the output tree by default
+ * Enabled by default
+ */
+int xmlIndentTreeOutput = 1;
+static int xmlIndentTreeOutputThrDef = 1;
+
+/**
+ * xmlTreeIndentString:
+ *
+ * The string used to do one-level indent. By default is equal to "  " (two spaces)
+ */
+const char *xmlTreeIndentString = "  ";
+static const char *xmlTreeIndentStringThrDef = "  ";
+
+/**
+ * xmlSaveNoEmptyTags:
+ *
+ * Global setting, asking the serializer to not output empty tags
+ * as <empty/> but <empty></empty>. those two forms are undistinguishable
+ * once parsed.
+ * Disabled by default
+ */
+int xmlSaveNoEmptyTags = 0;
+static int xmlSaveNoEmptyTagsThrDef = 0;
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlDefaultSAXHandler:
+ *
+ * Default SAX version1 handler for XML, builds the DOM tree
+ */
+xmlSAXHandlerV1 xmlDefaultSAXHandler = {
+    xmlSAX2InternalSubset,
+    xmlSAX2IsStandalone,
+    xmlSAX2HasInternalSubset,
+    xmlSAX2HasExternalSubset,
+    xmlSAX2ResolveEntity,
+    xmlSAX2GetEntity,
+    xmlSAX2EntityDecl,
+    xmlSAX2NotationDecl,
+    xmlSAX2AttributeDecl,
+    xmlSAX2ElementDecl,
+    xmlSAX2UnparsedEntityDecl,
+    xmlSAX2SetDocumentLocator,
+    xmlSAX2StartDocument,
+    xmlSAX2EndDocument,
+    xmlSAX2StartElement,
+    xmlSAX2EndElement,
+    xmlSAX2Reference,
+    xmlSAX2Characters,
+    xmlSAX2Characters,
+    xmlSAX2ProcessingInstruction,
+    xmlSAX2Comment,
+    xmlParserWarning,
+    xmlParserError,
+    xmlParserError,
+    xmlSAX2GetParameterEntity,
+    xmlSAX2CDataBlock,
+    xmlSAX2ExternalSubset,
+    0,
+};
+#endif /* LIBXML_SAX1_ENABLED */
+
+/**
+ * xmlDefaultSAXLocator:
+ *
+ * The default SAX Locator
+ * { getPublicId, getSystemId, getLineNumber, getColumnNumber}
+ */
+xmlSAXLocator xmlDefaultSAXLocator = {
+    xmlSAX2GetPublicId,
+    xmlSAX2GetSystemId,
+    xmlSAX2GetLineNumber,
+    xmlSAX2GetColumnNumber
+};
+
+#ifdef LIBXML_HTML_ENABLED
+/**
+ * htmlDefaultSAXHandler:
+ *
+ * Default old SAX v1 handler for HTML, builds the DOM tree
+ */
+xmlSAXHandlerV1 htmlDefaultSAXHandler = {
+    xmlSAX2InternalSubset,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    xmlSAX2GetEntity,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    xmlSAX2SetDocumentLocator,
+    xmlSAX2StartDocument,
+    xmlSAX2EndDocument,
+    xmlSAX2StartElement,
+    xmlSAX2EndElement,
+    NULL,
+    xmlSAX2Characters,
+    xmlSAX2IgnorableWhitespace,
+    xmlSAX2ProcessingInstruction,
+    xmlSAX2Comment,
+    xmlParserWarning,
+    xmlParserError,
+    xmlParserError,
+    xmlSAX2GetParameterEntity,
+    xmlSAX2CDataBlock,
+    NULL,
+    0,
+};
+#endif /* LIBXML_HTML_ENABLED */
+
+#ifdef LIBXML_DOCB_ENABLED
+/**
+ * docbDefaultSAXHandler:
+ *
+ * Default old SAX v1 handler for SGML DocBook, builds the DOM tree
+ */
+xmlSAXHandlerV1 docbDefaultSAXHandler = {
+    xmlSAX2InternalSubset,
+    xmlSAX2IsStandalone,
+    xmlSAX2HasInternalSubset,
+    xmlSAX2HasExternalSubset,
+    xmlSAX2ResolveEntity,
+    xmlSAX2GetEntity,
+    xmlSAX2EntityDecl,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    xmlSAX2SetDocumentLocator,
+    xmlSAX2StartDocument,
+    xmlSAX2EndDocument,
+    xmlSAX2StartElement,
+    xmlSAX2EndElement,
+    xmlSAX2Reference,
+    xmlSAX2Characters,
+    xmlSAX2IgnorableWhitespace,
+    NULL,
+    xmlSAX2Comment,
+    xmlParserWarning,
+    xmlParserError,
+    xmlParserError,
+    xmlSAX2GetParameterEntity,
+    NULL,
+    NULL,
+    0,
+};
+#endif /* LIBXML_DOCB_ENABLED */
+
+/**
+ * xmlInitializeGlobalState:
+ * @gs: a pointer to a newly allocated global state
+ *
+ * xmlInitializeGlobalState() initialize a global state with all the
+ * default values of the library.
+ */
+void
+xmlInitializeGlobalState(xmlGlobalStatePtr gs)
+{
+#ifdef DEBUG_GLOBALS
+    fprintf(stderr, "Initializing globals at %lu for thread %d\n",
+	    (unsigned long) gs, xmlGetThreadId());
+#endif
+
+    /*
+     * Perform initialization as required by libxml
+     */
+    if (xmlThrDefMutex == NULL)
+        xmlInitGlobals();
+
+    xmlMutexLock(xmlThrDefMutex);
+
+#if defined(LIBXML_DOCB_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED)
+    initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
+#endif
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
+    inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
+#endif
+
+    gs->oldXMLWDcompatibility = 0;
+    gs->xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
+    gs->xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
+#if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
+    initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
+#endif /* LIBXML_SAX1_ENABLED */
+    gs->xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
+    gs->xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
+    gs->xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
+    gs->xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
+    gs->xmlDoValidityCheckingDefaultValue = 
+         xmlDoValidityCheckingDefaultValueThrDef;
+#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
+    gs->xmlFree = (xmlFreeFunc) xmlMemFree;
+    gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
+    gs->xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
+    gs->xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
+    gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
+#else
+    gs->xmlFree = (xmlFreeFunc) free;
+    gs->xmlMalloc = (xmlMallocFunc) malloc;
+    gs->xmlMallocAtomic = (xmlMallocFunc) malloc;
+    gs->xmlRealloc = (xmlReallocFunc) realloc;
+    gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
+#endif
+    gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
+    gs->xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
+    gs->xmlTreeIndentString = xmlTreeIndentStringThrDef;
+    gs->xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
+    gs->xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
+    gs->xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
+    gs->xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
+    gs->xmlParserVersion = LIBXML_VERSION_STRING;
+    gs->xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
+    gs->xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
+    gs->xmlSubstituteEntitiesDefaultValue = 
+        xmlSubstituteEntitiesDefaultValueThrDef;
+
+    gs->xmlGenericError = xmlGenericErrorThrDef;
+    gs->xmlStructuredError = xmlStructuredErrorThrDef;
+    gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
+    gs->xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
+    gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
+    gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
+
+	gs->xmlParserInputBufferCreateFilenameValue = xmlParserInputBufferCreateFilenameValueThrDef;
+	gs->xmlOutputBufferCreateFilenameValue = xmlOutputBufferCreateFilenameValueThrDef;
+    memset(&gs->xmlLastError, 0, sizeof(xmlError));
+
+    xmlMutexUnlock(xmlThrDefMutex);
+}
+
+/**
+ * DOC_DISABLE : we ignore missing doc for the xmlThrDef functions,
+ *               those are really internal work
+ */
+void
+xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xmlMutexLock(xmlThrDefMutex);
+    xmlGenericErrorContextThrDef = ctx;
+    if (handler != NULL)
+	xmlGenericErrorThrDef = handler;
+    else
+	xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
+    xmlMutexUnlock(xmlThrDefMutex);
+}
+
+void
+xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
+    xmlMutexLock(xmlThrDefMutex);
+    xmlStructuredErrorContextThrDef = ctx;
+    xmlStructuredErrorThrDef = handler;
+    xmlMutexUnlock(xmlThrDefMutex);
+}
+
+/**
+ * xmlRegisterNodeDefault:
+ * @func: function pointer to the new RegisterNodeFunc
+ *
+ * Registers a callback for node creation
+ *
+ * Returns the old value of the registration function
+ */
+xmlRegisterNodeFunc
+xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+    xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlRegisterNodeDefaultValue = func;
+    return(old);
+}
+
+xmlRegisterNodeFunc
+xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+    xmlRegisterNodeFunc old;
+    
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlRegisterNodeDefaultValueThrDef;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlRegisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
+/**
+ * xmlDeregisterNodeDefault:
+ * @func: function pointer to the new DeregisterNodeFunc
+ *
+ * Registers a callback for node destruction
+ *
+ * Returns the previous value of the deregistration function
+ */
+xmlDeregisterNodeFunc
+xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+    xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlDeregisterNodeDefaultValue = func;
+    return(old);
+}
+
+xmlDeregisterNodeFunc
+xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+    xmlDeregisterNodeFunc old;
+
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlDeregisterNodeDefaultValueThrDef;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlDeregisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
+xmlParserInputBufferCreateFilenameFunc
+xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func)
+{
+    xmlParserInputBufferCreateFilenameFunc old;
+    
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlParserInputBufferCreateFilenameValueThrDef;
+    if (old == NULL) {
+		old = __xmlParserInputBufferCreateFilename;
+	}
+
+    xmlParserInputBufferCreateFilenameValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
+xmlOutputBufferCreateFilenameFunc
+xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func)
+{
+    xmlOutputBufferCreateFilenameFunc old;
+    
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlOutputBufferCreateFilenameValueThrDef;
+#ifdef LIBXML_OUTPUT_ENABLED
+    if (old == NULL) {
+		old = __xmlOutputBufferCreateFilename;
+	}
+#endif
+    xmlOutputBufferCreateFilenameValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
+#ifdef LIBXML_DOCB_ENABLED
+#undef	docbDefaultSAXHandler
+xmlSAXHandlerV1 *
+__docbDefaultSAXHandler(void) {
+    if (IS_MAIN_THREAD)
+	return (&docbDefaultSAXHandler);
+    else
+	return (&xmlGetGlobalState()->docbDefaultSAXHandler);
+}
+#endif
+
+#ifdef LIBXML_HTML_ENABLED
+#undef	htmlDefaultSAXHandler
+xmlSAXHandlerV1 *
+__htmlDefaultSAXHandler(void) {
+    if (IS_MAIN_THREAD)
+	return (&htmlDefaultSAXHandler);
+    else
+	return (&xmlGetGlobalState()->htmlDefaultSAXHandler);
+}
+#endif
+
+#undef xmlLastError
+xmlError *
+__xmlLastError(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlLastError);
+    else
+	return (&xmlGetGlobalState()->xmlLastError);
+}
+
+/*
+ * The following memory routines were apparently lost at some point,
+ * and were re-inserted at this point on June 10, 2004.  Hope it's
+ * the right place for them :-)
+ */
+#if defined(LIBXML_THREAD_ALLOC_ENABLED) && defined(LIBXML_THREAD_ENABLED)
+#undef xmlMalloc
+xmlMallocFunc *
+__xmlMalloc(void){
+    if (IS_MAIN_THREAD)
+        return (&xmlMalloc);
+    else
+    	return (&xmlGetGlobalState()->xmlMalloc);
+}
+
+#undef xmlMallocAtomic
+xmlMallocFunc *
+__xmlMallocAtomic(void){
+    if (IS_MAIN_THREAD)
+        return (&xmlMallocAtomic);
+    else
+        return (&xmlGetGlobalState()->xmlMallocAtomic);
+}
+
+#undef xmlRealloc
+xmlReallocFunc *
+__xmlRealloc(void){
+    if (IS_MAIN_THREAD)
+        return (&xmlRealloc);
+    else
+        return (&xmlGetGlobalState()->xmlRealloc);
+}
+
+#undef xmlFree
+xmlFreeFunc *
+__xmlFree(void){
+    if (IS_MAIN_THREAD)
+        return (&xmlFree);
+    else
+        return (&xmlGetGlobalState()->xmlFree);
+}
+
+xmlStrdupFunc *
+__xmlMemStrdup(void){
+    if (IS_MAIN_THREAD)
+        return (&xmlMemStrdup);
+    else
+        return (&xmlGetGlobalState()->xmlMemStrdup);
+}
+
+#endif
+
+/*
+ * Everything starting from the line below is
+ * Automatically generated by build_glob.py.
+ * Do not modify the previous line.
+ */
+
+
+#undef	oldXMLWDcompatibility
+int *
+__oldXMLWDcompatibility(void) {
+    if (IS_MAIN_THREAD)
+	return (&oldXMLWDcompatibility);
+    else
+	return (&xmlGetGlobalState()->oldXMLWDcompatibility);
+}
+
+#undef	xmlBufferAllocScheme
+xmlBufferAllocationScheme *
+__xmlBufferAllocScheme(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlBufferAllocScheme);
+    else
+	return (&xmlGetGlobalState()->xmlBufferAllocScheme);
+}
+xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) {
+    xmlBufferAllocationScheme ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlBufferAllocSchemeThrDef;
+    xmlBufferAllocSchemeThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlDefaultBufferSize
+int *
+__xmlDefaultBufferSize(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlDefaultBufferSize);
+    else
+	return (&xmlGetGlobalState()->xmlDefaultBufferSize);
+}
+int xmlThrDefDefaultBufferSize(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlDefaultBufferSizeThrDef;
+    xmlDefaultBufferSizeThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+#undef	xmlDefaultSAXHandler
+xmlSAXHandlerV1 *
+__xmlDefaultSAXHandler(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlDefaultSAXHandler);
+    else
+	return (&xmlGetGlobalState()->xmlDefaultSAXHandler);
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+#undef	xmlDefaultSAXLocator
+xmlSAXLocator *
+__xmlDefaultSAXLocator(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlDefaultSAXLocator);
+    else
+	return (&xmlGetGlobalState()->xmlDefaultSAXLocator);
+}
+
+#undef	xmlDoValidityCheckingDefaultValue
+int *
+__xmlDoValidityCheckingDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlDoValidityCheckingDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlDoValidityCheckingDefaultValue);
+}
+int xmlThrDefDoValidityCheckingDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlDoValidityCheckingDefaultValueThrDef;
+    xmlDoValidityCheckingDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlGenericError
+xmlGenericErrorFunc *
+__xmlGenericError(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlGenericError);
+    else
+	return (&xmlGetGlobalState()->xmlGenericError);
+}
+
+#undef	xmlStructuredError
+xmlStructuredErrorFunc *
+__xmlStructuredError(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlStructuredError);
+    else
+	return (&xmlGetGlobalState()->xmlStructuredError);
+}
+
+#undef	xmlGenericErrorContext
+void * *
+__xmlGenericErrorContext(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlGenericErrorContext);
+    else
+	return (&xmlGetGlobalState()->xmlGenericErrorContext);
+}
+
+#undef	xmlStructuredErrorContext
+void * *
+__xmlStructuredErrorContext(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlStructuredErrorContext);
+    else
+	return (&xmlGetGlobalState()->xmlStructuredErrorContext);
+}
+
+#undef	xmlGetWarningsDefaultValue
+int *
+__xmlGetWarningsDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlGetWarningsDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlGetWarningsDefaultValue);
+}
+int xmlThrDefGetWarningsDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlGetWarningsDefaultValueThrDef;
+    xmlGetWarningsDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlIndentTreeOutput
+int *
+__xmlIndentTreeOutput(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlIndentTreeOutput);
+    else
+	return (&xmlGetGlobalState()->xmlIndentTreeOutput);
+}
+int xmlThrDefIndentTreeOutput(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlIndentTreeOutputThrDef;
+    xmlIndentTreeOutputThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlTreeIndentString
+const char * *
+__xmlTreeIndentString(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlTreeIndentString);
+    else
+	return (&xmlGetGlobalState()->xmlTreeIndentString);
+}
+const char * xmlThrDefTreeIndentString(const char * v) {
+    const char * ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlTreeIndentStringThrDef;
+    xmlTreeIndentStringThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlKeepBlanksDefaultValue
+int *
+__xmlKeepBlanksDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlKeepBlanksDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlKeepBlanksDefaultValue);
+}
+int xmlThrDefKeepBlanksDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlKeepBlanksDefaultValueThrDef;
+    xmlKeepBlanksDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlLineNumbersDefaultValue
+int *
+__xmlLineNumbersDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlLineNumbersDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlLineNumbersDefaultValue);
+}
+int xmlThrDefLineNumbersDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlLineNumbersDefaultValueThrDef;
+    xmlLineNumbersDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlLoadExtDtdDefaultValue
+int *
+__xmlLoadExtDtdDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlLoadExtDtdDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlLoadExtDtdDefaultValue);
+}
+int xmlThrDefLoadExtDtdDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlLoadExtDtdDefaultValueThrDef;
+    xmlLoadExtDtdDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlParserDebugEntities
+int *
+__xmlParserDebugEntities(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlParserDebugEntities);
+    else
+	return (&xmlGetGlobalState()->xmlParserDebugEntities);
+}
+int xmlThrDefParserDebugEntities(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlParserDebugEntitiesThrDef;
+    xmlParserDebugEntitiesThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlParserVersion
+const char * *
+__xmlParserVersion(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlParserVersion);
+    else
+	return (&xmlGetGlobalState()->xmlParserVersion);
+}
+
+#undef	xmlPedanticParserDefaultValue
+int *
+__xmlPedanticParserDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlPedanticParserDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlPedanticParserDefaultValue);
+}
+int xmlThrDefPedanticParserDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlPedanticParserDefaultValueThrDef;
+    xmlPedanticParserDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlSaveNoEmptyTags
+int *
+__xmlSaveNoEmptyTags(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlSaveNoEmptyTags);
+    else
+	return (&xmlGetGlobalState()->xmlSaveNoEmptyTags);
+}
+int xmlThrDefSaveNoEmptyTags(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlSaveNoEmptyTagsThrDef;
+    xmlSaveNoEmptyTagsThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlSubstituteEntitiesDefaultValue
+int *
+__xmlSubstituteEntitiesDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlSubstituteEntitiesDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
+}
+int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlSubstituteEntitiesDefaultValueThrDef;
+    xmlSubstituteEntitiesDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
+
+#undef	xmlRegisterNodeDefaultValue
+xmlRegisterNodeFunc *
+__xmlRegisterNodeDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlRegisterNodeDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlRegisterNodeDefaultValue);
+}
+
+#undef	xmlDeregisterNodeDefaultValue
+xmlDeregisterNodeFunc *
+__xmlDeregisterNodeDefaultValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlDeregisterNodeDefaultValue);
+    else
+	return (&xmlGetGlobalState()->xmlDeregisterNodeDefaultValue);
+}
+
+#undef	xmlParserInputBufferCreateFilenameValue
+xmlParserInputBufferCreateFilenameFunc *
+__xmlParserInputBufferCreateFilenameValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlParserInputBufferCreateFilenameValue);
+    else
+	return (&xmlGetGlobalState()->xmlParserInputBufferCreateFilenameValue);
+}
+
+#undef	xmlOutputBufferCreateFilenameValue
+xmlOutputBufferCreateFilenameFunc *
+__xmlOutputBufferCreateFilenameValue(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlOutputBufferCreateFilenameValue);
+    else
+	return (&xmlGetGlobalState()->xmlOutputBufferCreateFilenameValue);
+}
+
+#define bottom_globals
+#include "elfgcchack.h"
diff --git a/src/hash.c b/src/hash.c
new file mode 100644
index 0000000..b78bc2d
--- /dev/null
+++ b/src/hash.c
@@ -0,0 +1,1089 @@
+/*
+ * hash.c: chained hash tables
+ *
+ * Reference: Your favorite introductory book on algorithms
+ *
+ * Copyright (C) 2000 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ * Author: breese@users.sourceforge.net
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/hash.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+
+#define MAX_HASH_LEN 8
+
+/* #define DEBUG_GROW */
+
+/*
+ * A single entry in the hash table
+ */
+typedef struct _xmlHashEntry xmlHashEntry;
+typedef xmlHashEntry *xmlHashEntryPtr;
+struct _xmlHashEntry {
+    struct _xmlHashEntry *next;
+    xmlChar *name;
+    xmlChar *name2;
+    xmlChar *name3;
+    void *payload;
+    int valid;
+};
+
+/*
+ * The entire hash table
+ */
+struct _xmlHashTable {
+    struct _xmlHashEntry *table;
+    int size;
+    int nbElems;
+    xmlDictPtr dict;
+};
+
+/*
+ * xmlHashComputeKey:
+ * Calculate the hash key
+ */
+static unsigned long
+xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
+	          const xmlChar *name2, const xmlChar *name3) {
+    unsigned long value = 0L;
+    char ch;
+    
+    if (name != NULL) {
+	value += 30 * (*name);
+	while ((ch = *name++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    if (name2 != NULL) {
+	while ((ch = *name2++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    if (name3 != NULL) {
+	while ((ch = *name3++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    return (value % table->size);
+}
+
+static unsigned long
+xmlHashComputeQKey(xmlHashTablePtr table,
+		   const xmlChar *prefix, const xmlChar *name,
+		   const xmlChar *prefix2, const xmlChar *name2,
+		   const xmlChar *prefix3, const xmlChar *name3) {
+    unsigned long value = 0L;
+    char ch;
+    
+    if (prefix != NULL)
+	value += 30 * (*prefix);
+    else
+	value += 30 * (*name);
+
+    if (prefix != NULL) {
+	while ((ch = *prefix++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+	value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
+    }
+    if (name != NULL) {
+	while ((ch = *name++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    if (prefix2 != NULL) {
+	while ((ch = *prefix2++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+	value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
+    }
+    if (name2 != NULL) {
+	while ((ch = *name2++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    if (prefix3 != NULL) {
+	while ((ch = *prefix3++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+	value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
+    }
+    if (name3 != NULL) {
+	while ((ch = *name3++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
+	}
+    }
+    return (value % table->size);
+}
+
+/**
+ * xmlHashCreate:
+ * @size: the size of the hash table
+ *
+ * Create a new xmlHashTablePtr.
+ *
+ * Returns the newly created object, or NULL if an error occured.
+ */
+xmlHashTablePtr
+xmlHashCreate(int size) {
+    xmlHashTablePtr table;
+  
+    if (size <= 0)
+        size = 256;
+  
+    table = xmlMalloc(sizeof(xmlHashTable));
+    if (table) {
+        table->dict = NULL;
+        table->size = size;
+	table->nbElems = 0;
+        table->table = xmlMalloc(size * sizeof(xmlHashEntry));
+        if (table->table) {
+  	    memset(table->table, 0, size * sizeof(xmlHashEntry));
+  	    return(table);
+        }
+        xmlFree(table);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlHashCreateDict:
+ * @size: the size of the hash table
+ * @dict: a dictionary to use for the hash
+ *
+ * Create a new xmlHashTablePtr which will use @dict as the internal dictionary
+ *
+ * Returns the newly created object, or NULL if an error occured.
+ */
+xmlHashTablePtr
+xmlHashCreateDict(int size, xmlDictPtr dict) {
+    xmlHashTablePtr table;
+
+    table = xmlHashCreate(size);
+    if (table != NULL) {
+        table->dict = dict;
+	xmlDictReference(dict);
+    }
+    return(table);
+}
+
+/**
+ * xmlHashGrow:
+ * @table: the hash table
+ * @size: the new size of the hash table
+ *
+ * resize the hash table
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlHashGrow(xmlHashTablePtr table, int size) {
+    unsigned long key;
+    int oldsize, i;
+    xmlHashEntryPtr iter, next;
+    struct _xmlHashEntry *oldtable;
+#ifdef DEBUG_GROW
+    unsigned long nbElem = 0;
+#endif
+  
+    if (table == NULL)
+	return(-1);
+    if (size < 8)
+        return(-1);
+    if (size > 8 * 2048)
+	return(-1);
+
+    oldsize = table->size;
+    oldtable = table->table;
+    if (oldtable == NULL)
+        return(-1);
+  
+    table->table = xmlMalloc(size * sizeof(xmlHashEntry));
+    if (table->table == NULL) {
+	table->table = oldtable;
+	return(-1);
+    }
+    memset(table->table, 0, size * sizeof(xmlHashEntry));
+    table->size = size;
+
+    /*	If the two loops are merged, there would be situations where
+	a new entry needs to allocated and data copied into it from 
+	the main table. So instead, we run through the array twice, first
+	copying all the elements in the main array (where we can't get
+	conflicts) and then the rest, so we only free (and don't allocate)
+    */
+    for (i = 0; i < oldsize; i++) {
+	if (oldtable[i].valid == 0) 
+	    continue;
+	key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
+				oldtable[i].name3);
+	memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
+	table->table[key].next = NULL;
+    }
+
+    for (i = 0; i < oldsize; i++) {
+	iter = oldtable[i].next;
+	while (iter) {
+	    next = iter->next;
+
+	    /*
+	     * put back the entry in the new table
+	     */
+
+	    key = xmlHashComputeKey(table, iter->name, iter->name2,
+		                    iter->name3);
+	    if (table->table[key].valid == 0) {
+		memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
+		table->table[key].next = NULL;
+		xmlFree(iter);
+	    } else {
+	    	iter->next = table->table[key].next;
+	    	table->table[key].next = iter;
+	    }
+
+#ifdef DEBUG_GROW
+	    nbElem++;
+#endif
+
+	    iter = next;
+	}
+    }
+
+    xmlFree(oldtable);
+
+#ifdef DEBUG_GROW
+    xmlGenericError(xmlGenericErrorContext,
+	    "xmlHashGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
+#endif
+
+    return(0);
+}
+
+/**
+ * xmlHashFree:
+ * @table: the hash table
+ * @f:  the deallocator function for items in the hash
+ *
+ * Free the hash @table and its contents. The userdata is
+ * deallocated with @f if provided.
+ */
+void
+xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
+    int i;
+    xmlHashEntryPtr iter;
+    xmlHashEntryPtr next;
+    int inside_table = 0;
+    int nbElems;
+
+    if (table == NULL)
+	return;
+    if (table->table) {
+	nbElems = table->nbElems;
+	for(i = 0; (i < table->size) && (nbElems > 0); i++) {
+	    iter = &(table->table[i]);
+	    if (iter->valid == 0)
+		continue;
+	    inside_table = 1;
+	    while (iter) {
+		next = iter->next;
+		if ((f != NULL) && (iter->payload != NULL))
+		    f(iter->payload, iter->name);
+		if (table->dict == NULL) {
+		    if (iter->name)
+			xmlFree(iter->name);
+		    if (iter->name2)
+			xmlFree(iter->name2);
+		    if (iter->name3)
+			xmlFree(iter->name3);
+		}
+		iter->payload = NULL;
+		if (!inside_table)
+		    xmlFree(iter);
+		nbElems--;
+		inside_table = 0;
+		iter = next;
+	    }
+	}
+	xmlFree(table->table);
+    }
+    if (table->dict)
+        xmlDictFree(table->dict);
+    xmlFree(table);
+}
+
+/**
+ * xmlHashAddEntry:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the @name. Duplicate names generate errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
+    return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
+}
+
+/**
+ * xmlHashAddEntry2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the (@name, @name2) tuple. Duplicate tuples generate errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
+	        const xmlChar *name2, void *userdata) {
+    return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
+}
+
+/**
+ * xmlHashUpdateEntry:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @userdata: a pointer to the userdata
+ * @f: the deallocator function for replaced item (if any)
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the @name. Existing entry for this @name will be removed
+ * and freed with @f if found.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
+	           void *userdata, xmlHashDeallocator f) {
+    return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
+}
+
+/**
+ * xmlHashUpdateEntry2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @userdata: a pointer to the userdata
+ * @f: the deallocator function for replaced item (if any)
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the (@name, @name2) tuple. Existing entry for this tuple will
+ * be removed and freed with @f if found.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
+	           const xmlChar *name2, void *userdata,
+		   xmlHashDeallocator f) {
+    return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
+}
+
+/**
+ * xmlHashLookup:
+ * @table: the hash table
+ * @name: the name of the userdata
+ *
+ * Find the userdata specified by the @name.
+ *
+ * Returns the pointer to the userdata
+ */
+void *
+xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
+    return(xmlHashLookup3(table, name, NULL, NULL));
+}
+
+/**
+ * xmlHashLookup2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ *
+ * Find the userdata specified by the (@name, @name2) tuple.
+ *
+ * Returns the pointer to the userdata
+ */
+void *
+xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
+	      const xmlChar *name2) {
+    return(xmlHashLookup3(table, name, name2, NULL));
+}
+
+/**
+ * xmlHashQLookup:
+ * @table: the hash table
+ * @prefix: the prefix of the userdata
+ * @name: the name of the userdata
+ *
+ * Find the userdata specified by the QName @prefix:@name/@name.
+ *
+ * Returns the pointer to the userdata
+ */
+void *
+xmlHashQLookup(xmlHashTablePtr table, const xmlChar *prefix,
+               const xmlChar *name) {
+    return(xmlHashQLookup3(table, prefix, name, NULL, NULL, NULL, NULL));
+}
+
+/**
+ * xmlHashQLookup2:
+ * @table: the hash table
+ * @prefix: the prefix of the userdata
+ * @name: the name of the userdata
+ * @prefix2: the second prefix of the userdata
+ * @name2: a second name of the userdata
+ *
+ * Find the userdata specified by the QNames tuple
+ *
+ * Returns the pointer to the userdata
+ */
+void *
+xmlHashQLookup2(xmlHashTablePtr table, const xmlChar *prefix,
+                const xmlChar *name, const xmlChar *prefix2,
+	        const xmlChar *name2) {
+    return(xmlHashQLookup3(table, prefix, name, prefix2, name2, NULL, NULL));
+}
+
+/**
+ * xmlHashAddEntry3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the tuple (@name, @name2, @name3). Duplicate entries generate
+ * errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
+	         const xmlChar *name2, const xmlChar *name3,
+		 void *userdata) {
+    unsigned long key, len = 0;
+    xmlHashEntryPtr entry;
+    xmlHashEntryPtr insert;
+
+    if ((table == NULL) || (name == NULL))
+	return(-1);
+
+    /*
+     * If using a dict internalize if needed
+     */
+    if (table->dict) {
+        if (!xmlDictOwns(table->dict, name)) {
+	    name = xmlDictLookup(table->dict, name, -1);
+	    if (name == NULL)
+	        return(-1);
+	}
+        if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
+	    name2 = xmlDictLookup(table->dict, name2, -1);
+	    if (name2 == NULL)
+	        return(-1);
+	}
+        if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
+	    name3 = xmlDictLookup(table->dict, name3, -1);
+	    if (name3 == NULL)
+	        return(-1);
+	}
+    }
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    key = xmlHashComputeKey(table, name, name2, name3);
+    if (table->table[key].valid == 0) {
+	insert = NULL;
+    } else {
+        if (table->dict) {
+	    for (insert = &(table->table[key]); insert->next != NULL;
+		 insert = insert->next) {
+		if ((insert->name == name) &&
+		    (insert->name2 == name2) &&
+		    (insert->name3 == name3))
+		    return(-1);
+		len++;
+	    }
+	    if ((insert->name == name) &&
+		(insert->name2 == name2) &&
+		(insert->name3 == name3))
+		return(-1);
+	} else {
+	    for (insert = &(table->table[key]); insert->next != NULL;
+		 insert = insert->next) {
+		if ((xmlStrEqual(insert->name, name)) &&
+		    (xmlStrEqual(insert->name2, name2)) &&
+		    (xmlStrEqual(insert->name3, name3)))
+		    return(-1);
+		len++;
+	    }
+	    if ((xmlStrEqual(insert->name, name)) &&
+		(xmlStrEqual(insert->name2, name2)) &&
+		(xmlStrEqual(insert->name3, name3)))
+		return(-1);
+	}
+    }
+
+    if (insert == NULL) {
+	entry = &(table->table[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlHashEntry));
+	if (entry == NULL)
+	     return(-1);
+    }
+
+    if (table->dict != NULL) {
+        entry->name = (xmlChar *) name;
+        entry->name2 = (xmlChar *) name2;
+        entry->name3 = (xmlChar *) name3;
+    } else {
+	entry->name = xmlStrdup(name);
+	entry->name2 = xmlStrdup(name2);
+	entry->name3 = xmlStrdup(name3);
+    }
+    entry->payload = userdata;
+    entry->next = NULL;
+    entry->valid = 1;
+
+
+    if (insert != NULL) 
+	insert->next = entry;
+
+    table->nbElems++;
+
+    if (len > MAX_HASH_LEN)
+	xmlHashGrow(table, MAX_HASH_LEN * table->size);
+
+    return(0);
+}
+
+/**
+ * xmlHashUpdateEntry3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ * @userdata: a pointer to the userdata
+ * @f: the deallocator function for replaced item (if any)
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using the tuple (@name, @name2, @name3). Existing entry for this tuple
+ * will be removed and freed with @f if found.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
+	           const xmlChar *name2, const xmlChar *name3,
+		   void *userdata, xmlHashDeallocator f) {
+    unsigned long key;
+    xmlHashEntryPtr entry;
+    xmlHashEntryPtr insert;
+
+    if ((table == NULL) || name == NULL)
+	return(-1);
+
+    /*
+     * If using a dict internalize if needed
+     */
+    if (table->dict) {
+        if (!xmlDictOwns(table->dict, name)) {
+	    name = xmlDictLookup(table->dict, name, -1);
+	    if (name == NULL)
+	        return(-1);
+	}
+        if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
+	    name2 = xmlDictLookup(table->dict, name2, -1);
+	    if (name2 == NULL)
+	        return(-1);
+	}
+        if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
+	    name3 = xmlDictLookup(table->dict, name3, -1);
+	    if (name3 == NULL)
+	        return(-1);
+	}
+    }
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    key = xmlHashComputeKey(table, name, name2, name3);
+    if (table->table[key].valid == 0) {
+	insert = NULL;
+    } else {
+        if (table ->dict) {
+	    for (insert = &(table->table[key]); insert->next != NULL;
+		 insert = insert->next) {
+		if ((insert->name == name) &&
+		    (insert->name2 == name2) &&
+		    (insert->name3 == name3)) {
+		    if (f)
+			f(insert->payload, insert->name);
+		    insert->payload = userdata;
+		    return(0);
+		}
+	    }
+	    if ((insert->name == name) &&
+		(insert->name2 == name2) &&
+		(insert->name3 == name3)) {
+		if (f)
+		    f(insert->payload, insert->name);
+		insert->payload = userdata;
+		return(0);
+	    }
+	} else {
+	    for (insert = &(table->table[key]); insert->next != NULL;
+		 insert = insert->next) {
+		if ((xmlStrEqual(insert->name, name)) &&
+		    (xmlStrEqual(insert->name2, name2)) &&
+		    (xmlStrEqual(insert->name3, name3))) {
+		    if (f)
+			f(insert->payload, insert->name);
+		    insert->payload = userdata;
+		    return(0);
+		}
+	    }
+	    if ((xmlStrEqual(insert->name, name)) &&
+		(xmlStrEqual(insert->name2, name2)) &&
+		(xmlStrEqual(insert->name3, name3))) {
+		if (f)
+		    f(insert->payload, insert->name);
+		insert->payload = userdata;
+		return(0);
+	    }
+	}
+    }
+
+    if (insert == NULL) {
+	entry =  &(table->table[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlHashEntry));
+	if (entry == NULL)
+	     return(-1);
+    }
+
+    if (table->dict != NULL) {
+        entry->name = (xmlChar *) name;
+        entry->name2 = (xmlChar *) name2;
+        entry->name3 = (xmlChar *) name3;
+    } else {
+	entry->name = xmlStrdup(name);
+	entry->name2 = xmlStrdup(name2);
+	entry->name3 = xmlStrdup(name3);
+    }
+    entry->payload = userdata;
+    entry->next = NULL;
+    entry->valid = 1;
+    table->nbElems++;
+
+
+    if (insert != NULL) {
+	insert->next = entry;
+    }
+    return(0);
+}
+
+/**
+ * xmlHashLookup3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ *
+ * Find the userdata specified by the (@name, @name2, @name3) tuple.
+ *
+ * Returns the a pointer to the userdata
+ */
+void *
+xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, 
+	       const xmlChar *name2, const xmlChar *name3) {
+    unsigned long key;
+    xmlHashEntryPtr entry;
+
+    if (table == NULL)
+	return(NULL);
+    if (name == NULL)
+	return(NULL);
+    key = xmlHashComputeKey(table, name, name2, name3);
+    if (table->table[key].valid == 0)
+	return(NULL);
+    if (table->dict) {
+	for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
+	    if ((entry->name == name) &&
+		(entry->name2 == name2) &&
+		(entry->name3 == name3))
+		return(entry->payload);
+	}
+    }
+    for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
+	if ((xmlStrEqual(entry->name, name)) &&
+	    (xmlStrEqual(entry->name2, name2)) &&
+	    (xmlStrEqual(entry->name3, name3)))
+	    return(entry->payload);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlHashQLookup3:
+ * @table: the hash table
+ * @prefix: the prefix of the userdata
+ * @name: the name of the userdata
+ * @prefix2: the second prefix of the userdata
+ * @name2: a second name of the userdata
+ * @prefix3: the third prefix of the userdata
+ * @name3: a third name of the userdata
+ *
+ * Find the userdata specified by the (@name, @name2, @name3) tuple.
+ *
+ * Returns the a pointer to the userdata
+ */
+void *
+xmlHashQLookup3(xmlHashTablePtr table,
+                const xmlChar *prefix, const xmlChar *name,
+		const xmlChar *prefix2, const xmlChar *name2,
+		const xmlChar *prefix3, const xmlChar *name3) {
+    unsigned long key;
+    xmlHashEntryPtr entry;
+
+    if (table == NULL)
+	return(NULL);
+    if (name == NULL)
+	return(NULL);
+    key = xmlHashComputeQKey(table, prefix, name, prefix2,
+                             name2, prefix3, name3);
+    if (table->table[key].valid == 0)
+	return(NULL);
+    for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
+	if ((xmlStrQEqual(prefix, name, entry->name)) &&
+	    (xmlStrQEqual(prefix2, name2, entry->name2)) &&
+	    (xmlStrQEqual(prefix3, name3, entry->name3)))
+	    return(entry->payload);
+    }
+    return(NULL);
+}
+
+typedef struct {
+    xmlHashScanner hashscanner;
+    void *data;
+} stubData;
+
+static void 
+stubHashScannerFull (void *payload, void *data, const xmlChar *name, 
+                     const xmlChar *name2 ATTRIBUTE_UNUSED,
+		     const xmlChar *name3 ATTRIBUTE_UNUSED) {
+    stubData *stubdata = (stubData *) data;
+    stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);
+}                                  
+ 
+/**
+ * xmlHashScan:
+ * @table: the hash table
+ * @f:  the scanner function for items in the hash
+ * @data:  extra data passed to f
+ *
+ * Scan the hash @table and applied @f to each value.
+ */
+void
+xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
+    stubData stubdata;
+    stubdata.data = data;
+    stubdata.hashscanner = f; 
+    xmlHashScanFull (table, stubHashScannerFull, &stubdata);
+}
+
+/**
+ * xmlHashScanFull:
+ * @table: the hash table
+ * @f:  the scanner function for items in the hash
+ * @data:  extra data passed to f
+ *
+ * Scan the hash @table and applied @f to each value.
+ */
+void
+xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
+    int i, nb;
+    xmlHashEntryPtr iter;
+    xmlHashEntryPtr next;
+
+    if (table == NULL)
+	return;
+    if (f == NULL)
+	return;
+
+    if (table->table) {
+	for(i = 0; i < table->size; i++) {
+	    if (table->table[i].valid == 0) 
+		continue;
+	    iter = &(table->table[i]);
+	    while (iter) {
+		next = iter->next;
+                nb = table->nbElems;
+		if ((f != NULL) && (iter->payload != NULL))
+		    f(iter->payload, data, iter->name,
+		      iter->name2, iter->name3);
+                if (nb != table->nbElems) {
+                    /* table was modified by the callback, be careful */
+                    if (iter == &(table->table[i])) {
+                        if (table->table[i].valid == 0)
+                            iter = NULL;
+                        if (table->table[i].next != next)
+			    iter = &(table->table[i]);
+                    } else
+		        iter = next;
+                } else
+		    iter = next;
+	    }
+	}
+    }
+}
+
+/**
+ * xmlHashScan3:
+ * @table: the hash table
+ * @name: the name of the userdata or NULL
+ * @name2: a second name of the userdata or NULL
+ * @name3: a third name of the userdata or NULL
+ * @f:  the scanner function for items in the hash
+ * @data:  extra data passed to f
+ *
+ * Scan the hash @table and applied @f to each value matching
+ * (@name, @name2, @name3) tuple. If one of the names is null,
+ * the comparison is considered to match.
+ */
+void
+xmlHashScan3(xmlHashTablePtr table, const xmlChar *name, 
+	     const xmlChar *name2, const xmlChar *name3,
+	     xmlHashScanner f, void *data) {
+    xmlHashScanFull3 (table, name, name2, name3,
+		      (xmlHashScannerFull) f, data);
+}
+
+/**
+ * xmlHashScanFull3:
+ * @table: the hash table
+ * @name: the name of the userdata or NULL
+ * @name2: a second name of the userdata or NULL
+ * @name3: a third name of the userdata or NULL
+ * @f:  the scanner function for items in the hash
+ * @data:  extra data passed to f
+ *
+ * Scan the hash @table and applied @f to each value matching
+ * (@name, @name2, @name3) tuple. If one of the names is null,
+ * the comparison is considered to match.
+ */
+void
+xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name, 
+		 const xmlChar *name2, const xmlChar *name3,
+		 xmlHashScannerFull f, void *data) {
+    int i;
+    xmlHashEntryPtr iter;
+    xmlHashEntryPtr next;
+
+    if (table == NULL)
+	return;
+    if (f == NULL)
+	return;
+
+    if (table->table) {
+	for(i = 0; i < table->size; i++) {
+	    if (table->table[i].valid == 0)
+		continue;
+	    iter = &(table->table[i]);
+	    while (iter) {
+		next = iter->next;
+		if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
+		    ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
+		    ((name3 == NULL) || (xmlStrEqual(name3, iter->name3))) &&
+		    (iter->payload != NULL)) {
+		    f(iter->payload, data, iter->name,
+		      iter->name2, iter->name3);
+		}
+		iter = next;
+	    }
+	}
+    }
+}
+
+/**
+ * xmlHashCopy:
+ * @table: the hash table
+ * @f:  the copier function for items in the hash
+ *
+ * Scan the hash @table and applied @f to each value.
+ *
+ * Returns the new table or NULL in case of error.
+ */
+xmlHashTablePtr
+xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
+    int i;
+    xmlHashEntryPtr iter;
+    xmlHashEntryPtr next;
+    xmlHashTablePtr ret;
+
+    if (table == NULL)
+	return(NULL);
+    if (f == NULL)
+	return(NULL);
+
+    ret = xmlHashCreate(table->size);
+    if (table->table) {
+	for(i = 0; i < table->size; i++) {
+	    if (table->table[i].valid == 0)
+		continue;
+	    iter = &(table->table[i]);
+	    while (iter) {
+		next = iter->next;
+		xmlHashAddEntry3(ret, iter->name, iter->name2,
+			         iter->name3, f(iter->payload, iter->name));
+		iter = next;
+	    }
+	}
+    }
+    ret->nbElems = table->nbElems;
+    return(ret);
+}
+
+/**
+ * xmlHashSize:
+ * @table: the hash table
+ *
+ * Query the number of elements installed in the hash @table.
+ *
+ * Returns the number of elements in the hash table or
+ * -1 in case of error
+ */
+int
+xmlHashSize(xmlHashTablePtr table) {
+    if (table == NULL)
+	return(-1);
+    return(table->nbElems);
+}
+
+/**
+ * xmlHashRemoveEntry:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @f: the deallocator function for removed item (if any)
+ *
+ * Find the userdata specified by the @name and remove
+ * it from the hash @table. Existing userdata for this tuple will be removed
+ * and freed with @f.
+ *
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ */
+int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
+		       xmlHashDeallocator f) {
+    return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
+}
+
+/**
+ * xmlHashRemoveEntry2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @f: the deallocator function for removed item (if any)
+ *
+ * Find the userdata specified by the (@name, @name2) tuple and remove
+ * it from the hash @table. Existing userdata for this tuple will be removed
+ * and freed with @f.
+ *
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ */
+int
+xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
+			const xmlChar *name2, xmlHashDeallocator f) {
+    return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
+}
+
+/**
+ * xmlHashRemoveEntry3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ * @f: the deallocator function for removed item (if any)
+ *
+ * Find the userdata specified by the (@name, @name2, @name3) tuple and remove
+ * it from the hash @table. Existing userdata for this tuple will be removed
+ * and freed with @f.
+ *
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ */
+int
+xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
+    const xmlChar *name2, const xmlChar *name3, xmlHashDeallocator f) {
+    unsigned long key;
+    xmlHashEntryPtr entry;
+    xmlHashEntryPtr prev = NULL;
+
+    if (table == NULL || name == NULL)
+        return(-1);
+
+    key = xmlHashComputeKey(table, name, name2, name3);
+    if (table->table[key].valid == 0) {
+        return(-1);
+    } else {
+        for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
+            if (xmlStrEqual(entry->name, name) &&
+                    xmlStrEqual(entry->name2, name2) &&
+                    xmlStrEqual(entry->name3, name3)) {
+                if ((f != NULL) && (entry->payload != NULL))
+                    f(entry->payload, entry->name);
+                entry->payload = NULL;
+		if (table->dict == NULL) {
+		    if(entry->name)
+			xmlFree(entry->name);
+		    if(entry->name2)
+			xmlFree(entry->name2);
+		    if(entry->name3)
+			xmlFree(entry->name3);
+		}
+                if(prev) {
+                    prev->next = entry->next;
+		    xmlFree(entry);
+		} else {
+		    if (entry->next == NULL) {
+			entry->valid = 0;
+		    } else {
+			entry = entry->next;
+			memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
+			xmlFree(entry);
+		    }
+		}
+                table->nbElems--;
+                return(0);
+            }
+            prev = entry;
+        }
+        return(-1);
+    }
+}
+
+#define bottom_hash
+#include "elfgcchack.h"
diff --git a/src/include/libxml/DOCBparser.h b/src/include/libxml/DOCBparser.h
new file mode 100644
index 0000000..461d4ee
--- /dev/null
+++ b/src/include/libxml/DOCBparser.h
@@ -0,0 +1,96 @@
+/*
+ * Summary: old DocBook SGML parser
+ * Description: interface for a DocBook SGML non-verifying parser
+ * This code is DEPRECATED, and should not be used anymore.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __DOCB_PARSER_H__
+#define __DOCB_PARSER_H__
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_DOCB_ENABLED
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+
+#ifndef IN_LIBXML
+#ifdef __GNUC__
+#warning "The DOCBparser module has been deprecated in libxml2-2.6.0"
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Most of the back-end structures from XML and SGML are shared.
+ */
+typedef xmlParserCtxt docbParserCtxt;
+typedef xmlParserCtxtPtr docbParserCtxtPtr;
+typedef xmlSAXHandler docbSAXHandler;
+typedef xmlSAXHandlerPtr docbSAXHandlerPtr;
+typedef xmlParserInput docbParserInput;
+typedef xmlParserInputPtr docbParserInputPtr;
+typedef xmlDocPtr docbDocPtr;
+
+/*
+ * There is only few public functions.
+ */
+XMLPUBFUN int XMLCALL
+		     docbEncodeEntities(unsigned char *out,
+                                        int *outlen,
+                                        const unsigned char *in,
+                                        int *inlen, int quoteChar);
+
+XMLPUBFUN docbDocPtr XMLCALL             
+		     docbSAXParseDoc   (xmlChar *cur,
+                                        const char *encoding,
+                                        docbSAXHandlerPtr sax,
+                                        void *userData);
+XMLPUBFUN docbDocPtr XMLCALL             
+		     docbParseDoc      (xmlChar *cur,
+                                        const char *encoding);
+XMLPUBFUN docbDocPtr XMLCALL             
+		     docbSAXParseFile  (const char *filename,
+                                        const char *encoding,
+                                        docbSAXHandlerPtr sax,
+                                        void *userData);
+XMLPUBFUN docbDocPtr XMLCALL             
+		     docbParseFile     (const char *filename,
+                                        const char *encoding);
+
+/**
+ * Interfaces for the Push mode.
+ */
+XMLPUBFUN void XMLCALL                  
+		     docbFreeParserCtxt      (docbParserCtxtPtr ctxt);
+XMLPUBFUN docbParserCtxtPtr XMLCALL     
+		     docbCreatePushParserCtxt(docbSAXHandlerPtr sax,
+                                              void *user_data,
+                                              const char *chunk,
+                                              int size,
+                                              const char *filename,
+                                              xmlCharEncoding enc);
+XMLPUBFUN int XMLCALL                   
+		     docbParseChunk          (docbParserCtxtPtr ctxt,
+                                              const char *chunk,
+                                              int size,
+                                              int terminate);
+XMLPUBFUN docbParserCtxtPtr XMLCALL       
+		     docbCreateFileParserCtxt(const char *filename,
+                                              const char *encoding);
+XMLPUBFUN int XMLCALL                   
+		     docbParseDocument       (docbParserCtxtPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_DOCB_ENABLED */
+
+#endif /* __DOCB_PARSER_H__ */
diff --git a/src/include/libxml/HTMLparser.h b/src/include/libxml/HTMLparser.h
new file mode 100644
index 0000000..cde0ac6
--- /dev/null
+++ b/src/include/libxml/HTMLparser.h
@@ -0,0 +1,304 @@
+/*
+ * Summary: interface for an HTML 4.0 non-verifying parser
+ * Description: this module implements an HTML 4.0 non-verifying parser
+ *              with API compatible with the XML parser ones. It should
+ *              be able to parse "real world" HTML, even if severely
+ *              broken from a specification point of view.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __HTML_PARSER_H__
+#define __HTML_PARSER_H__
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+
+#ifdef LIBXML_HTML_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Most of the back-end structures from XML and HTML are shared.
+ */
+typedef xmlParserCtxt htmlParserCtxt;
+typedef xmlParserCtxtPtr htmlParserCtxtPtr;
+typedef xmlParserNodeInfo htmlParserNodeInfo;
+typedef xmlSAXHandler htmlSAXHandler;
+typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
+typedef xmlParserInput htmlParserInput;
+typedef xmlParserInputPtr htmlParserInputPtr;
+typedef xmlDocPtr htmlDocPtr;
+typedef xmlNodePtr htmlNodePtr;
+
+/*
+ * Internal description of an HTML element, representing HTML 4.01
+ * and XHTML 1.0 (which share the same structure).
+ */
+typedef struct _htmlElemDesc htmlElemDesc;
+typedef htmlElemDesc *htmlElemDescPtr;
+struct _htmlElemDesc {
+    const char *name;	/* The tag name */
+    char startTag;      /* Whether the start tag can be implied */
+    char endTag;        /* Whether the end tag can be implied */
+    char saveEndTag;    /* Whether the end tag should be saved */
+    char empty;         /* Is this an empty element ? */
+    char depr;          /* Is this a deprecated element ? */
+    char dtd;           /* 1: only in Loose DTD, 2: only Frameset one */
+    char isinline;      /* is this a block 0 or inline 1 element */
+    const char *desc;   /* the description */
+
+/* NRK Jan.2003
+ * New fields encapsulating HTML structure
+ *
+ * Bugs:
+ *	This is a very limited representation.  It fails to tell us when
+ *	an element *requires* subelements (we only have whether they're
+ *	allowed or not), and it doesn't tell us where CDATA and PCDATA
+ *	are allowed.  Some element relationships are not fully represented:
+ *	these are flagged with the word MODIFIER
+ */
+    const char** subelts;		/* allowed sub-elements of this element */
+    const char* defaultsubelt;	/* subelement for suggested auto-repair
+					   if necessary or NULL */
+    const char** attrs_opt;		/* Optional Attributes */
+    const char** attrs_depr;		/* Additional deprecated attributes */
+    const char** attrs_req;		/* Required attributes */
+};
+
+/*
+ * Internal description of an HTML entity.
+ */
+typedef struct _htmlEntityDesc htmlEntityDesc;
+typedef htmlEntityDesc *htmlEntityDescPtr;
+struct _htmlEntityDesc {
+    unsigned int value;	/* the UNICODE value for the character */
+    const char *name;	/* The entity name */
+    const char *desc;   /* the description */
+};
+
+/*
+ * There is only few public functions.
+ */
+XMLPUBFUN const htmlElemDesc * XMLCALL 	
+			htmlTagLookup	(const xmlChar *tag);
+XMLPUBFUN const htmlEntityDesc * XMLCALL 	
+			htmlEntityLookup(const xmlChar *name);
+XMLPUBFUN const htmlEntityDesc * XMLCALL 	
+			htmlEntityValueLookup(unsigned int value);
+
+XMLPUBFUN int XMLCALL			
+			htmlIsAutoClosed(htmlDocPtr doc,
+					 htmlNodePtr elem);
+XMLPUBFUN int XMLCALL			
+			htmlAutoCloseTag(htmlDocPtr doc,
+					 const xmlChar *name,
+					 htmlNodePtr elem);
+XMLPUBFUN const htmlEntityDesc * XMLCALL	
+			htmlParseEntityRef(htmlParserCtxtPtr ctxt,
+					 const xmlChar **str);
+XMLPUBFUN int XMLCALL			
+			htmlParseCharRef(htmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			htmlParseElement(htmlParserCtxtPtr ctxt);
+
+XMLPUBFUN htmlParserCtxtPtr XMLCALL	
+			htmlNewParserCtxt(void);
+
+XMLPUBFUN htmlParserCtxtPtr XMLCALL	
+			htmlCreateMemoryParserCtxt(const char *buffer,
+						   int size);
+
+XMLPUBFUN int XMLCALL			
+			htmlParseDocument(htmlParserCtxtPtr ctxt);
+XMLPUBFUN htmlDocPtr XMLCALL		
+			htmlSAXParseDoc	(xmlChar *cur,
+					 const char *encoding,
+					 htmlSAXHandlerPtr sax,
+					 void *userData);
+XMLPUBFUN htmlDocPtr XMLCALL		
+			htmlParseDoc	(xmlChar *cur,
+					 const char *encoding);
+XMLPUBFUN htmlDocPtr XMLCALL		
+			htmlSAXParseFile(const char *filename,
+					 const char *encoding,
+					 htmlSAXHandlerPtr sax,
+					 void *userData);
+XMLPUBFUN htmlDocPtr XMLCALL		
+			htmlParseFile	(const char *filename,
+					 const char *encoding);
+XMLPUBFUN int XMLCALL			
+			UTF8ToHtml	(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+XMLPUBFUN int XMLCALL			
+			htmlEncodeEntities(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen, int quoteChar);
+XMLPUBFUN int XMLCALL			
+			htmlIsScriptAttribute(const xmlChar *name);
+XMLPUBFUN int XMLCALL			
+			htmlHandleOmittedElem(int val);
+
+#ifdef LIBXML_PUSH_ENABLED
+/**
+ * Interfaces for the Push mode.
+ */
+XMLPUBFUN htmlParserCtxtPtr XMLCALL	
+			htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,
+						 void *user_data,
+						 const char *chunk,
+						 int size,
+						 const char *filename,
+						 xmlCharEncoding enc);
+XMLPUBFUN int XMLCALL			
+			htmlParseChunk		(htmlParserCtxtPtr ctxt,
+						 const char *chunk,
+						 int size,
+						 int terminate);
+#endif /* LIBXML_PUSH_ENABLED */
+
+XMLPUBFUN void XMLCALL			
+			htmlFreeParserCtxt	(htmlParserCtxtPtr ctxt);
+
+/*
+ * New set of simpler/more flexible APIs
+ */
+/**
+ * xmlParserOption:
+ *
+ * This is the set of XML parser options that can be passed down
+ * to the xmlReadDoc() and similar calls.
+ */
+typedef enum {
+    HTML_PARSE_RECOVER  = 1<<0, /* Relaxed parsing */
+    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_NOIMPLIED= 1<<13,/* Do not add implied html/body... elements */
+    HTML_PARSE_COMPACT  = 1<<16 /* compact small text nodes */
+} htmlParserOption;
+
+XMLPUBFUN void XMLCALL
+		htmlCtxtReset		(htmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		htmlCtxtUseOptions	(htmlParserCtxtPtr ctxt,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlReadDoc		(const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlReadFile		(const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlReadMemory		(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlReadFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlReadIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlCtxtReadDoc		(xmlParserCtxtPtr ctxt,
+					 const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlCtxtReadFile		(xmlParserCtxtPtr ctxt,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlCtxtReadMemory		(xmlParserCtxtPtr ctxt,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlCtxtReadFd		(xmlParserCtxtPtr ctxt,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlCtxtReadIO		(xmlParserCtxtPtr ctxt,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+/* NRK/Jan2003: further knowledge of HTML structure
+ */
+typedef enum {
+  HTML_NA = 0 ,		/* something we don't check at all */
+  HTML_INVALID = 0x1 ,
+  HTML_DEPRECATED = 0x2 ,
+  HTML_VALID = 0x4 ,
+  HTML_REQUIRED = 0xc /* VALID bit set so ( & HTML_VALID ) is TRUE */
+} htmlStatus ;
+
+/* Using htmlElemDesc rather than name here, to emphasise the fact
+   that otherwise there's a lookup overhead
+*/
+XMLPUBFUN htmlStatus XMLCALL htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ;
+XMLPUBFUN int XMLCALL htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ;
+XMLPUBFUN htmlStatus XMLCALL htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ;
+XMLPUBFUN htmlStatus XMLCALL htmlNodeStatus(const htmlNodePtr, int) ;
+/**
+ * htmlDefaultSubelement:
+ * @elt: HTML element
+ *
+ * Returns the default subelement for this element
+ */
+#define htmlDefaultSubelement(elt) elt->defaultsubelt
+/**
+ * htmlElementAllowedHereDesc:
+ * @parent: HTML parent element
+ * @elt: HTML element
+ *
+ * Checks whether an HTML element description may be a
+ * direct child of the specified element.
+ *
+ * Returns 1 if allowed; 0 otherwise.
+ */
+#define htmlElementAllowedHereDesc(parent,elt) \
+	htmlElementAllowedHere((parent), (elt)->name)
+/**
+ * htmlRequiredAttrs:
+ * @elt: HTML element
+ *
+ * Returns the attributes required for the specified element.
+ */
+#define htmlRequiredAttrs(elt) (elt)->attrs_req
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTML_ENABLED */
+#endif /* __HTML_PARSER_H__ */
diff --git a/src/include/libxml/HTMLtree.h b/src/include/libxml/HTMLtree.h
new file mode 100644
index 0000000..6ea8207
--- /dev/null
+++ b/src/include/libxml/HTMLtree.h
@@ -0,0 +1,147 @@
+/*
+ * Summary: specific APIs to process HTML tree, especially serialization
+ * Description: this module implements a few function needed to process
+ *              tree in an HTML specific way.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __HTML_TREE_H__
+#define __HTML_TREE_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/HTMLparser.h>
+
+#ifdef LIBXML_HTML_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * HTML_TEXT_NODE:
+ *
+ * Macro. A text node in a HTML document is really implemented
+ * the same way as a text node in an XML document.
+ */
+#define HTML_TEXT_NODE		XML_TEXT_NODE
+/**
+ * HTML_ENTITY_REF_NODE:
+ *
+ * Macro. An entity reference in a HTML document is really implemented
+ * the same way as an entity reference in an XML document.
+ */
+#define HTML_ENTITY_REF_NODE	XML_ENTITY_REF_NODE
+/**
+ * HTML_COMMENT_NODE:
+ *
+ * Macro. A comment in a HTML document is really implemented
+ * the same way as a comment in an XML document.
+ */
+#define HTML_COMMENT_NODE	XML_COMMENT_NODE
+/**
+ * HTML_PRESERVE_NODE:
+ *
+ * Macro. A preserved node in a HTML document is really implemented
+ * the same way as a CDATA section in an XML document.
+ */
+#define HTML_PRESERVE_NODE	XML_CDATA_SECTION_NODE
+/**
+ * HTML_PI_NODE:
+ *
+ * Macro. A processing instruction in a HTML document is really implemented
+ * the same way as a processing instruction in an XML document.
+ */
+#define HTML_PI_NODE		XML_PI_NODE
+
+XMLPUBFUN htmlDocPtr XMLCALL
+		htmlNewDoc		(const xmlChar *URI,
+					 const xmlChar *ExternalID);
+XMLPUBFUN htmlDocPtr XMLCALL	
+		htmlNewDocNoDtD		(const xmlChar *URI,
+					 const xmlChar *ExternalID);
+XMLPUBFUN const xmlChar * XMLCALL	
+		htmlGetMetaEncoding	(htmlDocPtr doc);
+XMLPUBFUN int XMLCALL		
+		htmlSetMetaEncoding	(htmlDocPtr doc,
+					 const xmlChar *encoding);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL	    
+		htmlDocDumpMemory	(xmlDocPtr cur,
+					 xmlChar **mem,
+					 int *size);
+XMLPUBFUN void XMLCALL	    
+		htmlDocDumpMemoryFormat	(xmlDocPtr cur,
+					 xmlChar **mem,
+					 int *size,
+					 int format);
+XMLPUBFUN int XMLCALL		
+		htmlDocDump		(FILE *f,
+					 xmlDocPtr cur);
+XMLPUBFUN int XMLCALL		
+		htmlSaveFile		(const char *filename,
+					 xmlDocPtr cur);
+XMLPUBFUN int XMLCALL		
+		htmlNodeDump		(xmlBufferPtr buf,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur);
+XMLPUBFUN void XMLCALL		
+		htmlNodeDumpFile	(FILE *out,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur);
+XMLPUBFUN int XMLCALL		
+		htmlNodeDumpFileFormat	(FILE *out,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur,
+					 const char *encoding,
+					 int format);
+XMLPUBFUN int XMLCALL		
+		htmlSaveFileEnc		(const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding);
+XMLPUBFUN int XMLCALL		
+		htmlSaveFileFormat	(const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding,
+					 int format);
+
+XMLPUBFUN void XMLCALL		
+		htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur,
+					 const char *encoding,
+					 int format);
+XMLPUBFUN void XMLCALL		
+		htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
+XMLPUBFUN void XMLCALL		
+		htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf,
+					 xmlDocPtr cur,
+					 const char *encoding,
+					 int format);
+XMLPUBFUN void XMLCALL 
+		htmlNodeDumpOutput	(xmlOutputBufferPtr buf, 
+					 xmlDocPtr doc,
+					 xmlNodePtr cur, 
+					 const char *encoding);
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+XMLPUBFUN int XMLCALL		
+		htmlIsBooleanAttr	(const xmlChar *name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTML_ENABLED */
+
+#endif /* __HTML_TREE_H__ */
+
diff --git a/src/include/libxml/SAX.h b/src/include/libxml/SAX.h
new file mode 100644
index 0000000..0ca161b
--- /dev/null
+++ b/src/include/libxml/SAX.h
@@ -0,0 +1,173 @@
+/*
+ * Summary: Old SAX version 1 handler, deprecated
+ * Description: DEPRECATED set of SAX version 1 interfaces used to
+ *              build the DOM tree.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SAX_H__
+#define __XML_SAX_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/xlink.h>
+
+#ifdef LIBXML_LEGACY_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XMLPUBFUN const xmlChar * XMLCALL
+		getPublicId			(void *ctx);
+XMLPUBFUN const xmlChar * XMLCALL	
+		getSystemId			(void *ctx);
+XMLPUBFUN void XMLCALL		
+		setDocumentLocator		(void *ctx,
+						 xmlSAXLocatorPtr loc);
+    
+XMLPUBFUN int XMLCALL		
+		getLineNumber			(void *ctx);
+XMLPUBFUN int XMLCALL		
+		getColumnNumber			(void *ctx);
+
+XMLPUBFUN int XMLCALL		
+		isStandalone			(void *ctx);
+XMLPUBFUN int XMLCALL		
+		hasInternalSubset		(void *ctx);
+XMLPUBFUN int XMLCALL		
+		hasExternalSubset		(void *ctx);
+
+XMLPUBFUN void XMLCALL		
+		internalSubset			(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID);
+XMLPUBFUN void XMLCALL		
+		externalSubset			(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID);
+XMLPUBFUN xmlEntityPtr XMLCALL	
+		getEntity			(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntityPtr XMLCALL	
+		getParameterEntity		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlParserInputPtr XMLCALL 
+		resolveEntity			(void *ctx,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+
+XMLPUBFUN void XMLCALL		
+		entityDecl			(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 xmlChar *content);
+XMLPUBFUN void XMLCALL		
+		attributeDecl			(void *ctx,
+						 const xmlChar *elem,
+						 const xmlChar *fullname,
+						 int type,
+						 int def,
+						 const xmlChar *defaultValue,
+						 xmlEnumerationPtr tree);
+XMLPUBFUN void XMLCALL		
+		elementDecl			(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 xmlElementContentPtr content);
+XMLPUBFUN void XMLCALL		
+		notationDecl			(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+XMLPUBFUN void XMLCALL		
+		unparsedEntityDecl		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *notationName);
+
+XMLPUBFUN void XMLCALL		
+		startDocument			(void *ctx);
+XMLPUBFUN void XMLCALL		
+		endDocument			(void *ctx);
+XMLPUBFUN void XMLCALL		
+		attribute			(void *ctx,
+						 const xmlChar *fullname,
+						 const xmlChar *value);
+XMLPUBFUN void XMLCALL		
+		startElement			(void *ctx,
+						 const xmlChar *fullname,
+						 const xmlChar **atts);
+XMLPUBFUN void XMLCALL		
+		endElement			(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN void XMLCALL		
+		reference			(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN void XMLCALL		
+		characters			(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void XMLCALL		
+		ignorableWhitespace		(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void XMLCALL		
+		processingInstruction		(void *ctx,
+						 const xmlChar *target,
+						 const xmlChar *data);
+XMLPUBFUN void XMLCALL		
+		globalNamespace			(void *ctx,
+						 const xmlChar *href,
+						 const xmlChar *prefix);
+XMLPUBFUN void XMLCALL		
+		setNamespace			(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlNsPtr XMLCALL	
+		getNamespace			(void *ctx);
+XMLPUBFUN int XMLCALL		
+		checkNamespace			(void *ctx,
+						 xmlChar *nameSpace);
+XMLPUBFUN void XMLCALL		
+		namespaceDecl			(void *ctx,
+						 const xmlChar *href,
+						 const xmlChar *prefix);
+XMLPUBFUN void XMLCALL		
+		comment				(void *ctx,
+						 const xmlChar *value);
+XMLPUBFUN void XMLCALL		
+		cdataBlock			(void *ctx,
+						 const xmlChar *value,
+						 int len);
+
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN void XMLCALL		
+		initxmlDefaultSAXHandler	(xmlSAXHandlerV1 *hdlr,
+						 int warning);
+#ifdef LIBXML_HTML_ENABLED
+XMLPUBFUN void XMLCALL		
+		inithtmlDefaultSAXHandler	(xmlSAXHandlerV1 *hdlr);
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+XMLPUBFUN void XMLCALL		
+		initdocbDefaultSAXHandler	(xmlSAXHandlerV1 *hdlr);
+#endif
+#endif /* LIBXML_SAX1_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_LEGACY_ENABLED */
+
+#endif /* __XML_SAX_H__ */
diff --git a/src/include/libxml/SAX2.h b/src/include/libxml/SAX2.h
new file mode 100644
index 0000000..8d2db02
--- /dev/null
+++ b/src/include/libxml/SAX2.h
@@ -0,0 +1,176 @@
+/*
+ * Summary: SAX2 parser interface used to build the DOM tree
+ * Description: those are the default SAX2 interfaces used by
+ *              the library when building DOM tree.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SAX2_H__
+#define __XML_SAX2_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/xlink.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XMLPUBFUN const xmlChar * XMLCALL
+		xmlSAX2GetPublicId		(void *ctx);
+XMLPUBFUN const xmlChar * XMLCALL	
+		xmlSAX2GetSystemId		(void *ctx);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2SetDocumentLocator	(void *ctx,
+						 xmlSAXLocatorPtr loc);
+    
+XMLPUBFUN int XMLCALL		
+		xmlSAX2GetLineNumber		(void *ctx);
+XMLPUBFUN int XMLCALL		
+		xmlSAX2GetColumnNumber		(void *ctx);
+
+XMLPUBFUN int XMLCALL		
+		xmlSAX2IsStandalone		(void *ctx);
+XMLPUBFUN int XMLCALL		
+		xmlSAX2HasInternalSubset	(void *ctx);
+XMLPUBFUN int XMLCALL		
+		xmlSAX2HasExternalSubset	(void *ctx);
+
+XMLPUBFUN void XMLCALL		
+		xmlSAX2InternalSubset		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2ExternalSubset		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID);
+XMLPUBFUN xmlEntityPtr XMLCALL	
+		xmlSAX2GetEntity		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntityPtr XMLCALL	
+		xmlSAX2GetParameterEntity	(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlParserInputPtr XMLCALL 
+		xmlSAX2ResolveEntity		(void *ctx,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+
+XMLPUBFUN void XMLCALL		
+		xmlSAX2EntityDecl		(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 xmlChar *content);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2AttributeDecl		(void *ctx,
+						 const xmlChar *elem,
+						 const xmlChar *fullname,
+						 int type,
+						 int def,
+						 const xmlChar *defaultValue,
+						 xmlEnumerationPtr tree);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2ElementDecl		(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 xmlElementContentPtr content);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2NotationDecl		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2UnparsedEntityDecl	(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *notationName);
+
+XMLPUBFUN void XMLCALL		
+		xmlSAX2StartDocument		(void *ctx);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2EndDocument		(void *ctx);
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+XMLPUBFUN void XMLCALL		
+		xmlSAX2StartElement		(void *ctx,
+						 const xmlChar *fullname,
+						 const xmlChar **atts);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2EndElement		(void *ctx,
+						 const xmlChar *name);
+#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED */
+XMLPUBFUN void XMLCALL
+		xmlSAX2StartElementNs		(void *ctx,
+						 const xmlChar *localname,
+						 const xmlChar *prefix,
+						 const xmlChar *URI,
+						 int nb_namespaces,
+						 const xmlChar **namespaces,
+						 int nb_attributes,
+						 int nb_defaulted,
+						 const xmlChar **attributes);
+XMLPUBFUN void XMLCALL
+		xmlSAX2EndElementNs		(void *ctx,
+						 const xmlChar *localname,
+						 const xmlChar *prefix,
+						 const xmlChar *URI);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2Reference		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2Characters		(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2IgnorableWhitespace	(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2ProcessingInstruction	(void *ctx,
+						 const xmlChar *target,
+						 const xmlChar *data);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2Comment			(void *ctx,
+						 const xmlChar *value);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2CDataBlock		(void *ctx,
+						 const xmlChar *value,
+						 int len);
+
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int XMLCALL
+		xmlSAXDefaultVersion		(int version);
+#endif /* LIBXML_SAX1_ENABLED */
+
+XMLPUBFUN int XMLCALL
+		xmlSAXVersion			(xmlSAXHandler *hdlr,
+						 int version);
+XMLPUBFUN void XMLCALL		
+		xmlSAX2InitDefaultSAXHandler    (xmlSAXHandler *hdlr,
+						 int warning);
+#ifdef LIBXML_HTML_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr);
+XMLPUBFUN void XMLCALL		
+		htmlDefaultSAXHandlerInit	(void);
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr);
+XMLPUBFUN void XMLCALL		
+		docbDefaultSAXHandlerInit	(void);
+#endif
+XMLPUBFUN void XMLCALL		
+		xmlDefaultSAXHandlerInit	(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_SAX2_H__ */
diff --git a/src/include/libxml/c14n.h b/src/include/libxml/c14n.h
new file mode 100644
index 0000000..3011af7
--- /dev/null
+++ b/src/include/libxml/c14n.h
@@ -0,0 +1,126 @@
+/*
+ * Summary: Provide Canonical XML and Exclusive XML Canonicalization
+ * Description: the c14n modules provides a
+ *
+ * "Canonical XML" implementation
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * and an
+ *
+ * "Exclusive XML Canonicalization" implementation
+ * http://www.w3.org/TR/xml-exc-c14n
+
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef __XML_C14N_H__
+#define __XML_C14N_H__
+#ifdef LIBXML_C14N_ENABLED
+#ifdef LIBXML_OUTPUT_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+/*
+ * XML Canonicazation
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * Exclusive XML Canonicazation
+ * http://www.w3.org/TR/xml-exc-c14n
+ *
+ * Canonical form of an XML document could be created if and only if
+ *  a) default attributes (if any) are added to all nodes
+ *  b) all character and parsed entity references are resolved
+ * In order to achive this in libxml2 the document MUST be loaded with
+ * following global setings:
+ *
+ *    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ *    xmlSubstituteEntitiesDefault(1);
+ *
+ * or corresponding parser context setting:
+ *    xmlParserCtxtPtr ctxt;
+ *
+ *    ...
+ *    ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ *    ctxt->replaceEntities = 1;
+ *    ...
+ */
+
+/*
+ * 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 mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlOutputBufferPtr buf);
+
+XMLPUBFUN int XMLCALL
+		xmlC14NDocDumpMemory	(xmlDocPtr doc,
+					 xmlNodeSetPtr nodes,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlChar **doc_txt_ptr);
+
+XMLPUBFUN int XMLCALL
+		xmlC14NDocSave		(xmlDocPtr doc,
+					 xmlNodeSetPtr nodes,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 const char* filename,
+					 int compression);
+
+
+/**
+ * This is the core C14N function
+ */
+/**
+ * xmlC14NIsVisibleCallback:
+ * @user_data: user data
+ * @node: the curent node
+ * @parent: the parent node
+ *
+ * Signature for a C14N callback on visible nodes
+ *
+ * Returns 1 if the node should be included
+ */
+typedef int (*xmlC14NIsVisibleCallback)	(void* user_data,
+					 xmlNodePtr node,
+					 xmlNodePtr parent);
+
+XMLPUBFUN int XMLCALL
+		xmlC14NExecute		(xmlDocPtr doc,
+					 xmlC14NIsVisibleCallback is_visible_callback,
+					 void* user_data,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlOutputBufferPtr buf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+#endif /* LIBXML_C14N_ENABLED */
+#endif /* __XML_C14N_H__ */
+
diff --git a/src/include/libxml/catalog.h b/src/include/libxml/catalog.h
new file mode 100644
index 0000000..b444137
--- /dev/null
+++ b/src/include/libxml/catalog.h
@@ -0,0 +1,182 @@
+/**
+ * Summary: interfaces to the Catalog handling system
+ * Description: the catalog module implements the support for
+ * XML Catalogs and SGML catalogs
+ *
+ * SGML Open Technical Resolution TR9401:1997.
+ * http://www.jclark.com/sp/catalog.htm
+ *
+ * XML Catalogs Working Draft 06 August 2001
+ * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_CATALOG_H__
+#define __XML_CATALOG_H__
+
+#include <stdio.h>
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_CATALOG_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XML_CATALOGS_NAMESPACE:
+ *
+ * The namespace for the XML Catalogs elements.
+ */
+#define XML_CATALOGS_NAMESPACE					\
+    (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
+/**
+ * XML_CATALOG_PI:
+ *
+ * The specific XML Catalog Processing Instuction name.
+ */
+#define XML_CATALOG_PI						\
+    (const xmlChar *) "oasis-xml-catalog"
+
+/*
+ * The API is voluntarily limited to general cataloging.
+ */
+typedef enum {
+    XML_CATA_PREFER_NONE = 0,
+    XML_CATA_PREFER_PUBLIC = 1,
+    XML_CATA_PREFER_SYSTEM
+} xmlCatalogPrefer;
+
+typedef enum {
+    XML_CATA_ALLOW_NONE = 0,
+    XML_CATA_ALLOW_GLOBAL = 1,
+    XML_CATA_ALLOW_DOCUMENT = 2,
+    XML_CATA_ALLOW_ALL = 3
+} xmlCatalogAllow;
+
+typedef struct _xmlCatalog xmlCatalog;
+typedef xmlCatalog *xmlCatalogPtr;
+
+/*
+ * Operations on a given catalog.
+ */
+XMLPUBFUN xmlCatalogPtr XMLCALL
+		xmlNewCatalog		(int sgml);
+XMLPUBFUN xmlCatalogPtr XMLCALL	
+		xmlLoadACatalog		(const char *filename);
+XMLPUBFUN xmlCatalogPtr XMLCALL	
+		xmlLoadSGMLSuperCatalog	(const char *filename);
+XMLPUBFUN int XMLCALL		
+		xmlConvertSGMLCatalog	(xmlCatalogPtr catal);
+XMLPUBFUN int XMLCALL		
+		xmlACatalogAdd		(xmlCatalogPtr catal,
+					 const xmlChar *type,
+					 const xmlChar *orig,
+					 const xmlChar *replace);
+XMLPUBFUN int XMLCALL		
+		xmlACatalogRemove	(xmlCatalogPtr catal,
+					 const xmlChar *value);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlACatalogResolve	(xmlCatalogPtr catal,
+					 const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlACatalogResolveSystem(xmlCatalogPtr catal,
+					 const xmlChar *sysID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlACatalogResolvePublic(xmlCatalogPtr catal,
+					 const xmlChar *pubID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlACatalogResolveURI	(xmlCatalogPtr catal,
+					 const xmlChar *URI);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlACatalogDump		(xmlCatalogPtr catal,
+					 FILE *out);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN void XMLCALL		
+		xmlFreeCatalog		(xmlCatalogPtr catal);
+XMLPUBFUN int XMLCALL		
+		xmlCatalogIsEmpty	(xmlCatalogPtr catal);
+
+/*
+ * Global operations.
+ */
+XMLPUBFUN void XMLCALL		
+		xmlInitializeCatalog	(void);
+XMLPUBFUN int XMLCALL		
+		xmlLoadCatalog		(const char *filename);
+XMLPUBFUN void XMLCALL		
+		xmlLoadCatalogs		(const char *paths);
+XMLPUBFUN void XMLCALL		
+		xmlCatalogCleanup	(void);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlCatalogDump		(FILE *out);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogResolve	(const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogResolveSystem	(const xmlChar *sysID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogResolvePublic	(const xmlChar *pubID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogResolveURI	(const xmlChar *URI);
+XMLPUBFUN int XMLCALL		
+		xmlCatalogAdd		(const xmlChar *type,
+					 const xmlChar *orig,
+					 const xmlChar *replace);
+XMLPUBFUN int XMLCALL		
+		xmlCatalogRemove	(const xmlChar *value);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlParseCatalogFile	(const char *filename);
+XMLPUBFUN int XMLCALL		
+		xmlCatalogConvert	(void);
+
+/*
+ * Strictly minimal interfaces for per-document catalogs used
+ * by the parser.
+ */
+XMLPUBFUN void XMLCALL		
+		xmlCatalogFreeLocal	(void *catalogs);
+XMLPUBFUN void * XMLCALL		
+		xmlCatalogAddLocal	(void *catalogs,
+					 const xmlChar *URL);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogLocalResolve	(void *catalogs,
+					 const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlCatalogLocalResolveURI(void *catalogs,
+					 const xmlChar *URI);
+/*
+ * Preference settings.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlCatalogSetDebug	(int level);
+XMLPUBFUN xmlCatalogPrefer XMLCALL 
+		xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
+XMLPUBFUN void XMLCALL		
+		xmlCatalogSetDefaults	(xmlCatalogAllow allow);
+XMLPUBFUN xmlCatalogAllow XMLCALL	
+		xmlCatalogGetDefaults	(void);
+
+
+/* DEPRECATED interfaces */
+XMLPUBFUN const xmlChar * XMLCALL	
+		xmlCatalogGetSystem	(const xmlChar *sysID);
+XMLPUBFUN const xmlChar * XMLCALL	
+		xmlCatalogGetPublic	(const xmlChar *pubID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LIBXML_CATALOG_ENABLED */
+#endif /* __XML_CATALOG_H__ */
diff --git a/src/include/libxml/chvalid.h b/src/include/libxml/chvalid.h
new file mode 100644
index 0000000..fb43016
--- /dev/null
+++ b/src/include/libxml/chvalid.h
@@ -0,0 +1,230 @@
+/*
+ * Summary: Unicode character range checking
+ * Description: this module exports interfaces for the character
+ *               range validation APIs
+ *
+ * This file is automatically generated from the cvs source
+ * definition files using the genChRanges.py Python script
+ *
+ * Generation date: Mon Mar 27 11:09:48 2006
+ * Sources: chvalid.def
+ * Author: William Brack <wbrack@mmm.com.hk>
+ */
+
+#ifndef __XML_CHVALID_H__
+#define __XML_CHVALID_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Define our typedefs and structures
+ *
+ */
+typedef struct _xmlChSRange xmlChSRange;
+typedef xmlChSRange *xmlChSRangePtr;
+struct _xmlChSRange {
+    unsigned short	low;
+    unsigned short	high;
+};
+
+typedef struct _xmlChLRange xmlChLRange;
+typedef xmlChLRange *xmlChLRangePtr;
+struct _xmlChLRange {
+    unsigned int	low;
+    unsigned int	high;
+};
+
+typedef struct _xmlChRangeGroup xmlChRangeGroup;
+typedef xmlChRangeGroup *xmlChRangeGroupPtr;
+struct _xmlChRangeGroup {
+    int			nbShortRange;
+    int			nbLongRange;
+    const xmlChSRange	*shortRange;	/* points to an array of ranges */
+    const xmlChLRange	*longRange;
+};
+
+/**
+ * Range checking routine
+ */
+XMLPUBFUN int XMLCALL
+		xmlCharInRange(unsigned int val, const xmlChRangeGroup *group);
+
+
+/**
+ * xmlIsBaseChar_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsBaseChar_ch(c)	(((0x41 <= (c)) && ((c) <= 0x5a)) || \
+				 ((0x61 <= (c)) && ((c) <= 0x7a)) || \
+				 ((0xc0 <= (c)) && ((c) <= 0xd6)) || \
+				 ((0xd8 <= (c)) && ((c) <= 0xf6)) || \
+				  (0xf8 <= (c)))
+
+/**
+ * xmlIsBaseCharQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsBaseCharQ(c)	(((c) < 0x100) ? \
+				 xmlIsBaseChar_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsBaseCharGroup))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsBaseCharGroup;
+
+/**
+ * xmlIsBlank_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsBlank_ch(c)	(((c) == 0x20) || \
+				 ((0x9 <= (c)) && ((c) <= 0xa)) || \
+				 ((c) == 0xd))
+
+/**
+ * xmlIsBlankQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsBlankQ(c)		(((c) < 0x100) ? \
+				 xmlIsBlank_ch((c)) : 0)
+
+
+/**
+ * xmlIsChar_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsChar_ch(c)		(((0x9 <= (c)) && ((c) <= 0xa)) || \
+				 ((c) == 0xd) || \
+				  (0x20 <= (c)))
+
+/**
+ * xmlIsCharQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsCharQ(c)		(((c) < 0x100) ? \
+				 xmlIsChar_ch((c)) :\
+				(((0x100 <= (c)) && ((c) <= 0xd7ff)) || \
+				 ((0xe000 <= (c)) && ((c) <= 0xfffd)) || \
+				 ((0x10000 <= (c)) && ((c) <= 0x10ffff))))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsCharGroup;
+
+/**
+ * xmlIsCombiningQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsCombiningQ(c)	(((c) < 0x100) ? \
+				 0 : \
+				 xmlCharInRange((c), &xmlIsCombiningGroup))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsCombiningGroup;
+
+/**
+ * xmlIsDigit_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsDigit_ch(c)	(((0x30 <= (c)) && ((c) <= 0x39)))
+
+/**
+ * xmlIsDigitQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsDigitQ(c)		(((c) < 0x100) ? \
+				 xmlIsDigit_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsDigitGroup))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsDigitGroup;
+
+/**
+ * xmlIsExtender_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsExtender_ch(c)	(((c) == 0xb7))
+
+/**
+ * xmlIsExtenderQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsExtenderQ(c)	(((c) < 0x100) ? \
+				 xmlIsExtender_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsExtenderGroup))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsExtenderGroup;
+
+/**
+ * xmlIsIdeographicQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsIdeographicQ(c)	(((c) < 0x100) ? \
+				 0 :\
+				(((0x4e00 <= (c)) && ((c) <= 0x9fa5)) || \
+				 ((c) == 0x3007) || \
+				 ((0x3021 <= (c)) && ((c) <= 0x3029))))
+
+XMLPUBVAR const xmlChRangeGroup xmlIsIdeographicGroup;
+XMLPUBVAR const unsigned char xmlIsPubidChar_tab[256];
+
+/**
+ * xmlIsPubidChar_ch:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsPubidChar_ch(c)	(xmlIsPubidChar_tab[(c)])
+
+/**
+ * xmlIsPubidCharQ:
+ * @c: char to validate
+ *
+ * Automatically generated by genChRanges.py
+ */
+#define xmlIsPubidCharQ(c)	(((c) < 0x100) ? \
+				 xmlIsPubidChar_ch((c)) : 0)
+
+XMLPUBFUN int XMLCALL
+		xmlIsBaseChar(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsBlank(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsChar(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsCombining(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsDigit(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsExtender(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsIdeographic(unsigned int ch);
+XMLPUBFUN int XMLCALL
+		xmlIsPubidChar(unsigned int ch);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_CHVALID_H__ */
diff --git a/src/include/libxml/debugXML.h b/src/include/libxml/debugXML.h
new file mode 100644
index 0000000..5a9d20b
--- /dev/null
+++ b/src/include/libxml/debugXML.h
@@ -0,0 +1,217 @@
+/*
+ * Summary: Tree debugging APIs
+ * Description: Interfaces to a set of routines used for debugging the tree
+ *              produced by the XML parser.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __DEBUG_XML__
+#define __DEBUG_XML__
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_DEBUG_ENABLED
+
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The standard Dump routines.
+ */
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpString	(FILE *output,
+				 const xmlChar *str);
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpAttr	(FILE *output,
+				 xmlAttrPtr attr,
+				 int depth);
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpAttrList	(FILE *output,
+				 xmlAttrPtr attr,
+				 int depth);
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpOneNode	(FILE *output,
+				 xmlNodePtr node,
+				 int depth);
+XMLPUBFUN void XMLCALL
+	xmlDebugDumpNode	(FILE *output,
+				 xmlNodePtr node,
+				 int depth);
+XMLPUBFUN void XMLCALL
+	xmlDebugDumpNodeList	(FILE *output,
+				 xmlNodePtr node,
+				 int depth);
+XMLPUBFUN void XMLCALL
+	xmlDebugDumpDocumentHead(FILE *output,
+				 xmlDocPtr doc);
+XMLPUBFUN void XMLCALL
+	xmlDebugDumpDocument	(FILE *output,
+				 xmlDocPtr doc);
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpDTD		(FILE *output,
+				 xmlDtdPtr dtd);
+XMLPUBFUN void XMLCALL	
+	xmlDebugDumpEntities	(FILE *output,
+				 xmlDocPtr doc);
+
+/****************************************************************
+ *								*
+ *	 		Checking routines			*
+ *								*
+ ****************************************************************/
+
+XMLPUBFUN int XMLCALL
+	xmlDebugCheckDocument	(FILE * output,
+				 xmlDocPtr doc);
+
+/****************************************************************
+ *								*
+ *	 		XML shell helpers			*
+ *								*
+ ****************************************************************/
+
+XMLPUBFUN void XMLCALL	
+	xmlLsOneNode		(FILE *output, xmlNodePtr node);
+XMLPUBFUN int XMLCALL	
+	xmlLsCountNode		(xmlNodePtr node);
+
+XMLPUBFUN const char * XMLCALL 
+	xmlBoolToText		(int boolval);
+
+/****************************************************************
+ *								*
+ *	 The XML shell related structures and functions		*
+ *								*
+ ****************************************************************/
+
+#ifdef LIBXML_XPATH_ENABLED
+/**
+ * xmlShellReadlineFunc:
+ * @prompt:  a string prompt
+ *
+ * This is a generic signature for the XML shell input function.
+ *
+ * Returns a string which will be freed by the Shell.
+ */
+typedef char * (* xmlShellReadlineFunc)(char *prompt);
+
+/**
+ * xmlShellCtxt:
+ *
+ * A debugging shell context.
+ * TODO: add the defined function tables.
+ */
+typedef struct _xmlShellCtxt xmlShellCtxt;
+typedef xmlShellCtxt *xmlShellCtxtPtr;
+struct _xmlShellCtxt {
+    char *filename;
+    xmlDocPtr doc;
+    xmlNodePtr node;
+    xmlXPathContextPtr pctxt;
+    int loaded;
+    FILE *output;
+    xmlShellReadlineFunc input;
+};
+
+/**
+ * xmlShellCmd:
+ * @ctxt:  a shell context
+ * @arg:  a string argument
+ * @node:  a first node
+ * @node2:  a second node
+ *
+ * This is a generic signature for the XML shell functions.
+ *
+ * Returns an int, negative returns indicating errors.
+ */
+typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt,
+                             char *arg,
+			     xmlNodePtr node,
+			     xmlNodePtr node2);
+
+XMLPUBFUN void XMLCALL	
+	xmlShellPrintXPathError	(int errorType,
+				 const char *arg);
+XMLPUBFUN void XMLCALL	
+	xmlShellPrintXPathResult(xmlXPathObjectPtr list);
+XMLPUBFUN int XMLCALL	
+	xmlShellList		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellBase		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellDir		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellLoad		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL	
+	xmlShellPrintNode	(xmlNodePtr node);
+XMLPUBFUN int XMLCALL	
+	xmlShellCat		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellWrite		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellSave		(xmlShellCtxtPtr ctxt,
+				 char *filename,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_VALID_ENABLED
+XMLPUBFUN int XMLCALL	
+	xmlShellValidate	(xmlShellCtxtPtr ctxt,
+				 char *dtd,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+#endif /* LIBXML_VALID_ENABLED */
+XMLPUBFUN int XMLCALL	
+	xmlShellDu		(xmlShellCtxtPtr ctxt,
+				 char *arg,
+				 xmlNodePtr tree,
+				 xmlNodePtr node2);
+XMLPUBFUN int XMLCALL	
+	xmlShellPwd		(xmlShellCtxtPtr ctxt,
+				 char *buffer,
+				 xmlNodePtr node,
+				 xmlNodePtr node2);
+
+/*
+ * The Shell interface.
+ */
+XMLPUBFUN void XMLCALL	
+	xmlShell		(xmlDocPtr doc,
+				 char *filename,
+				 xmlShellReadlineFunc input,
+				 FILE *output);
+			 
+#endif /* LIBXML_XPATH_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_DEBUG_ENABLED */
+#endif /* __DEBUG_XML__ */
diff --git a/src/include/libxml/dict.h b/src/include/libxml/dict.h
new file mode 100644
index 0000000..abb8339
--- /dev/null
+++ b/src/include/libxml/dict.h
@@ -0,0 +1,69 @@
+/*
+ * Summary: string dictionnary
+ * Description: dictionary of reusable strings, just used to avoid allocation
+ *         and freeing operations.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_DICT_H__
+#define __XML_DICT_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The dictionnary.
+ */
+typedef struct _xmlDict xmlDict;
+typedef xmlDict *xmlDictPtr;
+
+/*
+ * Constructor and destructor.
+ */
+XMLPUBFUN xmlDictPtr XMLCALL
+			xmlDictCreate	(void);
+XMLPUBFUN xmlDictPtr XMLCALL
+			xmlDictCreateSub(xmlDictPtr sub);
+XMLPUBFUN int XMLCALL
+			xmlDictReference(xmlDictPtr dict);
+XMLPUBFUN void XMLCALL			
+			xmlDictFree	(xmlDictPtr dict);
+
+/*
+ * Lookup of entry in the dictionnary.
+ */
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlDictLookup	(xmlDictPtr dict,
+		                         const xmlChar *name,
+		                         int len);
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlDictExists	(xmlDictPtr dict,
+		                         const xmlChar *name,
+		                         int len);
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlDictQLookup	(xmlDictPtr dict,
+		                         const xmlChar *prefix,
+		                         const xmlChar *name);
+XMLPUBFUN int XMLCALL
+			xmlDictOwns	(xmlDictPtr dict,
+					 const xmlChar *str);
+XMLPUBFUN int XMLCALL			
+			xmlDictSize	(xmlDictPtr dict);
+
+/*
+ * Cleanup function
+ */
+XMLPUBFUN void XMLCALL
+                        xmlDictCleanup  (void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_DICT_H__ */
diff --git a/src/include/libxml/encoding.h b/src/include/libxml/encoding.h
new file mode 100644
index 0000000..b5f8b48
--- /dev/null
+++ b/src/include/libxml/encoding.h
@@ -0,0 +1,255 @@
+/*
+ * Summary: interface for the encoding conversion functions
+ * Description: interface for the encoding conversion functions needed for
+ *              XML basic encoding and iconv() support.
+ *
+ * Related specs are
+ * rfc2044        (UTF-8 and UTF-16) F. Yergeau Alis Technologies
+ * [ISO-10646]    UTF-8 and UTF-16 in Annexes
+ * [ISO-8859-1]   ISO Latin-1 characters codes.
+ * [UNICODE]      The Unicode Consortium, "The Unicode Standard --
+ *                Worldwide Character Encoding -- Version 1.0", Addison-
+ *                Wesley, Volume 1, 1991, Volume 2, 1992.  UTF-8 is
+ *                described in Unicode Technical Report #4.
+ * [US-ASCII]     Coded Character Set--7-bit American Standard Code for
+ *                Information Interchange, ANSI X3.4-1986.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_CHAR_ENCODING_H__
+#define __XML_CHAR_ENCODING_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_ICONV_ENABLED
+#include <iconv.h>
+#else 
+#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" {
+#endif
+
+/*
+ * xmlCharEncoding:
+ *
+ * Predefined values for some standard encodings.
+ * Libxml does not do beforehand translation on UTF8 and ISOLatinX.
+ * It also supports ASCII, ISO-8859-1, and UTF16 (LE and BE) by default.
+ *
+ * Anything else would have to be translated to UTF8 before being
+ * given to the parser itself. The BOM for UTF16 and the encoding
+ * declaration are looked at and a converter is looked for at that
+ * point. If not found the parser stops here as asked by the XML REC. A
+ * converter can be registered by the user using xmlRegisterCharEncodingHandler
+ * but the current form doesn't allow stateful transcoding (a serious
+ * problem agreed !). If iconv has been found it will be used
+ * automatically and allow stateful transcoding, the simplest is then
+ * to be sure to enable iconv and to provide iconv libs for the encoding
+ * support needed.
+ *
+ * Note that the generic "UTF-16" is not a predefined value.  Instead, only
+ * the specific UTF-16LE and UTF-16BE are present.
+ */
+typedef enum {
+    XML_CHAR_ENCODING_ERROR=   -1, /* No char encoding detected */
+    XML_CHAR_ENCODING_NONE=	0, /* No char encoding detected */
+    XML_CHAR_ENCODING_UTF8=	1, /* UTF-8 */
+    XML_CHAR_ENCODING_UTF16LE=	2, /* UTF-16 little endian */
+    XML_CHAR_ENCODING_UTF16BE=	3, /* UTF-16 big endian */
+    XML_CHAR_ENCODING_UCS4LE=	4, /* UCS-4 little endian */
+    XML_CHAR_ENCODING_UCS4BE=	5, /* UCS-4 big endian */
+    XML_CHAR_ENCODING_EBCDIC=	6, /* EBCDIC uh! */
+    XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */
+    XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */
+    XML_CHAR_ENCODING_UCS2=	9, /* UCS-2 */
+    XML_CHAR_ENCODING_8859_1=	10,/* ISO-8859-1 ISO Latin 1 */
+    XML_CHAR_ENCODING_8859_2=	11,/* ISO-8859-2 ISO Latin 2 */
+    XML_CHAR_ENCODING_8859_3=	12,/* ISO-8859-3 */
+    XML_CHAR_ENCODING_8859_4=	13,/* ISO-8859-4 */
+    XML_CHAR_ENCODING_8859_5=	14,/* ISO-8859-5 */
+    XML_CHAR_ENCODING_8859_6=	15,/* ISO-8859-6 */
+    XML_CHAR_ENCODING_8859_7=	16,/* ISO-8859-7 */
+    XML_CHAR_ENCODING_8859_8=	17,/* ISO-8859-8 */
+    XML_CHAR_ENCODING_8859_9=	18,/* ISO-8859-9 */
+    XML_CHAR_ENCODING_2022_JP=  19,/* ISO-2022-JP */
+    XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */
+    XML_CHAR_ENCODING_EUC_JP=   21,/* EUC-JP */
+    XML_CHAR_ENCODING_ASCII=    22 /* pure ASCII */
+} xmlCharEncoding;
+
+/**
+ * xmlCharEncodingInputFunc:
+ * @out:  a pointer to an array of bytes to store the UTF-8 result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of chars in the original encoding
+ * @inlen:  the length of @in
+ *
+ * Take a block of chars in the original encoding and try to convert
+ * it to an UTF-8 block of chars out.
+ *
+ * Returns the number of bytes written, -1 if lack of space, or -2
+ *     if the transcoding failed.
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictiable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+typedef int (* xmlCharEncodingInputFunc)(unsigned char *out, int *outlen,
+                                         const unsigned char *in, int *inlen);
+
+
+/**
+ * xmlCharEncodingOutputFunc:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of UTF-8 chars
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to another
+ * encoding.
+ * Note: a first call designed to produce heading info is called with
+ * in = NULL. If stateful this should also initialize the encoder state.
+ *
+ * Returns the number of bytes written, -1 if lack of space, or -2
+ *     if the transcoding failed.
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictiable.
+ * The value of @outlen after return is the number of octets produced.
+ */
+typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
+                                          const unsigned char *in, int *inlen);
+
+
+/*
+ * Block defining the handlers for non UTF-8 encodings.
+ * If iconv is supported, there are two extra fields.
+ */
+#ifdef LIBXML_ICU_ENABLED
+struct _uconv_t {
+  UConverter *uconv; /* for conversion between an encoding and UTF-16 */
+  UConverter *utf8; /* for conversion between UTF-8 and UTF-16 */
+};
+typedef struct _uconv_t uconv_t;
+#endif
+
+typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
+typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
+struct _xmlCharEncodingHandler {
+    char                       *name;
+    xmlCharEncodingInputFunc   input;
+    xmlCharEncodingOutputFunc  output;
+#ifdef LIBXML_ICONV_ENABLED
+    iconv_t                    iconv_in;
+    iconv_t                    iconv_out;
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    uconv_t                    *uconv_in;
+    uconv_t                    *uconv_out;
+#endif /* LIBXML_ICU_ENABLED */
+};
+
+#ifdef __cplusplus
+}
+#endif
+#include <libxml/tree.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Interfaces for encoding handlers.
+ */
+XMLPUBFUN void XMLCALL	
+	xmlInitCharEncodingHandlers	(void);
+XMLPUBFUN void XMLCALL	
+	xmlCleanupCharEncodingHandlers	(void);
+XMLPUBFUN void XMLCALL	
+	xmlRegisterCharEncodingHandler	(xmlCharEncodingHandlerPtr handler);
+XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL
+	xmlGetCharEncodingHandler	(xmlCharEncoding enc);
+XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL
+	xmlFindCharEncodingHandler	(const char *name);
+XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL
+	xmlNewCharEncodingHandler	(const char *name, 
+                          		 xmlCharEncodingInputFunc input,
+                          		 xmlCharEncodingOutputFunc output);
+
+/*
+ * Interfaces for encoding names and aliases.
+ */
+XMLPUBFUN int XMLCALL	
+	xmlAddEncodingAlias		(const char *name,
+					 const char *alias);
+XMLPUBFUN int XMLCALL	
+	xmlDelEncodingAlias		(const char *alias);
+XMLPUBFUN const char * XMLCALL
+	xmlGetEncodingAlias		(const char *alias);
+XMLPUBFUN void XMLCALL	
+	xmlCleanupEncodingAliases	(void);
+XMLPUBFUN xmlCharEncoding XMLCALL
+	xmlParseCharEncoding		(const char *name);
+XMLPUBFUN const char * XMLCALL
+	xmlGetCharEncodingName		(xmlCharEncoding enc);
+
+/*
+ * Interfaces directly used by the parsers.
+ */
+XMLPUBFUN xmlCharEncoding XMLCALL
+	xmlDetectCharEncoding		(const unsigned char *in,
+					 int len);
+
+XMLPUBFUN int XMLCALL	
+	xmlCharEncOutFunc		(xmlCharEncodingHandler *handler,
+					 xmlBufferPtr out,
+					 xmlBufferPtr in);
+
+XMLPUBFUN int XMLCALL	
+	xmlCharEncInFunc		(xmlCharEncodingHandler *handler,
+					 xmlBufferPtr out,
+					 xmlBufferPtr in);
+XMLPUBFUN int XMLCALL
+	xmlCharEncFirstLine		(xmlCharEncodingHandler *handler,
+					 xmlBufferPtr out,
+					 xmlBufferPtr in);
+XMLPUBFUN int XMLCALL	
+	xmlCharEncCloseFunc		(xmlCharEncodingHandler *handler);
+
+/*
+ * Export a few useful functions
+ */
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN int XMLCALL	
+	UTF8Toisolat1			(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN int XMLCALL	
+	isolat1ToUTF8			(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_CHAR_ENCODING_H__ */
diff --git a/src/include/libxml/entities.h b/src/include/libxml/entities.h
new file mode 100644
index 0000000..cefb97f
--- /dev/null
+++ b/src/include/libxml/entities.h
@@ -0,0 +1,150 @@
+/*
+ * Summary: interface for the XML entities handling
+ * Description: this module provides some of the entity API needed
+ *              for the parser and applications.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The different valid entity types.
+ */
+typedef enum {
+    XML_INTERNAL_GENERAL_ENTITY = 1,
+    XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
+    XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
+    XML_INTERNAL_PARAMETER_ENTITY = 4,
+    XML_EXTERNAL_PARAMETER_ENTITY = 5,
+    XML_INTERNAL_PREDEFINED_ENTITY = 6
+} xmlEntityType;
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+struct _xmlEntity {
+    void           *_private;	        /* application data */
+    xmlElementType          type;       /* XML_ENTITY_DECL, must be second ! */
+    const xmlChar          *name;	/* Entity name */
+    struct _xmlNode    *children;	/* First child link */
+    struct _xmlNode        *last;	/* Last child link */
+    struct _xmlDtd       *parent;	/* -> DTD */
+    struct _xmlNode        *next;	/* next sibling link  */
+    struct _xmlNode        *prev;	/* previous sibling link  */
+    struct _xmlDoc          *doc;       /* the containing document */
+
+    xmlChar                *orig;	/* content without ref substitution */
+    xmlChar             *content;	/* content or ndata if unparsed */
+    int                   length;	/* the content length */
+    xmlEntityType          etype;	/* The entity type */
+    const xmlChar    *ExternalID;	/* External identifier for PUBLIC */
+    const xmlChar      *SystemID;	/* URI for a SYSTEM or PUBLIC Entity */
+
+    struct _xmlEntity     *nexte;	/* unused */
+    const xmlChar           *URI;	/* the full URI as computed */
+    int                    owner;	/* does the entity own the childrens */
+    int			 checked;	/* was the entity content checked */
+					/* this is also used to count entites
+					 * references done from that entity */
+};
+
+/*
+ * All entities are stored in an hash table.
+ * There is 2 separate hash tables for global and parameter entities.
+ */
+
+typedef struct _xmlHashTable xmlEntitiesTable;
+typedef xmlEntitiesTable *xmlEntitiesTablePtr;
+
+/*
+ * External functions:
+ */
+
+#ifdef LIBXML_LEGACY_ENABLED
+XMLPUBFUN void XMLCALL
+		xmlInitializePredefinedEntities	(void);
+#endif /* LIBXML_LEGACY_ENABLED */
+
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlNewEntity		(xmlDocPtr doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID,
+						 const xmlChar *content);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlAddDocEntity		(xmlDocPtr doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID,
+						 const xmlChar *content);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlAddDtdEntity		(xmlDocPtr doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID,
+						 const xmlChar *content);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlGetPredefinedEntity	(const xmlChar *name);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlGetDocEntity		(xmlDocPtr doc,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlGetDtdEntity		(xmlDocPtr doc,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntityPtr XMLCALL
+			xmlGetParameterEntity	(xmlDocPtr doc,
+						 const xmlChar *name);
+#ifdef LIBXML_LEGACY_ENABLED
+XMLPUBFUN const xmlChar * XMLCALL
+			xmlEncodeEntities	(xmlDocPtr doc,
+						 const xmlChar *input);
+#endif /* LIBXML_LEGACY_ENABLED */
+XMLPUBFUN xmlChar * XMLCALL
+			xmlEncodeEntitiesReentrant(xmlDocPtr doc,
+						 const xmlChar *input);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlEncodeSpecialChars	(xmlDocPtr doc,
+						 const xmlChar *input);
+XMLPUBFUN xmlEntitiesTablePtr XMLCALL
+			xmlCreateEntitiesTable	(void);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlEntitiesTablePtr XMLCALL
+			xmlCopyEntitiesTable	(xmlEntitiesTablePtr table);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL
+			xmlFreeEntitiesTable	(xmlEntitiesTablePtr table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL
+			xmlDumpEntitiesTable	(xmlBufferPtr buf,
+						 xmlEntitiesTablePtr table);
+XMLPUBFUN void XMLCALL
+			xmlDumpEntityDecl	(xmlBufferPtr buf,
+						 xmlEntityPtr ent);
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_LEGACY_ENABLED
+XMLPUBFUN void XMLCALL
+			xmlCleanupPredefinedEntities(void);
+#endif /* LIBXML_LEGACY_ENABLED */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/src/include/libxml/globals.h b/src/include/libxml/globals.h
new file mode 100644
index 0000000..9d688e0
--- /dev/null
+++ b/src/include/libxml/globals.h
@@ -0,0 +1,502 @@
+/*
+ * Summary: interface for all global variables of the library
+ * Description: all the global variables and thread handling for
+ *              those variables is handled by this module.
+ *
+ * The bottom of this file is automatically generated by build_glob.py
+ * based on the description file global.data
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Gary Pennington <Gary.Pennington@uk.sun.com>, Daniel Veillard
+ */
+
+#ifndef __XML_GLOBALS_H
+#define __XML_GLOBALS_H
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/xmlerror.h>
+#include <libxml/SAX.h>
+#include <libxml/SAX2.h>
+#include <libxml/xmlmemory.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XMLPUBFUN void XMLCALL xmlInitGlobals(void);
+XMLPUBFUN void XMLCALL xmlCleanupGlobals(void);
+
+/**
+ * xmlParserInputBufferCreateFilenameFunc:
+ * @URI: the URI to read from
+ * @enc: the requested source encoding
+ *
+ * Signature for the function doing the lookup for a suitable input method
+ * corresponding to an URI.
+ *
+ * Returns the new xmlParserInputBufferPtr in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI, xmlCharEncoding enc);
+
+/**
+ * xmlOutputBufferCreateFilenameFunc:
+ * @URI: the URI to write to
+ * @enc: the requested target encoding
+ *
+ * Signature for the function doing the lookup for a suitable output method
+ * corresponding to an URI.
+ *
+ * Returns the new xmlOutputBufferPtr in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI, xmlCharEncodingHandlerPtr encoder, int compression);
+
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
+XMLCALL xmlParserInputBufferCreateFilenameDefault (xmlParserInputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc
+XMLCALL xmlOutputBufferCreateFilenameDefault (xmlOutputBufferCreateFilenameFunc func);
+
+/*
+ * Externally global symbols which need to be protected for backwards
+ * compatibility support.
+ */
+
+#undef	docbDefaultSAXHandler
+#undef	htmlDefaultSAXHandler
+#undef	oldXMLWDcompatibility
+#undef	xmlBufferAllocScheme
+#undef	xmlDefaultBufferSize
+#undef	xmlDefaultSAXHandler
+#undef	xmlDefaultSAXLocator
+#undef	xmlDoValidityCheckingDefaultValue
+#undef	xmlFree
+#undef	xmlGenericError
+#undef	xmlStructuredError
+#undef	xmlGenericErrorContext
+#undef	xmlStructuredErrorContext
+#undef	xmlGetWarningsDefaultValue
+#undef	xmlIndentTreeOutput
+#undef  xmlTreeIndentString
+#undef	xmlKeepBlanksDefaultValue
+#undef	xmlLineNumbersDefaultValue
+#undef	xmlLoadExtDtdDefaultValue
+#undef	xmlMalloc
+#undef	xmlMallocAtomic
+#undef	xmlMemStrdup
+#undef	xmlParserDebugEntities
+#undef	xmlParserVersion
+#undef	xmlPedanticParserDefaultValue
+#undef	xmlRealloc
+#undef	xmlSaveNoEmptyTags
+#undef	xmlSubstituteEntitiesDefaultValue
+#undef  xmlRegisterNodeDefaultValue
+#undef  xmlDeregisterNodeDefaultValue
+#undef  xmlLastError
+#undef  xmlParserInputBufferCreateFilenameValue
+#undef  xmlOutputBufferCreateFilenameValue
+
+/**
+ * xmlRegisterNodeFunc:
+ * @node: the current node
+ *
+ * Signature for the registration callback of a created node
+ */
+typedef void (*xmlRegisterNodeFunc) (xmlNodePtr node);
+/**
+ * xmlDeregisterNodeFunc:
+ * @node: the current node
+ *
+ * Signature for the deregistration callback of a discarded node
+ */
+typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node);
+
+typedef struct _xmlGlobalState xmlGlobalState;
+typedef xmlGlobalState *xmlGlobalStatePtr;
+struct _xmlGlobalState
+{
+	const char *xmlParserVersion;
+
+	xmlSAXLocator xmlDefaultSAXLocator;
+	xmlSAXHandlerV1 xmlDefaultSAXHandler;
+	xmlSAXHandlerV1 docbDefaultSAXHandler;
+	xmlSAXHandlerV1 htmlDefaultSAXHandler;
+
+	xmlFreeFunc xmlFree;
+	xmlMallocFunc xmlMalloc;
+	xmlStrdupFunc xmlMemStrdup;
+	xmlReallocFunc xmlRealloc;
+
+	xmlGenericErrorFunc xmlGenericError;
+	xmlStructuredErrorFunc xmlStructuredError;
+	void *xmlGenericErrorContext;
+
+	int oldXMLWDcompatibility;
+
+	xmlBufferAllocationScheme xmlBufferAllocScheme;
+	int xmlDefaultBufferSize;
+
+	int xmlSubstituteEntitiesDefaultValue;
+	int xmlDoValidityCheckingDefaultValue;
+	int xmlGetWarningsDefaultValue;
+	int xmlKeepBlanksDefaultValue;
+	int xmlLineNumbersDefaultValue;
+	int xmlLoadExtDtdDefaultValue;
+	int xmlParserDebugEntities;
+	int xmlPedanticParserDefaultValue;
+
+	int xmlSaveNoEmptyTags;
+	int xmlIndentTreeOutput;
+	const char *xmlTreeIndentString;
+
+	xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+	xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+
+	xmlMallocFunc xmlMallocAtomic;
+	xmlError xmlLastError;
+
+	xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
+	xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
+
+	void *xmlStructuredErrorContext;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#include <libxml/threads.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XMLPUBFUN void XMLCALL	xmlInitializeGlobalState(xmlGlobalStatePtr gs);
+
+XMLPUBFUN void XMLCALL xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler);
+
+XMLPUBFUN void XMLCALL xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler);
+
+XMLPUBFUN xmlRegisterNodeFunc XMLCALL xmlRegisterNodeDefault(xmlRegisterNodeFunc func);
+XMLPUBFUN xmlRegisterNodeFunc XMLCALL xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
+XMLPUBFUN xmlDeregisterNodeFunc XMLCALL xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+XMLPUBFUN xmlDeregisterNodeFunc XMLCALL xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc XMLCALL
+	xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc XMLCALL
+	xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func);
+
+/** DOC_DISABLE */
+/*
+ * In general the memory allocation entry points are not kept
+ * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
+ *    - xmlMalloc
+ *    - xmlMallocAtomic
+ *    - xmlRealloc
+ *    - xmlMemStrdup
+ *    - xmlFree
+ */
+
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+#ifdef LIBXML_THREAD_ENABLED
+XMLPUBFUN  xmlMallocFunc * XMLCALL __xmlMalloc(void);
+#define xmlMalloc \
+(*(__xmlMalloc()))
+#else
+XMLPUBVAR xmlMallocFunc xmlMalloc;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+XMLPUBFUN  xmlMallocFunc * XMLCALL __xmlMallocAtomic(void);
+#define xmlMallocAtomic \
+(*(__xmlMallocAtomic()))
+#else
+XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+XMLPUBFUN  xmlReallocFunc * XMLCALL __xmlRealloc(void);
+#define xmlRealloc \
+(*(__xmlRealloc()))
+#else
+XMLPUBVAR xmlReallocFunc xmlRealloc;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+XMLPUBFUN  xmlFreeFunc * XMLCALL __xmlFree(void);
+#define xmlFree \
+(*(__xmlFree()))
+#else
+XMLPUBVAR xmlFreeFunc xmlFree;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+XMLPUBFUN  xmlStrdupFunc * XMLCALL __xmlMemStrdup(void);
+#define xmlMemStrdup \
+(*(__xmlMemStrdup()))
+#else
+XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
+#endif
+
+#else /* !LIBXML_THREAD_ALLOC_ENABLED */
+XMLPUBVAR xmlMallocFunc xmlMalloc;
+XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
+XMLPUBVAR xmlReallocFunc xmlRealloc;
+XMLPUBVAR xmlFreeFunc xmlFree;
+XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
+#endif /* LIBXML_THREAD_ALLOC_ENABLED */
+
+#ifdef LIBXML_DOCB_ENABLED
+XMLPUBFUN  xmlSAXHandlerV1 * XMLCALL __docbDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define docbDefaultSAXHandler \
+(*(__docbDefaultSAXHandler()))
+#else
+XMLPUBVAR xmlSAXHandlerV1 docbDefaultSAXHandler;
+#endif
+#endif
+
+#ifdef LIBXML_HTML_ENABLED
+XMLPUBFUN xmlSAXHandlerV1 * XMLCALL __htmlDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define htmlDefaultSAXHandler \
+(*(__htmlDefaultSAXHandler()))
+#else
+XMLPUBVAR xmlSAXHandlerV1 htmlDefaultSAXHandler;
+#endif
+#endif
+
+XMLPUBFUN xmlError * XMLCALL __xmlLastError(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlLastError \
+(*(__xmlLastError()))
+#else
+XMLPUBVAR xmlError xmlLastError;
+#endif
+
+/*
+ * Everything starting from the line below is
+ * Automatically generated by build_glob.py.
+ * Do not modify the previous line.
+ */
+
+
+XMLPUBFUN int * XMLCALL __oldXMLWDcompatibility(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define oldXMLWDcompatibility \
+(*(__oldXMLWDcompatibility()))
+#else
+XMLPUBVAR int oldXMLWDcompatibility;
+#endif
+
+XMLPUBFUN xmlBufferAllocationScheme * XMLCALL __xmlBufferAllocScheme(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlBufferAllocScheme \
+(*(__xmlBufferAllocScheme()))
+#else
+XMLPUBVAR xmlBufferAllocationScheme xmlBufferAllocScheme;
+#endif
+XMLPUBFUN xmlBufferAllocationScheme XMLCALL xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
+
+XMLPUBFUN int * XMLCALL __xmlDefaultBufferSize(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultBufferSize \
+(*(__xmlDefaultBufferSize()))
+#else
+XMLPUBVAR int xmlDefaultBufferSize;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefDefaultBufferSize(int v);
+
+XMLPUBFUN xmlSAXHandlerV1 * XMLCALL __xmlDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultSAXHandler \
+(*(__xmlDefaultSAXHandler()))
+#else
+XMLPUBVAR xmlSAXHandlerV1 xmlDefaultSAXHandler;
+#endif
+
+XMLPUBFUN xmlSAXLocator * XMLCALL __xmlDefaultSAXLocator(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultSAXLocator \
+(*(__xmlDefaultSAXLocator()))
+#else
+XMLPUBVAR xmlSAXLocator xmlDefaultSAXLocator;
+#endif
+
+XMLPUBFUN int * XMLCALL __xmlDoValidityCheckingDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDoValidityCheckingDefaultValue \
+(*(__xmlDoValidityCheckingDefaultValue()))
+#else
+XMLPUBVAR int xmlDoValidityCheckingDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefDoValidityCheckingDefaultValue(int v);
+
+XMLPUBFUN xmlGenericErrorFunc * XMLCALL __xmlGenericError(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlGenericError \
+(*(__xmlGenericError()))
+#else
+XMLPUBVAR xmlGenericErrorFunc xmlGenericError;
+#endif
+
+XMLPUBFUN xmlStructuredErrorFunc * XMLCALL __xmlStructuredError(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlStructuredError \
+(*(__xmlStructuredError()))
+#else
+XMLPUBVAR xmlStructuredErrorFunc xmlStructuredError;
+#endif
+
+XMLPUBFUN void * * XMLCALL __xmlGenericErrorContext(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlGenericErrorContext \
+(*(__xmlGenericErrorContext()))
+#else
+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 \
+(*(__xmlGetWarningsDefaultValue()))
+#else
+XMLPUBVAR int xmlGetWarningsDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefGetWarningsDefaultValue(int v);
+
+XMLPUBFUN int * XMLCALL __xmlIndentTreeOutput(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlIndentTreeOutput \
+(*(__xmlIndentTreeOutput()))
+#else
+XMLPUBVAR int xmlIndentTreeOutput;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefIndentTreeOutput(int v);
+
+XMLPUBFUN const char * * XMLCALL __xmlTreeIndentString(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlTreeIndentString \
+(*(__xmlTreeIndentString()))
+#else
+XMLPUBVAR const char * xmlTreeIndentString;
+#endif
+XMLPUBFUN const char * XMLCALL xmlThrDefTreeIndentString(const char * v);
+
+XMLPUBFUN int * XMLCALL __xmlKeepBlanksDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlKeepBlanksDefaultValue \
+(*(__xmlKeepBlanksDefaultValue()))
+#else
+XMLPUBVAR int xmlKeepBlanksDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefKeepBlanksDefaultValue(int v);
+
+XMLPUBFUN int * XMLCALL __xmlLineNumbersDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlLineNumbersDefaultValue \
+(*(__xmlLineNumbersDefaultValue()))
+#else
+XMLPUBVAR int xmlLineNumbersDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefLineNumbersDefaultValue(int v);
+
+XMLPUBFUN int * XMLCALL __xmlLoadExtDtdDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlLoadExtDtdDefaultValue \
+(*(__xmlLoadExtDtdDefaultValue()))
+#else
+XMLPUBVAR int xmlLoadExtDtdDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefLoadExtDtdDefaultValue(int v);
+
+XMLPUBFUN int * XMLCALL __xmlParserDebugEntities(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlParserDebugEntities \
+(*(__xmlParserDebugEntities()))
+#else
+XMLPUBVAR int xmlParserDebugEntities;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefParserDebugEntities(int v);
+
+XMLPUBFUN const char * * XMLCALL __xmlParserVersion(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlParserVersion \
+(*(__xmlParserVersion()))
+#else
+XMLPUBVAR const char * xmlParserVersion;
+#endif
+
+XMLPUBFUN int * XMLCALL __xmlPedanticParserDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlPedanticParserDefaultValue \
+(*(__xmlPedanticParserDefaultValue()))
+#else
+XMLPUBVAR int xmlPedanticParserDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefPedanticParserDefaultValue(int v);
+
+XMLPUBFUN int * XMLCALL __xmlSaveNoEmptyTags(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlSaveNoEmptyTags \
+(*(__xmlSaveNoEmptyTags()))
+#else
+XMLPUBVAR int xmlSaveNoEmptyTags;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefSaveNoEmptyTags(int v);
+
+XMLPUBFUN int * XMLCALL __xmlSubstituteEntitiesDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlSubstituteEntitiesDefaultValue \
+(*(__xmlSubstituteEntitiesDefaultValue()))
+#else
+XMLPUBVAR int xmlSubstituteEntitiesDefaultValue;
+#endif
+XMLPUBFUN int XMLCALL xmlThrDefSubstituteEntitiesDefaultValue(int v);
+
+XMLPUBFUN xmlRegisterNodeFunc * XMLCALL __xmlRegisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlRegisterNodeDefaultValue \
+(*(__xmlRegisterNodeDefaultValue()))
+#else
+XMLPUBVAR xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+#endif
+
+XMLPUBFUN xmlDeregisterNodeFunc * XMLCALL __xmlDeregisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDeregisterNodeDefaultValue \
+(*(__xmlDeregisterNodeDefaultValue()))
+#else
+XMLPUBVAR xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+#endif
+
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * XMLCALL __xmlParserInputBufferCreateFilenameValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlParserInputBufferCreateFilenameValue \
+(*(__xmlParserInputBufferCreateFilenameValue()))
+#else
+XMLPUBVAR xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
+#endif
+
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc * XMLCALL __xmlOutputBufferCreateFilenameValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlOutputBufferCreateFilenameValue \
+(*(__xmlOutputBufferCreateFilenameValue()))
+#else
+XMLPUBVAR xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_GLOBALS_H */
diff --git a/src/include/libxml/hash.h b/src/include/libxml/hash.h
new file mode 100644
index 0000000..7fe4be7
--- /dev/null
+++ b/src/include/libxml/hash.h
@@ -0,0 +1,233 @@
+/*
+ * Summary: Chained hash tables
+ * Description: This module implements the hash table support used in 
+ * 		various places in the library.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Bjorn Reese <bjorn.reese@systematic.dk>
+ */
+
+#ifndef __XML_HASH_H__
+#define __XML_HASH_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The hash table.
+ */
+typedef struct _xmlHashTable xmlHashTable;
+typedef xmlHashTable *xmlHashTablePtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/dict.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Recent version of gcc produce a warning when a function pointer is assigned
+ * to an object pointer, or vice versa.  The following macro is a dirty hack
+ * to allow suppression of the warning.  If your architecture has function
+ * pointers which are a different size than a void pointer, there may be some
+ * serious trouble within the library.
+ */
+/**
+ * XML_CAST_FPTR:
+ * @fptr:  pointer to a function
+ *
+ * Macro to do a casting from an object pointer to a
+ * function pointer without encountering a warning from
+ * gcc
+ *
+ * #define XML_CAST_FPTR(fptr) (*(void **)(&fptr))
+ * This macro violated ISO C aliasing rules (gcc4 on s390 broke)
+ * so it is disabled now
+ */
+
+#define XML_CAST_FPTR(fptr) fptr
+
+
+/*
+ * function types:
+ */
+/**
+ * xmlHashDeallocator:
+ * @payload:  the data in the hash
+ * @name:  the name associated
+ *
+ * Callback to free data from a hash.
+ */
+typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
+/**
+ * xmlHashCopier:
+ * @payload:  the data in the hash
+ * @name:  the name associated
+ *
+ * Callback to copy data from a hash.
+ *
+ * Returns a copy of the data or NULL in case of error.
+ */
+typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
+/**
+ * xmlHashScanner:
+ * @payload:  the data in the hash
+ * @data:  extra scannner data
+ * @name:  the name associated
+ *
+ * Callback when scanning data in a hash with the simple scanner.
+ */
+typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name);
+/**
+ * xmlHashScannerFull:
+ * @payload:  the data in the hash
+ * @data:  extra scannner data
+ * @name:  the name associated
+ * @name2:  the second name associated
+ * @name3:  the third name associated
+ *
+ * Callback when scanning data in a hash with the full scanner.
+ */
+typedef void (*xmlHashScannerFull)(void *payload, void *data,
+				   const xmlChar *name, const xmlChar *name2,
+				   const xmlChar *name3);
+
+/*
+ * Constructor and destructor.
+ */
+XMLPUBFUN xmlHashTablePtr XMLCALL
+			xmlHashCreate	(int size);
+XMLPUBFUN xmlHashTablePtr XMLCALL
+			xmlHashCreateDict(int size,
+					 xmlDictPtr dict);
+XMLPUBFUN void XMLCALL			
+			xmlHashFree	(xmlHashTablePtr table,
+					 xmlHashDeallocator f);
+
+/*
+ * Add a new entry to the hash table.
+ */
+XMLPUBFUN int XMLCALL			
+			xmlHashAddEntry	(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         void *userdata);
+XMLPUBFUN int XMLCALL			
+			xmlHashUpdateEntry(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         void *userdata,
+					 xmlHashDeallocator f);
+XMLPUBFUN int XMLCALL		    
+			xmlHashAddEntry2(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         void *userdata);
+XMLPUBFUN int XMLCALL			
+			xmlHashUpdateEntry2(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         void *userdata,
+					 xmlHashDeallocator f);
+XMLPUBFUN int XMLCALL			
+			xmlHashAddEntry3(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         const xmlChar *name3,
+		                         void *userdata);
+XMLPUBFUN int XMLCALL			
+			xmlHashUpdateEntry3(xmlHashTablePtr table,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         const xmlChar *name3,
+		                         void *userdata,
+					 xmlHashDeallocator f);
+
+/*
+ * Remove an entry from the hash table.
+ */
+XMLPUBFUN int XMLCALL     
+			xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
+                           xmlHashDeallocator f);
+XMLPUBFUN int XMLCALL     
+			xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
+                            const xmlChar *name2, xmlHashDeallocator f);
+XMLPUBFUN int  XMLCALL    
+			xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
+                            const xmlChar *name2, const xmlChar *name3,
+                            xmlHashDeallocator f);
+
+/*
+ * Retrieve the userdata.
+ */
+XMLPUBFUN void * XMLCALL			
+			xmlHashLookup	(xmlHashTablePtr table,
+					 const xmlChar *name);
+XMLPUBFUN void * XMLCALL			
+			xmlHashLookup2	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *name2);
+XMLPUBFUN void * XMLCALL			
+			xmlHashLookup3	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3);
+XMLPUBFUN void * XMLCALL			
+			xmlHashQLookup	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *prefix);
+XMLPUBFUN void * XMLCALL			
+			xmlHashQLookup2	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *prefix,
+					 const xmlChar *name2,
+					 const xmlChar *prefix2);
+XMLPUBFUN void * XMLCALL			
+			xmlHashQLookup3	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *prefix,
+					 const xmlChar *name2,
+					 const xmlChar *prefix2,
+					 const xmlChar *name3,
+					 const xmlChar *prefix3);
+
+/*
+ * Helpers.
+ */
+XMLPUBFUN xmlHashTablePtr XMLCALL		
+			xmlHashCopy	(xmlHashTablePtr table,
+					 xmlHashCopier f);
+XMLPUBFUN int XMLCALL			
+			xmlHashSize	(xmlHashTablePtr table);
+XMLPUBFUN void XMLCALL			
+			xmlHashScan	(xmlHashTablePtr table,
+					 xmlHashScanner f,
+					 void *data);
+XMLPUBFUN void XMLCALL			
+			xmlHashScan3	(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3,
+					 xmlHashScanner f,
+					 void *data);
+XMLPUBFUN void XMLCALL			
+			xmlHashScanFull	(xmlHashTablePtr table,
+					 xmlHashScannerFull f,
+					 void *data);
+XMLPUBFUN void XMLCALL			
+			xmlHashScanFull3(xmlHashTablePtr table,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3,
+					 xmlHashScannerFull f,
+					 void *data);
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_HASH_H__ */
diff --git a/src/include/libxml/list.h b/src/include/libxml/list.h
new file mode 100644
index 0000000..1d83482
--- /dev/null
+++ b/src/include/libxml/list.h
@@ -0,0 +1,137 @@
+/*
+ * Summary: lists interfaces
+ * Description: this module implement the list support used in 
+ * various place in the library.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Gary Pennington <Gary.Pennington@uk.sun.com>
+ */
+
+#ifndef __XML_LINK_INCLUDE__
+#define __XML_LINK_INCLUDE__
+
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _xmlLink xmlLink;
+typedef xmlLink *xmlLinkPtr;
+
+typedef struct _xmlList xmlList;
+typedef xmlList *xmlListPtr;
+
+/**
+ * xmlListDeallocator:
+ * @lk:  the data to deallocate
+ *
+ * Callback function used to free data from a list.
+ */
+typedef void (*xmlListDeallocator) (xmlLinkPtr lk);
+/**
+ * xmlListDataCompare:
+ * @data0: the first data
+ * @data1: the second data
+ *
+ * Callback function used to compare 2 data.
+ *
+ * Returns 0 is equality, -1 or 1 otherwise depending on the ordering.
+ */
+typedef int  (*xmlListDataCompare) (const void *data0, const void *data1);
+/**
+ * xmlListWalker:
+ * @data: the data found in the list
+ * @user: extra user provided data to the walker
+ *
+ * Callback function used when walking a list with xmlListWalk().
+ *
+ * Returns 0 to stop walking the list, 1 otherwise.
+ */
+typedef int (*xmlListWalker) (const void *data, const void *user);
+
+/* Creation/Deletion */
+XMLPUBFUN xmlListPtr XMLCALL
+		xmlListCreate		(xmlListDeallocator deallocator,
+	                                 xmlListDataCompare compare);
+XMLPUBFUN void XMLCALL		
+		xmlListDelete		(xmlListPtr l);
+
+/* Basic Operators */
+XMLPUBFUN void * XMLCALL		
+		xmlListSearch		(xmlListPtr l,
+					 void *data);
+XMLPUBFUN void * XMLCALL		
+		xmlListReverseSearch	(xmlListPtr l,
+					 void *data);
+XMLPUBFUN int XMLCALL		
+		xmlListInsert		(xmlListPtr l,
+					 void *data) ;
+XMLPUBFUN int XMLCALL		
+		xmlListAppend		(xmlListPtr l,
+					 void *data) ;
+XMLPUBFUN int XMLCALL		
+		xmlListRemoveFirst	(xmlListPtr l,
+					 void *data);
+XMLPUBFUN int XMLCALL		
+		xmlListRemoveLast	(xmlListPtr l,
+					 void *data);
+XMLPUBFUN int XMLCALL		
+		xmlListRemoveAll	(xmlListPtr l,
+					 void *data);
+XMLPUBFUN void XMLCALL		
+		xmlListClear		(xmlListPtr l);
+XMLPUBFUN int XMLCALL		
+		xmlListEmpty		(xmlListPtr l);
+XMLPUBFUN xmlLinkPtr XMLCALL	
+		xmlListFront		(xmlListPtr l);
+XMLPUBFUN xmlLinkPtr XMLCALL	
+		xmlListEnd		(xmlListPtr l);
+XMLPUBFUN int XMLCALL		
+		xmlListSize		(xmlListPtr l);
+
+XMLPUBFUN void XMLCALL		
+		xmlListPopFront		(xmlListPtr l);
+XMLPUBFUN void XMLCALL		
+		xmlListPopBack		(xmlListPtr l);
+XMLPUBFUN int XMLCALL		
+		xmlListPushFront	(xmlListPtr l,
+					 void *data);
+XMLPUBFUN int XMLCALL		
+		xmlListPushBack		(xmlListPtr l,
+					 void *data);
+
+/* Advanced Operators */
+XMLPUBFUN void XMLCALL		
+		xmlListReverse		(xmlListPtr l);
+XMLPUBFUN void XMLCALL		
+		xmlListSort		(xmlListPtr l);
+XMLPUBFUN void XMLCALL		
+		xmlListWalk		(xmlListPtr l,
+					 xmlListWalker walker,
+					 const void *user);
+XMLPUBFUN void XMLCALL		
+		xmlListReverseWalk	(xmlListPtr l,
+					 xmlListWalker walker,
+					 const void *user);
+XMLPUBFUN void XMLCALL		
+		xmlListMerge		(xmlListPtr l1,
+					 xmlListPtr l2);
+XMLPUBFUN xmlListPtr XMLCALL	
+		xmlListDup		(const xmlListPtr old);
+XMLPUBFUN int XMLCALL		
+		xmlListCopy		(xmlListPtr cur,
+					 const xmlListPtr old);
+/* Link operators */
+XMLPUBFUN void * XMLCALL          
+		xmlLinkGetData          (xmlLinkPtr lk);
+
+/* xmlListUnique() */
+/* xmlListSwap */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_LINK_INCLUDE__ */
diff --git a/src/include/libxml/parser.h b/src/include/libxml/parser.h
new file mode 100644
index 0000000..3580b63
--- /dev/null
+++ b/src/include/libxml/parser.h
@@ -0,0 +1,1236 @@
+/*
+ * Summary: the core parser module
+ * Description: Interfaces, constants and types related to the XML parser
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include <stdarg.h>
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/dict.h>
+#include <libxml/hash.h>
+#include <libxml/valid.h>
+#include <libxml/entities.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XML_DEFAULT_VERSION:
+ *
+ * The default version of XML used: 1.0
+ */
+#define XML_DEFAULT_VERSION	"1.0"
+
+/**
+ * xmlParserInput:
+ *
+ * An xmlParserInput is an input flow for the XML processor.
+ * Each entity parsed is associated an xmlParserInput (except the
+ * few predefined ones). This is the case both for internal entities
+ * - in which case the flow is already completely in memory - or
+ * external entities - in which case we use the buf structure for
+ * progressive reading and I18N conversions to the internal UTF-8 format.
+ */
+
+/**
+ * xmlParserInputDeallocate:
+ * @str:  the string to deallocate
+ *
+ * Callback for freeing some parser input allocations.
+ */
+typedef void (* xmlParserInputDeallocate)(xmlChar *str);
+
+struct _xmlParserInput {
+    /* Input buffer */
+    xmlParserInputBufferPtr buf;      /* UTF-8 encoded buffer */
+
+    const char *filename;             /* The file analyzed, if any */
+    const char *directory;            /* the directory/base of the file */
+    const xmlChar *base;              /* Base of the array to parse */
+    const xmlChar *cur;               /* Current char being parsed */
+    const xmlChar *end;               /* end of the array to parse */
+    int length;                       /* length if known */
+    int line;                         /* Current line */
+    int col;                          /* Current column */
+    /*
+     * NOTE: consumed is only tested for equality in the parser code,
+     *       so even if there is an overflow this should not give troubles
+     *       for parsing very large instances.
+     */
+    unsigned long consumed;           /* How many xmlChars already consumed */
+    xmlParserInputDeallocate free;    /* function to deallocate the base */
+    const xmlChar *encoding;          /* the encoding string for entity */
+    const xmlChar *version;           /* the version string for entity */
+    int standalone;                   /* Was that entity marked standalone */
+    int id;                           /* an unique identifier for the entity */
+};
+
+/**
+ * xmlParserNodeInfo:
+ *
+ * The parser can be asked to collect Node informations, i.e. at what
+ * place in the file they were detected. 
+ * NOTE: This is off by default and not very well tested.
+ */
+typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
+typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
+
+struct _xmlParserNodeInfo {
+  const struct _xmlNode* node;
+  /* Position & line # that text that created the node begins & ends on */
+  unsigned long begin_pos;
+  unsigned long begin_line;
+  unsigned long end_pos;
+  unsigned long end_line;
+};
+
+typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
+typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
+struct _xmlParserNodeInfoSeq {
+  unsigned long maximum;
+  unsigned long length;
+  xmlParserNodeInfo* buffer;
+};
+
+/**
+ * xmlParserInputState:
+ *
+ * The parser is now working also as a state based parser.
+ * The recursive one use the state info for entities processing.
+ */
+typedef enum {
+    XML_PARSER_EOF = -1,	/* nothing is to be parsed */
+    XML_PARSER_START = 0,	/* nothing has been parsed */
+    XML_PARSER_MISC,		/* Misc* before int subset */
+    XML_PARSER_PI,		/* Within a processing instruction */
+    XML_PARSER_DTD,		/* within some DTD content */
+    XML_PARSER_PROLOG,		/* Misc* after internal subset */
+    XML_PARSER_COMMENT,		/* within a comment */
+    XML_PARSER_START_TAG,	/* within a start tag */
+    XML_PARSER_CONTENT,		/* within the content */
+    XML_PARSER_CDATA_SECTION,	/* within a CDATA section */
+    XML_PARSER_END_TAG,		/* within a closing tag */
+    XML_PARSER_ENTITY_DECL,	/* within an entity declaration */
+    XML_PARSER_ENTITY_VALUE,	/* within an entity value in a decl */
+    XML_PARSER_ATTRIBUTE_VALUE,	/* within an attribute value */
+    XML_PARSER_SYSTEM_LITERAL,	/* within a SYSTEM value */
+    XML_PARSER_EPILOG, 		/* the Misc* after the last end tag */
+    XML_PARSER_IGNORE,		/* within an IGNORED section */
+    XML_PARSER_PUBLIC_LITERAL 	/* within a PUBLIC value */
+} xmlParserInputState;
+
+/**
+ * XML_DETECT_IDS:
+ *
+ * Bit in the loadsubset context field to tell to do ID/REFs lookups.
+ * Use it to initialize xmlLoadExtDtdDefaultValue.
+ */
+#define XML_DETECT_IDS		2
+
+/**
+ * XML_COMPLETE_ATTRS:
+ *
+ * Bit in the loadsubset context field to tell to do complete the
+ * elements attributes lists with the ones defaulted from the DTDs.
+ * Use it to initialize xmlLoadExtDtdDefaultValue.
+ */
+#define XML_COMPLETE_ATTRS	4
+
+/**
+ * XML_SKIP_IDS:
+ *
+ * Bit in the loadsubset context field to tell to not do ID/REFs registration.
+ * Used to initialize xmlLoadExtDtdDefaultValue in some special cases.
+ */
+#define XML_SKIP_IDS		8
+
+/**
+ * xmlParserMode:
+ *
+ * A parser can operate in various modes
+ */
+typedef enum {
+    XML_PARSE_UNKNOWN = 0,
+    XML_PARSE_DOM = 1,
+    XML_PARSE_SAX = 2,
+    XML_PARSE_PUSH_DOM = 3,
+    XML_PARSE_PUSH_SAX = 4,
+    XML_PARSE_READER = 5
+} xmlParserMode;
+
+/**
+ * xmlParserCtxt:
+ *
+ * The parser context.
+ * NOTE This doesn't completely define the parser state, the (current ?)
+ *      design of the parser uses recursive function calls since this allow
+ *      and easy mapping from the production rules of the specification
+ *      to the actual code. The drawback is that the actual function call
+ *      also reflect the parser state. However most of the parsing routines
+ *      takes as the only argument the parser context pointer, so migrating
+ *      to a state based parser for progressive parsing shouldn't be too hard.
+ */
+struct _xmlParserCtxt {
+    struct _xmlSAXHandler *sax;       /* The SAX handler */
+    void            *userData;        /* For SAX interface only, used by DOM build */
+    xmlDocPtr           myDoc;        /* the document being built */
+    int            wellFormed;        /* is the document well formed */
+    int       replaceEntities;        /* shall we replace entities ? */
+    const xmlChar    *version;        /* the XML version string */
+    const xmlChar   *encoding;        /* the declared encoding, if any */
+    int            standalone;        /* standalone 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 */
+    int                inputNr;       /* Number of current input streams */
+    int                inputMax;      /* Max number of input streams */
+    xmlParserInputPtr *inputTab;      /* stack of inputs */
+
+    /* Node analysis stack only used for DOM building */
+    xmlNodePtr         node;          /* Current parsed Node */
+    int                nodeNr;        /* Depth of the parsing stack */
+    int                nodeMax;       /* Max depth of the parsing stack */
+    xmlNodePtr        *nodeTab;       /* array of nodes */
+
+    int record_info;                  /* Whether node info should be kept */
+    xmlParserNodeInfoSeq node_seq;    /* info about each node parsed */
+
+    int errNo;                        /* error code */
+
+    int     hasExternalSubset;        /* reference and external subset */
+    int             hasPErefs;        /* the internal subset has PE refs */
+    int              external;        /* are we parsing an external entity */
+
+    int                 valid;        /* is the document valid */
+    int              validate;        /* shall we try to validate ? */
+    xmlValidCtxt        vctxt;        /* The validity context */
+
+    xmlParserInputState instate;      /* current type of input */
+    int                 token;        /* next char look-ahead */    
+
+    char           *directory;        /* the data directory */
+
+    /* Node name stack */
+    const xmlChar     *name;          /* Current parsed Node */
+    int                nameNr;        /* Depth of the parsing stack */
+    int                nameMax;       /* Max depth of the parsing stack */
+    const xmlChar *   *nameTab;       /* array of nodes */
+
+    long               nbChars;       /* number of xmlChar processed */
+    long            checkIndex;       /* used by progressive parsing lookup */
+    int             keepBlanks;       /* ugly but ... */
+    int             disableSAX;       /* SAX callbacks are disabled */
+    int               inSubset;       /* Parsing is in int 1/ext 2 subset */
+    const xmlChar *    intSubName;    /* name of subset */
+    xmlChar *          extSubURI;     /* URI of external subset */
+    xmlChar *          extSubSystem;  /* SYSTEM ID of external subset */
+
+    /* xml:space values */
+    int *              space;         /* Should the parser preserve spaces */
+    int                spaceNr;       /* Depth of the parsing stack */
+    int                spaceMax;      /* Max depth of the parsing stack */
+    int *              spaceTab;      /* array of space infos */
+
+    int                depth;         /* to prevent entity substitution loops */
+    xmlParserInputPtr  entity;        /* used to check entities boundaries */
+    int                charset;       /* encoding of the in-memory content
+				         actually an xmlCharEncoding */
+    int                nodelen;       /* Those two fields are there to */
+    int                nodemem;       /* Speed up large node parsing */
+    int                pedantic;      /* signal pedantic warnings */
+    void              *_private;      /* For user data, libxml won't touch it */
+
+    int                loadsubset;    /* should the external subset be loaded */
+    int                linenumbers;   /* set line number in element content */
+    void              *catalogs;      /* document's own catalog */
+    int                recovery;      /* run in recovery mode */
+    int                progressive;   /* is this a progressive parsing */
+    xmlDictPtr         dict;          /* dictionnary for the parser */
+    const xmlChar *   *atts;          /* array for the attributes callbacks */
+    int                maxatts;       /* the size of the array */
+    int                docdict;       /* use strings from dict to build tree */
+
+    /*
+     * pre-interned strings
+     */
+    const xmlChar *str_xml;
+    const xmlChar *str_xmlns;
+    const xmlChar *str_xml_ns;
+
+    /*
+     * Everything below is used only by the new SAX mode
+     */
+    int                sax2;          /* operating in the new SAX mode */
+    int                nsNr;          /* the number of inherited namespaces */
+    int                nsMax;         /* the size of the arrays */
+    const xmlChar *   *nsTab;         /* the array of prefix/namespace name */
+    int               *attallocs;     /* which attribute were allocated */
+    void *            *pushTab;       /* array of data for push */
+    xmlHashTablePtr    attsDefault;   /* defaulted attributes if any */
+    xmlHashTablePtr    attsSpecial;   /* non-CDATA attributes if any */
+    int                nsWellFormed;  /* is the document XML Nanespace okay */
+    int                options;       /* Extra options */
+
+    /*
+     * Those fields are needed only for treaming parsing so far
+     */
+    int               dictNames;    /* Use dictionary names for the tree */
+    int               freeElemsNr;  /* number of freed element nodes */
+    xmlNodePtr        freeElems;    /* List of freed element nodes */
+    int               freeAttrsNr;  /* number of freed attributes nodes */
+    xmlAttrPtr        freeAttrs;    /* List of freed attributes nodes */
+
+    /*
+     * the complete error informations for the last error.
+     */
+    xmlError          lastError;
+    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 */
+};
+
+/**
+ * xmlSAXLocator:
+ *
+ * A SAX Locator.
+ */
+struct _xmlSAXLocator {
+    const xmlChar *(*getPublicId)(void *ctx);
+    const xmlChar *(*getSystemId)(void *ctx);
+    int (*getLineNumber)(void *ctx);
+    int (*getColumnNumber)(void *ctx);
+};
+
+/**
+ * xmlSAXHandler:
+ *
+ * A SAX handler is bunch of callbacks called by the parser when processing
+ * of the input generate data or structure informations.
+ */
+
+/**
+ * resolveEntitySAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Callback:
+ * The entity loader, to control the loading of external entities,
+ * the application can either:
+ *    - override this resolveEntity() callback in the SAX block
+ *    - or better use the xmlSetExternalEntityLoader() function to
+ *      set up it's own entity resolution routine
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * internalSubsetSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on internal subset declaration.
+ */
+typedef void (*internalSubsetSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *ExternalID,
+				const xmlChar *SystemID);
+/**
+ * externalSubsetSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on external subset declaration.
+ */
+typedef void (*externalSubsetSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *ExternalID,
+				const xmlChar *SystemID);
+/**
+ * getEntitySAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get an entity by name.
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * getParameterEntitySAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get a parameter entity by name.
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * entityDeclSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @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).
+ *
+ * An entity definition has been parsed.
+ */
+typedef void (*entityDeclSAXFunc) (void *ctx,
+				const xmlChar *name,
+				int type,
+				const xmlChar *publicId,
+				const xmlChar *systemId,
+				xmlChar *content);
+/**
+ * notationDeclSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+typedef void (*notationDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * attributeDeclSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @elem:  the name of the element
+ * @fullname:  the attribute name 
+ * @type:  the attribute type 
+ * @def:  the type of default value
+ * @defaultValue: the attribute default value
+ * @tree:  the tree of enumerated value set
+ *
+ * An attribute definition has been parsed.
+ */
+typedef void (*attributeDeclSAXFunc)(void *ctx,
+				const xmlChar *elem,
+				const xmlChar *fullname,
+				int type,
+				int def,
+				const xmlChar *defaultValue,
+				xmlEnumerationPtr tree);
+/**
+ * elementDeclSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  the element name 
+ * @type:  the element type 
+ * @content: the element value tree
+ *
+ * An element definition has been parsed.
+ */
+typedef void (*elementDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				int type,
+				xmlElementContentPtr content);
+/**
+ * unparsedEntityDeclSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed.
+ */
+typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId,
+				const xmlChar *notationName);
+/**
+ * setDocumentLocatorSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator.
+ * Everything is available on the context, so this is useless in our case.
+ */
+typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
+				xmlSAXLocatorPtr loc);
+/**
+ * startDocumentSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ *
+ * Called when the document start being processed.
+ */
+typedef void (*startDocumentSAXFunc) (void *ctx);
+/**
+ * endDocumentSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ *
+ * Called when the document end has been detected.
+ */
+typedef void (*endDocumentSAXFunc) (void *ctx);
+/**
+ * startElementSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  The element name, including namespace prefix
+ * @atts:  An array of name/value attributes pairs, NULL terminated
+ *
+ * Called when an opening tag has been processed.
+ */
+typedef void (*startElementSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar **atts);
+/**
+ * endElementSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  The element name
+ *
+ * Called when the end of an element has been detected.
+ */
+typedef void (*endElementSAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * attributeSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  The attribute name, including namespace prefix
+ * @value:  The attribute value
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ */
+typedef void (*attributeSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *value);
+/**
+ * referenceSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @name:  The entity name
+ *
+ * Called when an entity reference is detected. 
+ */
+typedef void (*referenceSAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * charactersSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * Receiving some chars from the parser.
+ */
+typedef void (*charactersSAXFunc) (void *ctx,
+				const xmlChar *ch,
+				int len);
+/**
+ * ignorableWhitespaceSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * Receiving some ignorable whitespaces from the parser.
+ * UNUSED: by default the DOM building will use characters.
+ */
+typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
+				const xmlChar *ch,
+				int len);
+/**
+ * processingInstructionSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @target:  the target name
+ * @data: the PI data's
+ *
+ * A processing instruction has been parsed.
+ */
+typedef void (*processingInstructionSAXFunc) (void *ctx,
+				const xmlChar *target,
+				const xmlChar *data);
+/**
+ * commentSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+typedef void (*commentSAXFunc) (void *ctx,
+				const xmlChar *value);
+/**
+ * cdataBlockSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * Called when a pcdata block has been parsed.
+ */
+typedef void (*cdataBlockSAXFunc) (
+	                        void *ctx,
+				const xmlChar *value,
+				int len);
+/**
+ * warningSAXFunc:
+ * @ctx:  an XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Display and format a warning messages, callback.
+ */
+typedef void (XMLCDECL *warningSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * errorSAXFunc:
+ * @ctx:  an XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Display and format an error messages, callback.
+ */
+typedef void (XMLCDECL *errorSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * fatalErrorSAXFunc:
+ * @ctx:  an XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ * 
+ * Display and format fatal error messages, callback.
+ * Note: so far fatalError() SAX callbacks are not used, error()
+ *       get all the callbacks for errors.
+ */
+typedef void (XMLCDECL *fatalErrorSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * isStandaloneSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ *
+ * Is this document tagged standalone?
+ *
+ * Returns 1 if true
+ */
+typedef int (*isStandaloneSAXFunc) (void *ctx);
+/**
+ * hasInternalSubsetSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ *
+ * Does this document has an internal subset.
+ *
+ * Returns 1 if true
+ */
+typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
+
+/**
+ * hasExternalSubsetSAXFunc:
+ * @ctx:  the user data (XML parser context)
+ *
+ * Does this document has an external subset?
+ *
+ * Returns 1 if true
+ */
+typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
+
+/************************************************************************
+ *									*
+ *			The SAX version 2 API extensions		*
+ *									*
+ ************************************************************************/
+/**
+ * XML_SAX2_MAGIC:
+ *
+ * Special constant found in SAX2 blocks initialized fields
+ */
+#define XML_SAX2_MAGIC 0xDEEDBEAF
+
+/**
+ * startElementNsSAX2Func:
+ * @ctx:  the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ * @nb_namespaces:  number of namespace definitions on that node
+ * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
+ * @nb_attributes:  the number of attributes on that node
+ * @nb_defaulted:  the number of defaulted attributes. The defaulted
+ *                  ones are at the end of the array
+ * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
+ *               attribute values.
+ *
+ * SAX2 callback when an element start has been detected by the parser.
+ * It provides the namespace informations for the element, as well as
+ * the new namespace declarations on the element.
+ */
+
+typedef void (*startElementNsSAX2Func) (void *ctx,
+					const xmlChar *localname,
+					const xmlChar *prefix,
+					const xmlChar *URI,
+					int nb_namespaces,
+					const xmlChar **namespaces,
+					int nb_attributes,
+					int nb_defaulted,
+					const xmlChar **attributes);
+ 
+/**
+ * endElementNsSAX2Func:
+ * @ctx:  the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ *
+ * SAX2 callback when an element end has been detected by the parser.
+ * It provides the namespace informations for the element.
+ */
+
+typedef void (*endElementNsSAX2Func)   (void *ctx,
+					const xmlChar *localname,
+					const xmlChar *prefix,
+					const xmlChar *URI);
+
+
+struct _xmlSAXHandler {
+    internalSubsetSAXFunc internalSubset;
+    isStandaloneSAXFunc isStandalone;
+    hasInternalSubsetSAXFunc hasInternalSubset;
+    hasExternalSubsetSAXFunc hasExternalSubset;
+    resolveEntitySAXFunc resolveEntity;
+    getEntitySAXFunc getEntity;
+    entityDeclSAXFunc entityDecl;
+    notationDeclSAXFunc notationDecl;
+    attributeDeclSAXFunc attributeDecl;
+    elementDeclSAXFunc elementDecl;
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    startDocumentSAXFunc startDocument;
+    endDocumentSAXFunc endDocument;
+    startElementSAXFunc startElement;
+    endElementSAXFunc endElement;
+    referenceSAXFunc reference;
+    charactersSAXFunc characters;
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    processingInstructionSAXFunc processingInstruction;
+    commentSAXFunc comment;
+    warningSAXFunc warning;
+    errorSAXFunc error;
+    fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
+    getParameterEntitySAXFunc getParameterEntity;
+    cdataBlockSAXFunc cdataBlock;
+    externalSubsetSAXFunc externalSubset;
+    unsigned int initialized;
+    /* The following fields are extensions available only on version 2 */
+    void *_private;
+    startElementNsSAX2Func startElementNs;
+    endElementNsSAX2Func endElementNs;
+    xmlStructuredErrorFunc serror;
+};
+
+/*
+ * SAX Version 1
+ */
+typedef struct _xmlSAXHandlerV1 xmlSAXHandlerV1;
+typedef xmlSAXHandlerV1 *xmlSAXHandlerV1Ptr;
+struct _xmlSAXHandlerV1 {
+    internalSubsetSAXFunc internalSubset;
+    isStandaloneSAXFunc isStandalone;
+    hasInternalSubsetSAXFunc hasInternalSubset;
+    hasExternalSubsetSAXFunc hasExternalSubset;
+    resolveEntitySAXFunc resolveEntity;
+    getEntitySAXFunc getEntity;
+    entityDeclSAXFunc entityDecl;
+    notationDeclSAXFunc notationDecl;
+    attributeDeclSAXFunc attributeDecl;
+    elementDeclSAXFunc elementDecl;
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    startDocumentSAXFunc startDocument;
+    endDocumentSAXFunc endDocument;
+    startElementSAXFunc startElement;
+    endElementSAXFunc endElement;
+    referenceSAXFunc reference;
+    charactersSAXFunc characters;
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    processingInstructionSAXFunc processingInstruction;
+    commentSAXFunc comment;
+    warningSAXFunc warning;
+    errorSAXFunc error;
+    fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
+    getParameterEntitySAXFunc getParameterEntity;
+    cdataBlockSAXFunc cdataBlock;
+    externalSubsetSAXFunc externalSubset;
+    unsigned int initialized;
+};
+
+
+/**
+ * xmlExternalEntityLoader:
+ * @URL: The System ID of the resource requested
+ * @ID: The Public ID of the resource requested
+ * @context: the XML parser context 
+ *
+ * External entity loaders types.
+ *
+ * Returns the entity input parser.
+ */
+typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL,
+					 const char *ID,
+					 xmlParserCtxtPtr context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+#include <libxml/globals.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Init/Cleanup
+ */
+XMLPUBFUN void XMLCALL		
+		xmlInitParser		(void);
+XMLPUBFUN void XMLCALL		
+		xmlCleanupParser	(void);
+
+/*
+ * Input functions
+ */
+XMLPUBFUN int XMLCALL		
+		xmlParserInputRead	(xmlParserInputPtr in,
+					 int len);
+XMLPUBFUN int XMLCALL		
+		xmlParserInputGrow	(xmlParserInputPtr in,
+					 int len);
+
+/*
+ * Basic parsing Interfaces
+ */
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlParseDoc		(const xmlChar *cur);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlParseFile		(const char *filename);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlParseMemory		(const char *buffer,
+					 int size);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN int XMLCALL		
+		xmlSubstituteEntitiesDefault(int val);
+XMLPUBFUN int XMLCALL		
+		xmlKeepBlanksDefault	(int val);
+XMLPUBFUN void XMLCALL		
+		xmlStopParser		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL		
+		xmlPedanticParserDefault(int val);
+XMLPUBFUN int XMLCALL		
+		xmlLineNumbersDefault	(int val);
+
+#ifdef LIBXML_SAX1_ENABLED
+/*
+ * Recovery mode 
+ */
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlRecoverDoc		(const xmlChar *cur);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlRecoverMemory	(const char *buffer,
+					 int size);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlRecoverFile		(const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+
+/*
+ * Less common routines and SAX interfaces
+ */
+XMLPUBFUN int XMLCALL		
+		xmlParseDocument	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL		
+		xmlParseExtParsedEnt	(xmlParserCtxtPtr ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int XMLCALL		
+		xmlSAXUserParseFile	(xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 const char *filename);
+XMLPUBFUN int XMLCALL		
+		xmlSAXUserParseMemory	(xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 const char *buffer,
+					 int size);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseDoc		(xmlSAXHandlerPtr sax,
+					 const xmlChar *cur,
+					 int recovery);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseMemory	(xmlSAXHandlerPtr sax,
+					 const char *buffer,
+                                   	 int size,
+					 int recovery);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseMemoryWithData (xmlSAXHandlerPtr sax,
+					 const char *buffer,
+                                   	 int size,
+					 int recovery,
+					 void *data);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseFile		(xmlSAXHandlerPtr sax,
+					 const char *filename,
+					 int recovery);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseFileWithData	(xmlSAXHandlerPtr sax,
+					 const char *filename,
+					 int recovery,
+					 void *data);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlSAXParseEntity	(xmlSAXHandlerPtr sax,
+					 const char *filename);
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlParseEntity		(const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlSAXParseDTD		(xmlSAXHandlerPtr sax,
+					 const xmlChar *ExternalID,
+					 const xmlChar *SystemID);
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlParseDTD		(const xmlChar *ExternalID,
+					 const xmlChar *SystemID);
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlIOParseDTD		(xmlSAXHandlerPtr sax,
+					 xmlParserInputBufferPtr input,
+					 xmlCharEncoding enc);
+#endif /* LIBXML_VALID_ENABLE */
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int XMLCALL	
+		xmlParseBalancedChunkMemory(xmlDocPtr doc,
+					 xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 int depth,
+					 const xmlChar *string,
+					 xmlNodePtr *lst);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN xmlParserErrors XMLCALL
+		xmlParseInNodeContext	(xmlNodePtr node,
+					 const char *data,
+					 int datalen,
+					 int options,
+					 xmlNodePtr *lst);
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int XMLCALL          
+		xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc,
+                     xmlSAXHandlerPtr sax,
+                     void *user_data,
+                     int depth,
+                     const xmlChar *string,
+                     xmlNodePtr *lst,
+                     int recover);
+XMLPUBFUN int XMLCALL		
+		xmlParseExternalEntity	(xmlDocPtr doc,
+					 xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 int depth,
+					 const xmlChar *URL,
+					 const xmlChar *ID,
+					 xmlNodePtr *lst);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN int XMLCALL		
+		xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx,
+					 const xmlChar *URL,
+					 const xmlChar *ID,
+					 xmlNodePtr *lst);
+
+/*
+ * Parser contexts handling.
+ */
+XMLPUBFUN xmlParserCtxtPtr XMLCALL	
+		xmlNewParserCtxt	(void);
+XMLPUBFUN int XMLCALL		
+		xmlInitParserCtxt	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL		
+		xmlClearParserCtxt	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL		
+		xmlFreeParserCtxt	(xmlParserCtxtPtr ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlSetupParserForBuffer	(xmlParserCtxtPtr ctxt,
+					 const xmlChar* buffer,
+					 const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN xmlParserCtxtPtr XMLCALL 
+		xmlCreateDocParserCtxt	(const xmlChar *cur);
+
+#ifdef LIBXML_LEGACY_ENABLED
+/*
+ * Reading/setting optional parsing features.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlGetFeaturesList	(int *len,
+					 const char **result);
+XMLPUBFUN int XMLCALL		
+		xmlGetFeature		(xmlParserCtxtPtr ctxt,
+					 const char *name,
+					 void *result);
+XMLPUBFUN int XMLCALL		
+		xmlSetFeature		(xmlParserCtxtPtr ctxt,
+					 const char *name,
+					 void *value);
+#endif /* LIBXML_LEGACY_ENABLED */
+
+#ifdef LIBXML_PUSH_ENABLED
+/*
+ * Interfaces for the Push mode.
+ */
+XMLPUBFUN xmlParserCtxtPtr XMLCALL 
+		xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 const char *chunk,
+					 int size,
+					 const char *filename);
+XMLPUBFUN int XMLCALL		 
+		xmlParseChunk		(xmlParserCtxtPtr ctxt,
+					 const char *chunk,
+					 int size,
+					 int terminate);
+#endif /* LIBXML_PUSH_ENABLED */
+
+/*
+ * Special I/O mode.
+ */
+
+XMLPUBFUN xmlParserCtxtPtr XMLCALL 
+		xmlCreateIOParserCtxt	(xmlSAXHandlerPtr sax,
+					 void *user_data,
+					 xmlInputReadCallback   ioread,
+					 xmlInputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncoding enc);
+
+XMLPUBFUN xmlParserInputPtr XMLCALL 
+		xmlNewIOInputStream	(xmlParserCtxtPtr ctxt,
+					 xmlParserInputBufferPtr input,
+					 xmlCharEncoding enc);
+
+/*
+ * Node infos.
+ */
+XMLPUBFUN const xmlParserNodeInfo* XMLCALL
+		xmlParserFindNodeInfo	(const xmlParserCtxtPtr ctxt,
+				         const xmlNodePtr node);
+XMLPUBFUN void XMLCALL		
+		xmlInitNodeInfoSeq	(xmlParserNodeInfoSeqPtr seq);
+XMLPUBFUN void XMLCALL		
+		xmlClearNodeInfoSeq	(xmlParserNodeInfoSeqPtr seq);
+XMLPUBFUN unsigned long XMLCALL 
+		xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
+                                         const xmlNodePtr node);
+XMLPUBFUN void XMLCALL		
+		xmlParserAddNodeInfo	(xmlParserCtxtPtr ctxt,
+					 const xmlParserNodeInfoPtr info);
+
+/*
+ * External entities handling actually implemented in xmlIO.
+ */
+
+XMLPUBFUN void XMLCALL		
+		xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
+XMLPUBFUN xmlExternalEntityLoader XMLCALL
+		xmlGetExternalEntityLoader(void);
+XMLPUBFUN xmlParserInputPtr XMLCALL
+		xmlLoadExternalEntity	(const char *URL,
+					 const char *ID,
+					 xmlParserCtxtPtr ctxt);
+
+/*
+ * Index lookup, actually implemented in the encoding module
+ */
+XMLPUBFUN long XMLCALL
+		xmlByteConsumed		(xmlParserCtxtPtr ctxt);
+
+/*
+ * New set of simpler/more flexible APIs
+ */
+/**
+ * xmlParserOption:
+ *
+ * This is the set of XML parser options that can be passed down
+ * to the xmlReadDoc() and similar calls.
+ */
+typedef enum {
+    XML_PARSE_RECOVER	= 1<<0,	/* recover on errors */
+    XML_PARSE_NOENT	= 1<<1,	/* substitute entities */
+    XML_PARSE_DTDLOAD	= 1<<2,	/* load the external subset */
+    XML_PARSE_DTDATTR	= 1<<3,	/* default DTD attributes */
+    XML_PARSE_DTDVALID	= 1<<4,	/* validate with the DTD */
+    XML_PARSE_NOERROR	= 1<<5,	/* suppress error reports */
+    XML_PARSE_NOWARNING	= 1<<6,	/* suppress warning reports */
+    XML_PARSE_PEDANTIC	= 1<<7,	/* pedantic error reporting */
+    XML_PARSE_NOBLANKS	= 1<<8,	/* remove blank nodes */
+    XML_PARSE_SAX1	= 1<<9,	/* use the SAX1 interface internally */
+    XML_PARSE_XINCLUDE	= 1<<10,/* Implement XInclude substitition  */
+    XML_PARSE_NONET	= 1<<11,/* Forbid network access */
+    XML_PARSE_NODICT	= 1<<12,/* Do not reuse the context dictionnary */
+    XML_PARSE_NSCLEAN	= 1<<13,/* remove redundant namespaces declarations */
+    XML_PARSE_NOCDATA	= 1<<14,/* merge CDATA as text nodes */
+    XML_PARSE_NOXINCNODE= 1<<15,/* do not generate XINCLUDE START/END nodes */
+    XML_PARSE_COMPACT   = 1<<16,/* compact small text nodes; no modification of
+                                   the tree allowed afterwards (will possibly
+				   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 */
+} xmlParserOption;
+
+XMLPUBFUN void XMLCALL
+		xmlCtxtReset		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		xmlCtxtResetPush	(xmlParserCtxtPtr ctxt,
+					 const char *chunk,
+					 int size,
+					 const char *filename,
+					 const char *encoding);
+XMLPUBFUN int XMLCALL
+		xmlCtxtUseOptions	(xmlParserCtxtPtr ctxt,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlReadDoc		(const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlReadFile		(const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlReadMemory		(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlReadFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlReadIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlCtxtReadDoc		(xmlParserCtxtPtr ctxt,
+					 const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlCtxtReadFile		(xmlParserCtxtPtr ctxt,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlCtxtReadMemory		(xmlParserCtxtPtr ctxt,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlCtxtReadFd		(xmlParserCtxtPtr ctxt,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDocPtr XMLCALL
+		xmlCtxtReadIO		(xmlParserCtxtPtr ctxt,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+/*
+ * Library wide options
+ */
+/**
+ * xmlFeature:
+ *
+ * Used to examine the existance of features that can be enabled
+ * or disabled at compile-time.
+ * They used to be called XML_FEATURE_xxx but this clashed with Expat
+ */
+typedef enum {
+    XML_WITH_THREAD = 1,
+    XML_WITH_TREE = 2,
+    XML_WITH_OUTPUT = 3,
+    XML_WITH_PUSH = 4,
+    XML_WITH_READER = 5,
+    XML_WITH_PATTERN = 6,
+    XML_WITH_WRITER = 7,
+    XML_WITH_SAX1 = 8,
+    XML_WITH_FTP = 9,
+    XML_WITH_HTTP = 10,
+    XML_WITH_VALID = 11,
+    XML_WITH_HTML = 12,
+    XML_WITH_LEGACY = 13,
+    XML_WITH_C14N = 14,
+    XML_WITH_CATALOG = 15,
+    XML_WITH_XPATH = 16,
+    XML_WITH_XPTR = 17,
+    XML_WITH_XINCLUDE = 18,
+    XML_WITH_ICONV = 19,
+    XML_WITH_ISO8859X = 20,
+    XML_WITH_UNICODE = 21,
+    XML_WITH_REGEXP = 22,
+    XML_WITH_AUTOMATA = 23,
+    XML_WITH_EXPR = 24,
+    XML_WITH_SCHEMAS = 25,
+    XML_WITH_SCHEMATRON = 26,
+    XML_WITH_MODULES = 27,
+    XML_WITH_DEBUG = 28,
+    XML_WITH_DEBUG_MEM = 29,
+    XML_WITH_DEBUG_RUN = 30,
+    XML_WITH_ZLIB = 31,
+    XML_WITH_ICU = 32,
+    XML_WITH_NONE = 99999 /* just to be sure of allocation size */
+} xmlFeature;
+
+XMLPUBFUN int XMLCALL
+		xmlHasFeature		(xmlFeature feature);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_H__ */
+
diff --git a/src/include/libxml/parserInternals.h b/src/include/libxml/parserInternals.h
new file mode 100644
index 0000000..a5e75b5
--- /dev/null
+++ b/src/include/libxml/parserInternals.h
@@ -0,0 +1,611 @@
+/*
+ * Summary: internals routines exported by the parser.
+ * Description: this module exports a number of internal parsing routines
+ *              they are not really all intended for applications but
+ *              can prove useful doing low level processing.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_PARSER_INTERNALS_H__
+#define __XML_PARSER_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/chvalid.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlParserMaxDepth:
+ *
+ * arbitrary depth limit for the XML documents that we allow to
+ * process. This is not a limitation of the parser but a safety
+ * boundary feature, use XML_PARSE_HUGE option to override it.
+ */
+XMLPUBVAR unsigned int xmlParserMaxDepth;
+
+/**
+ * XML_MAX_TEXT_LENGTH:
+ *
+ * Maximum size allowed for a single text node when building a tree.
+ * This is not a limitation of the parser but a safety boundary feature,
+ * use XML_PARSE_HUGE option to override it.
+ */
+#define XML_MAX_TEXT_LENGTH 10000000
+
+/**
+ * XML_MAX_NAMELEN:
+ *
+ * Identifiers can be longer, but this will be more costly
+ * at runtime.
+ */
+#define XML_MAX_NAMELEN 100
+
+/**
+ * INPUT_CHUNK:
+ *
+ * The parser tries to always have that amount of input ready.
+ * One of the point is providing context when reporting errors.
+ */
+#define INPUT_CHUNK	250
+
+/************************************************************************
+ *									*
+ * UNICODE version of the macros.      					*
+ *									*
+ ************************************************************************/
+/**
+ * IS_BYTE_CHAR:
+ * @c:  an byte value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [2] Char ::= #x9 | #xA | #xD | [#x20...]
+ * any byte character in the accepted range
+ */
+#define IS_BYTE_CHAR(c)	 xmlIsChar_ch(c)
+
+/**
+ * IS_CHAR:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ *                  | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c)   xmlIsCharQ(c)
+
+/**
+ * IS_CHAR_CH:
+ * @c: an xmlChar (usually an unsigned char)
+ *
+ * Behaves like IS_CHAR on single-byte value
+ */
+#define IS_CHAR_CH(c)  xmlIsChar_ch(c)
+
+/**
+ * IS_BLANK:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c)  xmlIsBlankQ(c)
+
+/**
+ * IS_BLANK_CH:
+ * @c:  an xmlChar value (normally unsigned char)
+ *
+ * Behaviour same as IS_BLANK
+ */
+#define IS_BLANK_CH(c)  xmlIsBlank_ch(c)
+
+/**
+ * IS_BASECHAR:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [85] BaseChar ::= ... long list see REC ...
+ */
+#define IS_BASECHAR(c) xmlIsBaseCharQ(c)
+
+/**
+ * IS_DIGIT:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) xmlIsDigitQ(c)
+
+/**
+ * IS_DIGIT_CH:
+ * @c:  an xmlChar value (usually an unsigned char)
+ *
+ * Behaves like IS_DIGIT but with a single byte argument
+ */
+#define IS_DIGIT_CH(c)  xmlIsDigit_ch(c)
+
+/**
+ * IS_COMBINING:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) xmlIsCombiningQ(c)
+
+/**
+ * IS_COMBINING_CH:
+ * @c:  an xmlChar (usually an unsigned char)
+ *
+ * Always false (all combining chars > 0xff)
+ */
+#define IS_COMBINING_CH(c) 0 
+
+/**
+ * IS_EXTENDER:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ *                   #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ *                   [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c) xmlIsExtenderQ(c)
+
+/**
+ * IS_EXTENDER_CH:
+ * @c:  an xmlChar value (usually an unsigned char)
+ *
+ * Behaves like IS_EXTENDER but with a single-byte argument
+ */
+#define IS_EXTENDER_CH(c)  xmlIsExtender_ch(c)
+
+/**
+ * IS_IDEOGRAPHIC:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
+ */
+#define IS_IDEOGRAPHIC(c) xmlIsIdeographicQ(c)
+
+/**
+ * IS_LETTER:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [84] Letter ::= BaseChar | Ideographic 
+ */
+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
+
+/**
+ * IS_LETTER_CH:
+ * @c:  an xmlChar value (normally unsigned char)
+ *
+ * Macro behaves like IS_LETTER, but only check base chars
+ *
+ */
+#define IS_LETTER_CH(c) xmlIsBaseChar_ch(c)
+
+/**
+ * IS_ASCII_LETTER:
+ * @c: an xmlChar value
+ *
+ * Macro to check [a-zA-Z]
+ *
+ */
+#define IS_ASCII_LETTER(c)	(((0x41 <= (c)) && ((c) <= 0x5a)) || \
+				 ((0x61 <= (c)) && ((c) <= 0x7a)))
+
+/**
+ * IS_ASCII_DIGIT:
+ * @c: an xmlChar value
+ *
+ * Macro to check [0-9]
+ *
+ */
+#define IS_ASCII_DIGIT(c)	((0x30 <= (c)) && ((c) <= 0x39))
+
+/**
+ * IS_PUBIDCHAR:
+ * @c:  an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+ */
+#define IS_PUBIDCHAR(c)	xmlIsPubidCharQ(c)
+
+/**
+ * IS_PUBIDCHAR_CH:
+ * @c:  an xmlChar value (normally unsigned char)
+ *
+ * Same as IS_PUBIDCHAR but for single-byte value
+ */
+#define IS_PUBIDCHAR_CH(c) xmlIsPubidChar_ch(c)
+
+/**
+ * SKIP_EOL:
+ * @p:  and UTF8 string pointer
+ *
+ * Skips the end of line chars.
+ */
+#define SKIP_EOL(p) 							\
+    if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; }			\
+    if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
+
+/**
+ * MOVETO_ENDTAG:
+ * @p:  and UTF8 string pointer
+ *
+ * Skips to the next '>' char.
+ */
+#define MOVETO_ENDTAG(p)						\
+    while ((*p) && (*(p) != '>')) (p)++
+
+/**
+ * MOVETO_STARTTAG:
+ * @p:  and UTF8 string pointer
+ *
+ * Skips to the next '<' char.
+ */
+#define MOVETO_STARTTAG(p)						\
+    while ((*p) && (*(p) != '<')) (p)++
+
+/**
+ * Global variables used for predefined strings.
+ */
+XMLPUBVAR const xmlChar xmlStringText[];
+XMLPUBVAR const xmlChar xmlStringTextNoenc[];
+XMLPUBVAR const xmlChar xmlStringComment[];
+
+/*
+ * Function to finish the work of the macros where needed.
+ */
+XMLPUBFUN int XMLCALL                   xmlIsLetter     (int c);
+
+/**
+ * Parser context.
+ */
+XMLPUBFUN xmlParserCtxtPtr XMLCALL	
+			xmlCreateFileParserCtxt	(const char *filename);
+XMLPUBFUN xmlParserCtxtPtr XMLCALL	
+			xmlCreateURLParserCtxt	(const char *filename,
+						 int options);
+XMLPUBFUN xmlParserCtxtPtr XMLCALL	
+			xmlCreateMemoryParserCtxt(const char *buffer,
+						 int size);
+XMLPUBFUN xmlParserCtxtPtr XMLCALL	
+			xmlCreateEntityParserCtxt(const xmlChar *URL,
+						 const xmlChar *ID,
+						 const xmlChar *base);
+XMLPUBFUN int XMLCALL			
+			xmlSwitchEncoding	(xmlParserCtxtPtr ctxt,
+						 xmlCharEncoding enc);
+XMLPUBFUN int XMLCALL			
+			xmlSwitchToEncoding	(xmlParserCtxtPtr ctxt,
+					 xmlCharEncodingHandlerPtr handler);
+XMLPUBFUN int XMLCALL			
+			xmlSwitchInputEncoding	(xmlParserCtxtPtr ctxt,
+						 xmlParserInputPtr input,
+					 xmlCharEncodingHandlerPtr handler);
+
+#ifdef IN_LIBXML
+/* internal error reporting */
+XMLPUBFUN void XMLCALL
+			__xmlErrEncoding	(xmlParserCtxtPtr ctxt,
+						 xmlParserErrors xmlerr,
+						 const char *msg,
+						 const xmlChar * str1,
+						 const xmlChar * str2);
+#endif
+
+/**
+ * Input Streams.
+ */
+XMLPUBFUN xmlParserInputPtr XMLCALL	
+			xmlNewStringInputStream	(xmlParserCtxtPtr ctxt,
+						 const xmlChar *buffer);
+XMLPUBFUN xmlParserInputPtr XMLCALL	
+			xmlNewEntityInputStream	(xmlParserCtxtPtr ctxt,
+						 xmlEntityPtr entity);
+XMLPUBFUN int XMLCALL			
+			xmlPushInput		(xmlParserCtxtPtr ctxt,
+						 xmlParserInputPtr input);
+XMLPUBFUN xmlChar XMLCALL			
+			xmlPopInput		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlFreeInputStream	(xmlParserInputPtr input);
+XMLPUBFUN xmlParserInputPtr XMLCALL	
+			xmlNewInputFromFile	(xmlParserCtxtPtr ctxt,
+						 const char *filename);
+XMLPUBFUN xmlParserInputPtr XMLCALL	
+			xmlNewInputStream	(xmlParserCtxtPtr ctxt);
+
+/**
+ * Namespaces.
+ */
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlSplitQName		(xmlParserCtxtPtr ctxt,
+						 const xmlChar *name,
+						 xmlChar **prefix);
+
+/**
+ * Generic production rules.
+ */
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlParseName		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseNmtoken		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseEntityValue	(xmlParserCtxtPtr ctxt,
+						 xmlChar **orig);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseAttValue	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseSystemLiteral	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParsePubidLiteral	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseCharData	(xmlParserCtxtPtr ctxt,
+						 int cdata);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseExternalID	(xmlParserCtxtPtr ctxt,
+						 xmlChar **publicID,
+						 int strict);
+XMLPUBFUN void XMLCALL			
+			xmlParseComment		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlParsePITarget	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParsePI		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseNotationDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseEntityDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			
+			xmlParseDefaultDecl	(xmlParserCtxtPtr ctxt,
+						 xmlChar **value);
+XMLPUBFUN xmlEnumerationPtr XMLCALL	
+			xmlParseNotationType	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlEnumerationPtr XMLCALL	
+			xmlParseEnumerationType	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			
+			xmlParseEnumeratedType	(xmlParserCtxtPtr ctxt,
+						 xmlEnumerationPtr *tree);
+XMLPUBFUN int XMLCALL			
+			xmlParseAttributeType	(xmlParserCtxtPtr ctxt,
+						 xmlEnumerationPtr *tree);
+XMLPUBFUN void XMLCALL			
+			xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlElementContentPtr XMLCALL	
+			xmlParseElementMixedContentDecl
+						(xmlParserCtxtPtr ctxt,
+						 int inputchk);
+XMLPUBFUN xmlElementContentPtr XMLCALL	
+			xmlParseElementChildrenContentDecl
+						(xmlParserCtxtPtr ctxt,
+						 int inputchk);
+XMLPUBFUN int XMLCALL			
+			xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,
+						 const xmlChar *name,
+						 xmlElementContentPtr *result);
+XMLPUBFUN int XMLCALL			
+			xmlParseElementDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseMarkupDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			
+			xmlParseCharRef		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlEntityPtr XMLCALL		
+			xmlParseEntityRef	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseReference	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParsePEReference	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseDocTypeDecl	(xmlParserCtxtPtr ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlParseAttribute	(xmlParserCtxtPtr ctxt,
+						 xmlChar **value);
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlParseStartTag	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseEndTag		(xmlParserCtxtPtr ctxt);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN void XMLCALL			
+			xmlParseCDSect		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseContent		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseElement		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseVersionNum	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseVersionInfo	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseEncName		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN const xmlChar * XMLCALL		
+			xmlParseEncodingDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			
+			xmlParseSDDecl		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseXMLDecl		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseTextDecl	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseMisc		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			
+			xmlParseExternalSubset	(xmlParserCtxtPtr ctxt,
+						 const xmlChar *ExternalID,
+						 const xmlChar *SystemID); 
+/**
+ * XML_SUBSTITUTE_NONE:
+ *
+ * If no entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_NONE	0
+/**
+ * XML_SUBSTITUTE_REF:
+ *
+ * Whether general entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_REF	1
+/**
+ * XML_SUBSTITUTE_PEREF:
+ *
+ * Whether parameter entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_PEREF	2
+/**
+ * XML_SUBSTITUTE_BOTH:
+ *
+ * Both general and parameter entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_BOTH 	3
+
+XMLPUBFUN xmlChar * XMLCALL
+		xmlStringDecodeEntities		(xmlParserCtxtPtr ctxt,
+						 const xmlChar *str,
+						 int what,
+						 xmlChar end,
+						 xmlChar  end2,
+						 xmlChar end3);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlStringLenDecodeEntities	(xmlParserCtxtPtr ctxt,
+						 const xmlChar *str,
+						 int len,
+						 int what,
+						 xmlChar end,
+						 xmlChar  end2,
+						 xmlChar end3);
+
+/*
+ * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP.
+ */
+XMLPUBFUN int XMLCALL			nodePush		(xmlParserCtxtPtr ctxt,
+						 xmlNodePtr value);
+XMLPUBFUN xmlNodePtr XMLCALL		nodePop			(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			inputPush		(xmlParserCtxtPtr ctxt,
+						 xmlParserInputPtr value);
+XMLPUBFUN xmlParserInputPtr XMLCALL	inputPop		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN const xmlChar * XMLCALL	namePop			(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			namePush		(xmlParserCtxtPtr ctxt,
+						 const xmlChar *value);
+
+/*
+ * other commodities shared between parser.c and parserInternals.
+ */
+XMLPUBFUN int XMLCALL			xmlSkipBlankChars	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			xmlStringCurrentChar	(xmlParserCtxtPtr ctxt,
+						 const xmlChar *cur,
+						 int *len);
+XMLPUBFUN void XMLCALL			xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			xmlCheckLanguageID	(const xmlChar *lang);
+
+/*
+ * Really core function shared with HTML parser.
+ */
+XMLPUBFUN int XMLCALL			xmlCurrentChar		(xmlParserCtxtPtr ctxt,
+						 int *len);
+XMLPUBFUN int XMLCALL		xmlCopyCharMultiByte	(xmlChar *out,
+						 int val);
+XMLPUBFUN int XMLCALL			xmlCopyChar		(int len,
+						 xmlChar *out,
+						 int val);
+XMLPUBFUN void XMLCALL			xmlNextChar		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL			xmlParserInputShrink	(xmlParserInputPtr in);
+
+#ifdef LIBXML_HTML_ENABLED
+/*
+ * Actually comes from the HTML parser but launched from the init stuff.
+ */
+XMLPUBFUN void XMLCALL			htmlInitAutoClose	(void);
+XMLPUBFUN htmlParserCtxtPtr XMLCALL	htmlCreateFileParserCtxt(const char *filename,
+	                                         const char *encoding);
+#endif
+
+/*
+ * Specific function to keep track of entities references
+ * and used by the XSLT debugger.
+ */
+#ifdef LIBXML_LEGACY_ENABLED
+/**
+ * xmlEntityReferenceFunc:
+ * @ent: the entity
+ * @firstNode:  the fist node in the chunk
+ * @lastNode:  the last nod in the chunk
+ *
+ * Callback function used when one needs to be able to track back the
+ * provenance of a chunk of nodes inherited from an entity replacement.
+ */
+typedef	void	(*xmlEntityReferenceFunc)	(xmlEntityPtr ent,
+						 xmlNodePtr firstNode,
+						 xmlNodePtr lastNode);
+  
+XMLPUBFUN void XMLCALL		xmlSetEntityReferenceFunc	(xmlEntityReferenceFunc func);
+
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlParseQuotedString	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL
+                        xmlParseNamespace       (xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlNamespaceParseNSDef	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlScanName		(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlNamespaceParseNCName	(xmlParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL	xmlParserHandleReference(xmlParserCtxtPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL		
+			xmlNamespaceParseQName	(xmlParserCtxtPtr ctxt,
+						 xmlChar **prefix);
+/**
+ * Entities
+ */
+XMLPUBFUN xmlChar * XMLCALL
+		xmlDecodeEntities		(xmlParserCtxtPtr ctxt,
+						 int len,
+						 int what,
+						 xmlChar end,
+						 xmlChar  end2,
+						 xmlChar end3);
+XMLPUBFUN void XMLCALL			
+			xmlHandleEntity		(xmlParserCtxtPtr ctxt,
+						 xmlEntityPtr entity);
+
+#endif /* LIBXML_LEGACY_ENABLED */
+
+#ifdef IN_LIBXML
+/*
+ * internal only
+ */
+XMLPUBFUN void XMLCALL
+	xmlErrMemory		(xmlParserCtxtPtr ctxt,
+				 const char *extra);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_INTERNALS_H__ */
diff --git a/src/include/libxml/pattern.h b/src/include/libxml/pattern.h
new file mode 100644
index 0000000..97d2cd2
--- /dev/null
+++ b/src/include/libxml/pattern.h
@@ -0,0 +1,100 @@
+/*
+ * Summary: pattern expression handling
+ * Description: allows to compile and test pattern expressions for nodes
+ *              either in a tree or based on a parser state.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_PATTERN_H__
+#define __XML_PATTERN_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/dict.h>
+
+#ifdef LIBXML_PATTERN_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlPattern:
+ *
+ * A compiled (XPath based) pattern to select nodes
+ */
+typedef struct _xmlPattern xmlPattern;
+typedef xmlPattern *xmlPatternPtr;
+
+/**
+ * xmlPatternFlags:
+ *
+ * This is the set of options affecting the behaviour of pattern
+ * matching with this module
+ *
+ */
+typedef enum {
+    XML_PATTERN_DEFAULT		= 0,	/* simple pattern match */
+    XML_PATTERN_XPATH		= 1<<0,	/* standard XPath pattern */
+    XML_PATTERN_XSSEL		= 1<<1,	/* XPath subset for schema selector */
+    XML_PATTERN_XSFIELD		= 1<<2	/* XPath subset for schema field */
+} xmlPatternFlags;
+
+XMLPUBFUN void XMLCALL
+			xmlFreePattern		(xmlPatternPtr comp);
+
+XMLPUBFUN void XMLCALL
+			xmlFreePatternList	(xmlPatternPtr comp);
+
+XMLPUBFUN xmlPatternPtr XMLCALL
+			xmlPatterncompile	(const xmlChar *pattern,
+						 xmlDict *dict,
+						 int flags,
+						 const xmlChar **namespaces);
+XMLPUBFUN int XMLCALL
+			xmlPatternMatch		(xmlPatternPtr comp,
+						 xmlNodePtr node);
+
+/* streaming interfaces */
+typedef struct _xmlStreamCtxt xmlStreamCtxt;
+typedef xmlStreamCtxt *xmlStreamCtxtPtr;
+
+XMLPUBFUN int XMLCALL
+			xmlPatternStreamable	(xmlPatternPtr comp);
+XMLPUBFUN int XMLCALL
+			xmlPatternMaxDepth	(xmlPatternPtr comp);
+XMLPUBFUN int XMLCALL
+			xmlPatternMinDepth	(xmlPatternPtr comp);
+XMLPUBFUN int XMLCALL
+			xmlPatternFromRoot	(xmlPatternPtr comp);
+XMLPUBFUN xmlStreamCtxtPtr XMLCALL
+			xmlPatternGetStreamCtxt	(xmlPatternPtr comp);
+XMLPUBFUN void XMLCALL
+			xmlFreeStreamCtxt	(xmlStreamCtxtPtr stream);
+XMLPUBFUN int XMLCALL
+			xmlStreamPushNode	(xmlStreamCtxtPtr stream,
+						 const xmlChar *name,
+						 const xmlChar *ns,
+						 int nodeType);
+XMLPUBFUN int XMLCALL
+			xmlStreamPush		(xmlStreamCtxtPtr stream,
+						 const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int XMLCALL
+			xmlStreamPushAttr	(xmlStreamCtxtPtr stream,
+						 const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int XMLCALL
+			xmlStreamPop		(xmlStreamCtxtPtr stream);
+XMLPUBFUN int XMLCALL
+			xmlStreamWantsAnyNode	(xmlStreamCtxtPtr stream);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_PATTERN_ENABLED */
+
+#endif /* __XML_PATTERN_H__ */
diff --git a/src/include/libxml/relaxng.h b/src/include/libxml/relaxng.h
new file mode 100644
index 0000000..bdb0a7d
--- /dev/null
+++ b/src/include/libxml/relaxng.h
@@ -0,0 +1,213 @@
+/*
+ * Summary: implementation of the Relax-NG validation
+ * Description: implementation of the Relax-NG validation
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_RELAX_NG__
+#define __XML_RELAX_NG__
+
+#include <libxml/xmlversion.h>
+#include <libxml/hash.h>
+#include <libxml/xmlstring.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _xmlRelaxNG xmlRelaxNG;
+typedef xmlRelaxNG *xmlRelaxNGPtr;
+
+
+/**
+ * xmlRelaxNGValidityErrorFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of an error callback from a Relax-NG validation
+ */
+typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * xmlRelaxNGValidityWarningFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of a warning callback from a Relax-NG validation
+ */
+typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * A schemas validation context
+ */
+typedef struct _xmlRelaxNGParserCtxt xmlRelaxNGParserCtxt;
+typedef xmlRelaxNGParserCtxt *xmlRelaxNGParserCtxtPtr;
+
+typedef struct _xmlRelaxNGValidCtxt xmlRelaxNGValidCtxt;
+typedef xmlRelaxNGValidCtxt *xmlRelaxNGValidCtxtPtr;
+
+/*
+ * xmlRelaxNGValidErr:
+ *
+ * List of possible Relax NG validation errors
+ */
+typedef enum {
+    XML_RELAXNG_OK = 0,
+    XML_RELAXNG_ERR_MEMORY,
+    XML_RELAXNG_ERR_TYPE,
+    XML_RELAXNG_ERR_TYPEVAL,
+    XML_RELAXNG_ERR_DUPID,
+    XML_RELAXNG_ERR_TYPECMP,
+    XML_RELAXNG_ERR_NOSTATE,
+    XML_RELAXNG_ERR_NODEFINE,
+    XML_RELAXNG_ERR_LISTEXTRA,
+    XML_RELAXNG_ERR_LISTEMPTY,
+    XML_RELAXNG_ERR_INTERNODATA,
+    XML_RELAXNG_ERR_INTERSEQ,
+    XML_RELAXNG_ERR_INTEREXTRA,
+    XML_RELAXNG_ERR_ELEMNAME,
+    XML_RELAXNG_ERR_ATTRNAME,
+    XML_RELAXNG_ERR_ELEMNONS,
+    XML_RELAXNG_ERR_ATTRNONS,
+    XML_RELAXNG_ERR_ELEMWRONGNS,
+    XML_RELAXNG_ERR_ATTRWRONGNS,
+    XML_RELAXNG_ERR_ELEMEXTRANS,
+    XML_RELAXNG_ERR_ATTREXTRANS,
+    XML_RELAXNG_ERR_ELEMNOTEMPTY,
+    XML_RELAXNG_ERR_NOELEM,
+    XML_RELAXNG_ERR_NOTELEM,
+    XML_RELAXNG_ERR_ATTRVALID,
+    XML_RELAXNG_ERR_CONTENTVALID,
+    XML_RELAXNG_ERR_EXTRACONTENT,
+    XML_RELAXNG_ERR_INVALIDATTR,
+    XML_RELAXNG_ERR_DATAELEM,
+    XML_RELAXNG_ERR_VALELEM,
+    XML_RELAXNG_ERR_LISTELEM,
+    XML_RELAXNG_ERR_DATATYPE,
+    XML_RELAXNG_ERR_VALUE,
+    XML_RELAXNG_ERR_LIST,
+    XML_RELAXNG_ERR_NOGRAMMAR,
+    XML_RELAXNG_ERR_EXTRADATA,
+    XML_RELAXNG_ERR_LACKDATA,
+    XML_RELAXNG_ERR_INTERNAL,
+    XML_RELAXNG_ERR_ELEMWRONG,
+    XML_RELAXNG_ERR_TEXTWRONG
+} xmlRelaxNGValidErr;
+
+/*
+ * xmlRelaxNGParserFlags:
+ *
+ * List of possible Relax NG Parser flags
+ */
+typedef enum {
+    XML_RELAXNGP_NONE = 0,
+    XML_RELAXNGP_FREE_DOC = 1,
+    XML_RELAXNGP_CRNG = 2
+} xmlRelaxNGParserFlag;
+
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGInitTypes		(void);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGCleanupTypes	(void);
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlRelaxNGParserCtxtPtr XMLCALL
+		    xmlRelaxNGNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlRelaxNGParserCtxtPtr XMLCALL
+		    xmlRelaxNGNewMemParserCtxt	(const char *buffer,
+						 int size);
+XMLPUBFUN xmlRelaxNGParserCtxtPtr XMLCALL
+		    xmlRelaxNGNewDocParserCtxt	(xmlDocPtr doc);
+
+XMLPUBFUN int XMLCALL
+		    xmlRelaxParserSetFlag	(xmlRelaxNGParserCtxtPtr ctxt,
+						 int flag);
+
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGFreeParserCtxt	(xmlRelaxNGParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
+					 xmlRelaxNGValidityErrorFunc err,
+					 xmlRelaxNGValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
+					 xmlRelaxNGValidityErrorFunc *err,
+					 xmlRelaxNGValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGSetParserStructuredErrors(
+					 xmlRelaxNGParserCtxtPtr ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN xmlRelaxNGPtr XMLCALL
+		    xmlRelaxNGParse		(xmlRelaxNGParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGFree		(xmlRelaxNGPtr schema);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGDump		(FILE *output,
+					 xmlRelaxNGPtr schema);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGDumpTree	(FILE * output,
+					 xmlRelaxNGPtr schema);
+#endif /* LIBXML_OUTPUT_ENABLED */
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
+					 xmlRelaxNGValidityErrorFunc err,
+					 xmlRelaxNGValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
+					 xmlRelaxNGValidityErrorFunc *err,
+					 xmlRelaxNGValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN void XMLCALL
+			xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
+					  xmlStructuredErrorFunc serror, void *ctx);
+XMLPUBFUN xmlRelaxNGValidCtxtPtr XMLCALL
+		    xmlRelaxNGNewValidCtxt	(xmlRelaxNGPtr schema);
+XMLPUBFUN void XMLCALL
+		    xmlRelaxNGFreeValidCtxt	(xmlRelaxNGValidCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGValidateDoc	(xmlRelaxNGValidCtxtPtr ctxt,
+						 xmlDocPtr doc);
+/*
+ * Interfaces for progressive validation when possible
+ */
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGValidatePushElement	(xmlRelaxNGValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGValidatePushCData	(xmlRelaxNGValidCtxtPtr ctxt,
+					 const xmlChar *data,
+					 int len);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGValidatePopElement	(xmlRelaxNGValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem);
+XMLPUBFUN int XMLCALL
+		    xmlRelaxNGValidateFullElement	(xmlRelaxNGValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+
+#endif /* __XML_RELAX_NG__ */
diff --git a/src/include/libxml/schemasInternals.h b/src/include/libxml/schemasInternals.h
new file mode 100644
index 0000000..b68a6e1
--- /dev/null
+++ b/src/include/libxml/schemasInternals.h
@@ -0,0 +1,958 @@
+/*
+ * Summary: internal interfaces for XML Schemas
+ * Description: internal interfaces for the XML Schemas handling
+ *              and schema validity checking
+ *		The Schemas development is a Work In Progress.
+ *              Some of those interfaces are not garanteed to be API or ABI stable !
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_INTERNALS_H__
+#define __XML_SCHEMA_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/xmlregexp.h>
+#include <libxml/hash.h>
+#include <libxml/dict.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    XML_SCHEMAS_UNKNOWN = 0,
+    XML_SCHEMAS_STRING,
+    XML_SCHEMAS_NORMSTRING,
+    XML_SCHEMAS_DECIMAL,
+    XML_SCHEMAS_TIME,
+    XML_SCHEMAS_GDAY,
+    XML_SCHEMAS_GMONTH,
+    XML_SCHEMAS_GMONTHDAY,
+    XML_SCHEMAS_GYEAR,
+    XML_SCHEMAS_GYEARMONTH,
+    XML_SCHEMAS_DATE,
+    XML_SCHEMAS_DATETIME,
+    XML_SCHEMAS_DURATION,
+    XML_SCHEMAS_FLOAT,
+    XML_SCHEMAS_DOUBLE,
+    XML_SCHEMAS_BOOLEAN,
+    XML_SCHEMAS_TOKEN,
+    XML_SCHEMAS_LANGUAGE,
+    XML_SCHEMAS_NMTOKEN,
+    XML_SCHEMAS_NMTOKENS,
+    XML_SCHEMAS_NAME,
+    XML_SCHEMAS_QNAME,
+    XML_SCHEMAS_NCNAME,
+    XML_SCHEMAS_ID,
+    XML_SCHEMAS_IDREF,
+    XML_SCHEMAS_IDREFS,
+    XML_SCHEMAS_ENTITY,
+    XML_SCHEMAS_ENTITIES,
+    XML_SCHEMAS_NOTATION,
+    XML_SCHEMAS_ANYURI,
+    XML_SCHEMAS_INTEGER,
+    XML_SCHEMAS_NPINTEGER,
+    XML_SCHEMAS_NINTEGER,
+    XML_SCHEMAS_NNINTEGER,
+    XML_SCHEMAS_PINTEGER,
+    XML_SCHEMAS_INT,
+    XML_SCHEMAS_UINT,
+    XML_SCHEMAS_LONG,
+    XML_SCHEMAS_ULONG,
+    XML_SCHEMAS_SHORT,
+    XML_SCHEMAS_USHORT,
+    XML_SCHEMAS_BYTE,
+    XML_SCHEMAS_UBYTE,
+    XML_SCHEMAS_HEXBINARY,
+    XML_SCHEMAS_BASE64BINARY,
+    XML_SCHEMAS_ANYTYPE,
+    XML_SCHEMAS_ANYSIMPLETYPE
+} xmlSchemaValType;
+
+/*
+ * XML Schemas defines multiple type of types.
+ */
+typedef enum {
+    XML_SCHEMA_TYPE_BASIC = 1, /* A built-in datatype */
+    XML_SCHEMA_TYPE_ANY,
+    XML_SCHEMA_TYPE_FACET,
+    XML_SCHEMA_TYPE_SIMPLE,
+    XML_SCHEMA_TYPE_COMPLEX,
+    XML_SCHEMA_TYPE_SEQUENCE = 6,
+    XML_SCHEMA_TYPE_CHOICE,
+    XML_SCHEMA_TYPE_ALL,
+    XML_SCHEMA_TYPE_SIMPLE_CONTENT,
+    XML_SCHEMA_TYPE_COMPLEX_CONTENT,
+    XML_SCHEMA_TYPE_UR,
+    XML_SCHEMA_TYPE_RESTRICTION,
+    XML_SCHEMA_TYPE_EXTENSION,
+    XML_SCHEMA_TYPE_ELEMENT,
+    XML_SCHEMA_TYPE_ATTRIBUTE,
+    XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
+    XML_SCHEMA_TYPE_GROUP,
+    XML_SCHEMA_TYPE_NOTATION,
+    XML_SCHEMA_TYPE_LIST,
+    XML_SCHEMA_TYPE_UNION,
+    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+    XML_SCHEMA_TYPE_IDC_UNIQUE,
+    XML_SCHEMA_TYPE_IDC_KEY,
+    XML_SCHEMA_TYPE_IDC_KEYREF,
+    XML_SCHEMA_TYPE_PARTICLE = 25, 
+    XML_SCHEMA_TYPE_ATTRIBUTE_USE, 
+    XML_SCHEMA_FACET_MININCLUSIVE = 1000,
+    XML_SCHEMA_FACET_MINEXCLUSIVE,
+    XML_SCHEMA_FACET_MAXINCLUSIVE,
+    XML_SCHEMA_FACET_MAXEXCLUSIVE,
+    XML_SCHEMA_FACET_TOTALDIGITS,
+    XML_SCHEMA_FACET_FRACTIONDIGITS,
+    XML_SCHEMA_FACET_PATTERN,
+    XML_SCHEMA_FACET_ENUMERATION,
+    XML_SCHEMA_FACET_WHITESPACE,
+    XML_SCHEMA_FACET_LENGTH,
+    XML_SCHEMA_FACET_MAXLENGTH,
+    XML_SCHEMA_FACET_MINLENGTH,
+    XML_SCHEMA_EXTRA_QNAMEREF = 2000,
+    XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
+} xmlSchemaTypeType;
+
+typedef enum {
+    XML_SCHEMA_CONTENT_UNKNOWN = 0,
+    XML_SCHEMA_CONTENT_EMPTY = 1,
+    XML_SCHEMA_CONTENT_ELEMENTS,
+    XML_SCHEMA_CONTENT_MIXED,
+    XML_SCHEMA_CONTENT_SIMPLE,
+    XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS, /* Obsolete */
+    XML_SCHEMA_CONTENT_BASIC,
+    XML_SCHEMA_CONTENT_ANY
+} xmlSchemaContentType;
+
+typedef struct _xmlSchemaVal xmlSchemaVal;
+typedef xmlSchemaVal *xmlSchemaValPtr;
+
+typedef struct _xmlSchemaType xmlSchemaType;
+typedef xmlSchemaType *xmlSchemaTypePtr;
+
+typedef struct _xmlSchemaFacet xmlSchemaFacet;
+typedef xmlSchemaFacet *xmlSchemaFacetPtr;
+
+/**
+ * Annotation
+ */
+typedef struct _xmlSchemaAnnot xmlSchemaAnnot;
+typedef xmlSchemaAnnot *xmlSchemaAnnotPtr;
+struct _xmlSchemaAnnot {
+    struct _xmlSchemaAnnot *next;
+    xmlNodePtr content;         /* the annotation */
+};
+
+/**
+ * XML_SCHEMAS_ANYATTR_SKIP:
+ *
+ * Skip unknown attribute from validation
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_SKIP        1
+/**
+ * XML_SCHEMAS_ANYATTR_LAX:
+ *
+ * Ignore validation non definition on attributes
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_LAX                2
+/**
+ * XML_SCHEMAS_ANYATTR_STRICT:
+ *
+ * Apply strict validation rules on attributes
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_STRICT        3
+/**
+ * XML_SCHEMAS_ANY_SKIP:
+ *
+ * Skip unknown attribute from validation
+ */
+#define XML_SCHEMAS_ANY_SKIP        1
+/**
+ * XML_SCHEMAS_ANY_LAX:
+ *
+ * Used by wildcards.
+ * Validate if type found, don't worry if not found
+ */
+#define XML_SCHEMAS_ANY_LAX                2
+/**
+ * XML_SCHEMAS_ANY_STRICT:
+ *
+ * Used by wildcards.
+ * Apply strict validation rules
+ */
+#define XML_SCHEMAS_ANY_STRICT        3
+/**
+ * XML_SCHEMAS_ATTR_USE_PROHIBITED:
+ *
+ * Used by wildcards.
+ * The attribute is prohibited.
+ */
+#define XML_SCHEMAS_ATTR_USE_PROHIBITED 0
+/**
+ * XML_SCHEMAS_ATTR_USE_REQUIRED:
+ *
+ * The attribute is required.
+ */
+#define XML_SCHEMAS_ATTR_USE_REQUIRED 1
+/**
+ * XML_SCHEMAS_ATTR_USE_OPTIONAL:
+ *
+ * The attribute is optional.
+ */
+#define XML_SCHEMAS_ATTR_USE_OPTIONAL 2
+/**
+ * XML_SCHEMAS_ATTR_GLOBAL:
+ *
+ * allow elements in no namespace
+ */
+#define XML_SCHEMAS_ATTR_GLOBAL        1 << 0
+/**
+ * XML_SCHEMAS_ATTR_NSDEFAULT:
+ *
+ * allow elements in no namespace
+ */
+#define XML_SCHEMAS_ATTR_NSDEFAULT        1 << 7
+/**
+ * XML_SCHEMAS_ATTR_INTERNAL_RESOLVED:
+ *
+ * this is set when the "type" and "ref" references
+ * have been resolved.
+ */
+#define XML_SCHEMAS_ATTR_INTERNAL_RESOLVED        1 << 8
+/**
+ * XML_SCHEMAS_ATTR_FIXED:
+ *
+ * the attribute has a fixed value
+ */
+#define XML_SCHEMAS_ATTR_FIXED        1 << 9
+
+/**
+ * xmlSchemaAttribute:
+ * An attribute definition.
+ */
+
+typedef struct _xmlSchemaAttribute xmlSchemaAttribute;
+typedef xmlSchemaAttribute *xmlSchemaAttributePtr;
+struct _xmlSchemaAttribute {
+    xmlSchemaTypeType type;
+    struct _xmlSchemaAttribute *next; /* the next attribute (not used?) */
+    const xmlChar *name; /* the name of the declaration */
+    const xmlChar *id; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    const xmlChar *typeName; /* the local name of the type definition */
+    const xmlChar *typeNs; /* the ns URI of the type definition */
+    xmlSchemaAnnotPtr annot;
+
+    xmlSchemaTypePtr base; /* Deprecated; not used */
+    int occurs; /* Deprecated; not used */
+    const xmlChar *defValue; /* The initial value of the value constraint */
+    xmlSchemaTypePtr subtypes; /* the type definition */
+    xmlNodePtr node;
+    const xmlChar *targetNamespace;
+    int flags;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaValPtr defVal; /* The compiled value constraint */
+    xmlSchemaAttributePtr refDecl; /* Deprecated; not used */
+};
+
+/**
+ * xmlSchemaAttributeLink:
+ * Used to build a list of attribute uses on complexType definitions.
+ * WARNING: Deprecated; not used.
+ */
+typedef struct _xmlSchemaAttributeLink xmlSchemaAttributeLink;
+typedef xmlSchemaAttributeLink *xmlSchemaAttributeLinkPtr;
+struct _xmlSchemaAttributeLink {
+    struct _xmlSchemaAttributeLink *next;/* the next attribute link ... */
+    struct _xmlSchemaAttribute *attr;/* the linked attribute */
+};
+
+/**
+ * XML_SCHEMAS_WILDCARD_COMPLETE:
+ *
+ * If the wildcard is complete.
+ */
+#define XML_SCHEMAS_WILDCARD_COMPLETE 1 << 0
+
+/**
+ * xmlSchemaCharValueLink:
+ * Used to build a list of namespaces on wildcards.
+ */
+typedef struct _xmlSchemaWildcardNs xmlSchemaWildcardNs;
+typedef xmlSchemaWildcardNs *xmlSchemaWildcardNsPtr;
+struct _xmlSchemaWildcardNs {
+    struct _xmlSchemaWildcardNs *next;/* the next constraint link ... */
+    const xmlChar *value;/* the value */
+};
+
+/**
+ * xmlSchemaWildcard.
+ * A wildcard.
+ */
+typedef struct _xmlSchemaWildcard xmlSchemaWildcard;
+typedef xmlSchemaWildcard *xmlSchemaWildcardPtr;
+struct _xmlSchemaWildcard {
+    xmlSchemaTypeType type;        /* The kind of type */
+    const xmlChar *id; /* Deprecated; not used */
+    xmlSchemaAnnotPtr annot;
+    xmlNodePtr node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+    int processContents;
+    int any; /* Indicates if the ns constraint is of ##any */
+    xmlSchemaWildcardNsPtr nsSet; /* The list of allowed namespaces */
+    xmlSchemaWildcardNsPtr negNsSet; /* The negated namespace */
+    int flags;
+};
+
+/**
+ * XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED:
+ *
+ * The attribute wildcard has been already builded.
+ */
+#define XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED 1 << 0
+/**
+ * XML_SCHEMAS_ATTRGROUP_GLOBAL:
+ *
+ * The attribute wildcard has been already builded.
+ */
+#define XML_SCHEMAS_ATTRGROUP_GLOBAL 1 << 1
+/**
+ * XML_SCHEMAS_ATTRGROUP_MARKED:
+ *
+ * Marks the attr group as marked; used for circular checks.
+ */
+#define XML_SCHEMAS_ATTRGROUP_MARKED 1 << 2
+
+/**
+ * XML_SCHEMAS_ATTRGROUP_REDEFINED:
+ *
+ * The attr group was redefined.
+ */
+#define XML_SCHEMAS_ATTRGROUP_REDEFINED 1 << 3
+/**
+ * XML_SCHEMAS_ATTRGROUP_HAS_REFS:
+ *
+ * Whether this attr. group contains attr. group references.
+ */
+#define XML_SCHEMAS_ATTRGROUP_HAS_REFS 1 << 4
+
+/**
+ * An attribute group definition.
+ *
+ * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures
+ * must be kept similar
+ */
+typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup;
+typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr;
+struct _xmlSchemaAttributeGroup {
+    xmlSchemaTypeType type;        /* The kind of type */
+    struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
+    const xmlChar *name;
+    const xmlChar *id;
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnotPtr annot;
+
+    xmlSchemaAttributePtr attributes; /* Deprecated; not used */
+    xmlNodePtr node;
+    int flags;
+    xmlSchemaWildcardPtr attributeWildcard;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaAttributeGroupPtr refItem; /* Deprecated; not used */
+    const xmlChar *targetNamespace;
+    void *attrUses;
+};
+
+/**
+ * xmlSchemaTypeLink:
+ * Used to build a list of types (e.g. member types of
+ * simpleType with variety "union").
+ */
+typedef struct _xmlSchemaTypeLink xmlSchemaTypeLink;
+typedef xmlSchemaTypeLink *xmlSchemaTypeLinkPtr;
+struct _xmlSchemaTypeLink {
+    struct _xmlSchemaTypeLink *next;/* the next type link ... */
+    xmlSchemaTypePtr type;/* the linked type */
+};
+
+/**
+ * xmlSchemaFacetLink:
+ * Used to build a list of facets.
+ */
+typedef struct _xmlSchemaFacetLink xmlSchemaFacetLink;
+typedef xmlSchemaFacetLink *xmlSchemaFacetLinkPtr;
+struct _xmlSchemaFacetLink {
+    struct _xmlSchemaFacetLink *next;/* the next facet link ... */
+    xmlSchemaFacetPtr facet;/* the linked facet */
+};
+
+/**
+ * XML_SCHEMAS_TYPE_MIXED:
+ *
+ * the element content type is mixed
+ */
+#define XML_SCHEMAS_TYPE_MIXED                1 << 0
+/**
+ * XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION:
+ *
+ * the simple or complex type has a derivation method of "extension".
+ */
+#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION                1 << 1
+/**
+ * XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION:
+ *
+ * the simple or complex type has a derivation method of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION                1 << 2
+/**
+ * XML_SCHEMAS_TYPE_GLOBAL:
+ *
+ * the type is global
+ */
+#define XML_SCHEMAS_TYPE_GLOBAL                1 << 3
+/**
+ * XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD:
+ *
+ * the complexType owns an attribute wildcard, i.e.
+ * it can be freed by the complexType
+ */
+#define XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD    1 << 4 /* Obsolete. */
+/**
+ * XML_SCHEMAS_TYPE_VARIETY_ABSENT:
+ *
+ * the simpleType has a variety of "absent".
+ * TODO: Actually not necessary :-/, since if
+ * none of the variety flags occur then it's
+ * automatically absent.
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_ABSENT    1 << 5
+/**
+ * XML_SCHEMAS_TYPE_VARIETY_LIST:
+ *
+ * the simpleType has a variety of "list".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_LIST    1 << 6
+/**
+ * XML_SCHEMAS_TYPE_VARIETY_UNION:
+ *
+ * the simpleType has a variety of "union".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_UNION    1 << 7
+/**
+ * XML_SCHEMAS_TYPE_VARIETY_ATOMIC:
+ *
+ * the simpleType has a variety of "union".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_ATOMIC    1 << 8
+/**
+ * XML_SCHEMAS_TYPE_FINAL_EXTENSION:
+ *
+ * the complexType has a final of "extension".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_EXTENSION    1 << 9
+/**
+ * XML_SCHEMAS_TYPE_FINAL_RESTRICTION:
+ *
+ * the simpleType/complexType has a final of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_RESTRICTION    1 << 10
+/**
+ * XML_SCHEMAS_TYPE_FINAL_LIST:
+ *
+ * the simpleType has a final of "list".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_LIST    1 << 11
+/**
+ * XML_SCHEMAS_TYPE_FINAL_UNION:
+ *
+ * the simpleType has a final of "union".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_UNION    1 << 12
+/**
+ * XML_SCHEMAS_TYPE_FINAL_DEFAULT:
+ *
+ * the simpleType has a final of "default".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_DEFAULT    1 << 13
+/**
+ * XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE:
+ *
+ * Marks the item as a builtin primitive.
+ */
+#define XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE    1 << 14
+/**
+ * XML_SCHEMAS_TYPE_MARKED:
+ *
+ * Marks the item as marked; used for circular checks.
+ */
+#define XML_SCHEMAS_TYPE_MARKED        1 << 16
+/**
+ * XML_SCHEMAS_TYPE_BLOCK_DEFAULT:
+ *
+ * the complexType did not specify 'block' so use the default of the
+ * <schema> item.
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_DEFAULT    1 << 17
+/**
+ * XML_SCHEMAS_TYPE_BLOCK_EXTENSION:
+ *
+ * the complexType has a 'block' of "extension".
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_EXTENSION    1 << 18
+/**
+ * XML_SCHEMAS_TYPE_BLOCK_RESTRICTION:
+ *
+ * the complexType has a 'block' of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_RESTRICTION    1 << 19
+/**
+ * XML_SCHEMAS_TYPE_ABSTRACT:
+ *
+ * the simple/complexType is abstract.
+ */
+#define XML_SCHEMAS_TYPE_ABSTRACT    1 << 20
+/**
+ * XML_SCHEMAS_TYPE_FACETSNEEDVALUE:
+ *
+ * indicates if the facets need a computed value
+ */
+#define XML_SCHEMAS_TYPE_FACETSNEEDVALUE    1 << 21
+/**
+ * XML_SCHEMAS_TYPE_INTERNAL_RESOLVED:
+ *
+ * indicates that the type was typefixed
+ */
+#define XML_SCHEMAS_TYPE_INTERNAL_RESOLVED    1 << 22
+/**
+ * XML_SCHEMAS_TYPE_INTERNAL_INVALID:
+ *
+ * indicates that the type is invalid
+ */
+#define XML_SCHEMAS_TYPE_INTERNAL_INVALID    1 << 23
+/**
+ * XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE:
+ *
+ * a whitespace-facet value of "preserve"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE    1 << 24
+/**
+ * XML_SCHEMAS_TYPE_WHITESPACE_REPLACE:
+ *
+ * a whitespace-facet value of "replace"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_REPLACE    1 << 25
+/**
+ * XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE:
+ *
+ * a whitespace-facet value of "collapse"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE    1 << 26
+/**
+ * XML_SCHEMAS_TYPE_HAS_FACETS:
+ *
+ * has facets
+ */
+#define XML_SCHEMAS_TYPE_HAS_FACETS    1 << 27
+/**
+ * XML_SCHEMAS_TYPE_NORMVALUENEEDED:
+ *
+ * indicates if the facets (pattern) need a normalized value
+ */
+#define XML_SCHEMAS_TYPE_NORMVALUENEEDED    1 << 28
+
+/**
+ * XML_SCHEMAS_TYPE_FIXUP_1:
+ *
+ * First stage of fixup was done.
+ */
+#define XML_SCHEMAS_TYPE_FIXUP_1    1 << 29
+
+/**
+ * XML_SCHEMAS_TYPE_REDEFINED:
+ *
+ * The type was redefined.
+ */
+#define XML_SCHEMAS_TYPE_REDEFINED    1 << 30
+/**
+ * XML_SCHEMAS_TYPE_REDEFINING:
+ *
+ * The type redefines an other type.
+ */
+/* #define XML_SCHEMAS_TYPE_REDEFINING    1 << 31 */
+
+/**
+ * _xmlSchemaType:
+ *
+ * Schemas type definition.
+ */
+struct _xmlSchemaType {
+    xmlSchemaTypeType type; /* The kind of type */
+    struct _xmlSchemaType *next; /* the next type if in a sequence ... */
+    const xmlChar *name;
+    const xmlChar *id ; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTypePtr subtypes;
+    xmlSchemaAttributePtr attributes; /* Deprecated; not used */
+    xmlNodePtr node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+
+    int flags;
+    xmlSchemaContentType contentType;
+    const xmlChar *base; /* Base type's local name */
+    const xmlChar *baseNs; /* Base type's target namespace */
+    xmlSchemaTypePtr baseType; /* The base type component */
+    xmlSchemaFacetPtr facets; /* Local facets */
+    struct _xmlSchemaType *redef; /* Deprecated; not used */
+    int recurse; /* Obsolete */
+    xmlSchemaAttributeLinkPtr *attributeUses; /* Deprecated; not used */
+    xmlSchemaWildcardPtr attributeWildcard;
+    int builtInType; /* Type of built-in types. */
+    xmlSchemaTypeLinkPtr memberTypes; /* member-types if a union type. */
+    xmlSchemaFacetLinkPtr facetSet; /* All facets (incl. inherited) */
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaTypePtr contentTypeDef; /* Used for the simple content of complex types.
+                                        Could we use @subtypes for this? */
+    xmlRegexpPtr contModel; /* Holds the automaton of the content model */
+    const xmlChar *targetNamespace;
+    void *attrUses;
+};
+
+/*
+ * xmlSchemaElement:
+ * An element definition.
+ *
+ * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of
+ * structures must be kept similar
+ */
+/**
+ * XML_SCHEMAS_ELEM_NILLABLE:
+ *
+ * the element is nillable
+ */
+#define XML_SCHEMAS_ELEM_NILLABLE        1 << 0
+/**
+ * XML_SCHEMAS_ELEM_GLOBAL:
+ *
+ * the element is global
+ */
+#define XML_SCHEMAS_ELEM_GLOBAL                1 << 1
+/**
+ * XML_SCHEMAS_ELEM_DEFAULT:
+ *
+ * the element has a default value
+ */
+#define XML_SCHEMAS_ELEM_DEFAULT        1 << 2
+/**
+ * XML_SCHEMAS_ELEM_FIXED:
+ *
+ * the element has a fixed value
+ */
+#define XML_SCHEMAS_ELEM_FIXED                1 << 3
+/**
+ * XML_SCHEMAS_ELEM_ABSTRACT:
+ *
+ * the element is abstract
+ */
+#define XML_SCHEMAS_ELEM_ABSTRACT        1 << 4
+/**
+ * XML_SCHEMAS_ELEM_TOPLEVEL:
+ *
+ * the element is top level
+ * obsolete: use XML_SCHEMAS_ELEM_GLOBAL instead
+ */
+#define XML_SCHEMAS_ELEM_TOPLEVEL        1 << 5
+/**
+ * XML_SCHEMAS_ELEM_REF:
+ *
+ * the element is a reference to a type
+ */
+#define XML_SCHEMAS_ELEM_REF                1 << 6
+/**
+ * XML_SCHEMAS_ELEM_NSDEFAULT:
+ *
+ * allow elements in no namespace
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ELEM_NSDEFAULT        1 << 7
+/**
+ * XML_SCHEMAS_ELEM_INTERNAL_RESOLVED:
+ *
+ * this is set when "type", "ref", "substitutionGroup"
+ * references have been resolved.
+ */
+#define XML_SCHEMAS_ELEM_INTERNAL_RESOLVED        1 << 8
+ /**
+ * XML_SCHEMAS_ELEM_CIRCULAR:
+ *
+ * a helper flag for the search of circular references.
+ */
+#define XML_SCHEMAS_ELEM_CIRCULAR        1 << 9
+/**
+ * XML_SCHEMAS_ELEM_BLOCK_ABSENT:
+ *
+ * the "block" attribute is absent
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_ABSENT        1 << 10
+/**
+ * XML_SCHEMAS_ELEM_BLOCK_EXTENSION:
+ *
+ * disallowed substitutions are absent
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_EXTENSION        1 << 11
+/**
+ * XML_SCHEMAS_ELEM_BLOCK_RESTRICTION:
+ *
+ * disallowed substitutions: "restriction"
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_RESTRICTION        1 << 12
+/**
+ * XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION:
+ *
+ * disallowed substitutions: "substituion"
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION        1 << 13
+/**
+ * XML_SCHEMAS_ELEM_FINAL_ABSENT:
+ *
+ * substitution group exclusions are absent
+ */
+#define XML_SCHEMAS_ELEM_FINAL_ABSENT        1 << 14
+/**
+ * XML_SCHEMAS_ELEM_FINAL_EXTENSION:
+ *
+ * substitution group exclusions: "extension"
+ */
+#define XML_SCHEMAS_ELEM_FINAL_EXTENSION        1 << 15
+/**
+ * XML_SCHEMAS_ELEM_FINAL_RESTRICTION:
+ *
+ * substitution group exclusions: "restriction"
+ */
+#define XML_SCHEMAS_ELEM_FINAL_RESTRICTION        1 << 16
+/**
+ * XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD:
+ *
+ * the declaration is a substitution group head
+ */
+#define XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD        1 << 17
+/**
+ * XML_SCHEMAS_ELEM_INTERNAL_CHECKED:
+ *
+ * this is set when the elem decl has been checked against
+ * all constraints
+ */
+#define XML_SCHEMAS_ELEM_INTERNAL_CHECKED        1 << 18
+
+typedef struct _xmlSchemaElement xmlSchemaElement;
+typedef xmlSchemaElement *xmlSchemaElementPtr;
+struct _xmlSchemaElement {
+    xmlSchemaTypeType type; /* The kind of type */
+    struct _xmlSchemaType *next; /* Not used? */
+    const xmlChar *name;
+    const xmlChar *id; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTypePtr subtypes; /* the type definition */
+    xmlSchemaAttributePtr attributes;
+    xmlNodePtr node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+
+    int flags;
+    const xmlChar *targetNamespace;
+    const xmlChar *namedType;
+    const xmlChar *namedTypeNs;
+    const xmlChar *substGroup;
+    const xmlChar *substGroupNs;
+    const xmlChar *scope;
+    const xmlChar *value; /* The original value of the value constraint. */
+    struct _xmlSchemaElement *refDecl; /* This will now be used for the
+                                          substitution group affiliation */
+    xmlRegexpPtr contModel; /* Obsolete for WXS, maybe used for RelaxNG */
+    xmlSchemaContentType contentType;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaValPtr defVal; /* The compiled value contraint. */
+    void *idcs; /* The identity-constraint defs */
+};
+
+/*
+ * XML_SCHEMAS_FACET_UNKNOWN:
+ *
+ * unknown facet handling
+ */
+#define XML_SCHEMAS_FACET_UNKNOWN        0
+/*
+ * XML_SCHEMAS_FACET_PRESERVE:
+ *
+ * preserve the type of the facet
+ */
+#define XML_SCHEMAS_FACET_PRESERVE        1
+/*
+ * XML_SCHEMAS_FACET_REPLACE:
+ *
+ * replace the type of the facet
+ */
+#define XML_SCHEMAS_FACET_REPLACE        2
+/*
+ * XML_SCHEMAS_FACET_COLLAPSE:
+ *
+ * collapse the types of the facet
+ */
+#define XML_SCHEMAS_FACET_COLLAPSE        3
+/**
+ * A facet definition.
+ */
+struct _xmlSchemaFacet {
+    xmlSchemaTypeType type;        /* The kind of type */
+    struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */
+    const xmlChar *value; /* The original value */
+    const xmlChar *id; /* Obsolete */
+    xmlSchemaAnnotPtr annot;
+    xmlNodePtr node;
+    int fixed; /* XML_SCHEMAS_FACET_PRESERVE, etc. */
+    int whitespace;
+    xmlSchemaValPtr val; /* The compiled value */
+    xmlRegexpPtr    regexp; /* The regex for patterns */
+};
+
+/**
+ * A notation definition.
+ */
+typedef struct _xmlSchemaNotation xmlSchemaNotation;
+typedef xmlSchemaNotation *xmlSchemaNotationPtr;
+struct _xmlSchemaNotation {
+    xmlSchemaTypeType type; /* The kind of type */
+    const xmlChar *name;
+    xmlSchemaAnnotPtr annot;
+    const xmlChar *identifier;
+    const xmlChar *targetNamespace;
+};
+
+/*
+* TODO: Actually all those flags used for the schema should sit
+* on the schema parser context, since they are used only
+* during parsing an XML schema document, and not available
+* on the component level as per spec.
+*/
+/**
+ * XML_SCHEMAS_QUALIF_ELEM:
+ *
+ * Reflects elementFormDefault == qualified in
+ * an XML schema document.
+ */
+#define XML_SCHEMAS_QUALIF_ELEM                1 << 0
+/**
+ * XML_SCHEMAS_QUALIF_ATTR:
+ *
+ * Reflects attributeFormDefault == qualified in
+ * an XML schema document.
+ */
+#define XML_SCHEMAS_QUALIF_ATTR            1 << 1
+/**
+ * XML_SCHEMAS_FINAL_DEFAULT_EXTENSION:
+ *
+ * the schema has "extension" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_EXTENSION        1 << 2
+/**
+ * XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION:
+ *
+ * the schema has "restriction" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION            1 << 3
+/**
+ * XML_SCHEMAS_FINAL_DEFAULT_LIST:
+ *
+ * the cshema has "list" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_LIST            1 << 4
+/**
+ * XML_SCHEMAS_FINAL_DEFAULT_UNION:
+ *
+ * the schema has "union" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_UNION            1 << 5
+/**
+ * XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION:
+ *
+ * the schema has "extension" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION            1 << 6
+/**
+ * XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION:
+ *
+ * the schema has "restriction" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION            1 << 7
+/**
+ * XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION:
+ *
+ * the schema has "substitution" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION            1 << 8
+/**
+ * XML_SCHEMAS_INCLUDING_CONVERT_NS:
+ *
+ * the schema is currently including an other schema with
+ * no target namespace.
+ */
+#define XML_SCHEMAS_INCLUDING_CONVERT_NS            1 << 9
+/**
+ * _xmlSchema:
+ *
+ * A Schemas definition
+ */
+struct _xmlSchema {
+    const xmlChar *name; /* schema name */
+    const xmlChar *targetNamespace; /* the target namespace */
+    const xmlChar *version;
+    const xmlChar *id; /* Obsolete */
+    xmlDocPtr doc;
+    xmlSchemaAnnotPtr annot;
+    int flags;
+
+    xmlHashTablePtr typeDecl;
+    xmlHashTablePtr attrDecl;
+    xmlHashTablePtr attrgrpDecl;
+    xmlHashTablePtr elemDecl;
+    xmlHashTablePtr notaDecl;
+
+    xmlHashTablePtr schemasImports;
+
+    void *_private;        /* unused by the library for users or bindings */
+    xmlHashTablePtr groupDecl;
+    xmlDictPtr      dict;
+    void *includes;     /* the includes, this is opaque for now */
+    int preserve;        /* whether to free the document */
+    int counter; /* used to give ononymous components unique names */
+    xmlHashTablePtr idcDef; /* All identity-constraint defs. */
+    void *volatiles; /* Obsolete */
+};
+
+XMLPUBFUN void XMLCALL         xmlSchemaFreeType        (xmlSchemaTypePtr type);
+XMLPUBFUN void XMLCALL         xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_INTERNALS_H__ */
diff --git a/src/include/libxml/schematron.h b/src/include/libxml/schematron.h
new file mode 100644
index 0000000..f442826
--- /dev/null
+++ b/src/include/libxml/schematron.h
@@ -0,0 +1,142 @@
+/*
+ * Summary: XML Schemastron implementation
+ * Description: interface to the XML Schematron validity checking.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMATRON_H__
+#define __XML_SCHEMATRON_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    XML_SCHEMATRON_OUT_QUIET = 1 << 0,	/* quiet no report */
+    XML_SCHEMATRON_OUT_TEXT = 1 << 1,	/* build a textual report */
+    XML_SCHEMATRON_OUT_XML = 1 << 2,	/* output SVRL */
+    XML_SCHEMATRON_OUT_ERROR = 1 << 3,  /* output via xmlStructuredErrorFunc */
+    XML_SCHEMATRON_OUT_FILE = 1 << 8,	/* output to a file descriptor */
+    XML_SCHEMATRON_OUT_BUFFER = 1 << 9,	/* output to a buffer */
+    XML_SCHEMATRON_OUT_IO = 1 << 10	/* output to I/O mechanism */
+} xmlSchematronValidOptions;
+
+/**
+ * The schemas related types are kept internal
+ */
+typedef struct _xmlSchematron xmlSchematron;
+typedef xmlSchematron *xmlSchematronPtr;
+
+/**
+ * xmlSchematronValidityErrorFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of an error callback from a Schematron validation
+ */
+typedef void (*xmlSchematronValidityErrorFunc) (void *ctx, const char *msg, ...);
+
+/**
+ * xmlSchematronValidityWarningFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of a warning callback from a Schematron validation
+ */
+typedef void (*xmlSchematronValidityWarningFunc) (void *ctx, const char *msg, ...);
+
+/**
+ * A schemas validation context
+ */
+typedef struct _xmlSchematronParserCtxt xmlSchematronParserCtxt;
+typedef xmlSchematronParserCtxt *xmlSchematronParserCtxtPtr;
+
+typedef struct _xmlSchematronValidCtxt xmlSchematronValidCtxt;
+typedef xmlSchematronValidCtxt *xmlSchematronValidCtxtPtr;
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlSchematronParserCtxtPtr XMLCALL 
+	    xmlSchematronNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlSchematronParserCtxtPtr XMLCALL 
+	    xmlSchematronNewMemParserCtxt(const char *buffer,
+					 int size);
+XMLPUBFUN xmlSchematronParserCtxtPtr XMLCALL
+	    xmlSchematronNewDocParserCtxt(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL		
+	    xmlSchematronFreeParserCtxt	(xmlSchematronParserCtxtPtr ctxt);
+/*****
+XMLPUBFUN void XMLCALL		
+	    xmlSchematronSetParserErrors(xmlSchematronParserCtxtPtr ctxt,
+					 xmlSchematronValidityErrorFunc err,
+					 xmlSchematronValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+		xmlSchematronGetParserErrors(xmlSchematronParserCtxtPtr ctxt,
+					xmlSchematronValidityErrorFunc * err,
+					xmlSchematronValidityWarningFunc * warn,
+					void **ctx);
+XMLPUBFUN int XMLCALL
+		xmlSchematronIsValid	(xmlSchematronValidCtxtPtr ctxt);
+ *****/
+XMLPUBFUN xmlSchematronPtr XMLCALL	
+	    xmlSchematronParse		(xmlSchematronParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL		
+	    xmlSchematronFree		(xmlSchematronPtr schema);
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void XMLCALL
+	    xmlSchematronSetValidStructuredErrors(
+	                                  xmlSchematronValidCtxtPtr ctxt,
+					  xmlStructuredErrorFunc serror,
+					  void *ctx);
+/******
+XMLPUBFUN void XMLCALL		
+	    xmlSchematronSetValidErrors	(xmlSchematronValidCtxtPtr ctxt,
+					 xmlSchematronValidityErrorFunc err,
+					 xmlSchematronValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+	    xmlSchematronGetValidErrors	(xmlSchematronValidCtxtPtr ctxt,
+					 xmlSchematronValidityErrorFunc *err,
+					 xmlSchematronValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN int XMLCALL
+	    xmlSchematronSetValidOptions(xmlSchematronValidCtxtPtr ctxt,
+					 int options);
+XMLPUBFUN int XMLCALL
+	    xmlSchematronValidCtxtGetOptions(xmlSchematronValidCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+            xmlSchematronValidateOneElement (xmlSchematronValidCtxtPtr ctxt,
+			                 xmlNodePtr elem);
+ *******/
+
+XMLPUBFUN xmlSchematronValidCtxtPtr XMLCALL	
+	    xmlSchematronNewValidCtxt	(xmlSchematronPtr schema,
+	    				 int options);
+XMLPUBFUN void XMLCALL			
+	    xmlSchematronFreeValidCtxt	(xmlSchematronValidCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL			
+	    xmlSchematronValidateDoc	(xmlSchematronValidCtxtPtr ctxt,
+					 xmlDocPtr instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMATRON_ENABLED */
+#endif /* __XML_SCHEMATRON_H__ */
diff --git a/src/include/libxml/threads.h b/src/include/libxml/threads.h
new file mode 100644
index 0000000..d31f16a
--- /dev/null
+++ b/src/include/libxml/threads.h
@@ -0,0 +1,84 @@
+/**
+ * Summary: interfaces for thread handling
+ * Description: set of generic threading related routines
+ *              should work with pthreads, Windows native or TLS threads
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_THREADS_H__
+#define __XML_THREADS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * xmlMutex are a simple mutual exception locks.
+ */
+typedef struct _xmlMutex xmlMutex;
+typedef xmlMutex *xmlMutexPtr;
+
+/*
+ * xmlRMutex are reentrant mutual exception locks.
+ */
+typedef struct _xmlRMutex xmlRMutex;
+typedef xmlRMutex *xmlRMutexPtr;
+
+#ifdef __cplusplus
+}
+#endif
+#include <libxml/globals.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+XMLPUBFUN xmlMutexPtr XMLCALL
+			xmlNewMutex	(void);
+XMLPUBFUN void XMLCALL
+			xmlMutexLock	(xmlMutexPtr tok);
+XMLPUBFUN void XMLCALL
+			xmlMutexUnlock	(xmlMutexPtr tok);
+XMLPUBFUN void XMLCALL
+			xmlFreeMutex	(xmlMutexPtr tok);
+
+XMLPUBFUN xmlRMutexPtr XMLCALL
+			xmlNewRMutex	(void);
+XMLPUBFUN void XMLCALL
+			xmlRMutexLock	(xmlRMutexPtr tok);
+XMLPUBFUN void XMLCALL
+			xmlRMutexUnlock	(xmlRMutexPtr tok);
+XMLPUBFUN void XMLCALL
+			xmlFreeRMutex	(xmlRMutexPtr tok);
+
+/*
+ * Library wide APIs.
+ */
+XMLPUBFUN void XMLCALL
+			xmlInitThreads	(void);
+XMLPUBFUN void XMLCALL
+			xmlLockLibrary	(void);
+XMLPUBFUN void XMLCALL
+			xmlUnlockLibrary(void);
+XMLPUBFUN int XMLCALL
+			xmlGetThreadId	(void);
+XMLPUBFUN int XMLCALL
+			xmlIsMainThread	(void);
+XMLPUBFUN void XMLCALL
+			xmlCleanupThreads(void);
+XMLPUBFUN xmlGlobalStatePtr XMLCALL
+			xmlGetGlobalState(void);
+
+#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC_FOR_DLL)
+int XMLCALL xmlDllMain(void *hinstDLL, unsigned long fdwReason, void *lpvReserved);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __XML_THREADS_H__ */
diff --git a/src/include/libxml/tree.h b/src/include/libxml/tree.h
new file mode 100644
index 0000000..8d93cba
--- /dev/null
+++ b/src/include/libxml/tree.h
@@ -0,0 +1,1253 @@
+/*
+ * Summary: interfaces for tree manipulation
+ * Description: this module describes the structures found in an tree resulting
+ *              from an XML or HTML parsing, as well as the API provided for
+ *              various processing on that tree
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Some of the basic types pointer to structures:
+ */
+/* xmlIO.h */
+typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
+typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
+
+typedef struct _xmlOutputBuffer xmlOutputBuffer;
+typedef xmlOutputBuffer *xmlOutputBufferPtr;
+
+/* parser.h */
+typedef struct _xmlParserInput xmlParserInput;
+typedef xmlParserInput *xmlParserInputPtr;
+
+typedef struct _xmlParserCtxt xmlParserCtxt;
+typedef xmlParserCtxt *xmlParserCtxtPtr;
+
+typedef struct _xmlSAXLocator xmlSAXLocator;
+typedef xmlSAXLocator *xmlSAXLocatorPtr;
+
+typedef struct _xmlSAXHandler xmlSAXHandler;
+typedef xmlSAXHandler *xmlSAXHandlerPtr;
+
+/* entities.h */
+typedef struct _xmlEntity xmlEntity;
+typedef xmlEntity *xmlEntityPtr;
+
+/**
+ * BASE_BUFFER_SIZE:
+ *
+ * default buffer size 4000.
+ */
+#define BASE_BUFFER_SIZE 4096
+
+/**
+ * LIBXML_NAMESPACE_DICT:
+ *
+ * Defines experimental behaviour:
+ * 1) xmlNs gets an additional field @context (a xmlDoc)
+ * 2) when creating a tree, xmlNs->href is stored in the dict of xmlDoc.
+ */
+/* #define LIBXML_NAMESPACE_DICT */
+
+/**
+ * xmlBufferAllocationScheme:
+ *
+ * A buffer allocation scheme can be defined to either match exactly the
+ * need or double it's allocated size each time it is found too small.
+ */
+
+typedef enum {
+    XML_BUFFER_ALLOC_DOUBLEIT,	/* double each time one need to grow */
+    XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
+    XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
+    XML_BUFFER_ALLOC_IO		/* special allocation scheme used for I/O */
+} xmlBufferAllocationScheme;
+
+/**
+ * xmlBuffer:
+ *
+ * A buffer structure.
+ */
+typedef struct _xmlBuffer xmlBuffer;
+typedef xmlBuffer *xmlBufferPtr;
+struct _xmlBuffer {
+    xmlChar *content;		/* The buffer content UTF8 */
+    unsigned int use;		/* The buffer size used */
+    unsigned int size;		/* The buffer size */
+    xmlBufferAllocationScheme alloc; /* The realloc method */
+    xmlChar *contentIO;		/* in IO mode we may have a different base */
+};
+
+/**
+ * XML_XML_NAMESPACE:
+ *
+ * This is the namespace for the special xml: prefix predefined in the
+ * XML Namespace specification.
+ */
+#define XML_XML_NAMESPACE \
+    (const xmlChar *) "http://www.w3.org/XML/1998/namespace"
+
+/**
+ * XML_XML_ID:
+ *
+ * This is the name for the special xml:id attribute
+ */
+#define XML_XML_ID (const xmlChar *) "xml:id"
+
+/*
+ * The different element types carried by an XML tree.
+ *
+ * NOTE: This is synchronized with DOM Level1 values
+ *       See http://www.w3.org/TR/REC-DOM-Level-1/
+ *
+ * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should
+ * be deprecated to use an XML_DTD_NODE.
+ */
+typedef enum {
+    XML_ELEMENT_NODE=		1,
+    XML_ATTRIBUTE_NODE=		2,
+    XML_TEXT_NODE=		3,
+    XML_CDATA_SECTION_NODE=	4,
+    XML_ENTITY_REF_NODE=	5,
+    XML_ENTITY_NODE=		6,
+    XML_PI_NODE=		7,
+    XML_COMMENT_NODE=		8,
+    XML_DOCUMENT_NODE=		9,
+    XML_DOCUMENT_TYPE_NODE=	10,
+    XML_DOCUMENT_FRAG_NODE=	11,
+    XML_NOTATION_NODE=		12,
+    XML_HTML_DOCUMENT_NODE=	13,
+    XML_DTD_NODE=		14,
+    XML_ELEMENT_DECL=		15,
+    XML_ATTRIBUTE_DECL=		16,
+    XML_ENTITY_DECL=		17,
+    XML_NAMESPACE_DECL=		18,
+    XML_XINCLUDE_START=		19,
+    XML_XINCLUDE_END=		20
+#ifdef LIBXML_DOCB_ENABLED
+   ,XML_DOCB_DOCUMENT_NODE=	21
+#endif
+} xmlElementType;
+
+
+/**
+ * xmlNotation:
+ *
+ * A DTD Notation definition.
+ */
+
+typedef struct _xmlNotation xmlNotation;
+typedef xmlNotation *xmlNotationPtr;
+struct _xmlNotation {
+    const xmlChar               *name;	        /* Notation name */
+    const xmlChar               *PublicID;	/* Public identifier, if any */
+    const xmlChar               *SystemID;	/* System identifier, if any */
+};
+
+/**
+ * xmlAttributeType:
+ *
+ * A DTD Attribute type definition.
+ */
+
+typedef enum {
+    XML_ATTRIBUTE_CDATA = 1,
+    XML_ATTRIBUTE_ID,
+    XML_ATTRIBUTE_IDREF	,
+    XML_ATTRIBUTE_IDREFS,
+    XML_ATTRIBUTE_ENTITY,
+    XML_ATTRIBUTE_ENTITIES,
+    XML_ATTRIBUTE_NMTOKEN,
+    XML_ATTRIBUTE_NMTOKENS,
+    XML_ATTRIBUTE_ENUMERATION,
+    XML_ATTRIBUTE_NOTATION
+} xmlAttributeType;
+
+/**
+ * xmlAttributeDefault:
+ *
+ * A DTD Attribute default definition.
+ */
+
+typedef enum {
+    XML_ATTRIBUTE_NONE = 1,
+    XML_ATTRIBUTE_REQUIRED,
+    XML_ATTRIBUTE_IMPLIED,
+    XML_ATTRIBUTE_FIXED
+} xmlAttributeDefault;
+
+/**
+ * xmlEnumeration:
+ *
+ * List structure used when there is an enumeration in DTDs.
+ */
+
+typedef struct _xmlEnumeration xmlEnumeration;
+typedef xmlEnumeration *xmlEnumerationPtr;
+struct _xmlEnumeration {
+    struct _xmlEnumeration    *next;	/* next one */
+    const xmlChar            *name;	/* Enumeration name */
+};
+
+/**
+ * xmlAttribute:
+ *
+ * An Attribute declaration in a DTD.
+ */
+
+typedef struct _xmlAttribute xmlAttribute;
+typedef xmlAttribute *xmlAttributePtr;
+struct _xmlAttribute {
+    void           *_private;	        /* application data */
+    xmlElementType          type;       /* XML_ATTRIBUTE_DECL, must be second ! */
+    const xmlChar          *name;	/* Attribute name */
+    struct _xmlNode    *children;	/* NULL */
+    struct _xmlNode        *last;	/* NULL */
+    struct _xmlDtd       *parent;	/* -> DTD */
+    struct _xmlNode        *next;	/* next sibling link  */
+    struct _xmlNode        *prev;	/* previous sibling link  */
+    struct _xmlDoc          *doc;       /* the containing document */
+
+    struct _xmlAttribute  *nexth;	/* next in hash table */
+    xmlAttributeType       atype;	/* The attribute type */
+    xmlAttributeDefault      def;	/* the default */
+    const xmlChar  *defaultValue;	/* or the default value */
+    xmlEnumerationPtr       tree;       /* or the enumeration tree if any */
+    const xmlChar        *prefix;	/* the namespace prefix if any */
+    const xmlChar          *elem;	/* Element holding the attribute */
+};
+
+/**
+ * xmlElementContentType:
+ *
+ * Possible definitions of element content types.
+ */
+typedef enum {
+    XML_ELEMENT_CONTENT_PCDATA = 1,
+    XML_ELEMENT_CONTENT_ELEMENT,
+    XML_ELEMENT_CONTENT_SEQ,
+    XML_ELEMENT_CONTENT_OR
+} xmlElementContentType;
+
+/**
+ * xmlElementContentOccur:
+ *
+ * Possible definitions of element content occurrences.
+ */
+typedef enum {
+    XML_ELEMENT_CONTENT_ONCE = 1,
+    XML_ELEMENT_CONTENT_OPT,
+    XML_ELEMENT_CONTENT_MULT,
+    XML_ELEMENT_CONTENT_PLUS
+} xmlElementContentOccur;
+
+/**
+ * xmlElementContent:
+ *
+ * An XML Element content as stored after parsing an element definition
+ * in a DTD.
+ */
+
+typedef struct _xmlElementContent xmlElementContent;
+typedef xmlElementContent *xmlElementContentPtr;
+struct _xmlElementContent {
+    xmlElementContentType     type;	/* PCDATA, ELEMENT, SEQ or OR */
+    xmlElementContentOccur    ocur;	/* ONCE, OPT, MULT or PLUS */
+    const xmlChar             *name;	/* Element name */
+    struct _xmlElementContent *c1;	/* first child */
+    struct _xmlElementContent *c2;	/* second child */
+    struct _xmlElementContent *parent;	/* parent */
+    const xmlChar             *prefix;	/* Namespace prefix */
+};
+
+/**
+ * xmlElementTypeVal:
+ *
+ * The different possibilities for an element content type.
+ */
+
+typedef enum {
+    XML_ELEMENT_TYPE_UNDEFINED = 0,
+    XML_ELEMENT_TYPE_EMPTY = 1,
+    XML_ELEMENT_TYPE_ANY,
+    XML_ELEMENT_TYPE_MIXED,
+    XML_ELEMENT_TYPE_ELEMENT
+} xmlElementTypeVal;
+
+#ifdef __cplusplus
+}
+#endif
+#include <libxml/xmlregexp.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlElement:
+ *
+ * An XML Element declaration from a DTD.
+ */
+
+typedef struct _xmlElement xmlElement;
+typedef xmlElement *xmlElementPtr;
+struct _xmlElement {
+    void           *_private;	        /* application data */
+    xmlElementType          type;       /* XML_ELEMENT_DECL, must be second ! */
+    const xmlChar          *name;	/* Element name */
+    struct _xmlNode    *children;	/* NULL */
+    struct _xmlNode        *last;	/* NULL */
+    struct _xmlDtd       *parent;	/* -> DTD */
+    struct _xmlNode        *next;	/* next sibling link  */
+    struct _xmlNode        *prev;	/* previous sibling link  */
+    struct _xmlDoc          *doc;       /* the containing document */
+
+    xmlElementTypeVal      etype;	/* The type */
+    xmlElementContentPtr content;	/* the allowed element content */
+    xmlAttributePtr   attributes;	/* List of the declared attributes */
+    const xmlChar        *prefix;	/* the namespace prefix if any */
+#ifdef LIBXML_REGEXP_ENABLED
+    xmlRegexpPtr       contModel;	/* the validating regexp */
+#else
+    void	      *contModel;
+#endif
+};
+
+
+/**
+ * XML_LOCAL_NAMESPACE:
+ *
+ * A namespace declaration node.
+ */
+#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
+typedef xmlElementType xmlNsType;
+
+/**
+ * xmlNs:
+ *
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overridden).
+ *
+ * xmlNsType is unified with xmlElementType.
+ */
+
+typedef struct _xmlNs xmlNs;
+typedef xmlNs *xmlNsPtr;
+struct _xmlNs {
+    struct _xmlNs  *next;	/* next Ns link for this node  */
+    xmlNsType      type;	/* global or local */
+    const xmlChar *href;	/* URL for the namespace */
+    const char* dummy_children; /* lines up with node->children */
+    const xmlChar *prefix;	/* prefix for the namespace */
+    void           *_private;   /* application data */
+    struct _xmlDoc *context;		/* normally an xmlDoc */
+};
+
+/**
+ * xmlDtd:
+ *
+ * An XML DTD, as defined by <!DOCTYPE ... There is actually one for
+ * the internal subset and for the external subset.
+ */
+typedef struct _xmlDtd xmlDtd;
+typedef xmlDtd *xmlDtdPtr;
+struct _xmlDtd {
+    void           *_private;	/* application data */
+    xmlElementType  type;       /* XML_DTD_NODE, must be second ! */
+    const xmlChar *name;	/* Name of the DTD */
+    struct _xmlNode *children;	/* the value of the property link */
+    struct _xmlNode *last;	/* last child link */
+    struct _xmlDoc  *parent;	/* child->parent link */
+    struct _xmlNode *next;	/* next sibling link  */
+    struct _xmlNode *prev;	/* previous sibling link  */
+    struct _xmlDoc  *doc;	/* the containing document */
+
+    /* End of common part */
+    void          *notations;   /* Hash table for notations if any */
+    void          *elements;    /* Hash table for elements if any */
+    void          *attributes;  /* Hash table for attributes if any */
+    void          *entities;    /* Hash table for entities if any */
+    const xmlChar *ExternalID;	/* External identifier for PUBLIC DTD */
+    const xmlChar *SystemID;	/* URI for a SYSTEM or PUBLIC DTD */
+    void          *pentities;   /* Hash table for param entities if any */
+};
+
+/**
+ * xmlAttr:
+ *
+ * An attribute on an XML node.
+ */
+typedef struct _xmlAttr xmlAttr;
+typedef xmlAttr *xmlAttrPtr;
+struct _xmlAttr {
+    void           *_private;	/* application data */
+    xmlElementType   type;      /* XML_ATTRIBUTE_NODE, must be second ! */
+    const xmlChar   *name;      /* the name of the property */
+    struct _xmlNode *children;	/* the value of the property */
+    struct _xmlNode *last;	/* NULL */
+    struct _xmlNode *parent;	/* child->parent link */
+    struct _xmlAttr *next;	/* next sibling link  */
+    struct _xmlAttr *prev;	/* previous sibling link  */
+    struct _xmlDoc  *doc;	/* the containing document */
+    xmlNs           *ns;        /* pointer to the associated namespace */
+    xmlAttributeType atype;     /* the attribute type if validating */
+    void            *psvi;	/* for type/PSVI informations */
+};
+
+/**
+ * xmlID:
+ *
+ * An XML ID instance.
+ */
+
+typedef struct _xmlID xmlID;
+typedef xmlID *xmlIDPtr;
+struct _xmlID {
+    struct _xmlID    *next;	/* next ID */
+    const xmlChar    *value;	/* The ID name */
+    xmlAttrPtr        attr;	/* The attribute holding it */
+    const xmlChar    *name;	/* The attribute if attr is not available */
+    int               lineno;	/* The line number if attr is not available */
+    struct _xmlDoc   *doc;	/* The document holding the ID */
+};
+
+/**
+ * xmlRef:
+ *
+ * An XML IDREF instance.
+ */
+
+typedef struct _xmlRef xmlRef;
+typedef xmlRef *xmlRefPtr;
+struct _xmlRef {
+    struct _xmlRef    *next;	/* next Ref */
+    const xmlChar     *value;	/* The Ref name */
+    xmlAttrPtr        attr;	/* The attribute holding it */
+    const xmlChar    *name;	/* The attribute if attr is not available */
+    int               lineno;	/* The line number if attr is not available */
+};
+
+/**
+ * xmlNode:
+ *
+ * A node in an XML tree.
+ */
+typedef struct _xmlNode xmlNode;
+typedef xmlNode *xmlNodePtr;
+struct _xmlNode {
+    void           *_private;	/* application data */
+    xmlElementType   type;	/* type number, must be second ! */
+    const xmlChar   *name;      /* the name of the node, or the entity */
+    struct _xmlNode *children;	/* parent->childs link */
+    struct _xmlNode *last;	/* last child link */
+    struct _xmlNode *parent;	/* child->parent link */
+    struct _xmlNode *next;	/* next sibling link  */
+    struct _xmlNode *prev;	/* previous sibling link  */
+    struct _xmlDoc  *doc;	/* the containing document */
+
+    /* End of common part */
+    xmlNs           *ns;        /* pointer to the associated namespace */
+    xmlChar         *content;   /* the content */
+    struct _xmlAttr *properties;/* properties list */
+    xmlNs           *nsDef;     /* namespace definitions on this node */
+    void            *psvi;	/* for type/PSVI informations */
+    unsigned short   line;	/* line number */
+    unsigned short   extra;	/* extra data for XPath/XSLT */
+};
+
+/**
+ * XML_GET_CONTENT:
+ *
+ * Macro to extract the content pointer of a node.
+ */
+#define XML_GET_CONTENT(n)					\
+    ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content)
+
+/**
+ * XML_GET_LINE:
+ *
+ * Macro to extract the line number of an element node. 
+ */
+#define XML_GET_LINE(n)						\
+    (xmlGetLineNo(n))
+
+/**
+ * xmlDocProperty
+ *
+ * Set of properties of the document as found by the parser
+ * Some of them are linked to similary named xmlParserOption
+ */
+typedef enum {
+    XML_DOC_WELLFORMED		= 1<<0, /* document is XML well formed */
+    XML_DOC_NSVALID		= 1<<1, /* document is Namespace valid */
+    XML_DOC_OLD10		= 1<<2, /* parsed with old XML-1.0 parser */
+    XML_DOC_DTDVALID		= 1<<3, /* DTD validation was successful */
+    XML_DOC_XINCLUDE		= 1<<4, /* XInclude substitution was done */
+    XML_DOC_USERBUILT		= 1<<5, /* Document was built using the API
+                                           and not by parsing an instance */
+    XML_DOC_INTERNAL		= 1<<6, /* built for internal processing */
+    XML_DOC_HTML		= 1<<7  /* parsed or built HTML document */
+} xmlDocProperties;
+
+/**
+ * xmlDoc:
+ *
+ * An XML document.
+ */
+typedef struct _xmlDoc xmlDoc;
+typedef xmlDoc *xmlDocPtr;
+struct _xmlDoc {
+    void           *_private;	/* application data */
+    xmlElementType  type;       /* XML_DOCUMENT_NODE, must be second ! */
+    char           *name;	/* name/filename/URI of the document */
+    struct _xmlNode *children;	/* the document tree */
+    struct _xmlNode *last;	/* last child link */
+    struct _xmlNode *parent;	/* child->parent link */
+    struct _xmlNode *next;	/* next sibling link  */
+    struct _xmlNode *prev;	/* previous sibling link  */
+    struct _xmlDoc  *doc;	/* autoreference to itself */
+
+    /* End of common part */
+    int             compression;/* level of zlib compression */
+    int             standalone; /* standalone document (no external refs) 
+				     1 if standalone="yes"
+				     0 if standalone="no"
+				    -1 if there is no XML declaration
+				    -2 if there is an XML declaration, but no
+					standalone attribute was specified */
+    struct _xmlDtd  *intSubset;	/* the document internal subset */
+    struct _xmlDtd  *extSubset;	/* the document external subset */
+    struct _xmlNs   *oldNs;	/* Global namespace, the old way */
+    const xmlChar  *version;	/* the XML version string */
+    const xmlChar  *encoding;   /* external initial encoding, if any */
+    void           *ids;        /* Hash table for ID attributes if any */
+    void           *refs;       /* Hash table for IDREFs attributes if any */
+    const xmlChar  *URL;	/* The URI for that document */
+    int             charset;    /* encoding of the in-memory content
+				   actually an xmlCharEncoding */
+    struct _xmlDict *dict;      /* dict used to allocate names or NULL */
+    void           *psvi;	/* for type/PSVI informations */
+    int             parseFlags;	/* set of xmlParserOption used to parse the
+				   document */
+    int             properties;	/* set of xmlDocProperties for this document
+				   set at the end of parsing */
+};
+
+
+typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt;
+typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr;
+
+/**
+ * xmlDOMWrapAcquireNsFunction:
+ * @ctxt:  a DOM wrapper context
+ * @node:  the context node (element or attribute) 
+ * @nsName:  the requested namespace name
+ * @nsPrefix:  the requested namespace prefix 
+ *
+ * A function called to acquire namespaces (xmlNs) from the wrapper.
+ *
+ * Returns an xmlNsPtr or NULL in case of an error.
+ */
+typedef xmlNsPtr (*xmlDOMWrapAcquireNsFunction) (xmlDOMWrapCtxtPtr ctxt,
+						 xmlNodePtr node,
+						 const xmlChar *nsName,
+						 const xmlChar *nsPrefix);
+
+/**
+ * xmlDOMWrapCtxt:
+ *
+ * Context for DOM wrapper-operations.
+ */
+struct _xmlDOMWrapCtxt {
+    void * _private;
+    /*
+    * The type of this context, just in case we need specialized
+    * contexts in the future.
+    */
+    int type;
+    /*
+    * Internal namespace map used for various operations.
+    */
+    void * namespaceMap;
+    /*
+    * Use this one to acquire an xmlNsPtr intended for node->ns.
+    * (Note that this is not intended for elem->nsDef).
+    */
+    xmlDOMWrapAcquireNsFunction getNsForNodeFunc;
+};
+
+/**
+ * xmlChildrenNode:
+ *
+ * Macro for compatibility naming layer with libxml1. Maps
+ * to "children."
+ */
+#ifndef xmlChildrenNode
+#define xmlChildrenNode children
+#endif
+
+/**
+ * xmlRootNode:
+ *
+ * Macro for compatibility naming layer with libxml1. Maps 
+ * to "children".
+ */
+#ifndef xmlRootNode
+#define xmlRootNode children
+#endif
+
+/*
+ * Variables.
+ */
+
+/*
+ * Some helper functions
+ */
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+XMLPUBFUN int XMLCALL
+		xmlValidateNCName	(const xmlChar *value,
+					 int space);
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN int XMLCALL		
+		xmlValidateQName	(const xmlChar *value,
+					 int space);
+XMLPUBFUN int XMLCALL		
+		xmlValidateName		(const xmlChar *value,
+					 int space);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNMToken	(const xmlChar *value,
+					 int space);
+#endif
+
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlBuildQName		(const xmlChar *ncname,
+					 const xmlChar *prefix,
+					 xmlChar *memory,
+					 int len);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlSplitQName2		(const xmlChar *name,
+					 xmlChar **prefix);
+XMLPUBFUN const xmlChar * XMLCALL	
+		xmlSplitQName3		(const xmlChar *name,
+					 int *len);
+
+/*
+ * Handling Buffers.
+ */
+
+XMLPUBFUN void XMLCALL		
+		xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme);
+XMLPUBFUN xmlBufferAllocationScheme XMLCALL	 
+		xmlGetBufferAllocationScheme(void);
+
+XMLPUBFUN xmlBufferPtr XMLCALL	
+		xmlBufferCreate		(void);
+XMLPUBFUN xmlBufferPtr XMLCALL	
+		xmlBufferCreateSize	(size_t size);
+XMLPUBFUN xmlBufferPtr XMLCALL	
+		xmlBufferCreateStatic	(void *mem,
+					 size_t size);
+XMLPUBFUN int XMLCALL		
+		xmlBufferResize		(xmlBufferPtr buf,
+					 unsigned int size);
+XMLPUBFUN void XMLCALL		
+		xmlBufferFree		(xmlBufferPtr buf);
+XMLPUBFUN int XMLCALL		
+		xmlBufferDump		(FILE *file,
+					 xmlBufferPtr buf);
+XMLPUBFUN int XMLCALL		
+		xmlBufferAdd		(xmlBufferPtr buf,
+					 const xmlChar *str,
+					 int len);
+XMLPUBFUN int XMLCALL		
+		xmlBufferAddHead	(xmlBufferPtr buf,
+					 const xmlChar *str,
+					 int len);
+XMLPUBFUN int XMLCALL		
+		xmlBufferCat		(xmlBufferPtr buf,
+					 const xmlChar *str);
+XMLPUBFUN int XMLCALL	
+		xmlBufferCCat		(xmlBufferPtr buf,
+					 const char *str);
+XMLPUBFUN int XMLCALL		
+		xmlBufferShrink		(xmlBufferPtr buf,
+					 unsigned int len);
+XMLPUBFUN int XMLCALL		
+		xmlBufferGrow		(xmlBufferPtr buf,
+					 unsigned int len);
+XMLPUBFUN void XMLCALL		
+		xmlBufferEmpty		(xmlBufferPtr buf);
+XMLPUBFUN const xmlChar* XMLCALL	
+		xmlBufferContent	(const xmlBufferPtr buf);
+XMLPUBFUN void XMLCALL		
+		xmlBufferSetAllocationScheme(xmlBufferPtr buf,
+					 xmlBufferAllocationScheme scheme);
+XMLPUBFUN int XMLCALL		
+		xmlBufferLength		(const xmlBufferPtr buf);
+
+/*
+ * Creating/freeing new structures.
+ */
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlCreateIntSubset	(xmlDocPtr doc,
+					 const xmlChar *name,
+					 const xmlChar *ExternalID,
+					 const xmlChar *SystemID);
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlNewDtd		(xmlDocPtr doc,
+					 const xmlChar *name,
+					 const xmlChar *ExternalID,
+					 const xmlChar *SystemID);
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlGetIntSubset		(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL		
+		xmlFreeDtd		(xmlDtdPtr cur);
+#ifdef LIBXML_LEGACY_ENABLED
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlNewGlobalNs		(xmlDocPtr doc,
+					 const xmlChar *href,
+					 const xmlChar *prefix);
+#endif /* LIBXML_LEGACY_ENABLED */
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlNewNs		(xmlNodePtr node,
+					 const xmlChar *href,
+					 const xmlChar *prefix);
+XMLPUBFUN void XMLCALL		
+		xmlFreeNs		(xmlNsPtr cur);
+XMLPUBFUN void XMLCALL		
+		xmlFreeNsList		(xmlNsPtr cur);
+XMLPUBFUN xmlDocPtr XMLCALL 	
+		xmlNewDoc		(const xmlChar *version);
+XMLPUBFUN void XMLCALL		
+		xmlFreeDoc		(xmlDocPtr cur);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlNewDocProp		(xmlDocPtr doc,
+					 const xmlChar *name,
+					 const xmlChar *value);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlNewProp		(xmlNodePtr node,
+					 const xmlChar *name,
+					 const xmlChar *value);
+#endif
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlNewNsProp		(xmlNodePtr node,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlNewNsPropEatName	(xmlNodePtr node,
+					 xmlNsPtr ns,
+					 xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN void XMLCALL		
+		xmlFreePropList		(xmlAttrPtr cur);
+XMLPUBFUN void XMLCALL		
+		xmlFreeProp		(xmlAttrPtr cur);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlCopyProp		(xmlNodePtr target,
+					 xmlAttrPtr cur);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlCopyPropList		(xmlNodePtr target,
+					 xmlAttrPtr cur);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlDtdPtr XMLCALL	
+		xmlCopyDtd		(xmlDtdPtr dtd);
+#endif /* LIBXML_TREE_ENABLED */
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN xmlDocPtr XMLCALL	
+		xmlCopyDoc		(xmlDocPtr doc,
+					 int recursive);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) */
+/*
+ * Creating new nodes.
+ */
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocNode		(xmlDocPtr doc,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocNodeEatName	(xmlDocPtr doc,
+					 xmlNsPtr ns,
+					 xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewNode		(xmlNsPtr ns,
+					 const xmlChar *name);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewNodeEatName	(xmlNsPtr ns,
+					 xmlChar *name);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewChild		(xmlNodePtr parent,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+#endif
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocText		(xmlDocPtr doc,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewText		(const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocPI		(xmlDocPtr doc,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewPI		(const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocTextLen	(xmlDocPtr doc,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewTextLen		(const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocComment	(xmlDocPtr doc,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewComment		(const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewCDataBlock	(xmlDocPtr doc,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewCharRef		(xmlDocPtr doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewReference		(xmlDocPtr doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlCopyNode		(const xmlNodePtr node,
+					 int recursive);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlDocCopyNode		(const xmlNodePtr node,
+					 xmlDocPtr doc,
+					 int recursive);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlDocCopyNodeList	(xmlDocPtr doc,
+					 const xmlNodePtr node);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlCopyNodeList		(const xmlNodePtr node);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewTextChild		(xmlNodePtr parent,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocRawNode	(xmlDocPtr doc,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlNewDocFragment	(xmlDocPtr doc);
+#endif /* LIBXML_TREE_ENABLED */
+
+/*
+ * Navigating.
+ */
+XMLPUBFUN long XMLCALL		
+		xmlGetLineNo		(xmlNodePtr node);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlGetNodePath		(xmlNodePtr node);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) */
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlDocGetRootElement	(xmlDocPtr doc);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlGetLastChild		(xmlNodePtr parent);
+XMLPUBFUN int XMLCALL		
+		xmlNodeIsText		(xmlNodePtr node);
+XMLPUBFUN int XMLCALL		
+		xmlIsBlankNode		(xmlNodePtr node);
+
+/*
+ * Changing the structure.
+ */
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlDocSetRootElement	(xmlDocPtr doc,
+					 xmlNodePtr root);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetName		(xmlNodePtr cur,
+					 const xmlChar *name);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlAddChild		(xmlNodePtr parent,
+					 xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlAddChildList		(xmlNodePtr parent,
+					 xmlNodePtr cur);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlReplaceNode		(xmlNodePtr old,
+					 xmlNodePtr cur);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlAddPrevSibling	(xmlNodePtr cur,
+					 xmlNodePtr elem);
+#endif /* LIBXML_TREE_ENABLED || LIBXML_HTML_ENABLED || LIBXML_SCHEMAS_ENABLED */
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlAddSibling		(xmlNodePtr cur,
+					 xmlNodePtr elem);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlAddNextSibling	(xmlNodePtr cur,
+					 xmlNodePtr elem);
+XMLPUBFUN void XMLCALL		
+		xmlUnlinkNode		(xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlTextMerge		(xmlNodePtr first,
+					 xmlNodePtr second);
+XMLPUBFUN int XMLCALL		
+		xmlTextConcat		(xmlNodePtr node,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN void XMLCALL		
+		xmlFreeNodeList		(xmlNodePtr cur);
+XMLPUBFUN void XMLCALL		
+		xmlFreeNode		(xmlNodePtr cur);
+XMLPUBFUN void XMLCALL		
+		xmlSetTreeDoc		(xmlNodePtr tree,
+					 xmlDocPtr doc);
+XMLPUBFUN void XMLCALL		
+		xmlSetListDoc		(xmlNodePtr list,
+					 xmlDocPtr doc);
+/*
+ * Namespaces.
+ */
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlSearchNs		(xmlDocPtr doc,
+					 xmlNodePtr node,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlSearchNsByHref	(xmlDocPtr doc,
+					 xmlNodePtr node,
+					 const xmlChar *href);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN xmlNsPtr * XMLCALL	
+		xmlGetNsList		(xmlDocPtr doc,
+					 xmlNodePtr node);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) */
+
+XMLPUBFUN void XMLCALL		
+		xmlSetNs		(xmlNodePtr node,
+					 xmlNsPtr ns);
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlCopyNamespace	(xmlNsPtr cur);
+XMLPUBFUN xmlNsPtr XMLCALL	
+		xmlCopyNamespaceList	(xmlNsPtr cur);
+
+/*
+ * Changing the content.
+ */
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlSetProp		(xmlNodePtr node,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlSetNsProp		(xmlNodePtr node,
+					 xmlNsPtr ns,
+					 const xmlChar *name,
+					 const xmlChar *value);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlGetNoNsProp		(xmlNodePtr node,
+					 const xmlChar *name);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlGetProp		(xmlNodePtr node,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlHasProp		(xmlNodePtr node,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlHasNsProp		(xmlNodePtr node,
+					 const xmlChar *name,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlGetNsProp		(xmlNodePtr node,
+					 const xmlChar *name,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlStringGetNodeList	(xmlDocPtr doc,
+					 const xmlChar *value);
+XMLPUBFUN xmlNodePtr XMLCALL	
+		xmlStringLenGetNodeList	(xmlDocPtr doc,
+					 const xmlChar *value,
+					 int len);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlNodeListGetString	(xmlDocPtr doc,
+					 xmlNodePtr list,
+					 int inLine);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlNodeListGetRawString	(xmlDocPtr doc,
+					 xmlNodePtr list,
+					 int inLine);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetContent	(xmlNodePtr cur,
+					 const xmlChar *content);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetContentLen	(xmlNodePtr cur,
+					 const xmlChar *content,
+					 int len);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL		
+		xmlNodeAddContent	(xmlNodePtr cur,
+					 const xmlChar *content);
+XMLPUBFUN void XMLCALL		
+		xmlNodeAddContentLen	(xmlNodePtr cur,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlNodeGetContent	(xmlNodePtr cur);
+XMLPUBFUN int XMLCALL
+		xmlNodeBufGetContent	(xmlBufferPtr buffer,
+					 xmlNodePtr cur);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlNodeGetLang		(xmlNodePtr cur);
+XMLPUBFUN int XMLCALL		
+		xmlNodeGetSpacePreserve	(xmlNodePtr cur);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetLang		(xmlNodePtr cur,
+					 const xmlChar *lang);
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetSpacePreserve (xmlNodePtr cur,
+					 int val);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlNodeGetBase		(xmlDocPtr doc,
+					 xmlNodePtr cur);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
+XMLPUBFUN void XMLCALL		
+		xmlNodeSetBase		(xmlNodePtr cur,
+					 const xmlChar *uri);
+#endif
+
+/*
+ * Removing content.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlRemoveProp		(xmlAttrPtr cur);
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN int XMLCALL		
+		xmlUnsetNsProp		(xmlNodePtr node,
+					 xmlNsPtr ns,
+					 const xmlChar *name);
+XMLPUBFUN int XMLCALL		
+		xmlUnsetProp		(xmlNodePtr node,
+					 const xmlChar *name);
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) */
+
+/*
+ * Internal, don't use.
+ */
+XMLPUBFUN void XMLCALL		
+		xmlBufferWriteCHAR	(xmlBufferPtr buf,
+					 const xmlChar *string);
+XMLPUBFUN void XMLCALL		
+		xmlBufferWriteChar	(xmlBufferPtr buf,
+					 const char *string);
+XMLPUBFUN void XMLCALL		
+		xmlBufferWriteQuotedString(xmlBufferPtr buf,
+					 const xmlChar *string);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void xmlAttrSerializeTxtContent(xmlBufferPtr buf,
+					 xmlDocPtr doc,
+					 xmlAttrPtr attr,
+					 const xmlChar *string);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef LIBXML_TREE_ENABLED
+/*
+ * Namespace handling.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlReconciliateNs	(xmlDocPtr doc,
+					 xmlNodePtr tree);
+#endif
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Saving.
+ */
+XMLPUBFUN void XMLCALL		
+		xmlDocDumpFormatMemory	(xmlDocPtr cur,
+					 xmlChar **mem,
+					 int *size,
+					 int format);
+XMLPUBFUN void XMLCALL		
+		xmlDocDumpMemory	(xmlDocPtr cur,
+					 xmlChar **mem,
+					 int *size);
+XMLPUBFUN void XMLCALL		
+		xmlDocDumpMemoryEnc	(xmlDocPtr out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding);
+XMLPUBFUN void XMLCALL		
+		xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding,
+					 int format);
+XMLPUBFUN int XMLCALL		
+		xmlDocFormatDump	(FILE *f,
+					 xmlDocPtr cur,
+					 int format);
+XMLPUBFUN int XMLCALL	
+		xmlDocDump		(FILE *f,
+					 xmlDocPtr cur);
+XMLPUBFUN void XMLCALL		
+		xmlElemDump		(FILE *f,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur);
+XMLPUBFUN int XMLCALL		
+		xmlSaveFile		(const char *filename,
+					 xmlDocPtr cur);
+XMLPUBFUN int XMLCALL		
+		xmlSaveFormatFile	(const char *filename,
+					 xmlDocPtr cur,
+					 int format);
+XMLPUBFUN int XMLCALL		
+		xmlNodeDump		(xmlBufferPtr buf,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur,
+					 int level,
+					 int format);
+
+XMLPUBFUN int XMLCALL		
+		xmlSaveFileTo		(xmlOutputBufferPtr buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
+XMLPUBFUN int XMLCALL             
+		xmlSaveFormatFileTo     (xmlOutputBufferPtr buf,
+					 xmlDocPtr cur,
+				         const char *encoding,
+				         int format);
+XMLPUBFUN void XMLCALL		
+		xmlNodeDumpOutput	(xmlOutputBufferPtr buf,
+					 xmlDocPtr doc,
+					 xmlNodePtr cur,
+					 int level,
+					 int format,
+					 const char *encoding);
+
+XMLPUBFUN int XMLCALL		
+		xmlSaveFormatFileEnc    (const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding,
+					 int format);
+
+XMLPUBFUN int XMLCALL		
+		xmlSaveFileEnc		(const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding);
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+/*
+ * XHTML
+ */
+XMLPUBFUN int XMLCALL		
+		xmlIsXHTML		(const xmlChar *systemID,
+					 const xmlChar *publicID);
+
+/*
+ * Compression.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlGetDocCompressMode	(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL		
+		xmlSetDocCompressMode	(xmlDocPtr doc,
+					 int mode);
+XMLPUBFUN int XMLCALL		
+		xmlGetCompressMode	(void);
+XMLPUBFUN void XMLCALL		
+		xmlSetCompressMode	(int mode);
+
+/*
+* DOM-wrapper helper functions.
+*/
+XMLPUBFUN xmlDOMWrapCtxtPtr XMLCALL
+		xmlDOMWrapNewCtxt	(void);
+XMLPUBFUN void XMLCALL
+		xmlDOMWrapFreeCtxt	(xmlDOMWrapCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+	    xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt,
+					 xmlNodePtr elem,
+					 int options);
+XMLPUBFUN int XMLCALL
+	    xmlDOMWrapAdoptNode		(xmlDOMWrapCtxtPtr ctxt,
+					 xmlDocPtr sourceDoc,
+					 xmlNodePtr node,
+					 xmlDocPtr destDoc,		    
+					 xmlNodePtr destParent,
+					 int options);
+XMLPUBFUN int XMLCALL
+	    xmlDOMWrapRemoveNode	(xmlDOMWrapCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr node,
+					 int options);
+XMLPUBFUN int XMLCALL
+	    xmlDOMWrapCloneNode		(xmlDOMWrapCtxtPtr ctxt,
+					 xmlDocPtr sourceDoc,
+					 xmlNodePtr node,
+					 xmlNodePtr *clonedNode,
+					 xmlDocPtr destDoc,
+					 xmlNodePtr destParent,
+					 int deep,
+					 int options);
+
+#ifdef LIBXML_TREE_ENABLED
+/*
+ * 5 interfaces from DOM ElementTraversal, but different in entities
+ * traversal.
+ */
+XMLPUBFUN unsigned long XMLCALL
+            xmlChildElementCount        (xmlNodePtr parent);
+XMLPUBFUN xmlNodePtr XMLCALL
+            xmlNextElementSibling       (xmlNodePtr node);
+XMLPUBFUN xmlNodePtr XMLCALL
+            xmlFirstElementChild        (xmlNodePtr parent);
+XMLPUBFUN xmlNodePtr XMLCALL
+            xmlLastElementChild         (xmlNodePtr parent);
+XMLPUBFUN xmlNodePtr XMLCALL
+            xmlPreviousElementSibling   (xmlNodePtr node);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#ifndef __XML_PARSER_H__
+#include <libxml/xmlmemory.h>
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/src/include/libxml/uri.h b/src/include/libxml/uri.h
new file mode 100644
index 0000000..db48262
--- /dev/null
+++ b/src/include/libxml/uri.h
@@ -0,0 +1,94 @@
+/**
+ * Summary: library of generic URI related routines
+ * Description: library of generic URI related routines
+ *              Implements RFC 2396
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_URI_H__
+#define __XML_URI_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlURI:
+ *
+ * A parsed URI reference. This is a struct containing the various fields
+ * as described in RFC 2396 but separated for further processing.
+ *
+ * Note: query is a deprecated field which is incorrectly unescaped.
+ * query_raw takes precedence over query if the former is set.
+ * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00127
+ */
+typedef struct _xmlURI xmlURI;
+typedef xmlURI *xmlURIPtr;
+struct _xmlURI {
+    char *scheme;	/* the URI scheme */
+    char *opaque;	/* opaque part */
+    char *authority;	/* the authority part */
+    char *server;	/* the server part */
+    char *user;		/* the user part */
+    int port;		/* the port number */
+    char *path;		/* the path string */
+    char *query;	/* the query string (deprecated - use with caution) */
+    char *fragment;	/* the fragment identifier */
+    int  cleanup;	/* parsing potentially unclean URI */
+    char *query_raw;	/* the query string (as it appears in the URI) */
+};
+
+/*
+ * This function is in tree.h:
+ * xmlChar *	xmlNodeGetBase	(xmlDocPtr doc,
+ *                               xmlNodePtr cur);
+ */
+XMLPUBFUN xmlURIPtr XMLCALL
+		xmlCreateURI		(void);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlBuildURI		(const xmlChar *URI,
+					 const xmlChar *base);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlBuildRelativeURI	(const xmlChar *URI,
+					 const xmlChar *base);
+XMLPUBFUN xmlURIPtr XMLCALL
+		xmlParseURI		(const char *str);
+XMLPUBFUN xmlURIPtr XMLCALL
+		xmlParseURIRaw		(const char *str,
+					 int raw);
+XMLPUBFUN int XMLCALL
+		xmlParseURIReference	(xmlURIPtr uri,
+					 const char *str);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlSaveUri		(xmlURIPtr uri);
+XMLPUBFUN void XMLCALL
+		xmlPrintURI		(FILE *stream,
+					 xmlURIPtr uri);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlURIEscapeStr         (const xmlChar *str,
+					 const xmlChar *list);
+XMLPUBFUN char * XMLCALL
+		xmlURIUnescapeString	(const char *str,
+					 int len,
+					 char *target);
+XMLPUBFUN int XMLCALL
+		xmlNormalizeURIPath	(char *path);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlURIEscape		(const xmlChar *str);
+XMLPUBFUN void XMLCALL
+		xmlFreeURI		(xmlURIPtr uri);
+XMLPUBFUN xmlChar* XMLCALL
+		xmlCanonicPath		(const xmlChar *path);
+XMLPUBFUN xmlChar* XMLCALL
+		xmlPathToURI		(const xmlChar *path);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_URI_H__ */
diff --git a/src/include/libxml/valid.h b/src/include/libxml/valid.h
new file mode 100644
index 0000000..a2307f1
--- /dev/null
+++ b/src/include/libxml/valid.h
@@ -0,0 +1,458 @@
+/*
+ * Summary: The DTD validation
+ * Description: API for the DTD handling and the validity checking
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_VALID_H__
+#define __XML_VALID_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
+#include <libxml/tree.h>
+#include <libxml/list.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlregexp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Validation state added for non-determinist content model.
+ */
+typedef struct _xmlValidState xmlValidState;
+typedef xmlValidState *xmlValidStatePtr;
+
+/**
+ * xmlValidityErrorFunc:
+ * @ctx:  usually an xmlValidCtxtPtr to a validity error context,
+ *        but comes from ctxt->userData (which normally contains such
+ *        a pointer); ctxt->userData can be changed by the user.
+ * @msg:  the string to format *printf like vararg
+ * @...:  remaining arguments to the format
+ *
+ * Callback called when a validity error is found. This is a message
+ * oriented function similar to an *printf function.
+ */
+typedef void (XMLCDECL *xmlValidityErrorFunc) (void *ctx,
+			     const char *msg,
+			     ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * xmlValidityWarningFunc:
+ * @ctx:  usually an xmlValidCtxtPtr to a validity error context,
+ *        but comes from ctxt->userData (which normally contains such
+ *        a pointer); ctxt->userData can be changed by the user.
+ * @msg:  the string to format *printf like vararg
+ * @...:  remaining arguments to the format
+ *
+ * Callback called when a validity warning is found. This is a message
+ * oriented function similar to an *printf function.
+ */
+typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx,
+			       const char *msg,
+			       ...) LIBXML_ATTR_FORMAT(2,3);
+
+#ifdef IN_LIBXML
+/**
+ * XML_CTXT_FINISH_DTD_0:
+ *
+ * Special value for finishDtd field when embedded in an xmlParserCtxt
+ */
+#define XML_CTXT_FINISH_DTD_0 0xabcd1234
+/**
+ * XML_CTXT_FINISH_DTD_1:
+ *
+ * Special value for finishDtd field when embedded in an xmlParserCtxt
+ */
+#define XML_CTXT_FINISH_DTD_1 0xabcd1235
+#endif
+
+/*
+ * xmlValidCtxt:
+ * An xmlValidCtxt is used for error reporting when validating.
+ */
+typedef struct _xmlValidCtxt xmlValidCtxt;
+typedef xmlValidCtxt *xmlValidCtxtPtr;
+struct _xmlValidCtxt {
+    void *userData;			/* user specific data block */
+    xmlValidityErrorFunc error;		/* the callback in case of errors */
+    xmlValidityWarningFunc warning;	/* the callback in case of warning */
+
+    /* Node analysis stack used when validating within entities */
+    xmlNodePtr         node;          /* Current parsed Node */
+    int                nodeNr;        /* Depth of the parsing stack */
+    int                nodeMax;       /* Max depth of the parsing stack */
+    xmlNodePtr        *nodeTab;       /* array of nodes */
+
+    unsigned int     finishDtd;       /* finished validating the Dtd ? */
+    xmlDocPtr              doc;       /* the document */
+    int                  valid;       /* temporary validity check result */
+
+    /* state state used for non-determinist content validation */
+    xmlValidState     *vstate;        /* current state */
+    int                vstateNr;      /* Depth of the validation stack */
+    int                vstateMax;     /* Max depth of the validation stack */
+    xmlValidState     *vstateTab;     /* array of validation states */
+
+#ifdef LIBXML_REGEXP_ENABLED
+    xmlAutomataPtr            am;     /* the automata */
+    xmlAutomataStatePtr    state;     /* used to build the automata */
+#else
+    void                     *am;
+    void                  *state;
+#endif
+};
+
+/*
+ * ALL notation declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlNotationTable;
+typedef xmlNotationTable *xmlNotationTablePtr;
+
+/*
+ * ALL element declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlElementTable;
+typedef xmlElementTable *xmlElementTablePtr;
+
+/*
+ * ALL attribute declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlAttributeTable;
+typedef xmlAttributeTable *xmlAttributeTablePtr;
+
+/*
+ * ALL IDs attributes are stored in a table.
+ * There is one table per document.
+ */
+
+typedef struct _xmlHashTable xmlIDTable;
+typedef xmlIDTable *xmlIDTablePtr;
+
+/*
+ * ALL Refs attributes are stored in a table.
+ * There is one table per document.
+ */
+
+typedef struct _xmlHashTable xmlRefTable;
+typedef xmlRefTable *xmlRefTablePtr;
+
+/* Notation */
+XMLPUBFUN xmlNotationPtr XMLCALL	    
+		xmlAddNotationDecl	(xmlValidCtxtPtr ctxt,
+					 xmlDtdPtr dtd,
+					 const xmlChar *name,
+					 const xmlChar *PublicID,
+					 const xmlChar *SystemID);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlNotationTablePtr XMLCALL 
+		xmlCopyNotationTable	(xmlNotationTablePtr table);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL		    
+		xmlFreeNotationTable	(xmlNotationTablePtr table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL		    
+		xmlDumpNotationDecl	(xmlBufferPtr buf,
+					 xmlNotationPtr nota);
+XMLPUBFUN void XMLCALL		    
+		xmlDumpNotationTable	(xmlBufferPtr buf,
+					 xmlNotationTablePtr table);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* Element Content */
+/* the non Doc version are being deprecated */
+XMLPUBFUN xmlElementContentPtr XMLCALL 
+		xmlNewElementContent	(const xmlChar *name,
+					 xmlElementContentType type);
+XMLPUBFUN xmlElementContentPtr XMLCALL 
+		xmlCopyElementContent	(xmlElementContentPtr content);
+XMLPUBFUN void XMLCALL		     
+		xmlFreeElementContent	(xmlElementContentPtr cur);
+/* the new versions with doc argument */
+XMLPUBFUN xmlElementContentPtr XMLCALL 
+		xmlNewDocElementContent	(xmlDocPtr doc,
+					 const xmlChar *name,
+					 xmlElementContentType type);
+XMLPUBFUN xmlElementContentPtr XMLCALL 
+		xmlCopyDocElementContent(xmlDocPtr doc,
+					 xmlElementContentPtr content);
+XMLPUBFUN void XMLCALL		     
+		xmlFreeDocElementContent(xmlDocPtr doc,
+					 xmlElementContentPtr cur);
+XMLPUBFUN void XMLCALL		     
+		xmlSnprintfElementContent(char *buf,
+					 int size,
+	                                 xmlElementContentPtr content,
+					 int englob);
+#ifdef LIBXML_OUTPUT_ENABLED
+/* DEPRECATED */
+XMLPUBFUN void XMLCALL		     
+		xmlSprintfElementContent(char *buf,
+	                                 xmlElementContentPtr content,
+					 int englob);
+#endif /* LIBXML_OUTPUT_ENABLED */
+/* DEPRECATED */
+
+/* Element */
+XMLPUBFUN xmlElementPtr XMLCALL	   
+		xmlAddElementDecl	(xmlValidCtxtPtr ctxt,
+					 xmlDtdPtr dtd,
+					 const xmlChar *name,
+					 xmlElementTypeVal type,
+					 xmlElementContentPtr content);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlElementTablePtr XMLCALL 
+		xmlCopyElementTable	(xmlElementTablePtr table);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL		   
+		xmlFreeElementTable	(xmlElementTablePtr table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL		   
+		xmlDumpElementTable	(xmlBufferPtr buf,
+					 xmlElementTablePtr table);
+XMLPUBFUN void XMLCALL		   
+		xmlDumpElementDecl	(xmlBufferPtr buf,
+					 xmlElementPtr elem);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* Enumeration */
+XMLPUBFUN xmlEnumerationPtr XMLCALL 
+		xmlCreateEnumeration	(const xmlChar *name);
+XMLPUBFUN void XMLCALL		   
+		xmlFreeEnumeration	(xmlEnumerationPtr cur);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlEnumerationPtr XMLCALL  
+		xmlCopyEnumeration	(xmlEnumerationPtr cur);
+#endif /* LIBXML_TREE_ENABLED */
+
+/* Attribute */
+XMLPUBFUN xmlAttributePtr XMLCALL	    
+		xmlAddAttributeDecl	(xmlValidCtxtPtr ctxt,
+					 xmlDtdPtr dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name,
+					 const xmlChar *ns,
+					 xmlAttributeType type,
+					 xmlAttributeDefault def,
+					 const xmlChar *defaultValue,
+					 xmlEnumerationPtr tree);
+#ifdef LIBXML_TREE_ENABLED
+XMLPUBFUN xmlAttributeTablePtr XMLCALL 
+		xmlCopyAttributeTable  (xmlAttributeTablePtr table);
+#endif /* LIBXML_TREE_ENABLED */
+XMLPUBFUN void XMLCALL		     
+		xmlFreeAttributeTable  (xmlAttributeTablePtr table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL		     
+		xmlDumpAttributeTable  (xmlBufferPtr buf,
+					xmlAttributeTablePtr table);
+XMLPUBFUN void XMLCALL		     
+		xmlDumpAttributeDecl   (xmlBufferPtr buf,
+					xmlAttributePtr attr);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* IDs */
+XMLPUBFUN xmlIDPtr XMLCALL	
+		xmlAddID	       (xmlValidCtxtPtr ctxt,
+					xmlDocPtr doc,
+					const xmlChar *value,
+					xmlAttrPtr attr);
+XMLPUBFUN void XMLCALL		
+		xmlFreeIDTable	       (xmlIDTablePtr table);
+XMLPUBFUN xmlAttrPtr XMLCALL	
+		xmlGetID	       (xmlDocPtr doc,
+					const xmlChar *ID);
+XMLPUBFUN int XMLCALL		
+		xmlIsID		       (xmlDocPtr doc,
+					xmlNodePtr elem,
+					xmlAttrPtr attr);
+XMLPUBFUN int XMLCALL		
+		xmlRemoveID	       (xmlDocPtr doc, 
+					xmlAttrPtr attr);
+
+/* IDREFs */
+XMLPUBFUN xmlRefPtr XMLCALL	
+		xmlAddRef	       (xmlValidCtxtPtr ctxt,
+					xmlDocPtr doc,
+					const xmlChar *value,
+					xmlAttrPtr attr);
+XMLPUBFUN void XMLCALL		
+		xmlFreeRefTable	       (xmlRefTablePtr table);
+XMLPUBFUN int XMLCALL		
+		xmlIsRef	       (xmlDocPtr doc,
+					xmlNodePtr elem,
+					xmlAttrPtr attr);
+XMLPUBFUN int XMLCALL		
+		xmlRemoveRef	       (xmlDocPtr doc, 
+					xmlAttrPtr attr);
+XMLPUBFUN xmlListPtr XMLCALL	
+		xmlGetRefs	       (xmlDocPtr doc,
+					const xmlChar *ID);
+
+/**
+ * The public function calls related to validity checking.
+ */
+#ifdef LIBXML_VALID_ENABLED
+/* Allocate/Release Validation Contexts */
+XMLPUBFUN xmlValidCtxtPtr XMLCALL	    
+		xmlNewValidCtxt(void);
+XMLPUBFUN void XMLCALL		    
+		xmlFreeValidCtxt(xmlValidCtxtPtr);
+
+XMLPUBFUN int XMLCALL		
+		xmlValidateRoot		(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc);
+XMLPUBFUN int XMLCALL		
+		xmlValidateElementDecl	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+		                         xmlElementPtr elem);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlValidNormalizeAttributeValue(xmlDocPtr doc,
+					 xmlNodePtr elem,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+		                         xmlAttributePtr attr);
+XMLPUBFUN int XMLCALL		
+		xmlValidateAttributeValue(xmlAttributeType type,
+					 const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNotationDecl	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+		                         xmlNotationPtr nota);
+XMLPUBFUN int XMLCALL		
+		xmlValidateDtd		(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlDtdPtr dtd);
+XMLPUBFUN int XMLCALL		
+		xmlValidateDtdFinal	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc);
+XMLPUBFUN int XMLCALL		
+		xmlValidateDocument	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc);
+XMLPUBFUN int XMLCALL		
+		xmlValidateElement	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem);
+XMLPUBFUN int XMLCALL		
+		xmlValidateOneElement	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+		                         xmlNodePtr elem);
+XMLPUBFUN int XMLCALL	
+		xmlValidateOneAttribute	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr	elem,
+					 xmlAttrPtr attr,
+					 const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateOneNamespace	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem,
+					 const xmlChar *prefix,
+					 xmlNsPtr ns,
+					 const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc);
+#endif /* LIBXML_VALID_ENABLED */
+
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN int XMLCALL		
+		xmlValidateNotationUse	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 const xmlChar *notationName);
+#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */
+
+XMLPUBFUN int XMLCALL		
+		xmlIsMixedElement	(xmlDocPtr doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttributePtr XMLCALL	
+		xmlGetDtdAttrDesc	(xmlDtdPtr dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttributePtr XMLCALL	
+		xmlGetDtdQAttrDesc	(xmlDtdPtr dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name,
+					 const xmlChar *prefix);
+XMLPUBFUN xmlNotationPtr XMLCALL	
+		xmlGetDtdNotationDesc	(xmlDtdPtr dtd,
+					 const xmlChar *name);
+XMLPUBFUN xmlElementPtr XMLCALL	
+		xmlGetDtdQElementDesc	(xmlDtdPtr dtd,
+					 const xmlChar *name,
+					 const xmlChar *prefix);
+XMLPUBFUN xmlElementPtr XMLCALL	
+		xmlGetDtdElementDesc	(xmlDtdPtr dtd,
+					 const xmlChar *name);
+
+#ifdef LIBXML_VALID_ENABLED
+
+XMLPUBFUN int XMLCALL		
+		xmlValidGetPotentialChildren(xmlElementContent *ctree,
+					 const xmlChar **names,
+					 int *len,
+					 int max);
+
+XMLPUBFUN int XMLCALL		
+		xmlValidGetValidElements(xmlNode *prev,
+					 xmlNode *next,
+					 const xmlChar **names,
+					 int max);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNameValue	(const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNamesValue	(const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNmtokenValue	(const xmlChar *value);
+XMLPUBFUN int XMLCALL		
+		xmlValidateNmtokensValue(const xmlChar *value);
+
+#ifdef LIBXML_REGEXP_ENABLED
+/*
+ * Validation based on the regexp support
+ */
+XMLPUBFUN int XMLCALL		
+		xmlValidBuildContentModel(xmlValidCtxtPtr ctxt,
+					 xmlElementPtr elem);
+
+XMLPUBFUN int XMLCALL		
+		xmlValidatePushElement	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem,
+					 const xmlChar *qname);
+XMLPUBFUN int XMLCALL		
+		xmlValidatePushCData	(xmlValidCtxtPtr ctxt,
+					 const xmlChar *data,
+					 int len);
+XMLPUBFUN int XMLCALL		
+		xmlValidatePopElement	(xmlValidCtxtPtr ctxt,
+					 xmlDocPtr doc,
+					 xmlNodePtr elem,
+					 const xmlChar *qname);
+#endif /* LIBXML_REGEXP_ENABLED */
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_VALID_H__ */
diff --git a/src/include/libxml/xinclude.h b/src/include/libxml/xinclude.h
new file mode 100644
index 0000000..863ab25
--- /dev/null
+++ b/src/include/libxml/xinclude.h
@@ -0,0 +1,129 @@
+/*
+ * Summary: implementation of XInclude
+ * Description: API to handle XInclude processing,
+ * implements the
+ * World Wide Web Consortium Last Call Working Draft 10 November 2003
+ * http://www.w3.org/TR/2003/WD-xinclude-20031110
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XINCLUDE_H__
+#define __XML_XINCLUDE_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XINCLUDE_NS:
+ *
+ * Macro defining the Xinclude namespace: http://www.w3.org/2003/XInclude
+ */
+#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2003/XInclude"
+/**
+ * XINCLUDE_OLD_NS:
+ *
+ * Macro defining the draft Xinclude namespace: http://www.w3.org/2001/XInclude
+ */
+#define XINCLUDE_OLD_NS (const xmlChar *) "http://www.w3.org/2001/XInclude"
+/**
+ * XINCLUDE_NODE:
+ *
+ * Macro defining "include"
+ */
+#define XINCLUDE_NODE (const xmlChar *) "include"
+/**
+ * XINCLUDE_FALLBACK:
+ *
+ * Macro defining "fallback"
+ */
+#define XINCLUDE_FALLBACK (const xmlChar *) "fallback"
+/**
+ * XINCLUDE_HREF:
+ *
+ * Macro defining "href"
+ */
+#define XINCLUDE_HREF (const xmlChar *) "href"
+/**
+ * XINCLUDE_PARSE:
+ *
+ * Macro defining "parse"
+ */
+#define XINCLUDE_PARSE (const xmlChar *) "parse"
+/**
+ * XINCLUDE_PARSE_XML:
+ *
+ * Macro defining "xml"
+ */
+#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
+/**
+ * XINCLUDE_PARSE_TEXT:
+ *
+ * Macro defining "text"
+ */
+#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
+/**
+ * XINCLUDE_PARSE_ENCODING:
+ *
+ * Macro defining "encoding"
+ */
+#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding"
+/**
+ * XINCLUDE_PARSE_XPOINTER:
+ *
+ * Macro defining "xpointer"
+ */
+#define XINCLUDE_PARSE_XPOINTER (const xmlChar *) "xpointer"
+
+typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
+typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
+
+/*
+ * standalone processing
+ */
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcess	(xmlDocPtr doc);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcessFlags	(xmlDocPtr doc,
+					 int flags);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcessFlagsData(xmlDocPtr doc,
+					 int flags,
+					 void *data);
+XMLPUBFUN int XMLCALL
+                xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree,
+                                         int flags,
+                                         void *data);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcessTree	(xmlNodePtr tree);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcessTreeFlags(xmlNodePtr tree,
+					 int flags);
+/*
+ * contextual processing
+ */
+XMLPUBFUN xmlXIncludeCtxtPtr XMLCALL
+		xmlXIncludeNewContext	(xmlDocPtr doc);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeSetFlags	(xmlXIncludeCtxtPtr ctxt,
+					 int flags);
+XMLPUBFUN void XMLCALL
+		xmlXIncludeFreeContext	(xmlXIncludeCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		xmlXIncludeProcessNode	(xmlXIncludeCtxtPtr ctxt,
+					 xmlNodePtr tree);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XINCLUDE_ENABLED */
+
+#endif /* __XML_XINCLUDE_H__ */
diff --git a/src/include/libxml/xlink.h b/src/include/libxml/xlink.h
new file mode 100644
index 0000000..083c7ed
--- /dev/null
+++ b/src/include/libxml/xlink.h
@@ -0,0 +1,189 @@
+/*
+ * Summary: unfinished XLink detection module
+ * Description: unfinished XLink detection module
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XLINK_H__
+#define __XML_XLINK_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_XPTR_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Various defines for the various Link properties.
+ *
+ * NOTE: the link detection layer will try to resolve QName expansion
+ *       of namespaces. If "foo" is the prefix for "http://foo.com/"
+ *       then the link detection layer will expand role="foo:myrole"
+ *       to "http://foo.com/:myrole".
+ * NOTE: the link detection layer will expand URI-Refences found on
+ *       href attributes by using the base mechanism if found.
+ */
+typedef xmlChar *xlinkHRef;
+typedef xmlChar *xlinkRole;
+typedef xmlChar *xlinkTitle;
+
+typedef enum {
+    XLINK_TYPE_NONE = 0,
+    XLINK_TYPE_SIMPLE,
+    XLINK_TYPE_EXTENDED,
+    XLINK_TYPE_EXTENDED_SET
+} xlinkType;
+
+typedef enum {
+    XLINK_SHOW_NONE = 0,
+    XLINK_SHOW_NEW,
+    XLINK_SHOW_EMBED,
+    XLINK_SHOW_REPLACE
+} xlinkShow;
+
+typedef enum {
+    XLINK_ACTUATE_NONE = 0,
+    XLINK_ACTUATE_AUTO,
+    XLINK_ACTUATE_ONREQUEST
+} xlinkActuate;
+
+/**
+ * xlinkNodeDetectFunc:
+ * @ctx:  user data pointer
+ * @node:  the node to check
+ * 
+ * This is the prototype for the link detection routine.
+ * It calls the default link detection callbacks upon link detection.
+ */
+typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNodePtr node);
+
+/*
+ * The link detection module interact with the upper layers using
+ * a set of callback registered at parsing time.
+ */
+
+/**
+ * xlinkSimpleLinkFunk:
+ * @ctx:  user data pointer
+ * @node:  the node carrying the link
+ * @href:  the target of the link
+ * @role:  the role string
+ * @title:  the link title
+ *
+ * This is the prototype for a simple link detection callback.
+ */
+typedef void
+(*xlinkSimpleLinkFunk)	(void *ctx,
+			 xmlNodePtr node,
+			 const xlinkHRef href,
+			 const xlinkRole role,
+			 const xlinkTitle title);
+
+/**
+ * xlinkExtendedLinkFunk:
+ * @ctx:  user data pointer
+ * @node:  the node carrying the link
+ * @nbLocators: the number of locators detected on the link
+ * @hrefs:  pointer to the array of locator hrefs
+ * @roles:  pointer to the array of locator roles
+ * @nbArcs: the number of arcs detected on the link
+ * @from:  pointer to the array of source roles found on the arcs
+ * @to:  pointer to the array of target roles found on the arcs
+ * @show:  array of values for the show attributes found on the arcs
+ * @actuate:  array of values for the actuate attributes found on the arcs
+ * @nbTitles: the number of titles detected on the link
+ * @title:  array of titles detected on the link
+ * @langs:  array of xml:lang values for the titles
+ *
+ * This is the prototype for a extended link detection callback.
+ */
+typedef void
+(*xlinkExtendedLinkFunk)(void *ctx,
+			 xmlNodePtr node,
+			 int nbLocators,
+			 const xlinkHRef *hrefs,
+			 const xlinkRole *roles,
+			 int nbArcs,
+			 const xlinkRole *from,
+			 const xlinkRole *to,
+			 xlinkShow *show,
+			 xlinkActuate *actuate,
+			 int nbTitles,
+			 const xlinkTitle *titles,
+			 const xmlChar **langs);
+
+/**
+ * xlinkExtendedLinkSetFunk:
+ * @ctx:  user data pointer
+ * @node:  the node carrying the link
+ * @nbLocators: the number of locators detected on the link
+ * @hrefs:  pointer to the array of locator hrefs
+ * @roles:  pointer to the array of locator roles
+ * @nbTitles: the number of titles detected on the link
+ * @title:  array of titles detected on the link
+ * @langs:  array of xml:lang values for the titles
+ *
+ * This is the prototype for a extended link set detection callback.
+ */
+typedef void
+(*xlinkExtendedLinkSetFunk)	(void *ctx,
+				 xmlNodePtr node,
+				 int nbLocators,
+				 const xlinkHRef *hrefs,
+				 const xlinkRole *roles,
+				 int nbTitles,
+				 const xlinkTitle *titles,
+				 const xmlChar **langs);
+
+/**
+ * This is the structure containing a set of Links detection callbacks.
+ *
+ * There is no default xlink callbacks, if one want to get link
+ * recognition activated, those call backs must be provided before parsing.
+ */
+typedef struct _xlinkHandler xlinkHandler;
+typedef xlinkHandler *xlinkHandlerPtr;
+struct _xlinkHandler {
+    xlinkSimpleLinkFunk simple;
+    xlinkExtendedLinkFunk extended;
+    xlinkExtendedLinkSetFunk set;
+};
+
+/*
+ * The default detection routine, can be overridden, they call the default
+ * detection callbacks. 
+ */
+
+XMLPUBFUN xlinkNodeDetectFunc XMLCALL	
+		xlinkGetDefaultDetect	(void);
+XMLPUBFUN void XMLCALL			
+		xlinkSetDefaultDetect	(xlinkNodeDetectFunc func);
+
+/*
+ * Routines to set/get the default handlers.
+ */
+XMLPUBFUN xlinkHandlerPtr XMLCALL	
+		xlinkGetDefaultHandler	(void);
+XMLPUBFUN void XMLCALL		
+		xlinkSetDefaultHandler	(xlinkHandlerPtr handler);
+
+/*
+ * Link detection module itself.
+ */
+XMLPUBFUN xlinkType XMLCALL	 
+		xlinkIsLink		(xmlDocPtr doc,
+					 xmlNodePtr node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPTR_ENABLED */
+
+#endif /* __XML_XLINK_H__ */
diff --git a/src/include/libxml/xmlIO.h b/src/include/libxml/xmlIO.h
new file mode 100644
index 0000000..eea9ed6
--- /dev/null
+++ b/src/include/libxml/xmlIO.h
@@ -0,0 +1,360 @@
+/*
+ * Summary: interface for the I/O interfaces used by the parser
+ * Description: interface for the I/O interfaces used by the parser
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_IO_H__
+#define __XML_IO_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Those are the functions and datatypes for the parser input
+ * I/O structures.
+ */
+
+/**
+ * xmlInputMatchCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Input API to detect if the current handler 
+ * can provide input fonctionnalities for this resource.
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+typedef int (XMLCALL *xmlInputMatchCallback) (char const *filename);
+/**
+ * xmlInputOpenCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Input API to open the resource
+ *
+ * Returns an Input context or NULL in case or error
+ */
+typedef void * (XMLCALL *xmlInputOpenCallback) (char const *filename);
+/**
+ * xmlInputReadCallback:
+ * @context:  an Input context
+ * @buffer:  the buffer to store data read
+ * @len:  the length of the buffer in bytes
+ *
+ * Callback used in the I/O Input API to read the resource
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+typedef int (XMLCALL *xmlInputReadCallback) (void * context, char * buffer, int len);
+/**
+ * xmlInputCloseCallback:
+ * @context:  an Input context
+ *
+ * Callback used in the I/O Input API to close the resource
+ *
+ * Returns 0 or -1 in case of error
+ */
+typedef int (XMLCALL *xmlInputCloseCallback) (void * context);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Those are the functions and datatypes for the library output
+ * I/O structures.
+ */
+
+/**
+ * xmlOutputMatchCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Output API to detect if the current handler 
+ * can provide output fonctionnalities for this resource.
+ *
+ * Returns 1 if yes and 0 if another Output module should be used
+ */
+typedef int (XMLCALL *xmlOutputMatchCallback) (char const *filename);
+/**
+ * xmlOutputOpenCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Output API to open the resource
+ *
+ * Returns an Output context or NULL in case or error
+ */
+typedef void * (XMLCALL *xmlOutputOpenCallback) (char const *filename);
+/**
+ * xmlOutputWriteCallback:
+ * @context:  an Output context
+ * @buffer:  the buffer of data to write
+ * @len:  the length of the buffer in bytes
+ *
+ * Callback used in the I/O Output API to write to the resource
+ *
+ * Returns the number of bytes written or -1 in case of error
+ */
+typedef int (XMLCALL *xmlOutputWriteCallback) (void * context, const char * buffer,
+                                       int len);
+/**
+ * xmlOutputCloseCallback:
+ * @context:  an Output context
+ *
+ * Callback used in the I/O Output API to close the resource
+ *
+ * Returns 0 or -1 in case of error
+ */
+typedef int (XMLCALL *xmlOutputCloseCallback) (void * context);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <libxml/globals.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/encoding.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct _xmlParserInputBuffer {
+    void*                  context;
+    xmlInputReadCallback   readcallback;
+    xmlInputCloseCallback  closecallback;
+    
+    xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+    
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 */
+    xmlBufferPtr raw;       /* if encoder != NULL buffer for raw input */
+    int	compressed;	    /* -1=unknown, 0=not compressed, 1=compressed */
+    int error;
+    unsigned long rawconsumed;/* amount consumed from raw */
+};
+
+
+#ifdef LIBXML_OUTPUT_ENABLED
+struct _xmlOutputBuffer {
+    void*                   context;
+    xmlOutputWriteCallback  writecallback;
+    xmlOutputCloseCallback  closecallback;
+    
+    xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+    
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBufferPtr conv;      /* if encoder != NULL buffer for output */
+    int written;            /* total number of byte written */
+    int error;
+};
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/*
+ * Interfaces for input
+ */
+XMLPUBFUN void XMLCALL	
+	xmlCleanupInputCallbacks		(void);
+
+XMLPUBFUN int XMLCALL
+	xmlPopInputCallbacks			(void);
+
+XMLPUBFUN void XMLCALL	
+	xmlRegisterDefaultInputCallbacks	(void);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlAllocParserInputBuffer		(xmlCharEncoding enc);
+
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateFilename	(const char *URI,
+                                                 xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateFile		(FILE *file,
+                                                 xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateFd		(int fd,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateMem		(const char *mem, int size,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateStatic	(const char *mem, int size,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+	xmlParserInputBufferCreateIO		(xmlInputReadCallback   ioread,
+						 xmlInputCloseCallback  ioclose,
+						 void *ioctx,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN int XMLCALL	
+	xmlParserInputBufferRead		(xmlParserInputBufferPtr in,
+						 int len);
+XMLPUBFUN int XMLCALL	
+	xmlParserInputBufferGrow		(xmlParserInputBufferPtr in,
+						 int len);
+XMLPUBFUN int XMLCALL	
+	xmlParserInputBufferPush		(xmlParserInputBufferPtr in,
+						 int len,
+						 const char *buf);
+XMLPUBFUN void XMLCALL	
+	xmlFreeParserInputBuffer		(xmlParserInputBufferPtr in);
+XMLPUBFUN char * XMLCALL	
+	xmlParserGetDirectory			(const char *filename);
+
+XMLPUBFUN int XMLCALL     
+	xmlRegisterInputCallbacks		(xmlInputMatchCallback matchFunc,
+						 xmlInputOpenCallback openFunc,
+						 xmlInputReadCallback readFunc,
+						 xmlInputCloseCallback closeFunc);
+
+xmlParserInputBufferPtr
+	__xmlParserInputBufferCreateFilename(const char *URI,
+										xmlCharEncoding enc);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Interfaces for output
+ */
+XMLPUBFUN void XMLCALL	
+	xmlCleanupOutputCallbacks		(void);
+XMLPUBFUN void XMLCALL	
+	xmlRegisterDefaultOutputCallbacks(void);
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlAllocOutputBuffer		(xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlOutputBufferCreateFilename	(const char *URI,
+					 xmlCharEncodingHandlerPtr encoder,
+					 int compression);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlOutputBufferCreateFile	(FILE *file,
+					 xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlOutputBufferCreateBuffer	(xmlBufferPtr buffer,
+					 xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlOutputBufferCreateFd		(int fd,
+					 xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
+	xmlOutputBufferCreateIO		(xmlOutputWriteCallback   iowrite,
+					 xmlOutputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN int XMLCALL	
+	xmlOutputBufferWrite		(xmlOutputBufferPtr out,
+					 int len,
+					 const char *buf);
+XMLPUBFUN int XMLCALL	
+	xmlOutputBufferWriteString	(xmlOutputBufferPtr out,
+					 const char *str);
+XMLPUBFUN int XMLCALL	
+	xmlOutputBufferWriteEscape	(xmlOutputBufferPtr out,
+					 const xmlChar *str,
+					 xmlCharEncodingOutputFunc escaping);
+
+XMLPUBFUN int XMLCALL	
+	xmlOutputBufferFlush		(xmlOutputBufferPtr out);
+XMLPUBFUN int XMLCALL	
+	xmlOutputBufferClose		(xmlOutputBufferPtr out);
+
+XMLPUBFUN int XMLCALL     
+	xmlRegisterOutputCallbacks	(xmlOutputMatchCallback matchFunc,
+					 xmlOutputOpenCallback openFunc,
+					 xmlOutputWriteCallback writeFunc,
+					 xmlOutputCloseCallback closeFunc);
+
+xmlOutputBufferPtr
+	__xmlOutputBufferCreateFilename(const char *URI,
+                              xmlCharEncodingHandlerPtr encoder,
+                              int compression);
+
+#ifdef LIBXML_HTTP_ENABLED
+/*  This function only exists if HTTP support built into the library  */
+XMLPUBFUN void XMLCALL	
+	xmlRegisterHTTPPostCallbacks	(void );
+#endif /* LIBXML_HTTP_ENABLED */
+	
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+XMLPUBFUN xmlParserInputPtr XMLCALL
+	xmlCheckHTTPInput		(xmlParserCtxtPtr ctxt,
+					 xmlParserInputPtr ret);
+
+/*
+ * A predefined entity loader disabling network accesses
+ */
+XMLPUBFUN xmlParserInputPtr XMLCALL 
+	xmlNoNetExternalEntityLoader	(const char *URL,
+					 const char *ID,
+					 xmlParserCtxtPtr ctxt);
+
+/* 
+ * xmlNormalizeWindowsPath is obsolete, don't use it. 
+ * Check xmlCanonicPath in uri.h for a better alternative.
+ */
+XMLPUBFUN xmlChar * XMLCALL 
+	xmlNormalizeWindowsPath		(const xmlChar *path);
+
+XMLPUBFUN int XMLCALL	
+	xmlCheckFilename		(const char *path);
+/**
+ * Default 'file://' protocol callbacks 
+ */
+XMLPUBFUN int XMLCALL	
+	xmlFileMatch 			(const char *filename);
+XMLPUBFUN void * XMLCALL	
+	xmlFileOpen 			(const char *filename);
+XMLPUBFUN int XMLCALL	
+	xmlFileRead 			(void * context, 
+					 char * buffer, 
+					 int len);
+XMLPUBFUN int XMLCALL	
+	xmlFileClose 			(void * context);
+
+/**
+ * Default 'http://' protocol callbacks 
+ */
+#ifdef LIBXML_HTTP_ENABLED
+XMLPUBFUN int XMLCALL	
+	xmlIOHTTPMatch 			(const char *filename);
+XMLPUBFUN void * XMLCALL	
+	xmlIOHTTPOpen 			(const char *filename);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void * XMLCALL	
+	xmlIOHTTPOpenW			(const char * post_uri,
+					 int   compression );
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN int XMLCALL 	
+	xmlIOHTTPRead			(void * context, 
+					 char * buffer, 
+					 int len);
+XMLPUBFUN int XMLCALL	
+	xmlIOHTTPClose 			(void * context);
+#endif /* LIBXML_HTTP_ENABLED */
+
+/**
+ * Default 'ftp://' protocol callbacks 
+ */
+#ifdef LIBXML_FTP_ENABLED 
+XMLPUBFUN int XMLCALL	
+	xmlIOFTPMatch 			(const char *filename);
+XMLPUBFUN void * XMLCALL	
+	xmlIOFTPOpen 			(const char *filename);
+XMLPUBFUN int XMLCALL 	
+	xmlIOFTPRead			(void * context, 
+					 char * buffer, 
+					 int len);
+XMLPUBFUN int XMLCALL 	
+	xmlIOFTPClose 			(void * context);
+#endif /* LIBXML_FTP_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_IO_H__ */
diff --git a/src/include/libxml/xmlautomata.h b/src/include/libxml/xmlautomata.h
new file mode 100644
index 0000000..f98b55e
--- /dev/null
+++ b/src/include/libxml/xmlautomata.h
@@ -0,0 +1,146 @@
+/*
+ * Summary: API to build regexp automata
+ * Description: the API to build regexp automata
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_AUTOMATA_H__
+#define __XML_AUTOMATA_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_REGEXP_ENABLED
+#ifdef LIBXML_AUTOMATA_ENABLED
+#include <libxml/xmlregexp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlAutomataPtr:
+ *
+ * A libxml automata description, It can be compiled into a regexp
+ */
+typedef struct _xmlAutomata xmlAutomata;
+typedef xmlAutomata *xmlAutomataPtr;
+
+/**
+ * xmlAutomataStatePtr:
+ *
+ * A state int the automata description,
+ */
+typedef struct _xmlAutomataState xmlAutomataState;
+typedef xmlAutomataState *xmlAutomataStatePtr;
+
+/*
+ * Building API
+ */
+XMLPUBFUN xmlAutomataPtr XMLCALL		
+		    xmlNewAutomata		(void);
+XMLPUBFUN void XMLCALL			
+		    xmlFreeAutomata		(xmlAutomataPtr am);
+
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataGetInitState	(xmlAutomataPtr am);
+XMLPUBFUN int XMLCALL			
+		    xmlAutomataSetFinalState	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr state);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewState		(xmlAutomataPtr am);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewTransition	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewTransition2	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL
+                    xmlAutomataNewNegTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 void *data);
+
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewCountTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 int min,
+						 int max,
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewCountTrans2	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 int min,
+						 int max,
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewOnceTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 const xmlChar *token,
+						 int min,
+						 int max,
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL
+		    xmlAutomataNewOnceTrans2	(xmlAutomataPtr am, 
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to, 
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 int min, 
+						 int max, 
+						 void *data);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewAllTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 int lax);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewEpsilon	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewCountedTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 int counter);
+XMLPUBFUN xmlAutomataStatePtr XMLCALL	
+		    xmlAutomataNewCounterTrans	(xmlAutomataPtr am,
+						 xmlAutomataStatePtr from,
+						 xmlAutomataStatePtr to,
+						 int counter);
+XMLPUBFUN int XMLCALL			
+		    xmlAutomataNewCounter	(xmlAutomataPtr am,
+						 int min,
+						 int max);
+
+XMLPUBFUN xmlRegexpPtr XMLCALL		
+		    xmlAutomataCompile		(xmlAutomataPtr am);
+XMLPUBFUN int XMLCALL	    		
+		    xmlAutomataIsDeterminist	(xmlAutomataPtr am);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /* LIBXML_AUTOMATA_ENABLED */
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /* __XML_AUTOMATA_H__ */
diff --git a/src/include/libxml/xmlerror.h b/src/include/libxml/xmlerror.h
new file mode 100644
index 0000000..10be606
--- /dev/null
+++ b/src/include/libxml/xmlerror.h
@@ -0,0 +1,945 @@
+/*
+ * Summary: error handling
+ * Description: the API used to report errors
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#include <libxml/parser.h>
+
+#ifndef __XML_ERROR_H__
+#define __XML_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlErrorLevel:
+ *
+ * Indicates the level of an error
+ */
+typedef enum {
+    XML_ERR_NONE = 0,
+    XML_ERR_WARNING = 1,	/* A simple warning */
+    XML_ERR_ERROR = 2,		/* A recoverable error */
+    XML_ERR_FATAL = 3		/* A fatal error */
+} xmlErrorLevel;
+
+/**
+ * xmlErrorDomain:
+ *
+ * Indicates where an error may have come from
+ */
+typedef enum {
+    XML_FROM_NONE = 0,
+    XML_FROM_PARSER,	/* The XML parser */
+    XML_FROM_TREE,	/* The tree module */
+    XML_FROM_NAMESPACE,	/* The XML Namespace module */
+    XML_FROM_DTD,	/* The XML DTD validation with parser context*/
+    XML_FROM_HTML,	/* The HTML parser */
+    XML_FROM_MEMORY,	/* The memory allocator */
+    XML_FROM_OUTPUT,	/* The serialization code */
+    XML_FROM_IO,	/* The Input/Output stack */
+    XML_FROM_FTP,	/* The FTP module */
+    XML_FROM_HTTP,	/* The HTTP module */
+    XML_FROM_XINCLUDE,	/* The XInclude processing */
+    XML_FROM_XPATH,	/* The XPath module */
+    XML_FROM_XPOINTER,	/* The XPointer module */
+    XML_FROM_REGEXP,	/* The regular expressions module */
+    XML_FROM_DATATYPE,	/* The W3C XML Schemas Datatype module */
+    XML_FROM_SCHEMASP,	/* The W3C XML Schemas parser module */
+    XML_FROM_SCHEMASV,	/* The W3C XML Schemas validation module */
+    XML_FROM_RELAXNGP,	/* The Relax-NG parser module */
+    XML_FROM_RELAXNGV,	/* The Relax-NG validator module */
+    XML_FROM_CATALOG,	/* The Catalog module */
+    XML_FROM_C14N,	/* The Canonicalization module */
+    XML_FROM_XSLT,	/* The XSLT engine from libxslt */
+    XML_FROM_VALID,	/* The XML DTD validation with valid context */
+    XML_FROM_CHECK,	/* The error checking module */
+    XML_FROM_WRITER,	/* The xmlwriter module */
+    XML_FROM_MODULE,	/* The dynamically loaded module module*/
+    XML_FROM_I18N,	/* The module handling character conversion */
+    XML_FROM_SCHEMATRONV	/* The Schematron validator module */
+} xmlErrorDomain;
+
+/**
+ * xmlError:
+ *
+ * An XML Error instance.
+ */
+
+typedef struct _xmlError xmlError;
+typedef xmlError *xmlErrorPtr;
+struct _xmlError {
+    int		domain;	/* What part of the library raised this error */
+    int		code;	/* The error code, e.g. an xmlParserError */
+    char       *message;/* human-readable informative error message */
+    xmlErrorLevel level;/* how consequent is the error */
+    char       *file;	/* the filename */
+    int		line;	/* the line number if available */
+    char       *str1;	/* extra string information */
+    char       *str2;	/* extra string information */
+    char       *str3;	/* extra string information */
+    int		int1;	/* extra number information */
+    int		int2;	/* column number of the error or 0 if N/A (todo: rename this field when we would break ABI) */
+    void       *ctxt;   /* the parser context if available */
+    void       *node;   /* the node in the tree */
+};
+
+/**
+ * xmlParserError:
+ *
+ * This is an error that the XML (or HTML) parser can generate
+ */
+typedef enum {
+    XML_ERR_OK = 0,
+    XML_ERR_INTERNAL_ERROR, /* 1 */
+    XML_ERR_NO_MEMORY, /* 2 */
+    XML_ERR_DOCUMENT_START, /* 3 */
+    XML_ERR_DOCUMENT_EMPTY, /* 4 */
+    XML_ERR_DOCUMENT_END, /* 5 */
+    XML_ERR_INVALID_HEX_CHARREF, /* 6 */
+    XML_ERR_INVALID_DEC_CHARREF, /* 7 */
+    XML_ERR_INVALID_CHARREF, /* 8 */
+    XML_ERR_INVALID_CHAR, /* 9 */
+    XML_ERR_CHARREF_AT_EOF, /* 10 */
+    XML_ERR_CHARREF_IN_PROLOG, /* 11 */
+    XML_ERR_CHARREF_IN_EPILOG, /* 12 */
+    XML_ERR_CHARREF_IN_DTD, /* 13 */
+    XML_ERR_ENTITYREF_AT_EOF, /* 14 */
+    XML_ERR_ENTITYREF_IN_PROLOG, /* 15 */
+    XML_ERR_ENTITYREF_IN_EPILOG, /* 16 */
+    XML_ERR_ENTITYREF_IN_DTD, /* 17 */
+    XML_ERR_PEREF_AT_EOF, /* 18 */
+    XML_ERR_PEREF_IN_PROLOG, /* 19 */
+    XML_ERR_PEREF_IN_EPILOG, /* 20 */
+    XML_ERR_PEREF_IN_INT_SUBSET, /* 21 */
+    XML_ERR_ENTITYREF_NO_NAME, /* 22 */
+    XML_ERR_ENTITYREF_SEMICOL_MISSING, /* 23 */
+    XML_ERR_PEREF_NO_NAME, /* 24 */
+    XML_ERR_PEREF_SEMICOL_MISSING, /* 25 */
+    XML_ERR_UNDECLARED_ENTITY, /* 26 */
+    XML_WAR_UNDECLARED_ENTITY, /* 27 */
+    XML_ERR_UNPARSED_ENTITY, /* 28 */
+    XML_ERR_ENTITY_IS_EXTERNAL, /* 29 */
+    XML_ERR_ENTITY_IS_PARAMETER, /* 30 */
+    XML_ERR_UNKNOWN_ENCODING, /* 31 */
+    XML_ERR_UNSUPPORTED_ENCODING, /* 32 */
+    XML_ERR_STRING_NOT_STARTED, /* 33 */
+    XML_ERR_STRING_NOT_CLOSED, /* 34 */
+    XML_ERR_NS_DECL_ERROR, /* 35 */
+    XML_ERR_ENTITY_NOT_STARTED, /* 36 */
+    XML_ERR_ENTITY_NOT_FINISHED, /* 37 */
+    XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
+    XML_ERR_ATTRIBUTE_NOT_STARTED, /* 39 */
+    XML_ERR_ATTRIBUTE_NOT_FINISHED, /* 40 */
+    XML_ERR_ATTRIBUTE_WITHOUT_VALUE, /* 41 */
+    XML_ERR_ATTRIBUTE_REDEFINED, /* 42 */
+    XML_ERR_LITERAL_NOT_STARTED, /* 43 */
+    XML_ERR_LITERAL_NOT_FINISHED, /* 44 */
+    XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
+    XML_ERR_PI_NOT_STARTED, /* 46 */
+    XML_ERR_PI_NOT_FINISHED, /* 47 */
+    XML_ERR_NOTATION_NOT_STARTED, /* 48 */
+    XML_ERR_NOTATION_NOT_FINISHED, /* 49 */
+    XML_ERR_ATTLIST_NOT_STARTED, /* 50 */
+    XML_ERR_ATTLIST_NOT_FINISHED, /* 51 */
+    XML_ERR_MIXED_NOT_STARTED, /* 52 */
+    XML_ERR_MIXED_NOT_FINISHED, /* 53 */
+    XML_ERR_ELEMCONTENT_NOT_STARTED, /* 54 */
+    XML_ERR_ELEMCONTENT_NOT_FINISHED, /* 55 */
+    XML_ERR_XMLDECL_NOT_STARTED, /* 56 */
+    XML_ERR_XMLDECL_NOT_FINISHED, /* 57 */
+    XML_ERR_CONDSEC_NOT_STARTED, /* 58 */
+    XML_ERR_CONDSEC_NOT_FINISHED, /* 59 */
+    XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 60 */
+    XML_ERR_DOCTYPE_NOT_FINISHED, /* 61 */
+    XML_ERR_MISPLACED_CDATA_END, /* 62 */
+    XML_ERR_CDATA_NOT_FINISHED, /* 63 */
+    XML_ERR_RESERVED_XML_NAME, /* 64 */
+    XML_ERR_SPACE_REQUIRED, /* 65 */
+    XML_ERR_SEPARATOR_REQUIRED, /* 66 */
+    XML_ERR_NMTOKEN_REQUIRED, /* 67 */
+    XML_ERR_NAME_REQUIRED, /* 68 */
+    XML_ERR_PCDATA_REQUIRED, /* 69 */
+    XML_ERR_URI_REQUIRED, /* 70 */
+    XML_ERR_PUBID_REQUIRED, /* 71 */
+    XML_ERR_LT_REQUIRED, /* 72 */
+    XML_ERR_GT_REQUIRED, /* 73 */
+    XML_ERR_LTSLASH_REQUIRED, /* 74 */
+    XML_ERR_EQUAL_REQUIRED, /* 75 */
+    XML_ERR_TAG_NAME_MISMATCH, /* 76 */
+    XML_ERR_TAG_NOT_FINISHED, /* 77 */
+    XML_ERR_STANDALONE_VALUE, /* 78 */
+    XML_ERR_ENCODING_NAME, /* 79 */
+    XML_ERR_HYPHEN_IN_COMMENT, /* 80 */
+    XML_ERR_INVALID_ENCODING, /* 81 */
+    XML_ERR_EXT_ENTITY_STANDALONE, /* 82 */
+    XML_ERR_CONDSEC_INVALID, /* 83 */
+    XML_ERR_VALUE_REQUIRED, /* 84 */
+    XML_ERR_NOT_WELL_BALANCED, /* 85 */
+    XML_ERR_EXTRA_CONTENT, /* 86 */
+    XML_ERR_ENTITY_CHAR_ERROR, /* 87 */
+    XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
+    XML_ERR_ENTITY_LOOP, /* 89 */
+    XML_ERR_ENTITY_BOUNDARY, /* 90 */
+    XML_ERR_INVALID_URI, /* 91 */
+    XML_ERR_URI_FRAGMENT, /* 92 */
+    XML_WAR_CATALOG_PI, /* 93 */
+    XML_ERR_NO_DTD, /* 94 */
+    XML_ERR_CONDSEC_INVALID_KEYWORD, /* 95 */
+    XML_ERR_VERSION_MISSING, /* 96 */
+    XML_WAR_UNKNOWN_VERSION, /* 97 */
+    XML_WAR_LANG_VALUE, /* 98 */
+    XML_WAR_NS_URI, /* 99 */
+    XML_WAR_NS_URI_RELATIVE, /* 100 */
+    XML_ERR_MISSING_ENCODING, /* 101 */
+    XML_WAR_SPACE_VALUE, /* 102 */
+    XML_ERR_NOT_STANDALONE, /* 103 */
+    XML_ERR_ENTITY_PROCESSING, /* 104 */
+    XML_ERR_NOTATION_PROCESSING, /* 105 */
+    XML_WAR_NS_COLUMN, /* 106 */
+    XML_WAR_ENTITY_REDEFINED, /* 107 */
+    XML_ERR_UNKNOWN_VERSION, /* 108 */
+    XML_ERR_VERSION_MISMATCH, /* 109 */
+    XML_ERR_USER_STOP, /* 110 */
+    XML_NS_ERR_XML_NAMESPACE = 200,
+    XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
+    XML_NS_ERR_QNAME, /* 202 */
+    XML_NS_ERR_ATTRIBUTE_REDEFINED, /* 203 */
+    XML_NS_ERR_EMPTY, /* 204 */
+    XML_NS_ERR_COLON, /* 205 */
+    XML_DTD_ATTRIBUTE_DEFAULT = 500,
+    XML_DTD_ATTRIBUTE_REDEFINED, /* 501 */
+    XML_DTD_ATTRIBUTE_VALUE, /* 502 */
+    XML_DTD_CONTENT_ERROR, /* 503 */
+    XML_DTD_CONTENT_MODEL, /* 504 */
+    XML_DTD_CONTENT_NOT_DETERMINIST, /* 505 */
+    XML_DTD_DIFFERENT_PREFIX, /* 506 */
+    XML_DTD_ELEM_DEFAULT_NAMESPACE, /* 507 */
+    XML_DTD_ELEM_NAMESPACE, /* 508 */
+    XML_DTD_ELEM_REDEFINED, /* 509 */
+    XML_DTD_EMPTY_NOTATION, /* 510 */
+    XML_DTD_ENTITY_TYPE, /* 511 */
+    XML_DTD_ID_FIXED, /* 512 */
+    XML_DTD_ID_REDEFINED, /* 513 */
+    XML_DTD_ID_SUBSET, /* 514 */
+    XML_DTD_INVALID_CHILD, /* 515 */
+    XML_DTD_INVALID_DEFAULT, /* 516 */
+    XML_DTD_LOAD_ERROR, /* 517 */
+    XML_DTD_MISSING_ATTRIBUTE, /* 518 */
+    XML_DTD_MIXED_CORRUPT, /* 519 */
+    XML_DTD_MULTIPLE_ID, /* 520 */
+    XML_DTD_NO_DOC, /* 521 */
+    XML_DTD_NO_DTD, /* 522 */
+    XML_DTD_NO_ELEM_NAME, /* 523 */
+    XML_DTD_NO_PREFIX, /* 524 */
+    XML_DTD_NO_ROOT, /* 525 */
+    XML_DTD_NOTATION_REDEFINED, /* 526 */
+    XML_DTD_NOTATION_VALUE, /* 527 */
+    XML_DTD_NOT_EMPTY, /* 528 */
+    XML_DTD_NOT_PCDATA, /* 529 */
+    XML_DTD_NOT_STANDALONE, /* 530 */
+    XML_DTD_ROOT_NAME, /* 531 */
+    XML_DTD_STANDALONE_WHITE_SPACE, /* 532 */
+    XML_DTD_UNKNOWN_ATTRIBUTE, /* 533 */
+    XML_DTD_UNKNOWN_ELEM, /* 534 */
+    XML_DTD_UNKNOWN_ENTITY, /* 535 */
+    XML_DTD_UNKNOWN_ID, /* 536 */
+    XML_DTD_UNKNOWN_NOTATION, /* 537 */
+    XML_DTD_STANDALONE_DEFAULTED, /* 538 */
+    XML_DTD_XMLID_VALUE, /* 539 */
+    XML_DTD_XMLID_TYPE, /* 540 */
+    XML_DTD_DUP_TOKEN, /* 541 */
+    XML_HTML_STRUCURE_ERROR = 800,
+    XML_HTML_UNKNOWN_TAG, /* 801 */
+    XML_RNGP_ANYNAME_ATTR_ANCESTOR = 1000,
+    XML_RNGP_ATTR_CONFLICT, /* 1001 */
+    XML_RNGP_ATTRIBUTE_CHILDREN, /* 1002 */
+    XML_RNGP_ATTRIBUTE_CONTENT, /* 1003 */
+    XML_RNGP_ATTRIBUTE_EMPTY, /* 1004 */
+    XML_RNGP_ATTRIBUTE_NOOP, /* 1005 */
+    XML_RNGP_CHOICE_CONTENT, /* 1006 */
+    XML_RNGP_CHOICE_EMPTY, /* 1007 */
+    XML_RNGP_CREATE_FAILURE, /* 1008 */
+    XML_RNGP_DATA_CONTENT, /* 1009 */
+    XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, /* 1010 */
+    XML_RNGP_DEFINE_CREATE_FAILED, /* 1011 */
+    XML_RNGP_DEFINE_EMPTY, /* 1012 */
+    XML_RNGP_DEFINE_MISSING, /* 1013 */
+    XML_RNGP_DEFINE_NAME_MISSING, /* 1014 */
+    XML_RNGP_ELEM_CONTENT_EMPTY, /* 1015 */
+    XML_RNGP_ELEM_CONTENT_ERROR, /* 1016 */
+    XML_RNGP_ELEMENT_EMPTY, /* 1017 */
+    XML_RNGP_ELEMENT_CONTENT, /* 1018 */
+    XML_RNGP_ELEMENT_NAME, /* 1019 */
+    XML_RNGP_ELEMENT_NO_CONTENT, /* 1020 */
+    XML_RNGP_ELEM_TEXT_CONFLICT, /* 1021 */
+    XML_RNGP_EMPTY, /* 1022 */
+    XML_RNGP_EMPTY_CONSTRUCT, /* 1023 */
+    XML_RNGP_EMPTY_CONTENT, /* 1024 */
+    XML_RNGP_EMPTY_NOT_EMPTY, /* 1025 */
+    XML_RNGP_ERROR_TYPE_LIB, /* 1026 */
+    XML_RNGP_EXCEPT_EMPTY, /* 1027 */
+    XML_RNGP_EXCEPT_MISSING, /* 1028 */
+    XML_RNGP_EXCEPT_MULTIPLE, /* 1029 */
+    XML_RNGP_EXCEPT_NO_CONTENT, /* 1030 */
+    XML_RNGP_EXTERNALREF_EMTPY, /* 1031 */
+    XML_RNGP_EXTERNAL_REF_FAILURE, /* 1032 */
+    XML_RNGP_EXTERNALREF_RECURSE, /* 1033 */
+    XML_RNGP_FORBIDDEN_ATTRIBUTE, /* 1034 */
+    XML_RNGP_FOREIGN_ELEMENT, /* 1035 */
+    XML_RNGP_GRAMMAR_CONTENT, /* 1036 */
+    XML_RNGP_GRAMMAR_EMPTY, /* 1037 */
+    XML_RNGP_GRAMMAR_MISSING, /* 1038 */
+    XML_RNGP_GRAMMAR_NO_START, /* 1039 */
+    XML_RNGP_GROUP_ATTR_CONFLICT, /* 1040 */
+    XML_RNGP_HREF_ERROR, /* 1041 */
+    XML_RNGP_INCLUDE_EMPTY, /* 1042 */
+    XML_RNGP_INCLUDE_FAILURE, /* 1043 */
+    XML_RNGP_INCLUDE_RECURSE, /* 1044 */
+    XML_RNGP_INTERLEAVE_ADD, /* 1045 */
+    XML_RNGP_INTERLEAVE_CREATE_FAILED, /* 1046 */
+    XML_RNGP_INTERLEAVE_EMPTY, /* 1047 */
+    XML_RNGP_INTERLEAVE_NO_CONTENT, /* 1048 */
+    XML_RNGP_INVALID_DEFINE_NAME, /* 1049 */
+    XML_RNGP_INVALID_URI, /* 1050 */
+    XML_RNGP_INVALID_VALUE, /* 1051 */
+    XML_RNGP_MISSING_HREF, /* 1052 */
+    XML_RNGP_NAME_MISSING, /* 1053 */
+    XML_RNGP_NEED_COMBINE, /* 1054 */
+    XML_RNGP_NOTALLOWED_NOT_EMPTY, /* 1055 */
+    XML_RNGP_NSNAME_ATTR_ANCESTOR, /* 1056 */
+    XML_RNGP_NSNAME_NO_NS, /* 1057 */
+    XML_RNGP_PARAM_FORBIDDEN, /* 1058 */
+    XML_RNGP_PARAM_NAME_MISSING, /* 1059 */
+    XML_RNGP_PARENTREF_CREATE_FAILED, /* 1060 */
+    XML_RNGP_PARENTREF_NAME_INVALID, /* 1061 */
+    XML_RNGP_PARENTREF_NO_NAME, /* 1062 */
+    XML_RNGP_PARENTREF_NO_PARENT, /* 1063 */
+    XML_RNGP_PARENTREF_NOT_EMPTY, /* 1064 */
+    XML_RNGP_PARSE_ERROR, /* 1065 */
+    XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, /* 1066 */
+    XML_RNGP_PAT_ATTR_ATTR, /* 1067 */
+    XML_RNGP_PAT_ATTR_ELEM, /* 1068 */
+    XML_RNGP_PAT_DATA_EXCEPT_ATTR, /* 1069 */
+    XML_RNGP_PAT_DATA_EXCEPT_ELEM, /* 1070 */
+    XML_RNGP_PAT_DATA_EXCEPT_EMPTY, /* 1071 */
+    XML_RNGP_PAT_DATA_EXCEPT_GROUP, /* 1072 */
+    XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, /* 1073 */
+    XML_RNGP_PAT_DATA_EXCEPT_LIST, /* 1074 */
+    XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, /* 1075 */
+    XML_RNGP_PAT_DATA_EXCEPT_REF, /* 1076 */
+    XML_RNGP_PAT_DATA_EXCEPT_TEXT, /* 1077 */
+    XML_RNGP_PAT_LIST_ATTR, /* 1078 */
+    XML_RNGP_PAT_LIST_ELEM, /* 1079 */
+    XML_RNGP_PAT_LIST_INTERLEAVE, /* 1080 */
+    XML_RNGP_PAT_LIST_LIST, /* 1081 */
+    XML_RNGP_PAT_LIST_REF, /* 1082 */
+    XML_RNGP_PAT_LIST_TEXT, /* 1083 */
+    XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, /* 1084 */
+    XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, /* 1085 */
+    XML_RNGP_PAT_ONEMORE_GROUP_ATTR, /* 1086 */
+    XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, /* 1087 */
+    XML_RNGP_PAT_START_ATTR, /* 1088 */
+    XML_RNGP_PAT_START_DATA, /* 1089 */
+    XML_RNGP_PAT_START_EMPTY, /* 1090 */
+    XML_RNGP_PAT_START_GROUP, /* 1091 */
+    XML_RNGP_PAT_START_INTERLEAVE, /* 1092 */
+    XML_RNGP_PAT_START_LIST, /* 1093 */
+    XML_RNGP_PAT_START_ONEMORE, /* 1094 */
+    XML_RNGP_PAT_START_TEXT, /* 1095 */
+    XML_RNGP_PAT_START_VALUE, /* 1096 */
+    XML_RNGP_PREFIX_UNDEFINED, /* 1097 */
+    XML_RNGP_REF_CREATE_FAILED, /* 1098 */
+    XML_RNGP_REF_CYCLE, /* 1099 */
+    XML_RNGP_REF_NAME_INVALID, /* 1100 */
+    XML_RNGP_REF_NO_DEF, /* 1101 */
+    XML_RNGP_REF_NO_NAME, /* 1102 */
+    XML_RNGP_REF_NOT_EMPTY, /* 1103 */
+    XML_RNGP_START_CHOICE_AND_INTERLEAVE, /* 1104 */
+    XML_RNGP_START_CONTENT, /* 1105 */
+    XML_RNGP_START_EMPTY, /* 1106 */
+    XML_RNGP_START_MISSING, /* 1107 */
+    XML_RNGP_TEXT_EXPECTED, /* 1108 */
+    XML_RNGP_TEXT_HAS_CHILD, /* 1109 */
+    XML_RNGP_TYPE_MISSING, /* 1110 */
+    XML_RNGP_TYPE_NOT_FOUND, /* 1111 */
+    XML_RNGP_TYPE_VALUE, /* 1112 */
+    XML_RNGP_UNKNOWN_ATTRIBUTE, /* 1113 */
+    XML_RNGP_UNKNOWN_COMBINE, /* 1114 */
+    XML_RNGP_UNKNOWN_CONSTRUCT, /* 1115 */
+    XML_RNGP_UNKNOWN_TYPE_LIB, /* 1116 */
+    XML_RNGP_URI_FRAGMENT, /* 1117 */
+    XML_RNGP_URI_NOT_ABSOLUTE, /* 1118 */
+    XML_RNGP_VALUE_EMPTY, /* 1119 */
+    XML_RNGP_VALUE_NO_CONTENT, /* 1120 */
+    XML_RNGP_XMLNS_NAME, /* 1121 */
+    XML_RNGP_XML_NS, /* 1122 */
+    XML_XPATH_EXPRESSION_OK = 1200,
+    XML_XPATH_NUMBER_ERROR, /* 1201 */
+    XML_XPATH_UNFINISHED_LITERAL_ERROR, /* 1202 */
+    XML_XPATH_START_LITERAL_ERROR, /* 1203 */
+    XML_XPATH_VARIABLE_REF_ERROR, /* 1204 */
+    XML_XPATH_UNDEF_VARIABLE_ERROR, /* 1205 */
+    XML_XPATH_INVALID_PREDICATE_ERROR, /* 1206 */
+    XML_XPATH_EXPR_ERROR, /* 1207 */
+    XML_XPATH_UNCLOSED_ERROR, /* 1208 */
+    XML_XPATH_UNKNOWN_FUNC_ERROR, /* 1209 */
+    XML_XPATH_INVALID_OPERAND, /* 1210 */
+    XML_XPATH_INVALID_TYPE, /* 1211 */
+    XML_XPATH_INVALID_ARITY, /* 1212 */
+    XML_XPATH_INVALID_CTXT_SIZE, /* 1213 */
+    XML_XPATH_INVALID_CTXT_POSITION, /* 1214 */
+    XML_XPATH_MEMORY_ERROR, /* 1215 */
+    XML_XPTR_SYNTAX_ERROR, /* 1216 */
+    XML_XPTR_RESOURCE_ERROR, /* 1217 */
+    XML_XPTR_SUB_RESOURCE_ERROR, /* 1218 */
+    XML_XPATH_UNDEF_PREFIX_ERROR, /* 1219 */
+    XML_XPATH_ENCODING_ERROR, /* 1220 */
+    XML_XPATH_INVALID_CHAR_ERROR, /* 1221 */
+    XML_TREE_INVALID_HEX = 1300,
+    XML_TREE_INVALID_DEC, /* 1301 */
+    XML_TREE_UNTERMINATED_ENTITY, /* 1302 */
+    XML_TREE_NOT_UTF8, /* 1303 */
+    XML_SAVE_NOT_UTF8 = 1400,
+    XML_SAVE_CHAR_INVALID, /* 1401 */
+    XML_SAVE_NO_DOCTYPE, /* 1402 */
+    XML_SAVE_UNKNOWN_ENCODING, /* 1403 */
+    XML_REGEXP_COMPILE_ERROR = 1450,
+    XML_IO_UNKNOWN = 1500,
+    XML_IO_EACCES, /* 1501 */
+    XML_IO_EAGAIN, /* 1502 */
+    XML_IO_EBADF, /* 1503 */
+    XML_IO_EBADMSG, /* 1504 */
+    XML_IO_EBUSY, /* 1505 */
+    XML_IO_ECANCELED, /* 1506 */
+    XML_IO_ECHILD, /* 1507 */
+    XML_IO_EDEADLK, /* 1508 */
+    XML_IO_EDOM, /* 1509 */
+    XML_IO_EEXIST, /* 1510 */
+    XML_IO_EFAULT, /* 1511 */
+    XML_IO_EFBIG, /* 1512 */
+    XML_IO_EINPROGRESS, /* 1513 */
+    XML_IO_EINTR, /* 1514 */
+    XML_IO_EINVAL, /* 1515 */
+    XML_IO_EIO, /* 1516 */
+    XML_IO_EISDIR, /* 1517 */
+    XML_IO_EMFILE, /* 1518 */
+    XML_IO_EMLINK, /* 1519 */
+    XML_IO_EMSGSIZE, /* 1520 */
+    XML_IO_ENAMETOOLONG, /* 1521 */
+    XML_IO_ENFILE, /* 1522 */
+    XML_IO_ENODEV, /* 1523 */
+    XML_IO_ENOENT, /* 1524 */
+    XML_IO_ENOEXEC, /* 1525 */
+    XML_IO_ENOLCK, /* 1526 */
+    XML_IO_ENOMEM, /* 1527 */
+    XML_IO_ENOSPC, /* 1528 */
+    XML_IO_ENOSYS, /* 1529 */
+    XML_IO_ENOTDIR, /* 1530 */
+    XML_IO_ENOTEMPTY, /* 1531 */
+    XML_IO_ENOTSUP, /* 1532 */
+    XML_IO_ENOTTY, /* 1533 */
+    XML_IO_ENXIO, /* 1534 */
+    XML_IO_EPERM, /* 1535 */
+    XML_IO_EPIPE, /* 1536 */
+    XML_IO_ERANGE, /* 1537 */
+    XML_IO_EROFS, /* 1538 */
+    XML_IO_ESPIPE, /* 1539 */
+    XML_IO_ESRCH, /* 1540 */
+    XML_IO_ETIMEDOUT, /* 1541 */
+    XML_IO_EXDEV, /* 1542 */
+    XML_IO_NETWORK_ATTEMPT, /* 1543 */
+    XML_IO_ENCODER, /* 1544 */
+    XML_IO_FLUSH, /* 1545 */
+    XML_IO_WRITE, /* 1546 */
+    XML_IO_NO_INPUT, /* 1547 */
+    XML_IO_BUFFER_FULL, /* 1548 */
+    XML_IO_LOAD_ERROR, /* 1549 */
+    XML_IO_ENOTSOCK, /* 1550 */
+    XML_IO_EISCONN, /* 1551 */
+    XML_IO_ECONNREFUSED, /* 1552 */
+    XML_IO_ENETUNREACH, /* 1553 */
+    XML_IO_EADDRINUSE, /* 1554 */
+    XML_IO_EALREADY, /* 1555 */
+    XML_IO_EAFNOSUPPORT, /* 1556 */
+    XML_XINCLUDE_RECURSION=1600,
+    XML_XINCLUDE_PARSE_VALUE, /* 1601 */
+    XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */
+    XML_XINCLUDE_NO_HREF, /* 1603 */
+    XML_XINCLUDE_NO_FALLBACK, /* 1604 */
+    XML_XINCLUDE_HREF_URI, /* 1605 */
+    XML_XINCLUDE_TEXT_FRAGMENT, /* 1606 */
+    XML_XINCLUDE_TEXT_DOCUMENT, /* 1607 */
+    XML_XINCLUDE_INVALID_CHAR, /* 1608 */
+    XML_XINCLUDE_BUILD_FAILED, /* 1609 */
+    XML_XINCLUDE_UNKNOWN_ENCODING, /* 1610 */
+    XML_XINCLUDE_MULTIPLE_ROOT, /* 1611 */
+    XML_XINCLUDE_XPTR_FAILED, /* 1612 */
+    XML_XINCLUDE_XPTR_RESULT, /* 1613 */
+    XML_XINCLUDE_INCLUDE_IN_INCLUDE, /* 1614 */
+    XML_XINCLUDE_FALLBACKS_IN_INCLUDE, /* 1615 */
+    XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, /* 1616 */
+    XML_XINCLUDE_DEPRECATED_NS, /* 1617 */
+    XML_XINCLUDE_FRAGMENT_ID, /* 1618 */
+    XML_CATALOG_MISSING_ATTR = 1650,
+    XML_CATALOG_ENTRY_BROKEN, /* 1651 */
+    XML_CATALOG_PREFER_VALUE, /* 1652 */
+    XML_CATALOG_NOT_CATALOG, /* 1653 */
+    XML_CATALOG_RECURSION, /* 1654 */
+    XML_SCHEMAP_PREFIX_UNDEFINED = 1700,
+    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, /* 1701 */
+    XML_SCHEMAP_ATTRGRP_NONAME_NOREF, /* 1702 */
+    XML_SCHEMAP_ATTR_NONAME_NOREF, /* 1703 */
+    XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, /* 1704 */
+    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, /* 1705 */
+    XML_SCHEMAP_ELEM_NONAME_NOREF, /* 1706 */
+    XML_SCHEMAP_EXTENSION_NO_BASE, /* 1707 */
+    XML_SCHEMAP_FACET_NO_VALUE, /* 1708 */
+    XML_SCHEMAP_FAILED_BUILD_IMPORT, /* 1709 */
+    XML_SCHEMAP_GROUP_NONAME_NOREF, /* 1710 */
+    XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, /* 1711 */
+    XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, /* 1712 */
+    XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, /* 1713 */
+    XML_SCHEMAP_INVALID_BOOLEAN, /* 1714 */
+    XML_SCHEMAP_INVALID_ENUM, /* 1715 */
+    XML_SCHEMAP_INVALID_FACET, /* 1716 */
+    XML_SCHEMAP_INVALID_FACET_VALUE, /* 1717 */
+    XML_SCHEMAP_INVALID_MAXOCCURS, /* 1718 */
+    XML_SCHEMAP_INVALID_MINOCCURS, /* 1719 */
+    XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, /* 1720 */
+    XML_SCHEMAP_INVALID_WHITE_SPACE, /* 1721 */
+    XML_SCHEMAP_NOATTR_NOREF, /* 1722 */
+    XML_SCHEMAP_NOTATION_NO_NAME, /* 1723 */
+    XML_SCHEMAP_NOTYPE_NOREF, /* 1724 */
+    XML_SCHEMAP_REF_AND_SUBTYPE, /* 1725 */
+    XML_SCHEMAP_RESTRICTION_NONAME_NOREF, /* 1726 */
+    XML_SCHEMAP_SIMPLETYPE_NONAME, /* 1727 */
+    XML_SCHEMAP_TYPE_AND_SUBTYPE, /* 1728 */
+    XML_SCHEMAP_UNKNOWN_ALL_CHILD, /* 1729 */
+    XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, /* 1730 */
+    XML_SCHEMAP_UNKNOWN_ATTR_CHILD, /* 1731 */
+    XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, /* 1732 */
+    XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, /* 1733 */
+    XML_SCHEMAP_UNKNOWN_BASE_TYPE, /* 1734 */
+    XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, /* 1735 */
+    XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, /* 1736 */
+    XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, /* 1737 */
+    XML_SCHEMAP_UNKNOWN_ELEM_CHILD, /* 1738 */
+    XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, /* 1739 */
+    XML_SCHEMAP_UNKNOWN_FACET_CHILD, /* 1740 */
+    XML_SCHEMAP_UNKNOWN_FACET_TYPE, /* 1741 */
+    XML_SCHEMAP_UNKNOWN_GROUP_CHILD, /* 1742 */
+    XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, /* 1743 */
+    XML_SCHEMAP_UNKNOWN_LIST_CHILD, /* 1744 */
+    XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, /* 1745 */
+    XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, /* 1746 */
+    XML_SCHEMAP_UNKNOWN_REF, /* 1747 */
+    XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, /* 1748 */
+    XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, /* 1749 */
+    XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, /* 1750 */
+    XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, /* 1751 */
+    XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, /* 1752 */
+    XML_SCHEMAP_UNKNOWN_TYPE, /* 1753 */
+    XML_SCHEMAP_UNKNOWN_UNION_CHILD, /* 1754 */
+    XML_SCHEMAP_ELEM_DEFAULT_FIXED, /* 1755 */
+    XML_SCHEMAP_REGEXP_INVALID, /* 1756 */
+    XML_SCHEMAP_FAILED_LOAD, /* 1757 */
+    XML_SCHEMAP_NOTHING_TO_PARSE, /* 1758 */
+    XML_SCHEMAP_NOROOT, /* 1759 */
+    XML_SCHEMAP_REDEFINED_GROUP, /* 1760 */
+    XML_SCHEMAP_REDEFINED_TYPE, /* 1761 */
+    XML_SCHEMAP_REDEFINED_ELEMENT, /* 1762 */
+    XML_SCHEMAP_REDEFINED_ATTRGROUP, /* 1763 */
+    XML_SCHEMAP_REDEFINED_ATTR, /* 1764 */
+    XML_SCHEMAP_REDEFINED_NOTATION, /* 1765 */
+    XML_SCHEMAP_FAILED_PARSE, /* 1766 */
+    XML_SCHEMAP_UNKNOWN_PREFIX, /* 1767 */
+    XML_SCHEMAP_DEF_AND_PREFIX, /* 1768 */
+    XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, /* 1769 */
+    XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, /* 1770 */
+    XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, /* 1771 */
+    XML_SCHEMAP_NOT_SCHEMA, /* 1772 */
+    XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, /* 1773 */
+    XML_SCHEMAP_INVALID_ATTR_USE, /* 1774 */
+    XML_SCHEMAP_RECURSIVE, /* 1775 */
+    XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, /* 1776 */
+    XML_SCHEMAP_INVALID_ATTR_COMBINATION, /* 1777 */
+    XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, /* 1778 */
+    XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, /* 1779 */
+    XML_SCHEMAP_INVALID_ATTR_NAME, /* 1780 */
+    XML_SCHEMAP_REF_AND_CONTENT, /* 1781 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_1, /* 1782 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_2, /* 1783 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_3, /* 1784 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_4, /* 1785 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_5, /* 1786 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, /* 1787 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, /* 1788 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, /* 1789 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, /* 1790 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, /* 1791 */
+    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, /* 1792 */
+    XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, /* 1793 */
+    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, /* 1794 */
+    XML_SCHEMAP_SRC_IMPORT_3_1, /* 1795 */
+    XML_SCHEMAP_SRC_IMPORT_3_2, /* 1796 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, /* 1797 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, /* 1798 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, /* 1799 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_3, /* 1800 */
+    XML_SCHEMAV_NOROOT = 1801,
+    XML_SCHEMAV_UNDECLAREDELEM, /* 1802 */
+    XML_SCHEMAV_NOTTOPLEVEL, /* 1803 */
+    XML_SCHEMAV_MISSING, /* 1804 */
+    XML_SCHEMAV_WRONGELEM, /* 1805 */
+    XML_SCHEMAV_NOTYPE, /* 1806 */
+    XML_SCHEMAV_NOROLLBACK, /* 1807 */
+    XML_SCHEMAV_ISABSTRACT, /* 1808 */
+    XML_SCHEMAV_NOTEMPTY, /* 1809 */
+    XML_SCHEMAV_ELEMCONT, /* 1810 */
+    XML_SCHEMAV_HAVEDEFAULT, /* 1811 */
+    XML_SCHEMAV_NOTNILLABLE, /* 1812 */
+    XML_SCHEMAV_EXTRACONTENT, /* 1813 */
+    XML_SCHEMAV_INVALIDATTR, /* 1814 */
+    XML_SCHEMAV_INVALIDELEM, /* 1815 */
+    XML_SCHEMAV_NOTDETERMINIST, /* 1816 */
+    XML_SCHEMAV_CONSTRUCT, /* 1817 */
+    XML_SCHEMAV_INTERNAL, /* 1818 */
+    XML_SCHEMAV_NOTSIMPLE, /* 1819 */
+    XML_SCHEMAV_ATTRUNKNOWN, /* 1820 */
+    XML_SCHEMAV_ATTRINVALID, /* 1821 */
+    XML_SCHEMAV_VALUE, /* 1822 */
+    XML_SCHEMAV_FACET, /* 1823 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, /* 1824 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, /* 1825 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, /* 1826 */
+    XML_SCHEMAV_CVC_TYPE_3_1_1, /* 1827 */
+    XML_SCHEMAV_CVC_TYPE_3_1_2, /* 1828 */
+    XML_SCHEMAV_CVC_FACET_VALID, /* 1829 */
+    XML_SCHEMAV_CVC_LENGTH_VALID, /* 1830 */
+    XML_SCHEMAV_CVC_MINLENGTH_VALID, /* 1831 */
+    XML_SCHEMAV_CVC_MAXLENGTH_VALID, /* 1832 */
+    XML_SCHEMAV_CVC_MININCLUSIVE_VALID, /* 1833 */
+    XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, /* 1834 */
+    XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, /* 1835 */
+    XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, /* 1836 */
+    XML_SCHEMAV_CVC_TOTALDIGITS_VALID, /* 1837 */
+    XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, /* 1838 */
+    XML_SCHEMAV_CVC_PATTERN_VALID, /* 1839 */
+    XML_SCHEMAV_CVC_ENUMERATION_VALID, /* 1840 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, /* 1841 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, /* 1842 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, /* 1843 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, /* 1844 */
+    XML_SCHEMAV_CVC_ELT_1, /* 1845 */
+    XML_SCHEMAV_CVC_ELT_2, /* 1846 */
+    XML_SCHEMAV_CVC_ELT_3_1, /* 1847 */
+    XML_SCHEMAV_CVC_ELT_3_2_1, /* 1848 */
+    XML_SCHEMAV_CVC_ELT_3_2_2, /* 1849 */
+    XML_SCHEMAV_CVC_ELT_4_1, /* 1850 */
+    XML_SCHEMAV_CVC_ELT_4_2, /* 1851 */
+    XML_SCHEMAV_CVC_ELT_4_3, /* 1852 */
+    XML_SCHEMAV_CVC_ELT_5_1_1, /* 1853 */
+    XML_SCHEMAV_CVC_ELT_5_1_2, /* 1854 */
+    XML_SCHEMAV_CVC_ELT_5_2_1, /* 1855 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_1, /* 1856 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_2_1, /* 1857 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_2_2, /* 1858 */
+    XML_SCHEMAV_CVC_ELT_6, /* 1859 */
+    XML_SCHEMAV_CVC_ELT_7, /* 1860 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_1, /* 1861 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_2, /* 1862 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_3, /* 1863 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_4, /* 1864 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, /* 1865 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, /* 1866 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, /* 1867 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_4, /* 1868 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, /* 1869 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, /* 1870 */
+    XML_SCHEMAV_ELEMENT_CONTENT, /* 1871 */
+    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, /* 1872 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_1, /* 1873 */
+    XML_SCHEMAV_CVC_AU, /* 1874 */
+    XML_SCHEMAV_CVC_TYPE_1, /* 1875 */
+    XML_SCHEMAV_CVC_TYPE_2, /* 1876 */
+    XML_SCHEMAV_CVC_IDC, /* 1877 */
+    XML_SCHEMAV_CVC_WILDCARD, /* 1878 */
+    XML_SCHEMAV_MISC, /* 1879 */
+    XML_XPTR_UNKNOWN_SCHEME = 1900,
+    XML_XPTR_CHILDSEQ_START, /* 1901 */
+    XML_XPTR_EVAL_FAILED, /* 1902 */
+    XML_XPTR_EXTRA_OBJECTS, /* 1903 */
+    XML_C14N_CREATE_CTXT = 1950,
+    XML_C14N_REQUIRES_UTF8, /* 1951 */
+    XML_C14N_CREATE_STACK, /* 1952 */
+    XML_C14N_INVALID_NODE, /* 1953 */
+    XML_C14N_UNKNOW_NODE, /* 1954 */
+    XML_C14N_RELATIVE_NAMESPACE, /* 1955 */
+    XML_FTP_PASV_ANSWER = 2000,
+    XML_FTP_EPSV_ANSWER, /* 2001 */
+    XML_FTP_ACCNT, /* 2002 */
+    XML_FTP_URL_SYNTAX, /* 2003 */
+    XML_HTTP_URL_SYNTAX = 2020,
+    XML_HTTP_USE_IP, /* 2021 */
+    XML_HTTP_UNKNOWN_HOST, /* 2022 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_1 = 3000,
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_2, /* 3001 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_3, /* 3002 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_4, /* 3003 */
+    XML_SCHEMAP_SRC_RESOLVE, /* 3004 */
+    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, /* 3005 */
+    XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, /* 3006 */
+    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, /* 3007 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_1, /* 3008 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_2, /* 3009 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_3, /* 3010 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_1, /* 3011 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_2, /* 3012 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, /* 3013 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, /* 3014 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_1, /* 3015 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, /* 3016 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, /* 3017 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, /* 3018 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, /* 3019 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, /* 3020 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, /* 3021 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, /* 3022 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_1, /* 3023 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, /* 3024 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, /* 3025 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, /* 3026 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, /* 3027 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, /* 3028 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, /* 3029 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, /* 3030 */
+    XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, /* 3031 */
+    XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, /* 3032 */
+    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, /* 3033 */
+    XML_SCHEMAP_S4S_ELEM_MISSING, /* 3034 */
+    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, /* 3035 */
+    XML_SCHEMAP_S4S_ATTR_MISSING, /* 3036 */
+    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, /* 3037 */
+    XML_SCHEMAP_SRC_ELEMENT_1, /* 3038 */
+    XML_SCHEMAP_SRC_ELEMENT_2_1, /* 3039 */
+    XML_SCHEMAP_SRC_ELEMENT_2_2, /* 3040 */
+    XML_SCHEMAP_SRC_ELEMENT_3, /* 3041 */
+    XML_SCHEMAP_P_PROPS_CORRECT_1, /* 3042 */
+    XML_SCHEMAP_P_PROPS_CORRECT_2_1, /* 3043 */
+    XML_SCHEMAP_P_PROPS_CORRECT_2_2, /* 3044 */
+    XML_SCHEMAP_E_PROPS_CORRECT_2, /* 3045 */
+    XML_SCHEMAP_E_PROPS_CORRECT_3, /* 3046 */
+    XML_SCHEMAP_E_PROPS_CORRECT_4, /* 3047 */
+    XML_SCHEMAP_E_PROPS_CORRECT_5, /* 3048 */
+    XML_SCHEMAP_E_PROPS_CORRECT_6, /* 3049 */
+    XML_SCHEMAP_SRC_INCLUDE, /* 3050 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_1, /* 3051 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_2, /* 3052 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_3_1, /* 3053 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_3_2, /* 3054 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_4, /* 3055 */
+    XML_SCHEMAP_NO_XMLNS, /* 3056 */
+    XML_SCHEMAP_NO_XSI, /* 3057 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_1, /* 3058 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_1, /* 3059 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, /* 3060 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, /* 3061 */
+    XML_SCHEMAP_CVC_SIMPLE_TYPE, /* 3062 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_1, /* 3063 */
+    XML_SCHEMAP_SRC_IMPORT_1_1, /* 3064 */
+    XML_SCHEMAP_SRC_IMPORT_1_2, /* 3065 */
+    XML_SCHEMAP_SRC_IMPORT_2, /* 3066 */
+    XML_SCHEMAP_SRC_IMPORT_2_1, /* 3067 */
+    XML_SCHEMAP_SRC_IMPORT_2_2, /* 3068 */
+    XML_SCHEMAP_INTERNAL, /* 3069 non-W3C */
+    XML_SCHEMAP_NOT_DETERMINISTIC, /* 3070 non-W3C */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, /* 3071 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, /* 3072 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, /* 3073 */
+    XML_SCHEMAP_MG_PROPS_CORRECT_1, /* 3074 */
+    XML_SCHEMAP_MG_PROPS_CORRECT_2, /* 3075 */
+    XML_SCHEMAP_SRC_CT_1, /* 3076 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, /* 3077 */
+    XML_SCHEMAP_AU_PROPS_CORRECT_2, /* 3078 */
+    XML_SCHEMAP_A_PROPS_CORRECT_2, /* 3079 */
+    XML_SCHEMAP_C_PROPS_CORRECT, /* 3080 */
+    XML_SCHEMAP_SRC_REDEFINE, /* 3081 */
+    XML_SCHEMAP_SRC_IMPORT, /* 3082 */
+    XML_SCHEMAP_WARN_SKIP_SCHEMA, /* 3083 */
+    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, /* 3084 */
+    XML_SCHEMAP_WARN_ATTR_REDECL_PROH, /* 3085 */
+    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, /* 3085 */
+    XML_SCHEMAP_AG_PROPS_CORRECT, /* 3086 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_2, /* 3087 */
+    XML_SCHEMAP_AU_PROPS_CORRECT, /* 3088 */
+    XML_SCHEMAP_A_PROPS_CORRECT_3, /* 3089 */
+    XML_SCHEMAP_COS_ALL_LIMITED, /* 3090 */
+    XML_SCHEMATRONV_ASSERT = 4000, /* 4000 */
+    XML_SCHEMATRONV_REPORT,
+    XML_MODULE_OPEN = 4900, /* 4900 */
+    XML_MODULE_CLOSE, /* 4901 */
+    XML_CHECK_FOUND_ELEMENT = 5000,
+    XML_CHECK_FOUND_ATTRIBUTE, /* 5001 */
+    XML_CHECK_FOUND_TEXT, /* 5002 */
+    XML_CHECK_FOUND_CDATA, /* 5003 */
+    XML_CHECK_FOUND_ENTITYREF, /* 5004 */
+    XML_CHECK_FOUND_ENTITY, /* 5005 */
+    XML_CHECK_FOUND_PI, /* 5006 */
+    XML_CHECK_FOUND_COMMENT, /* 5007 */
+    XML_CHECK_FOUND_DOCTYPE, /* 5008 */
+    XML_CHECK_FOUND_FRAGMENT, /* 5009 */
+    XML_CHECK_FOUND_NOTATION, /* 5010 */
+    XML_CHECK_UNKNOWN_NODE, /* 5011 */
+    XML_CHECK_ENTITY_TYPE, /* 5012 */
+    XML_CHECK_NO_PARENT, /* 5013 */
+    XML_CHECK_NO_DOC, /* 5014 */
+    XML_CHECK_NO_NAME, /* 5015 */
+    XML_CHECK_NO_ELEM, /* 5016 */
+    XML_CHECK_WRONG_DOC, /* 5017 */
+    XML_CHECK_NO_PREV, /* 5018 */
+    XML_CHECK_WRONG_PREV, /* 5019 */
+    XML_CHECK_NO_NEXT, /* 5020 */
+    XML_CHECK_WRONG_NEXT, /* 5021 */
+    XML_CHECK_NOT_DTD, /* 5022 */
+    XML_CHECK_NOT_ATTR, /* 5023 */
+    XML_CHECK_NOT_ATTR_DECL, /* 5024 */
+    XML_CHECK_NOT_ELEM_DECL, /* 5025 */
+    XML_CHECK_NOT_ENTITY_DECL, /* 5026 */
+    XML_CHECK_NOT_NS_DECL, /* 5027 */
+    XML_CHECK_NO_HREF, /* 5028 */
+    XML_CHECK_WRONG_PARENT,/* 5029 */
+    XML_CHECK_NS_SCOPE, /* 5030 */
+    XML_CHECK_NS_ANCESTOR, /* 5031 */
+    XML_CHECK_NOT_UTF8, /* 5032 */
+    XML_CHECK_NO_DICT, /* 5033 */
+    XML_CHECK_NOT_NCNAME, /* 5034 */
+    XML_CHECK_OUTSIDE_DICT, /* 5035 */
+    XML_CHECK_WRONG_NAME, /* 5036 */
+    XML_CHECK_NAME_NOT_NULL, /* 5037 */
+    XML_I18N_NO_NAME = 6000,
+    XML_I18N_NO_HANDLER, /* 6001 */
+    XML_I18N_EXCESS_HANDLER, /* 6002 */
+    XML_I18N_CONV_FAILED, /* 6003 */
+    XML_I18N_NO_OUTPUT /* 6004 */
+#if 0
+    XML_CHECK_, /* 5033 */
+    XML_CHECK_X /* 503 */
+#endif
+} xmlParserErrors;
+
+/**
+ * xmlGenericErrorFunc:
+ * @ctx:  a parsing context
+ * @msg:  the message
+ * @...:  the extra arguments of the varags to format the message
+ *
+ * Signature of the function to use when there is an error and
+ * no parsing or validity context available .
+ */
+typedef void (XMLCDECL *xmlGenericErrorFunc) (void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * xmlStructuredErrorFunc:
+ * @userData:  user provided data for the error callback
+ * @error:  the error being raised.
+ *
+ * Signature of the function to use when there is an error and
+ * the module handles the new error reporting mechanism.
+ */
+typedef void (XMLCALL *xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
+
+/*
+ * Use the following function to reset the two global variables
+ * xmlGenericError and xmlGenericErrorContext.
+ */
+XMLPUBFUN void XMLCALL
+    xmlSetGenericErrorFunc	(void *ctx,
+				 xmlGenericErrorFunc handler);
+XMLPUBFUN void XMLCALL
+    initGenericErrorDefaultFunc	(xmlGenericErrorFunc *handler);
+
+XMLPUBFUN void XMLCALL
+    xmlSetStructuredErrorFunc	(void *ctx,
+				 xmlStructuredErrorFunc handler);
+/*
+ * Default message routines used by SAX and Valid context for error
+ * and warning reporting.
+ */
+XMLPUBFUN void XMLCDECL
+    xmlParserError		(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void XMLCDECL
+    xmlParserWarning		(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void XMLCDECL
+    xmlParserValidityError	(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void XMLCDECL
+    xmlParserValidityWarning	(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void XMLCALL
+    xmlParserPrintFileInfo	(xmlParserInputPtr input);
+XMLPUBFUN void XMLCALL
+    xmlParserPrintFileContext	(xmlParserInputPtr input);
+
+/*
+ * Extended error information routines
+ */
+XMLPUBFUN xmlErrorPtr XMLCALL
+    xmlGetLastError		(void);
+XMLPUBFUN void XMLCALL
+    xmlResetLastError		(void);
+XMLPUBFUN xmlErrorPtr XMLCALL
+    xmlCtxtGetLastError		(void *ctx);
+XMLPUBFUN void XMLCALL
+    xmlCtxtResetLastError	(void *ctx);
+XMLPUBFUN void XMLCALL
+    xmlResetError		(xmlErrorPtr err);
+XMLPUBFUN int XMLCALL
+    xmlCopyError		(xmlErrorPtr from,
+				 xmlErrorPtr to);
+
+#ifdef IN_LIBXML
+/*
+ * Internal callback reporting routine
+ */
+XMLPUBFUN void XMLCALL
+    __xmlRaiseError		(xmlStructuredErrorFunc schannel,
+				 xmlGenericErrorFunc channel,
+				 void *data,
+                                 void *ctx,
+				 void *node,
+				 int domain,
+				 int code,
+				 xmlErrorLevel level,
+				 const char *file,
+				 int line,
+				 const char *str1,
+				 const char *str2,
+				 const char *str3,
+				 int int1,
+				 int col,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(16,17);
+XMLPUBFUN void XMLCALL
+    __xmlSimpleError		(int domain,
+				 int code,
+				 xmlNodePtr node,
+				 const char *msg,
+				 const char *extra);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_ERROR_H__ */
diff --git a/src/include/libxml/xmlexports.h b/src/include/libxml/xmlexports.h
new file mode 100644
index 0000000..9c6790c
--- /dev/null
+++ b/src/include/libxml/xmlexports.h
@@ -0,0 +1,162 @@
+/*
+ * Summary: macros for marking symbols as exportable/importable.
+ * Description: macros for marking symbols as exportable/importable.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Igor Zlatovic <igor@zlatkovic.com>
+ */
+
+#ifndef __XML_EXPORTS_H__
+#define __XML_EXPORTS_H__
+
+/**
+ * XMLPUBFUN, XMLPUBVAR, XMLCALL
+ *
+ * Macros which declare an exportable function, an exportable variable and
+ * the calling convention used for functions.
+ *
+ * Please use an extra block for every platform/compiler combination when
+ * modifying this, rather than overlong #ifdef lines. This helps
+ * readability as well as the fact that different compilers on the same
+ * platform might need different definitions.
+ */
+
+/**
+ * XMLPUBFUN:
+ *
+ * Macros which declare an exportable function
+ */
+#define XMLPUBFUN
+/**
+ * XMLPUBVAR:
+ *
+ * Macros which declare an exportable variable
+ */
+#define XMLPUBVAR extern
+/**
+ * XMLCALL:
+ *
+ * Macros which declare the called convention for exported functions
+ */
+#define XMLCALL
+/**
+ * XMLCDECL:
+ *
+ * Macro which declares the calling convention for exported functions that 
+ * use '...'.
+ */
+#define XMLCDECL
+
+/** DOC_DISABLE */
+
+/* Windows platform with MS compiler */
+#if defined(_WIN32) && defined(_MSC_VER)
+  #undef XMLPUBFUN
+  #undef XMLPUBVAR
+  #undef XMLCALL
+  #undef XMLCDECL
+  #if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
+    #define XMLPUBFUN __declspec(dllexport)
+    #define XMLPUBVAR __declspec(dllexport)
+  #else
+    #define XMLPUBFUN
+    #if !defined(LIBXML_STATIC)
+      #define XMLPUBVAR __declspec(dllimport) extern
+    #else
+      #define XMLPUBVAR extern
+    #endif
+  #endif
+  #if defined(LIBXML_FASTCALL)
+    #define XMLCALL __fastcall
+  #else
+    #define XMLCALL __cdecl
+  #endif
+  #define XMLCDECL __cdecl
+  #if !defined _REENTRANT
+    #define _REENTRANT
+  #endif
+#endif
+
+/* Windows platform with Borland compiler */
+#if defined(_WIN32) && defined(__BORLANDC__)
+  #undef XMLPUBFUN
+  #undef XMLPUBVAR
+  #undef XMLCALL
+  #undef XMLCDECL
+  #if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
+    #define XMLPUBFUN __declspec(dllexport)
+    #define XMLPUBVAR __declspec(dllexport) extern
+  #else
+    #define XMLPUBFUN
+    #if !defined(LIBXML_STATIC)
+      #define XMLPUBVAR __declspec(dllimport) extern
+    #else
+      #define XMLPUBVAR extern
+    #endif
+  #endif
+  #define XMLCALL __cdecl
+  #define XMLCDECL __cdecl
+  #if !defined _REENTRANT
+    #define _REENTRANT
+  #endif
+#endif
+
+/* Windows platform with GNU compiler (Mingw) */
+#if defined(_WIN32) && defined(__MINGW32__)
+  #undef XMLPUBFUN
+  #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)
+  #else
+    #define XMLPUBFUN
+    #if !defined(LIBXML_STATIC)
+      #define XMLPUBVAR __declspec(dllimport) extern
+    #else
+      #define XMLPUBVAR extern
+    #endif
+  #endif
+  #define XMLCALL __cdecl
+  #define XMLCDECL __cdecl
+  #if !defined _REENTRANT
+    #define _REENTRANT
+  #endif
+#endif
+
+/* Cygwin platform, GNU compiler */
+#if defined(_WIN32) && defined(__CYGWIN__)
+  #undef XMLPUBFUN
+  #undef XMLPUBVAR
+  #undef XMLCALL
+  #undef XMLCDECL
+  #if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
+    #define XMLPUBFUN __declspec(dllexport)
+    #define XMLPUBVAR __declspec(dllexport)
+  #else
+    #define XMLPUBFUN
+    #if !defined(LIBXML_STATIC)
+      #define XMLPUBVAR __declspec(dllimport) extern
+    #else
+      #define XMLPUBVAR
+    #endif
+  #endif
+  #define XMLCALL __cdecl
+  #define XMLCDECL __cdecl
+#endif
+
+/* Compatibility */
+#if !defined(LIBXML_DLL_IMPORT)
+#define LIBXML_DLL_IMPORT XMLPUBVAR
+#endif
+
+#endif /* __XML_EXPORTS_H__ */
+
+
diff --git a/src/include/libxml/xmlmemory.h b/src/include/libxml/xmlmemory.h
new file mode 100644
index 0000000..17e375a
--- /dev/null
+++ b/src/include/libxml/xmlmemory.h
@@ -0,0 +1,224 @@
+/*
+ * Summary: interface for the memory allocator
+ * Description: provides interfaces for the memory allocator,
+ *              including debugging capabilities.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __DEBUG_MEMORY_ALLOC__
+#define __DEBUG_MEMORY_ALLOC__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+
+/**
+ * DEBUG_MEMORY:
+ *
+ * DEBUG_MEMORY replaces the allocator with a collect and debug
+ * shell to the libc allocator.
+ * DEBUG_MEMORY should only be activated when debugging
+ * libxml i.e. if libxml has been configured with --with-debug-mem too.
+ */
+/* #define DEBUG_MEMORY_FREED */
+/* #define DEBUG_MEMORY_LOCATION */
+
+#ifdef DEBUG
+#ifndef DEBUG_MEMORY
+#define DEBUG_MEMORY
+#endif
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * DEBUG_MEMORY_LOCATION should be activated only when debugging
+ * libxml i.e. if libxml has been configured with --with-debug-mem too.
+ */
+#ifdef DEBUG_MEMORY_LOCATION
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The XML memory wrapper support 4 basic overloadable functions.
+ */
+/**
+ * xmlFreeFunc:
+ * @mem: an already allocated block of memory
+ *
+ * Signature for a free() implementation.
+ */
+typedef void (XMLCALL *xmlFreeFunc)(void *mem);
+/**
+ * xmlMallocFunc:
+ * @size:  the size requested in bytes
+ *
+ * Signature for a malloc() implementation.
+ *
+ * Returns a pointer to the newly allocated block or NULL in case of error.
+ */
+typedef void *(LIBXML_ATTR_ALLOC_SIZE(1) XMLCALL *xmlMallocFunc)(size_t size);
+
+/**
+ * xmlReallocFunc:
+ * @mem: an already allocated block of memory
+ * @size:  the new size requested in bytes
+ *
+ * Signature for a realloc() implementation.
+ *
+ * Returns a pointer to the newly reallocated block or NULL in case of error.
+ */
+typedef void *(XMLCALL *xmlReallocFunc)(void *mem, size_t size);
+
+/**
+ * xmlStrdupFunc:
+ * @str: a zero terminated string
+ *
+ * Signature for an strdup() implementation.
+ *
+ * Returns the copy of the string or NULL in case of error.
+ */
+typedef char *(XMLCALL *xmlStrdupFunc)(const char *str);
+
+/*
+ * The 4 interfaces used for all memory handling within libxml.
+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;
+ */
+
+/*
+ * The way to overload the existing functions.
+ * The xmlGc function have an extra entry for atomic block
+ * allocations useful for garbage collected memory allocators
+ */
+XMLPUBFUN int XMLCALL
+	xmlMemSetup	(xmlFreeFunc freeFunc,
+			 xmlMallocFunc mallocFunc,
+			 xmlReallocFunc reallocFunc,
+			 xmlStrdupFunc strdupFunc);
+XMLPUBFUN int XMLCALL
+	xmlMemGet	(xmlFreeFunc *freeFunc,
+			 xmlMallocFunc *mallocFunc,
+			 xmlReallocFunc *reallocFunc,
+			 xmlStrdupFunc *strdupFunc);
+XMLPUBFUN int XMLCALL
+	xmlGcMemSetup	(xmlFreeFunc freeFunc,
+			 xmlMallocFunc mallocFunc,
+			 xmlMallocFunc mallocAtomicFunc,
+			 xmlReallocFunc reallocFunc,
+			 xmlStrdupFunc strdupFunc);
+XMLPUBFUN int XMLCALL
+	xmlGcMemGet	(xmlFreeFunc *freeFunc,
+			 xmlMallocFunc *mallocFunc,
+			 xmlMallocFunc *mallocAtomicFunc,
+			 xmlReallocFunc *reallocFunc,
+			 xmlStrdupFunc *strdupFunc);
+
+/*
+ * Initialization of the memory layer.
+ */
+XMLPUBFUN int XMLCALL
+	xmlInitMemory	(void);
+
+/*
+ * Cleanup of the memory layer.
+ */
+XMLPUBFUN void XMLCALL
+                xmlCleanupMemory        (void);
+/*
+ * These are specific to the XML debug memory wrapper.
+ */
+XMLPUBFUN int XMLCALL
+	xmlMemUsed	(void);
+XMLPUBFUN int XMLCALL
+	xmlMemBlocks	(void);
+XMLPUBFUN void XMLCALL
+	xmlMemDisplay	(FILE *fp);
+XMLPUBFUN void XMLCALL
+	xmlMemDisplayLast(FILE *fp, long nbBytes);
+XMLPUBFUN void XMLCALL
+	xmlMemShow	(FILE *fp, int nr);
+XMLPUBFUN void XMLCALL
+	xmlMemoryDump	(void);
+XMLPUBFUN void * XMLCALL
+	xmlMemMalloc	(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
+XMLPUBFUN void * XMLCALL
+	xmlMemRealloc	(void *ptr,size_t size);
+XMLPUBFUN void XMLCALL
+	xmlMemFree	(void *ptr);
+XMLPUBFUN char * XMLCALL
+	xmlMemoryStrdup	(const char *str);
+XMLPUBFUN void * XMLCALL
+	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) LIBXML_ATTR_ALLOC_SIZE(1);
+XMLPUBFUN char * XMLCALL
+	xmlMemStrdupLoc	(const char *str, const char *file, int line);
+
+
+#ifdef DEBUG_MEMORY_LOCATION
+/**
+ * xmlMalloc:
+ * @size:  number of bytes to allocate
+ *
+ * Wrapper for the malloc() function used in the XML library.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__)
+/**
+ * xmlMallocAtomic:
+ * @size:  number of bytes to allocate
+ *
+ * Wrapper for the malloc() function used in the XML library for allocation
+ * of block not containing pointers to other areas.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlMallocAtomic(size) xmlMallocAtomicLoc((size), __FILE__, __LINE__)
+/**
+ * xmlRealloc:
+ * @ptr:  pointer to the existing allocated area
+ * @size:  number of bytes to allocate
+ *
+ * Wrapper for the realloc() function used in the XML library.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlRealloc(ptr, size) xmlReallocLoc((ptr), (size), __FILE__, __LINE__)
+/**
+ * xmlMemStrdup:
+ * @str:  pointer to the existing string
+ *
+ * Wrapper for the strdup() function, xmlStrdup() is usually preferred.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
+
+#endif /* DEBUG_MEMORY_LOCATION */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#ifndef __XML_GLOBALS_H
+#ifndef __XML_THREADS_H__
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+#endif
+#endif
+
+#endif  /* __DEBUG_MEMORY_ALLOC__ */
+
diff --git a/src/include/libxml/xmlmodule.h b/src/include/libxml/xmlmodule.h
new file mode 100644
index 0000000..8f4a560
--- /dev/null
+++ b/src/include/libxml/xmlmodule.h
@@ -0,0 +1,57 @@
+/*
+ * Summary: dynamic module loading
+ * Description: basic API for dynamic module loading, used by
+ *              libexslt added in 2.6.17
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Joel W. Reed
+ */
+
+#ifndef __XML_MODULE_H__
+#define __XML_MODULE_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_MODULES_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlModulePtr:
+ *
+ * A handle to a dynamically loaded module
+ */
+typedef struct _xmlModule xmlModule;
+typedef xmlModule *xmlModulePtr;
+
+/**
+ * xmlModuleOption:
+ *
+ * enumeration of options that can be passed down to xmlModuleOpen()
+ */
+typedef enum {
+    XML_MODULE_LAZY = 1,	/* lazy binding */
+    XML_MODULE_LOCAL= 2		/* local binding */
+} xmlModuleOption;
+
+XMLPUBFUN xmlModulePtr XMLCALL xmlModuleOpen	(const char *filename,
+						 int options);
+
+XMLPUBFUN int XMLCALL xmlModuleSymbol		(xmlModulePtr module,
+						 const char* name,
+						 void **result);
+
+XMLPUBFUN int XMLCALL xmlModuleClose		(xmlModulePtr module);
+
+XMLPUBFUN int XMLCALL xmlModuleFree		(xmlModulePtr module);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /* LIBXML_MODULES_ENABLED */
+
+#endif /*__XML_MODULE_H__ */
diff --git a/src/include/libxml/xmlreader.h b/src/include/libxml/xmlreader.h
new file mode 100644
index 0000000..6964482
--- /dev/null
+++ b/src/include/libxml/xmlreader.h
@@ -0,0 +1,424 @@
+/*
+ * Summary: the XMLReader implementation
+ * Description: API of the XML streaming API based on C# interfaces.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XMLREADER_H__
+#define __XML_XMLREADER_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/xmlIO.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlParserSeverities:
+ *
+ * How severe an error callback is when the per-reader error callback API
+ * is used.
+ */
+typedef enum {
+    XML_PARSER_SEVERITY_VALIDITY_WARNING = 1,
+    XML_PARSER_SEVERITY_VALIDITY_ERROR = 2,
+    XML_PARSER_SEVERITY_WARNING = 3,
+    XML_PARSER_SEVERITY_ERROR = 4
+} xmlParserSeverities;
+
+#ifdef LIBXML_READER_ENABLED
+
+/**
+ * xmlTextReaderMode:
+ *
+ * Internal state values for the reader.
+ */
+typedef enum {
+    XML_TEXTREADER_MODE_INITIAL = 0,
+    XML_TEXTREADER_MODE_INTERACTIVE = 1,
+    XML_TEXTREADER_MODE_ERROR = 2,
+    XML_TEXTREADER_MODE_EOF =3,
+    XML_TEXTREADER_MODE_CLOSED = 4,
+    XML_TEXTREADER_MODE_READING = 5
+} xmlTextReaderMode;
+
+/**
+ * xmlParserProperties:
+ *
+ * Some common options to use with xmlTextReaderSetParserProp, but it
+ * is better to use xmlParserOption and the xmlReaderNewxxx and
+ * xmlReaderForxxx APIs now.
+ */
+typedef enum {
+    XML_PARSER_LOADDTD = 1,
+    XML_PARSER_DEFAULTATTRS = 2,
+    XML_PARSER_VALIDATE = 3,
+    XML_PARSER_SUBST_ENTITIES = 4
+} xmlParserProperties;
+
+/**
+ * xmlReaderTypes:
+ *
+ * Predefined constants for the different types of nodes.
+ */
+typedef enum {
+    XML_READER_TYPE_NONE = 0,
+    XML_READER_TYPE_ELEMENT = 1,
+    XML_READER_TYPE_ATTRIBUTE = 2,
+    XML_READER_TYPE_TEXT = 3,
+    XML_READER_TYPE_CDATA = 4,
+    XML_READER_TYPE_ENTITY_REFERENCE = 5,
+    XML_READER_TYPE_ENTITY = 6,
+    XML_READER_TYPE_PROCESSING_INSTRUCTION = 7,
+    XML_READER_TYPE_COMMENT = 8,
+    XML_READER_TYPE_DOCUMENT = 9,
+    XML_READER_TYPE_DOCUMENT_TYPE = 10,
+    XML_READER_TYPE_DOCUMENT_FRAGMENT = 11,
+    XML_READER_TYPE_NOTATION = 12,
+    XML_READER_TYPE_WHITESPACE = 13,
+    XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,
+    XML_READER_TYPE_END_ELEMENT = 15,
+    XML_READER_TYPE_END_ENTITY = 16,
+    XML_READER_TYPE_XML_DECLARATION = 17
+} xmlReaderTypes;
+
+/**
+ * xmlTextReader:
+ *
+ * Structure for an xmlReader context.
+ */
+typedef struct _xmlTextReader xmlTextReader;
+
+/**
+ * xmlTextReaderPtr:
+ *
+ * Pointer to an xmlReader context.
+ */
+typedef xmlTextReader *xmlTextReaderPtr;
+
+/*
+ * Constructors & Destructor
+ */
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+			xmlNewTextReader	(xmlParserInputBufferPtr input,
+	                                         const char *URI);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+			xmlNewTextReaderFilename(const char *URI);
+
+XMLPUBFUN void XMLCALL
+			xmlFreeTextReader	(xmlTextReaderPtr reader);
+
+XMLPUBFUN int XMLCALL
+            xmlTextReaderSetup(xmlTextReaderPtr reader,
+                   xmlParserInputBufferPtr input, const char *URL,
+                   const char *encoding, int options);
+
+/*
+ * Iterators
+ */
+XMLPUBFUN int XMLCALL
+			xmlTextReaderRead	(xmlTextReaderPtr reader);
+
+#ifdef LIBXML_WRITER_ENABLED
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderReadInnerXml	(xmlTextReaderPtr reader);
+
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderReadOuterXml	(xmlTextReaderPtr reader);
+#endif
+
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderReadString		(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderReadAttributeValue	(xmlTextReaderPtr reader);
+
+/*
+ * Attributes of the node
+ */
+XMLPUBFUN int XMLCALL
+			xmlTextReaderAttributeCount(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderDepth	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderHasAttributes(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderHasValue(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderIsDefault	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderNodeType	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderQuoteChar	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+			xmlTextReaderReadState	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+                        xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader);
+
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstBaseUri	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstLocalName	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstName	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstPrefix	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstXmlLang	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstString	(xmlTextReaderPtr reader,
+						 const xmlChar *str);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstValue	(xmlTextReaderPtr reader);
+
+/*
+ * use the Const version of the routine for
+ * better performance and simpler code
+ */
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderBaseUri	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderLocalName	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderName	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderNamespaceUri(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderPrefix	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderXmlLang	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+			xmlTextReaderValue	(xmlTextReaderPtr reader);
+
+/*
+ * Methods of the XmlTextReader
+ */
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderClose		(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+		    xmlTextReaderGetAttributeNo	(xmlTextReaderPtr reader,
+						 int no);
+XMLPUBFUN xmlChar * XMLCALL
+		    xmlTextReaderGetAttribute	(xmlTextReaderPtr reader,
+						 const xmlChar *name);
+XMLPUBFUN xmlChar * XMLCALL
+		    xmlTextReaderGetAttributeNs	(xmlTextReaderPtr reader,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+XMLPUBFUN xmlParserInputBufferPtr XMLCALL
+		    xmlTextReaderGetRemainder	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlChar * XMLCALL
+		    xmlTextReaderLookupNamespace(xmlTextReaderPtr reader,
+						 const xmlChar *prefix);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader,
+						 int no);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader,
+						 const xmlChar *name);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderMoveToElement	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderNormalization	(xmlTextReaderPtr reader);
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstEncoding  (xmlTextReaderPtr reader);
+
+/*
+ * Extensions
+ */
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderSetParserProp	(xmlTextReaderPtr reader,
+						 int prop,
+						 int value);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderGetParserProp	(xmlTextReaderPtr reader,
+						 int prop);
+XMLPUBFUN xmlNodePtr XMLCALL
+		    xmlTextReaderCurrentNode	(xmlTextReaderPtr reader);
+
+XMLPUBFUN int XMLCALL
+            xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader);
+
+XMLPUBFUN int XMLCALL
+            xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader);
+
+XMLPUBFUN xmlNodePtr XMLCALL
+		    xmlTextReaderPreserve	(xmlTextReaderPtr reader);
+#ifdef LIBXML_PATTERN_ENABLED
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderPreservePattern(xmlTextReaderPtr reader,
+						 const xmlChar *pattern,
+						 const xmlChar **namespaces);
+#endif /* LIBXML_PATTERN_ENABLED */
+XMLPUBFUN xmlDocPtr XMLCALL
+		    xmlTextReaderCurrentDoc	(xmlTextReaderPtr reader);
+XMLPUBFUN xmlNodePtr XMLCALL
+		    xmlTextReaderExpand		(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderNext		(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderNextSibling	(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderIsValid	(xmlTextReaderPtr reader);
+#ifdef LIBXML_SCHEMAS_ENABLED
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader,
+						 const char *rng);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader,
+						 xmlRelaxNGPtr schema);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderSchemaValidate	(xmlTextReaderPtr reader,
+						 const char *xsd);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
+						 xmlSchemaValidCtxtPtr ctxt,
+						 int options);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderSetSchema	(xmlTextReaderPtr reader,
+						 xmlSchemaPtr schema);
+#endif
+XMLPUBFUN const xmlChar * XMLCALL
+		    xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderStandalone     (xmlTextReaderPtr reader);
+
+
+/*
+ * Index lookup
+ */
+XMLPUBFUN long XMLCALL
+		xmlTextReaderByteConsumed	(xmlTextReaderPtr reader);
+
+/*
+ * New more complete APIs for simpler creation and reuse of readers
+ */
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderWalker		(xmlDocPtr doc);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderForDoc		(const xmlChar * cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderForFile	(const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderForMemory	(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderForFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReaderPtr XMLCALL
+		xmlReaderForIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN int XMLCALL
+		xmlReaderNewWalker	(xmlTextReaderPtr reader,
+					 xmlDocPtr doc);
+XMLPUBFUN int XMLCALL
+		xmlReaderNewDoc		(xmlTextReaderPtr reader,
+					 const xmlChar * cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int XMLCALL
+		xmlReaderNewFile	(xmlTextReaderPtr reader,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int XMLCALL
+		xmlReaderNewMemory	(xmlTextReaderPtr reader,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int XMLCALL
+		xmlReaderNewFd		(xmlTextReaderPtr reader,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int XMLCALL
+		xmlReaderNewIO		(xmlTextReaderPtr reader,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+/*
+ * Error handling extensions
+ */
+typedef void *  xmlTextReaderLocatorPtr;
+
+/**
+ * xmlTextReaderErrorFunc:
+ * @arg: the user argument
+ * @msg: the message
+ * @severity: the severity of the error
+ * @locator: a locator indicating where the error occured
+ *
+ * Signature of an error callback from a reader parser
+ */
+typedef void   (XMLCALL *xmlTextReaderErrorFunc)(void *arg,
+						 const char *msg,
+						 xmlParserSeverities severity,
+						 xmlTextReaderLocatorPtr locator);
+XMLPUBFUN int XMLCALL
+		    xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator);
+/*int             xmlTextReaderLocatorLinePosition(xmlTextReaderLocatorPtr locator);*/
+XMLPUBFUN xmlChar * XMLCALL
+		    xmlTextReaderLocatorBaseURI (xmlTextReaderLocatorPtr locator);
+XMLPUBFUN void XMLCALL
+		    xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
+						 xmlTextReaderErrorFunc f,
+						 void *arg);
+XMLPUBFUN void XMLCALL
+		    xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
+							   xmlStructuredErrorFunc f,
+							   void *arg);
+XMLPUBFUN void XMLCALL
+		    xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
+						 xmlTextReaderErrorFunc *f,
+						 void **arg);
+
+#endif /* LIBXML_READER_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XMLREADER_H__ */
+
diff --git a/src/include/libxml/xmlregexp.h b/src/include/libxml/xmlregexp.h
new file mode 100644
index 0000000..7009645
--- /dev/null
+++ b/src/include/libxml/xmlregexp.h
@@ -0,0 +1,222 @@
+/*
+ * Summary: regular expressions handling
+ * Description: basic API for libxml regular expressions handling used
+ *              for XML Schemas and validation.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_REGEXP_H__
+#define __XML_REGEXP_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlRegexpPtr:
+ *
+ * A libxml regular expression, they can actually be far more complex
+ * thank the POSIX regex expressions.
+ */
+typedef struct _xmlRegexp xmlRegexp;
+typedef xmlRegexp *xmlRegexpPtr;
+
+/**
+ * xmlRegExecCtxtPtr:
+ *
+ * A libxml progressive regular expression evaluation context
+ */
+typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
+typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;
+
+#ifdef __cplusplus
+}
+#endif
+#include <libxml/tree.h>
+#include <libxml/dict.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The POSIX like API
+ */
+XMLPUBFUN xmlRegexpPtr XMLCALL
+		    xmlRegexpCompile	(const xmlChar *regexp);
+XMLPUBFUN void XMLCALL			 xmlRegFreeRegexp(xmlRegexpPtr regexp);
+XMLPUBFUN int XMLCALL
+		    xmlRegexpExec	(xmlRegexpPtr comp,
+					 const xmlChar *value);
+XMLPUBFUN void XMLCALL
+		    xmlRegexpPrint	(FILE *output,
+					 xmlRegexpPtr regexp);
+XMLPUBFUN int XMLCALL
+		    xmlRegexpIsDeterminist(xmlRegexpPtr comp);
+
+/**
+ * xmlRegExecCallbacks:
+ * @exec: the regular expression context
+ * @token: the current token string
+ * @transdata: transition data
+ * @inputdata: input data
+ *
+ * Callback function when doing a transition in the automata
+ */
+typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxtPtr exec,
+	                             const xmlChar *token,
+				     void *transdata,
+				     void *inputdata);
+
+/*
+ * The progressive API
+ */
+XMLPUBFUN xmlRegExecCtxtPtr XMLCALL
+		    xmlRegNewExecCtxt	(xmlRegexpPtr comp,
+					 xmlRegExecCallbacks callback,
+					 void *data);
+XMLPUBFUN void XMLCALL
+		    xmlRegFreeExecCtxt	(xmlRegExecCtxtPtr exec);
+XMLPUBFUN int XMLCALL
+		    xmlRegExecPushString(xmlRegExecCtxtPtr exec,
+					 const xmlChar *value,
+					 void *data);
+XMLPUBFUN int XMLCALL
+		    xmlRegExecPushString2(xmlRegExecCtxtPtr exec,
+					 const xmlChar *value,
+					 const xmlChar *value2,
+					 void *data);
+
+XMLPUBFUN int XMLCALL
+		    xmlRegExecNextValues(xmlRegExecCtxtPtr exec,
+					 int *nbval,
+					 int *nbneg,
+					 xmlChar **values,
+					 int *terminal);
+XMLPUBFUN int XMLCALL
+		    xmlRegExecErrInfo	(xmlRegExecCtxtPtr exec,
+					 const xmlChar **string,
+					 int *nbval,
+					 int *nbneg,
+					 xmlChar **values,
+					 int *terminal);
+#ifdef LIBXML_EXPR_ENABLED
+/*
+ * Formal regular expression handling
+ * Its goal is to do some formal work on content models
+ */
+
+/* expressions are used within a context */
+typedef struct _xmlExpCtxt xmlExpCtxt;
+typedef xmlExpCtxt *xmlExpCtxtPtr;
+
+XMLPUBFUN void XMLCALL
+			xmlExpFreeCtxt	(xmlExpCtxtPtr ctxt);
+XMLPUBFUN xmlExpCtxtPtr XMLCALL
+			xmlExpNewCtxt	(int maxNodes,
+					 xmlDictPtr dict);
+
+XMLPUBFUN int XMLCALL
+			xmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+			xmlExpCtxtNbCons(xmlExpCtxtPtr ctxt);
+
+/* Expressions are trees but the tree is opaque */
+typedef struct _xmlExpNode xmlExpNode;
+typedef xmlExpNode *xmlExpNodePtr;
+
+typedef enum {
+    XML_EXP_EMPTY = 0,
+    XML_EXP_FORBID = 1,
+    XML_EXP_ATOM = 2,
+    XML_EXP_SEQ = 3,
+    XML_EXP_OR = 4,
+    XML_EXP_COUNT = 5
+} xmlExpNodeType;
+
+/*
+ * 2 core expressions shared by all for the empty language set
+ * and for the set with just the empty token
+ */
+XMLPUBVAR xmlExpNodePtr forbiddenExp;
+XMLPUBVAR xmlExpNodePtr emptyExp;
+
+/*
+ * Expressions are reference counted internally
+ */
+XMLPUBFUN void XMLCALL
+			xmlExpFree	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr);
+XMLPUBFUN void XMLCALL
+			xmlExpRef	(xmlExpNodePtr expr);
+
+/*
+ * constructors can be either manual or from a string
+ */
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpParse	(xmlExpCtxtPtr ctxt,
+					 const char *expr);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpNewAtom	(xmlExpCtxtPtr ctxt,
+					 const xmlChar *name,
+					 int len);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpNewOr	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr left,
+					 xmlExpNodePtr right);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpNewSeq	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr left,
+					 xmlExpNodePtr right);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpNewRange	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr subset,
+					 int min,
+					 int max);
+/*
+ * The really interesting APIs
+ */
+XMLPUBFUN int XMLCALL
+			xmlExpIsNillable(xmlExpNodePtr expr);
+XMLPUBFUN int XMLCALL
+			xmlExpMaxToken	(xmlExpNodePtr expr);
+XMLPUBFUN int XMLCALL
+			xmlExpGetLanguage(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr,
+					 const xmlChar**langList,
+					 int len);
+XMLPUBFUN int XMLCALL
+			xmlExpGetStart	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr,
+					 const xmlChar**tokList,
+					 int len);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpStringDerive(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr,
+					 const xmlChar *str,
+					 int len);
+XMLPUBFUN xmlExpNodePtr XMLCALL
+			xmlExpExpDerive	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr,
+					 xmlExpNodePtr sub);
+XMLPUBFUN int XMLCALL
+			xmlExpSubsume	(xmlExpCtxtPtr ctxt,
+					 xmlExpNodePtr expr,
+					 xmlExpNodePtr sub);
+XMLPUBFUN void XMLCALL
+			xmlExpDump	(xmlBufferPtr buf,
+					 xmlExpNodePtr expr);
+#endif /* LIBXML_EXPR_ENABLED */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /*__XML_REGEXP_H__ */
diff --git a/src/include/libxml/xmlsave.h b/src/include/libxml/xmlsave.h
new file mode 100644
index 0000000..4201b4d
--- /dev/null
+++ b/src/include/libxml/xmlsave.h
@@ -0,0 +1,87 @@
+/*
+ * Summary: the XML document serializer
+ * Description: API to save document or subtree of document
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XMLSAVE_H__
+#define __XML_XMLSAVE_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlSaveOption:
+ *
+ * This is the set of XML save options that can be passed down
+ * to the xmlSaveToFd() and similar calls.
+ */
+typedef enum {
+    XML_SAVE_FORMAT     = 1<<0,	/* format save output */
+    XML_SAVE_NO_DECL    = 1<<1,	/* drop the xml declaration */
+    XML_SAVE_NO_EMPTY	= 1<<2, /* no empty tags */
+    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 */
+} xmlSaveOption;
+
+
+typedef struct _xmlSaveCtxt xmlSaveCtxt;
+typedef xmlSaveCtxt *xmlSaveCtxtPtr;
+
+XMLPUBFUN xmlSaveCtxtPtr XMLCALL
+		xmlSaveToFd		(int fd,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlSaveCtxtPtr XMLCALL
+		xmlSaveToFilename	(const char *filename,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN xmlSaveCtxtPtr XMLCALL
+		xmlSaveToBuffer		(xmlBufferPtr buffer,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN xmlSaveCtxtPtr XMLCALL
+		xmlSaveToIO		(xmlOutputWriteCallback iowrite,
+					 xmlOutputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN long XMLCALL
+		xmlSaveDoc		(xmlSaveCtxtPtr ctxt,
+					 xmlDocPtr doc);
+XMLPUBFUN long XMLCALL
+		xmlSaveTree		(xmlSaveCtxtPtr ctxt,
+					 xmlNodePtr node);
+
+XMLPUBFUN int XMLCALL
+		xmlSaveFlush		(xmlSaveCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		xmlSaveClose		(xmlSaveCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+		xmlSaveSetEscape	(xmlSaveCtxtPtr ctxt,
+					 xmlCharEncodingOutputFunc escape);
+XMLPUBFUN int XMLCALL
+		xmlSaveSetAttrEscape	(xmlSaveCtxtPtr ctxt,
+					 xmlCharEncodingOutputFunc escape);
+#ifdef __cplusplus
+}
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
+#endif /* __XML_XMLSAVE_H__ */
+
+
diff --git a/src/include/libxml/xmlschemas.h b/src/include/libxml/xmlschemas.h
new file mode 100644
index 0000000..752bc3a
--- /dev/null
+++ b/src/include/libxml/xmlschemas.h
@@ -0,0 +1,218 @@
+/*
+ * Summary: incomplete XML Schemas structure implementation
+ * Description: interface to the XML Schemas handling and schema validity
+ *              checking, it is incomplete right now.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_H__
+#define __XML_SCHEMA_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This error codes are obsolete; not used any more.
+ */
+typedef enum {
+    XML_SCHEMAS_ERR_OK		= 0,
+    XML_SCHEMAS_ERR_NOROOT	= 1,
+    XML_SCHEMAS_ERR_UNDECLAREDELEM,
+    XML_SCHEMAS_ERR_NOTTOPLEVEL,
+    XML_SCHEMAS_ERR_MISSING,
+    XML_SCHEMAS_ERR_WRONGELEM,
+    XML_SCHEMAS_ERR_NOTYPE,
+    XML_SCHEMAS_ERR_NOROLLBACK,
+    XML_SCHEMAS_ERR_ISABSTRACT,
+    XML_SCHEMAS_ERR_NOTEMPTY,
+    XML_SCHEMAS_ERR_ELEMCONT,
+    XML_SCHEMAS_ERR_HAVEDEFAULT,
+    XML_SCHEMAS_ERR_NOTNILLABLE,
+    XML_SCHEMAS_ERR_EXTRACONTENT,
+    XML_SCHEMAS_ERR_INVALIDATTR,
+    XML_SCHEMAS_ERR_INVALIDELEM,
+    XML_SCHEMAS_ERR_NOTDETERMINIST,
+    XML_SCHEMAS_ERR_CONSTRUCT,
+    XML_SCHEMAS_ERR_INTERNAL,
+    XML_SCHEMAS_ERR_NOTSIMPLE,
+    XML_SCHEMAS_ERR_ATTRUNKNOWN,
+    XML_SCHEMAS_ERR_ATTRINVALID,
+    XML_SCHEMAS_ERR_VALUE,
+    XML_SCHEMAS_ERR_FACET,
+    XML_SCHEMAS_ERR_,
+    XML_SCHEMAS_ERR_XXX
+} xmlSchemaValidError;
+
+/*
+* ATTENTION: Change xmlSchemaSetValidOptions's check
+* for invalid values, if adding to the validation
+* options below.
+*/
+/**
+ * xmlSchemaValidOption:
+ *
+ * This is the set of XML Schema validation options.
+ */
+typedef enum {
+    XML_SCHEMA_VAL_VC_I_CREATE			= 1<<0
+	/* Default/fixed: create an attribute node
+	* or an element's text node on the instance.
+	*/
+} xmlSchemaValidOption;
+
+/*
+    XML_SCHEMA_VAL_XSI_ASSEMBLE			= 1<<1,
+	* assemble schemata using
+	* xsi:schemaLocation and
+	* xsi:noNamespaceSchemaLocation
+*/
+
+/**
+ * The schemas related types are kept internal
+ */
+typedef struct _xmlSchema xmlSchema;
+typedef xmlSchema *xmlSchemaPtr;
+
+/**
+ * xmlSchemaValidityErrorFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of an error callback from an XSD validation
+ */
+typedef void (XMLCDECL *xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * xmlSchemaValidityWarningFunc:
+ * @ctx: the validation context
+ * @msg: the message
+ * @...: extra arguments
+ *
+ * Signature of a warning callback from an XSD validation
+ */
+typedef void (XMLCDECL *xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * A schemas validation context
+ */
+typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt;
+typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr;
+
+typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt;
+typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr;
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlSchemaParserCtxtPtr XMLCALL
+	    xmlSchemaNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlSchemaParserCtxtPtr XMLCALL
+	    xmlSchemaNewMemParserCtxt	(const char *buffer,
+					 int size);
+XMLPUBFUN xmlSchemaParserCtxtPtr XMLCALL
+	    xmlSchemaNewDocParserCtxt	(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaFreeParserCtxt	(xmlSchemaParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaSetParserErrors	(xmlSchemaParserCtxtPtr ctxt,
+					 xmlSchemaValidityErrorFunc err,
+					 xmlSchemaValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+		xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
+					xmlSchemaValidityErrorFunc * err,
+					xmlSchemaValidityWarningFunc * warn,
+					void **ctx);
+XMLPUBFUN int XMLCALL
+		xmlSchemaIsValid	(xmlSchemaValidCtxtPtr ctxt);
+
+XMLPUBFUN xmlSchemaPtr XMLCALL
+	    xmlSchemaParse		(xmlSchemaParserCtxtPtr ctxt);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaFree		(xmlSchemaPtr schema);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void XMLCALL
+	    xmlSchemaDump		(FILE *output,
+					 xmlSchemaPtr schema);
+#endif /* LIBXML_OUTPUT_ENABLED */
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void XMLCALL
+	    xmlSchemaSetValidErrors	(xmlSchemaValidCtxtPtr ctxt,
+					 xmlSchemaValidityErrorFunc err,
+					 xmlSchemaValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaGetValidErrors	(xmlSchemaValidCtxtPtr ctxt,
+					 xmlSchemaValidityErrorFunc *err,
+					 xmlSchemaValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaSetValidOptions	(xmlSchemaValidCtxtPtr ctxt,
+					 int options);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt);
+
+XMLPUBFUN xmlSchemaValidCtxtPtr XMLCALL
+	    xmlSchemaNewValidCtxt	(xmlSchemaPtr schema);
+XMLPUBFUN void XMLCALL
+	    xmlSchemaFreeValidCtxt	(xmlSchemaValidCtxtPtr ctxt);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaValidateDoc	(xmlSchemaValidCtxtPtr ctxt,
+					 xmlDocPtr instance);
+XMLPUBFUN int XMLCALL
+            xmlSchemaValidateOneElement (xmlSchemaValidCtxtPtr ctxt,
+			                 xmlNodePtr elem);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaValidateStream	(xmlSchemaValidCtxtPtr ctxt,
+					 xmlParserInputBufferPtr input,
+					 xmlCharEncoding enc,
+					 xmlSAXHandlerPtr sax,
+					 void *user_data);
+XMLPUBFUN int XMLCALL
+	    xmlSchemaValidateFile	(xmlSchemaValidCtxtPtr ctxt,
+					 const char * filename,
+					 int options);
+
+XMLPUBFUN xmlParserCtxtPtr XMLCALL
+	    xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt);
+
+/*
+ * Interface to insert Schemas SAX validation in a SAX stream
+ */
+typedef struct _xmlSchemaSAXPlug xmlSchemaSAXPlugStruct;
+typedef xmlSchemaSAXPlugStruct *xmlSchemaSAXPlugPtr;
+
+XMLPUBFUN xmlSchemaSAXPlugPtr XMLCALL
+            xmlSchemaSAXPlug		(xmlSchemaValidCtxtPtr ctxt,
+					 xmlSAXHandlerPtr *sax,
+					 void **user_data);
+XMLPUBFUN int XMLCALL
+            xmlSchemaSAXUnplug		(xmlSchemaSAXPlugPtr plug);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_H__ */
diff --git a/src/include/libxml/xmlschemastypes.h b/src/include/libxml/xmlschemastypes.h
new file mode 100644
index 0000000..9a3a7a1
--- /dev/null
+++ b/src/include/libxml/xmlschemastypes.h
@@ -0,0 +1,151 @@
+/*
+ * Summary: implementation of XML Schema Datatypes
+ * Description: module providing the XML Schema Datatypes implementation
+ *              both definition and validity checking
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_TYPES_H__
+#define __XML_SCHEMA_TYPES_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/schemasInternals.h>
+#include <libxml/xmlschemas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    XML_SCHEMA_WHITESPACE_UNKNOWN = 0,
+    XML_SCHEMA_WHITESPACE_PRESERVE = 1,
+    XML_SCHEMA_WHITESPACE_REPLACE = 2,
+    XML_SCHEMA_WHITESPACE_COLLAPSE = 3
+} xmlSchemaWhitespaceValueType;
+
+XMLPUBFUN void XMLCALL		
+    		xmlSchemaInitTypes		(void);
+XMLPUBFUN void XMLCALL		
+		xmlSchemaCleanupTypes		(void);
+XMLPUBFUN xmlSchemaTypePtr XMLCALL 
+		xmlSchemaGetPredefinedType	(const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int XMLCALL		
+		xmlSchemaValidatePredefinedType	(xmlSchemaTypePtr type,
+						 const xmlChar *value,
+						 xmlSchemaValPtr *val);
+XMLPUBFUN int XMLCALL		
+		xmlSchemaValPredefTypeNode	(xmlSchemaTypePtr type,
+						 const xmlChar *value,
+						 xmlSchemaValPtr *val,
+						 xmlNodePtr node);
+XMLPUBFUN int XMLCALL		
+		xmlSchemaValidateFacet		(xmlSchemaTypePtr base,
+						 xmlSchemaFacetPtr facet,
+						 const xmlChar *value,
+						 xmlSchemaValPtr val);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValidateFacetWhtsp	(xmlSchemaFacetPtr facet,
+						 xmlSchemaWhitespaceValueType fws,
+						 xmlSchemaValType valType,						 
+						 const xmlChar *value,
+						 xmlSchemaValPtr val,
+						 xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN void XMLCALL		
+		xmlSchemaFreeValue		(xmlSchemaValPtr val);
+XMLPUBFUN xmlSchemaFacetPtr XMLCALL 
+		xmlSchemaNewFacet		(void);
+XMLPUBFUN int XMLCALL		
+		xmlSchemaCheckFacet		(xmlSchemaFacetPtr facet,
+						 xmlSchemaTypePtr typeDecl,
+						 xmlSchemaParserCtxtPtr ctxt,
+						 const xmlChar *name);
+XMLPUBFUN void XMLCALL		
+		xmlSchemaFreeFacet		(xmlSchemaFacetPtr facet);
+XMLPUBFUN int XMLCALL		
+		xmlSchemaCompareValues		(xmlSchemaValPtr x,
+						 xmlSchemaValPtr y);
+XMLPUBFUN xmlSchemaTypePtr XMLCALL		
+    xmlSchemaGetBuiltInListSimpleTypeItemType	(xmlSchemaTypePtr type);
+XMLPUBFUN int XMLCALL
+    xmlSchemaValidateListSimpleTypeFacet	(xmlSchemaFacetPtr facet,
+						 const xmlChar *value,
+						 unsigned long actualLen,
+						 unsigned long *expectedLen);
+XMLPUBFUN xmlSchemaTypePtr XMLCALL
+		xmlSchemaGetBuiltInType		(xmlSchemaValType type);
+XMLPUBFUN int XMLCALL
+		xmlSchemaIsBuiltInTypeFacet	(xmlSchemaTypePtr type, 
+						 int facetType);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlSchemaCollapseString		(const xmlChar *value);
+XMLPUBFUN xmlChar * XMLCALL
+		xmlSchemaWhiteSpaceReplace	(const xmlChar *value);
+XMLPUBFUN unsigned long  XMLCALL
+		xmlSchemaGetFacetValueAsULong	(xmlSchemaFacetPtr facet);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValidateLengthFacet	(xmlSchemaTypePtr type, 
+						 xmlSchemaFacetPtr facet,
+						 const xmlChar *value,
+						 xmlSchemaValPtr val,
+						 unsigned long *length);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet,
+						  xmlSchemaValType valType,
+						  const xmlChar *value,
+						  xmlSchemaValPtr val,						  
+						  unsigned long *length,
+						  xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaTypePtr type, 
+						 const xmlChar *value,
+						 xmlSchemaValPtr *val, 
+						 xmlNodePtr node);
+XMLPUBFUN int XMLCALL
+		xmlSchemaGetCanonValue		(xmlSchemaValPtr val,
+						 const xmlChar **retValue);
+XMLPUBFUN int XMLCALL
+		xmlSchemaGetCanonValueWhtsp	(xmlSchemaValPtr val,						 
+						 const xmlChar **retValue,
+						 xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValueAppend		(xmlSchemaValPtr prev,
+						 xmlSchemaValPtr cur);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+		xmlSchemaValueGetNext		(xmlSchemaValPtr cur);
+XMLPUBFUN const xmlChar * XMLCALL
+		xmlSchemaValueGetAsString	(xmlSchemaValPtr val);
+XMLPUBFUN int XMLCALL
+		xmlSchemaValueGetAsBoolean	(xmlSchemaValPtr val);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+		xmlSchemaNewStringValue		(xmlSchemaValType type,
+						 const xmlChar *value);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+		xmlSchemaNewNOTATIONValue	(const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+		xmlSchemaNewQNameValue		(const xmlChar *namespaceName,
+						 const xmlChar *localName);
+XMLPUBFUN int XMLCALL
+		xmlSchemaCompareValuesWhtsp	(xmlSchemaValPtr x,
+						 xmlSchemaWhitespaceValueType xws,
+						 xmlSchemaValPtr y,
+						 xmlSchemaWhitespaceValueType yws);
+XMLPUBFUN xmlSchemaValPtr XMLCALL
+		xmlSchemaCopyValue		(xmlSchemaValPtr val);
+XMLPUBFUN xmlSchemaValType XMLCALL
+		xmlSchemaGetValType		(xmlSchemaValPtr val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_TYPES_H__ */
diff --git a/src/include/libxml/xmlstring.h b/src/include/libxml/xmlstring.h
new file mode 100644
index 0000000..0bc6888
--- /dev/null
+++ b/src/include/libxml/xmlstring.h
@@ -0,0 +1,140 @@
+/*
+ * Summary: set of routines to process strings
+ * Description: type and interfaces needed for the internal string handling
+ *              of the library, especially UTF8 processing.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_STRING_H__
+#define __XML_STRING_H__
+
+#include <stdarg.h>
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlChar:
+ *
+ * This is a basic byte in an UTF-8 encoded string.
+ * It's unsigned allowing to pinpoint case where char * are assigned
+ * to xmlChar * (possibly making serialization back impossible).
+ */
+typedef unsigned char xmlChar;
+
+/**
+ * BAD_CAST:
+ *
+ * Macro to cast a string to an xmlChar * when one know its safe.
+ */
+#define BAD_CAST (xmlChar *)
+
+/*
+ * xmlChar handling
+ */
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrdup                (const xmlChar *cur);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrndup               (const xmlChar *cur,
+                                         int len);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlCharStrndup           (const char *cur,
+                                         int len);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlCharStrdup            (const char *cur);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrsub                (const xmlChar *str,
+                                         int start,
+                                         int len);
+XMLPUBFUN const xmlChar * XMLCALL
+                xmlStrchr                (const xmlChar *str,
+                                         xmlChar val);
+XMLPUBFUN const xmlChar * XMLCALL
+                xmlStrstr                (const xmlChar *str,
+                                         const xmlChar *val);
+XMLPUBFUN const xmlChar * XMLCALL
+                xmlStrcasestr            (const xmlChar *str,
+                                         const xmlChar *val);
+XMLPUBFUN int XMLCALL
+                xmlStrcmp                (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int XMLCALL
+                xmlStrncmp               (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int XMLCALL
+                xmlStrcasecmp            (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int XMLCALL
+                xmlStrncasecmp           (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int XMLCALL
+                xmlStrEqual              (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int XMLCALL
+                xmlStrQEqual             (const xmlChar *pref,
+                                         const xmlChar *name,
+                                         const xmlChar *str);
+XMLPUBFUN int XMLCALL
+                xmlStrlen                (const xmlChar *str);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrcat                (xmlChar *cur,
+                                         const xmlChar *add);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrncat               (xmlChar *cur,
+                                         const xmlChar *add,
+                                         int len);
+XMLPUBFUN xmlChar * XMLCALL
+                xmlStrncatNew            (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int XMLCALL
+                xmlStrPrintf             (xmlChar *buf,
+                                         int len,
+                                         const xmlChar *msg,
+                                         ...);
+XMLPUBFUN int XMLCALL
+                xmlStrVPrintf                (xmlChar *buf,
+                                         int len,
+                                         const xmlChar *msg,
+                                         va_list ap);
+
+XMLPUBFUN int XMLCALL
+        xmlGetUTF8Char                   (const unsigned char *utf,
+                                         int *len);
+XMLPUBFUN int XMLCALL
+        xmlCheckUTF8                     (const unsigned char *utf);
+XMLPUBFUN int XMLCALL
+        xmlUTF8Strsize                   (const xmlChar *utf,
+                                         int len);
+XMLPUBFUN xmlChar * XMLCALL 
+        xmlUTF8Strndup                   (const xmlChar *utf,
+                                         int len);
+XMLPUBFUN const xmlChar * XMLCALL 
+        xmlUTF8Strpos                    (const xmlChar *utf,
+                                         int pos);
+XMLPUBFUN int XMLCALL
+        xmlUTF8Strloc                    (const xmlChar *utf,
+                                         const xmlChar *utfchar);
+XMLPUBFUN xmlChar * XMLCALL 
+        xmlUTF8Strsub                    (const xmlChar *utf,
+                                         int start,
+                                         int len);
+XMLPUBFUN int XMLCALL
+        xmlUTF8Strlen                    (const xmlChar *utf);
+XMLPUBFUN int XMLCALL
+        xmlUTF8Size                      (const xmlChar *utf);
+XMLPUBFUN int XMLCALL
+        xmlUTF8Charcmp                   (const xmlChar *utf1,
+                                         const xmlChar *utf2);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_STRING_H__ */
diff --git a/src/include/libxml/xmlunicode.h b/src/include/libxml/xmlunicode.h
new file mode 100644
index 0000000..01ac8b6
--- /dev/null
+++ b/src/include/libxml/xmlunicode.h
@@ -0,0 +1,202 @@
+/*
+ * Summary: Unicode character APIs
+ * Description: API for the Unicode character APIs
+ *
+ * This file is automatically generated from the
+ * UCS description files of the Unicode Character Database
+ * http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html
+ * using the genUnicode.py Python script.
+ *
+ * Generation date: Mon Mar 27 11:09:52 2006
+ * Sources: Blocks-4.0.1.txt UnicodeData-4.0.1.txt
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_UNICODE_H__
+#define __XML_UNICODE_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_UNICODE_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XMLPUBFUN int XMLCALL xmlUCSIsAegeanNumbers	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsAlphabeticPresentationForms	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsArabic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsArabicPresentationFormsA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsArabicPresentationFormsB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsArmenian	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsArrows	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBasicLatin	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBengali	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBlockElements	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBopomofo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBopomofoExtended	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBoxDrawing	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBraillePatterns	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsBuhid	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsByzantineMusicalSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKCompatibility	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKCompatibilityForms	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKCompatibilityIdeographs	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKCompatibilityIdeographsSupplement	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKRadicalsSupplement	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKSymbolsandPunctuation	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKUnifiedIdeographs	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKUnifiedIdeographsExtensionA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCJKUnifiedIdeographsExtensionB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCherokee	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCombiningDiacriticalMarks	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCombiningDiacriticalMarksforSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCombiningHalfMarks	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCombiningMarksforSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsControlPictures	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCurrencySymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCypriotSyllabary	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCyrillic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCyrillicSupplement	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsDeseret	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsDevanagari	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsDingbats	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsEnclosedAlphanumerics	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsEnclosedCJKLettersandMonths	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsEthiopic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGeneralPunctuation	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGeometricShapes	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGeorgian	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGothic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGreek	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGreekExtended	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGreekandCoptic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGujarati	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsGurmukhi	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHalfwidthandFullwidthForms	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHangulCompatibilityJamo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHangulJamo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHangulSyllables	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHanunoo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHebrew	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHighPrivateUseSurrogates	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHighSurrogates	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsHiragana	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsIPAExtensions	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsIdeographicDescriptionCharacters	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKanbun	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKangxiRadicals	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKannada	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKatakana	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKatakanaPhoneticExtensions	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKhmer	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsKhmerSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLao	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLatin1Supplement	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLatinExtendedA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLatinExtendedB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLatinExtendedAdditional	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLetterlikeSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLimbu	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLinearBIdeograms	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLinearBSyllabary	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsLowSurrogates	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMalayalam	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMathematicalAlphanumericSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMathematicalOperators	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMiscellaneousMathematicalSymbolsA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMiscellaneousMathematicalSymbolsB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMiscellaneousSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMiscellaneousSymbolsandArrows	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMiscellaneousTechnical	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMongolian	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMusicalSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsMyanmar	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsNumberForms	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsOgham	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsOldItalic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsOpticalCharacterRecognition	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsOriya	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsOsmanya	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsPhoneticExtensions	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsPrivateUse	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsPrivateUseArea	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsRunic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsShavian	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSinhala	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSmallFormVariants	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSpacingModifierLetters	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSpecials	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSuperscriptsandSubscripts	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSupplementalArrowsA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSupplementalArrowsB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSupplementalMathematicalOperators	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSupplementaryPrivateUseAreaA	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSupplementaryPrivateUseAreaB	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsSyriac	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTagalog	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTagbanwa	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTags	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTaiLe	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTaiXuanJingSymbols	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTamil	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTelugu	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsThaana	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsThai	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsTibetan	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsUgaritic	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsUnifiedCanadianAboriginalSyllabics	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsVariationSelectors	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsVariationSelectorsSupplement	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsYiRadicals	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsYiSyllables	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsYijingHexagramSymbols	(int code);
+
+XMLPUBFUN int XMLCALL xmlUCSIsBlock	(int code, const char *block);
+
+XMLPUBFUN int XMLCALL xmlUCSIsCatC	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatCc	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatCf	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatCo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatCs	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatL	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatLl	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatLm	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatLo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatLt	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatLu	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatM	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatMc	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatMe	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatMn	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatN	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatNd	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatNl	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatNo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatP	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPc	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPd	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPe	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPf	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPi	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatPs	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatS	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatSc	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatSk	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatSm	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatSo	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatZ	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatZl	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatZp	(int code);
+XMLPUBFUN int XMLCALL xmlUCSIsCatZs	(int code);
+
+XMLPUBFUN int XMLCALL xmlUCSIsCat	(int code, const char *cat);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_UNICODE_ENABLED */
+
+#endif /* __XML_UNICODE_H__ */
diff --git a/src/include/libxml/xmlversion.h.in b/src/include/libxml/xmlversion.h.in
new file mode 100644
index 0000000..9585654
--- /dev/null
+++ b/src/include/libxml/xmlversion.h.in
@@ -0,0 +1,467 @@
+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "@VERSION@"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA "@LIBXML_VERSION_EXTRA@"
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * 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(@LIBXML_VERSION_NUMBER@);
+
+#ifndef VMS
+#if @WITH_TRIO@
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if @WITH_THREADS@
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if @WITH_TREE@
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if @WITH_OUTPUT@
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if @WITH_PUSH@
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if @WITH_READER@
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if @WITH_PATTERN@
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if @WITH_WRITER@
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if @WITH_SAX1@
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if @WITH_FTP@
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if @WITH_HTTP@
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if @WITH_VALID@
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if @WITH_HTML@
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if @WITH_LEGACY@
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if @WITH_C14N@
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if @WITH_CATALOG@
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if @WITH_DOCB@
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if @WITH_XPATH@
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if @WITH_XPTR@
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if @WITH_XINCLUDE@
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if @WITH_ICONV@
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ICU_ENABLED:
+ *
+ * Whether icu support is available
+ */
+#if @WITH_ICU@
+#define LIBXML_ICU_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if @WITH_ISO8859X@
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if @WITH_DEBUG@
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if @WITH_MEM_DEBUG@
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if @WITH_RUN_DEBUG@
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if @WITH_REGEXPS@
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if @WITH_REGEXPS@
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if @WITH_REGEXPS@
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if @WITH_SCHEMAS@
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if @WITH_SCHEMAS@
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if @WITH_SCHEMATRON@
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if @WITH_MODULES@
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION "@MODULE_EXTENSION@" 
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if @WITH_ZLIB@
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+
diff --git a/src/include/libxml/xmlwriter.h b/src/include/libxml/xmlwriter.h
new file mode 100644
index 0000000..91e683c
--- /dev/null
+++ b/src/include/libxml/xmlwriter.h
@@ -0,0 +1,485 @@
+
+/*
+ * Summary: text writing API for XML
+ * Description: text writing API for XML
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Alfred Mickautsch <alfred@mickautsch.de>
+ */
+
+#ifndef __XML_XMLWRITER_H__
+#define __XML_XMLWRITER_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_WRITER_ENABLED
+
+#include <stdarg.h>
+#include <libxml/xmlIO.h>
+#include <libxml/list.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    typedef struct _xmlTextWriter xmlTextWriter;
+    typedef xmlTextWriter *xmlTextWriterPtr;
+
+/*
+ * Constructors & Destructor
+ */
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriter(xmlOutputBufferPtr out);
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriterFilename(const char *uri, int compression);
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriterMemory(xmlBufferPtr buf, int compression);
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, int compression);
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriterDoc(xmlDocPtr * doc, int compression);
+    XMLPUBFUN xmlTextWriterPtr XMLCALL
+        xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node,
+                             int compression);
+    XMLPUBFUN void XMLCALL xmlFreeTextWriter(xmlTextWriterPtr writer);
+
+/*
+ * Functions
+ */
+
+
+/*
+ * Document
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartDocument(xmlTextWriterPtr writer,
+                                   const char *version,
+                                   const char *encoding,
+                                   const char *standalone);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndDocument(xmlTextWriterPtr
+                                                   writer);
+
+/*
+ * Comments
+ */
+    XMLPUBFUN int XMLCALL xmlTextWriterStartComment(xmlTextWriterPtr
+                                                    writer);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndComment(xmlTextWriterPtr writer);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
+                                        const char *format, ...)
+					LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
+                                         const char *format,
+                                         va_list argptr)
+					 LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteComment(xmlTextWriterPtr
+                                                    writer,
+                                                    const xmlChar *
+                                                    content);
+
+/*
+ * Elements
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartElement(xmlTextWriterPtr writer,
+                                  const xmlChar * name);
+    XMLPUBFUN int XMLCALL xmlTextWriterStartElementNS(xmlTextWriterPtr
+                                                      writer,
+                                                      const xmlChar *
+                                                      prefix,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      namespaceURI);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndElement(xmlTextWriterPtr writer);
+    XMLPUBFUN int XMLCALL xmlTextWriterFullEndElement(xmlTextWriterPtr
+                                                      writer);
+
+/*
+ * Elements conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
+                                        const xmlChar * name,
+                                        const char *format, ...)
+					LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
+                                         const xmlChar * name,
+                                         const char *format,
+                                         va_list argptr)
+					 LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteElement(xmlTextWriterPtr
+                                                    writer,
+                                                    const xmlChar * name,
+                                                    const xmlChar *
+                                                    content);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
+                                          const xmlChar * prefix,
+                                          const xmlChar * name,
+                                          const xmlChar * namespaceURI,
+                                          const char *format, ...)
+					  LIBXML_ATTR_FORMAT(5,6);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
+                                           const xmlChar * prefix,
+                                           const xmlChar * name,
+                                           const xmlChar * namespaceURI,
+                                           const char *format,
+                                           va_list argptr)
+					   LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteElementNS(xmlTextWriterPtr
+                                                      writer,
+                                                      const xmlChar *
+                                                      prefix,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      namespaceURI,
+                                                      const xmlChar *
+                                                      content);
+
+/*
+ * Text
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer,
+                                    const char *format, ...)
+				    LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer,
+                                     const char *format, va_list argptr)
+				     LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteRawLen(xmlTextWriterPtr writer,
+                                 const xmlChar * content, int len);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteRaw(xmlTextWriterPtr writer,
+                              const xmlChar * content);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteFormatString(xmlTextWriterPtr
+                                                         writer,
+                                                         const char
+                                                         *format, ...)
+							 LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteVFormatString(xmlTextWriterPtr
+                                                          writer,
+                                                          const char
+                                                          *format,
+                                                          va_list argptr)
+							  LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteString(xmlTextWriterPtr writer,
+                                                   const xmlChar *
+                                                   content);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteBase64(xmlTextWriterPtr writer,
+                                                   const char *data,
+                                                   int start, int len);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteBinHex(xmlTextWriterPtr writer,
+                                                   const char *data,
+                                                   int start, int len);
+
+/*
+ * Attributes
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartAttribute(xmlTextWriterPtr writer,
+                                    const xmlChar * name);
+    XMLPUBFUN int XMLCALL xmlTextWriterStartAttributeNS(xmlTextWriterPtr
+                                                        writer,
+                                                        const xmlChar *
+                                                        prefix,
+                                                        const xmlChar *
+                                                        name,
+                                                        const xmlChar *
+                                                        namespaceURI);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndAttribute(xmlTextWriterPtr
+                                                    writer);
+
+/*
+ * Attributes conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
+                                          const xmlChar * name,
+                                          const char *format, ...)
+					  LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
+                                           const xmlChar * name,
+                                           const char *format,
+                                           va_list argptr)
+					   LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteAttribute(xmlTextWriterPtr
+                                                      writer,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      content);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
+                                            const xmlChar * prefix,
+                                            const xmlChar * name,
+                                            const xmlChar * namespaceURI,
+                                            const char *format, ...)
+					    LIBXML_ATTR_FORMAT(5,6);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
+                                             const xmlChar * prefix,
+                                             const xmlChar * name,
+                                             const xmlChar * namespaceURI,
+                                             const char *format,
+                                             va_list argptr)
+					     LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteAttributeNS(xmlTextWriterPtr
+                                                        writer,
+                                                        const xmlChar *
+                                                        prefix,
+                                                        const xmlChar *
+                                                        name,
+                                                        const xmlChar *
+                                                        namespaceURI,
+                                                        const xmlChar *
+                                                        content);
+
+/*
+ * PI's
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartPI(xmlTextWriterPtr writer,
+                             const xmlChar * target);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndPI(xmlTextWriterPtr writer);
+
+/*
+ * PI conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer,
+                                   const xmlChar * target,
+                                   const char *format, ...)
+				   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
+                                    const xmlChar * target,
+                                    const char *format, va_list argptr)
+				    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWritePI(xmlTextWriterPtr writer,
+                             const xmlChar * target,
+                             const xmlChar * content);
+
+/**
+ * xmlTextWriterWriteProcessingInstruction:
+ *
+ * This macro maps to xmlTextWriterWritePI
+ */
+#define xmlTextWriterWriteProcessingInstruction xmlTextWriterWritePI
+
+/*
+ * CDATA
+ */
+    XMLPUBFUN int XMLCALL xmlTextWriterStartCDATA(xmlTextWriterPtr writer);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndCDATA(xmlTextWriterPtr writer);
+
+/*
+ * CDATA conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer,
+                                      const char *format, ...)
+				      LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer,
+                                       const char *format, va_list argptr)
+				       LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteCDATA(xmlTextWriterPtr writer,
+                                const xmlChar * content);
+
+/*
+ * DTD
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartDTD(xmlTextWriterPtr writer,
+                              const xmlChar * name,
+                              const xmlChar * pubid,
+                              const xmlChar * sysid);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndDTD(xmlTextWriterPtr writer);
+
+/*
+ * DTD conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
+                                    const xmlChar * name,
+                                    const xmlChar * pubid,
+                                    const xmlChar * sysid,
+                                    const char *format, ...)
+				    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)
+				     LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
+                              const xmlChar * name,
+                              const xmlChar * pubid,
+                              const xmlChar * sysid,
+                              const xmlChar * subset);
+
+/**
+ * xmlTextWriterWriteDocType:
+ *
+ * this macro maps to xmlTextWriterWriteDTD
+ */
+#define xmlTextWriterWriteDocType xmlTextWriterWriteDTD
+
+/*
+ * DTD element definition
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartDTDElement(xmlTextWriterPtr writer,
+                                     const xmlChar * name);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndDTDElement(xmlTextWriterPtr
+                                                     writer);
+
+/*
+ * DTD element definition conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
+                                           const xmlChar * name,
+                                           const char *format, ...)
+					   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
+                                            const xmlChar * name,
+                                            const char *format,
+                                            va_list argptr)
+					    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDElement(xmlTextWriterPtr
+                                                       writer,
+                                                       const xmlChar *
+                                                       name,
+                                                       const xmlChar *
+                                                       content);
+
+/*
+ * DTD attribute list definition
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer,
+                                     const xmlChar * name);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndDTDAttlist(xmlTextWriterPtr
+                                                     writer);
+
+/*
+ * DTD attribute list definition conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
+                                           const xmlChar * name,
+                                           const char *format, ...)
+					   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
+                                            const xmlChar * name,
+                                            const char *format,
+                                            va_list argptr)
+					    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr
+                                                       writer,
+                                                       const xmlChar *
+                                                       name,
+                                                       const xmlChar *
+                                                       content);
+
+/*
+ * DTD entity definition
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
+                                    int pe, const xmlChar * name);
+    XMLPUBFUN int XMLCALL xmlTextWriterEndDTDEntity(xmlTextWriterPtr
+                                                    writer);
+
+/*
+ * DTD entity definition conveniency functions
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
+                                                  int pe,
+                                                  const xmlChar * name,
+                                                  const char *format, ...)
+						  LIBXML_ATTR_FORMAT(4,5);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
+                                                   int pe,
+                                                   const xmlChar * name,
+                                                   const char *format,
+                                                   va_list argptr)
+						   LIBXML_ATTR_FORMAT(4,0);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
+                                            int pe,
+                                            const xmlChar * name,
+                                            const xmlChar * content);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
+                                            int pe,
+                                            const xmlChar * name,
+                                            const xmlChar * pubid,
+                                            const xmlChar * sysid,
+                                            const xmlChar * ndataid);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr
+                                                    writer,
+                                                    const xmlChar * pubid,
+                                                    const xmlChar * sysid,
+                                                    const xmlChar *
+                                                    ndataid);
+    XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDEntity(xmlTextWriterPtr
+                                                      writer, int pe,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      pubid,
+                                                      const xmlChar *
+                                                      sysid,
+                                                      const xmlChar *
+                                                      ndataid,
+                                                      const xmlChar *
+                                                      content);
+
+/*
+ * DTD notation definition
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
+                                      const xmlChar * name,
+                                      const xmlChar * pubid,
+                                      const xmlChar * sysid);
+
+/*
+ * Indentation
+ */
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent);
+    XMLPUBFUN int XMLCALL
+        xmlTextWriterSetIndentString(xmlTextWriterPtr writer,
+                                     const xmlChar * str);
+
+/*
+ * misc
+ */
+    XMLPUBFUN int XMLCALL xmlTextWriterFlush(xmlTextWriterPtr writer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_WRITER_ENABLED */
+
+#endif                          /* __XML_XMLWRITER_H__ */
diff --git a/src/include/libxml/xpath.h b/src/include/libxml/xpath.h
new file mode 100644
index 0000000..1a9e30e
--- /dev/null
+++ b/src/include/libxml/xpath.h
@@ -0,0 +1,546 @@
+/*
+ * Summary: XML Path Language implementation
+ * Description: API for the XML Path Language implementation
+ *
+ * XML Path Language implementation
+ * XPath is a language for addressing parts of an XML document,
+ * designed to be used by both XSLT and XPointer
+ *     http://www.w3.org/TR/xpath
+ *
+ * Implements
+ * W3C Recommendation 16 November 1999
+ *     http://www.w3.org/TR/1999/REC-xpath-19991116
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XPATH_H__
+#define __XML_XPATH_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#include <libxml/xmlerror.h>
+#include <libxml/tree.h>
+#include <libxml/hash.h>
+#endif /* LIBXML_XPATH_ENABLED */
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif /* LIBXML_XPATH_ENABLED or LIBXML_SCHEMAS_ENABLED */
+	
+#ifdef LIBXML_XPATH_ENABLED
+
+typedef struct _xmlXPathContext xmlXPathContext;
+typedef xmlXPathContext *xmlXPathContextPtr;
+typedef struct _xmlXPathParserContext xmlXPathParserContext;
+typedef xmlXPathParserContext *xmlXPathParserContextPtr;
+
+/**
+ * The set of XPath error codes.
+ */
+
+typedef enum {
+    XPATH_EXPRESSION_OK = 0,
+    XPATH_NUMBER_ERROR,
+    XPATH_UNFINISHED_LITERAL_ERROR,
+    XPATH_START_LITERAL_ERROR,
+    XPATH_VARIABLE_REF_ERROR,
+    XPATH_UNDEF_VARIABLE_ERROR,
+    XPATH_INVALID_PREDICATE_ERROR,
+    XPATH_EXPR_ERROR,
+    XPATH_UNCLOSED_ERROR,
+    XPATH_UNKNOWN_FUNC_ERROR,
+    XPATH_INVALID_OPERAND,
+    XPATH_INVALID_TYPE,
+    XPATH_INVALID_ARITY,
+    XPATH_INVALID_CTXT_SIZE,
+    XPATH_INVALID_CTXT_POSITION,
+    XPATH_MEMORY_ERROR,
+    XPTR_SYNTAX_ERROR,
+    XPTR_RESOURCE_ERROR,
+    XPTR_SUB_RESOURCE_ERROR,
+    XPATH_UNDEF_PREFIX_ERROR,
+    XPATH_ENCODING_ERROR,
+    XPATH_INVALID_CHAR_ERROR,
+    XPATH_INVALID_CTXT
+} xmlXPathError;
+
+/*
+ * A node-set (an unordered collection of nodes without duplicates).
+ */
+typedef struct _xmlNodeSet xmlNodeSet;
+typedef xmlNodeSet *xmlNodeSetPtr;
+struct _xmlNodeSet {
+    int nodeNr;			/* number of nodes in the set */
+    int nodeMax;		/* size of the array as allocated */
+    xmlNodePtr *nodeTab;	/* array of nodes in no particular order */
+    /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+};
+
+/*
+ * An expression is evaluated to yield an object, which
+ * has one of the following four basic types:
+ *   - node-set
+ *   - boolean
+ *   - number
+ *   - string
+ *
+ * @@ XPointer will add more types !
+ */
+
+typedef enum {
+    XPATH_UNDEFINED = 0,
+    XPATH_NODESET = 1,
+    XPATH_BOOLEAN = 2,
+    XPATH_NUMBER = 3,
+    XPATH_STRING = 4,
+    XPATH_POINT = 5,
+    XPATH_RANGE = 6,
+    XPATH_LOCATIONSET = 7,
+    XPATH_USERS = 8,
+    XPATH_XSLT_TREE = 9  /* An XSLT value tree, non modifiable */
+} xmlXPathObjectType;
+
+typedef struct _xmlXPathObject xmlXPathObject;
+typedef xmlXPathObject *xmlXPathObjectPtr;
+struct _xmlXPathObject {
+    xmlXPathObjectType type;
+    xmlNodeSetPtr nodesetval;
+    int boolval;
+    double floatval;
+    xmlChar *stringval;
+    void *user;
+    int index;
+    void *user2;
+    int index2;
+};
+
+/**
+ * xmlXPathConvertFunc:
+ * @obj:  an XPath object
+ * @type:  the number of the target type
+ *
+ * A conversion function is associated to a type and used to cast
+ * the new type to primitive values.
+ *
+ * Returns -1 in case of error, 0 otherwise
+ */
+typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
+
+/*
+ * Extra type: a name and a conversion function.
+ */
+
+typedef struct _xmlXPathType xmlXPathType;
+typedef xmlXPathType *xmlXPathTypePtr;
+struct _xmlXPathType {
+    const xmlChar         *name;		/* the type name */
+    xmlXPathConvertFunc func;		/* the conversion function */
+};
+
+/*
+ * Extra variable: a name and a value.
+ */
+
+typedef struct _xmlXPathVariable xmlXPathVariable;
+typedef xmlXPathVariable *xmlXPathVariablePtr;
+struct _xmlXPathVariable {
+    const xmlChar       *name;		/* the variable name */
+    xmlXPathObjectPtr value;		/* the value */
+};
+
+/**
+ * xmlXPathEvalFunc:
+ * @ctxt: an XPath parser context
+ * @nargs: the number of arguments passed to the function
+ *
+ * An XPath evaluation function, the parameters are on the XPath context stack.
+ */
+
+typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt,
+	                         int nargs);
+
+/*
+ * Extra function: a name and a evaluation function.
+ */
+
+typedef struct _xmlXPathFunct xmlXPathFunct;
+typedef xmlXPathFunct *xmlXPathFuncPtr;
+struct _xmlXPathFunct {
+    const xmlChar      *name;		/* the function name */
+    xmlXPathEvalFunc func;		/* the evaluation function */
+};
+
+/**
+ * xmlXPathAxisFunc:
+ * @ctxt:  the XPath interpreter context
+ * @cur:  the previous node being explored on that axis
+ *
+ * An axis traversal function. To traverse an axis, the engine calls
+ * the first time with cur == NULL and repeat until the function returns
+ * NULL indicating the end of the axis traversal.
+ *
+ * Returns the next node in that axis or NULL if at the end of the axis.
+ */
+
+typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
+				 xmlXPathObjectPtr cur);
+
+/*
+ * Extra axis: a name and an axis function.
+ */
+
+typedef struct _xmlXPathAxis xmlXPathAxis;
+typedef xmlXPathAxis *xmlXPathAxisPtr;
+struct _xmlXPathAxis {
+    const xmlChar      *name;		/* the axis name */
+    xmlXPathAxisFunc func;		/* the search function */
+};
+
+/**
+ * xmlXPathFunction:
+ * @ctxt:  the XPath interprestation context
+ * @nargs:  the number of arguments
+ *
+ * An XPath function.
+ * The arguments (if any) are popped out from the context stack
+ * and the result is pushed on the stack.
+ */
+
+typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
+
+/*
+ * Function and Variable Lookup.
+ */
+
+/**
+ * xmlXPathVariableLookupFunc:
+ * @ctxt:  an XPath context
+ * @name:  name of the variable
+ * @ns_uri:  the namespace name hosting this variable
+ *
+ * Prototype for callbacks used to plug variable lookup in the XPath
+ * engine.
+ *
+ * Returns the XPath object value or NULL if not found.
+ */
+typedef xmlXPathObjectPtr (*xmlXPathVariableLookupFunc) (void *ctxt,
+                                         const xmlChar *name,
+                                         const xmlChar *ns_uri);
+
+/**
+ * xmlXPathFuncLookupFunc:
+ * @ctxt:  an XPath context
+ * @name:  name of the function
+ * @ns_uri:  the namespace name hosting this function
+ *
+ * Prototype for callbacks used to plug function lookup in the XPath
+ * engine.
+ *
+ * Returns the XPath function or NULL if not found.
+ */
+typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt,
+					 const xmlChar *name,
+					 const xmlChar *ns_uri);
+
+/**
+ * xmlXPathFlags:
+ * Flags for XPath engine compilation and runtime
+ */
+/**
+ * XML_XPATH_CHECKNS:
+ *
+ * check namespaces at compilation
+ */
+#define XML_XPATH_CHECKNS (1<<0)
+/**
+ * XML_XPATH_NOVAR:
+ *
+ * forbid variables in expression
+ */
+#define XML_XPATH_NOVAR	  (1<<1)
+
+/**
+ * xmlXPathContext:
+ *
+ * Expression evaluation occurs with respect to a context.
+ * he context consists of:
+ *    - a node (the context node) 
+ *    - a node list (the context node list) 
+ *    - 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.
+ * The node may be modified when the context is passed to libxml2
+ * for an XPath evaluation so you may need to initialize it again
+ * before the next call.
+ */
+
+struct _xmlXPathContext {
+    xmlDocPtr doc;			/* The current document */
+    xmlNodePtr node;			/* The current node */
+
+    int nb_variables_unused;		/* unused (hash table) */
+    int max_variables_unused;		/* unused (hash table) */
+    xmlHashTablePtr varHash;		/* Hash table of defined variables */
+
+    int nb_types;			/* number of defined types */
+    int max_types;			/* max number of types */
+    xmlXPathTypePtr types;		/* Array of defined types */
+
+    int nb_funcs_unused;		/* unused (hash table) */
+    int max_funcs_unused;		/* unused (hash table) */
+    xmlHashTablePtr funcHash;		/* Hash table of defined funcs */
+
+    int nb_axis;			/* number of defined axis */
+    int max_axis;			/* max number of axis */
+    xmlXPathAxisPtr axis;		/* Array of defined axis */
+
+    /* 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 */
+    int proximityPosition;		/* the proximity position */
+
+    /* extra stuff for XPointer */
+    int xptr;				/* is 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 */
+    xmlXPathVariableLookupFunc varLookupFunc;/* variable lookup func */
+    void *varLookupData;		/* variable lookup data */
+
+    /* Possibility to link in an extra item */
+    void *extra;                        /* needed for XSLT */
+
+    /* The function name and URI when calling a function */
+    const xmlChar *function;
+    const xmlChar *functionURI;
+
+    /* function lookup function and data */
+    xmlXPathFuncLookupFunc funcLookupFunc;/* function lookup func */
+    void *funcLookupData;		/* function lookup data */
+
+    /* temporary namespace lists kept for walking the namespace axis */
+    xmlNsPtr *tmpNsList;		/* Array of namespaces */
+    int tmpNsNr;			/* number of namespaces in scope */
+
+    /* error reporting mechanism */
+    void *userData;                     /* user specific data block */
+    xmlStructuredErrorFunc error;       /* the callback in case of errors */
+    xmlError lastError;			/* the last error */
+    xmlNodePtr debugNode;		/* the source node XSLT */
+
+    /* dictionary */
+    xmlDictPtr dict;			/* dictionary if any */
+
+    int flags;				/* flags to control compilation */
+
+    /* Cache for reusal of XPath objects */
+    void *cache;
+};
+
+/*
+ * The structure of a compiled expression form is not public.
+ */
+
+typedef struct _xmlXPathCompExpr xmlXPathCompExpr;
+typedef xmlXPathCompExpr *xmlXPathCompExprPtr;
+
+/**
+ * xmlXPathParserContext:
+ *
+ * An XPath parser context. It contains pure parsing informations,
+ * an xmlXPathContext, and the stack of objects.
+ */
+struct _xmlXPathParserContext {
+    const xmlChar *cur;			/* the current char being parsed */
+    const xmlChar *base;			/* the full expression */
+
+    int error;				/* error code */
+
+    xmlXPathContextPtr  context;	/* the evaluation context */
+    xmlXPathObjectPtr     value;	/* the current value */
+    int                 valueNr;	/* number of values stacked */
+    int                valueMax;	/* max number of values stacked */
+    xmlXPathObjectPtr *valueTab;	/* stack of values */
+
+    xmlXPathCompExprPtr comp;		/* the precompiled expression */
+    int xptr;				/* it this an XPointer expression */
+    xmlNodePtr         ancestor;	/* used for walking preceding axis */
+};
+
+/************************************************************************
+ *									*
+ *			Public API					*
+ *									*
+ ************************************************************************/
+
+/**
+ * Objects and Nodesets handling
+ */
+
+XMLPUBVAR double xmlXPathNAN;
+XMLPUBVAR double xmlXPathPINF;
+XMLPUBVAR double xmlXPathNINF;
+
+/* These macros may later turn into functions */
+/**
+ * xmlXPathNodeSetGetLength:
+ * @ns:  a node-set
+ *
+ * Implement a functionality similar to the DOM NodeList.length.
+ *
+ * Returns the number of nodes in the node-set.
+ */
+#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0)
+/**
+ * xmlXPathNodeSetItem:
+ * @ns:  a node-set
+ * @index:  index of a node in the set
+ *
+ * Implements a functionality similar to the DOM NodeList.item().
+ *
+ * Returns the xmlNodePtr at the given @index in @ns or NULL if
+ *         @index is out of range (0 to length-1)
+ */
+#define xmlXPathNodeSetItem(ns, index)				\
+		((((ns) != NULL) && 				\
+		  ((index) >= 0) && ((index) < (ns)->nodeNr)) ?	\
+		 (ns)->nodeTab[(index)]				\
+		 : NULL)
+/**
+ * xmlXPathNodeSetIsEmpty:
+ * @ns: a node-set
+ *
+ * Checks whether @ns is empty or not.
+ *
+ * Returns %TRUE if @ns is an empty node-set.
+ */
+#define xmlXPathNodeSetIsEmpty(ns)                                      \
+    (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL))
+
+
+XMLPUBFUN void XMLCALL		   
+		    xmlXPathFreeObject		(xmlXPathObjectPtr obj);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	   
+		    xmlXPathNodeSetCreate	(xmlNodePtr val);
+XMLPUBFUN void XMLCALL		   
+		    xmlXPathFreeNodeSetList	(xmlXPathObjectPtr obj);
+XMLPUBFUN void XMLCALL		   
+		    xmlXPathFreeNodeSet		(xmlNodeSetPtr obj);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathObjectCopy		(xmlXPathObjectPtr val);
+XMLPUBFUN int XMLCALL		   
+		    xmlXPathCmpNodes		(xmlNodePtr node1,
+						 xmlNodePtr node2);
+/**
+ * Conversion functions to basic types.
+ */
+XMLPUBFUN int XMLCALL		   
+		    xmlXPathCastNumberToBoolean	(double val);
+XMLPUBFUN int XMLCALL		   
+		    xmlXPathCastStringToBoolean	(const xmlChar * val);
+XMLPUBFUN int XMLCALL		   
+		    xmlXPathCastNodeSetToBoolean(xmlNodeSetPtr ns);
+XMLPUBFUN int XMLCALL		   
+		    xmlXPathCastToBoolean	(xmlXPathObjectPtr val);
+
+XMLPUBFUN double XMLCALL		   
+		    xmlXPathCastBooleanToNumber	(int val);
+XMLPUBFUN double XMLCALL		   
+		    xmlXPathCastStringToNumber	(const xmlChar * val);
+XMLPUBFUN double XMLCALL		   
+		    xmlXPathCastNodeToNumber	(xmlNodePtr node);
+XMLPUBFUN double XMLCALL		   
+		    xmlXPathCastNodeSetToNumber	(xmlNodeSetPtr ns);
+XMLPUBFUN double XMLCALL		   
+		    xmlXPathCastToNumber	(xmlXPathObjectPtr val);
+
+XMLPUBFUN xmlChar * XMLCALL	   
+		    xmlXPathCastBooleanToString	(int val);
+XMLPUBFUN xmlChar * XMLCALL	   
+		    xmlXPathCastNumberToString	(double val);
+XMLPUBFUN xmlChar * XMLCALL	   
+		    xmlXPathCastNodeToString	(xmlNodePtr node);
+XMLPUBFUN xmlChar * XMLCALL	   
+		    xmlXPathCastNodeSetToString	(xmlNodeSetPtr ns);
+XMLPUBFUN xmlChar * XMLCALL	   
+		    xmlXPathCastToString	(xmlXPathObjectPtr val);
+
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathConvertBoolean	(xmlXPathObjectPtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathConvertNumber	(xmlXPathObjectPtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathConvertString	(xmlXPathObjectPtr val);
+
+/**
+ * Context handling.
+ */
+XMLPUBFUN xmlXPathContextPtr XMLCALL 
+		    xmlXPathNewContext		(xmlDocPtr doc);
+XMLPUBFUN void XMLCALL
+		    xmlXPathFreeContext		(xmlXPathContextPtr ctxt);
+XMLPUBFUN int XMLCALL
+		    xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
+				            int active,
+					    int value,
+					    int options);
+/**
+ * Evaluation functions.
+ */
+XMLPUBFUN long XMLCALL               
+		    xmlXPathOrderDocElems	(xmlDocPtr doc);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathEval		(const xmlChar *str,
+						 xmlXPathContextPtr ctx);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		    xmlXPathEvalExpression	(const xmlChar *str,
+						 xmlXPathContextPtr ctxt);
+XMLPUBFUN int XMLCALL                
+		    xmlXPathEvalPredicate	(xmlXPathContextPtr ctxt,
+						 xmlXPathObjectPtr res);
+/**
+ * Separate compilation/evaluation entry points.
+ */
+XMLPUBFUN xmlXPathCompExprPtr XMLCALL 
+		    xmlXPathCompile		(const xmlChar *str);
+XMLPUBFUN xmlXPathCompExprPtr XMLCALL 
+		    xmlXPathCtxtCompile		(xmlXPathContextPtr ctxt,
+		    				 const xmlChar *str);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL   
+		    xmlXPathCompiledEval	(xmlXPathCompExprPtr comp,
+						 xmlXPathContextPtr ctx);
+XMLPUBFUN int XMLCALL   
+		    xmlXPathCompiledEvalToBoolean(xmlXPathCompExprPtr comp,
+						 xmlXPathContextPtr ctxt);
+XMLPUBFUN void XMLCALL                
+		    xmlXPathFreeCompExpr	(xmlXPathCompExprPtr comp);
+#endif /* LIBXML_XPATH_ENABLED */
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+XMLPUBFUN void XMLCALL		   
+		    xmlXPathInit		(void);
+XMLPUBFUN int XMLCALL
+		xmlXPathIsNaN	(double val);
+XMLPUBFUN int XMLCALL
+		xmlXPathIsInf	(double val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPATH_ENABLED or LIBXML_SCHEMAS_ENABLED*/
+#endif /* ! __XML_XPATH_H__ */
diff --git a/src/include/libxml/xpathInternals.h b/src/include/libxml/xpathInternals.h
new file mode 100644
index 0000000..dcd5243
--- /dev/null
+++ b/src/include/libxml/xpathInternals.h
@@ -0,0 +1,630 @@
+/*
+ * Summary: internal interfaces for XML Path Language implementation
+ * Description: internal interfaces for XML Path Language implementation
+ *              used to build new modules on top of XPath like XPointer and
+ *              XSLT
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XPATH_INTERNALS_H__
+#define __XML_XPATH_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xpath.h>
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************
+ *									*
+ *			Helpers						*
+ *									*
+ ************************************************************************/
+
+/*
+ * Many of these macros may later turn into functions. They
+ * shouldn't be used in #ifdef's preprocessor instructions.
+ */
+/**
+ * xmlXPathSetError:
+ * @ctxt:  an XPath parser context
+ * @err:  an xmlXPathError code
+ *
+ * Raises an error.
+ */
+#define xmlXPathSetError(ctxt, err)					\
+    { xmlXPatherror((ctxt), __FILE__, __LINE__, (err));			\
+      if ((ctxt) != NULL) (ctxt)->error = (err); }
+
+/**
+ * xmlXPathSetArityError:
+ * @ctxt:  an XPath parser context
+ *
+ * Raises an XPATH_INVALID_ARITY error.
+ */
+#define xmlXPathSetArityError(ctxt)					\
+    xmlXPathSetError((ctxt), XPATH_INVALID_ARITY)
+
+/**
+ * xmlXPathSetTypeError:
+ * @ctxt:  an XPath parser context
+ *
+ * Raises an XPATH_INVALID_TYPE error.
+ */
+#define xmlXPathSetTypeError(ctxt)					\
+    xmlXPathSetError((ctxt), XPATH_INVALID_TYPE)
+
+/**
+ * xmlXPathGetError:
+ * @ctxt:  an XPath parser context
+ *
+ * Get the error code of an XPath context.
+ *
+ * Returns the context error.
+ */
+#define xmlXPathGetError(ctxt)	  ((ctxt)->error)
+
+/**
+ * xmlXPathCheckError:
+ * @ctxt:  an XPath parser context
+ *
+ * Check if an XPath error was raised.
+ *
+ * Returns true if an error has been raised, false otherwise.
+ */
+#define xmlXPathCheckError(ctxt)  ((ctxt)->error != XPATH_EXPRESSION_OK)
+
+/**
+ * xmlXPathGetDocument:
+ * @ctxt:  an XPath parser context
+ *
+ * Get the document of an XPath context.
+ *
+ * Returns the context document.
+ */
+#define xmlXPathGetDocument(ctxt)	((ctxt)->context->doc)
+
+/**
+ * xmlXPathGetContextNode:
+ * @ctxt: an XPath parser context
+ *
+ * Get the context node of an XPath context.
+ *
+ * Returns the context node.
+ */
+#define xmlXPathGetContextNode(ctxt)	((ctxt)->context->node)
+
+XMLPUBFUN int XMLCALL		
+		xmlXPathPopBoolean	(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN double XMLCALL		
+    		xmlXPathPopNumber	(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL	
+    		xmlXPathPopString	(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+    		xmlXPathPopNodeSet	(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void * XMLCALL		
+    		xmlXPathPopExternal	(xmlXPathParserContextPtr ctxt);
+
+/**
+ * xmlXPathReturnBoolean:
+ * @ctxt:  an XPath parser context
+ * @val:  a boolean
+ *
+ * Pushes the boolean @val on the context stack.
+ */
+#define xmlXPathReturnBoolean(ctxt, val)				\
+    valuePush((ctxt), xmlXPathNewBoolean(val))
+
+/**
+ * xmlXPathReturnTrue:
+ * @ctxt:  an XPath parser context
+ *
+ * Pushes true on the context stack.
+ */
+#define xmlXPathReturnTrue(ctxt)   xmlXPathReturnBoolean((ctxt), 1)
+
+/**
+ * xmlXPathReturnFalse:
+ * @ctxt:  an XPath parser context
+ *
+ * Pushes false on the context stack.
+ */
+#define xmlXPathReturnFalse(ctxt)  xmlXPathReturnBoolean((ctxt), 0)
+
+/**
+ * xmlXPathReturnNumber:
+ * @ctxt:  an XPath parser context
+ * @val:  a double
+ *
+ * Pushes the double @val on the context stack.
+ */
+#define xmlXPathReturnNumber(ctxt, val)					\
+    valuePush((ctxt), xmlXPathNewFloat(val))
+
+/**
+ * xmlXPathReturnString:
+ * @ctxt:  an XPath parser context
+ * @str:  a string
+ *
+ * Pushes the string @str on the context stack.
+ */
+#define xmlXPathReturnString(ctxt, str)					\
+    valuePush((ctxt), xmlXPathWrapString(str))
+
+/**
+ * xmlXPathReturnEmptyString:
+ * @ctxt:  an XPath parser context
+ *
+ * Pushes an empty string on the stack.
+ */
+#define xmlXPathReturnEmptyString(ctxt)					\
+    valuePush((ctxt), xmlXPathNewCString(""))
+
+/**
+ * xmlXPathReturnNodeSet:
+ * @ctxt:  an XPath parser context
+ * @ns:  a node-set
+ *
+ * Pushes the node-set @ns on the context stack.
+ */
+#define xmlXPathReturnNodeSet(ctxt, ns)					\
+    valuePush((ctxt), xmlXPathWrapNodeSet(ns))
+
+/**
+ * xmlXPathReturnEmptyNodeSet:
+ * @ctxt:  an XPath parser context
+ *
+ * Pushes an empty node-set on the context stack.
+ */
+#define xmlXPathReturnEmptyNodeSet(ctxt)				\
+    valuePush((ctxt), xmlXPathNewNodeSet(NULL))
+
+/**
+ * xmlXPathReturnExternal:
+ * @ctxt:  an XPath parser context
+ * @val:  user data
+ *
+ * Pushes user data on the context stack.
+ */
+#define xmlXPathReturnExternal(ctxt, val)				\
+    valuePush((ctxt), xmlXPathWrapExternal(val))
+
+/**
+ * xmlXPathStackIsNodeSet:
+ * @ctxt: an XPath parser context
+ *
+ * Check if the current value on the XPath stack is a node set or
+ * an XSLT value tree.
+ *
+ * Returns true if the current object on the stack is a node-set.
+ */
+#define xmlXPathStackIsNodeSet(ctxt)					\
+    (((ctxt)->value != NULL)						\
+     && (((ctxt)->value->type == XPATH_NODESET)				\
+         || ((ctxt)->value->type == XPATH_XSLT_TREE)))
+
+/**
+ * xmlXPathStackIsExternal:
+ * @ctxt: an XPath parser context
+ *
+ * Checks if the current value on the XPath stack is an external
+ * object.
+ *
+ * Returns true if the current object on the stack is an external
+ * object.
+ */
+#define xmlXPathStackIsExternal(ctxt)					\
+	((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS))
+
+/**
+ * xmlXPathEmptyNodeSet:
+ * @ns:  a node-set
+ *
+ * Empties a node-set.
+ */
+#define xmlXPathEmptyNodeSet(ns)					\
+    { while ((ns)->nodeNr > 0) (ns)->nodeTab[(ns)->nodeNr--] = NULL; }
+
+/**
+ * CHECK_ERROR:
+ *
+ * Macro to return from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR							\
+    if (ctxt->error != XPATH_EXPRESSION_OK) return
+
+/**
+ * CHECK_ERROR0:
+ *
+ * Macro to return 0 from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR0							\
+    if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
+
+/**
+ * XP_ERROR:
+ * @X:  the error code
+ *
+ * Macro to raise an XPath error and return.
+ */
+#define XP_ERROR(X)							\
+    { xmlXPathErr(ctxt, X); return; }
+
+/**
+ * XP_ERROR0:
+ * @X:  the error code
+ *
+ * Macro to raise an XPath error and return 0.
+ */
+#define XP_ERROR0(X)							\
+    { xmlXPathErr(ctxt, X); return(0); }
+
+/**
+ * CHECK_TYPE:
+ * @typeval:  the XPath type
+ *
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type.
+ */
+#define CHECK_TYPE(typeval)						\
+    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+/**
+ * CHECK_TYPE0:
+ * @typeval:  the XPath type
+ *
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type. Return(0) in case of failure
+ */
+#define CHECK_TYPE0(typeval)						\
+    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
+        XP_ERROR0(XPATH_INVALID_TYPE)
+
+/**
+ * CHECK_ARITY:
+ * @x:  the number of expected args
+ *
+ * Macro to check that the number of args passed to an XPath function matches.
+ */
+#define CHECK_ARITY(x)							\
+    if (ctxt == NULL) return;						\
+    if (nargs != (x))							\
+        XP_ERROR(XPATH_INVALID_ARITY);
+
+/**
+ * CAST_TO_STRING:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a string.
+ */
+#define CAST_TO_STRING							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING))	\
+        xmlXPathStringFunction(ctxt, 1);
+
+/**
+ * CAST_TO_NUMBER:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a number.
+ */
+#define CAST_TO_NUMBER							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER))	\
+        xmlXPathNumberFunction(ctxt, 1);
+
+/**
+ * CAST_TO_BOOLEAN:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a boolean.
+ */
+#define CAST_TO_BOOLEAN							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN))	\
+        xmlXPathBooleanFunction(ctxt, 1);
+
+/*
+ * Variable Lookup forwarding.
+ */
+
+XMLPUBFUN void XMLCALL	
+	xmlXPathRegisterVariableLookup	(xmlXPathContextPtr ctxt,
+					 xmlXPathVariableLookupFunc f,
+					 void *data);
+
+/*
+ * Function Lookup forwarding.
+ */
+
+XMLPUBFUN void XMLCALL	
+	    xmlXPathRegisterFuncLookup	(xmlXPathContextPtr ctxt,
+					 xmlXPathFuncLookupFunc f,
+					 void *funcCtxt);
+
+/*
+ * Error reporting.
+ */
+XMLPUBFUN void XMLCALL		
+		xmlXPatherror	(xmlXPathParserContextPtr ctxt,
+				 const char *file,
+				 int line,
+				 int no);
+
+XMLPUBFUN void XMLCALL
+		xmlXPathErr	(xmlXPathParserContextPtr ctxt,
+				 int error);
+
+#ifdef LIBXML_DEBUG_ENABLED
+XMLPUBFUN void XMLCALL		
+		xmlXPathDebugDumpObject	(FILE *output,
+					 xmlXPathObjectPtr cur,
+					 int depth);
+XMLPUBFUN void XMLCALL		
+	    xmlXPathDebugDumpCompExpr(FILE *output,
+					 xmlXPathCompExprPtr comp,
+					 int depth);
+#endif
+/**
+ * NodeSet handling.
+ */
+XMLPUBFUN int XMLCALL		
+		xmlXPathNodeSetContains		(xmlNodeSetPtr cur,
+						 xmlNodePtr val);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathDifference		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathIntersection		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathDistinctSorted		(xmlNodeSetPtr nodes);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathDistinct		(xmlNodeSetPtr nodes);
+
+XMLPUBFUN int XMLCALL		
+		xmlXPathHasSameNodes		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathNodeLeadingSorted	(xmlNodeSetPtr nodes,
+						 xmlNodePtr node);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathLeadingSorted		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathNodeLeading		(xmlNodeSetPtr nodes,
+						 xmlNodePtr node);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathLeading			(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathNodeTrailingSorted	(xmlNodeSetPtr nodes,
+						 xmlNodePtr node);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathTrailingSorted		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathNodeTrailing		(xmlNodeSetPtr nodes,
+						 xmlNodePtr node);
+XMLPUBFUN xmlNodeSetPtr XMLCALL	
+		xmlXPathTrailing		(xmlNodeSetPtr nodes1,
+						 xmlNodeSetPtr nodes2);
+
+
+/**
+ * Extending a context.
+ */
+
+XMLPUBFUN int XMLCALL		   
+		xmlXPathRegisterNs		(xmlXPathContextPtr ctxt,
+						 const xmlChar *prefix,
+						 const xmlChar *ns_uri);
+XMLPUBFUN const xmlChar * XMLCALL	   
+		xmlXPathNsLookup		(xmlXPathContextPtr ctxt,
+						 const xmlChar *prefix);
+XMLPUBFUN void XMLCALL		   
+		xmlXPathRegisteredNsCleanup	(xmlXPathContextPtr ctxt);
+
+XMLPUBFUN int XMLCALL		   
+		xmlXPathRegisterFunc		(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 xmlXPathFunction f);
+XMLPUBFUN int XMLCALL		   
+		xmlXPathRegisterFuncNS		(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri,
+						 xmlXPathFunction f);
+XMLPUBFUN int XMLCALL		   
+		xmlXPathRegisterVariable	(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 xmlXPathObjectPtr value);
+XMLPUBFUN int XMLCALL		   
+		xmlXPathRegisterVariableNS	(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri,
+						 xmlXPathObjectPtr value);
+XMLPUBFUN xmlXPathFunction XMLCALL   
+		xmlXPathFunctionLookup		(xmlXPathContextPtr ctxt,
+						 const xmlChar *name);
+XMLPUBFUN xmlXPathFunction XMLCALL   
+		xmlXPathFunctionLookupNS	(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri);
+XMLPUBFUN void XMLCALL		   
+		xmlXPathRegisteredFuncsCleanup	(xmlXPathContextPtr ctxt);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		xmlXPathVariableLookup		(xmlXPathContextPtr ctxt,
+						 const xmlChar *name);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL  
+		xmlXPathVariableLookupNS	(xmlXPathContextPtr ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri);
+XMLPUBFUN void XMLCALL		   
+		xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt);
+
+/**
+ * Utilities to extend XPath.
+ */
+XMLPUBFUN xmlXPathParserContextPtr XMLCALL
+		  xmlXPathNewParserContext	(const xmlChar *str,
+			  			 xmlXPathContextPtr ctxt);
+XMLPUBFUN void XMLCALL		  
+		xmlXPathFreeParserContext	(xmlXPathParserContextPtr ctxt);
+
+/* TODO: remap to xmlXPathValuePop and Push. */
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		valuePop			(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN int XMLCALL		  
+		valuePush			(xmlXPathParserContextPtr ctxt,
+					 	 xmlXPathObjectPtr value);
+
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewString		(const xmlChar *val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewCString		(const char *val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathWrapString		(xmlChar *val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathWrapCString		(char * val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewFloat		(double val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewBoolean		(int val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewNodeSet		(xmlNodePtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewValueTree		(xmlNodePtr val);
+XMLPUBFUN void XMLCALL		  
+		xmlXPathNodeSetAdd		(xmlNodeSetPtr cur,
+						 xmlNodePtr val);
+XMLPUBFUN void XMLCALL              
+		xmlXPathNodeSetAddUnique	(xmlNodeSetPtr cur,
+						 xmlNodePtr val);
+XMLPUBFUN void XMLCALL		  
+		xmlXPathNodeSetAddNs		(xmlNodeSetPtr cur, 
+						 xmlNodePtr node, 
+						 xmlNsPtr ns);
+XMLPUBFUN void XMLCALL              
+		xmlXPathNodeSetSort		(xmlNodeSetPtr set);
+
+XMLPUBFUN void XMLCALL		  
+		xmlXPathRoot			(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL		  
+		xmlXPathEvalExpr		(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL	  
+		xmlXPathParseName		(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN xmlChar * XMLCALL	  
+		xmlXPathParseNCName		(xmlXPathParserContextPtr ctxt);
+
+/*
+ * Existing functions.
+ */
+XMLPUBFUN double XMLCALL 
+		xmlXPathStringEvalNumber	(const xmlChar *str);
+XMLPUBFUN int XMLCALL 
+		xmlXPathEvaluatePredicateResult (xmlXPathParserContextPtr ctxt, 
+						 xmlXPathObjectPtr res);
+XMLPUBFUN void XMLCALL 
+		xmlXPathRegisterAllFunctions	(xmlXPathContextPtr ctxt);
+XMLPUBFUN xmlNodeSetPtr XMLCALL 
+		xmlXPathNodeSetMerge		(xmlNodeSetPtr val1, 
+						 xmlNodeSetPtr val2);
+XMLPUBFUN void XMLCALL 
+		xmlXPathNodeSetDel		(xmlNodeSetPtr cur, 
+						 xmlNodePtr val);
+XMLPUBFUN void XMLCALL 
+		xmlXPathNodeSetRemove		(xmlNodeSetPtr cur, 
+						 int val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathNewNodeSetList		(xmlNodeSetPtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathWrapNodeSet		(xmlNodeSetPtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+		xmlXPathWrapExternal		(void *val);
+
+XMLPUBFUN int XMLCALL xmlXPathEqualValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN int XMLCALL xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN int XMLCALL xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict);
+XMLPUBFUN void XMLCALL xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL xmlXPathAddValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL xmlXPathSubValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL xmlXPathMultValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL xmlXPathDivValues(xmlXPathParserContextPtr ctxt);
+XMLPUBFUN void XMLCALL xmlXPathModValues(xmlXPathParserContextPtr ctxt);
+
+XMLPUBFUN int XMLCALL xmlXPathIsNodeType(const xmlChar *name);
+
+/*
+ * Some of the axis navigation routines.
+ */
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextSelf(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextChild(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextParent(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+XMLPUBFUN xmlNodePtr XMLCALL xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt,
+			xmlNodePtr cur);
+/*
+ * The official core of XPath functions.
+ */
+XMLPUBFUN void XMLCALL xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
+XMLPUBFUN void XMLCALL xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
+
+/**
+ * Really internal functions
+ */
+XMLPUBFUN void XMLCALL xmlXPathNodeSetFreeNs(xmlNsPtr ns);
+ 
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPATH_ENABLED */
+#endif /* ! __XML_XPATH_INTERNALS_H__ */
diff --git a/src/include/libxml/xpointer.h b/src/include/libxml/xpointer.h
new file mode 100644
index 0000000..dde1dfb
--- /dev/null
+++ b/src/include/libxml/xpointer.h
@@ -0,0 +1,114 @@
+/*
+ * Summary: API to handle XML Pointers
+ * Description: API to handle XML Pointers
+ * Base implementation was made accordingly to
+ * W3C Candidate Recommendation 7 June 2000
+ * http://www.w3.org/TR/2000/CR-xptr-20000607
+ *
+ * Added support for the element() scheme described in:
+ * W3C Proposed Recommendation 13 November 2002
+ * http://www.w3.org/TR/2002/PR-xptr-element-20021113/  
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_XPTR_H__
+#define __XML_XPTR_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_XPTR_ENABLED
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A Location Set
+ */
+typedef struct _xmlLocationSet xmlLocationSet;
+typedef xmlLocationSet *xmlLocationSetPtr;
+struct _xmlLocationSet {
+    int locNr;		      /* number of locations in the set */
+    int locMax;		      /* size of the array as allocated */
+    xmlXPathObjectPtr *locTab;/* array of locations */
+};
+
+/*
+ * Handling of location sets.
+ */
+
+XMLPUBFUN xmlLocationSetPtr XMLCALL			
+		    xmlXPtrLocationSetCreate	(xmlXPathObjectPtr val);
+XMLPUBFUN void XMLCALL			
+		    xmlXPtrFreeLocationSet	(xmlLocationSetPtr obj);
+XMLPUBFUN xmlLocationSetPtr XMLCALL	
+		    xmlXPtrLocationSetMerge	(xmlLocationSetPtr val1,
+						 xmlLocationSetPtr val2);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewRange		(xmlNodePtr start,
+						 int startindex,
+						 xmlNodePtr end,
+						 int endindex);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewRangePoints	(xmlXPathObjectPtr start,
+						 xmlXPathObjectPtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewRangeNodePoint	(xmlNodePtr start,
+						 xmlXPathObjectPtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewRangePointNode	(xmlXPathObjectPtr start,
+						 xmlNodePtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL			
+		    xmlXPtrNewRangeNodes	(xmlNodePtr start,
+						 xmlNodePtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewLocationSetNodes	(xmlNodePtr start,
+						 xmlNodePtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewRangeNodeObject	(xmlNodePtr start,
+						 xmlXPathObjectPtr end);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrNewCollapsedRange	(xmlNodePtr start);
+XMLPUBFUN void XMLCALL			
+		    xmlXPtrLocationSetAdd	(xmlLocationSetPtr cur,
+						 xmlXPathObjectPtr val);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrWrapLocationSet	(xmlLocationSetPtr val);
+XMLPUBFUN void XMLCALL			
+		    xmlXPtrLocationSetDel	(xmlLocationSetPtr cur,
+						 xmlXPathObjectPtr val);
+XMLPUBFUN void XMLCALL			
+		    xmlXPtrLocationSetRemove	(xmlLocationSetPtr cur,
+						 int val);
+
+/*
+ * Functions.
+ */
+XMLPUBFUN xmlXPathContextPtr XMLCALL	
+		    xmlXPtrNewContext		(xmlDocPtr doc,
+						 xmlNodePtr here,
+						 xmlNodePtr origin);
+XMLPUBFUN xmlXPathObjectPtr XMLCALL	
+		    xmlXPtrEval			(const xmlChar *str,
+						 xmlXPathContextPtr ctx);
+XMLPUBFUN void XMLCALL					    
+		    xmlXPtrRangeToFunction	(xmlXPathParserContextPtr ctxt,
+       						 int nargs);
+XMLPUBFUN xmlNodePtr XMLCALL		
+		    xmlXPtrBuildNodeList	(xmlXPathObjectPtr obj);
+XMLPUBFUN void XMLCALL		
+		    xmlXPtrEvalRangePredicate	(xmlXPathParserContextPtr ctxt);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPTR_ENABLED */
+#endif /* __XML_XPTR_H__ */
diff --git a/src/include/win32config.h b/src/include/win32config.h
new file mode 100644
index 0000000..5112ce6
--- /dev/null
+++ b/src/include/win32config.h
@@ -0,0 +1,126 @@
+#ifndef __LIBXML_WIN32_CONFIG__
+#define __LIBXML_WIN32_CONFIG__
+
+#define HAVE_CTYPE_H
+#define HAVE_STDARG_H
+#define HAVE_MALLOC_H
+#define HAVE_ERRNO_H
+
+#if defined(_WIN32_WCE)
+#undef HAVE_ERRNO_H
+#include <windows.h>
+#include "wincecompat.h"
+#else
+#define HAVE_SYS_STAT_H
+#define HAVE__STAT
+#define HAVE_STAT
+#define HAVE_STDLIB_H
+#define HAVE_TIME_H
+#define HAVE_FCNTL_H
+#include <io.h>
+#include <direct.h>
+#endif
+
+#include <libxml/xmlversion.h>
+
+#ifndef ICONV_CONST
+#define ICONV_CONST const
+#endif
+
+#ifdef NEED_SOCKETS
+#include <wsockcompat.h>
+#endif
+
+/*
+ * Windows platforms may define except 
+ */
+#undef except
+
+#define HAVE_ISINF
+#define HAVE_ISNAN
+#include <math.h>
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+/* MS C-runtime has functions which can be used in order to determine if
+   a given floating-point variable contains NaN, (+-)INF. These are 
+   preferred, because floating-point technology is considered propriatary
+   by MS and we can assume that their functions know more about their 
+   oddities than we do. */
+#include <float.h>
+/* Bjorn Reese figured a quite nice construct for isinf() using the _fpclass
+   function. */
+#ifndef isinf
+#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
+	: ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
+#endif
+/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
+#ifndef isnan
+#define isnan(d) (_isnan(d))
+#endif
+#else /* _MSC_VER */
+#ifndef isinf
+static int isinf (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 1;
+        } else if (val == -0.5) {
+            return -1;
+        } else {
+            return 0;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#ifndef isnan
+static int isnan (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 0;
+        } else if (val == -0.5) {
+            return 0;
+        } else {
+            return 1;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#endif /* _MSC_VER */
+
+#if defined(_MSC_VER)
+#define mkdir(p,m) _mkdir(p)
+#if _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+#if _MSC_VER < 1500
+#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+#endif
+#elif defined(__MINGW32__)
+#define mkdir(p,m) _mkdir(p)
+#endif
+
+/* Threading API to use should be specified here for compatibility reasons.
+   This is however best specified on the compiler's command-line. */
+#if defined(LIBXML_THREAD_ENABLED)
+#if !defined(HAVE_PTHREAD_H) && !defined(HAVE_WIN32_THREADS) && !defined(_WIN32_WCE)
+#define HAVE_WIN32_THREADS
+#endif
+#endif
+
+/* Some third-party libraries far from our control assume the following
+   is defined, which it is not if we don't include windows.h. */
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!(FALSE))
+#endif
+
+#endif /* __LIBXML_WIN32_CONFIG__ */
+
diff --git a/src/include/wsockcompat.h b/src/include/wsockcompat.h
new file mode 100644
index 0000000..f4bdab4
--- /dev/null
+++ b/src/include/wsockcompat.h
@@ -0,0 +1,83 @@
+/* include/wsockcompat.h
+ * Windows -> Berkeley Sockets compatibility things.
+ */
+
+#if !defined __XML_WSOCKCOMPAT_H__
+#define __XML_WSOCKCOMPAT_H__
+
+#ifdef _WIN32_WCE
+#include <winsock.h>
+#else
+#undef HAVE_ERRNO_H
+#include <winsock2.h>
+
+/* the following is a workaround a problem for 'inline' keyword in said
+   header when compiled with Borland C++ 6 */
+#if defined(__BORLANDC__) && !defined(__cplusplus)
+#define inline __inline
+#define _inline __inline
+#endif
+
+#include <ws2tcpip.h>
+
+/* Check if ws2tcpip.h is a recent version which provides getaddrinfo() */
+#if defined(GetAddrInfo)
+#include <wspiapi.h>
+#define HAVE_GETADDRINFO
+#endif
+#endif
+
+#ifdef __MINGW32__
+/* Include <errno.h> here to ensure that it doesn't get included later
+ * (e.g. by iconv.h) and overwrites the definition of EWOULDBLOCK. */
+#include <errno.h>
+#undef EWOULDBLOCK
+#endif
+
+#if !defined SOCKLEN_T
+#define SOCKLEN_T int
+#endif
+
+#define EWOULDBLOCK             WSAEWOULDBLOCK
+#define EINPROGRESS             WSAEINPROGRESS
+#define EALREADY                WSAEALREADY
+#define ENOTSOCK                WSAENOTSOCK
+#define EDESTADDRREQ            WSAEDESTADDRREQ
+#define EMSGSIZE                WSAEMSGSIZE
+#define EPROTOTYPE              WSAEPROTOTYPE
+#define ENOPROTOOPT             WSAENOPROTOOPT
+#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP              WSAEOPNOTSUPP
+#define EPFNOSUPPORT            WSAEPFNOSUPPORT
+#define EAFNOSUPPORT            WSAEAFNOSUPPORT
+#define EADDRINUSE              WSAEADDRINUSE
+#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
+#define ENETDOWN                WSAENETDOWN
+#define ENETUNREACH             WSAENETUNREACH
+#define ENETRESET               WSAENETRESET
+#define ECONNABORTED            WSAECONNABORTED
+#define ECONNRESET              WSAECONNRESET
+#define ENOBUFS                 WSAENOBUFS
+#define EISCONN                 WSAEISCONN
+#define ENOTCONN                WSAENOTCONN
+#define ESHUTDOWN               WSAESHUTDOWN
+#define ETOOMANYREFS            WSAETOOMANYREFS
+#define ETIMEDOUT               WSAETIMEDOUT
+#define ECONNREFUSED            WSAECONNREFUSED
+#define ELOOP                   WSAELOOP
+#define EHOSTDOWN               WSAEHOSTDOWN
+#define EHOSTUNREACH            WSAEHOSTUNREACH
+#define EPROCLIM                WSAEPROCLIM
+#define EUSERS                  WSAEUSERS
+#define EDQUOT                  WSAEDQUOT
+#define ESTALE                  WSAESTALE
+#define EREMOTE                 WSAEREMOTE
+/* These cause conflicts with the codes from errno.h. Since they are 
+   not used in the relevant code (nanoftp, nanohttp), we can leave 
+   them disabled.
+#define ENAMETOOLONG            WSAENAMETOOLONG
+#define ENOTEMPTY               WSAENOTEMPTY
+*/
+
+#endif /* __XML_WSOCKCOMPAT_H__ */
diff --git a/src/install-sh b/src/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/src/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# 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
+# furnished 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,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium 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 the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/legacy.c b/src/legacy.c
new file mode 100644
index 0000000..e75178a
--- /dev/null
+++ b/src/legacy.c
@@ -0,0 +1,1343 @@
+/*
+ * legacy.c: set of deprecated routines, not to be used anymore but
+ *           kept purely for ABI compatibility
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_LEGACY_ENABLED
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/entities.h>
+#include <libxml/SAX.h>
+#include <libxml/parserInternals.h>
+#include <libxml/HTMLparser.h>
+
+void xmlUpgradeOldNs(xmlDocPtr doc);
+
+/************************************************************************
+ *									*
+ *		Deprecated functions kept for compatibility		*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_HTML_ENABLED
+xmlChar *htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len, xmlChar end,
+                            xmlChar end2, xmlChar end3);
+
+/**
+ * htmlDecodeEntities:
+ * @ctxt:  the parser context
+ * @len:  the len to decode (in bytes !), -1 for no size limit
+ * @end:  an end marker xmlChar, 0 if none
+ * @end2:  an end marker xmlChar, 0 if none
+ * @end3:  an end marker xmlChar, 0 if none
+ *
+ * Substitute the HTML entities by their value
+ *
+ * DEPRECATED !!!!
+ *
+ * Returns A newly allocated string with the substitution done. The caller
+ *      must deallocate it !
+ */
+xmlChar *
+htmlDecodeEntities(htmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                   int len ATTRIBUTE_UNUSED, xmlChar end ATTRIBUTE_UNUSED,
+                   xmlChar end2 ATTRIBUTE_UNUSED,
+                   xmlChar end3 ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "htmlDecodeEntities() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+#endif
+
+/**
+ * xmlInitializePredefinedEntities:
+ *
+ * Set up the predefined entities.
+ * Deprecated call
+ */
+void
+xmlInitializePredefinedEntities(void)
+{
+}
+
+/**
+ * xmlCleanupPredefinedEntities:
+ *
+ * Cleanup up the predefined entities table.
+ * Deprecated call
+ */
+void
+xmlCleanupPredefinedEntities(void)
+{
+}
+
+static const char *xmlFeaturesList[] = {
+    "validate",
+    "load subset",
+    "keep blanks",
+    "disable SAX",
+    "fetch external entities",
+    "substitute entities",
+    "gather line info",
+    "user data",
+    "is html",
+    "is standalone",
+    "stop parser",
+    "document",
+    "is well formed",
+    "is valid",
+    "SAX block",
+    "SAX function internalSubset",
+    "SAX function isStandalone",
+    "SAX function hasInternalSubset",
+    "SAX function hasExternalSubset",
+    "SAX function resolveEntity",
+    "SAX function getEntity",
+    "SAX function entityDecl",
+    "SAX function notationDecl",
+    "SAX function attributeDecl",
+    "SAX function elementDecl",
+    "SAX function unparsedEntityDecl",
+    "SAX function setDocumentLocator",
+    "SAX function startDocument",
+    "SAX function endDocument",
+    "SAX function startElement",
+    "SAX function endElement",
+    "SAX function reference",
+    "SAX function characters",
+    "SAX function ignorableWhitespace",
+    "SAX function processingInstruction",
+    "SAX function comment",
+    "SAX function warning",
+    "SAX function error",
+    "SAX function fatalError",
+    "SAX function getParameterEntity",
+    "SAX function cdataBlock",
+    "SAX function externalSubset",
+};
+
+/**
+ * xmlGetFeaturesList:
+ * @len:  the length of the features name array (input/output)
+ * @result:  an array of string to be filled with the features name.
+ *
+ * Copy at most *@len feature names into the @result array
+ *
+ * Returns -1 in case or error, or the total number of features,
+ *            len is updated with the number of strings copied,
+ *            strings must not be deallocated
+ */
+int
+xmlGetFeaturesList(int *len, const char **result)
+{
+    int ret, i;
+
+    ret = sizeof(xmlFeaturesList) / sizeof(xmlFeaturesList[0]);
+    if ((len == NULL) || (result == NULL))
+        return (ret);
+    if ((*len < 0) || (*len >= 1000))
+        return (-1);
+    if (*len > ret)
+        *len = ret;
+    for (i = 0; i < *len; i++)
+        result[i] = xmlFeaturesList[i];
+    return (ret);
+}
+
+/**
+ * xmlGetFeature:
+ * @ctxt:  an XML/HTML parser context
+ * @name:  the feature name
+ * @result:  location to store the result
+ *
+ * Read the current value of one feature of this parser instance
+ *
+ * Returns -1 in case or error, 0 otherwise
+ */
+int
+xmlGetFeature(xmlParserCtxtPtr ctxt, const char *name, void *result)
+{
+    if ((ctxt == NULL) || (name == NULL) || (result == NULL))
+        return (-1);
+
+    if (!strcmp(name, "validate")) {
+        *((int *) result) = ctxt->validate;
+    } else if (!strcmp(name, "keep blanks")) {
+        *((int *) result) = ctxt->keepBlanks;
+    } else if (!strcmp(name, "disable SAX")) {
+        *((int *) result) = ctxt->disableSAX;
+    } else if (!strcmp(name, "fetch external entities")) {
+        *((int *) result) = ctxt->loadsubset;
+    } else if (!strcmp(name, "substitute entities")) {
+        *((int *) result) = ctxt->replaceEntities;
+    } else if (!strcmp(name, "gather line info")) {
+        *((int *) result) = ctxt->record_info;
+    } else if (!strcmp(name, "user data")) {
+        *((void **) result) = ctxt->userData;
+    } else if (!strcmp(name, "is html")) {
+        *((int *) result) = ctxt->html;
+    } else if (!strcmp(name, "is standalone")) {
+        *((int *) result) = ctxt->standalone;
+    } else if (!strcmp(name, "document")) {
+        *((xmlDocPtr *) result) = ctxt->myDoc;
+    } else if (!strcmp(name, "is well formed")) {
+        *((int *) result) = ctxt->wellFormed;
+    } else if (!strcmp(name, "is valid")) {
+        *((int *) result) = ctxt->valid;
+    } else if (!strcmp(name, "SAX block")) {
+        *((xmlSAXHandlerPtr *) result) = ctxt->sax;
+    } else if (!strcmp(name, "SAX function internalSubset")) {
+        *((internalSubsetSAXFunc *) result) = ctxt->sax->internalSubset;
+    } else if (!strcmp(name, "SAX function isStandalone")) {
+        *((isStandaloneSAXFunc *) result) = ctxt->sax->isStandalone;
+    } else if (!strcmp(name, "SAX function hasInternalSubset")) {
+        *((hasInternalSubsetSAXFunc *) result) =
+            ctxt->sax->hasInternalSubset;
+    } else if (!strcmp(name, "SAX function hasExternalSubset")) {
+        *((hasExternalSubsetSAXFunc *) result) =
+            ctxt->sax->hasExternalSubset;
+    } else if (!strcmp(name, "SAX function resolveEntity")) {
+        *((resolveEntitySAXFunc *) result) = ctxt->sax->resolveEntity;
+    } else if (!strcmp(name, "SAX function getEntity")) {
+        *((getEntitySAXFunc *) result) = ctxt->sax->getEntity;
+    } else if (!strcmp(name, "SAX function entityDecl")) {
+        *((entityDeclSAXFunc *) result) = ctxt->sax->entityDecl;
+    } else if (!strcmp(name, "SAX function notationDecl")) {
+        *((notationDeclSAXFunc *) result) = ctxt->sax->notationDecl;
+    } else if (!strcmp(name, "SAX function attributeDecl")) {
+        *((attributeDeclSAXFunc *) result) = ctxt->sax->attributeDecl;
+    } else if (!strcmp(name, "SAX function elementDecl")) {
+        *((elementDeclSAXFunc *) result) = ctxt->sax->elementDecl;
+    } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
+        *((unparsedEntityDeclSAXFunc *) result) =
+            ctxt->sax->unparsedEntityDecl;
+    } else if (!strcmp(name, "SAX function setDocumentLocator")) {
+        *((setDocumentLocatorSAXFunc *) result) =
+            ctxt->sax->setDocumentLocator;
+    } else if (!strcmp(name, "SAX function startDocument")) {
+        *((startDocumentSAXFunc *) result) = ctxt->sax->startDocument;
+    } else if (!strcmp(name, "SAX function endDocument")) {
+        *((endDocumentSAXFunc *) result) = ctxt->sax->endDocument;
+    } else if (!strcmp(name, "SAX function startElement")) {
+        *((startElementSAXFunc *) result) = ctxt->sax->startElement;
+    } else if (!strcmp(name, "SAX function endElement")) {
+        *((endElementSAXFunc *) result) = ctxt->sax->endElement;
+    } else if (!strcmp(name, "SAX function reference")) {
+        *((referenceSAXFunc *) result) = ctxt->sax->reference;
+    } else if (!strcmp(name, "SAX function characters")) {
+        *((charactersSAXFunc *) result) = ctxt->sax->characters;
+    } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
+        *((ignorableWhitespaceSAXFunc *) result) =
+            ctxt->sax->ignorableWhitespace;
+    } else if (!strcmp(name, "SAX function processingInstruction")) {
+        *((processingInstructionSAXFunc *) result) =
+            ctxt->sax->processingInstruction;
+    } else if (!strcmp(name, "SAX function comment")) {
+        *((commentSAXFunc *) result) = ctxt->sax->comment;
+    } else if (!strcmp(name, "SAX function warning")) {
+        *((warningSAXFunc *) result) = ctxt->sax->warning;
+    } else if (!strcmp(name, "SAX function error")) {
+        *((errorSAXFunc *) result) = ctxt->sax->error;
+    } else if (!strcmp(name, "SAX function fatalError")) {
+        *((fatalErrorSAXFunc *) result) = ctxt->sax->fatalError;
+    } else if (!strcmp(name, "SAX function getParameterEntity")) {
+        *((getParameterEntitySAXFunc *) result) =
+            ctxt->sax->getParameterEntity;
+    } else if (!strcmp(name, "SAX function cdataBlock")) {
+        *((cdataBlockSAXFunc *) result) = ctxt->sax->cdataBlock;
+    } else if (!strcmp(name, "SAX function externalSubset")) {
+        *((externalSubsetSAXFunc *) result) = ctxt->sax->externalSubset;
+    } else {
+        return (-1);
+    }
+    return (0);
+}
+
+/**
+ * xmlSetFeature:
+ * @ctxt:  an XML/HTML parser context
+ * @name:  the feature name
+ * @value:  pointer to the location of the new value
+ *
+ * Change the current value of one feature of this parser instance
+ *
+ * Returns -1 in case or error, 0 otherwise
+ */
+int
+xmlSetFeature(xmlParserCtxtPtr ctxt, const char *name, void *value)
+{
+    if ((ctxt == NULL) || (name == NULL) || (value == NULL))
+        return (-1);
+
+    if (!strcmp(name, "validate")) {
+        int newvalidate = *((int *) value);
+
+        if ((!ctxt->validate) && (newvalidate != 0)) {
+            if (ctxt->vctxt.warning == NULL)
+                ctxt->vctxt.warning = xmlParserValidityWarning;
+            if (ctxt->vctxt.error == NULL)
+                ctxt->vctxt.error = xmlParserValidityError;
+            ctxt->vctxt.nodeMax = 0;
+        }
+        ctxt->validate = newvalidate;
+    } else if (!strcmp(name, "keep blanks")) {
+        ctxt->keepBlanks = *((int *) value);
+    } else if (!strcmp(name, "disable SAX")) {
+        ctxt->disableSAX = *((int *) value);
+    } else if (!strcmp(name, "fetch external entities")) {
+        ctxt->loadsubset = *((int *) value);
+    } else if (!strcmp(name, "substitute entities")) {
+        ctxt->replaceEntities = *((int *) value);
+    } else if (!strcmp(name, "gather line info")) {
+        ctxt->record_info = *((int *) value);
+    } else if (!strcmp(name, "user data")) {
+        ctxt->userData = *((void **) value);
+    } else if (!strcmp(name, "is html")) {
+        ctxt->html = *((int *) value);
+    } else if (!strcmp(name, "is standalone")) {
+        ctxt->standalone = *((int *) value);
+    } else if (!strcmp(name, "document")) {
+        ctxt->myDoc = *((xmlDocPtr *) value);
+    } else if (!strcmp(name, "is well formed")) {
+        ctxt->wellFormed = *((int *) value);
+    } else if (!strcmp(name, "is valid")) {
+        ctxt->valid = *((int *) value);
+    } else if (!strcmp(name, "SAX block")) {
+        ctxt->sax = *((xmlSAXHandlerPtr *) value);
+    } else if (!strcmp(name, "SAX function internalSubset")) {
+        ctxt->sax->internalSubset = *((internalSubsetSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function isStandalone")) {
+        ctxt->sax->isStandalone = *((isStandaloneSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function hasInternalSubset")) {
+        ctxt->sax->hasInternalSubset =
+            *((hasInternalSubsetSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function hasExternalSubset")) {
+        ctxt->sax->hasExternalSubset =
+            *((hasExternalSubsetSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function resolveEntity")) {
+        ctxt->sax->resolveEntity = *((resolveEntitySAXFunc *) value);
+    } else if (!strcmp(name, "SAX function getEntity")) {
+        ctxt->sax->getEntity = *((getEntitySAXFunc *) value);
+    } else if (!strcmp(name, "SAX function entityDecl")) {
+        ctxt->sax->entityDecl = *((entityDeclSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function notationDecl")) {
+        ctxt->sax->notationDecl = *((notationDeclSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function attributeDecl")) {
+        ctxt->sax->attributeDecl = *((attributeDeclSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function elementDecl")) {
+        ctxt->sax->elementDecl = *((elementDeclSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
+        ctxt->sax->unparsedEntityDecl =
+            *((unparsedEntityDeclSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function setDocumentLocator")) {
+        ctxt->sax->setDocumentLocator =
+            *((setDocumentLocatorSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function startDocument")) {
+        ctxt->sax->startDocument = *((startDocumentSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function endDocument")) {
+        ctxt->sax->endDocument = *((endDocumentSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function startElement")) {
+        ctxt->sax->startElement = *((startElementSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function endElement")) {
+        ctxt->sax->endElement = *((endElementSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function reference")) {
+        ctxt->sax->reference = *((referenceSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function characters")) {
+        ctxt->sax->characters = *((charactersSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
+        ctxt->sax->ignorableWhitespace =
+            *((ignorableWhitespaceSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function processingInstruction")) {
+        ctxt->sax->processingInstruction =
+            *((processingInstructionSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function comment")) {
+        ctxt->sax->comment = *((commentSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function warning")) {
+        ctxt->sax->warning = *((warningSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function error")) {
+        ctxt->sax->error = *((errorSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function fatalError")) {
+        ctxt->sax->fatalError = *((fatalErrorSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function getParameterEntity")) {
+        ctxt->sax->getParameterEntity =
+            *((getParameterEntitySAXFunc *) value);
+    } else if (!strcmp(name, "SAX function cdataBlock")) {
+        ctxt->sax->cdataBlock = *((cdataBlockSAXFunc *) value);
+    } else if (!strcmp(name, "SAX function externalSubset")) {
+        ctxt->sax->externalSubset = *((externalSubsetSAXFunc *) value);
+    } else {
+        return (-1);
+    }
+    return (0);
+}
+
+/**
+ * xmlDecodeEntities:
+ * @ctxt:  the parser context
+ * @len:  the len to decode (in bytes !), -1 for no size limit
+ * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
+ * @end:  an end marker xmlChar, 0 if none
+ * @end2:  an end marker xmlChar, 0 if none
+ * @end3:  an end marker xmlChar, 0 if none
+ * 
+ * This function is deprecated, we now always process entities content
+ * through xmlStringDecodeEntities
+ *
+ * TODO: remove it in next major release.
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ *
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * Returns A newly allocated string with the substitution done. The caller
+ *      must deallocate it !
+ */
+xmlChar *
+xmlDecodeEntities(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                  int len ATTRIBUTE_UNUSED, int what ATTRIBUTE_UNUSED,
+                  xmlChar end ATTRIBUTE_UNUSED,
+                  xmlChar end2 ATTRIBUTE_UNUSED,
+                  xmlChar end3 ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlDecodeEntities() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlNamespaceParseNCName:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML namespace name.
+ *
+ * TODO: this seems not in use anymore, the namespace handling is done on
+ *       top of the SAX interfaces, i.e. not on raw input.
+ *
+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
+ *
+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
+ *                       CombiningChar | Extender
+ *
+ * Returns the namespace name or NULL
+ */
+
+xmlChar *
+xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNamespaceParseNCName() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlNamespaceParseQName:
+ * @ctxt:  an XML parser context
+ * @prefix:  a xmlChar ** 
+ *
+ * TODO: this seems not in use anymore, the namespace handling is done on
+ *       top of the SAX interfaces, i.e. not on raw input.
+ *
+ * parse an XML qualified name
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns the local part, and prefix is updated
+ *   to get the Prefix if any.
+ */
+
+xmlChar *
+xmlNamespaceParseQName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                       xmlChar ** prefix ATTRIBUTE_UNUSED)
+{
+
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNamespaceParseQName() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlNamespaceParseNSDef:
+ * @ctxt:  an XML parser context
+ *
+ * parse a namespace prefix declaration
+ *
+ * TODO: this seems not in use anymore, the namespace handling is done on
+ *       top of the SAX interfaces, i.e. not on raw input.
+ *
+ * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
+ *
+ * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
+ *
+ * Returns the namespace name
+ */
+
+xmlChar *
+xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNamespaceParseNSDef() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlParseQuotedString:
+ * @ctxt:  an XML parser context
+ *
+ * Parse and return a string between quotes or doublequotes
+ *
+ * TODO: Deprecated, to  be removed at next drop of binary compatibility
+ *
+ * Returns the string parser or NULL.
+ */
+xmlChar *
+xmlParseQuotedString(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlParseQuotedString() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlParseNamespace:
+ * @ctxt:  an XML parser context
+ *
+ * xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
+ *
+ * This is what the older xml-name Working Draft specified, a bunch of
+ * other stuff may still rely on it, so support is still here as
+ * if it was declared on the root of the Tree:-(
+ *
+ * TODO: remove from library
+ *
+ * To be removed at next drop of binary compatibility
+ */
+
+void
+xmlParseNamespace(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlParseNamespace() deprecated function reached\n");
+        deprecated = 1;
+    }
+}
+
+/**
+ * xmlScanName:
+ * @ctxt:  an XML parser context
+ *
+ * Trickery: parse an XML name but without consuming the input flow
+ * Needed for rollback cases. Used only when parsing entities references.
+ *
+ * TODO: seems deprecated now, only used in the default part of
+ *       xmlParserHandleReference
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (S Name)*
+ *
+ * Returns the Name parsed or NULL
+ */
+
+xmlChar *
+xmlScanName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlScanName() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlParserHandleReference:
+ * @ctxt:  the parser context
+ * 
+ * TODO: Remove, now deprecated ... the test is done directly in the
+ *       content parsing
+ * routines.
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ *
+ * [ WFC: Entity Declared ]
+ * the Name given in the entity reference must match that in an entity
+ * declaration, except that well-formed documents need not declare any
+ * of the following entities: amp, lt, gt, apos, quot. 
+ *
+ * [ WFC: Parsed Entity ]
+ * An entity reference must not contain the name of an unparsed entity
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ *                  '&#x' [0-9a-fA-F]+ ';'
+ *
+ * A PEReference may have been detected in the current input stream
+ * the handling is done accordingly to 
+ *      http://www.w3.org/TR/REC-xml#entproc
+ */
+void
+xmlParserHandleReference(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlParserHandleReference() deprecated function reached\n");
+        deprecated = 1;
+    }
+
+    return;
+}
+
+/**
+ * xmlHandleEntity:
+ * @ctxt:  an XML parser context
+ * @entity:  an XML entity pointer.
+ *
+ * Default handling of defined entities, when should we define a new input
+ * stream ? When do we just handle that as a set of chars ?
+ *
+ * OBSOLETE: to be removed at some point.
+ */
+
+void
+xmlHandleEntity(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                xmlEntityPtr entity ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlHandleEntity() deprecated function reached\n");
+        deprecated = 1;
+    }
+}
+
+/**
+ * xmlNewGlobalNs:
+ * @doc:  the document carrying the namespace
+ * @href:  the URI associated
+ * @prefix:  the prefix for the namespace
+ *
+ * Creation of a Namespace, the old way using PI and without scoping
+ *   DEPRECATED !!!
+ * Returns NULL this functionality had been removed
+ */
+xmlNsPtr
+xmlNewGlobalNs(xmlDocPtr doc ATTRIBUTE_UNUSED,
+               const xmlChar * href ATTRIBUTE_UNUSED,
+               const xmlChar * prefix ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNewGlobalNs() deprecated function reached\n");
+        deprecated = 1;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlUpgradeOldNs:
+ * @doc:  a document pointer
+ * 
+ * Upgrade old style Namespaces (PI) and move them to the root of the document.
+ * DEPRECATED
+ */
+void
+xmlUpgradeOldNs(xmlDocPtr doc ATTRIBUTE_UNUSED)
+{
+    static int deprecated = 0;
+
+    if (!deprecated) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlUpgradeOldNs() deprecated function reached\n");
+        deprecated = 1;
+    }
+}
+
+/**
+ * xmlEncodeEntities:
+ * @doc:  the document containing the string
+ * @input:  A string to convert to XML.
+ *
+ * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
+ *       compatibility
+ *
+ * People must migrate their code to xmlEncodeEntitiesReentrant !
+ * This routine will issue a warning when encountered.
+ * 
+ * Returns NULL
+ */
+const xmlChar *
+xmlEncodeEntities(xmlDocPtr doc ATTRIBUTE_UNUSED,
+                  const xmlChar * input ATTRIBUTE_UNUSED)
+{
+    static int warning = 1;
+
+    if (warning) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Deprecated API xmlEncodeEntities() used\n");
+        xmlGenericError(xmlGenericErrorContext,
+                        "   change code to use xmlEncodeEntitiesReentrant()\n");
+        warning = 0;
+    }
+    return (NULL);
+}
+
+/************************************************************************
+ *									*
+ *		Old set of SAXv1 functions 				*
+ *									*
+ ************************************************************************/
+static int deprecated_v1_msg = 0;
+
+#define DEPRECATED(n)						\
+    if (deprecated_v1_msg == 0)					\
+	xmlGenericError(xmlGenericErrorContext,			\
+	  "Use of deprecated SAXv1 function %s\n", n);		\
+    deprecated_v1_msg++;
+
+/**
+ * getPublicId:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
+ * DEPRECATED: use xmlSAX2GetPublicId()
+ *
+ * Returns a xmlChar *
+ */
+const xmlChar *
+getPublicId(void *ctx)
+{
+    DEPRECATED("getPublicId")
+        return (xmlSAX2GetPublicId(ctx));
+}
+
+/**
+ * getSystemId:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provides the system ID, basically URL or filename e.g.
+ * http://www.sgmlsource.com/dtds/memo.dtd
+ * DEPRECATED: use xmlSAX2GetSystemId()
+ *
+ * Returns a xmlChar *
+ */
+const xmlChar *
+getSystemId(void *ctx)
+{
+    DEPRECATED("getSystemId")
+        return (xmlSAX2GetSystemId(ctx));
+}
+
+/**
+ * getLineNumber:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provide the line number of the current parsing point.
+ * DEPRECATED: use xmlSAX2GetLineNumber()
+ *
+ * Returns an int
+ */
+int
+getLineNumber(void *ctx)
+{
+    DEPRECATED("getLineNumber")
+        return (xmlSAX2GetLineNumber(ctx));
+}
+
+/**
+ * getColumnNumber:
+ * @ctx: the user data (XML parser context)
+ *
+ * Provide the column number of the current parsing point.
+ * DEPRECATED: use xmlSAX2GetColumnNumber()
+ *
+ * Returns an int
+ */
+int
+getColumnNumber(void *ctx)
+{
+    DEPRECATED("getColumnNumber")
+        return (xmlSAX2GetColumnNumber(ctx));
+}
+
+/**
+ * isStandalone:
+ * @ctx: the user data (XML parser context)
+ *
+ * Is this document tagged standalone ?
+ * DEPRECATED: use xmlSAX2IsStandalone()
+ *
+ * Returns 1 if true
+ */
+int
+isStandalone(void *ctx)
+{
+    DEPRECATED("isStandalone")
+        return (xmlSAX2IsStandalone(ctx));
+}
+
+/**
+ * hasInternalSubset:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an internal subset
+ * DEPRECATED: use xmlSAX2HasInternalSubset()
+ *
+ * Returns 1 if true
+ */
+int
+hasInternalSubset(void *ctx)
+{
+    DEPRECATED("hasInternalSubset")
+        return (xmlSAX2HasInternalSubset(ctx));
+}
+
+/**
+ * hasExternalSubset:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an external subset
+ * DEPRECATED: use xmlSAX2HasExternalSubset()
+ *
+ * Returns 1 if true
+ */
+int
+hasExternalSubset(void *ctx)
+{
+    DEPRECATED("hasExternalSubset")
+        return (xmlSAX2HasExternalSubset(ctx));
+}
+
+/**
+ * internalSubset:
+ * @ctx:  the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on internal subset declaration.
+ * DEPRECATED: use xmlSAX2InternalSubset()
+ */
+void
+internalSubset(void *ctx, const xmlChar * name,
+               const xmlChar * ExternalID, const xmlChar * SystemID)
+{
+    DEPRECATED("internalSubset")
+        xmlSAX2InternalSubset(ctx, name, ExternalID, SystemID);
+}
+
+/**
+ * externalSubset:
+ * @ctx: the user data (XML parser context)
+ * @name:  the root element name
+ * @ExternalID:  the external ID
+ * @SystemID:  the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on external subset declaration.
+ * DEPRECATED: use xmlSAX2ExternalSubset()
+ */
+void
+externalSubset(void *ctx, const xmlChar * name,
+               const xmlChar * ExternalID, const xmlChar * SystemID)
+{
+    DEPRECATED("externalSubset")
+        xmlSAX2ExternalSubset(ctx, name, ExternalID, SystemID);
+}
+
+/**
+ * resolveEntity:
+ * @ctx: the user data (XML parser context)
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * The entity loader, to control the loading of external entities,
+ * the application can either:
+ *    - override this resolveEntity() callback in the SAX block
+ *    - or better use the xmlSetExternalEntityLoader() function to
+ *      set up it's own entity resolution routine
+ * DEPRECATED: use xmlSAX2ResolveEntity()
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+xmlParserInputPtr
+resolveEntity(void *ctx, const xmlChar * publicId,
+              const xmlChar * systemId)
+{
+    DEPRECATED("resolveEntity")
+        return (xmlSAX2ResolveEntity(ctx, publicId, systemId));
+}
+
+/**
+ * getEntity:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get an entity by name
+ * DEPRECATED: use xmlSAX2GetEntity()
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+xmlEntityPtr
+getEntity(void *ctx, const xmlChar * name)
+{
+    DEPRECATED("getEntity")
+        return (xmlSAX2GetEntity(ctx, name));
+}
+
+/**
+ * getParameterEntity:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ * DEPRECATED: use xmlSAX2GetParameterEntity()
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+xmlEntityPtr
+getParameterEntity(void *ctx, const xmlChar * name)
+{
+    DEPRECATED("getParameterEntity")
+        return (xmlSAX2GetParameterEntity(ctx, name));
+}
+
+
+/**
+ * entityDecl:
+ * @ctx: the user data (XML parser context)
+ * @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).
+ *
+ * An entity definition has been parsed
+ * DEPRECATED: use xmlSAX2EntityDecl()
+ */
+void
+entityDecl(void *ctx, const xmlChar * name, int type,
+           const xmlChar * publicId, const xmlChar * systemId,
+           xmlChar * content)
+{
+    DEPRECATED("entityDecl")
+        xmlSAX2EntityDecl(ctx, name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDecl:
+ * @ctx: the user data (XML parser context)
+ * @elem:  the name of the element
+ * @fullname:  the attribute name 
+ * @type:  the attribute type 
+ * @def:  the type of default value
+ * @defaultValue: the attribute default value
+ * @tree:  the tree of enumerated value set
+ *
+ * An attribute definition has been parsed
+ * DEPRECATED: use xmlSAX2AttributeDecl()
+ */
+void
+attributeDecl(void *ctx, const xmlChar * elem, const xmlChar * fullname,
+              int type, int def, const xmlChar * defaultValue,
+              xmlEnumerationPtr tree)
+{
+    DEPRECATED("attributeDecl")
+        xmlSAX2AttributeDecl(ctx, elem, fullname, type, def, defaultValue,
+                             tree);
+}
+
+/**
+ * elementDecl:
+ * @ctx: the user data (XML parser context)
+ * @name:  the element name 
+ * @type:  the element type 
+ * @content: the element value tree
+ *
+ * An element definition has been parsed
+ * DEPRECATED: use xmlSAX2ElementDecl()
+ */
+void
+elementDecl(void *ctx, const xmlChar * name, int type,
+            xmlElementContentPtr content)
+{
+    DEPRECATED("elementDecl")
+        xmlSAX2ElementDecl(ctx, name, type, content);
+}
+
+/**
+ * notationDecl:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ * DEPRECATED: use xmlSAX2NotationDecl()
+ */
+void
+notationDecl(void *ctx, const xmlChar * name,
+             const xmlChar * publicId, const xmlChar * systemId)
+{
+    DEPRECATED("notationDecl")
+        xmlSAX2NotationDecl(ctx, name, publicId, systemId);
+}
+
+/**
+ * unparsedEntityDecl:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ * DEPRECATED: use xmlSAX2UnparsedEntityDecl()
+ */
+void
+unparsedEntityDecl(void *ctx, const xmlChar * name,
+                   const xmlChar * publicId, const xmlChar * systemId,
+                   const xmlChar * notationName)
+{
+    DEPRECATED("unparsedEntityDecl")
+        xmlSAX2UnparsedEntityDecl(ctx, name, publicId, systemId,
+                                  notationName);
+}
+
+/**
+ * setDocumentLocator:
+ * @ctx: the user data (XML parser context)
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ * DEPRECATED
+ */
+void
+setDocumentLocator(void *ctx ATTRIBUTE_UNUSED,
+                   xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("setDocumentLocator")
+}
+
+/**
+ * startDocument:
+ * @ctx: the user data (XML parser context)
+ *
+ * called when the document start being processed.
+ * DEPRECATED: use xmlSAX2StartDocument()
+ */
+void
+startDocument(void *ctx)
+{
+   /* don't be too painful for glade users */
+   /*  DEPRECATED("startDocument") */
+        xmlSAX2StartDocument(ctx);
+}
+
+/**
+ * endDocument:
+ * @ctx: the user data (XML parser context)
+ *
+ * called when the document end has been detected.
+ * DEPRECATED: use xmlSAX2EndDocument()
+ */
+void
+endDocument(void *ctx)
+{
+    DEPRECATED("endDocument")
+        xmlSAX2EndDocument(ctx);
+}
+
+/**
+ * attribute:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The attribute name, including namespace prefix
+ * @value:  The attribute value
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ * DEPRECATED: use xmlSAX2Attribute()
+ */
+void
+attribute(void *ctx ATTRIBUTE_UNUSED,
+          const xmlChar * fullname ATTRIBUTE_UNUSED,
+          const xmlChar * value ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("attribute")
+}
+
+/**
+ * startElement:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The element name, including namespace prefix
+ * @atts:  An array of name/value attributes pairs, NULL terminated
+ *
+ * called when an opening tag has been processed.
+ * DEPRECATED: use xmlSAX2StartElement()
+ */
+void
+startElement(void *ctx, const xmlChar * fullname, const xmlChar ** atts)
+{
+    xmlSAX2StartElement(ctx, fullname, atts);
+}
+
+/**
+ * endElement:
+ * @ctx: the user data (XML parser context)
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ * DEPRECATED: use xmlSAX2EndElement()
+ */
+void
+endElement(void *ctx, const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("endElement")
+        xmlSAX2EndElement(ctx, name);
+}
+
+/**
+ * reference:
+ * @ctx: the user data (XML parser context)
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected. 
+ * DEPRECATED: use xmlSAX2Reference()
+ */
+void
+reference(void *ctx, const xmlChar * name)
+{
+    DEPRECATED("reference")
+        xmlSAX2Reference(ctx, name);
+}
+
+/**
+ * characters:
+ * @ctx: the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * DEPRECATED: use xmlSAX2Characters()
+ */
+void
+characters(void *ctx, const xmlChar * ch, int len)
+{
+    DEPRECATED("characters")
+        xmlSAX2Characters(ctx, ch, len);
+}
+
+/**
+ * ignorableWhitespace:
+ * @ctx: the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * UNUSED: by default the DOM building will use characters
+ * DEPRECATED: use xmlSAX2IgnorableWhitespace()
+ */
+void
+ignorableWhitespace(void *ctx ATTRIBUTE_UNUSED,
+                    const xmlChar * ch ATTRIBUTE_UNUSED,
+                    int len ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("ignorableWhitespace")
+}
+
+/**
+ * processingInstruction:
+ * @ctx: the user data (XML parser context)
+ * @target:  the target name
+ * @data: the PI data's
+ *
+ * A processing instruction has been parsed.
+ * DEPRECATED: use xmlSAX2ProcessingInstruction()
+ */
+void
+processingInstruction(void *ctx, const xmlChar * target,
+                      const xmlChar * data)
+{
+    DEPRECATED("processingInstruction")
+        xmlSAX2ProcessingInstruction(ctx, target, data);
+}
+
+/**
+ * globalNamespace:
+ * @ctx: the user data (XML parser context)
+ * @href:  the namespace associated URN
+ * @prefix: the namespace prefix
+ *
+ * An old global namespace has been parsed.
+ * DEPRECATED
+ */
+void
+globalNamespace(void *ctx ATTRIBUTE_UNUSED,
+                const xmlChar * href ATTRIBUTE_UNUSED,
+                const xmlChar * prefix ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("globalNamespace")
+}
+
+/**
+ * setNamespace:
+ * @ctx: the user data (XML parser context)
+ * @name:  the namespace prefix
+ *
+ * Set the current element namespace.
+ * DEPRECATED
+ */
+
+void
+setNamespace(void *ctx ATTRIBUTE_UNUSED,
+             const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("setNamespace")
+}
+
+/**
+ * getNamespace:
+ * @ctx: the user data (XML parser context)
+ *
+ * Get the current element namespace.
+ * DEPRECATED
+ *
+ * Returns the xmlNsPtr or NULL if none
+ */
+
+xmlNsPtr
+getNamespace(void *ctx ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("getNamespace")
+        return (NULL);
+}
+
+/**
+ * checkNamespace:
+ * @ctx: the user data (XML parser context)
+ * @namespace: the namespace to check against
+ *
+ * Check that the current element namespace is the same as the
+ * one read upon parsing.
+ * DEPRECATED
+ *
+ * Returns 1 if true 0 otherwise
+ */
+
+int
+checkNamespace(void *ctx ATTRIBUTE_UNUSED,
+               xmlChar * namespace ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("checkNamespace")
+        return (0);
+}
+
+/**
+ * namespaceDecl:
+ * @ctx: the user data (XML parser context)
+ * @href:  the namespace associated URN
+ * @prefix: the namespace prefix
+ *
+ * A namespace has been parsed.
+ * DEPRECATED
+ */
+void
+namespaceDecl(void *ctx ATTRIBUTE_UNUSED,
+              const xmlChar * href ATTRIBUTE_UNUSED,
+              const xmlChar * prefix ATTRIBUTE_UNUSED)
+{
+    DEPRECATED("namespaceDecl")
+}
+
+/**
+ * comment:
+ * @ctx: the user data (XML parser context)
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ * DEPRECATED: use xmlSAX2Comment()
+ */
+void
+comment(void *ctx, const xmlChar * value)
+{
+    DEPRECATED("comment")
+        xmlSAX2Comment(ctx, value);
+}
+
+/**
+ * cdataBlock:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ * DEPRECATED: use xmlSAX2CDataBlock()
+ */
+void
+cdataBlock(void *ctx, const xmlChar * value, int len)
+{
+    DEPRECATED("cdataBlock")
+        xmlSAX2CDataBlock(ctx, value, len);
+}
+#define bottom_legacy
+#include "elfgcchack.h"
+#endif /* LIBXML_LEGACY_ENABLED */
+
diff --git a/src/libxml-2.0-uninstalled.pc.in b/src/libxml-2.0-uninstalled.pc.in
new file mode 100644
index 0000000..0a4c833
--- /dev/null
+++ b/src/libxml-2.0-uninstalled.pc.in
@@ -0,0 +1,12 @@
+prefix=
+exec_prefix=
+libdir=${pcfiledir}
+includedir=${pcfiledir}/include
+
+
+Name: libXML
+Version: @VERSION@
+Description: libXML library version2.
+Requires:
+Libs: -L${libdir} -lxml2 @THREAD_LIBS@ @Z_LIBS@ @ICONV_LIBS@ @M_LIBS@ @LIBS@
+Cflags: -I${includedir} @XML_INCLUDEDIR@ @XML_CFLAGS@
diff --git a/src/libxml-2.0.pc.in b/src/libxml-2.0.pc.in
new file mode 100644
index 0000000..31a1b8c
--- /dev/null
+++ b/src/libxml-2.0.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+modules=@WITH_MODULES@
+
+Name: libXML
+Version: @VERSION@
+Description: libXML library version2.
+Requires:
+Libs: -L${libdir} -lxml2
+Libs.private: @THREAD_LIBS@ @Z_LIBS@ @ICONV_LIBS@ @M_LIBS@ @WIN32_EXTRA_LIBADD@ @LIBS@
+Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
diff --git a/src/libxml.h b/src/libxml.h
new file mode 100644
index 0000000..f8a368c
--- /dev/null
+++ b/src/libxml.h
@@ -0,0 +1,99 @@
+/*
+ * libxml.h: internal header only used during the compilation of libxml
+ *
+ * See COPYRIGHT for the status of this software
+ *
+ * Author: breese@users.sourceforge.net
+ */
+
+#ifndef __XML_LIBXML_H__
+#define __XML_LIBXML_H__
+
+#ifndef NO_LARGEFILE_SOURCE
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+#endif
+#ifndef _CRT_NO_POSIX_ERROR_CODES
+#define _CRT_NO_POSIX_ERROR_CODES
+#endif
+
+#if defined(macintosh)
+#include "config-mac.h"
+#elif defined(_WIN32_WCE)
+/*
+ * Windows CE compatibility definitions and functions
+ * This is needed to compile libxml2 for Windows CE.
+ * At least I tested it with WinCE 5.0 for Emulator and WinCE 4.2/SH4 target
+ */
+#include <win32config.h>
+#include <libxml/xmlversion.h>
+#else
+#include "config.h"
+#include <libxml/xmlversion.h>
+#endif
+
+#if defined(__Lynx__)
+#include <stdio.h> /* pull definition of size_t */
+#include <varargs.h>
+int snprintf(char *, size_t, const char *, ...);
+int vfprintf(FILE *, const char *, va_list);
+#endif
+
+#ifndef WITH_TRIO
+#include <stdio.h>
+#else
+/**
+ * TRIO_REPLACE_STDIO:
+ *
+ * This macro is defined if teh trio string formatting functions are to
+ * be used instead of the default stdio ones.
+ */
+#define TRIO_REPLACE_STDIO
+#include "trio.h"
+#endif
+
+/*
+ * Internal variable indicating if a callback has been registered for
+ * node creation/destruction. It avoids spending a lot of time in locking
+ * function while checking if the callback exists.
+ */
+extern int __xmlRegisterCallbacks;
+/*
+ * internal error reporting routines, shared but not partof the API.
+ */
+void __xmlIOErr(int domain, int code, const char *extra);
+void __xmlLoaderErr(void *ctx, const char *msg, const char *filename);
+#ifdef LIBXML_HTML_ENABLED
+/*
+ * internal function of HTML parser needed for xmlParseInNodeContext
+ * but not part of the API
+ */
+void __htmlParseContent(void *ctx);
+#endif
+
+/*
+ * internal global initialization critical section routines.
+ */
+void __xmlGlobalInitMutexLock(void);
+void __xmlGlobalInitMutexUnlock(void);
+void __xmlGlobalInitMutexDestroy(void);
+
+#ifdef IN_LIBXML
+#ifdef __GNUC__
+#ifdef PIC
+#ifdef linux
+#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
+#include "elfgcchack.h"
+#endif
+#endif
+#endif
+#endif
+#endif
+#ifndef PIC
+#  define LIBXML_STATIC
+#endif
+#endif /* ! __XML_LIBXML_H__ */
diff --git a/src/libxml.m4 b/src/libxml.m4
new file mode 100644
index 0000000..68cd824
--- /dev/null
+++ b/src/libxml.m4
@@ -0,0 +1,188 @@
+# Configure paths for LIBXML2
+# Mike Hommey 2004-06-19
+# use CPPFLAGS instead of CFLAGS
+# Toshio Kuratomi 2001-04-21
+# Adapted from:
+# Configure paths for GLIB
+# Owen Taylor     97-11-3
+
+dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for XML, and define XML_CPPFLAGS and XML_LIBS
+dnl
+AC_DEFUN([AM_PATH_XML2],[ 
+AC_ARG_WITH(xml-prefix,
+            [  --with-xml-prefix=PFX   Prefix where libxml is installed (optional)],
+            xml_config_prefix="$withval", xml_config_prefix="")
+AC_ARG_WITH(xml-exec-prefix,
+            [  --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
+            xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
+AC_ARG_ENABLE(xmltest,
+              [  --disable-xmltest       Do not try to compile and run a test LIBXML program],,
+              enable_xmltest=yes)
+
+  if test x$xml_config_exec_prefix != x ; then
+     xml_config_args="$xml_config_args"
+     if test x${XML2_CONFIG+set} != xset ; then
+        XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
+     fi
+  fi
+  if test x$xml_config_prefix != x ; then
+     xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
+     if test x${XML2_CONFIG+set} != xset ; then
+        XML2_CONFIG=$xml_config_prefix/bin/xml2-config
+     fi
+  fi
+
+  AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
+  min_xml_version=ifelse([$1], ,2.0.0,[$1])
+  AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
+  no_xml=""
+  if test "$XML2_CONFIG" = "no" ; then
+    no_xml=yes
+  else
+    XML_CPPFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
+    XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
+    xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_xmltest" = "xyes" ; then
+      ac_save_CPPFLAGS="$CPPFLAGS"
+      ac_save_LIBS="$LIBS"
+      CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
+      LIBS="$XML_LIBS $LIBS"
+dnl
+dnl Now check if the installed libxml is sufficiently new.
+dnl (Also sanity checks the results of xml2-config to some extent)
+dnl
+      rm -f conf.xmltest
+      AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libxml/xmlversion.h>
+
+int 
+main()
+{
+  int xml_major_version, xml_minor_version, xml_micro_version;
+  int major, minor, micro;
+  char *tmp_version;
+
+  system("touch conf.xmltest");
+
+  /* Capture xml2-config output via autoconf/configure variables */
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = (char *)strdup("$min_xml_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string from xml2-config\n", "$min_xml_version");
+     exit(1);
+   }
+   free(tmp_version);
+
+   /* Capture the version information from the header files */
+   tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
+   if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
+     printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
+     exit(1);
+   }
+   free(tmp_version);
+
+ /* Compare xml2-config output to the libxml headers */
+  if ((xml_major_version != $xml_config_major_version) ||
+      (xml_minor_version != $xml_config_minor_version) ||
+      (xml_micro_version != $xml_config_micro_version))
+    {
+      printf("*** libxml header files (version %d.%d.%d) do not match\n",
+         xml_major_version, xml_minor_version, xml_micro_version);
+      printf("*** xml2-config (version %d.%d.%d)\n",
+         $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
+      return 1;
+    } 
+/* Compare the headers to the library to make sure we match */
+  /* Less than ideal -- doesn't provide us with return value feedback, 
+   * only exits if there's a serious mismatch between header and library.
+   */
+    LIBXML_TEST_VERSION;
+
+    /* Test that the library is greater than our minimum version */
+    if ((xml_major_version > major) ||
+        ((xml_major_version == major) && (xml_minor_version > minor)) ||
+        ((xml_major_version == major) && (xml_minor_version == minor) &&
+        (xml_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
+               xml_major_version, xml_minor_version, xml_micro_version);
+        printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
+           major, minor, micro);
+        printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
+        printf("*** correct copy of xml2-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+    }
+  return 1;
+}
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CPPFLAGS="$ac_save_CPPFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+
+  if test "x$no_xml" = x ; then
+     AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$XML2_CONFIG" = "no" ; then
+       echo "*** The xml2-config script installed by LIBXML could not be found"
+       echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the XML2_CONFIG environment variable to the"
+       echo "*** full path to xml2-config."
+     else
+       if test -f conf.xmltest ; then
+        :
+       else
+          echo "*** Could not run libxml test program, checking why..."
+          CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
+          LIBS="$LIBS $XML_LIBS"
+          AC_TRY_LINK([
+#include <libxml/xmlversion.h>
+#include <stdio.h>
+],      [ LIBXML_TEST_VERSION; return 0;],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
+          echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+          echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
+          echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
+          echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
+          CPPFLAGS="$ac_save_CPPFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+
+     XML_CPPFLAGS=""
+     XML_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(XML_CPPFLAGS)
+  AC_SUBST(XML_LIBS)
+  rm -f conf.xmltest
+])
diff --git a/src/libxml.spec.in b/src/libxml.spec.in
new file mode 100644
index 0000000..688811a
--- /dev/null
+++ b/src/libxml.spec.in
@@ -0,0 +1,132 @@
+Summary: Library providing XML and HTML support
+Name: libxml2
+Version: @VERSION@
+Release: 1
+License: MIT
+Group: Development/Libraries
+Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRequires: python python-devel zlib-devel pkgconfig
+URL: http://xmlsoft.org/
+
+%description
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DtDs, either
+at parse time or later once the document has been modified. The output
+can be a simple SAX stream or and in-memory DOM like representations.
+In this case one can use the built-in XPath and XPointer implementation
+to select subnodes or ranges. A flexible Input/Output mechanism is
+available, with existing HTTP and FTP modules and combined to an
+URI library.
+
+%package devel
+Summary: Libraries, includes, etc. to develop XML and HTML applications
+Group: Development/Libraries
+Requires: libxml2 = %{version}-%{release}
+Requires: zlib-devel
+Requires: pkgconfig
+
+%description devel
+Libraries, include files, etc you can use to develop XML applications.
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DtDs, either
+at parse time or later once the document has been modified. The output
+can be a simple SAX stream or and in-memory DOM like representations.
+In this case one can use the built-in XPath and XPointer implementation
+to select subnodes or ranges. A flexible Input/Output mechanism is
+available, with existing HTTP and FTP modules and combined to an
+URI library.
+
+%package python
+Summary: Python bindings for the libxml2 library
+Group: Development/Libraries
+Requires: libxml2 = %{version}-%{release}
+Requires: python
+
+%description python
+The libxml2-python package contains a module that permits applications
+written in the Python programming language to use the interface
+supplied by the libxml2 library to manipulate XML files.
+
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DTDs, either
+at parse time or later once the document has been modified.
+
+%prep
+%setup -q
+
+%build
+%configure
+make %{_smp_mflags}
+gzip -9 ChangeLog
+
+%install
+rm -fr %{buildroot}
+
+%makeinstall
+(cd doc/examples ; make clean ; rm -rf .deps Makefile)
+gzip -9 doc/libxml2-api.xml
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+
+%clean
+rm -fr %{buildroot}
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%defattr(-, root, root)
+
+%doc AUTHORS ChangeLog.gz NEWS README Copyright TODO
+%doc %{_mandir}/man1/xmllint.1*
+%doc %{_mandir}/man1/xmlcatalog.1*
+%doc %{_mandir}/man3/libxml.3*
+
+%{_libdir}/lib*.so.*
+%{_bindir}/xmllint
+%{_bindir}/xmlcatalog
+
+%files devel
+%defattr(-, root, root)
+
+%doc %{_mandir}/man1/xml2-config.1*
+%doc AUTHORS ChangeLog.gz NEWS README Copyright
+%doc doc/*.html doc/html doc/*.gif doc/*.png
+%doc doc/tutorial doc/libxml2-api.xml.gz
+%doc doc/examples
+%doc %dir %{_datadir}/gtk-doc/html/libxml2
+%doc %{_datadir}/gtk-doc/html/libxml2/*.devhelp
+%doc %{_datadir}/gtk-doc/html/libxml2/*.html
+%doc %{_datadir}/gtk-doc/html/libxml2/*.png
+%doc %{_datadir}/gtk-doc/html/libxml2/*.css
+
+%{_libdir}/lib*.so
+%{_libdir}/*a
+%{_libdir}/*.sh
+%{_includedir}/*
+%{_bindir}/xml2-config
+%{_datadir}/aclocal/libxml.m4
+%{_libdir}/pkgconfig/libxml-2.0.pc
+%files python
+%defattr(-, root, root)
+
+%doc AUTHORS ChangeLog.gz NEWS README Copyright
+%{_libdir}/python*/site-packages/libxml2.py*
+%{_libdir}/python*/site-packages/drv_libxml2.py*
+%{_libdir}/python*/site-packages/libxml2mod*
+%doc python/TODO
+%doc python/libxml2class.txt
+%doc python/tests/*.py
+%doc doc/*.py
+%doc doc/python.html
+
+%changelog
+* @RELDATE@ Daniel Veillard <veillard@redhat.com>
+- upstream release @VERSION@ see http://xmlsoft.org/news.html
+
diff --git a/src/libxml2.spec b/src/libxml2.spec
new file mode 100644
index 0000000..94a2a3f
--- /dev/null
+++ b/src/libxml2.spec
@@ -0,0 +1,132 @@
+Summary: Library providing XML and HTML support
+Name: libxml2
+Version: 2.7.7
+Release: 1
+License: MIT
+Group: Development/Libraries
+Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRequires: python python-devel zlib-devel pkgconfig
+URL: http://xmlsoft.org/
+
+%description
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DtDs, either
+at parse time or later once the document has been modified. The output
+can be a simple SAX stream or and in-memory DOM like representations.
+In this case one can use the built-in XPath and XPointer implementation
+to select subnodes or ranges. A flexible Input/Output mechanism is
+available, with existing HTTP and FTP modules and combined to an
+URI library.
+
+%package devel
+Summary: Libraries, includes, etc. to develop XML and HTML applications
+Group: Development/Libraries
+Requires: libxml2 = %{version}-%{release}
+Requires: zlib-devel
+Requires: pkgconfig
+
+%description devel
+Libraries, include files, etc you can use to develop XML applications.
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DtDs, either
+at parse time or later once the document has been modified. The output
+can be a simple SAX stream or and in-memory DOM like representations.
+In this case one can use the built-in XPath and XPointer implementation
+to select subnodes or ranges. A flexible Input/Output mechanism is
+available, with existing HTTP and FTP modules and combined to an
+URI library.
+
+%package python
+Summary: Python bindings for the libxml2 library
+Group: Development/Libraries
+Requires: libxml2 = %{version}-%{release}
+Requires: python
+
+%description python
+The libxml2-python package contains a module that permits applications
+written in the Python programming language to use the interface
+supplied by the libxml2 library to manipulate XML files.
+
+This library allows to manipulate XML files. It includes support 
+to read, modify and write XML and HTML files. There is DTDs support
+this includes parsing and validation even with complex DTDs, either
+at parse time or later once the document has been modified.
+
+%prep
+%setup -q
+
+%build
+%configure
+make %{_smp_mflags}
+gzip -9 ChangeLog
+
+%install
+rm -fr %{buildroot}
+
+%makeinstall
+(cd doc/examples ; make clean ; rm -rf .deps Makefile)
+gzip -9 doc/libxml2-api.xml
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+
+%clean
+rm -fr %{buildroot}
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%defattr(-, root, root)
+
+%doc AUTHORS ChangeLog.gz NEWS README Copyright TODO
+%doc %{_mandir}/man1/xmllint.1*
+%doc %{_mandir}/man1/xmlcatalog.1*
+%doc %{_mandir}/man3/libxml.3*
+
+%{_libdir}/lib*.so.*
+%{_bindir}/xmllint
+%{_bindir}/xmlcatalog
+
+%files devel
+%defattr(-, root, root)
+
+%doc %{_mandir}/man1/xml2-config.1*
+%doc AUTHORS ChangeLog.gz NEWS README Copyright
+%doc doc/*.html doc/html doc/*.gif doc/*.png
+%doc doc/tutorial doc/libxml2-api.xml.gz
+%doc doc/examples
+%doc %dir %{_datadir}/gtk-doc/html/libxml2
+%doc %{_datadir}/gtk-doc/html/libxml2/*.devhelp
+%doc %{_datadir}/gtk-doc/html/libxml2/*.html
+%doc %{_datadir}/gtk-doc/html/libxml2/*.png
+%doc %{_datadir}/gtk-doc/html/libxml2/*.css
+
+%{_libdir}/lib*.so
+%{_libdir}/*a
+%{_libdir}/*.sh
+%{_includedir}/*
+%{_bindir}/xml2-config
+%{_datadir}/aclocal/libxml.m4
+%{_libdir}/pkgconfig/libxml-2.0.pc
+%files python
+%defattr(-, root, root)
+
+%doc AUTHORS ChangeLog.gz NEWS README Copyright
+%{_libdir}/python*/site-packages/libxml2.py*
+%{_libdir}/python*/site-packages/drv_libxml2.py*
+%{_libdir}/python*/site-packages/libxml2mod*
+%doc python/TODO
+%doc python/libxml2class.txt
+%doc python/tests/*.py
+%doc doc/*.py
+%doc doc/python.html
+
+%changelog
+* Mon Mar 15 2010 Daniel Veillard <veillard@redhat.com>
+- upstream release 2.7.7 see http://xmlsoft.org/news.html
+
diff --git a/src/list.c b/src/list.c
new file mode 100644
index 0000000..5c01c83
--- /dev/null
+++ b/src/list.c
@@ -0,0 +1,779 @@
+/*
+ * list.c: lists handling implementation
+ *
+ * Copyright (C) 2000 Gary Pennington 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ * Author: Gary.Pennington@uk.sun.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/list.h>
+#include <libxml/globals.h>
+
+/*
+ * Type definition are kept internal
+ */
+
+struct _xmlLink
+{
+    struct _xmlLink *next;
+    struct _xmlLink *prev;
+    void *data;
+};
+
+struct _xmlList
+{
+    xmlLinkPtr sentinel;
+    void (*linkDeallocator)(xmlLinkPtr );
+    int (*linkCompare)(const void *, const void*);
+};
+
+/************************************************************************
+ *                                    *
+ *                Interfaces                *
+ *                                    *
+ ************************************************************************/
+
+/**
+ * xmlLinkDeallocator:
+ * @l:  a list
+ * @lk:  a link
+ *
+ * Unlink and deallocate @lk from list @l
+ */
+static void
+xmlLinkDeallocator(xmlListPtr l, xmlLinkPtr lk)
+{
+    (lk->prev)->next = lk->next;
+    (lk->next)->prev = lk->prev;
+    if(l->linkDeallocator)
+        l->linkDeallocator(lk);
+    xmlFree(lk);
+}
+
+/**
+ * xmlLinkCompare:
+ * @data0:  first data
+ * @data1:  second data
+ *
+ * Compares two arbitrary data
+ *
+ * Returns -1, 0 or 1 depending on whether data1 is greater equal or smaller
+ *          than data0
+ */
+static int
+xmlLinkCompare(const void *data0, const void *data1)
+{
+    if (data0 < data1)
+        return (-1);
+    else if (data0 == data1)
+	return (0);
+    return (1);
+}
+
+/**
+ * xmlListLowerSearch:
+ * @l:  a list
+ * @data:  a data
+ *
+ * Search data in the ordered list walking from the beginning
+ *
+ * Returns the link containing the data or NULL
+ */
+static xmlLinkPtr 
+xmlListLowerSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+
+    if (l == NULL)
+        return(NULL);
+    for(lk = l->sentinel->next;lk != l->sentinel && l->linkCompare(lk->data, data) <0 ;lk = lk->next);
+    return lk;    
+}
+
+/**
+ * xmlListHigherSearch:
+ * @l:  a list
+ * @data:  a data
+ *
+ * Search data in the ordered list walking backward from the end
+ *
+ * Returns the link containing the data or NULL
+ */
+static xmlLinkPtr 
+xmlListHigherSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+
+    if (l == NULL)
+        return(NULL);
+    for(lk = l->sentinel->prev;lk != l->sentinel && l->linkCompare(lk->data, data) >0 ;lk = lk->prev);
+    return lk;    
+}
+
+/**
+ * xmlListSearch:
+ * @l:  a list
+ * @data:  a data
+ *
+ * Search data in the list
+ *
+ * Returns the link containing the data or NULL
+ */
+static xmlLinkPtr 
+xmlListLinkSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+    if (l == NULL)
+        return(NULL);
+    lk = xmlListLowerSearch(l, data);
+    if (lk == l->sentinel)
+        return NULL;
+    else {
+        if (l->linkCompare(lk->data, data) ==0)
+            return lk;
+        return NULL;
+    }
+}
+
+/**
+ * xmlListLinkReverseSearch:
+ * @l:  a list
+ * @data:  a data
+ *
+ * Search data in the list processing backward
+ *
+ * Returns the link containing the data or NULL
+ */
+static xmlLinkPtr 
+xmlListLinkReverseSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+    if (l == NULL)
+        return(NULL);
+    lk = xmlListHigherSearch(l, data);
+    if (lk == l->sentinel)
+        return NULL;
+    else {
+        if (l->linkCompare(lk->data, data) ==0)
+            return lk;
+        return NULL;
+    }
+}
+
+/**
+ * xmlListCreate:
+ * @deallocator:  an optional deallocator function
+ * @compare:  an optional comparison function
+ *
+ * Create a new list
+ *
+ * Returns the new list or NULL in case of error
+ */
+xmlListPtr
+xmlListCreate(xmlListDeallocator deallocator, xmlListDataCompare compare)
+{
+    xmlListPtr l;
+    if (NULL == (l = (xmlListPtr )xmlMalloc( sizeof(xmlList)))) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for list");
+        return (NULL);
+    }
+    /* Initialize the list to NULL */
+    memset(l, 0, sizeof(xmlList));
+    
+    /* Add the sentinel */
+    if (NULL ==(l->sentinel = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for sentinel");
+	xmlFree(l);
+        return (NULL);
+    }
+    l->sentinel->next = l->sentinel;
+    l->sentinel->prev = l->sentinel;
+    l->sentinel->data = NULL;
+    
+    /* If there is a link deallocator, use it */
+    if (deallocator != NULL)
+        l->linkDeallocator = deallocator;
+    /* If there is a link comparator, use it */
+    if (compare != NULL)
+        l->linkCompare = compare;
+    else /* Use our own */
+        l->linkCompare = xmlLinkCompare;
+    return l;
+}
+    
+/**
+ * xmlListSearch:
+ * @l:  a list
+ * @data:  a search value
+ *
+ * Search the list for an existing value of @data
+ *
+ * Returns the value associated to @data or NULL in case of error
+ */
+void *
+xmlListSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+    if (l == NULL)
+        return(NULL);
+    lk = xmlListLinkSearch(l, data);
+    if (lk)
+        return (lk->data);
+    return NULL;
+}
+
+/**
+ * xmlListReverseSearch:
+ * @l:  a list
+ * @data:  a search value
+ *
+ * Search the list in reverse order for an existing value of @data
+ *
+ * Returns the value associated to @data or NULL in case of error
+ */
+void *
+xmlListReverseSearch(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lk;
+    if (l == NULL)
+        return(NULL);
+    lk = xmlListLinkReverseSearch(l, data);
+    if (lk)
+        return (lk->data);
+    return NULL;
+}
+
+/**
+ * xmlListInsert:
+ * @l:  a list
+ * @data:  the data
+ *
+ * Insert data in the ordered list at the beginning for this value
+ *
+ * Returns 0 in case of success, 1 in case of failure
+ */
+int
+xmlListInsert(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lkPlace, lkNew;
+
+    if (l == NULL)
+        return(1);
+    lkPlace = xmlListLowerSearch(l, data);
+    /* Add the new link */
+    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
+    if (lkNew == NULL) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for new link");
+        return (1);
+    }
+    lkNew->data = data;
+    lkPlace = lkPlace->prev;
+    lkNew->next = lkPlace->next;
+    (lkPlace->next)->prev = lkNew;
+    lkPlace->next = lkNew;
+    lkNew->prev = lkPlace;
+    return 0;
+}
+
+/**
+ * xmlListAppend:
+ * @l:  a list
+ * @data:  the data
+ *
+ * Insert data in the ordered list at the end for this value
+ *
+ * Returns 0 in case of success, 1 in case of failure
+ */
+int xmlListAppend(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lkPlace, lkNew;
+
+    if (l == NULL)
+        return(1);
+    lkPlace = xmlListHigherSearch(l, data);
+    /* Add the new link */
+    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
+    if (lkNew == NULL) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for new link");
+        return (1);
+    }
+    lkNew->data = data;
+    lkNew->next = lkPlace->next;
+    (lkPlace->next)->prev = lkNew;
+    lkPlace->next = lkNew;
+    lkNew->prev = lkPlace;
+    return 0;
+}
+
+/**
+ * xmlListDelete:
+ * @l:  a list
+ *
+ * Deletes the list and its associated data
+ */
+void xmlListDelete(xmlListPtr l)
+{
+    if (l == NULL)
+        return;
+
+    xmlListClear(l);
+    xmlFree(l->sentinel);
+    xmlFree(l);
+}
+
+/**
+ * xmlListRemoveFirst:
+ * @l:  a list
+ * @data:  list data
+ *
+ * Remove the first instance associated to data in the list
+ *
+ * Returns 1 if a deallocation occured, or 0 if not found
+ */
+int
+xmlListRemoveFirst(xmlListPtr l, void *data)
+{
+    xmlLinkPtr lk;
+    
+    if (l == NULL)
+        return(0);
+    /*Find the first instance of this data */
+    lk = xmlListLinkSearch(l, data);
+    if (lk != NULL) {
+        xmlLinkDeallocator(l, lk);
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * xmlListRemoveLast:
+ * @l:  a list
+ * @data:  list data
+ *
+ * Remove the last instance associated to data in the list
+ *
+ * Returns 1 if a deallocation occured, or 0 if not found
+ */
+int
+xmlListRemoveLast(xmlListPtr l, void *data)
+{
+    xmlLinkPtr lk;
+    
+    if (l == NULL)
+        return(0);
+    /*Find the last instance of this data */
+    lk = xmlListLinkReverseSearch(l, data);
+    if (lk != NULL) {
+	xmlLinkDeallocator(l, lk);
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * xmlListRemoveAll:
+ * @l:  a list
+ * @data:  list data
+ *
+ * Remove the all instance associated to data in the list
+ *
+ * Returns the number of deallocation, or 0 if not found
+ */
+int
+xmlListRemoveAll(xmlListPtr l, void *data)
+{
+    int count=0;
+    
+    if (l == NULL)
+        return(0);
+
+    while(xmlListRemoveFirst(l, data))
+        count++;
+    return count;
+}
+
+/**
+ * xmlListClear:
+ * @l:  a list
+ *
+ * Remove the all data in the list
+ */
+void
+xmlListClear(xmlListPtr l)
+{
+    xmlLinkPtr  lk;
+    
+    if (l == NULL)
+        return;
+    lk = l->sentinel->next;
+    while(lk != l->sentinel) {
+        xmlLinkPtr next = lk->next;
+
+        xmlLinkDeallocator(l, lk);
+        lk = next;
+    }
+}
+
+/**
+ * xmlListEmpty:
+ * @l:  a list
+ *
+ * Is the list empty ?
+ *
+ * Returns 1 if the list is empty, 0 if not empty and -1 in case of error
+ */
+int
+xmlListEmpty(xmlListPtr l)
+{
+    if (l == NULL)
+        return(-1);
+    return (l->sentinel->next == l->sentinel);
+}
+
+/**
+ * xmlListFront:
+ * @l:  a list
+ *
+ * Get the first element in the list
+ *
+ * Returns the first element in the list, or NULL
+ */
+xmlLinkPtr 
+xmlListFront(xmlListPtr l)
+{
+    if (l == NULL)
+        return(NULL);
+    return (l->sentinel->next);
+}
+    
+/**
+ * xmlListEnd:
+ * @l:  a list
+ *
+ * Get the last element in the list
+ *
+ * Returns the last element in the list, or NULL
+ */
+xmlLinkPtr 
+xmlListEnd(xmlListPtr l)
+{
+    if (l == NULL)
+        return(NULL);
+    return (l->sentinel->prev);
+}
+    
+/**
+ * xmlListSize:
+ * @l:  a list
+ *
+ * Get the number of elements in the list
+ *
+ * Returns the number of elements in the list or -1 in case of error
+ */
+int
+xmlListSize(xmlListPtr l)
+{
+    xmlLinkPtr lk;
+    int count=0;
+
+    if (l == NULL)
+        return(-1);
+    /* TODO: keep a counter in xmlList instead */
+    for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next, count++);
+    return count;
+}
+
+/**
+ * xmlListPopFront:
+ * @l:  a list
+ *
+ * Removes the first element in the list
+ */
+void
+xmlListPopFront(xmlListPtr l)
+{
+    if(!xmlListEmpty(l))
+        xmlLinkDeallocator(l, l->sentinel->next);
+}
+
+/**
+ * xmlListPopBack:
+ * @l:  a list
+ *
+ * Removes the last element in the list
+ */
+void
+xmlListPopBack(xmlListPtr l)
+{
+    if(!xmlListEmpty(l))
+        xmlLinkDeallocator(l, l->sentinel->prev);
+}
+
+/**
+ * xmlListPushFront:
+ * @l:  a list
+ * @data:  new data
+ *
+ * add the new data at the beginning of the list
+ *
+ * Returns 1 if successful, 0 otherwise
+ */
+int
+xmlListPushFront(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lkPlace, lkNew;
+
+    if (l == NULL)
+        return(0);
+    lkPlace = l->sentinel;
+    /* Add the new link */
+    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
+    if (lkNew == NULL) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for new link");
+        return (0);
+    }
+    lkNew->data = data;
+    lkNew->next = lkPlace->next;
+    (lkPlace->next)->prev = lkNew;
+    lkPlace->next = lkNew;
+    lkNew->prev = lkPlace;
+    return 1;
+}
+
+/**
+ * xmlListPushBack:
+ * @l:  a list
+ * @data:  new data
+ *
+ * add the new data at the end of the list
+ *
+ * Returns 1 if successful, 0 otherwise
+ */
+int
+xmlListPushBack(xmlListPtr l, void *data) 
+{
+    xmlLinkPtr lkPlace, lkNew;
+
+    if (l == NULL)
+        return(0);
+    lkPlace = l->sentinel->prev;
+    /* Add the new link */
+    if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
+        xmlGenericError(xmlGenericErrorContext, 
+		        "Cannot initialize memory for new link");
+        return (0);
+    }
+    lkNew->data = data;
+    lkNew->next = lkPlace->next;
+    (lkPlace->next)->prev = lkNew;
+    lkPlace->next = lkNew;
+    lkNew->prev = lkPlace;
+    return 1;
+}
+
+/**
+ * xmlLinkGetData:
+ * @lk:  a link
+ *
+ * See Returns.
+ *
+ * Returns a pointer to the data referenced from this link
+ */
+void *
+xmlLinkGetData(xmlLinkPtr lk)
+{
+    if (lk == NULL)
+        return(NULL);
+    return lk->data;
+}
+
+/**
+ * xmlListReverse:
+ * @l:  a list
+ *
+ * Reverse the order of the elements in the list
+ */
+void
+xmlListReverse(xmlListPtr l)
+{
+    xmlLinkPtr lk;
+    xmlLinkPtr lkPrev;
+
+    if (l == NULL)
+        return;
+    lkPrev = l->sentinel;
+    for (lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
+        lkPrev->next = lkPrev->prev;
+        lkPrev->prev = lk;
+        lkPrev = lk;
+    }
+    /* Fix up the last node */
+    lkPrev->next = lkPrev->prev;
+    lkPrev->prev = lk;
+}
+
+/**
+ * xmlListSort:
+ * @l:  a list
+ *
+ * Sort all the elements in the list
+ */
+void
+xmlListSort(xmlListPtr l)
+{
+    xmlListPtr lTemp;
+    
+    if (l == NULL)
+        return;
+    if(xmlListEmpty(l))
+        return;
+
+    /* I think that the real answer is to implement quicksort, the
+     * alternative is to implement some list copying procedure which
+     * would be based on a list copy followed by a clear followed by
+     * an insert. This is slow...
+     */
+
+    if (NULL ==(lTemp = xmlListDup(l)))
+        return;
+    xmlListClear(l);
+    xmlListMerge(l, lTemp);
+    xmlListDelete(lTemp);
+    return;
+}
+
+/**
+ * xmlListWalk:
+ * @l:  a list
+ * @walker:  a processing function
+ * @user:  a user parameter passed to the walker function
+ *
+ * Walk all the element of the first from first to last and
+ * apply the walker function to it
+ */
+void
+xmlListWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
+    xmlLinkPtr lk;
+
+    if ((l == NULL) || (walker == NULL))
+        return;
+    for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
+        if((walker(lk->data, user)) == 0)
+                break;
+    }
+}
+
+/**
+ * xmlListReverseWalk:
+ * @l:  a list
+ * @walker:  a processing function
+ * @user:  a user parameter passed to the walker function
+ *
+ * Walk all the element of the list in reverse order and
+ * apply the walker function to it
+ */
+void
+xmlListReverseWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
+    xmlLinkPtr lk;
+
+    if ((l == NULL) || (walker == NULL))
+        return;
+    for(lk = l->sentinel->prev; lk != l->sentinel; lk = lk->prev) {
+        if((walker(lk->data, user)) == 0)
+                break;
+    }
+}
+
+/**
+ * xmlListMerge:
+ * @l1:  the original list
+ * @l2:  the new list
+ *
+ * include all the elements of the second list in the first one and
+ * clear the second list
+ */
+void
+xmlListMerge(xmlListPtr l1, xmlListPtr l2)
+{
+    xmlListCopy(l1, l2);
+    xmlListClear(l2);
+}
+
+/**
+ * xmlListDup:
+ * @old:  the list
+ *
+ * Duplicate the list
+ * 
+ * Returns a new copy of the list or NULL in case of error
+ */
+xmlListPtr 
+xmlListDup(const xmlListPtr old)
+{
+    xmlListPtr cur;
+
+    if (old == NULL)
+        return(NULL);
+    /* Hmmm, how to best deal with allocation issues when copying
+     * lists. If there is a de-allocator, should responsibility lie with
+     * the new list or the old list. Surely not both. I'll arbitrarily
+     * set it to be the old list for the time being whilst I work out
+     * the answer
+     */
+    if (NULL ==(cur = xmlListCreate(NULL, old->linkCompare)))
+        return (NULL);
+    if (0 != xmlListCopy(cur, old))
+        return NULL;
+    return cur;
+}
+
+/**
+ * xmlListCopy:
+ * @cur:  the new list
+ * @old:  the old list
+ *
+ * Move all the element from the old list in the new list
+ * 
+ * Returns 0 in case of success 1 in case of error
+ */
+int
+xmlListCopy(xmlListPtr cur, const xmlListPtr old)
+{
+    /* Walk the old tree and insert the data into the new one */
+    xmlLinkPtr lk;
+
+    if ((old == NULL) || (cur == NULL))
+        return(1);
+    for(lk = old->sentinel->next; lk != old->sentinel; lk = lk->next) {
+        if (0 !=xmlListInsert(cur, lk->data)) {
+            xmlListDelete(cur);
+            return (1);
+        }
+    }
+    return (0);    
+}
+/* xmlListUnique() */
+/* xmlListSwap */
+#define bottom_list
+#include "elfgcchack.h"
diff --git a/src/ltmain.sh b/src/ltmain.sh
new file mode 100755
index 0000000..a72f2fd
--- /dev/null
+++ b/src/ltmain.sh
@@ -0,0 +1,8406 @@
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#     --config             show all configuration variables
+#     --debug              enable verbose shell tracing
+# -n, --dry-run            display commands without modifying any files
+#     --features           display basic configuration information and exit
+#     --mode=MODE          use operation mode MODE
+#     --preserve-dup-deps  don't remove duplicate dependency libraries
+#     --quiet, --silent    don't print informational messages
+#     --tag=TAG            use configuration variables from tag TAG
+# -v, --verbose            print informational messages (default)
+#     --version            print version information
+# -h, --help               print short or long help message
+#
+# MODE must be one of the following:
+#
+#       clean              remove files from the build directory
+#       compile            compile a source file into a libtool object
+#       execute            automatically set library path, then run a program
+#       finish             complete the installation of libtool libraries
+#       install            install libraries or executables
+#       link               create a library or an executable
+#       uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#       host-triplet:	$host
+#       shell:		$SHELL
+#       compiler:		$LTCC
+#       compiler flags:		$LTCFLAGS
+#       linker:		$LD (gnu? $with_gnu_ld)
+#       $progname:		(GNU libtool) 2.2.6b
+#       automake:		$automake_version
+#       autoconf:		$autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=2.2.6b
+TIMESTAMP=""
+package_revision=1.3017
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+  -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=:
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "X$1" | $Xsed \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $SED -n '/^# Usage:/,/# -h/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    $ECHO
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+	p
+     }' < "$progpath"
+    exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    func_error "missing argument for $1"
+    exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell, and then maybe $ECHO will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    $ECHO "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $ECHO "enable shared libraries"
+    else
+      $ECHO "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $ECHO "enable static libraries"
+    else
+      $ECHO "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# Parse options once, thoroughly.  This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+  # Shorthand for --mode=foo, only valid as the first argument
+  case $1 in
+  clean|clea|cle|cl)
+    shift; set dummy --mode clean ${1+"$@"}; shift
+    ;;
+  compile|compil|compi|comp|com|co|c)
+    shift; set dummy --mode compile ${1+"$@"}; shift
+    ;;
+  execute|execut|execu|exec|exe|ex|e)
+    shift; set dummy --mode execute ${1+"$@"}; shift
+    ;;
+  finish|finis|fini|fin|fi|f)
+    shift; set dummy --mode finish ${1+"$@"}; shift
+    ;;
+  install|instal|insta|inst|ins|in|i)
+    shift; set dummy --mode install ${1+"$@"}; shift
+    ;;
+  link|lin|li|l)
+    shift; set dummy --mode link ${1+"$@"}; shift
+    ;;
+  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+    shift; set dummy --mode uninstall ${1+"$@"}; shift
+    ;;
+  esac
+
+  # Parse non-mode specific arguments:
+  while test "$#" -gt 0; do
+    opt="$1"
+    shift
+
+    case $opt in
+      --config)		func_config					;;
+
+      --debug)		preserve_args="$preserve_args $opt"
+			func_echo "enabling shell trace mode"
+			opt_debug='set -x'
+			$opt_debug
+			;;
+
+      -dlopen)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			execute_dlfiles="$execute_dlfiles $1"
+			shift
+			;;
+
+      --dry-run | -n)	opt_dry_run=:					;;
+      --features)       func_features					;;
+      --finish)		mode="finish"					;;
+
+      --mode)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			case $1 in
+			  # Valid mode arguments:
+			  clean)	;;
+			  compile)	;;
+			  execute)	;;
+			  finish)	;;
+			  install)	;;
+			  link)		;;
+			  relink)	;;
+			  uninstall)	;;
+
+			  # Catch anything else as an error
+			  *) func_error "invalid argument for $opt"
+			     exit_cmd=exit
+			     break
+			     ;;
+		        esac
+
+			mode="$1"
+			shift
+			;;
+
+      --preserve-dup-deps)
+			opt_duplicate_deps=:				;;
+
+      --quiet|--silent)	preserve_args="$preserve_args $opt"
+			opt_silent=:
+			;;
+
+      --verbose| -v)	preserve_args="$preserve_args $opt"
+			opt_silent=false
+			;;
+
+      --tag)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			preserve_args="$preserve_args $opt $1"
+			func_enable_tag "$1"	# tagname is set here
+			shift
+			;;
+
+      # Separate optargs to long options:
+      -dlopen=*|--mode=*|--tag=*)
+			func_opt_split "$opt"
+			set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+			shift
+			;;
+
+      -\?|-h)		func_usage					;;
+      --help)		opt_help=:					;;
+      --version)	func_version					;;
+
+      -*)		func_fatal_help "unrecognized option \`$opt'"	;;
+
+      *)		nonopt="$opt"
+			break
+			;;
+    esac
+  done
+
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+      ;;
+  esac
+
+  # Having warned about all mis-specified options, bail out if
+  # anything was wrong.
+  $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+$opt_help || {
+  # Sanity checks first:
+  func_check_version_match
+
+  if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+    func_fatal_configuration "not configured to build any kind of library"
+  fi
+
+  test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+  # Darwin sucks
+  eval std_shrext=\"$shrext_cmds\"
+
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    func_error "unrecognized option \`-dlopen'"
+    $ECHO "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_ltwrapper_scriptname_result=""
+    if func_ltwrapper_executable_p "$1"; then
+	func_dirname_and_basename "$1" "" "."
+	func_stripname '' '.exe' "$func_basename_result"
+	func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+    fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+        func_quote_for_eval "$arg"
+	CC_quoted="$CC_quoted $func_quote_for_eval_result"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_quote_for_eval "$arg"
+	      CC_quoted="$CC_quoted $func_quote_for_eval_result"
+	    done
+	    case "$@ " in
+	      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          pie_flag="$pie_flag $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  later="$later $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_quote_for_eval "$arg"
+	    lastarg="$lastarg $func_quote_for_eval_result"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_quote_for_eval "$lastarg"
+      base_compile="$base_compile $func_quote_for_eval_result"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      removelist="$removelist $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    removelist="$removelist $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$mode'"
+        ;;
+    esac
+
+    $ECHO
+    $ECHO "Try \`$progname --help' for more information about other modes."
+
+    exit $?
+}
+
+  # Now that we've collected a possible --mode arg, show help if necessary
+  $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_quote_for_eval "$file"
+      args="$args $func_quote_for_eval_result"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	$ECHO "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
+    $ECHO "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $ECHO "   $libdir"
+    done
+    $ECHO
+    $ECHO "If you ever happen to want to link against installed libraries"
+    $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+    $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $ECHO "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $ECHO "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $ECHO "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $ECHO "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $ECHO "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $ECHO "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $ECHO "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $ECHO "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $ECHO
+
+    $ECHO "See any operating system documentation about shared libraries for"
+    case $host in
+      solaris2.[6789]|solaris2.1[0-9])
+        $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	$ECHO "pages."
+	;;
+      *)
+        $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+        ;;
+    esac
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    install_prog="$install_prog$func_quote_for_eval_result"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	case " $install_prog " in
+	*[\\\ /]cp\ *) ;;
+	*) prev=$arg ;;
+	esac
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      install_prog="$install_prog $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_verbose "extracting global C symbols from \`$progfile'"
+	    $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+	  $opt_dry_run || {
+	    eval '$ECHO ": $name " >> "$nlist"'
+	    eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	  }
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+"
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc* )
+	    $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs.  */"
+	    lt_dlsym_const= ;;
+	  *osf5*)
+	    echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+	    lt_dlsym_const= ;;
+	  *)
+	    lt_dlsym_const=const ;;
+	  esac
+
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) symtab_cflags="$symtab_cflags $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+	func_emit_wrapper_part1_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_part1_arg1=$1
+	fi
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    ECHO=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$ECHO works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$ECHO will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$ECHO "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+	func_emit_wrapper_part2_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_part2_arg1=$1
+	fi
+
+	$ECHO "\
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2* | *-cegcc*)
+	  $ECHO "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $ECHO "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_arg1=$1
+	fi
+
+	# split this up so that func_emit_cwrapperexe_src
+	# can call each part independently.
+	func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+	func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+#    $build          $host
+#    mingw (msys)    mingw  [e.g. native]
+#    cygwin          mingw
+#    *nix + wine     mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin.  Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+  func_to_host_path_result="$1"
+  if test -n "$1" ; then
+    case $host in
+      *mingw* )
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+        case $build in
+          *mingw* ) # actually, msys
+            # awkward: cmd appends spaces to result
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+            func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          *cygwin* )
+            func_to_host_path_tmp1=`cygpath -w "$1"`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          * )
+            # Unfortunately, winepath does not exit with a non-zero
+            # error code, so we are forced to check the contents of
+            # stdout. On the other hand, if the command is not
+            # found, the shell will set an exit code of 127 and print
+            # *an error message* to stdout. So we must check for both
+            # error code of zero AND non-empty stdout, which explains
+            # the odd construction:
+            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+              func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+                $SED -e "$lt_sed_naive_backslashify"`
+            else
+              # Allow warning below.
+              func_to_host_path_result=""
+            fi
+            ;;
+        esac
+        if test -z "$func_to_host_path_result" ; then
+          func_error "Could not determine host path corresponding to"
+          func_error "  '$1'"
+          func_error "Continuing, but uninstalled executables may not work."
+          # Fallback:
+          func_to_host_path_result="$1"
+        fi
+        ;;
+    esac
+  fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+#    $build          $host
+#    mingw (msys)    mingw  [e.g. native]
+#    cygwin          mingw
+#    *nix + wine     mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+  func_to_host_pathlist_result="$1"
+  if test -n "$1" ; then
+    case $host in
+      *mingw* )
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+        # Remove leading and trailing path separator characters from
+        # ARG. msys behavior is inconsistent here, cygpath turns them
+        # into '.;' and ';.', and winepath ignores them completely.
+        func_to_host_pathlist_tmp2="$1"
+        # Once set for this call, this variable should not be
+        # reassigned. It is used in tha fallback case.
+        func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+          $SED -e 's|^:*||' -e 's|:*$||'`
+        case $build in
+          *mingw* ) # Actually, msys.
+            # Awkward: cmd appends spaces to result.
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+            func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          *cygwin* )
+            func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          * )
+            # unfortunately, winepath doesn't convert pathlists
+            func_to_host_pathlist_result=""
+            func_to_host_pathlist_oldIFS=$IFS
+            IFS=:
+            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+              IFS=$func_to_host_pathlist_oldIFS
+              if test -n "$func_to_host_pathlist_f" ; then
+                func_to_host_path "$func_to_host_pathlist_f"
+                if test -n "$func_to_host_path_result" ; then
+                  if test -z "$func_to_host_pathlist_result" ; then
+                    func_to_host_pathlist_result="$func_to_host_path_result"
+                  else
+                    func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+                  fi
+                fi
+              fi
+              IFS=:
+            done
+            IFS=$func_to_host_pathlist_oldIFS
+            ;;
+        esac
+        if test -z "$func_to_host_pathlist_result" ; then
+          func_error "Could not determine the host path(s) corresponding to"
+          func_error "  '$1'"
+          func_error "Continuing, but uninstalled executables may not work."
+          # Fallback. This may break if $1 contains DOS-style drive
+          # specifications. The fix is not to complicate the expression
+          # below, but for the user to provide a working wine installation
+          # with winepath so that path translation in the cross-to-mingw
+          # case works properly.
+          lt_replace_pathsep_nix_to_dos="s|:|;|g"
+          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+            $SED -e "$lt_replace_pathsep_nix_to_dos"`
+        fi
+        # Now, add the leading and trailing path separators back
+        case "$1" in
+          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+            ;;
+        esac
+        case "$1" in
+          *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+            ;;
+        esac
+        ;;
+    esac
+  fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "$SHELL $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+	    cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+#  define HAVE_SETENV
+#  ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+#  endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+    va_list args;
+    va_start (args, fmt);
+    (void) vfprintf (stderr, fmt, args);
+    va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+	    func_emit_wrapper_part1 yes |
+	        $SED -e 's/\([\\"]\)/\\\1/g' \
+	             -e 's/^/  "/' -e 's/$/\\n"/'
+	    echo ";"
+	    cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+	    func_emit_wrapper_part2 yes |
+	        $SED -e 's/\([\\"]\)/\\\1/g' \
+	             -e 's/^/  "/' -e 's/$/\\n"/'
+	    echo ";"
+
+	    cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_pathlist "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_pathlist "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH  5
+
+static const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX "env-set";
+  /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX "env-prepend";
+  /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX "env-append";
+  /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  LTWRAPPER_DEBUGPRINTF (("(main) argv[0]      : %s\n", argv[0]));
+  LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+  /* very simple arg parsing; don't want to rely on getopt */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  printf ("%s", script_text_part1);
+	  printf ("%s", script_text_part2);
+	  return 0;
+	}
+    }
+
+  newargz = XMALLOC (char *, argc + 1);
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal ("Couldn't find %s", argv[0]);
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+			  tmp_pathspec));
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+			  actual_cwrapper_path));
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+			  target_name));
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+        {
+          if (argv[i][env_set_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_set_opt_len + 1;
+              lt_opt_process_env_set (p);
+            }
+          else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_set (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_set_opt);
+          continue;
+        }
+      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+        {
+          if (argv[i][env_prepend_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_prepend_opt_len + 1;
+              lt_opt_process_env_prepend (p);
+            }
+          else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_prepend_opt);
+          continue;
+        }
+      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+        {
+          if (argv[i][env_append_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_append_opt_len + 1;
+              lt_opt_process_env_append (p);
+            }
+          else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_append (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_append_opt);
+          continue;
+        }
+      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal ("Unrecognized option in %s namespace: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+  for (i = 0; i < newargc; i++)
+    {
+      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  LTWRAPPER_DEBUGPRINTF (("(check_executable)  : %s\n",
+			  path ? (*path ? path : "EMPTY!") : "NULL!"));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  LTWRAPPER_DEBUGPRINTF (("(make_executable)   : %s\n",
+			  path ? (*path ? path : "EMPTY!") : "NULL!"));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  LTWRAPPER_DEBUGPRINTF (("(find_executable)   : %s\n",
+			  wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal ("getcwd failed");
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+			      tmp_pathspec));
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  char *errstr = strerror (errno);
+	  lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal ("Could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+  const char *p;
+  int len;
+  if (!arg || !*arg)
+    return 1;
+
+  p = strchr (arg, (int)'=');
+
+  if (!p)
+    return 1;
+
+  *value = xstrdup (++p);
+
+  len = strlen (arg) - strlen (*value);
+  *name = XMALLOC (char, len);
+  strncpy (*name, arg, len-1);
+  (*name)[len - 1] = '\0';
+
+  return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+    }
+
+  lt_setenv (name, value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 0);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 1);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  weak_libs="$weak_libs $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname '-L' '' "$arg"
+	dir=$func_stripname_result
+	if test -z "$dir"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot)
+	compiler_flags="$compiler_flags $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	compiler_flags="$compiler_flags $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  arg="$arg $wl$func_quote_for_eval_result"
+	  compiler_flags="$compiler_flags $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  arg="$arg $wl$func_quote_for_eval_result"
+	  compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+	  linker_flags="$linker_flags $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -F/path gives path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_duplicate_deps ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  case $lib in
+	  *.la)	func_source "$lib" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+            deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) deplibs="$deplibs $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    compiler_flags="$compiler_flags $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    newlib_search_path="$newlib_search_path $func_stripname_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    newlib_search_path="$newlib_search_path $func_stripname_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    dir=$func_stripname_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		$ECHO
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because the file extensions .$libext of this argument makes me believe"
+		$ECHO "*** that it is just a static archive that I should not use here."
+	      else
+		$ECHO
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	    # Keep a list of preopened convenience libraries to check
+	    # that they are being used correctly in the link pass.
+	    test -z "$libdir" && \
+		dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         newlib_search_path="$newlib_search_path $func_stripname_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) temp_rpath="$temp_rpath$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      notinst_deplibs="$notinst_deplibs $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      notinst_deplibs="$notinst_deplibs $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    $ECHO
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  $ECHO
+			  $ECHO "*** And there doesn't seem to be a static archive available"
+			  $ECHO "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    $ECHO
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    $ECHO "*** I have the capability to make that library automatically link in when"
+	    $ECHO "*** you link to this library.  But I can only do this if you have a"
+	    $ECHO "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      $ECHO "*** But as you try to build a module library, libtool will still create "
+	      $ECHO "*** a static module, that should work as long as the dlopening application"
+	      $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		$ECHO
+		$ECHO "*** However, this would only work if libtool was able to extract symbol"
+		$ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		$ECHO "*** not find such a program.  So, this module is probably useless."
+		$ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_dirname "$deplib" "" "."
+		dir="$func_dirname_result"
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  tmp_libs="$tmp_libs $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  $ECHO
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      libobjs="$libobjs $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       removelist="$removelist $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+      #	deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    newdeplibs="$newdeplibs $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    $ECHO
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    $ECHO "*** I have the capability to make that library automatically link in when"
+		    $ECHO "*** you link to this library.  But I can only do this if you have a"
+		    $ECHO "*** shared version of the library, which I believe you do not have"
+		    $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+		    $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		newdeplibs="$newdeplibs $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      newdeplibs="$newdeplibs $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      newdeplibs="$newdeplibs $i"
+		    else
+		      droppeddeps=yes
+		      $ECHO
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      $ECHO "*** I have the capability to make that library automatically link in when"
+		      $ECHO "*** you link to this library.  But I can only do this if you have a"
+		      $ECHO "*** shared version of the library, which you do not appear to have"
+		      $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+		      $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  $ECHO
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  $ECHO "*** make it link in!  You will probably need to install it or some"
+		  $ECHO "*** library that it depends on before this library will be fully"
+		  $ECHO "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		newdeplibs="$newdeplibs $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$ECHO
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      newdeplibs="$newdeplibs $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$ECHO
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+	      -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+	    done
+	  fi
+	  if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[	 ]//g' |
+	     $GREP . >/dev/null; then
+	    $ECHO
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    $ECHO "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    $ECHO
+	    $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    $ECHO "*** a static module, that should work as long as the dlopening"
+	    $ECHO "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      $ECHO
+	      $ECHO "*** However, this would only work if libtool was able to extract symbol"
+	      $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      $ECHO "*** not find such a program.  So, this module is probably useless."
+	      $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    $ECHO "*** The inter-library dependencies that have been dropped here will be"
+	    $ECHO "*** automatically added whenever a program is linked with this library"
+	    $ECHO "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      $ECHO
+	      $ECHO "*** Since this library must not contain undefined symbols,"
+	      $ECHO "*** because either the platform does not support them or"
+	      $ECHO "*** it was explicitly requested with -no-undefined,"
+	      $ECHO "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  delfiles="$delfiles $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      eval cmd=\"$cmd\"
+	      func_len " $cmd"
+	      len=$func_len_result
+	      if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    tmp_deplibs="$tmp_deplibs $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    libobjs="$libobjs $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    $ECHO 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      $ECHO "$obj" >> $output
+	    done
+	    $ECHO ')' >> $output
+	    delfiles="$delfiles $output"
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      $ECHO "$obj" >> $output
+	    done
+	    delfiles="$delfiles $output"
+	    output=$firstobj\"$file_list_spec$output\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=$obj
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      delfiles="$delfiles $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  libobjs="$libobjs $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      compile_command="$compile_command ${wl}-bind_at_load"
+	      finalize_command="$finalize_command ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *cegcc)
+        # Disable wrappers for cegcc, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $ECHO for shipping.
+      if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+	case $progpath in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+	esac
+	qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    oldobjs="$oldobjs $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	generated="$generated $gentop"
+
+	func_extract_archives $gentop $addlibs
+	oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  oldobjs="$oldobjs $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  $ECHO "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      oldobjs="$oldobjs $gentop/$newobj"
+	      ;;
+	    *) oldobjs="$oldobjs $obj" ;;
+	    esac
+	  done
+	fi
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		newdlfiles="$newdlfiles $libdir/$name"
+		;;
+	      *) newdlfiles="$newdlfiles $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		newdlprefiles="$newdlprefiles $libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlfiles="$newdlfiles $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlprefiles="$newdlprefiles $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) RM="$RM $arg"; rmforce=yes ;;
+      -*) RM="$RM $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	objdir="$origobjdir"
+      else
+	objdir="$dir/$origobjdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+	  case "$mode" in
+	  clean)
+	    case "  $library_names " in
+	    # "  " in the beginning catches empty $dlname
+	    *" $dlname "*) ;;
+	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    rmfiles="$rmfiles $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      rmfiles="$rmfiles $objdir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/src/missing b/src/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/src/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/mkinstalldirs b/src/mkinstalldirs
new file mode 100755
index 0000000..4191a45
--- /dev/null
+++ b/src/mkinstalldirs
@@ -0,0 +1,162 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2009-04-28.21; # UTC
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+IFS=" ""	$nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  case $file in
+    /*) pathcomp=/ ;;
+    *)  pathcomp= ;;
+  esac
+  oIFS=$IFS
+  IFS=/
+  set fnord $file
+  shift
+  IFS=$oIFS
+
+  for d
+  do
+    test "x$d" = x && continue
+
+    pathcomp=$pathcomp$d
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp=$pathcomp/
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/parser.c b/src/parser.c
new file mode 100644
index 0000000..6ee5537
--- /dev/null
+++ b/src/parser.c
@@ -0,0 +1,15014 @@
+/*
+ * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
+ *            implemented on top of the SAX interfaces
+ *
+ * References:
+ *   The XML specification:
+ *     http://www.w3.org/TR/REC-xml
+ *   Original 1.0 version:
+ *     http://www.w3.org/TR/1998/REC-xml-19980210
+ *   XML second edition working draft
+ *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
+ *
+ * Okay this is a big file, the parser core is around 7000 lines, then it
+ * is followed by the progressive parser top routines, then the various
+ * high level APIs to call the parser and a few miscellaneous functions.
+ * A number of helper functions and deprecated ones have been moved to
+ * parserInternals.c to reduce this file size.
+ * As much as possible the functions are associated with their relative
+ * production in the XML specification. A few productions defining the
+ * different ranges of character are actually implanted either in 
+ * parserInternals.h or parserInternals.c
+ * The DOM tree build is realized from the default SAX callbacks in
+ * the module SAX.c.
+ * The routines doing the validation checks are in valid.c and called either
+ * from the SAX callbacks or as standalone functions using a preparsed
+ * document.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#if defined(WIN32) && !defined (__CYGWIN__)
+#define XML_DIR_SEP '\\'
+#else
+#define XML_DIR_SEP '/'
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/valid.h>
+#include <libxml/entities.h>
+#include <libxml/xmlerror.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+#include <libxml/uri.h>
+#ifdef LIBXML_CATALOG_ENABLED
+#include <libxml/catalog.h>
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/xmlschemastypes.h>
+#include <libxml/relaxng.h>
+#endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.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		*
+ *									*
+ ************************************************************************/
+
+#define XML_PARSER_BIG_ENTITY 1000
+#define XML_PARSER_LOT_ENTITY 5000
+
+/*
+ * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
+ *    replacement over the size in byte of the input indicates that you have
+ *    and eponential behaviour. A value of 10 correspond to at least 3 entity
+ *    replacement per byte of input.
+ */
+#define XML_PARSER_NON_LINEAR 10
+
+/*
+ * xmlParserEntityCheck
+ *
+ * Function to check non-linear entity expansion behaviour
+ * This is here to detect and stop exponential linear entity expansion
+ * This is not a limitation of the parser but a safety
+ * boundary feature. It can be disabled with the XML_PARSE_HUGE
+ * parser option.
+ */
+static int
+xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
+                     xmlEntityPtr ent)
+{
+    unsigned long consumed = 0;
+
+    if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
+        return (0);
+    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
+        return (1);
+    if (size != 0) {
+        /*
+         * Do the check based on the replacement size of the entity
+         */
+        if (size < XML_PARSER_BIG_ENTITY)
+	    return(0);
+
+        /*
+         * A limit on the amount of text data reasonably used
+         */
+        if (ctxt->input != NULL) {
+            consumed = ctxt->input->consumed +
+                (ctxt->input->cur - ctxt->input->base);
+        }
+        consumed += ctxt->sizeentities;
+
+        if ((size < XML_PARSER_NON_LINEAR * consumed) &&
+	    (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
+            return (0);
+    } else if (ent != NULL) {
+        /*
+         * use the number of parsed entities in the replacement
+         */
+        size = ent->checked;
+
+        /*
+         * The amount of data parsed counting entities size only once
+         */
+        if (ctxt->input != NULL) {
+            consumed = ctxt->input->consumed +
+                (ctxt->input->cur - ctxt->input->base);
+        }
+        consumed += ctxt->sizeentities;
+
+        /*
+         * Check the density of entities for the amount of data
+	 * knowing an entity reference will take at least 3 bytes
+         */
+        if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
+            return (0);
+    } else {
+        /*
+         * strange we got no data for checking just return
+         */
+        return (0);
+    }
+
+    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+    return (1);
+}
+
+/**
+ * xmlParserMaxDepth:
+ *
+ * arbitrary depth limit for the XML documents that we allow to
+ * process. This is not a limitation of the parser but a safety
+ * boundary feature. It can be disabled with the XML_PARSE_HUGE
+ * parser option.
+ */
+unsigned int xmlParserMaxDepth = 256;
+
+
+
+#define SAX2 1
+#define XML_PARSER_BIG_BUFFER_SIZE 300
+#define XML_PARSER_BUFFER_SIZE 100
+#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
+
+/*
+ * List of XML prefixed PI allowed by W3C specs
+ */
+
+static const char *xmlW3CPIs[] = {
+    "xml-stylesheet",
+    NULL
+};
+
+
+/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
+static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
+                                              const xmlChar **str);
+
+static xmlParserErrors
+xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
+	              xmlSAXHandlerPtr sax,
+		      void *user_data, int depth, const xmlChar *URL,
+		      const xmlChar *ID, xmlNodePtr *list);
+
+static int
+xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
+                          const char *encoding);
+#ifdef LIBXML_LEGACY_ENABLED
+static void
+xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
+                      xmlNodePtr lastNode);
+#endif /* LIBXML_LEGACY_ENABLED */
+
+static xmlParserErrors
+xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
+		      const xmlChar *string, void *user_data, xmlNodePtr *lst);
+
+static int
+xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
+
+/************************************************************************
+ *									*
+ * 		Some factorized error routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlErrAttributeDup:
+ * @ctxt:  an XML parser context
+ * @prefix:  the attribute prefix
+ * @localname:  the attribute localname
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
+                   const xmlChar * localname)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL)
+	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
+
+    if (prefix == NULL)
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+                        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,
+                        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);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlFatalErr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @extra:  extra information string
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
+{
+    const char *errmsg;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    switch (error) {
+        case XML_ERR_INVALID_HEX_CHARREF:
+            errmsg = "CharRef: invalid hexadecimal value\n";
+            break;
+        case XML_ERR_INVALID_DEC_CHARREF:
+            errmsg = "CharRef: invalid decimal value\n";
+            break;
+        case XML_ERR_INVALID_CHARREF:
+            errmsg = "CharRef: invalid value\n";
+            break;
+        case XML_ERR_INTERNAL_ERROR:
+            errmsg = "internal error";
+            break;
+        case XML_ERR_PEREF_AT_EOF:
+            errmsg = "PEReference at end of document\n";
+            break;
+        case XML_ERR_PEREF_IN_PROLOG:
+            errmsg = "PEReference in prolog\n";
+            break;
+        case XML_ERR_PEREF_IN_EPILOG:
+            errmsg = "PEReference in epilog\n";
+            break;
+        case XML_ERR_PEREF_NO_NAME:
+            errmsg = "PEReference: no name\n";
+            break;
+        case XML_ERR_PEREF_SEMICOL_MISSING:
+            errmsg = "PEReference: expecting ';'\n";
+            break;
+        case XML_ERR_ENTITY_LOOP:
+            errmsg = "Detected an entity reference loop\n";
+            break;
+        case XML_ERR_ENTITY_NOT_STARTED:
+            errmsg = "EntityValue: \" or ' expected\n";
+            break;
+        case XML_ERR_ENTITY_PE_INTERNAL:
+            errmsg = "PEReferences forbidden in internal subset\n";
+            break;
+        case XML_ERR_ENTITY_NOT_FINISHED:
+            errmsg = "EntityValue: \" or ' expected\n";
+            break;
+        case XML_ERR_ATTRIBUTE_NOT_STARTED:
+            errmsg = "AttValue: \" or ' expected\n";
+            break;
+        case XML_ERR_LT_IN_ATTRIBUTE:
+            errmsg = "Unescaped '<' not allowed in attributes values\n";
+            break;
+        case XML_ERR_LITERAL_NOT_STARTED:
+            errmsg = "SystemLiteral \" or ' expected\n";
+            break;
+        case XML_ERR_LITERAL_NOT_FINISHED:
+            errmsg = "Unfinished System or Public ID \" or ' expected\n";
+            break;
+        case XML_ERR_MISPLACED_CDATA_END:
+            errmsg = "Sequence ']]>' not allowed in content\n";
+            break;
+        case XML_ERR_URI_REQUIRED:
+            errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
+            break;
+        case XML_ERR_PUBID_REQUIRED:
+            errmsg = "PUBLIC, the Public Identifier is missing\n";
+            break;
+        case XML_ERR_HYPHEN_IN_COMMENT:
+            errmsg = "Comment must not contain '--' (double-hyphen)\n";
+            break;
+        case XML_ERR_PI_NOT_STARTED:
+            errmsg = "xmlParsePI : no target name\n";
+            break;
+        case XML_ERR_RESERVED_XML_NAME:
+            errmsg = "Invalid PI name\n";
+            break;
+        case XML_ERR_NOTATION_NOT_STARTED:
+            errmsg = "NOTATION: Name expected here\n";
+            break;
+        case XML_ERR_NOTATION_NOT_FINISHED:
+            errmsg = "'>' required to close NOTATION declaration\n";
+            break;
+        case XML_ERR_VALUE_REQUIRED:
+            errmsg = "Entity value required\n";
+            break;
+        case XML_ERR_URI_FRAGMENT:
+            errmsg = "Fragment not allowed";
+            break;
+        case XML_ERR_ATTLIST_NOT_STARTED:
+            errmsg = "'(' required to start ATTLIST enumeration\n";
+            break;
+        case XML_ERR_NMTOKEN_REQUIRED:
+            errmsg = "NmToken expected in ATTLIST enumeration\n";
+            break;
+        case XML_ERR_ATTLIST_NOT_FINISHED:
+            errmsg = "')' required to finish ATTLIST enumeration\n";
+            break;
+        case XML_ERR_MIXED_NOT_STARTED:
+            errmsg = "MixedContentDecl : '|' or ')*' expected\n";
+            break;
+        case XML_ERR_PCDATA_REQUIRED:
+            errmsg = "MixedContentDecl : '#PCDATA' expected\n";
+            break;
+        case XML_ERR_ELEMCONTENT_NOT_STARTED:
+            errmsg = "ContentDecl : Name or '(' expected\n";
+            break;
+        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
+            errmsg = "ContentDecl : ',' '|' or ')' expected\n";
+            break;
+        case XML_ERR_PEREF_IN_INT_SUBSET:
+            errmsg =
+                "PEReference: forbidden within markup decl in internal subset\n";
+            break;
+        case XML_ERR_GT_REQUIRED:
+            errmsg = "expected '>'\n";
+            break;
+        case XML_ERR_CONDSEC_INVALID:
+            errmsg = "XML conditional section '[' expected\n";
+            break;
+        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
+            errmsg = "Content error in the external subset\n";
+            break;
+        case XML_ERR_CONDSEC_INVALID_KEYWORD:
+            errmsg =
+                "conditional section INCLUDE or IGNORE keyword expected\n";
+            break;
+        case XML_ERR_CONDSEC_NOT_FINISHED:
+            errmsg = "XML conditional section not closed\n";
+            break;
+        case XML_ERR_XMLDECL_NOT_STARTED:
+            errmsg = "Text declaration '<?xml' required\n";
+            break;
+        case XML_ERR_XMLDECL_NOT_FINISHED:
+            errmsg = "parsing XML declaration: '?>' expected\n";
+            break;
+        case XML_ERR_EXT_ENTITY_STANDALONE:
+            errmsg = "external parsed entities cannot be standalone\n";
+            break;
+        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
+            errmsg = "EntityRef: expecting ';'\n";
+            break;
+        case XML_ERR_DOCTYPE_NOT_FINISHED:
+            errmsg = "DOCTYPE improperly terminated\n";
+            break;
+        case XML_ERR_LTSLASH_REQUIRED:
+            errmsg = "EndTag: '</' not found\n";
+            break;
+        case XML_ERR_EQUAL_REQUIRED:
+            errmsg = "expected '='\n";
+            break;
+        case XML_ERR_STRING_NOT_CLOSED:
+            errmsg = "String not closed expecting \" or '\n";
+            break;
+        case XML_ERR_STRING_NOT_STARTED:
+            errmsg = "String not started expecting ' or \"\n";
+            break;
+        case XML_ERR_ENCODING_NAME:
+            errmsg = "Invalid XML encoding name\n";
+            break;
+        case XML_ERR_STANDALONE_VALUE:
+            errmsg = "standalone accepts only 'yes' or 'no'\n";
+            break;
+        case XML_ERR_DOCUMENT_EMPTY:
+            errmsg = "Document is empty\n";
+            break;
+        case XML_ERR_DOCUMENT_END:
+            errmsg = "Extra content at the end of the document\n";
+            break;
+        case XML_ERR_NOT_WELL_BALANCED:
+            errmsg = "chunk is not well balanced\n";
+            break;
+        case XML_ERR_EXTRA_CONTENT:
+            errmsg = "extra content at the end of well balanced chunk\n";
+            break;
+        case XML_ERR_VERSION_MISSING:
+            errmsg = "Malformed declaration expecting version\n";
+            break;
+#if 0
+        case:
+            errmsg = "\n";
+            break;
+#endif
+        default:
+            errmsg = "Unregistered error message\n";
+    }
+    if (ctxt != NULL)
+	ctxt->errNo = error;
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                    XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
+                    info);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlFatalErrMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+               const char *msg)
+{
+    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_PARSER, error,
+                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlWarningMsg:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  extra data
+ * @str2:  extra data
+ *
+ * Handle a warning.
+ */
+static void
+xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+              const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
+        (ctxt->sax->initialized == XML_SAX2_MAGIC))
+        schannel = ctxt->sax->serror;
+    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);
+    }
+}
+
+/**
+ * xmlValidityError:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  extra data
+ *
+ * Handle a validity error.
+ */
+static void
+xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+              const char *msg, const xmlChar *str1, const xmlChar *str2)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL) {
+	ctxt->errNo = error;
+	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
+	    schannel = ctxt->sax->serror;
+    }
+    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);
+	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);
+    }
+}
+
+/**
+ * xmlFatalErrMsgInt:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  an integer value
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+                  const char *msg, int val)
+{
+    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_PARSER, error, XML_ERR_FATAL,
+                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlFatalErrMsgStrIntStr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @str1:  an string info
+ * @val:  an integer value
+ * @str2:  an string info
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+                  const char *msg, const xmlChar *str1, int val, 
+		  const xmlChar *str2)
+{
+    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_PARSER, error, XML_ERR_FATAL,
+                    NULL, 0, (const char *) str1, (const char *) str2,
+		    NULL, val, 0, msg, str1, val, str2);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlFatalErrMsgStr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  a string value
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+                  const char *msg, const xmlChar * val)
+{
+    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_PARSER, error, XML_ERR_FATAL,
+                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
+                    val);
+    if (ctxt != NULL) {
+	ctxt->wellFormed = 0;
+	if (ctxt->recovery == 0)
+	    ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlErrMsgStr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  a string value
+ *
+ * Handle a non fatal parser error
+ */
+static void
+xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+                  const char *msg, const xmlChar * val)
+{
+    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_PARSER, error, XML_ERR_ERROR,
+                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
+                    val);
+}
+
+/**
+ * xmlNsErr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the message
+ * @info1:  extra information string
+ * @info2:  extra information string
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+         const char *msg,
+         const xmlChar * info1, const xmlChar * info2,
+         const xmlChar * info3)
+{
+    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_ERROR, NULL, 0, (const char *) info1,
+                    (const char *) info2, (const char *) info3, 0, 0, msg,
+                    info1, info2, info3);
+    if (ctxt != NULL)
+	ctxt->nsWellFormed = 0;
+}
+
+/**
+ * xmlNsWarn
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the message
+ * @info1:  extra information string
+ * @info2:  extra information string
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+static void
+xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+         const char *msg,
+         const xmlChar * info1, const xmlChar * info2,
+         const xmlChar * info3)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    __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,
+                    info1, info2, info3);
+}
+
+/************************************************************************
+ *									*
+ * 		Library wide options					*
+ *									*
+ ************************************************************************/
+
+/**
+  * xmlHasFeature:
+  * @feature: the feature to be examined
+  *
+  * Examines if the library has been compiled with a given feature.
+  *
+  * Returns a non-zero value if the feature exist, otherwise zero.
+  * Returns zero (0) if the feature does not exist or an unknown
+  * unknown feature is requested, non-zero otherwise.
+  */
+int
+xmlHasFeature(xmlFeature feature)
+{
+    switch (feature) {
+	case XML_WITH_THREAD:
+#ifdef LIBXML_THREAD_ENABLED
+	    return(1);
+#else
+	    return(0);
+#endif
+        case XML_WITH_TREE:
+#ifdef LIBXML_TREE_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_OUTPUT:
+#ifdef LIBXML_OUTPUT_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_PUSH:
+#ifdef LIBXML_PUSH_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_READER:
+#ifdef LIBXML_READER_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_PATTERN:
+#ifdef LIBXML_PATTERN_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_WRITER:
+#ifdef LIBXML_WRITER_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_SAX1:
+#ifdef LIBXML_SAX1_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_FTP:
+#ifdef LIBXML_FTP_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_HTTP:
+#ifdef LIBXML_HTTP_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_VALID:
+#ifdef LIBXML_VALID_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_HTML:
+#ifdef LIBXML_HTML_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_LEGACY:
+#ifdef LIBXML_LEGACY_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_C14N:
+#ifdef LIBXML_C14N_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_CATALOG:
+#ifdef LIBXML_CATALOG_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_XPATH:
+#ifdef LIBXML_XPATH_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_XPTR:
+#ifdef LIBXML_XPTR_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_XINCLUDE:
+#ifdef LIBXML_XINCLUDE_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_ICONV:
+#ifdef LIBXML_ICONV_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_ISO8859X:
+#ifdef LIBXML_ISO8859X_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_UNICODE:
+#ifdef LIBXML_UNICODE_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_REGEXP:
+#ifdef LIBXML_REGEXP_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_AUTOMATA:
+#ifdef LIBXML_AUTOMATA_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_EXPR:
+#ifdef LIBXML_EXPR_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_SCHEMAS:
+#ifdef LIBXML_SCHEMAS_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_SCHEMATRON:
+#ifdef LIBXML_SCHEMATRON_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_MODULES:
+#ifdef LIBXML_MODULES_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_DEBUG:
+#ifdef LIBXML_DEBUG_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_DEBUG_MEM:
+#ifdef DEBUG_MEMORY_LOCATION
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_DEBUG_RUN:
+#ifdef LIBXML_DEBUG_RUNTIME
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_ZLIB:
+#ifdef LIBXML_ZLIB_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        case XML_WITH_ICU:
+#ifdef LIBXML_ICU_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
+        default:
+	    break;
+     }
+     return(0);
+}
+
+/************************************************************************
+ *									*
+ * 		SAX2 defaulted attributes handling			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlDetectSAX2:
+ * @ctxt:  an XML parser context
+ *
+ * Do the SAX2 detection and specific intialization
+ */
+static void
+xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL) return;
+#ifdef LIBXML_SAX1_ENABLED
+    if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
+        ((ctxt->sax->startElementNs != NULL) ||
+         (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
+#else
+    ctxt->sax2 = 1;
+#endif /* LIBXML_SAX1_ENABLED */
+
+    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+    if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
+    		(ctxt->str_xml_ns == NULL)) {
+        xmlErrMemory(ctxt, NULL);
+    }
+}
+
+typedef struct _xmlDefAttrs xmlDefAttrs;
+typedef xmlDefAttrs *xmlDefAttrsPtr;
+struct _xmlDefAttrs {
+    int nbAttrs;	/* number of defaulted attributes on that element */
+    int maxAttrs;       /* the size of the array */
+    const xmlChar *values[5]; /* array of localname/prefix/values/external */
+};
+
+/**
+ * xmlAttrNormalizeSpace:
+ * @src: the source string
+ * @dst: the target string
+ *
+ * Normalize the space in non CDATA attribute values:
+ * If the attribute type is not CDATA, then the XML processor MUST further
+ * process the normalized attribute value by discarding any leading and
+ * trailing space (#x20) characters, and by replacing sequences of space
+ * (#x20) characters by a single space (#x20) character.
+ * Note that the size of dst need to be at least src, and if one doesn't need
+ * to preserve dst (and it doesn't come from a dictionary or read-only) then
+ * passing src as dst is just fine.
+ *
+ * Returns a pointer to the normalized value (dst) or NULL if no conversion
+ *         is needed.
+ */
+static xmlChar *
+xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
+{
+    if ((src == NULL) || (dst == NULL))
+        return(NULL);
+
+    while (*src == 0x20) src++;
+    while (*src != 0) {
+	if (*src == 0x20) {
+	    while (*src == 0x20) src++;
+	    if (*src != 0)
+		*dst++ = 0x20;
+	} else {
+	    *dst++ = *src++;
+	}
+    }
+    *dst = 0;
+    if (dst == src)
+       return(NULL);
+    return(dst);
+}
+
+/**
+ * xmlAttrNormalizeSpace2:
+ * @src: the source string
+ *
+ * Normalize the space in non CDATA attribute values, a slightly more complex
+ * front end to avoid allocation problems when running on attribute values
+ * coming from the input.
+ *
+ * Returns a pointer to the normalized value (dst) or NULL if no conversion
+ *         is needed.
+ */
+static const xmlChar *
+xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
+{
+    int i;
+    int remove_head = 0;
+    int need_realloc = 0;
+    const xmlChar *cur;
+
+    if ((ctxt == NULL) || (src == NULL) || (len == NULL))
+        return(NULL);
+    i = *len;
+    if (i <= 0)
+        return(NULL);
+
+    cur = src;
+    while (*cur == 0x20) {
+        cur++;
+	remove_head++;
+    }
+    while (*cur != 0) {
+	if (*cur == 0x20) {
+	    cur++;
+	    if ((*cur == 0x20) || (*cur == 0)) {
+	        need_realloc = 1;
+		break;
+	    }
+	} else
+	    cur++;
+    }
+    if (need_realloc) {
+        xmlChar *ret;
+
+	ret = xmlStrndup(src + remove_head, i - remove_head + 1);
+	if (ret == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    return(NULL);
+	}
+	xmlAttrNormalizeSpace(ret, ret);
+	*len = (int) strlen((const char *)ret);
+        return(ret);
+    } else if (remove_head) {
+        *len -= remove_head;
+        memmove(src, src + remove_head, 1 + *len);
+	return(src);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlAddDefAttrs:
+ * @ctxt:  an XML parser context
+ * @fullname:  the element fullname
+ * @fullattr:  the attribute fullname
+ * @value:  the attribute value
+ *
+ * Add a defaulted attribute for an element
+ */
+static void
+xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
+               const xmlChar *fullname,
+               const xmlChar *fullattr,
+               const xmlChar *value) {
+    xmlDefAttrsPtr defaults;
+    int len;
+    const xmlChar *name;
+    const xmlChar *prefix;
+
+    /*
+     * Allows to detect attribute redefinitions
+     */
+    if (ctxt->attsSpecial != NULL) {
+        if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
+	    return;
+    }
+
+    if (ctxt->attsDefault == NULL) {
+        ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
+	if (ctxt->attsDefault == NULL)
+	    goto mem_error;
+    }
+
+    /*
+     * split the element name into prefix:localname , the string found
+     * are within the DTD and then not associated to namespace names.
+     */
+    name = xmlSplitQName3(fullname, &len);
+    if (name == NULL) {
+        name = xmlDictLookup(ctxt->dict, fullname, -1);
+	prefix = NULL;
+    } else {
+        name = xmlDictLookup(ctxt->dict, name, -1);
+	prefix = xmlDictLookup(ctxt->dict, fullname, len);
+    }
+
+    /*
+     * make sure there is some storage
+     */
+    defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
+    if (defaults == NULL) {
+        defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
+	                   (4 * 5) * sizeof(const xmlChar *));
+	if (defaults == NULL)
+	    goto mem_error;
+	defaults->nbAttrs = 0;
+	defaults->maxAttrs = 4;
+	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
+	                        defaults, NULL) < 0) {
+	    xmlFree(defaults);
+	    goto mem_error;
+	}
+    } else if (defaults->nbAttrs >= defaults->maxAttrs) {
+        xmlDefAttrsPtr temp;
+
+        temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
+		       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
+	if (temp == NULL)
+	    goto mem_error;
+	defaults = temp;
+	defaults->maxAttrs *= 2;
+	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
+	                        defaults, NULL) < 0) {
+	    xmlFree(defaults);
+	    goto mem_error;
+	}
+    }
+
+    /*
+     * Split the element name into prefix:localname , the string found
+     * are within the DTD and hen not associated to namespace names.
+     */
+    name = xmlSplitQName3(fullattr, &len);
+    if (name == NULL) {
+        name = xmlDictLookup(ctxt->dict, fullattr, -1);
+	prefix = NULL;
+    } else {
+        name = xmlDictLookup(ctxt->dict, name, -1);
+	prefix = xmlDictLookup(ctxt->dict, fullattr, len);
+    }
+
+    defaults->values[5 * defaults->nbAttrs] = name;
+    defaults->values[5 * defaults->nbAttrs + 1] = prefix;
+    /* intern the string and precompute the end */
+    len = xmlStrlen(value);
+    value = xmlDictLookup(ctxt->dict, value, len);
+    defaults->values[5 * defaults->nbAttrs + 2] = value;
+    defaults->values[5 * defaults->nbAttrs + 3] = value + len;
+    if (ctxt->external)
+        defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
+    else
+        defaults->values[5 * defaults->nbAttrs + 4] = NULL;
+    defaults->nbAttrs++;
+
+    return;
+
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return;
+}
+
+/**
+ * xmlAddSpecialAttr:
+ * @ctxt:  an XML parser context
+ * @fullname:  the element fullname
+ * @fullattr:  the attribute fullname
+ * @type:  the attribute type
+ *
+ * Register this attribute type
+ */
+static void
+xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
+		  const xmlChar *fullname,
+		  const xmlChar *fullattr,
+		  int type)
+{
+    if (ctxt->attsSpecial == NULL) {
+        ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
+	if (ctxt->attsSpecial == NULL)
+	    goto mem_error;
+    }
+
+    if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
+        return;
+
+    xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
+                     (void *) (long) type);
+    return;
+
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return;
+}
+
+/**
+ * xmlCleanSpecialAttrCallback:
+ *
+ * Removes CDATA attributes from the special attribute table
+ */
+static void
+xmlCleanSpecialAttrCallback(void *payload, void *data,
+                            const xmlChar *fullname, const xmlChar *fullattr,
+                            const xmlChar *unused ATTRIBUTE_UNUSED) {
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
+
+    if (((long) payload) == XML_ATTRIBUTE_CDATA) {
+        xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
+    }
+}
+
+/**
+ * xmlCleanSpecialAttr:
+ * @ctxt:  an XML parser context
+ *
+ * Trim the list of attributes defined to remove all those of type
+ * CDATA as they are not special. This call should be done when finishing
+ * to parse the DTD and before starting to parse the document root.
+ */
+static void
+xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
+{
+    if (ctxt->attsSpecial == NULL)
+        return;
+
+    xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
+
+    if (xmlHashSize(ctxt->attsSpecial) == 0) {
+        xmlHashFree(ctxt->attsSpecial, NULL);
+        ctxt->attsSpecial = NULL;
+    }
+    return;
+}
+
+/**
+ * xmlCheckLanguageID:
+ * @lang:  pointer to the string value
+ *
+ * Checks that the value conforms to the LanguageID production:
+ *
+ * NOTE: this is somewhat deprecated, those productions were removed from
+ *       the XML Second edition.
+ *
+ * [33] LanguageID ::= Langcode ('-' Subcode)*
+ * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
+ * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
+ * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
+ * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
+ * [38] Subcode ::= ([a-z] | [A-Z])+
+ *
+ * Returns 1 if correct 0 otherwise
+ **/
+int
+xmlCheckLanguageID(const xmlChar * lang)
+{
+    const xmlChar *cur = lang;
+
+    if (cur == NULL)
+        return (0);
+    if (((cur[0] == 'i') && (cur[1] == '-')) ||
+        ((cur[0] == 'I') && (cur[1] == '-'))) {
+        /*
+         * IANA code
+         */
+        cur += 2;
+        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
+               ((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 (1);
+}
+
+/************************************************************************
+ *									*
+ *		Parser stacks related functions and macros		*
+ *									*
+ ************************************************************************/
+
+static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
+                                            const xmlChar ** str);
+
+#ifdef SAX2
+/**
+ * nsPush:
+ * @ctxt:  an XML parser context
+ * @prefix:  the namespace prefix or NULL
+ * @URL:  the namespace name
+ *
+ * Pushes a new parser namespace on top of the ns stack
+ *
+ * Returns -1 in case of error, -2 if the namespace should be discarded
+ *	   and the index in the stack otherwise.
+ */
+static int
+nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
+{
+    if (ctxt->options & XML_PARSE_NSCLEAN) {
+        int i;
+	for (i = 0;i < ctxt->nsNr;i += 2) {
+	    if (ctxt->nsTab[i] == prefix) {
+		/* in scope */
+	        if (ctxt->nsTab[i + 1] == URL)
+		    return(-2);
+		/* out of scope keep it */
+		break;
+	    }
+	}
+    }
+    if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
+	ctxt->nsMax = 10;
+	ctxt->nsNr = 0;
+	ctxt->nsTab = (const xmlChar **)
+	              xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
+	if (ctxt->nsTab == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    ctxt->nsMax = 0;
+            return (-1);
+	}
+    } else if (ctxt->nsNr >= ctxt->nsMax) {
+        const xmlChar ** tmp;
+        ctxt->nsMax *= 2;
+        tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
+				    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
+        if (tmp == NULL) {
+            xmlErrMemory(ctxt, NULL);
+	    ctxt->nsMax /= 2;
+            return (-1);
+        }
+	ctxt->nsTab = tmp;
+    }
+    ctxt->nsTab[ctxt->nsNr++] = prefix;
+    ctxt->nsTab[ctxt->nsNr++] = URL;
+    return (ctxt->nsNr);
+}
+/**
+ * nsPop:
+ * @ctxt: an XML parser context
+ * @nr:  the number to pop
+ *
+ * Pops the top @nr parser prefix/namespace from the ns stack
+ *
+ * Returns the number of namespaces removed
+ */
+static int
+nsPop(xmlParserCtxtPtr ctxt, int nr)
+{
+    int i;
+
+    if (ctxt->nsTab == NULL) return(0);
+    if (ctxt->nsNr < nr) {
+        xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
+        nr = ctxt->nsNr;
+    }
+    if (ctxt->nsNr <= 0)
+        return (0);
+
+    for (i = 0;i < nr;i++) {
+         ctxt->nsNr--;
+	 ctxt->nsTab[ctxt->nsNr] = NULL;
+    }
+    return(nr);
+}
+#endif
+
+static int
+xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
+    const xmlChar **atts;
+    int *attallocs;
+    int maxatts;
+
+    if (ctxt->atts == NULL) {
+	maxatts = 55; /* allow for 10 attrs by default */
+	atts = (const xmlChar **)
+	       xmlMalloc(maxatts * sizeof(xmlChar *));
+	if (atts == NULL) goto mem_error;
+	ctxt->atts = atts;
+	attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
+	if (attallocs == NULL) goto mem_error;
+	ctxt->attallocs = attallocs;
+	ctxt->maxatts = maxatts;
+    } else if (nr + 5 > ctxt->maxatts) {
+	maxatts = (nr + 5) * 2;
+	atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
+				     maxatts * sizeof(const xmlChar *));
+	if (atts == NULL) goto mem_error;
+	ctxt->atts = atts;
+	attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
+	                             (maxatts / 5) * sizeof(int));
+	if (attallocs == NULL) goto mem_error;
+	ctxt->attallocs = attallocs;
+	ctxt->maxatts = maxatts;
+    }
+    return(ctxt->maxatts);
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return(-1);
+}
+
+/**
+ * inputPush:
+ * @ctxt:  an XML parser context
+ * @value:  the parser input
+ *
+ * Pushes a new parser input on top of the input stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+int
+inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
+{
+    if ((ctxt == NULL) || (value == NULL))
+        return(-1);
+    if (ctxt->inputNr >= ctxt->inputMax) {
+        ctxt->inputMax *= 2;
+        ctxt->inputTab =
+            (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
+                                             ctxt->inputMax *
+                                             sizeof(ctxt->inputTab[0]));
+        if (ctxt->inputTab == NULL) {
+            xmlErrMemory(ctxt, NULL);
+	    xmlFreeInputStream(value);
+	    ctxt->inputMax /= 2;
+	    value = NULL;
+            return (-1);
+        }
+    }
+    ctxt->inputTab[ctxt->inputNr] = value;
+    ctxt->input = value;
+    return (ctxt->inputNr++);
+}
+/**
+ * inputPop:
+ * @ctxt: an XML parser context
+ *
+ * Pops the top parser input from the input stack
+ *
+ * Returns the input just removed
+ */
+xmlParserInputPtr
+inputPop(xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr ret;
+
+    if (ctxt == NULL)
+        return(NULL);
+    if (ctxt->inputNr <= 0)
+        return (NULL);
+    ctxt->inputNr--;
+    if (ctxt->inputNr > 0)
+        ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
+    else
+        ctxt->input = NULL;
+    ret = ctxt->inputTab[ctxt->inputNr];
+    ctxt->inputTab[ctxt->inputNr] = NULL;
+    return (ret);
+}
+/**
+ * nodePush:
+ * @ctxt:  an XML parser context
+ * @value:  the element node
+ *
+ * Pushes a new element node on top of the node stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+int
+nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
+{
+    if (ctxt == NULL) return(0);
+    if (ctxt->nodeNr >= ctxt->nodeMax) {
+        xmlNodePtr *tmp;
+
+	tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
+                                      ctxt->nodeMax * 2 *
+                                      sizeof(ctxt->nodeTab[0]));
+        if (tmp == NULL) {
+            xmlErrMemory(ctxt, NULL);
+            return (-1);
+        }
+        ctxt->nodeTab = tmp;
+	ctxt->nodeMax *= 2;
+    }
+    if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
+        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
+		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
+			  xmlParserMaxDepth);
+	ctxt->instate = XML_PARSER_EOF;
+	return(-1);
+    }
+    ctxt->nodeTab[ctxt->nodeNr] = value;
+    ctxt->node = value;
+    return (ctxt->nodeNr++);
+}
+
+/**
+ * nodePop:
+ * @ctxt: an XML parser context
+ *
+ * Pops the top element node from the node stack
+ *
+ * Returns the node just removed
+ */
+xmlNodePtr
+nodePop(xmlParserCtxtPtr ctxt)
+{
+    xmlNodePtr ret;
+
+    if (ctxt == NULL) return(NULL);
+    if (ctxt->nodeNr <= 0)
+        return (NULL);
+    ctxt->nodeNr--;
+    if (ctxt->nodeNr > 0)
+        ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
+    else
+        ctxt->node = NULL;
+    ret = ctxt->nodeTab[ctxt->nodeNr];
+    ctxt->nodeTab[ctxt->nodeNr] = NULL;
+    return (ret);
+}
+
+#ifdef LIBXML_PUSH_ENABLED
+/**
+ * nameNsPush:
+ * @ctxt:  an XML parser context
+ * @value:  the element name
+ * @prefix:  the element prefix
+ * @URI:  the element namespace name
+ *
+ * Pushes a new element name/prefix/URL on top of the name stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+static int
+nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
+           const xmlChar *prefix, const xmlChar *URI, int nsNr)
+{
+    if (ctxt->nameNr >= ctxt->nameMax) {
+        const xmlChar * *tmp;
+        void **tmp2;
+        ctxt->nameMax *= 2;
+        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
+                                    ctxt->nameMax *
+                                    sizeof(ctxt->nameTab[0]));
+        if (tmp == NULL) {
+	    ctxt->nameMax /= 2;
+	    goto mem_error;
+        }
+	ctxt->nameTab = tmp;
+        tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
+                                    ctxt->nameMax * 3 *
+                                    sizeof(ctxt->pushTab[0]));
+        if (tmp2 == NULL) {
+	    ctxt->nameMax /= 2;
+	    goto mem_error;
+        }
+	ctxt->pushTab = tmp2;
+    }
+    ctxt->nameTab[ctxt->nameNr] = value;
+    ctxt->name = value;
+    ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
+    ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
+    ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
+    return (ctxt->nameNr++);
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return (-1);
+}
+/**
+ * nameNsPop:
+ * @ctxt: an XML parser context
+ *
+ * Pops the top element/prefix/URI name from the name stack
+ *
+ * Returns the name just removed
+ */
+static const xmlChar *
+nameNsPop(xmlParserCtxtPtr ctxt)
+{
+    const xmlChar *ret;
+
+    if (ctxt->nameNr <= 0)
+        return (NULL);
+    ctxt->nameNr--;
+    if (ctxt->nameNr > 0)
+        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
+    else
+        ctxt->name = NULL;
+    ret = ctxt->nameTab[ctxt->nameNr];
+    ctxt->nameTab[ctxt->nameNr] = NULL;
+    return (ret);
+}
+#endif /* LIBXML_PUSH_ENABLED */
+
+/**
+ * namePush:
+ * @ctxt:  an XML parser context
+ * @value:  the element name
+ *
+ * Pushes a new element name on top of the name stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+int
+namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
+{
+    if (ctxt == NULL) return (-1);
+
+    if (ctxt->nameNr >= ctxt->nameMax) {
+        const xmlChar * *tmp;
+        ctxt->nameMax *= 2;
+        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
+                                    ctxt->nameMax *
+                                    sizeof(ctxt->nameTab[0]));
+        if (tmp == NULL) {
+	    ctxt->nameMax /= 2;
+	    goto mem_error;
+        }
+	ctxt->nameTab = tmp;
+    }
+    ctxt->nameTab[ctxt->nameNr] = value;
+    ctxt->name = value;
+    return (ctxt->nameNr++);
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return (-1);
+}
+/**
+ * namePop:
+ * @ctxt: an XML parser context
+ *
+ * Pops the top element name from the name stack
+ *
+ * Returns the name just removed
+ */
+const xmlChar *
+namePop(xmlParserCtxtPtr ctxt)
+{
+    const xmlChar *ret;
+
+    if ((ctxt == NULL) || (ctxt->nameNr <= 0))
+        return (NULL);
+    ctxt->nameNr--;
+    if (ctxt->nameNr > 0)
+        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
+    else
+        ctxt->name = NULL;
+    ret = ctxt->nameTab[ctxt->nameNr];
+    ctxt->nameTab[ctxt->nameNr] = NULL;
+    return (ret);
+}
+
+static int spacePush(xmlParserCtxtPtr ctxt, int val) {
+    if (ctxt->spaceNr >= ctxt->spaceMax) {
+        int *tmp;
+
+	ctxt->spaceMax *= 2;
+        tmp = (int *) xmlRealloc(ctxt->spaceTab,
+	                         ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
+        if (tmp == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    ctxt->spaceMax /=2;
+	    return(-1);
+	}
+	ctxt->spaceTab = tmp;
+    }
+    ctxt->spaceTab[ctxt->spaceNr] = val;
+    ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
+    return(ctxt->spaceNr++);
+}
+
+static int spacePop(xmlParserCtxtPtr ctxt) {
+    int ret;
+    if (ctxt->spaceNr <= 0) return(0);
+    ctxt->spaceNr--;
+    if (ctxt->spaceNr > 0)
+	ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
+    else
+        ctxt->space = &ctxt->spaceTab[0];
+    ret = ctxt->spaceTab[ctxt->spaceNr];
+    ctxt->spaceTab[ctxt->spaceNr] = -1;
+    return(ret);
+}
+
+/*
+ * Macros for accessing the content. Those should be used only by the parser,
+ * and not exported.
+ *
+ * Dirty macros, i.e. one often need to make assumption on the context to
+ * use them
+ *
+ *   CUR_PTR return the current pointer to the xmlChar to be parsed.
+ *           To be used with extreme caution since operations consuming
+ *           characters may move the input buffer to a different location !
+ *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
+ *           This should be used internally by the parser
+ *           only to compare to ASCII values otherwise it would break when
+ *           running with UTF-8 encoding.
+ *   RAW     same as CUR but in the input buffer, bypass any token
+ *           extraction that may have been done
+ *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
+ *           to compare on ASCII based substring.
+ *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
+ *           strings without newlines within the parser.
+ *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
+ *           defined char within the parser.
+ * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
+ *
+ *   NEXT    Skip to the next character, this does the proper decoding
+ *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
+ *   NEXTL(l) Skip the current unicode character of l xmlChars long.
+ *   CUR_CHAR(l) returns the current unicode character (int), set l
+ *           to the number of xmlChars used for the encoding [0-5].
+ *   CUR_SCHAR  same but operate on a string instead of the context
+ *   COPY_BUF  copy the current unicode char to the target buffer, increment
+ *            the index
+ *   GROW, SHRINK  handling of input buffers
+ */
+
+#define RAW (*ctxt->input->cur)
+#define CUR (*ctxt->input->cur)
+#define NXT(val) ctxt->input->cur[(val)]
+#define CUR_PTR ctxt->input->cur
+
+#define CMP4( s, c1, c2, c3, c4 ) \
+  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
+    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
+#define CMP5( s, c1, c2, c3, c4, c5 ) \
+  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
+#define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
+  ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
+#define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
+  ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
+#define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
+  ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
+#define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
+  ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
+    ((unsigned char *) s)[ 8 ] == c9 )
+#define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
+  ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
+    ((unsigned char *) s)[ 9 ] == c10 )
+
+#define SKIP(val) do {							\
+    ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);			\
+    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
+    if ((*ctxt->input->cur == 0) &&					\
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
+	    xmlPopInput(ctxt);						\
+  } while (0)
+
+#define SKIPL(val) do {							\
+    int skipl;								\
+    for(skipl=0; skipl<val; skipl++) {					\
+    	if (*(ctxt->input->cur) == '\n') {				\
+	ctxt->input->line++; ctxt->input->col = 1;			\
+    	} else ctxt->input->col++;					\
+    	ctxt->nbChars++;						\
+	ctxt->input->cur++;						\
+    }									\
+    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
+    if ((*ctxt->input->cur == 0) &&					\
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
+	    xmlPopInput(ctxt);						\
+  } while (0)
+
+#define SHRINK if ((ctxt->progressive == 0) &&				\
+		   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
+		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
+	xmlSHRINK (ctxt);
+
+static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
+    xmlParserInputShrink(ctxt->input);
+    if ((*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
+	    xmlPopInput(ctxt);
+  }
+
+#define GROW if ((ctxt->progressive == 0) &&				\
+		 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))	\
+	xmlGROW (ctxt);
+
+static void xmlGROW (xmlParserCtxtPtr ctxt) {
+    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+    if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
+	    xmlPopInput(ctxt);
+}
+
+#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
+
+#define NEXT xmlNextChar(ctxt)
+
+#define NEXT1 {								\
+	ctxt->input->col++;						\
+	ctxt->input->cur++;						\
+	ctxt->nbChars++;						\
+	if (*ctxt->input->cur == 0)					\
+	    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);		\
+    }
+
+#define NEXTL(l) do {							\
+    if (*(ctxt->input->cur) == '\n') {					\
+	ctxt->input->line++; ctxt->input->col = 1;			\
+    } else ctxt->input->col++;						\
+    ctxt->input->cur += l;				\
+    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
+  } while (0)
+
+#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
+
+#define COPY_BUF(l,b,i,v)						\
+    if (l == 1) b[i++] = (xmlChar) v;					\
+    else i += xmlCopyCharMultiByte(&b[i],v)
+
+/**
+ * xmlSkipBlankChars:
+ * @ctxt:  the XML parser context
+ *
+ * skip all blanks character found at that point in the input streams.
+ * It pops up finished entities in the process if allowable at that point.
+ *
+ * Returns the number of space chars skipped
+ */
+
+int
+xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
+    int res = 0;
+
+    /*
+     * It's Okay to use CUR/NEXT here since all the blanks are on
+     * the ASCII range.
+     */
+    if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
+	const xmlChar *cur;
+	/*
+	 * if we are in the document content, go really fast
+	 */
+	cur = ctxt->input->cur;
+	while (IS_BLANK_CH(*cur)) {
+	    if (*cur == '\n') {
+		ctxt->input->line++; ctxt->input->col = 1;
+	    }
+	    cur++;
+	    res++;
+	    if (*cur == 0) {
+		ctxt->input->cur = cur;
+		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+		cur = ctxt->input->cur;
+	    }
+	}
+	ctxt->input->cur = cur;
+    } else {
+	int cur;
+	do {
+	    cur = CUR;
+	    while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
+		NEXT;
+		cur = CUR;
+		res++;
+	    }
+	    while ((cur == 0) && (ctxt->inputNr > 1) &&
+		   (ctxt->instate != XML_PARSER_COMMENT)) {
+		xmlPopInput(ctxt);
+		cur = CUR;
+	    }
+	    /*
+	     * Need to handle support of entities branching here
+	     */
+	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
+	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+    }
+    return(res);
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions to handle entities			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlPopInput:
+ * @ctxt:  an XML parser context
+ *
+ * xmlPopInput: the current input pointed by ctxt->input came to an end
+ *          pop it and return the next char.
+ *
+ * Returns the current xmlChar in the parser context
+ */
+xmlChar
+xmlPopInput(xmlParserCtxtPtr ctxt) {
+    if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"Popping input %d\n", ctxt->inputNr);
+    xmlFreeInputStream(inputPop(ctxt));
+    if ((*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
+	    return(xmlPopInput(ctxt));
+    return(CUR);
+}
+
+/**
+ * xmlPushInput:
+ * @ctxt:  an XML parser context
+ * @input:  an XML parser input fragment (entity, XML fragment ...).
+ *
+ * xmlPushInput: switch to a new input stream which is stacked on top
+ *               of the previous one(s).
+ * Returns -1 in case of error or the index in the input stack
+ */
+int
+xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
+    int ret;
+    if (input == NULL) return(-1);
+
+    if (xmlParserDebugEntities) {
+	if ((ctxt->input != NULL) && (ctxt->input->filename))
+	    xmlGenericError(xmlGenericErrorContext,
+		    "%s(%d): ", ctxt->input->filename,
+		    ctxt->input->line);
+	xmlGenericError(xmlGenericErrorContext,
+		"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
+    }
+    ret = inputPush(ctxt, input);
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(-1);
+    GROW;
+    return(ret);
+}
+
+/**
+ * xmlParseCharRef:
+ * @ctxt:  an XML parser context
+ *
+ * parse Reference declarations
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ *                  '&#x' [0-9a-fA-F]+ ';'
+ *
+ * [ WFC: Legal Character ]
+ * Characters referred to using character references must match the
+ * production for Char. 
+ *
+ * Returns the value parsed (as an int), 0 in case of error
+ */
+int
+xmlParseCharRef(xmlParserCtxtPtr ctxt) {
+    unsigned int val = 0;
+    int count = 0;
+    unsigned int outofrange = 0;
+
+    /*
+     * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
+     */
+    if ((RAW == '&') && (NXT(1) == '#') &&
+        (NXT(2) == 'x')) {
+	SKIP(3);
+	GROW;
+	while (RAW != ';') { /* loop blocked by count */
+	    if (count++ > 20) {
+		count = 0;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(0);
+	    }
+	    if ((RAW >= '0') && (RAW <= '9')) 
+	        val = val * 16 + (CUR - '0');
+	    else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
+	        val = val * 16 + (CUR - 'a') + 10;
+	    else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
+	        val = val * 16 + (CUR - 'A') + 10;
+	    else {
+		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
+		val = 0;
+		break;
+	    }
+	    if (val > 0x10FFFF)
+	        outofrange = val;
+
+	    NEXT;
+	    count++;
+	}
+	if (RAW == ';') {
+	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
+	    ctxt->input->col++;
+	    ctxt->nbChars ++;
+	    ctxt->input->cur++;
+	}
+    } else if  ((RAW == '&') && (NXT(1) == '#')) {
+	SKIP(2);
+	GROW;
+	while (RAW != ';') { /* loop blocked by count */
+	    if (count++ > 20) {
+		count = 0;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(0);
+	    }
+	    if ((RAW >= '0') && (RAW <= '9')) 
+	        val = val * 10 + (CUR - '0');
+	    else {
+		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
+		val = 0;
+		break;
+	    }
+	    if (val > 0x10FFFF)
+	        outofrange = val;
+
+	    NEXT;
+	    count++;
+	}
+	if (RAW == ';') {
+	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
+	    ctxt->input->col++;
+	    ctxt->nbChars ++;
+	    ctxt->input->cur++;
+	}
+    } else {
+        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
+    }
+
+    /*
+     * [ WFC: Legal Character ]
+     * Characters referred to using character references must match the
+     * production for Char. 
+     */
+    if ((IS_CHAR(val) && (outofrange == 0))) {
+        return(val);
+    } else {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "xmlParseCharRef: invalid xmlChar value %d\n",
+	                  val);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseStringCharRef:
+ * @ctxt:  an XML parser context
+ * @str:  a pointer to an index in the string
+ *
+ * parse Reference declarations, variant parsing from a string rather
+ * than an an input flow.
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ *                  '&#x' [0-9a-fA-F]+ ';'
+ *
+ * [ WFC: Legal Character ]
+ * Characters referred to using character references must match the
+ * production for Char. 
+ *
+ * Returns the value parsed (as an int), 0 in case of error, str will be
+ *         updated to the current value of the index
+ */
+static int
+xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
+    const xmlChar *ptr;
+    xmlChar cur;
+    unsigned int val = 0;
+    unsigned int outofrange = 0;
+
+    if ((str == NULL) || (*str == NULL)) return(0);
+    ptr = *str;
+    cur = *ptr;
+    if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
+	ptr += 3;
+	cur = *ptr;
+	while (cur != ';') { /* Non input consuming loop */
+	    if ((cur >= '0') && (cur <= '9')) 
+	        val = val * 16 + (cur - '0');
+	    else if ((cur >= 'a') && (cur <= 'f'))
+	        val = val * 16 + (cur - 'a') + 10;
+	    else if ((cur >= 'A') && (cur <= 'F'))
+	        val = val * 16 + (cur - 'A') + 10;
+	    else {
+		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
+		val = 0;
+		break;
+	    }
+	    if (val > 0x10FFFF)
+	        outofrange = val;
+
+	    ptr++;
+	    cur = *ptr;
+	}
+	if (cur == ';')
+	    ptr++;
+    } else if  ((cur == '&') && (ptr[1] == '#')){
+	ptr += 2;
+	cur = *ptr;
+	while (cur != ';') { /* Non input consuming loops */
+	    if ((cur >= '0') && (cur <= '9')) 
+	        val = val * 10 + (cur - '0');
+	    else {
+		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
+		val = 0;
+		break;
+	    }
+	    if (val > 0x10FFFF)
+	        outofrange = val;
+
+	    ptr++;
+	    cur = *ptr;
+	}
+	if (cur == ';')
+	    ptr++;
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
+	return(0);
+    }
+    *str = ptr;
+
+    /*
+     * [ WFC: Legal Character ]
+     * Characters referred to using character references must match the
+     * production for Char. 
+     */
+    if ((IS_CHAR(val) && (outofrange == 0))) {
+        return(val);
+    } else {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+			  "xmlParseStringCharRef: invalid xmlChar value %d\n",
+			  val);
+    }
+    return(0);
+}
+
+/**
+ * xmlNewBlanksWrapperInputStream:
+ * @ctxt:  an XML parser context
+ * @entity:  an Entity pointer
+ *
+ * Create a new input stream for wrapping
+ * blanks around a PEReference
+ *
+ * Returns the new input stream or NULL
+ */
+ 
+static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
+ 
+static xmlParserInputPtr
+xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+    xmlParserInputPtr input;
+    xmlChar *buffer;
+    size_t length;
+    if (entity == NULL) {
+	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	            "xmlNewBlanksWrapperInputStream entity\n");
+	return(NULL);
+    }
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"new blanks wrapper for entity: %s\n", entity->name);
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+	return(NULL);
+    }
+    length = xmlStrlen(entity->name) + 5;
+    buffer = xmlMallocAtomic(length);
+    if (buffer == NULL) {
+	xmlErrMemory(ctxt, NULL);
+        xmlFree(input);
+    	return(NULL);
+    }
+    buffer [0] = ' ';
+    buffer [1] = '%';
+    buffer [length-3] = ';';
+    buffer [length-2] = ' ';
+    buffer [length-1] = 0;
+    memcpy(buffer + 2, entity->name, length - 5);
+    input->free = deallocblankswrapper;
+    input->base = buffer;
+    input->cur = buffer;
+    input->length = length;
+    input->end = &buffer[length];
+    return(input);
+}
+
+/**
+ * xmlParserHandlePEReference:
+ * @ctxt:  the parser context
+ * 
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * [ WFC: No Recursion ]
+ * A parsed entity must not contain a recursive
+ * reference to itself, either directly or indirectly. 
+ *
+ * [ WFC: Entity Declared ]
+ * In a document without any DTD, a document with only an internal DTD
+ * subset which contains no parameter entity references, or a document
+ * with "standalone='yes'", ...  ... The declaration of a parameter
+ * entity must precede any reference to it...
+ *
+ * [ VC: Entity Declared ]
+ * In a document with an external subset or external parameter entities
+ * with "standalone='no'", ...  ... The declaration of a parameter entity
+ * must precede any reference to it...
+ *
+ * [ WFC: In DTD ]
+ * Parameter-entity references may only appear in the DTD.
+ * NOTE: misleading but this is handled.
+ *
+ * A PEReference may have been detected in the current input stream
+ * the handling is done accordingly to 
+ *      http://www.w3.org/TR/REC-xml#entproc
+ * i.e. 
+ *   - Included in literal in entity values
+ *   - Included as Parameter Entity reference within DTDs
+ */
+void
+xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlEntityPtr entity = NULL;
+    xmlParserInputPtr input;
+
+    if (RAW != '%') return;
+    switch(ctxt->instate) {
+	case XML_PARSER_CDATA_SECTION:
+	    return;
+        case XML_PARSER_COMMENT:
+	    return;
+	case XML_PARSER_START_TAG:
+	    return;
+	case XML_PARSER_END_TAG:
+	    return;
+        case XML_PARSER_EOF:
+	    xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
+	    return;
+        case XML_PARSER_PROLOG:
+	case XML_PARSER_START:
+	case XML_PARSER_MISC:
+	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
+	    return;
+	case XML_PARSER_ENTITY_DECL:
+        case XML_PARSER_CONTENT:
+        case XML_PARSER_ATTRIBUTE_VALUE:
+        case XML_PARSER_PI:
+	case XML_PARSER_SYSTEM_LITERAL:
+	case XML_PARSER_PUBLIC_LITERAL:
+	    /* we just ignore it there */
+	    return;
+        case XML_PARSER_EPILOG:
+	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
+	    return;
+	case XML_PARSER_ENTITY_VALUE:
+	    /*
+	     * NOTE: in the case of entity values, we don't do the
+	     *       substitution here since we need the literal
+	     *       entity value to be able to save the internal
+	     *       subset of the document.
+	     *       This will be handled by xmlStringDecodeEntities
+	     */
+	    return;
+        case XML_PARSER_DTD:
+	    /*
+	     * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
+	     * In the internal DTD subset, parameter-entity references
+	     * can occur only where markup declarations can occur, not
+	     * within markup declarations.
+	     * In that case this is handled in xmlParseMarkupDecl
+	     */
+	    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
+		return;
+	    if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
+		return;
+            break;
+        case XML_PARSER_IGNORE:
+            return;
+    }
+
+    NEXT;
+    name = xmlParseName(ctxt);
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"PEReference: %s\n", name);
+    if (name == NULL) {
+	xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
+    } else {
+	if (RAW == ';') {
+	    NEXT;
+	    if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
+		entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+	    if (ctxt->instate == XML_PARSER_EOF)
+	        return;
+	    if (entity == NULL) {
+	        
+		/*
+		 * [ WFC: Entity Declared ]
+		 * In a document without any DTD, a document with only an
+		 * internal DTD subset which contains no parameter entity
+		 * references, or a document with "standalone='yes'", ...
+		 * ... The declaration of a parameter entity must precede
+		 * any reference to it...
+		 */
+		if ((ctxt->standalone == 1) ||
+		    ((ctxt->hasExternalSubset == 0) &&
+		     (ctxt->hasPErefs == 0))) {
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+			 "PEReference: %%%s; not found\n", name);
+	        } else {
+		    /*
+		     * [ VC: Entity Declared ]
+		     * In a document with an external subset or external
+		     * parameter entities with "standalone='no'", ...
+		     * ... The declaration of a parameter entity must precede
+		     * any reference to it...
+		     */
+		    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
+		        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			                 "PEReference: %%%s; not found\n",
+				         name, NULL);
+		    } else 
+		        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			              "PEReference: %%%s; not found\n",
+				      name, NULL);
+		    ctxt->valid = 0;
+		}
+	    } else if (ctxt->input->free != deallocblankswrapper) {
+		    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+		    if (xmlPushInput(ctxt, input) < 0)
+		        return;
+	    } else {
+	        if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
+		    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
+		    xmlChar start[4];
+		    xmlCharEncoding enc;
+
+		    /*
+		     * handle the extra spaces added before and after
+		     * c.f. http://www.w3.org/TR/REC-xml#as-PE
+		     * this is done independently.
+		     */
+		    input = xmlNewEntityInputStream(ctxt, entity);
+		    if (xmlPushInput(ctxt, input) < 0)
+		        return;
+
+		    /* 
+		     * Get the 4 first bytes and decode the charset
+		     * if enc != XML_CHAR_ENCODING_NONE
+		     * plug some encoding conversion routines.
+		     * Note that, since we may have some non-UTF8
+		     * encoding (like UTF16, bug 135229), the 'length'
+		     * is not known, but we can calculate based upon
+		     * the amount of data in the buffer.
+		     */
+		    GROW
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        return;
+		    if ((ctxt->input->end - ctxt->input->cur)>=4) {
+			start[0] = RAW;
+			start[1] = NXT(1);
+			start[2] = NXT(2);
+			start[3] = NXT(3);
+			enc = xmlDetectCharEncoding(start, 4);
+			if (enc != XML_CHAR_ENCODING_NONE) {
+			    xmlSwitchEncoding(ctxt, enc);
+			}
+		    }
+
+		    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
+			(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
+			(IS_BLANK_CH(NXT(5)))) {
+			xmlParseTextDecl(ctxt);
+		    }
+		} else {
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
+			     "PEReference: %s is not a parameter entity\n",
+				      name);
+		}
+	    }
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
+	}
+    }
+}
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define growBuffer(buffer, n) {						\
+    xmlChar *tmp;							\
+    buffer##_size *= 2;							\
+    buffer##_size += n;							\
+    tmp = (xmlChar *)							\
+		xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));	\
+    if (tmp == NULL) goto mem_error;					\
+    buffer = tmp;							\
+}
+
+/**
+ * xmlStringLenDecodeEntities:
+ * @ctxt:  the parser context
+ * @str:  the input string
+ * @len: the string length
+ * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
+ * @end:  an end marker xmlChar, 0 if none
+ * @end2:  an end marker xmlChar, 0 if none
+ * @end3:  an end marker xmlChar, 0 if none
+ * 
+ * Takes a entity string content and process to do the adequate substitutions.
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ *
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * Returns A newly allocated string with the substitution done. The caller
+ *      must deallocate it !
+ */
+xmlChar *
+xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+		      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
+    xmlChar *buffer = NULL;
+    int buffer_size = 0;
+
+    xmlChar *current = NULL;
+    xmlChar *rep = NULL;
+    const xmlChar *last;
+    xmlEntityPtr ent;
+    int c,l;
+    int nbchars = 0;
+
+    if ((ctxt == NULL) || (str == NULL) || (len < 0))
+	return(NULL);
+    last = str + len;
+
+    if (((ctxt->depth > 40) &&
+         ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
+	(ctxt->depth > 1024)) {
+	xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+	return(NULL);
+    }
+
+    /*
+     * allocate a translation buffer.
+     */
+    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
+    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) goto mem_error;
+
+    /*
+     * OK loop until we reach one of the ending char or a size limit.
+     * we are operating on already parsed values.
+     */
+    if (str < last)
+	c = CUR_SCHAR(str, l);
+    else
+        c = 0;
+    while ((c != 0) && (c != end) && /* non input consuming loop */
+	   (c != end2) && (c != end3)) {
+
+	if (c == 0) break;
+        if ((c == '&') && (str[1] == '#')) {
+	    int val = xmlParseStringCharRef(ctxt, &str);
+	    if (val != 0) {
+		COPY_BUF(0,buffer,nbchars,val);
+	    }
+	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
+	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+	    }
+	} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
+	    if (xmlParserDebugEntities)
+		xmlGenericError(xmlGenericErrorContext,
+			"String decoding Entity Reference: %.30s\n",
+			str);
+	    ent = xmlParseStringEntityRef(ctxt, &str);
+	    if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
+	        (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
+	        goto int_error;
+	    if (ent != NULL)
+	        ctxt->nbentities += ent->checked;
+	    if ((ent != NULL) &&
+		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+		if (ent->content != NULL) {
+		    COPY_BUF(0,buffer,nbchars,ent->content[0]);
+		    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
+			growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+		    }
+		} else {
+		    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+			    "predefined entity has no content\n");
+		}
+	    } else if ((ent != NULL) && (ent->content != NULL)) {
+		ctxt->depth++;
+		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
+			                      0, 0, 0);
+		ctxt->depth--;
+
+		if (rep != NULL) {
+		    current = rep;
+		    while (*current != 0) { /* non input consuming loop */
+			buffer[nbchars++] = *current++;
+			if (nbchars >
+		            buffer_size - XML_PARSER_BUFFER_SIZE) {
+			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
+				goto int_error;
+			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+			}
+		    }
+		    xmlFree(rep);
+		    rep = NULL;
+		}
+	    } else if (ent != NULL) {
+		int i = xmlStrlen(ent->name);
+		const xmlChar *cur = ent->name;
+
+		buffer[nbchars++] = '&';
+		if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
+		    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
+		}
+		for (;i > 0;i--)
+		    buffer[nbchars++] = *cur++;
+		buffer[nbchars++] = ';';
+	    }
+	} else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
+	    if (xmlParserDebugEntities)
+		xmlGenericError(xmlGenericErrorContext,
+			"String decoding PE Reference: %.30s\n", str);
+	    ent = xmlParseStringPEReference(ctxt, &str);
+	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
+	        goto int_error;
+	    if (ent != NULL)
+	        ctxt->nbentities += ent->checked;
+	    if (ent != NULL) {
+                if (ent->content == NULL) {
+		    xmlLoadEntityContent(ctxt, ent);
+		}
+		ctxt->depth++;
+		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
+			                      0, 0, 0);
+		ctxt->depth--;
+		if (rep != NULL) {
+		    current = rep;
+		    while (*current != 0) { /* non input consuming loop */
+			buffer[nbchars++] = *current++;
+			if (nbchars >
+		            buffer_size - XML_PARSER_BUFFER_SIZE) {
+			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
+			        goto int_error;
+			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+			}
+		    }
+		    xmlFree(rep);
+		    rep = NULL;
+		}
+	    }
+	} else {
+	    COPY_BUF(l,buffer,nbchars,c);
+	    str += l;
+	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
+	      growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+	    }
+	}
+	if (str < last)
+	    c = CUR_SCHAR(str, l);
+	else
+	    c = 0;
+    }
+    buffer[nbchars] = 0;
+    return(buffer);
+
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+int_error:
+    if (rep != NULL)
+        xmlFree(rep);
+    if (buffer != NULL)
+        xmlFree(buffer);
+    return(NULL);
+}
+
+/**
+ * xmlStringDecodeEntities:
+ * @ctxt:  the parser context
+ * @str:  the input string
+ * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
+ * @end:  an end marker xmlChar, 0 if none
+ * @end2:  an end marker xmlChar, 0 if none
+ * @end3:  an end marker xmlChar, 0 if none
+ * 
+ * Takes a entity string content and process to do the adequate substitutions.
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ *
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * Returns A newly allocated string with the substitution done. The caller
+ *      must deallocate it !
+ */
+xmlChar *
+xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
+		        xmlChar end, xmlChar  end2, xmlChar end3) {
+    if ((ctxt == NULL) || (str == NULL)) return(NULL);
+    return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
+           end, end2, end3));
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions, cleanup needed ?			*
+ *									*
+ ************************************************************************/
+
+/**
+ * areBlanks:
+ * @ctxt:  an XML parser context
+ * @str:  a xmlChar *
+ * @len:  the size of @str
+ * @blank_chars: we know the chars are blanks
+ *
+ * Is this a sequence of blank chars that one can ignore ?
+ *
+ * Returns 1 if ignorable 0 otherwise.
+ */
+
+static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+                     int blank_chars) {
+    int i, ret;
+    xmlNodePtr lastChild;
+
+    /*
+     * Don't spend time trying to differentiate them, the same callback is
+     * used !
+     */
+    if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
+	return(0);
+
+    /*
+     * Check for xml:space value.
+     */
+    if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
+        (*(ctxt->space) == -2))
+	return(0);
+
+    /*
+     * Check that the string is made of blanks
+     */
+    if (blank_chars == 0) {
+	for (i = 0;i < len;i++)
+	    if (!(IS_BLANK_CH(str[i]))) return(0);
+    }
+
+    /*
+     * Look if the element is mixed content in the DTD if available
+     */
+    if (ctxt->node == NULL) return(0);
+    if (ctxt->myDoc != NULL) {
+	ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
+        if (ret == 0) return(1);
+        if (ret == 1) return(0);
+    }
+
+    /*
+     * Otherwise, heuristic :-\
+     */
+    if ((RAW != '<') && (RAW != 0xD)) return(0);
+    if ((ctxt->node->children == NULL) &&
+	(RAW == '<') && (NXT(1) == '/')) return(0);
+
+    lastChild = xmlGetLastChild(ctxt->node);
+    if (lastChild == NULL) {
+        if ((ctxt->node->type != XML_ELEMENT_NODE) &&
+            (ctxt->node->content != NULL)) return(0);
+    } else if (xmlNodeIsText(lastChild))
+        return(0);
+    else if ((ctxt->node->children != NULL) &&
+             (xmlNodeIsText(ctxt->node->children)))
+        return(0);
+    return(1);
+}
+
+/************************************************************************
+ *									*
+ *		Extra stuff for namespace support			*
+ *	Relates to http://www.w3.org/TR/WD-xml-names			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSplitQName:
+ * @ctxt:  an XML parser context
+ * @name:  an XML parser context
+ * @prefix:  a xmlChar **
+ *
+ * parse an UTF8 encoded XML qualified name string
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns the local part, and prefix is updated
+ *   to get the Prefix if any.
+ */
+
+xmlChar *
+xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
+    xmlChar buf[XML_MAX_NAMELEN + 5];
+    xmlChar *buffer = NULL;
+    int len = 0;
+    int max = XML_MAX_NAMELEN;
+    xmlChar *ret = NULL;
+    const xmlChar *cur = name;
+    int c;
+
+    if (prefix == NULL) return(NULL);
+    *prefix = NULL;
+
+    if (cur == NULL) return(NULL);
+
+#ifndef XML_XML_NAMESPACE
+    /* xml: prefix is not really a namespace */
+    if ((cur[0] == 'x') && (cur[1] == 'm') &&
+        (cur[2] == 'l') && (cur[3] == ':'))
+	return(xmlStrdup(name));
+#endif
+
+    /* nasty but well=formed */
+    if (cur[0] == ':')
+	return(xmlStrdup(name));
+
+    c = *cur++;
+    while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
+	buf[len++] = c;
+	c = *cur++;
+    }
+    if (len >= max) {
+	/*
+	 * Okay someone managed to make a huge name, so he's ready to pay
+	 * for the processing speed.
+	 */
+	max = len * 2;
+
+	buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+	if (buffer == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    return(NULL);
+	}
+	memcpy(buffer, buf, len);
+	while ((c != 0) && (c != ':')) { /* tested bigname.xml */
+	    if (len + 10 > max) {
+	        xmlChar *tmp;
+
+		max *= 2;
+		tmp = (xmlChar *) xmlRealloc(buffer,
+						max * sizeof(xmlChar));
+		if (tmp == NULL) {
+		    xmlFree(buffer);
+		    xmlErrMemory(ctxt, NULL);
+		    return(NULL);
+		}
+		buffer = tmp;
+	    }
+	    buffer[len++] = c;
+	    c = *cur++;
+	}
+	buffer[len] = 0;
+    }
+
+    if ((c == ':') && (*cur == 0)) {
+        if (buffer != NULL)
+	    xmlFree(buffer);
+	*prefix = NULL;
+	return(xmlStrdup(name));
+    }
+
+    if (buffer == NULL)
+	ret = xmlStrndup(buf, len);
+    else {
+	ret = buffer;
+	buffer = NULL;
+	max = XML_MAX_NAMELEN;
+    }
+
+
+    if (c == ':') {
+	c = *cur;
+        *prefix = ret;
+	if (c == 0) {
+	    return(xmlStrndup(BAD_CAST "", 0));
+	}
+	len = 0;
+
+	/*
+	 * Check that the first character is proper to start
+	 * a new name
+	 */
+	if (!(((c >= 0x61) && (c <= 0x7A)) ||
+	      ((c >= 0x41) && (c <= 0x5A)) ||
+	      (c == '_') || (c == ':'))) {
+	    int l;
+	    int first = CUR_SCHAR(cur, l);
+
+	    if (!IS_LETTER(first) && (first != '_')) {
+		xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
+			    "Name %s is not XML Namespace compliant\n",
+				  name);
+	    }
+	}
+	cur++;
+
+	while ((c != 0) && (len < max)) { /* tested bigname2.xml */
+	    buf[len++] = c;
+	    c = *cur++;
+	}
+	if (len >= max) {
+	    /*
+	     * Okay someone managed to make a huge name, so he's ready to pay
+	     * for the processing speed.
+	     */
+	    max = len * 2;
+
+	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+	    if (buffer == NULL) {
+	        xmlErrMemory(ctxt, NULL);
+		return(NULL);
+	    }
+	    memcpy(buffer, buf, len);
+	    while (c != 0) { /* tested bigname2.xml */
+		if (len + 10 > max) {
+		    xmlChar *tmp;
+
+		    max *= 2;
+		    tmp = (xmlChar *) xmlRealloc(buffer,
+						    max * sizeof(xmlChar));
+		    if (tmp == NULL) {
+			xmlErrMemory(ctxt, NULL);
+			xmlFree(buffer);
+			return(NULL);
+		    }
+		    buffer = tmp;
+		}
+		buffer[len++] = c;
+		c = *cur++;
+	    }
+	    buffer[len] = 0;
+	}
+
+	if (buffer == NULL)
+	    ret = xmlStrndup(buf, len);
+	else {
+	    ret = buffer;
+	}
+    }
+
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *			The parser itself				*
+ *	Relates to http://www.w3.org/TR/REC-xml				*
+ *									*
+ ************************************************************************/
+
+/************************************************************************
+ *									*
+ *	Routines to parse Name, NCName and NmToken			*
+ *									*
+ ************************************************************************/
+#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
+ * They correspond to the modified production [4] and the new production [4a]
+ * changes in that revision. Also note that the macros used for the
+ * productions Letter, Digit, CombiningChar and Extender are not needed
+ * anymore.
+ * We still keep compatibility to pre-revision5 parsing semantic if the
+ * new XML_PARSE_OLD10 option is given to the parser.
+ */
+static int
+xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
+    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
+        /*
+	 * Use the new checks of production [4] [4a] amd [5] of the
+	 * Update 5 of XML-1.0
+	 */
+	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
+	    (((c >= 'a') && (c <= 'z')) ||
+	     ((c >= 'A') && (c <= 'Z')) ||
+	     (c == '_') || (c == ':') ||
+	     ((c >= 0xC0) && (c <= 0xD6)) ||
+	     ((c >= 0xD8) && (c <= 0xF6)) ||
+	     ((c >= 0xF8) && (c <= 0x2FF)) ||
+	     ((c >= 0x370) && (c <= 0x37D)) ||
+	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	     ((c >= 0x200C) && (c <= 0x200D)) ||
+	     ((c >= 0x2070) && (c <= 0x218F)) ||
+	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	     ((c >= 0x10000) && (c <= 0xEFFFF))))
+	    return(1);
+    } else {
+        if (IS_LETTER(c) || (c == '_') || (c == ':'))
+	    return(1);
+    }
+    return(0);
+}
+
+static int
+xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
+    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
+        /*
+	 * Use the new checks of production [4] [4a] amd [5] of the
+	 * Update 5 of XML-1.0
+	 */
+	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
+	    (((c >= 'a') && (c <= 'z')) ||
+	     ((c >= 'A') && (c <= 'Z')) ||
+	     ((c >= '0') && (c <= '9')) || /* !start */
+	     (c == '_') || (c == ':') ||
+	     (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
+	     ((c >= 0xC0) && (c <= 0xD6)) ||
+	     ((c >= 0xD8) && (c <= 0xF6)) ||
+	     ((c >= 0xF8) && (c <= 0x2FF)) ||
+	     ((c >= 0x300) && (c <= 0x36F)) || /* !start */
+	     ((c >= 0x370) && (c <= 0x37D)) ||
+	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	     ((c >= 0x200C) && (c <= 0x200D)) ||
+	     ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
+	     ((c >= 0x2070) && (c <= 0x218F)) ||
+	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	     ((c >= 0x10000) && (c <= 0xEFFFF))))
+	     return(1);
+    } else {
+        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || (c == ':') || 
+	    (IS_COMBINING(c)) ||
+	    (IS_EXTENDER(c)))
+	    return(1);
+    }
+    return(0);
+}
+
+static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
+                                          int *len, int *alloc, int normalize);
+
+static const xmlChar *
+xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+    int len = 0, l;
+    int c;
+    int count = 0;
+
+#ifdef DEBUG
+    nbParseNameComplex++;
+#endif
+
+    /*
+     * Handler for more complex cases
+     */
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(NULL);
+    c = CUR_CHAR(l);
+    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
+        /*
+	 * Use the new checks of production [4] [4a] amd [5] of the
+	 * Update 5 of XML-1.0
+	 */
+	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+	    (!(((c >= 'a') && (c <= 'z')) ||
+	       ((c >= 'A') && (c <= 'Z')) ||
+	       (c == '_') || (c == ':') ||
+	       ((c >= 0xC0) && (c <= 0xD6)) ||
+	       ((c >= 0xD8) && (c <= 0xF6)) ||
+	       ((c >= 0xF8) && (c <= 0x2FF)) ||
+	       ((c >= 0x370) && (c <= 0x37D)) ||
+	       ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	       ((c >= 0x200C) && (c <= 0x200D)) ||
+	       ((c >= 0x2070) && (c <= 0x218F)) ||
+	       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	       ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	       ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	       ((c >= 0x10000) && (c <= 0xEFFFF))))) {
+	    return(NULL);
+	}
+	len += l;
+	NEXTL(l);
+	c = CUR_CHAR(l);
+	while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
+	       (((c >= 'a') && (c <= 'z')) ||
+	        ((c >= 'A') && (c <= 'Z')) ||
+	        ((c >= '0') && (c <= '9')) || /* !start */
+	        (c == '_') || (c == ':') ||
+	        (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
+	        ((c >= 0xC0) && (c <= 0xD6)) ||
+	        ((c >= 0xD8) && (c <= 0xF6)) ||
+	        ((c >= 0xF8) && (c <= 0x2FF)) ||
+	        ((c >= 0x300) && (c <= 0x36F)) || /* !start */
+	        ((c >= 0x370) && (c <= 0x37D)) ||
+	        ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	        ((c >= 0x200C) && (c <= 0x200D)) ||
+	        ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
+	        ((c >= 0x2070) && (c <= 0x218F)) ||
+	        ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	        ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	        ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	        ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	        ((c >= 0x10000) && (c <= 0xEFFFF))
+		)) {
+	    if (count++ > 100) {
+		count = 0;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+	    }
+	    len += l;
+	    NEXTL(l);
+	    c = CUR_CHAR(l);
+	}
+    } else {
+	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+	    (!IS_LETTER(c) && (c != '_') &&
+	     (c != ':'))) {
+	    return(NULL);
+	}
+	len += l;
+	NEXTL(l);
+	c = CUR_CHAR(l);
+
+	while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+	       ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+		(c == '.') || (c == '-') ||
+		(c == '_') || (c == ':') || 
+		(IS_COMBINING(c)) ||
+		(IS_EXTENDER(c)))) {
+	    if (count++ > 100) {
+		count = 0;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+	    }
+	    len += l;
+	    NEXTL(l);
+	    c = CUR_CHAR(l);
+	}
+    }
+    if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
+        return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
+    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+}
+
+/**
+ * xmlParseName:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML name.
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (#x20 Name)*
+ *
+ * Returns the Name parsed or NULL
+ */
+
+const xmlChar *
+xmlParseName(xmlParserCtxtPtr ctxt) {
+    const xmlChar *in;
+    const xmlChar *ret;
+    int count = 0;
+
+    GROW;
+
+#ifdef DEBUG
+    nbParseName++;
+#endif
+
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->input->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_') || (*in == ':')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == '-') ||
+	       (*in == ':') || (*in == '.'))
+	    in++;
+	if ((*in > 0) && (*in < 0x80)) {
+	    count = in - ctxt->input->cur;
+	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+	    ctxt->input->cur = in;
+	    ctxt->nbChars += count;
+	    ctxt->input->col += count;
+	    if (ret == NULL)
+	        xmlErrMemory(ctxt, NULL);
+	    return(ret);
+	}
+    }
+    /* accelerator for special cases */
+    return(xmlParseNameComplex(ctxt));
+}
+
+static const xmlChar *
+xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+    int len = 0, l;
+    int c;
+    int count = 0;
+
+#ifdef DEBUG
+    nbParseNCNameComplex++;
+#endif
+
+    /*
+     * Handler for more complex cases
+     */
+    GROW;
+    c = CUR_CHAR(l);
+    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+	(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
+	return(NULL);
+    }
+
+    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+	   (xmlIsNameChar(ctxt, c) && (c != ':'))) {
+	if (count++ > 100) {
+	    count = 0;
+	    GROW;
+            if (ctxt->instate == XML_PARSER_EOF)
+                return(NULL);
+	}
+	len += l;
+	NEXTL(l);
+	c = CUR_CHAR(l);
+    }
+    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+}
+
+/**
+ * xmlParseNCName:
+ * @ctxt:  an XML parser context
+ * @len:  lenght of the string parsed
+ *
+ * parse an XML name.
+ *
+ * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
+ *                      CombiningChar | Extender
+ *
+ * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static const xmlChar *
+xmlParseNCName(xmlParserCtxtPtr ctxt) {
+    const xmlChar *in;
+    const xmlChar *ret;
+    int count = 0;
+
+#ifdef DEBUG
+    nbParseNCName++;
+#endif
+
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->input->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == '-') ||
+	       (*in == '.'))
+	    in++;
+	if ((*in > 0) && (*in < 0x80)) {
+	    count = in - ctxt->input->cur;
+	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+	    ctxt->input->cur = in;
+	    ctxt->nbChars += count;
+	    ctxt->input->col += count;
+	    if (ret == NULL) {
+	        xmlErrMemory(ctxt, NULL);
+	    }
+	    return(ret);
+	}
+    }
+    return(xmlParseNCNameComplex(ctxt));
+}
+
+/**
+ * xmlParseNameAndCompare:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML name and compares for match
+ * (specialized for endtag parsing)
+ *
+ * Returns NULL for an illegal name, (xmlChar*) 1 for success
+ * and the name for mismatch
+ */
+
+static const xmlChar *
+xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
+    register const xmlChar *cmp = other;
+    register const xmlChar *in;
+    const xmlChar *ret;
+
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(NULL);
+
+    in = ctxt->input->cur;
+    while (*in != 0 && *in == *cmp) {
+	++in;
+	++cmp;
+	ctxt->input->col++;
+    }
+    if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
+	/* success */
+	ctxt->input->cur = in;
+	return (const xmlChar*) 1;
+    }
+    /* failure (or end of input buffer), check with full function */
+    ret = xmlParseName (ctxt);
+    /* strings coming from the dictionnary direct compare possible */
+    if (ret == other) {
+	return (const xmlChar*) 1;
+    }
+    return ret;
+}
+
+/**
+ * xmlParseStringName:
+ * @ctxt:  an XML parser context
+ * @str:  a pointer to the string pointer (IN/OUT)
+ *
+ * parse an XML name.
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (#x20 Name)*
+ *
+ * Returns the Name parsed or NULL. The @str pointer 
+ * is updated to the current location in the string.
+ */
+
+static xmlChar *
+xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+    xmlChar buf[XML_MAX_NAMELEN + 5];
+    const xmlChar *cur = *str;
+    int len = 0, l;
+    int c;
+
+#ifdef DEBUG
+    nbParseStringName++;
+#endif
+
+    c = CUR_SCHAR(cur, l);
+    if (!xmlIsNameStartChar(ctxt, c)) {
+	return(NULL);
+    }
+
+    COPY_BUF(l,buf,len,c);
+    cur += l;
+    c = CUR_SCHAR(cur, l);
+    while (xmlIsNameChar(ctxt, c)) {
+	COPY_BUF(l,buf,len,c);
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+	if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
+	    /*
+	     * Okay someone managed to make a huge name, so he's ready to pay
+	     * for the processing speed.
+	     */
+	    xmlChar *buffer;
+	    int max = len * 2;
+
+	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+	    if (buffer == NULL) {
+	        xmlErrMemory(ctxt, NULL);
+		return(NULL);
+	    }
+	    memcpy(buffer, buf, len);
+	    while (xmlIsNameChar(ctxt, c)) {
+		if (len + 10 > max) {
+		    xmlChar *tmp;
+		    max *= 2;
+		    tmp = (xmlChar *) xmlRealloc(buffer,
+			                            max * sizeof(xmlChar));
+		    if (tmp == NULL) {
+			xmlErrMemory(ctxt, NULL);
+			xmlFree(buffer);
+			return(NULL);
+		    }
+		    buffer = tmp;
+		}
+		COPY_BUF(l,buffer,len,c);
+		cur += l;
+		c = CUR_SCHAR(cur, l);
+	    }
+	    buffer[len] = 0;
+	    *str = cur;
+	    return(buffer);
+	}
+    }
+    *str = cur;
+    return(xmlStrndup(buf, len));
+}
+
+/**
+ * xmlParseNmtoken:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML Nmtoken.
+ *
+ * [7] Nmtoken ::= (NameChar)+
+ *
+ * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
+ *
+ * Returns the Nmtoken parsed or NULL
+ */
+
+xmlChar *
+xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+    xmlChar buf[XML_MAX_NAMELEN + 5];
+    int len = 0, l;
+    int c;
+    int count = 0;
+
+#ifdef DEBUG
+    nbParseNmToken++;
+#endif
+
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(NULL);
+    c = CUR_CHAR(l);
+
+    while (xmlIsNameChar(ctxt, c)) {
+	if (count++ > 100) {
+	    count = 0;
+	    GROW;
+	}
+	COPY_BUF(l,buf,len,c);
+	NEXTL(l);
+	c = CUR_CHAR(l);
+	if (len >= XML_MAX_NAMELEN) {
+	    /*
+	     * Okay someone managed to make a huge token, so he's ready to pay
+	     * for the processing speed.
+	     */
+	    xmlChar *buffer;
+	    int max = len * 2;
+
+	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+	    if (buffer == NULL) {
+	        xmlErrMemory(ctxt, NULL);
+		return(NULL);
+	    }
+	    memcpy(buffer, buf, len);
+	    while (xmlIsNameChar(ctxt, c)) {
+		if (count++ > 100) {
+		    count = 0;
+		    GROW;
+                    if (ctxt->instate == XML_PARSER_EOF) {
+                        xmlFree(buffer);
+                        return(NULL);
+                    }
+		}
+		if (len + 10 > max) {
+		    xmlChar *tmp;
+
+		    max *= 2;
+		    tmp = (xmlChar *) xmlRealloc(buffer,
+			                            max * sizeof(xmlChar));
+		    if (tmp == NULL) {
+			xmlErrMemory(ctxt, NULL);
+			xmlFree(buffer);
+			return(NULL);
+		    }
+		    buffer = tmp;
+		}
+		COPY_BUF(l,buffer,len,c);
+		NEXTL(l);
+		c = CUR_CHAR(l);
+	    }
+	    buffer[len] = 0;
+	    return(buffer);
+	}
+    }
+    if (len == 0)
+        return(NULL);
+    return(xmlStrndup(buf, len));
+}
+
+/**
+ * xmlParseEntityValue:
+ * @ctxt:  an XML parser context
+ * @orig:  if non-NULL store a copy of the original entity value
+ *
+ * parse a value for ENTITY declarations
+ *
+ * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
+ *	               "'" ([^%&'] | PEReference | Reference)* "'"
+ *
+ * Returns the EntityValue parsed with reference substituted or NULL
+ */
+
+xmlChar *
+xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = XML_PARSER_BUFFER_SIZE;
+    int c, l;
+    xmlChar stop;
+    xmlChar *ret = NULL;
+    const xmlChar *cur = NULL;
+    xmlParserInputPtr input;
+
+    if (RAW == '"') stop = '"';
+    else if (RAW == '\'') stop = '\'';
+    else {
+	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
+	return(NULL);
+    }
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+	xmlErrMemory(ctxt, NULL);
+	return(NULL);
+    }
+
+    /*
+     * The content of the entity definition is copied in a buffer.
+     */
+
+    ctxt->instate = XML_PARSER_ENTITY_VALUE;
+    input = ctxt->input;
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF) {
+        xmlFree(buf);
+        return(NULL);
+    }
+    NEXT;
+    c = CUR_CHAR(l);
+    /*
+     * NOTE: 4.4.5 Included in Literal
+     * When a parameter entity reference appears in a literal entity
+     * value, ... a single or double quote character in the replacement
+     * text is always treated as a normal data character and will not
+     * terminate the literal. 
+     * In practice it means we stop the loop only when back at parsing
+     * the initial entity and the quote is found
+     */
+    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
+	    (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
+	if (len + 5 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+		xmlErrMemory(ctxt, NULL);
+		xmlFree(buf);
+		return(NULL);
+	    }
+	    buf = tmp;
+	}
+	COPY_BUF(l,buf,len,c);
+	NEXTL(l);
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
+	    xmlPopInput(ctxt);
+
+	GROW;
+	c = CUR_CHAR(l);
+	if (c == 0) {
+	    GROW;
+	    c = CUR_CHAR(l);
+	}
+    }
+    buf[len] = 0;
+    if (ctxt->instate == XML_PARSER_EOF) {
+        xmlFree(buf);
+        return(NULL);
+    }
+
+    /*
+     * Raise problem w.r.t. '&' and '%' being used in non-entities
+     * reference constructs. Note Charref will be handled in
+     * xmlStringDecodeEntities()
+     */
+    cur = buf;
+    while (*cur != 0) { /* non input consuming */
+	if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
+	    xmlChar *name;
+	    xmlChar tmp = *cur;
+
+	    cur++;
+	    name = xmlParseStringName(ctxt, &cur);
+            if ((name == NULL) || (*cur != ';')) {
+		xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
+	    "EntityValue: '%c' forbidden except for entities references\n",
+	                          tmp);
+	    }
+	    if ((tmp == '%') && (ctxt->inSubset == 1) &&
+		(ctxt->inputNr == 1)) {
+		xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
+	    }
+	    if (name != NULL)
+		xmlFree(name);
+	    if (*cur == 0)
+	        break;
+	}
+	cur++;
+    }
+
+    /*
+     * Then PEReference entities are substituted.
+     */
+    if (c != stop) {
+	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
+	xmlFree(buf);
+    } else {
+	NEXT;
+	/*
+	 * NOTE: 4.4.7 Bypassed
+	 * When a general entity reference appears in the EntityValue in
+	 * an entity declaration, it is bypassed and left as is.
+	 * so XML_SUBSTITUTE_REF is not set here.
+	 */
+	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
+				      0, 0, 0);
+	if (orig != NULL)
+	    *orig = buf;
+	else
+	    xmlFree(buf);
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlParseAttValueComplex:
+ * @ctxt:  an XML parser context
+ * @len:   the resulting attribute len
+ * @normalize:  wether to apply the inner normalization
+ *
+ * parse a value for an attribute, this is the fallback function
+ * of xmlParseAttValue() when the attribute parsing requires handling
+ * of non-ASCII characters, or normalization compaction.
+ *
+ * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
+ */
+static xmlChar *
+xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+    xmlChar limit = 0;
+    xmlChar *buf = NULL;
+    xmlChar *rep = NULL;
+    int len = 0;
+    int buf_size = 0;
+    int c, l, in_space = 0;
+    xmlChar *current = NULL;
+    xmlEntityPtr ent;
+
+    if (NXT(0) == '"') {
+	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
+	limit = '"';
+        NEXT;
+    } else if (NXT(0) == '\'') {
+	limit = '\'';
+	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
+        NEXT;
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
+	return(NULL);
+    }
+
+    /*
+     * allocate a translation buffer.
+     */
+    buf_size = XML_PARSER_BUFFER_SIZE;
+    buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
+    if (buf == NULL) goto mem_error;
+
+    /*
+     * OK loop until we reach one of the ending char or a size limit.
+     */
+    c = CUR_CHAR(l);
+    while (((NXT(0) != limit) && /* checked */
+            (IS_CHAR(c)) && (c != '<')) &&
+            (ctxt->instate != XML_PARSER_EOF)) {
+	if (c == 0) break;
+	if (c == '&') {
+	    in_space = 0;
+	    if (NXT(1) == '#') {
+		int val = xmlParseCharRef(ctxt);
+
+		if (val == '&') {
+		    if (ctxt->replaceEntities) {
+			if (len > buf_size - 10) {
+			    growBuffer(buf, 10);
+			}
+			buf[len++] = '&';
+		    } else {
+			/*
+			 * The reparsing will be done in xmlStringGetNodeList()
+			 * called by the attribute() function in SAX.c
+			 */
+			if (len > buf_size - 10) {
+			    growBuffer(buf, 10);
+			}
+			buf[len++] = '&';
+			buf[len++] = '#';
+			buf[len++] = '3';
+			buf[len++] = '8';
+			buf[len++] = ';';
+		    }
+		} else if (val != 0) {
+		    if (len > buf_size - 10) {
+			growBuffer(buf, 10);
+		    }
+		    len += xmlCopyChar(0, &buf[len], val);
+		}
+	    } else {
+		ent = xmlParseEntityRef(ctxt);
+		ctxt->nbentities++;
+		if (ent != NULL)
+		    ctxt->nbentities += ent->owner;
+		if ((ent != NULL) &&
+		    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+		    if (len > buf_size - 10) {
+			growBuffer(buf, 10);
+		    }
+		    if ((ctxt->replaceEntities == 0) &&
+		        (ent->content[0] == '&')) {
+			buf[len++] = '&';
+			buf[len++] = '#';
+			buf[len++] = '3';
+			buf[len++] = '8';
+			buf[len++] = ';';
+		    } else {
+			buf[len++] = ent->content[0];
+		    }
+		} else if ((ent != NULL) && 
+		           (ctxt->replaceEntities != 0)) {
+		    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
+			rep = xmlStringDecodeEntities(ctxt, ent->content,
+						      XML_SUBSTITUTE_REF,
+						      0, 0, 0);
+			if (rep != NULL) {
+			    current = rep;
+			    while (*current != 0) { /* non input consuming */
+                                if ((*current == 0xD) || (*current == 0xA) ||
+                                    (*current == 0x9)) {
+                                    buf[len++] = 0x20;
+                                    current++;
+                                } else
+                                    buf[len++] = *current++;
+				if (len > buf_size - 10) {
+				    growBuffer(buf, 10);
+				}
+			    }
+			    xmlFree(rep);
+			    rep = NULL;
+			}
+		    } else {
+			if (len > buf_size - 10) {
+			    growBuffer(buf, 10);
+			}
+			if (ent->content != NULL)
+			    buf[len++] = ent->content[0];
+		    }
+		} else if (ent != NULL) {
+		    int i = xmlStrlen(ent->name);
+		    const xmlChar *cur = ent->name;
+
+		    /*
+		     * This may look absurd but is needed to detect
+		     * entities problems
+		     */
+		    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
+			(ent->content != NULL)) {
+			rep = xmlStringDecodeEntities(ctxt, ent->content,
+						  XML_SUBSTITUTE_REF, 0, 0, 0);
+			if (rep != NULL) {
+			    xmlFree(rep);
+			    rep = NULL;
+			}
+		    }
+
+		    /*
+		     * Just output the reference
+		     */
+		    buf[len++] = '&';
+		    while (len > buf_size - i - 10) {
+			growBuffer(buf, i + 10);
+		    }
+		    for (;i > 0;i--)
+			buf[len++] = *cur++;
+		    buf[len++] = ';';
+		}
+	    }
+	} else {
+	    if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
+	        if ((len != 0) || (!normalize)) {
+		    if ((!normalize) || (!in_space)) {
+			COPY_BUF(l,buf,len,0x20);
+			while (len > buf_size - 10) {
+			    growBuffer(buf, 10);
+			}
+		    }
+		    in_space = 1;
+		}
+	    } else {
+	        in_space = 0;
+		COPY_BUF(l,buf,len,c);
+		if (len > buf_size - 10) {
+		    growBuffer(buf, 10);
+		}
+	    }
+	    NEXTL(l);
+	}
+	GROW;
+	c = CUR_CHAR(l);
+    }
+    if (ctxt->instate == XML_PARSER_EOF)
+        goto error;
+
+    if ((in_space) && (normalize)) {
+        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
+    }
+    buf[len] = 0;
+    if (RAW == '<') {
+	xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
+    } else if (RAW != limit) {
+	if ((c != 0) && (!IS_CHAR(c))) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+			   "invalid character in attribute value\n");
+	} else {
+	    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+			   "AttValue: ' expected\n");
+        }
+    } else
+	NEXT;
+    if (attlen != NULL) *attlen = len;
+    return(buf);
+
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+error:
+    if (buf != NULL)
+        xmlFree(buf);
+    if (rep != NULL)
+        xmlFree(rep);
+    return(NULL);
+}
+
+/**
+ * xmlParseAttValue:
+ * @ctxt:  an XML parser context
+ *
+ * parse a value for an attribute
+ * Note: the parser won't do substitution of entities here, this
+ * will be handled later in xmlStringGetNodeList
+ *
+ * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
+ *                   "'" ([^<&'] | Reference)* "'"
+ *
+ * 3.3.3 Attribute-Value Normalization:
+ * Before the value of an attribute is passed to the application or
+ * checked for validity, the XML processor must normalize it as follows: 
+ * - a character reference is processed by appending the referenced
+ *   character to the attribute value
+ * - an entity reference is processed by recursively processing the
+ *   replacement text of the entity 
+ * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
+ *   appending #x20 to the normalized value, except that only a single
+ *   #x20 is appended for a "#xD#xA" sequence that is part of an external
+ *   parsed entity or the literal entity value of an internal parsed entity 
+ * - other characters are processed by appending them to the normalized value 
+ * If the declared value is not CDATA, then the XML processor must further
+ * process the normalized attribute value by discarding any leading and
+ * trailing space (#x20) characters, and by replacing sequences of space
+ * (#x20) characters by a single space (#x20) character.  
+ * All attributes for which no declaration has been read should be treated
+ * by a non-validating parser as if declared CDATA.
+ *
+ * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
+ */
+
+
+xmlChar *
+xmlParseAttValue(xmlParserCtxtPtr ctxt) {
+    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
+    return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
+}
+
+/**
+ * xmlParseSystemLiteral:
+ * @ctxt:  an XML parser context
+ * 
+ * parse an XML Literal
+ *
+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
+ *
+ * Returns the SystemLiteral parsed or NULL
+ */
+
+xmlChar *
+xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = XML_PARSER_BUFFER_SIZE;
+    int cur, l;
+    xmlChar stop;
+    int state = ctxt->instate;
+    int count = 0;
+
+    SHRINK;
+    if (RAW == '"') {
+        NEXT;
+	stop = '"';
+    } else if (RAW == '\'') {
+        NEXT;
+	stop = '\'';
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
+	return(NULL);
+    }
+    
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+        xmlErrMemory(ctxt, NULL);
+	return(NULL);
+    }
+    ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
+    cur = CUR_CHAR(l);
+    while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
+	if (len + 5 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+	        xmlFree(buf);
+		xmlErrMemory(ctxt, NULL);
+		ctxt->instate = (xmlParserInputState) state;
+		return(NULL);
+	    }
+	    buf = tmp;
+	}
+	count++;
+	if (count > 50) {
+	    GROW;
+	    count = 0;
+            if (ctxt->instate == XML_PARSER_EOF) {
+	        xmlFree(buf);
+		return(NULL);
+            }
+	}
+	COPY_BUF(l,buf,len,cur);
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+	if (cur == 0) {
+	    GROW;
+	    SHRINK;
+	    cur = CUR_CHAR(l);
+	}
+    }
+    buf[len] = 0;
+    ctxt->instate = (xmlParserInputState) state;
+    if (!IS_CHAR(cur)) {
+	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
+    } else {
+	NEXT;
+    }
+    return(buf);
+}
+
+/**
+ * xmlParsePubidLiteral:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML public literal
+ *
+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
+ *
+ * Returns the PubidLiteral parsed or NULL.
+ */
+
+xmlChar *
+xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = XML_PARSER_BUFFER_SIZE;
+    xmlChar cur;
+    xmlChar stop;
+    int count = 0;
+    xmlParserInputState oldstate = ctxt->instate;
+
+    SHRINK;
+    if (RAW == '"') {
+        NEXT;
+	stop = '"';
+    } else if (RAW == '\'') {
+        NEXT;
+	stop = '\'';
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
+	return(NULL);
+    }
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+	xmlErrMemory(ctxt, NULL);
+	return(NULL);
+    }
+    ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
+    cur = CUR;
+    while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
+	if (len + 1 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+		xmlErrMemory(ctxt, NULL);
+		xmlFree(buf);
+		return(NULL);
+	    }
+	    buf = tmp;
+	}
+	buf[len++] = cur;
+	count++;
+	if (count > 50) {
+	    GROW;
+	    count = 0;
+            if (ctxt->instate == XML_PARSER_EOF) {
+		xmlFree(buf);
+		return(NULL);
+            }
+	}
+	NEXT;
+	cur = CUR;
+	if (cur == 0) {
+	    GROW;
+	    SHRINK;
+	    cur = CUR;
+	}
+    }
+    buf[len] = 0;
+    if (cur != stop) {
+	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
+    } else {
+	NEXT;
+    }
+    ctxt->instate = oldstate;
+    return(buf);
+}
+
+static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
+
+/*
+ * used for the test in the inner loop of the char data testing
+ */
+static const unsigned char test_char_data[256] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
+    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/**
+ * xmlParseCharData:
+ * @ctxt:  an XML parser context
+ * @cdata:  int indicating whether we are within a CDATA section
+ *
+ * parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * The right angle bracket (>) may be represented using the string "&gt;",
+ * and must, for compatibility, be escaped using "&gt;" or a character
+ * reference when it appears in the string "]]>" in content, when that
+ * string is not marking the end of a CDATA section. 
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+void
+xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
+    const xmlChar *in;
+    int nbchar = 0;
+    int line = ctxt->input->line;
+    int col = ctxt->input->col;
+    int ccol;
+
+    SHRINK;
+    GROW;
+    /*
+     * Accelerated common case where input don't need to be
+     * modified before passing it to the handler.
+     */
+    if (!cdata) {
+	in = ctxt->input->cur;
+	do {
+get_more_space:
+	    while (*in == 0x20) { in++; ctxt->input->col++; }
+	    if (*in == 0xA) {
+		do {
+		    ctxt->input->line++; ctxt->input->col = 1;
+		    in++;
+		} while (*in == 0xA);
+		goto get_more_space;
+	    }
+	    if (*in == '<') {
+		nbchar = in - ctxt->input->cur;
+		if (nbchar > 0) {
+		    const xmlChar *tmp = ctxt->input->cur;
+		    ctxt->input->cur = in;
+
+		    if ((ctxt->sax != NULL) &&
+		        (ctxt->sax->ignorableWhitespace !=
+		         ctxt->sax->characters)) {
+			if (areBlanks(ctxt, tmp, nbchar, 1)) {
+			    if (ctxt->sax->ignorableWhitespace != NULL)
+				ctxt->sax->ignorableWhitespace(ctxt->userData,
+						       tmp, nbchar);
+			} else {
+			    if (ctxt->sax->characters != NULL)
+				ctxt->sax->characters(ctxt->userData,
+						      tmp, nbchar);
+			    if (*ctxt->space == -1)
+			        *ctxt->space = -2;
+			}
+		    } else if ((ctxt->sax != NULL) &&
+		               (ctxt->sax->characters != NULL)) {
+			ctxt->sax->characters(ctxt->userData,
+					      tmp, nbchar);
+		    }
+		}
+		return;
+	    }
+
+get_more:
+            ccol = ctxt->input->col;
+	    while (test_char_data[*in]) {
+		in++;
+		ccol++;
+	    }
+	    ctxt->input->col = ccol;
+	    if (*in == 0xA) {
+		do {
+		    ctxt->input->line++; ctxt->input->col = 1;
+		    in++;
+		} while (*in == 0xA);
+		goto get_more;
+	    }
+	    if (*in == ']') {
+		if ((in[1] == ']') && (in[2] == '>')) {
+		    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
+		    ctxt->input->cur = in;
+		    return;
+		}
+		in++;
+		ctxt->input->col++;
+		goto get_more;
+	    }
+	    nbchar = in - ctxt->input->cur;
+	    if (nbchar > 0) {
+		if ((ctxt->sax != NULL) &&
+		    (ctxt->sax->ignorableWhitespace !=
+		     ctxt->sax->characters) &&
+		    (IS_BLANK_CH(*ctxt->input->cur))) {
+		    const xmlChar *tmp = ctxt->input->cur;
+		    ctxt->input->cur = in;
+
+		    if (areBlanks(ctxt, tmp, nbchar, 0)) {
+		        if (ctxt->sax->ignorableWhitespace != NULL)
+			    ctxt->sax->ignorableWhitespace(ctxt->userData,
+							   tmp, nbchar);
+		    } else {
+		        if (ctxt->sax->characters != NULL)
+			    ctxt->sax->characters(ctxt->userData,
+						  tmp, nbchar);
+			if (*ctxt->space == -1)
+			    *ctxt->space = -2;
+		    }
+                    line = ctxt->input->line;
+                    col = ctxt->input->col;
+		} else if (ctxt->sax != NULL) {
+		    if (ctxt->sax->characters != NULL)
+			ctxt->sax->characters(ctxt->userData,
+					      ctxt->input->cur, nbchar);
+                    line = ctxt->input->line;
+                    col = ctxt->input->col;
+		}
+                /* something really bad happened in the SAX callback */
+                if (ctxt->instate != XML_PARSER_CONTENT)
+                    return;
+	    }
+	    ctxt->input->cur = in;
+	    if (*in == 0xD) {
+		in++;
+		if (*in == 0xA) {
+		    ctxt->input->cur = in;
+		    in++;
+		    ctxt->input->line++; ctxt->input->col = 1;
+		    continue; /* while */
+		}
+		in--;
+	    }
+	    if (*in == '<') {
+		return;
+	    }
+	    if (*in == '&') {
+		return;
+	    }
+	    SHRINK;
+	    GROW;
+            if (ctxt->instate == XML_PARSER_EOF)
+		return;
+	    in = ctxt->input->cur;
+	} while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
+	nbchar = 0;
+    }
+    ctxt->input->line = line;
+    ctxt->input->col = col;
+    xmlParseCharDataComplex(ctxt, cdata);
+}
+
+/**
+ * xmlParseCharDataComplex:
+ * @ctxt:  an XML parser context
+ * @cdata:  int indicating whether we are within a CDATA section
+ *
+ * parse a CharData section.this is the fallback function
+ * of xmlParseCharData() when the parsing requires handling
+ * of non-ASCII characters.
+ */
+static void
+xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
+    xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
+    int nbchar = 0;
+    int cur, l;
+    int count = 0;
+
+    SHRINK;
+    GROW;
+    cur = CUR_CHAR(l);
+    while ((cur != '<') && /* checked */
+           (cur != '&') && 
+	   (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
+	if ((cur == ']') && (NXT(1) == ']') &&
+	    (NXT(2) == '>')) {
+	    if (cdata) break;
+	    else {
+		xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
+	    }
+	}
+	COPY_BUF(l,buf,nbchar,cur);
+	if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
+	    buf[nbchar] = 0;
+
+	    /*
+	     * OK the segment is to be consumed as chars.
+	     */
+	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+		if (areBlanks(ctxt, buf, nbchar, 0)) {
+		    if (ctxt->sax->ignorableWhitespace != NULL)
+			ctxt->sax->ignorableWhitespace(ctxt->userData,
+			                               buf, nbchar);
+		} else {
+		    if (ctxt->sax->characters != NULL)
+			ctxt->sax->characters(ctxt->userData, buf, nbchar);
+		    if ((ctxt->sax->characters !=
+		         ctxt->sax->ignorableWhitespace) &&
+			(*ctxt->space == -1))
+			*ctxt->space = -2;
+		}
+	    }
+	    nbchar = 0;
+            /* something really bad happened in the SAX callback */
+            if (ctxt->instate != XML_PARSER_CONTENT)
+                return;
+	}
+	count++;
+	if (count > 50) {
+	    GROW;
+	    count = 0;
+            if (ctxt->instate == XML_PARSER_EOF)
+		return;
+	}
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+    }
+    if (nbchar != 0) {
+        buf[nbchar] = 0;
+	/*
+	 * OK the segment is to be consumed as chars.
+	 */
+	if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+	    if (areBlanks(ctxt, buf, nbchar, 0)) {
+		if (ctxt->sax->ignorableWhitespace != NULL)
+		    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
+	    } else {
+		if (ctxt->sax->characters != NULL)
+		    ctxt->sax->characters(ctxt->userData, buf, nbchar);
+		if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
+		    (*ctxt->space == -1))
+		    *ctxt->space = -2;
+	    }
+	}
+    }
+    if ((cur != 0) && (!IS_CHAR(cur))) {
+	/* Generate the error and skip the offending character */
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "PCDATA invalid Char value %d\n",
+	                  cur);
+	NEXTL(l);
+    }
+}
+
+/**
+ * xmlParseExternalID:
+ * @ctxt:  an XML parser context
+ * @publicID:  a xmlChar** receiving PubidLiteral
+ * @strict: indicate whether we should restrict parsing to only
+ *          production [75], see NOTE below
+ *
+ * Parse an External ID or a Public ID
+ *
+ * NOTE: Productions [75] and [83] interact badly since [75] can generate
+ *       'PUBLIC' S PubidLiteral S SystemLiteral
+ *
+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
+ *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
+ *
+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
+ *
+ * Returns the function returns SystemLiteral and in the second
+ *                case publicID receives PubidLiteral, is strict is off
+ *                it is possible to return NULL and have publicID set.
+ */
+
+xmlChar *
+xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
+    xmlChar *URI = NULL;
+
+    SHRINK;
+
+    *publicID = NULL;
+    if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
+        SKIP(6);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+	                   "Space required after 'SYSTEM'\n");
+	}
+        SKIP_BLANKS;
+	URI = xmlParseSystemLiteral(ctxt);
+	if (URI == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
+        }
+    } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
+        SKIP(6);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		    "Space required after 'PUBLIC'\n");
+	}
+        SKIP_BLANKS;
+	*publicID = xmlParsePubidLiteral(ctxt);
+	if (*publicID == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
+	}
+	if (strict) {
+	    /*
+	     * We don't handle [83] so "S SystemLiteral" is required.
+	     */
+	    if (!IS_BLANK_CH(CUR)) {
+		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			"Space required after the Public Identifier\n");
+	    }
+	} else {
+	    /*
+	     * We handle [83] so we return immediately, if 
+	     * "S SystemLiteral" is not detected. From a purely parsing
+	     * point of view that's a nice mess.
+	     */
+	    const xmlChar *ptr;
+	    GROW;
+
+	    ptr = CUR_PTR;
+	    if (!IS_BLANK_CH(*ptr)) return(NULL);
+	    
+	    while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
+	    if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
+	}
+        SKIP_BLANKS;
+	URI = xmlParseSystemLiteral(ctxt);
+	if (URI == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
+        }
+    }
+    return(URI);
+}
+
+/**
+ * xmlParseCommentComplex:
+ * @ctxt:  an XML parser context
+ * @buf:  the already parsed part of the buffer
+ * @len:  number of bytes filles in the buffer
+ * @size:  allocated size of the buffer
+ *
+ * Skip an XML (SGML) comment <!-- .... -->
+ *  The spec says that "For compatibility, the string "--" (double-hyphen)
+ *  must not occur within comments. "
+ * This is the slow routine in case the accelerator for ascii didn't work
+ *
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ */
+static void
+xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
+    int q, ql;
+    int r, rl;
+    int cur, l;
+    int count = 0;
+    int inputid;
+
+    inputid = ctxt->input->id;
+
+    if (buf == NULL) {
+        len = 0;
+	size = XML_PARSER_BUFFER_SIZE;
+	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+	if (buf == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    return;
+	}
+    }
+    GROW;	/* Assure there's enough input data */
+    q = CUR_CHAR(ql);
+    if (q == 0)
+        goto not_terminated;
+    if (!IS_CHAR(q)) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "xmlParseComment: invalid xmlChar value %d\n",
+	                  q);
+	xmlFree (buf);
+	return;
+    }
+    NEXTL(ql);
+    r = CUR_CHAR(rl);
+    if (r == 0)
+        goto not_terminated;
+    if (!IS_CHAR(r)) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "xmlParseComment: invalid xmlChar value %d\n",
+	                  q);
+	xmlFree (buf);
+	return;
+    }
+    NEXTL(rl);
+    cur = CUR_CHAR(l);
+    if (cur == 0)
+        goto not_terminated;
+    while (IS_CHAR(cur) && /* checked */
+           ((cur != '>') ||
+	    (r != '-') || (q != '-'))) {
+	if ((r == '-') && (q == '-')) {
+	    xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
+	}
+	if (len + 5 >= size) {
+	    xmlChar *new_buf;
+	    size *= 2;
+	    new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (new_buf == NULL) {
+		xmlFree (buf);
+		xmlErrMemory(ctxt, NULL);
+		return;
+	    }
+	    buf = new_buf;
+	}
+	COPY_BUF(ql,buf,len,q);
+	q = r;
+	ql = rl;
+	r = cur;
+	rl = l;
+
+	count++;
+	if (count > 50) {
+	    GROW;
+	    count = 0;
+            if (ctxt->instate == XML_PARSER_EOF) {
+		xmlFree(buf);
+		return;
+            }
+	}
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+	if (cur == 0) {
+	    SHRINK;
+	    GROW;
+	    cur = CUR_CHAR(l);
+	}
+    }
+    buf[len] = 0;
+    if (cur == 0) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+	                     "Comment not terminated \n<!--%.50s\n", buf);
+    } else if (!IS_CHAR(cur)) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "xmlParseComment: invalid xmlChar value %d\n",
+	                  cur);
+    } else {
+	if (inputid != ctxt->input->id) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+		"Comment doesn't start and stop in the same entity\n");
+	}
+        NEXT;
+	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
+	    (!ctxt->disableSAX))
+	    ctxt->sax->comment(ctxt->userData, buf);
+    }
+    xmlFree(buf);
+    return;
+not_terminated:
+    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+			 "Comment not terminated\n", NULL);
+    xmlFree(buf);
+    return;
+}
+
+/**
+ * xmlParseComment:
+ * @ctxt:  an XML parser context
+ *
+ * Skip an XML (SGML) comment <!-- .... -->
+ *  The spec says that "For compatibility, the string "--" (double-hyphen)
+ *  must not occur within comments. "
+ *
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ */
+void
+xmlParseComment(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int size = XML_PARSER_BUFFER_SIZE;
+    int len = 0;
+    xmlParserInputState state;
+    const xmlChar *in;
+    int nbchar = 0, ccol;
+    int inputid;
+
+    /*
+     * Check that there is a comment right here.
+     */
+    if ((RAW != '<') || (NXT(1) != '!') ||
+        (NXT(2) != '-') || (NXT(3) != '-')) return;
+    state = ctxt->instate;
+    ctxt->instate = XML_PARSER_COMMENT;
+    inputid = ctxt->input->id;
+    SKIP(4);
+    SHRINK;
+    GROW;
+
+    /*
+     * Accelerated common case where input don't need to be
+     * modified before passing it to the handler.
+     */
+    in = ctxt->input->cur;
+    do {
+	if (*in == 0xA) {
+	    do {
+		ctxt->input->line++; ctxt->input->col = 1;
+		in++;
+	    } while (*in == 0xA);
+	}
+get_more:
+        ccol = ctxt->input->col;
+	while (((*in > '-') && (*in <= 0x7F)) ||
+	       ((*in >= 0x20) && (*in < '-')) ||
+	       (*in == 0x09)) {
+		    in++;
+		    ccol++;
+	}
+	ctxt->input->col = ccol;
+	if (*in == 0xA) {
+	    do {
+		ctxt->input->line++; ctxt->input->col = 1;
+		in++;
+	    } while (*in == 0xA);
+	    goto get_more;
+	}
+	nbchar = in - ctxt->input->cur;
+	/*
+	 * save current set of data
+	 */
+	if (nbchar > 0) {
+	    if ((ctxt->sax != NULL) &&
+		(ctxt->sax->comment != NULL)) {
+		if (buf == NULL) {
+		    if ((*in == '-') && (in[1] == '-'))
+		        size = nbchar + 1;
+		    else
+		        size = XML_PARSER_BUFFER_SIZE + nbchar;
+		    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+		    if (buf == NULL) {
+		        xmlErrMemory(ctxt, NULL);
+			ctxt->instate = state;
+			return;
+		    }
+		    len = 0;
+		} else if (len + nbchar + 1 >= size) {
+		    xmlChar *new_buf;
+		    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
+		    new_buf = (xmlChar *) xmlRealloc(buf,
+		                                     size * sizeof(xmlChar));
+		    if (new_buf == NULL) {
+		        xmlFree (buf);
+			xmlErrMemory(ctxt, NULL);
+			ctxt->instate = state;
+			return;
+		    }
+		    buf = new_buf;
+		}
+		memcpy(&buf[len], ctxt->input->cur, nbchar);
+		len += nbchar;
+		buf[len] = 0;
+	    }
+	}
+	ctxt->input->cur = in;
+	if (*in == 0xA) {
+	    in++;
+	    ctxt->input->line++; ctxt->input->col = 1;
+	}
+	if (*in == 0xD) {
+	    in++;
+	    if (*in == 0xA) {
+		ctxt->input->cur = in;
+		in++;
+		ctxt->input->line++; ctxt->input->col = 1;
+		continue; /* while */
+	    }
+	    in--;
+	}
+	SHRINK;
+	GROW;
+        if (ctxt->instate == XML_PARSER_EOF) {
+            xmlFree(buf);
+            return;
+	}
+	in = ctxt->input->cur;
+	if (*in == '-') {
+	    if (in[1] == '-') {
+	        if (in[2] == '>') {
+		    if (ctxt->input->id != inputid) {
+			xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+			"comment doesn't start and stop in the same entity\n");
+		    }
+		    SKIP(3);
+		    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
+		        (!ctxt->disableSAX)) {
+			if (buf != NULL)
+			    ctxt->sax->comment(ctxt->userData, buf);
+			else
+			    ctxt->sax->comment(ctxt->userData, BAD_CAST "");
+		    }
+		    if (buf != NULL)
+		        xmlFree(buf);
+		    if (ctxt->instate != XML_PARSER_EOF)
+			ctxt->instate = state;
+		    return;
+		}
+		if (buf != NULL)
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+		                      "Comment not terminated \n<!--%.50s\n",
+				      buf);
+		else
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+		                      "Comment not terminated \n", NULL);
+		in++;
+		ctxt->input->col++;
+	    }
+	    in++;
+	    ctxt->input->col++;
+	    goto get_more;
+	}
+    } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
+    xmlParseCommentComplex(ctxt, buf, len, size);
+    ctxt->instate = state;
+    return;
+}
+
+
+/**
+ * xmlParsePITarget:
+ * @ctxt:  an XML parser context
+ * 
+ * parse the name of a PI
+ *
+ * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
+ *
+ * Returns the PITarget name or NULL
+ */
+
+const xmlChar *
+xmlParsePITarget(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+
+    name = xmlParseName(ctxt);
+    if ((name != NULL) &&
+        ((name[0] == 'x') || (name[0] == 'X')) &&
+        ((name[1] == 'm') || (name[1] == 'M')) &&
+        ((name[2] == 'l') || (name[2] == 'L'))) {
+	int i;
+	if ((name[0] == 'x') && (name[1] == 'm') &&
+	    (name[2] == 'l') && (name[3] == 0)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
+		 "XML declaration allowed only at the start of the document\n");
+	    return(name);
+	} else if (name[3] == 0) {
+	    xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
+	    return(name);
+	}
+	for (i = 0;;i++) {
+	    if (xmlW3CPIs[i] == NULL) break;
+	    if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
+	        return(name);
+	}
+	xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
+		      "xmlParsePITarget: invalid name prefix 'xml'\n",
+		      NULL, NULL);
+    }
+    if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
+	xmlNsErr(ctxt, XML_NS_ERR_COLON, 
+		 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
+    }
+    return(name);
+}
+
+#ifdef LIBXML_CATALOG_ENABLED
+/**
+ * xmlParseCatalogPI:
+ * @ctxt:  an XML parser context
+ * @catalog:  the PI value string
+ * 
+ * parse an XML Catalog Processing Instruction.
+ *
+ * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
+ *
+ * Occurs only if allowed by the user and if happening in the Misc
+ * part of the document before any doctype informations
+ * This will add the given catalog to the parsing context in order
+ * to be used if there is a resolution need further down in the document
+ */
+
+static void
+xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
+    xmlChar *URL = NULL;
+    const xmlChar *tmp, *base;
+    xmlChar marker;
+
+    tmp = catalog;
+    while (IS_BLANK_CH(*tmp)) tmp++;
+    if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
+	goto error;
+    tmp += 7;
+    while (IS_BLANK_CH(*tmp)) tmp++;
+    if (*tmp != '=') {
+	return;
+    }
+    tmp++;
+    while (IS_BLANK_CH(*tmp)) tmp++;
+    marker = *tmp;
+    if ((marker != '\'') && (marker != '"'))
+	goto error;
+    tmp++;
+    base = tmp;
+    while ((*tmp != 0) && (*tmp != marker)) tmp++;
+    if (*tmp == 0)
+	goto error;
+    URL = xmlStrndup(base, tmp - base);
+    tmp++;
+    while (IS_BLANK_CH(*tmp)) tmp++;
+    if (*tmp != 0)
+	goto error;
+
+    if (URL != NULL) {
+	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
+	xmlFree(URL);
+    }
+    return;
+
+error:
+    xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
+	          "Catalog PI syntax error: %s\n",
+		  catalog, NULL);
+    if (URL != NULL)
+	xmlFree(URL);
+}
+#endif
+
+/**
+ * xmlParsePI:
+ * @ctxt:  an XML parser context
+ * 
+ * parse an XML Processing Instruction.
+ *
+ * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ *
+ * The processing is transfered to SAX once parsed.
+ */
+
+void
+xmlParsePI(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = XML_PARSER_BUFFER_SIZE;
+    int cur, l;
+    const xmlChar *target;
+    xmlParserInputState state;
+    int count = 0;
+
+    if ((RAW == '<') && (NXT(1) == '?')) {
+	xmlParserInputPtr input = ctxt->input;
+	state = ctxt->instate;
+        ctxt->instate = XML_PARSER_PI;
+	/*
+	 * this is a Processing Instruction.
+	 */
+	SKIP(2);
+	SHRINK;
+
+	/*
+	 * Parse the target name and check for special support like
+	 * namespace.
+	 */
+        target = xmlParsePITarget(ctxt);
+	if (target != NULL) {
+	    if ((RAW == '?') && (NXT(1) == '>')) {
+		if (input != ctxt->input) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+	    "PI declaration doesn't start and stop in the same entity\n");
+		}
+		SKIP(2);
+
+		/*
+		 * SAX: PI detected.
+		 */
+		if ((ctxt->sax) && (!ctxt->disableSAX) &&
+		    (ctxt->sax->processingInstruction != NULL))
+		    ctxt->sax->processingInstruction(ctxt->userData,
+		                                     target, NULL);
+		if (ctxt->instate != XML_PARSER_EOF)
+		    ctxt->instate = state;
+		return;
+	    }
+	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+	    if (buf == NULL) {
+		xmlErrMemory(ctxt, NULL);
+		ctxt->instate = state;
+		return;
+	    }
+	    cur = CUR;
+	    if (!IS_BLANK(cur)) {
+		xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
+			  "ParsePI: PI %s space expected\n", target);
+	    }
+            SKIP_BLANKS;
+	    cur = CUR_CHAR(l);
+	    while (IS_CHAR(cur) && /* checked */
+		   ((cur != '?') || (NXT(1) != '>'))) {
+		if (len + 5 >= size) {
+		    xmlChar *tmp;
+
+		    size *= 2;
+		    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+		    if (tmp == NULL) {
+			xmlErrMemory(ctxt, NULL);
+			xmlFree(buf);
+			ctxt->instate = state;
+			return;
+		    }
+		    buf = tmp;
+		}
+		count++;
+		if (count > 50) {
+		    GROW;
+                    if (ctxt->instate == XML_PARSER_EOF) {
+                        xmlFree(buf);
+                        return;
+                    }
+		    count = 0;
+		}
+		COPY_BUF(l,buf,len,cur);
+		NEXTL(l);
+		cur = CUR_CHAR(l);
+		if (cur == 0) {
+		    SHRINK;
+		    GROW;
+		    cur = CUR_CHAR(l);
+		}
+	    }
+	    buf[len] = 0;
+	    if (cur != '?') {
+		xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
+		      "ParsePI: PI %s never end ...\n", target);
+	    } else {
+		if (input != ctxt->input) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+	    "PI declaration doesn't start and stop in the same entity\n");
+		}
+		SKIP(2);
+
+#ifdef LIBXML_CATALOG_ENABLED
+		if (((state == XML_PARSER_MISC) ||
+	             (state == XML_PARSER_START)) &&
+		    (xmlStrEqual(target, XML_CATALOG_PI))) {
+		    xmlCatalogAllow allow = xmlCatalogGetDefaults();
+		    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
+			(allow == XML_CATA_ALLOW_ALL))
+			xmlParseCatalogPI(ctxt, buf);
+		}
+#endif
+
+
+		/*
+		 * SAX: PI detected.
+		 */
+		if ((ctxt->sax) && (!ctxt->disableSAX) &&
+		    (ctxt->sax->processingInstruction != NULL))
+		    ctxt->sax->processingInstruction(ctxt->userData,
+		                                     target, buf);
+	    }
+	    xmlFree(buf);
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
+	}
+	if (ctxt->instate != XML_PARSER_EOF)
+	    ctxt->instate = state;
+    }
+}
+
+/**
+ * xmlParseNotationDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse a notation declaration
+ *
+ * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
+ *
+ * Hence there is actually 3 choices:
+ *     'PUBLIC' S PubidLiteral
+ *     'PUBLIC' S PubidLiteral S SystemLiteral
+ * and 'SYSTEM' S SystemLiteral
+ *
+ * See the NOTE on xmlParseExternalID().
+ */
+
+void
+xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlChar *Pubid;
+    xmlChar *Systemid;
+    
+    if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
+	xmlParserInputPtr input = ctxt->input;
+	SHRINK;
+	SKIP(10);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after '<!NOTATION'\n");
+	    return;
+	}
+	SKIP_BLANKS;
+
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
+	    return;
+	}
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		     "Space required after the NOTATION name'\n");
+	    return;
+	}
+	if (xmlStrchr(name, ':') != NULL) {
+	    xmlNsErr(ctxt, XML_NS_ERR_COLON, 
+		     "colon are forbidden from notation names '%s'\n",
+		     name, NULL, NULL);
+	}
+	SKIP_BLANKS;
+
+	/*
+	 * Parse the IDs.
+	 */
+	Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
+	SKIP_BLANKS;
+
+	if (RAW == '>') {
+	    if (input != ctxt->input) {
+		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+	"Notation declaration doesn't start and stop in the same entity\n");
+	    }
+	    NEXT;
+	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+		(ctxt->sax->notationDecl != NULL))
+		ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
+	}
+	if (Systemid != NULL) xmlFree(Systemid);
+	if (Pubid != NULL) xmlFree(Pubid);
+    }
+}
+
+/**
+ * xmlParseEntityDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse <!ENTITY declarations
+ *
+ * [70] EntityDecl ::= GEDecl | PEDecl
+ *
+ * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
+ *
+ * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
+ *
+ * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
+ *
+ * [74] PEDef ::= EntityValue | ExternalID
+ *
+ * [76] NDataDecl ::= S 'NDATA' S Name
+ *
+ * [ VC: Notation Declared ]
+ * The Name must match the declared name of a notation.
+ */
+
+void
+xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name = NULL;
+    xmlChar *value = NULL;
+    xmlChar *URI = NULL, *literal = NULL;
+    const xmlChar *ndata = NULL;
+    int isParameter = 0;
+    xmlChar *orig = NULL;
+    int skipped;
+    
+    /* GROW; done in the caller */
+    if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
+	xmlParserInputPtr input = ctxt->input;
+	SHRINK;
+	SKIP(8);
+	skipped = SKIP_BLANKS;
+	if (skipped == 0) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after '<!ENTITY'\n");
+	}
+
+	if (RAW == '%') {
+	    NEXT;
+	    skipped = SKIP_BLANKS;
+	    if (skipped == 0) {
+		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			       "Space required after '%'\n");
+	    }
+	    isParameter = 1;
+	}
+
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+	                   "xmlParseEntityDecl: no name\n");
+            return;
+	}
+	if (xmlStrchr(name, ':') != NULL) {
+	    xmlNsErr(ctxt, XML_NS_ERR_COLON, 
+		     "colon are forbidden from entities names '%s'\n",
+		     name, NULL, NULL);
+	}
+        skipped = SKIP_BLANKS;
+	if (skipped == 0) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after the entity name\n");
+	}
+
+	ctxt->instate = XML_PARSER_ENTITY_DECL;
+	/*
+	 * handle the various case of definitions...
+	 */
+	if (isParameter) {
+	    if ((RAW == '"') || (RAW == '\'')) {
+	        value = xmlParseEntityValue(ctxt, &orig);
+		if (value) {
+		    if ((ctxt->sax != NULL) &&
+			(!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
+			ctxt->sax->entityDecl(ctxt->userData, name,
+		                    XML_INTERNAL_PARAMETER_ENTITY,
+				    NULL, NULL, value);
+		}
+	    } else {
+	        URI = xmlParseExternalID(ctxt, &literal, 1);
+		if ((URI == NULL) && (literal == NULL)) {
+		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
+		}
+		if (URI) {
+		    xmlURIPtr uri;
+
+		    uri = xmlParseURI((const char *) URI);
+		    if (uri == NULL) {
+		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
+				     "Invalid URI: %s\n", URI);
+			/*
+			 * This really ought to be a well formedness error
+			 * but the XML Core WG decided otherwise c.f. issue
+			 * E26 of the XML erratas.
+			 */
+		    } else {
+			if (uri->fragment != NULL) {
+			    /*
+			     * Okay this is foolish to block those but not
+			     * invalid URIs.
+			     */
+			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
+			} else {
+			    if ((ctxt->sax != NULL) &&
+				(!ctxt->disableSAX) &&
+				(ctxt->sax->entityDecl != NULL))
+				ctxt->sax->entityDecl(ctxt->userData, name,
+					    XML_EXTERNAL_PARAMETER_ENTITY,
+					    literal, URI, NULL);
+			}
+			xmlFreeURI(uri);
+		    }
+		}
+	    }
+	} else {
+	    if ((RAW == '"') || (RAW == '\'')) {
+	        value = xmlParseEntityValue(ctxt, &orig);
+		if ((ctxt->sax != NULL) &&
+		    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
+		    ctxt->sax->entityDecl(ctxt->userData, name,
+				XML_INTERNAL_GENERAL_ENTITY,
+				NULL, NULL, value);
+		/*
+		 * For expat compatibility in SAX mode.
+		 */
+		if ((ctxt->myDoc == NULL) ||
+		    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
+		    if (ctxt->myDoc == NULL) {
+			ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
+			if (ctxt->myDoc == NULL) {
+			    xmlErrMemory(ctxt, "New Doc failed");
+			    return;
+			}
+			ctxt->myDoc->properties = XML_DOC_INTERNAL;
+		    }
+		    if (ctxt->myDoc->intSubset == NULL)
+			ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
+					    BAD_CAST "fake", NULL, NULL);
+
+		    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
+			              NULL, NULL, value);
+		}
+	    } else {
+	        URI = xmlParseExternalID(ctxt, &literal, 1);
+		if ((URI == NULL) && (literal == NULL)) {
+		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
+		}
+		if (URI) {
+		    xmlURIPtr uri;
+
+		    uri = xmlParseURI((const char *)URI);
+		    if (uri == NULL) {
+		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
+				     "Invalid URI: %s\n", URI);
+			/*
+			 * This really ought to be a well formedness error
+			 * but the XML Core WG decided otherwise c.f. issue
+			 * E26 of the XML erratas.
+			 */
+		    } else {
+			if (uri->fragment != NULL) {
+			    /*
+			     * Okay this is foolish to block those but not
+			     * invalid URIs.
+			     */
+			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
+			}
+			xmlFreeURI(uri);
+		    }
+		}
+		if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+				   "Space required before 'NDATA'\n");
+		}
+		SKIP_BLANKS;
+		if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
+		    SKIP(5);
+		    if (!IS_BLANK_CH(CUR)) {
+			xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+				       "Space required after 'NDATA'\n");
+		    }
+		    SKIP_BLANKS;
+		    ndata = xmlParseName(ctxt);
+		    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+		        (ctxt->sax->unparsedEntityDecl != NULL))
+			ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
+				    literal, URI, ndata);
+		} else {
+		    if ((ctxt->sax != NULL) &&
+		        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
+			ctxt->sax->entityDecl(ctxt->userData, name,
+				    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
+				    literal, URI, NULL);
+		    /*
+		     * For expat compatibility in SAX mode.
+		     * assuming the entity repalcement was asked for
+		     */
+		    if ((ctxt->replaceEntities != 0) &&
+			((ctxt->myDoc == NULL) ||
+			(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
+			if (ctxt->myDoc == NULL) {
+			    ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
+			    if (ctxt->myDoc == NULL) {
+			        xmlErrMemory(ctxt, "New Doc failed");
+				return;
+			    }
+			    ctxt->myDoc->properties = XML_DOC_INTERNAL;
+			}
+
+			if (ctxt->myDoc->intSubset == NULL)
+			    ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
+						BAD_CAST "fake", NULL, NULL);
+			xmlSAX2EntityDecl(ctxt, name,
+				          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
+				          literal, URI, NULL);
+		    }
+		}
+	    }
+	}
+	if (ctxt->instate == XML_PARSER_EOF)
+	    return;
+	SKIP_BLANKS;
+	if (RAW != '>') {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
+	            "xmlParseEntityDecl: entity %s not terminated\n", name);
+	} else {
+	    if (input != ctxt->input) {
+		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+	"Entity declaration doesn't start and stop in the same entity\n");
+	    }
+	    NEXT;
+	}
+	if (orig != NULL) {
+	    /*
+	     * Ugly mechanism to save the raw entity value.
+	     */
+	    xmlEntityPtr cur = NULL;
+
+	    if (isParameter) {
+	        if ((ctxt->sax != NULL) &&
+		    (ctxt->sax->getParameterEntity != NULL))
+		    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
+	    } else {
+	        if ((ctxt->sax != NULL) &&
+		    (ctxt->sax->getEntity != NULL))
+		    cur = ctxt->sax->getEntity(ctxt->userData, name);
+		if ((cur == NULL) && (ctxt->userData==ctxt)) {
+		    cur = xmlSAX2GetEntity(ctxt, name);
+		}
+	    }
+            if (cur != NULL) {
+	        if (cur->orig != NULL)
+		    xmlFree(orig);
+		else
+		    cur->orig = orig;
+	    } else
+		xmlFree(orig);
+	}
+	if (value != NULL) xmlFree(value);
+	if (URI != NULL) xmlFree(URI);
+	if (literal != NULL) xmlFree(literal);
+    }
+}
+
+/**
+ * xmlParseDefaultDecl:
+ * @ctxt:  an XML parser context
+ * @value:  Receive a possible fixed default value for the attribute
+ *
+ * Parse an attribute default declaration
+ *
+ * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
+ *
+ * [ VC: Required Attribute ]
+ * if the default declaration is the keyword #REQUIRED, then the
+ * attribute must be specified for all elements of the type in the
+ * attribute-list declaration.
+ *
+ * [ VC: Attribute Default Legal ]
+ * The declared default value must meet the lexical constraints of
+ * the declared attribute type c.f. xmlValidateAttributeDecl()
+ *
+ * [ VC: Fixed Attribute Default ]
+ * if an attribute has a default value declared with the #FIXED
+ * keyword, instances of that attribute must match the default value. 
+ *
+ * [ WFC: No < in Attribute Values ]
+ * handled in xmlParseAttValue()
+ *
+ * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
+ *          or XML_ATTRIBUTE_FIXED. 
+ */
+
+int
+xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
+    int val;
+    xmlChar *ret;
+
+    *value = NULL;
+    if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
+	SKIP(9);
+	return(XML_ATTRIBUTE_REQUIRED);
+    }
+    if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
+	SKIP(8);
+	return(XML_ATTRIBUTE_IMPLIED);
+    }
+    val = XML_ATTRIBUTE_NONE;
+    if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
+	SKIP(6);
+	val = XML_ATTRIBUTE_FIXED;
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after '#FIXED'\n");
+	}
+	SKIP_BLANKS;
+    }
+    ret = xmlParseAttValue(ctxt);
+    ctxt->instate = XML_PARSER_DTD;
+    if (ret == NULL) {
+	xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
+		       "Attribute default value declaration error\n");
+    } else
+        *value = ret;
+    return(val);
+}
+
+/**
+ * xmlParseNotationType:
+ * @ctxt:  an XML parser context
+ *
+ * parse an Notation attribute type.
+ *
+ * Note: the leading 'NOTATION' S part has already being parsed...
+ *
+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ *
+ * [ VC: Notation Attributes ]
+ * Values of this type must match one of the notation names included
+ * in the declaration; all notation names in the declaration must be declared. 
+ *
+ * Returns: the notation attribute tree built while parsing
+ */
+
+xmlEnumerationPtr
+xmlParseNotationType(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
+
+    if (RAW != '(') {
+	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
+	return(NULL);
+    }
+    SHRINK;
+    do {
+        NEXT;
+	SKIP_BLANKS;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+			   "Name expected in NOTATION declaration\n");
+            xmlFreeEnumeration(ret);
+	    return(NULL);
+	}
+	tmp = ret;
+	while (tmp != NULL) {
+	    if (xmlStrEqual(name, tmp->name)) {
+		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
+	  "standalone: attribute notation value token %s duplicated\n",
+				 name, NULL);
+		if (!xmlDictOwns(ctxt->dict, name))
+		    xmlFree((xmlChar *) name);
+		break;
+	    }
+	    tmp = tmp->next;
+	}
+	if (tmp == NULL) {
+	    cur = xmlCreateEnumeration(name);
+	    if (cur == NULL) {
+                xmlFreeEnumeration(ret);
+                return(NULL);
+            }
+	    if (last == NULL) ret = last = cur;
+	    else {
+		last->next = cur;
+		last = cur;
+	    }
+	}
+	SKIP_BLANKS;
+    } while (RAW == '|');
+    if (RAW != ')') {
+	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
+        xmlFreeEnumeration(ret);
+	return(NULL);
+    }
+    NEXT;
+    return(ret);
+}
+
+/**
+ * xmlParseEnumerationType:
+ * @ctxt:  an XML parser context
+ *
+ * parse an Enumeration attribute type.
+ *
+ * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
+ *
+ * [ VC: Enumeration ]
+ * Values of this type must match one of the Nmtoken tokens in
+ * the declaration
+ *
+ * Returns: the enumeration attribute tree built while parsing
+ */
+
+xmlEnumerationPtr
+xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
+    xmlChar *name;
+    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
+
+    if (RAW != '(') {
+	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
+	return(NULL);
+    }
+    SHRINK;
+    do {
+        NEXT;
+	SKIP_BLANKS;
+        name = xmlParseNmtoken(ctxt);
+	if (name == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
+	    return(ret);
+	}
+	tmp = ret;
+	while (tmp != NULL) {
+	    if (xmlStrEqual(name, tmp->name)) {
+		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
+	  "standalone: attribute enumeration value token %s duplicated\n",
+				 name, NULL);
+		if (!xmlDictOwns(ctxt->dict, name))
+		    xmlFree(name);
+		break;
+	    }
+	    tmp = tmp->next;
+	}
+	if (tmp == NULL) {
+	    cur = xmlCreateEnumeration(name);
+	    if (!xmlDictOwns(ctxt->dict, name))
+		xmlFree(name);
+	    if (cur == NULL) {
+                xmlFreeEnumeration(ret);
+                return(NULL);
+            }
+	    if (last == NULL) ret = last = cur;
+	    else {
+		last->next = cur;
+		last = cur;
+	    }
+	}
+	SKIP_BLANKS;
+    } while (RAW == '|');
+    if (RAW != ')') {
+	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
+	return(ret);
+    }
+    NEXT;
+    return(ret);
+}
+
+/**
+ * xmlParseEnumeratedType:
+ * @ctxt:  an XML parser context
+ * @tree:  the enumeration tree built while parsing
+ *
+ * parse an Enumerated attribute type.
+ *
+ * [57] EnumeratedType ::= NotationType | Enumeration
+ *
+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ *
+ *
+ * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
+ */
+
+int
+xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
+    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
+	SKIP(8);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after 'NOTATION'\n");
+	    return(0);
+	}
+        SKIP_BLANKS;
+	*tree = xmlParseNotationType(ctxt);
+	if (*tree == NULL) return(0);
+	return(XML_ATTRIBUTE_NOTATION);
+    }
+    *tree = xmlParseEnumerationType(ctxt);
+    if (*tree == NULL) return(0);
+    return(XML_ATTRIBUTE_ENUMERATION);
+}
+
+/**
+ * xmlParseAttributeType:
+ * @ctxt:  an XML parser context
+ * @tree:  the enumeration tree built while parsing
+ *
+ * parse the Attribute list def for an element
+ *
+ * [54] AttType ::= StringType | TokenizedType | EnumeratedType
+ *
+ * [55] StringType ::= 'CDATA'
+ *
+ * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
+ *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
+ *
+ * Validity constraints for attribute values syntax are checked in
+ * xmlValidateAttributeValue()
+ *
+ * [ VC: ID ]
+ * Values of type ID must match the Name production. A name must not
+ * appear more than once in an XML document as a value of this type;
+ * i.e., ID values must uniquely identify the elements which bear them.
+ *
+ * [ VC: One ID per Element Type ]
+ * No element type may have more than one ID attribute specified.
+ *
+ * [ VC: ID Attribute Default ]
+ * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
+ *
+ * [ VC: IDREF ]
+ * Values of type IDREF must match the Name production, and values
+ * of type IDREFS must match Names; each IDREF Name must match the value
+ * of an ID attribute on some element in the XML document; i.e. IDREF
+ * values must match the value of some ID attribute.
+ *
+ * [ VC: Entity Name ]
+ * Values of type ENTITY must match the Name production, values
+ * of type ENTITIES must match Names; each Entity Name must match the
+ * name of an unparsed entity declared in the DTD.  
+ *
+ * [ VC: Name Token ]
+ * Values of type NMTOKEN must match the Nmtoken production; values
+ * of type NMTOKENS must match Nmtokens. 
+ *
+ * Returns the attribute type
+ */
+int 
+xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
+    SHRINK;
+    if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
+	SKIP(5);
+	return(XML_ATTRIBUTE_CDATA);
+     } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
+	SKIP(6);
+	return(XML_ATTRIBUTE_IDREFS);
+     } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
+	SKIP(5);
+	return(XML_ATTRIBUTE_IDREF);
+     } else if ((RAW == 'I') && (NXT(1) == 'D')) {
+        SKIP(2);
+	return(XML_ATTRIBUTE_ID);
+     } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
+	SKIP(6);
+	return(XML_ATTRIBUTE_ENTITY);
+     } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
+	SKIP(8);
+	return(XML_ATTRIBUTE_ENTITIES);
+     } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
+	SKIP(8);
+	return(XML_ATTRIBUTE_NMTOKENS);
+     } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
+	SKIP(7);
+	return(XML_ATTRIBUTE_NMTOKEN);
+     }
+     return(xmlParseEnumeratedType(ctxt, tree));
+}
+
+/**
+ * xmlParseAttributeListDecl:
+ * @ctxt:  an XML parser context
+ *
+ * : parse the Attribute list def for an element
+ *
+ * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
+ *
+ * [53] AttDef ::= S Name S AttType S DefaultDecl
+ *
+ */
+void
+xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
+    const xmlChar *elemName;
+    const xmlChar *attrName;
+    xmlEnumerationPtr tree;
+
+    if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
+	xmlParserInputPtr input = ctxt->input;
+
+	SKIP(9);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		                 "Space required after '<!ATTLIST'\n");
+	}
+        SKIP_BLANKS;
+        elemName = xmlParseName(ctxt);
+	if (elemName == NULL) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+			   "ATTLIST: no name for Element\n");
+	    return;
+	}
+	SKIP_BLANKS;
+	GROW;
+	while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
+	    const xmlChar *check = CUR_PTR;
+	    int type;
+	    int def;
+	    xmlChar *defaultValue = NULL;
+
+	    GROW;
+            tree = NULL;
+	    attrName = xmlParseName(ctxt);
+	    if (attrName == NULL) {
+		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+			       "ATTLIST: no name for Attribute\n");
+		break;
+	    }
+	    GROW;
+	    if (!IS_BLANK_CH(CUR)) {
+		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		        "Space required after the attribute name\n");
+		break;
+	    }
+	    SKIP_BLANKS;
+
+	    type = xmlParseAttributeType(ctxt, &tree);
+	    if (type <= 0) {
+	        break;
+	    }
+
+	    GROW;
+	    if (!IS_BLANK_CH(CUR)) {
+		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			       "Space required after the attribute type\n");
+	        if (tree != NULL)
+		    xmlFreeEnumeration(tree);
+		break;
+	    }
+	    SKIP_BLANKS;
+
+	    def = xmlParseDefaultDecl(ctxt, &defaultValue);
+	    if (def <= 0) {
+                if (defaultValue != NULL)
+		    xmlFree(defaultValue);
+	        if (tree != NULL)
+		    xmlFreeEnumeration(tree);
+	        break;
+	    }
+	    if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
+	        xmlAttrNormalizeSpace(defaultValue, defaultValue);
+
+	    GROW;
+            if (RAW != '>') {
+		if (!IS_BLANK_CH(CUR)) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			"Space required after the attribute default value\n");
+		    if (defaultValue != NULL)
+			xmlFree(defaultValue);
+		    if (tree != NULL)
+			xmlFreeEnumeration(tree);
+		    break;
+		}
+		SKIP_BLANKS;
+	    }
+	    if (check == CUR_PTR) {
+		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		            "in xmlParseAttributeListDecl\n");
+		if (defaultValue != NULL)
+		    xmlFree(defaultValue);
+	        if (tree != NULL)
+		    xmlFreeEnumeration(tree);
+		break;
+	    }
+	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+		(ctxt->sax->attributeDecl != NULL))
+		ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
+	                        type, def, defaultValue, tree);
+	    else if (tree != NULL)
+		xmlFreeEnumeration(tree);
+
+	    if ((ctxt->sax2) && (defaultValue != NULL) &&
+	        (def != XML_ATTRIBUTE_IMPLIED) && 
+		(def != XML_ATTRIBUTE_REQUIRED)) {
+		xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
+	    }
+	    if (ctxt->sax2) {
+		xmlAddSpecialAttr(ctxt, elemName, attrName, type);
+	    }
+	    if (defaultValue != NULL)
+	        xmlFree(defaultValue);
+	    GROW;
+	}
+	if (RAW == '>') {
+	    if (input != ctxt->input) {
+		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+    "Attribute list declaration doesn't start and stop in the same entity\n",
+                                 NULL, NULL);
+	    }
+	    NEXT;
+	}
+    }
+}
+
+/**
+ * xmlParseElementMixedContentDecl:
+ * @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
+ * 
+ * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
+ *                '(' S? '#PCDATA' S? ')'
+ *
+ * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
+ *
+ * [ VC: No Duplicate Types ]
+ * The same name must not appear more than once in a single
+ * mixed-content declaration. 
+ *
+ * returns: the list of the xmlElementContentPtr describing the element choices
+ */
+xmlElementContentPtr
+xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
+    xmlElementContentPtr ret = NULL, cur = NULL, n;
+    const xmlChar *elem = NULL;
+
+    GROW;
+    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
+	SKIP(7);
+	SKIP_BLANKS;
+	SHRINK;
+	if (RAW == ')') {
+	    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",
+                                 NULL, NULL);
+	    }
+	    NEXT;
+	    ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
+	    if (ret == NULL)
+	        return(NULL);
+	    if (RAW == '*') {
+		ret->ocur = XML_ELEMENT_CONTENT_MULT;
+		NEXT;
+	    }
+	    return(ret);
+	}
+	if ((RAW == '(') || (RAW == '|')) {
+	    ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
+	    if (ret == NULL) return(NULL);
+	}
+	while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
+	    NEXT;
+	    if (elem == NULL) {
+	        ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
+		if (ret == NULL) return(NULL);
+		ret->c1 = cur;
+		if (cur != NULL)
+		    cur->parent = ret;
+		cur = ret;
+	    } else {
+	        n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
+		if (n == NULL) return(NULL);
+		n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
+		if (n->c1 != NULL)
+		    n->c1->parent = n;
+	        cur->c2 = n;
+		if (n != NULL)
+		    n->parent = cur;
+		cur = n;
+	    }
+	    SKIP_BLANKS;
+	    elem = xmlParseName(ctxt);
+	    if (elem == NULL) {
+		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+			"xmlParseElementMixedContentDecl : Name expected\n");
+		xmlFreeDocElementContent(ctxt->myDoc, cur);
+		return(NULL);
+	    }
+	    SKIP_BLANKS;
+	    GROW;
+	}
+	if ((RAW == ')') && (NXT(1) == '*')) {
+	    if (elem != NULL) {
+		cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
+		                               XML_ELEMENT_CONTENT_ELEMENT);
+		if (cur->c2 != NULL)
+		    cur->c2->parent = cur;
+            }
+            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",
+				 NULL, NULL);
+	    }
+	    SKIP(2);
+	} else {
+	    xmlFreeDocElementContent(ctxt->myDoc, ret);
+	    xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
+	    return(NULL);
+	}
+
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
+    }
+    return(ret);
+}
+
+/**
+ * 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
+ * 
+ *
+ * [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.
+ */
+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 == '(') {
+	int inputid = ctxt->input->id;
+
+        /* Recurse on first child */
+	NEXT;
+	SKIP_BLANKS;
+        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+                                                           depth + 1);
+	SKIP_BLANKS;
+	GROW;
+    } else {
+	elem = xmlParseName(ctxt);
+	if (elem == NULL) {
+	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
+	    return(NULL);
+	}
+        cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
+	if (cur == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    return(NULL);
+	}
+	GROW;
+	if (RAW == '?') {
+	    cur->ocur = XML_ELEMENT_CONTENT_OPT;
+	    NEXT;
+	} else if (RAW == '*') {
+	    cur->ocur = XML_ELEMENT_CONTENT_MULT;
+	    NEXT;
+	} else if (RAW == '+') {
+	    cur->ocur = XML_ELEMENT_CONTENT_PLUS;
+	    NEXT;
+	} else {
+	    cur->ocur = XML_ELEMENT_CONTENT_ONCE;
+	}
+	GROW;
+    }
+    SKIP_BLANKS;
+    SHRINK;
+    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
+        /*
+	 * Each loop we parse one separator and one element.
+	 */
+        if (RAW == ',') {
+	    if (type == 0) type = CUR;
+
+	    /*
+	     * Detect "Name | Name , Name" error
+	     */
+	    else if (type != CUR) {
+		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
+		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
+		                  type);
+		if ((last != NULL) && (last != ret))
+		    xmlFreeDocElementContent(ctxt->myDoc, last);
+		if (ret != NULL)
+		    xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    NEXT;
+
+	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
+	    if (op == NULL) {
+		if ((last != NULL) && (last != ret))
+		    xmlFreeDocElementContent(ctxt->myDoc, last);
+	        xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    if (last == NULL) {
+		op->c1 = ret;
+		if (ret != NULL)
+		    ret->parent = op;
+		ret = cur = op;
+	    } else {
+	        cur->c2 = op;
+		if (op != NULL)
+		    op->parent = cur;
+		op->c1 = last;
+		if (last != NULL)
+		    last->parent = op;
+		cur =op;
+		last = NULL;
+	    }
+	} else if (RAW == '|') {
+	    if (type == 0) type = CUR;
+
+	    /*
+	     * Detect "Name , Name | Name" error
+	     */
+	    else if (type != CUR) {
+		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
+		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
+				  type);
+		if ((last != NULL) && (last != ret))
+		    xmlFreeDocElementContent(ctxt->myDoc, last);
+		if (ret != NULL)
+		    xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    NEXT;
+
+	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
+	    if (op == NULL) {
+		if ((last != NULL) && (last != ret))
+		    xmlFreeDocElementContent(ctxt->myDoc, last);
+		if (ret != NULL)
+		    xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    if (last == NULL) {
+		op->c1 = ret;
+		if (ret != NULL)
+		    ret->parent = op;
+		ret = cur = op;
+	    } else {
+	        cur->c2 = op;
+		if (op != NULL)
+		    op->parent = cur;
+		op->c1 = last;
+		if (last != NULL)
+		    last->parent = op;
+		cur =op;
+		last = NULL;
+	    }
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
+	    if ((last != NULL) && (last != ret))
+	        xmlFreeDocElementContent(ctxt->myDoc, last);
+	    if (ret != NULL)
+		xmlFreeDocElementContent(ctxt->myDoc, ret);
+	    return(NULL);
+	}
+	GROW;
+	SKIP_BLANKS;
+	GROW;
+	if (RAW == '(') {
+	    int inputid = ctxt->input->id;
+	    /* Recurse on second child */
+	    NEXT;
+	    SKIP_BLANKS;
+	    last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+                                                          depth + 1);
+	    SKIP_BLANKS;
+	} else {
+	    elem = xmlParseName(ctxt);
+	    if (elem == NULL) {
+		xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
+		if (ret != NULL)
+		    xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
+	    if (last == NULL) {
+		if (ret != NULL)
+		    xmlFreeDocElementContent(ctxt->myDoc, ret);
+		return(NULL);
+	    }
+	    if (RAW == '?') {
+		last->ocur = XML_ELEMENT_CONTENT_OPT;
+		NEXT;
+	    } else if (RAW == '*') {
+		last->ocur = XML_ELEMENT_CONTENT_MULT;
+		NEXT;
+	    } else if (RAW == '+') {
+		last->ocur = XML_ELEMENT_CONTENT_PLUS;
+		NEXT;
+	    } else {
+		last->ocur = XML_ELEMENT_CONTENT_ONCE;
+	    }
+	}
+	SKIP_BLANKS;
+	GROW;
+    }
+    if ((cur != NULL) && (last != NULL)) {
+        cur->c2 = last;
+	if (last != NULL)
+	    last->parent = cur;
+    }
+    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",
+			 NULL, NULL);
+    }
+    NEXT;
+    if (RAW == '?') {
+	if (ret != NULL) {
+	    if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
+	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
+	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
+	    else
+	        ret->ocur = XML_ELEMENT_CONTENT_OPT;
+	}
+	NEXT;
+    } else if (RAW == '*') {
+	if (ret != NULL) {
+	    ret->ocur = XML_ELEMENT_CONTENT_MULT;
+	    cur = ret;
+	    /*
+	     * Some normalization:
+	     * (a | b* | c?)* == (a | b | c)*
+	     */
+	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
+		if ((cur->c1 != NULL) &&
+	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
+		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
+		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
+		if ((cur->c2 != NULL) &&
+	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
+		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
+		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
+		cur = cur->c2;
+	    }
+	}
+	NEXT;
+    } else if (RAW == '+') {
+	if (ret != NULL) {
+	    int found = 0;
+
+	    if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
+	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
+	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
+	    else
+	        ret->ocur = XML_ELEMENT_CONTENT_PLUS;
+	    /*
+	     * Some normalization:
+	     * (a | b*)+ == (a | b)*
+	     * (a | b?)+ == (a | b)*
+	     */
+	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
+		if ((cur->c1 != NULL) &&
+	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
+		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
+		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
+		    found = 1;
+		}
+		if ((cur->c2 != NULL) &&
+	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
+		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
+		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
+		    found = 1;
+		}
+		cur = cur->c2;
+	    }
+	    if (found)
+		ret->ocur = XML_ELEMENT_CONTENT_MULT;
+	}
+	NEXT;
+    }
+    return(ret);
+}
+
+/**
+ * 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.
+ * @result:  the Element Content pointer will be stored here if any
+ *
+ * parse the declaration for an Element content either Mixed or Children,
+ * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
+ * 
+ * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
+ *
+ * returns: the type of element content XML_ELEMENT_TYPE_xxx
+ */
+
+int
+xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
+                           xmlElementContentPtr *result) {
+
+    xmlElementContentPtr tree = NULL;
+    int inputid = ctxt->input->id;
+    int res;
+
+    *result = NULL;
+
+    if (RAW != '(') {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
+		"xmlParseElementContentDecl : %s '(' expected\n", name);
+	return(-1);
+    }
+    NEXT;
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(-1);
+    SKIP_BLANKS;
+    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
+        tree = xmlParseElementMixedContentDecl(ctxt, inputid);
+	res = XML_ELEMENT_TYPE_MIXED;
+    } else {
+        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
+	res = XML_ELEMENT_TYPE_ELEMENT;
+    }
+    SKIP_BLANKS;
+    *result = tree;
+    return(res);
+}
+
+/**
+ * xmlParseElementDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse an Element declaration.
+ *
+ * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
+ *
+ * [ VC: Unique Element Type Declaration ]
+ * No element type may be declared more than once
+ *
+ * Returns the type of the element, or -1 in case of error
+ */
+int
+xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    int ret = -1;
+    xmlElementContentPtr content  = NULL;
+
+    /* GROW; done in the caller */
+    if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
+	xmlParserInputPtr input = ctxt->input;
+
+	SKIP(9);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		           "Space required after 'ELEMENT'\n");
+	}
+        SKIP_BLANKS;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+			   "xmlParseElementDecl: no name for Element\n");
+	    return(-1);
+	}
+	while ((RAW == 0) && (ctxt->inputNr > 1))
+	    xmlPopInput(ctxt);
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "Space required after the element name\n");
+	}
+        SKIP_BLANKS;
+	if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
+	    SKIP(5);
+	    /*
+	     * Element must always be empty.
+	     */
+	    ret = XML_ELEMENT_TYPE_EMPTY;
+	} else if ((RAW == 'A') && (NXT(1) == 'N') &&
+	           (NXT(2) == 'Y')) {
+	    SKIP(3);
+	    /*
+	     * Element is a generic container.
+	     */
+	    ret = XML_ELEMENT_TYPE_ANY;
+	} else if (RAW == '(') {
+	    ret = xmlParseElementContentDecl(ctxt, name, &content);
+	} else {
+	    /*
+	     * [ WFC: PEs in Internal Subset ] error handling.
+	     */
+	    if ((RAW == '%') && (ctxt->external == 0) &&
+	        (ctxt->inputNr == 1)) {
+		xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
+	  "PEReference: forbidden within markup decl in internal subset\n");
+	    } else {
+		xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
+		      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
+            }
+	    return(-1);
+	}
+
+	SKIP_BLANKS;
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((RAW == 0) && (ctxt->inputNr > 1))
+	    xmlPopInput(ctxt);
+	SKIP_BLANKS;
+
+	if (RAW != '>') {
+	    xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
+	    if (content != NULL) {
+		xmlFreeDocElementContent(ctxt->myDoc, content);
+	    }
+	} else {
+	    if (input != ctxt->input) {
+		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+    "Element declaration doesn't start and stop in the same entity\n");
+	    }
+		
+	    NEXT;
+	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+		(ctxt->sax->elementDecl != NULL)) {
+		if (content != NULL)
+		    content->parent = NULL;
+	        ctxt->sax->elementDecl(ctxt->userData, name, ret,
+		                       content);
+		if ((content != NULL) && (content->parent == NULL)) {
+		    /*
+		     * this is a trick: if xmlAddElementDecl is called,
+		     * instead of copying the full tree it is plugged directly
+		     * if called from the parser. Avoid duplicating the 
+		     * interfaces or change the API/ABI
+		     */
+		    xmlFreeDocElementContent(ctxt->myDoc, content);
+		}
+	    } else if (content != NULL) {
+		xmlFreeDocElementContent(ctxt->myDoc, content);
+	    }
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlParseConditionalSections
+ * @ctxt:  an XML parser context
+ *
+ * [61] conditionalSect ::= includeSect | ignoreSect 
+ * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
+ * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
+ * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
+ * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
+ */
+
+static void
+xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
+    int id = ctxt->input->id;
+
+    SKIP(3);
+    SKIP_BLANKS;
+    if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
+	SKIP(7);
+	SKIP_BLANKS;
+	if (RAW != '[') {
+	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	} else {
+	    if (ctxt->input->id != id) {
+		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+	    "All markup of the conditional section is not in the same entity\n",
+				     NULL, NULL);
+	    }
+	    NEXT;
+	}
+	if (xmlParserDebugEntities) {
+	    if ((ctxt->input != NULL) && (ctxt->input->filename))
+		xmlGenericError(xmlGenericErrorContext,
+			"%s(%d): ", ctxt->input->filename,
+			ctxt->input->line);
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Entering INCLUDE Conditional Section\n");
+	}
+
+	while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
+	        (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
+	    const xmlChar *check = CUR_PTR;
+	    unsigned int cons = ctxt->input->consumed;
+
+	    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+		xmlParseConditionalSections(ctxt);
+	    } else if (IS_BLANK_CH(CUR)) {
+		NEXT;
+	    } else if (RAW == '%') {
+		xmlParsePEReference(ctxt);
+	    } else
+		xmlParseMarkupDecl(ctxt);
+
+	    /*
+	     * Pop-up of finished entities.
+	     */
+	    while ((RAW == 0) && (ctxt->inputNr > 1))
+		xmlPopInput(ctxt);
+
+	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+		break;
+	    }
+	}
+	if (xmlParserDebugEntities) {
+	    if ((ctxt->input != NULL) && (ctxt->input->filename))
+		xmlGenericError(xmlGenericErrorContext,
+			"%s(%d): ", ctxt->input->filename,
+			ctxt->input->line);
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Leaving INCLUDE Conditional Section\n");
+	}
+
+    } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
+	int state;
+	xmlParserInputState instate;
+	int depth = 0;
+
+	SKIP(6);
+	SKIP_BLANKS;
+	if (RAW != '[') {
+	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	} else {
+	    if (ctxt->input->id != id) {
+		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+	    "All markup of the conditional section is not in the same entity\n",
+				     NULL, NULL);
+	    }
+	    NEXT;
+	}
+	if (xmlParserDebugEntities) {
+	    if ((ctxt->input != NULL) && (ctxt->input->filename))
+		xmlGenericError(xmlGenericErrorContext,
+			"%s(%d): ", ctxt->input->filename,
+			ctxt->input->line);
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Entering IGNORE Conditional Section\n");
+	}
+
+	/*
+	 * Parse up to the end of the conditional section
+	 * But disable SAX event generating DTD building in the meantime
+	 */
+	state = ctxt->disableSAX;
+	instate = ctxt->instate;
+	if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+	ctxt->instate = XML_PARSER_IGNORE;
+
+	while (((depth >= 0) && (RAW != 0)) &&
+               (ctxt->instate != XML_PARSER_EOF)) {
+	  if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+	    depth++;
+	    SKIP(3);
+	    continue;
+	  }
+	  if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
+	    if (--depth >= 0) SKIP(3);
+	    continue;
+	  }
+	  NEXT;
+	  continue;
+	}
+
+	ctxt->disableSAX = state;
+	ctxt->instate = instate;
+
+	if (xmlParserDebugEntities) {
+	    if ((ctxt->input != NULL) && (ctxt->input->filename))
+		xmlGenericError(xmlGenericErrorContext,
+			"%s(%d): ", ctxt->input->filename,
+			ctxt->input->line);
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Leaving IGNORE Conditional Section\n");
+	}
+
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+    }
+
+    if (RAW == 0)
+        SHRINK;
+
+    if (RAW == 0) {
+	xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
+    } else {
+	if (ctxt->input->id != id) {
+	    xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
+	"All markup of the conditional section is not in the same entity\n",
+				 NULL, NULL);
+	}
+        SKIP(3);
+    }
+}
+
+/**
+ * xmlParseMarkupDecl:
+ * @ctxt:  an XML parser context
+ * 
+ * parse Markup declarations
+ *
+ * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
+ *                     NotationDecl | PI | Comment
+ *
+ * [ VC: Proper Declaration/PE Nesting ]
+ * Parameter-entity replacement text must be properly nested with
+ * markup declarations. That is to say, if either the first character
+ * or the last character of a markup declaration (markupdecl above) is
+ * contained in the replacement text for a parameter-entity reference,
+ * both must be contained in the same replacement text.
+ *
+ * [ WFC: PEs in Internal Subset ]
+ * In the internal DTD subset, parameter-entity references can occur
+ * only where markup declarations can occur, not within markup declarations.
+ * (This does not apply to references that occur in external parameter
+ * entities or to the external subset.) 
+ */
+void
+xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
+    GROW;
+    if (CUR == '<') {
+        if (NXT(1) == '!') {
+	    switch (NXT(2)) {
+	        case 'E':
+		    if (NXT(3) == 'L')
+			xmlParseElementDecl(ctxt);
+		    else if (NXT(3) == 'N')
+			xmlParseEntityDecl(ctxt);
+		    break;
+	        case 'A':
+		    xmlParseAttributeListDecl(ctxt);
+		    break;
+	        case 'N':
+		    xmlParseNotationDecl(ctxt);
+		    break;
+	        case '-':
+		    xmlParseComment(ctxt);
+		    break;
+		default:
+		    /* there is an error but it will be detected later */
+		    break;
+	    }
+	} else if (NXT(1) == '?') {
+	    xmlParsePI(ctxt);
+	}
+    }
+    /*
+     * This is only for internal subset. On external entities,
+     * the replacement is done before parsing stage
+     */
+    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
+	xmlParsePEReference(ctxt);
+
+    /*
+     * Conditional sections are allowed from entities included
+     * by PE References in the internal subset.
+     */
+    if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
+        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+	    xmlParseConditionalSections(ctxt);
+	}
+    }
+
+    ctxt->instate = XML_PARSER_DTD;
+}
+
+/**
+ * xmlParseTextDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML declaration header for external entities
+ *
+ * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
+ */
+
+void
+xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
+    xmlChar *version;
+    const xmlChar *encoding;
+
+    /*
+     * We know that '<?xml' is here.
+     */
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+	SKIP(5);
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
+	return;
+    }
+
+    if (!IS_BLANK_CH(CUR)) {
+	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		       "Space needed after '<?xml'\n");
+    }
+    SKIP_BLANKS;
+
+    /*
+     * We may have the VersionInfo here.
+     */
+    version = xmlParseVersionInfo(ctxt);
+    if (version == NULL)
+	version = xmlCharStrdup(XML_DEFAULT_VERSION);
+    else {
+	if (!IS_BLANK_CH(CUR)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+		           "Space needed here\n");
+	}
+    }
+    ctxt->input->version = version;
+
+    /*
+     * We must have the encoding declaration
+     */
+    encoding = xmlParseEncodingDecl(ctxt);
+    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	/*
+	 * The XML REC instructs us to stop parsing right here
+	 */
+        return;
+    }
+    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
+	xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
+		       "Missing encoding in text declaration\n");
+    }
+
+    SKIP_BLANKS;
+    if ((RAW == '?') && (NXT(1) == '>')) {
+        SKIP(2);
+    } else if (RAW == '>') {
+        /* Deprecated old WD ... */
+	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
+	NEXT;
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
+	MOVETO_ENDTAG(CUR_PTR);
+	NEXT;
+    }
+}
+
+/**
+ * xmlParseExternalSubset:
+ * @ctxt:  an XML parser context
+ * @ExternalID: the external identifier
+ * @SystemID: the system identifier (or URL)
+ * 
+ * parse Markup declarations from an external subset
+ *
+ * [30] extSubset ::= textDecl? extSubsetDecl
+ *
+ * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
+ */
+void
+xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
+                       const xmlChar *SystemID) {
+    xmlDetectSAX2(ctxt);
+    GROW;
+
+    if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+        (ctxt->input->end - ctxt->input->cur >= 4)) {
+        xmlChar start[4];
+	xmlCharEncoding enc;
+
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(start, 4);
+	if (enc != XML_CHAR_ENCODING_NONE)
+	    xmlSwitchEncoding(ctxt, enc);
+    }
+
+    if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
+	xmlParseTextDecl(ctxt);
+	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	    /*
+	     * The XML REC instructs us to stop parsing right here
+	     */
+	    ctxt->instate = XML_PARSER_EOF;
+	    return;
+	}
+    }
+    if (ctxt->myDoc == NULL) {
+        ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
+	if (ctxt->myDoc == NULL) {
+	    xmlErrMemory(ctxt, "New Doc failed");
+	    return;
+	}
+	ctxt->myDoc->properties = XML_DOC_INTERNAL;
+    }
+    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
+        xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
+
+    ctxt->instate = XML_PARSER_DTD;
+    ctxt->external = 1;
+    while (((RAW == '<') && (NXT(1) == '?')) ||
+           ((RAW == '<') && (NXT(1) == '!')) ||
+	   (RAW == '%') || IS_BLANK_CH(CUR)) {
+	const xmlChar *check = CUR_PTR;
+	unsigned int cons = ctxt->input->consumed;
+
+	GROW;
+        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+	    xmlParseConditionalSections(ctxt);
+	} else if (IS_BLANK_CH(CUR)) {
+	    NEXT;
+	} else if (RAW == '%') {
+            xmlParsePEReference(ctxt);
+	} else
+	    xmlParseMarkupDecl(ctxt);
+
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((RAW == 0) && (ctxt->inputNr > 1))
+	    xmlPopInput(ctxt);
+
+	if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+	    xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+	    break;
+	}
+    }
+
+    if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+    }
+
+}
+
+/**
+ * xmlParseReference:
+ * @ctxt:  an XML parser context
+ *
+ * parse and handle entity references in content, depending on the SAX
+ * interface, this may end-up in a call to character() if this is a
+ * CharRef, a predefined entity, if there is no reference() callback.
+ * or if the parser was asked to switch to that mode.
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ */
+void
+xmlParseReference(xmlParserCtxtPtr ctxt) {
+    xmlEntityPtr ent;
+    xmlChar *val;
+    int was_checked;
+    xmlNodePtr list = NULL;
+    xmlParserErrors ret = XML_ERR_OK;
+
+
+    if (RAW != '&')
+        return;
+
+    /*
+     * Simple case of a CharRef
+     */
+    if (NXT(1) == '#') {
+	int i = 0;
+	xmlChar out[10];
+	int hex = NXT(2);
+	int value = xmlParseCharRef(ctxt);
+
+	if (value == 0)
+	    return;
+	if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
+	    /*
+	     * So we are using non-UTF-8 buffers
+	     * Check that the char fit on 8bits, if not
+	     * generate a CharRef.
+	     */
+	    if (value <= 0xFF) {
+		out[0] = value;
+		out[1] = 0;
+		if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
+		    (!ctxt->disableSAX))
+		    ctxt->sax->characters(ctxt->userData, out, 1);
+	    } else {
+		if ((hex == 'x') || (hex == 'X'))
+		    snprintf((char *)out, sizeof(out), "#x%X", value);
+		else
+		    snprintf((char *)out, sizeof(out), "#%d", value);
+		if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
+		    (!ctxt->disableSAX))
+		    ctxt->sax->reference(ctxt->userData, out);
+	    }
+	} else {
+	    /*
+	     * Just encode the value in UTF-8
+	     */
+	    COPY_BUF(0 ,out, i, value);
+	    out[i] = 0;
+	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
+		(!ctxt->disableSAX))
+		ctxt->sax->characters(ctxt->userData, out, i);
+	}
+	return;
+    }
+
+    /*
+     * We are seeing an entity reference
+     */
+    ent = xmlParseEntityRef(ctxt);
+    if (ent == NULL) return;
+    if (!ctxt->wellFormed)
+	return;
+    was_checked = ent->checked;
+
+    /* special case of predefined entities */
+    if ((ent->name == NULL) ||
+        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+	val = ent->content;
+	if (val == NULL) return;
+	/*
+	 * inline the entity.
+	 */
+	if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
+	    (!ctxt->disableSAX))
+	    ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
+	return;
+    }
+
+    /*
+     * The first reference to the entity trigger a parsing phase
+     * where the ent->children is filled with the result from
+     * the parsing.
+     */
+    if (ent->checked == 0) {
+	unsigned long oldnbent = ctxt->nbentities;
+
+	/*
+	 * This is a bit hackish but this seems the best
+	 * way to make sure both SAX and DOM entity support
+	 * behaves okay.
+	 */
+	void *user_data;
+	if (ctxt->userData == ctxt)
+	    user_data = NULL;
+	else
+	    user_data = ctxt->userData;
+
+	/*
+	 * Check that this entity is well formed
+	 * 4.3.2: An internal general parsed entity is well-formed
+	 * if its replacement text matches the production labeled
+	 * content.
+	 */
+	if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
+	    ctxt->depth++;
+	    ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
+	                                              user_data, &list);
+	    ctxt->depth--;
+
+	} else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
+	    ctxt->depth++;
+	    ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
+	                                   user_data, ctxt->depth, ent->URI,
+					   ent->ExternalID, &list);
+	    ctxt->depth--;
+	} else {
+	    ret = XML_ERR_ENTITY_PE_INTERNAL;
+	    xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
+			 "invalid entity type found\n", NULL);
+	}
+
+	/*
+	 * Store the number of entities needing parsing for this entity
+	 * content and do checkings
+	 */
+	ent->checked = ctxt->nbentities - oldnbent;
+	if (ret == XML_ERR_ENTITY_LOOP) {
+	    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+	    xmlFreeNodeList(list);
+	    return;
+	}
+	if (xmlParserEntityCheck(ctxt, 0, ent)) {
+	    xmlFreeNodeList(list);
+	    return;
+	}
+
+	if ((ret == XML_ERR_OK) && (list != NULL)) {
+	    if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
+	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
+		(ent->children == NULL)) {
+		ent->children = list;
+		if (ctxt->replaceEntities) {
+		    /*
+		     * Prune it directly in the generated document
+		     * except for single text nodes.
+		     */
+		    if (((list->type == XML_TEXT_NODE) &&
+			 (list->next == NULL)) ||
+			(ctxt->parseMode == XML_PARSE_READER)) {
+			list->parent = (xmlNodePtr) ent;
+			list = NULL;
+			ent->owner = 1;
+		    } else {
+			ent->owner = 0;
+			while (list != NULL) {
+			    list->parent = (xmlNodePtr) ctxt->node;
+			    list->doc = ctxt->myDoc;
+			    if (list->next == NULL)
+				ent->last = list;
+			    list = list->next;
+			}
+			list = ent->children;
+#ifdef LIBXML_LEGACY_ENABLED
+			if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
+			  xmlAddEntityReference(ent, list, NULL);
+#endif /* LIBXML_LEGACY_ENABLED */
+		    }
+		} else {
+		    ent->owner = 1;
+		    while (list != NULL) {
+			list->parent = (xmlNodePtr) ent;
+			if (list->next == NULL)
+			    ent->last = list;
+			list = list->next;
+		    }
+		}
+	    } else {
+		xmlFreeNodeList(list);
+		list = NULL;
+	    }
+	} else if ((ret != XML_ERR_OK) &&
+		   (ret != XML_WAR_UNDECLARED_ENTITY)) {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+		     "Entity '%s' failed to parse\n", ent->name);
+	} else if (list != NULL) {
+	    xmlFreeNodeList(list);
+	    list = NULL;
+	}
+	if (ent->checked == 0)
+	    ent->checked = 1;
+    } else if (ent->checked != 1) {
+	ctxt->nbentities += ent->checked;
+    }
+
+    /*
+     * Now that the entity content has been gathered
+     * provide it to the application, this can take different forms based
+     * on the parsing modes.
+     */
+    if (ent->children == NULL) {
+	/*
+	 * Probably running in SAX mode and the callbacks don't
+	 * build the entity content. So unless we already went
+	 * though parsing for first checking go though the entity
+	 * content to generate callbacks associated to the entity
+	 */
+	if (was_checked != 0) {
+	    void *user_data;
+	    /*
+	     * This is a bit hackish but this seems the best
+	     * way to make sure both SAX and DOM entity support
+	     * behaves okay.
+	     */
+	    if (ctxt->userData == ctxt)
+		user_data = NULL;
+	    else
+		user_data = ctxt->userData;
+
+	    if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
+		ctxt->depth++;
+		ret = xmlParseBalancedChunkMemoryInternal(ctxt,
+				   ent->content, user_data, NULL);
+		ctxt->depth--;
+	    } else if (ent->etype ==
+		       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
+		ctxt->depth++;
+		ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
+			   ctxt->sax, user_data, ctxt->depth,
+			   ent->URI, ent->ExternalID, NULL);
+		ctxt->depth--;
+	    } else {
+		ret = XML_ERR_ENTITY_PE_INTERNAL;
+		xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
+			     "invalid entity type found\n", NULL);
+	    }
+	    if (ret == XML_ERR_ENTITY_LOOP) {
+		xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+		return;
+	    }
+	}
+	if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
+	    (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
+	    /*
+	     * Entity reference callback comes second, it's somewhat
+	     * superfluous but a compatibility to historical behaviour
+	     */
+	    ctxt->sax->reference(ctxt->userData, ent->name);
+	}
+	return;
+    }
+
+    /*
+     * If we didn't get any children for the entity being built
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
+	(ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
+	/*
+	 * Create a node.
+	 */
+	ctxt->sax->reference(ctxt->userData, ent->name);
+	return;
+    }
+
+    if ((ctxt->replaceEntities) || (ent->children == NULL))  {
+	/*
+	 * There is a problem on the handling of _private for entities
+	 * (bug 155816): Should we copy the content of the field from
+	 * the entity (possibly overwriting some value set by the user
+	 * when a copy is created), should we leave it alone, or should
+	 * we try to take care of different situations?  The problem
+	 * is exacerbated by the usage of this field by the xmlReader.
+	 * To fix this bug, we look at _private on the created node
+	 * and, if it's NULL, we copy in whatever was in the entity.
+	 * If it's not NULL we leave it alone.  This is somewhat of a
+	 * hack - maybe we should have further tests to determine
+	 * what to do.
+	 */
+	if ((ctxt->node != NULL) && (ent->children != NULL)) {
+	    /*
+	     * Seems we are generating the DOM content, do
+	     * a simple tree copy for all references except the first
+	     * In the first occurrence list contains the replacement.
+	     * progressive == 2 means we are operating on the Reader
+	     * and since nodes are discarded we must copy all the time.
+	     */
+	    if (((list == NULL) && (ent->owner == 0)) ||
+		(ctxt->parseMode == XML_PARSE_READER)) {
+		xmlNodePtr nw = NULL, cur, firstChild = NULL;
+
+		/*
+		 * when operating on a reader, the entities definitions
+		 * are always owning the entities subtree.
+		if (ctxt->parseMode == XML_PARSE_READER)
+		    ent->owner = 1;
+		 */
+
+		cur = ent->children;
+		while (cur != NULL) {
+		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
+		    if (nw != NULL) {
+			if (nw->_private == NULL)
+			    nw->_private = cur->_private;
+			if (firstChild == NULL){
+			    firstChild = nw;
+			}
+			nw = xmlAddChild(ctxt->node, nw);
+		    }
+		    if (cur == ent->last) {
+			/*
+			 * needed to detect some strange empty
+			 * node cases in the reader tests
+			 */
+			if ((ctxt->parseMode == XML_PARSE_READER) &&
+			    (nw != NULL) &&
+			    (nw->type == XML_ELEMENT_NODE) &&
+			    (nw->children == NULL))
+			    nw->extra = 1;
+
+			break;
+		    }
+		    cur = cur->next;
+		}
+#ifdef LIBXML_LEGACY_ENABLED
+		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
+		  xmlAddEntityReference(ent, firstChild, nw);
+#endif /* LIBXML_LEGACY_ENABLED */
+	    } else if (list == NULL) {
+		xmlNodePtr nw = NULL, cur, next, last,
+			   firstChild = NULL;
+		/*
+		 * Copy the entity child list and make it the new
+		 * entity child list. The goal is to make sure any
+		 * ID or REF referenced will be the one from the
+		 * document content and not the entity copy.
+		 */
+		cur = ent->children;
+		ent->children = NULL;
+		last = ent->last;
+		ent->last = NULL;
+		while (cur != NULL) {
+		    next = cur->next;
+		    cur->next = NULL;
+		    cur->parent = NULL;
+		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
+		    if (nw != NULL) {
+			if (nw->_private == NULL)
+			    nw->_private = cur->_private;
+			if (firstChild == NULL){
+			    firstChild = cur;
+			}
+			xmlAddChild((xmlNodePtr) ent, nw);
+			xmlAddChild(ctxt->node, cur);
+		    }
+		    if (cur == last)
+			break;
+		    cur = next;
+		}
+		if (ent->owner == 0)
+		    ent->owner = 1;
+#ifdef LIBXML_LEGACY_ENABLED
+		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
+		  xmlAddEntityReference(ent, firstChild, nw);
+#endif /* LIBXML_LEGACY_ENABLED */
+	    } else {
+		const xmlChar *nbktext;
+
+		/*
+		 * the name change is to avoid coalescing of the
+		 * node with a possible previous text one which
+		 * would make ent->children a dangling pointer
+		 */
+		nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
+					-1);
+		if (ent->children->type == XML_TEXT_NODE)
+		    ent->children->name = nbktext;
+		if ((ent->last != ent->children) &&
+		    (ent->last->type == XML_TEXT_NODE))
+		    ent->last->name = nbktext;
+		xmlAddChildList(ctxt->node, ent->children);
+	    }
+
+	    /*
+	     * This is to avoid a nasty side effect, see
+	     * characters() in SAX.c
+	     */
+	    ctxt->nodemem = 0;
+	    ctxt->nodelen = 0;
+	    return;
+	}
+    }
+}
+
+/**
+ * xmlParseEntityRef:
+ * @ctxt:  an XML parser context
+ *
+ * parse ENTITY references declarations
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ *
+ * [ WFC: Entity Declared ]
+ * In a document without any DTD, a document with only an internal DTD
+ * subset which contains no parameter entity references, or a document
+ * with "standalone='yes'", the Name given in the entity reference
+ * must match that in an entity declaration, except that well-formed
+ * documents need not declare any of the following entities: amp, lt,
+ * gt, apos, quot.  The declaration of a parameter entity must precede
+ * any reference to it.  Similarly, the declaration of a general entity
+ * must precede any reference to it which appears in a default value in an
+ * attribute-list declaration. Note that if entities are declared in the
+ * external subset or in external parameter entities, a non-validating
+ * processor is not obligated to read and process their declarations;
+ * for such documents, the rule that an entity must be declared is a
+ * well-formedness constraint only if standalone='yes'.
+ *
+ * [ WFC: Parsed Entity ]
+ * An entity reference must not contain the name of an unparsed entity
+ *
+ * Returns the xmlEntityPtr if found, or NULL otherwise.
+ */
+xmlEntityPtr
+xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    xmlEntityPtr ent = NULL;
+
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(NULL);
+
+    if (RAW != '&')
+        return(NULL);
+    NEXT;
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "xmlParseEntityRef: no name\n");
+        return(NULL);
+    }
+    if (RAW != ';') {
+	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
+	return(NULL);
+    }
+    NEXT;
+
+    /*
+     * Predefined entites override any extra definition
+     */
+    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
+        ent = xmlGetPredefinedEntity(name);
+        if (ent != NULL)
+            return(ent);
+    }
+
+    /*
+     * Increate the number of entity references parsed
+     */
+    ctxt->nbentities++;
+
+    /*
+     * Ask first SAX for entity resolution, otherwise try the
+     * entities which may have stored in the parser context.
+     */
+    if (ctxt->sax != NULL) {
+	if (ctxt->sax->getEntity != NULL)
+	    ent = ctxt->sax->getEntity(ctxt->userData, name);
+	if ((ctxt->wellFormed == 1 ) && (ent == NULL) && 
+	    (ctxt->options & XML_PARSE_OLDSAX))
+	    ent = xmlGetPredefinedEntity(name);
+	if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
+	    (ctxt->userData==ctxt)) {
+	    ent = xmlSAX2GetEntity(ctxt, name);
+	}
+    }
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(NULL);
+    /*
+     * [ WFC: Entity Declared ]
+     * In a document without any DTD, a document with only an
+     * internal DTD subset which contains no parameter entity
+     * references, or a document with "standalone='yes'", the
+     * Name given in the entity reference must match that in an
+     * entity declaration, except that well-formed documents
+     * need not declare any of the following entities: amp, lt,
+     * gt, apos, quot.
+     * The declaration of a parameter entity must precede any
+     * reference to it.
+     * Similarly, the declaration of a general entity must
+     * precede any reference to it which appears in a default
+     * value in an attribute-list declaration. Note that if
+     * entities are declared in the external subset or in
+     * external parameter entities, a non-validating processor
+     * is not obligated to read and process their declarations;
+     * for such documents, the rule that an entity must be
+     * declared is a well-formedness constraint only if
+     * standalone='yes'.
+     */
+    if (ent == NULL) {
+	if ((ctxt->standalone == 1) ||
+	    ((ctxt->hasExternalSubset == 0) &&
+	     (ctxt->hasPErefs == 0))) {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+		     "Entity '%s' not defined\n", name);
+	} else {
+	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
+		     "Entity '%s' not defined\n", name);
+	    if ((ctxt->inSubset == 0) &&
+		(ctxt->sax != NULL) &&
+		(ctxt->sax->reference != NULL)) {
+		ctxt->sax->reference(ctxt->userData, name);
+	    }
+	}
+	ctxt->valid = 0;
+    }
+
+    /*
+     * [ WFC: Parsed Entity ]
+     * An entity reference must not contain the name of an
+     * unparsed entity
+     */
+    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
+		 "Entity reference to unparsed entity %s\n", name);
+    }
+
+    /*
+     * [ WFC: No External Entity References ]
+     * Attribute values cannot contain direct or indirect
+     * entity references to external entities.
+     */
+    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
+	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
+	     "Attribute references external entity '%s'\n", name);
+    }
+    /*
+     * [ WFC: No < in Attribute Values ]
+     * The replacement text of any entity referred to directly or
+     * indirectly in an attribute value (other than "&lt;") must
+     * not contain a <. 
+     */
+    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
+	     (ent != NULL) && (ent->content != NULL) &&
+	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
+	     (xmlStrchr(ent->content, '<'))) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
+    "'<' in entity '%s' is not allowed in attributes values\n", name);
+    }
+
+    /*
+     * Internal check, no parameter entities here ...
+     */
+    else {
+	switch (ent->etype) {
+	    case XML_INTERNAL_PARAMETER_ENTITY:
+	    case XML_EXTERNAL_PARAMETER_ENTITY:
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
+	     "Attempt to reference the parameter entity '%s'\n",
+			      name);
+	    break;
+	    default:
+	    break;
+	}
+    }
+
+    /*
+     * [ WFC: No Recursion ]
+     * A parsed entity must not contain a recursive reference
+     * to itself, either directly or indirectly. 
+     * Done somewhere else
+     */
+    return(ent);
+}
+
+/**
+ * xmlParseStringEntityRef:
+ * @ctxt:  an XML parser context
+ * @str:  a pointer to an index in the string
+ *
+ * parse ENTITY references declarations, but this version parses it from
+ * a string value.
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ *
+ * [ WFC: Entity Declared ]
+ * In a document without any DTD, a document with only an internal DTD
+ * subset which contains no parameter entity references, or a document
+ * with "standalone='yes'", the Name given in the entity reference
+ * must match that in an entity declaration, except that well-formed
+ * documents need not declare any of the following entities: amp, lt,
+ * gt, apos, quot.  The declaration of a parameter entity must precede
+ * any reference to it.  Similarly, the declaration of a general entity
+ * must precede any reference to it which appears in a default value in an
+ * attribute-list declaration. Note that if entities are declared in the
+ * external subset or in external parameter entities, a non-validating
+ * processor is not obligated to read and process their declarations;
+ * for such documents, the rule that an entity must be declared is a
+ * well-formedness constraint only if standalone='yes'.
+ *
+ * [ WFC: Parsed Entity ]
+ * An entity reference must not contain the name of an unparsed entity
+ *
+ * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
+ * is updated to the current location in the string.
+ */
+static xmlEntityPtr
+xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
+    xmlChar *name;
+    const xmlChar *ptr;
+    xmlChar cur;
+    xmlEntityPtr ent = NULL;
+
+    if ((str == NULL) || (*str == NULL))
+        return(NULL);
+    ptr = *str;
+    cur = *ptr;
+    if (cur != '&')
+	return(NULL);
+
+    ptr++;
+    name = xmlParseStringName(ctxt, &ptr);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "xmlParseStringEntityRef: no name\n");
+	*str = ptr;
+	return(NULL);
+    }
+    if (*ptr != ';') {
+	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
+        xmlFree(name);
+	*str = ptr;
+	return(NULL);
+    }
+    ptr++;
+
+
+    /*
+     * Predefined entites override any extra definition
+     */
+    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
+        ent = xmlGetPredefinedEntity(name);
+        if (ent != NULL) {
+            xmlFree(name);
+            *str = ptr;
+            return(ent);
+        }
+    }
+
+    /*
+     * Increate the number of entity references parsed
+     */
+    ctxt->nbentities++;
+
+    /*
+     * Ask first SAX for entity resolution, otherwise try the
+     * entities which may have stored in the parser context.
+     */
+    if (ctxt->sax != NULL) {
+	if (ctxt->sax->getEntity != NULL)
+	    ent = ctxt->sax->getEntity(ctxt->userData, name);
+	if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
+	    ent = xmlGetPredefinedEntity(name);
+	if ((ent == NULL) && (ctxt->userData==ctxt)) {
+	    ent = xmlSAX2GetEntity(ctxt, name);
+	}
+    }
+    if (ctxt->instate == XML_PARSER_EOF) {
+	xmlFree(name);
+	return(NULL);
+    }
+
+    /*
+     * [ WFC: Entity Declared ]
+     * In a document without any DTD, a document with only an
+     * internal DTD subset which contains no parameter entity
+     * references, or a document with "standalone='yes'", the
+     * Name given in the entity reference must match that in an
+     * entity declaration, except that well-formed documents
+     * need not declare any of the following entities: amp, lt,
+     * gt, apos, quot.
+     * The declaration of a parameter entity must precede any
+     * reference to it.
+     * Similarly, the declaration of a general entity must
+     * precede any reference to it which appears in a default
+     * value in an attribute-list declaration. Note that if
+     * entities are declared in the external subset or in
+     * external parameter entities, a non-validating processor
+     * is not obligated to read and process their declarations;
+     * for such documents, the rule that an entity must be
+     * declared is a well-formedness constraint only if
+     * standalone='yes'. 
+     */
+    if (ent == NULL) {
+	if ((ctxt->standalone == 1) ||
+	    ((ctxt->hasExternalSubset == 0) &&
+	     (ctxt->hasPErefs == 0))) {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+		     "Entity '%s' not defined\n", name);
+	} else {
+	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			  "Entity '%s' not defined\n",
+			  name);
+	}
+	/* TODO ? check regressions ctxt->valid = 0; */
+    }
+
+    /*
+     * [ WFC: Parsed Entity ]
+     * An entity reference must not contain the name of an
+     * unparsed entity
+     */
+    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
+		 "Entity reference to unparsed entity %s\n", name);
+    }
+
+    /*
+     * [ WFC: No External Entity References ]
+     * Attribute values cannot contain direct or indirect
+     * entity references to external entities.
+     */
+    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
+	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
+	 "Attribute references external entity '%s'\n", name);
+    }
+    /*
+     * [ WFC: No < in Attribute Values ]
+     * The replacement text of any entity referred to directly or
+     * indirectly in an attribute value (other than "&lt;") must
+     * not contain a <.
+     */
+    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
+	     (ent != NULL) && (ent->content != NULL) &&
+	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
+	     (xmlStrchr(ent->content, '<'))) {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
+     "'<' in entity '%s' is not allowed in attributes values\n",
+			  name);
+    }
+
+    /*
+     * Internal check, no parameter entities here ...
+     */
+    else {
+	switch (ent->etype) {
+	    case XML_INTERNAL_PARAMETER_ENTITY:
+	    case XML_EXTERNAL_PARAMETER_ENTITY:
+		xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
+	     "Attempt to reference the parameter entity '%s'\n",
+				  name);
+	    break;
+	    default:
+	    break;
+	}
+    }
+
+    /*
+     * [ WFC: No Recursion ]
+     * A parsed entity must not contain a recursive reference
+     * to itself, either directly or indirectly.
+     * Done somewhere else
+     */
+
+    xmlFree(name);
+    *str = ptr;
+    return(ent);
+}
+
+/**
+ * xmlParsePEReference:
+ * @ctxt:  an XML parser context
+ *
+ * parse PEReference declarations
+ * The entity content is handled directly by pushing it's content as
+ * a new input stream.
+ *
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * [ WFC: No Recursion ]
+ * A parsed entity must not contain a recursive
+ * reference to itself, either directly or indirectly. 
+ *
+ * [ WFC: Entity Declared ]
+ * In a document without any DTD, a document with only an internal DTD
+ * subset which contains no parameter entity references, or a document
+ * with "standalone='yes'", ...  ... The declaration of a parameter
+ * entity must precede any reference to it...
+ *
+ * [ VC: Entity Declared ]
+ * In a document with an external subset or external parameter entities
+ * with "standalone='no'", ...  ... The declaration of a parameter entity
+ * must precede any reference to it...
+ *
+ * [ WFC: In DTD ]
+ * Parameter-entity references may only appear in the DTD.
+ * NOTE: misleading but this is handled.
+ */
+void
+xmlParsePEReference(xmlParserCtxtPtr ctxt)
+{
+    const xmlChar *name;
+    xmlEntityPtr entity = NULL;
+    xmlParserInputPtr input;
+
+    if (RAW != '%')
+        return;
+    NEXT;
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "xmlParsePEReference: no name\n");
+	return;
+    }
+    if (RAW != ';') {
+	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
+        return;
+    }
+
+    NEXT;
+
+    /*
+     * Increate the number of entity references parsed
+     */
+    ctxt->nbentities++;
+
+    /*
+     * Request the entity from SAX
+     */
+    if ((ctxt->sax != NULL) &&
+	(ctxt->sax->getParameterEntity != NULL))
+	entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return;
+    if (entity == NULL) {
+	/*
+	 * [ WFC: Entity Declared ]
+	 * In a document without any DTD, a document with only an
+	 * internal DTD subset which contains no parameter entity
+	 * references, or a document with "standalone='yes'", ...
+	 * ... The declaration of a parameter entity must precede
+	 * any reference to it...
+	 */
+	if ((ctxt->standalone == 1) ||
+	    ((ctxt->hasExternalSubset == 0) &&
+	     (ctxt->hasPErefs == 0))) {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+			      "PEReference: %%%s; not found\n",
+			      name);
+	} else {
+	    /*
+	     * [ VC: Entity Declared ]
+	     * In a document with an external subset or external
+	     * parameter entities with "standalone='no'", ...
+	     * ... The declaration of a parameter entity must
+	     * precede any reference to it...
+	     */
+	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			  "PEReference: %%%s; not found\n",
+			  name, NULL);
+	    ctxt->valid = 0;
+	}
+    } else {
+	/*
+	 * Internal checking in case the entity quest barfed
+	 */
+	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
+	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
+	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+		  "Internal: %%%s; is not a parameter entity\n",
+			  name, NULL);
+	} else if (ctxt->input->free != deallocblankswrapper) {
+	    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+	    if (xmlPushInput(ctxt, input) < 0)
+		return;
+	} else {
+	    /*
+	     * TODO !!!
+	     * handle the extra spaces added before and after
+	     * c.f. http://www.w3.org/TR/REC-xml#as-PE
+	     */
+	    input = xmlNewEntityInputStream(ctxt, entity);
+	    if (xmlPushInput(ctxt, input) < 0)
+		return;
+	    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
+		(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
+		(IS_BLANK_CH(NXT(5)))) {
+		xmlParseTextDecl(ctxt);
+		if (ctxt->errNo ==
+		    XML_ERR_UNSUPPORTED_ENCODING) {
+		    /*
+		     * The XML REC instructs us to stop parsing
+		     * right here
+		     */
+		    ctxt->instate = XML_PARSER_EOF;
+		    return;
+		}
+	    }
+	}
+    }
+    ctxt->hasPErefs = 1;
+}
+
+/**
+ * xmlLoadEntityContent:
+ * @ctxt:  an XML parser context
+ * @entity: an unloaded system entity
+ *
+ * Load the original content of the given system entity from the
+ * ExternalID/SystemID given. This is to be used for Included in Literal
+ * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
+ *
+ * Returns 0 in case of success and -1 in case of failure
+ */
+static int
+xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+    xmlParserInputPtr input;
+    xmlBufferPtr buf;
+    int l, c;
+    int count = 0;
+
+    if ((ctxt == NULL) || (entity == NULL) ||
+        ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
+	 (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
+	(entity->content != NULL)) {
+	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	            "xmlLoadEntityContent parameter error");
+        return(-1);
+    }
+
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"Reading %s entity content input\n", entity->name);
+
+    buf = xmlBufferCreate();
+    if (buf == NULL) {
+	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	            "xmlLoadEntityContent parameter error");
+        return(-1);
+    }
+
+    input = xmlNewEntityInputStream(ctxt, entity);
+    if (input == NULL) {
+	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	            "xmlLoadEntityContent input error");
+	xmlBufferFree(buf);
+        return(-1);
+    }
+
+    /*
+     * Push the entity as the current input, read char by char
+     * saving to the buffer until the end of the entity or an error
+     */
+    if (xmlPushInput(ctxt, input) < 0) {
+        xmlBufferFree(buf);
+	return(-1);
+    }
+
+    GROW;
+    c = CUR_CHAR(l);
+    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
+           (IS_CHAR(c))) {
+        xmlBufferAdd(buf, ctxt->input->cur, l);
+	if (count++ > 100) {
+	    count = 0;
+	    GROW;
+            if (ctxt->instate == XML_PARSER_EOF) {
+                xmlBufferFree(buf);
+                return(-1);
+            }
+	}
+	NEXTL(l);
+	c = CUR_CHAR(l);
+    }
+
+    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
+        xmlPopInput(ctxt);
+    } else if (!IS_CHAR(c)) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                          "xmlLoadEntityContent: invalid char value %d\n",
+	                  c);
+	xmlBufferFree(buf);
+	return(-1);
+    }
+    entity->content = buf->content;
+    buf->content = NULL;
+    xmlBufferFree(buf);
+
+    return(0);
+}
+
+/**
+ * xmlParseStringPEReference:
+ * @ctxt:  an XML parser context
+ * @str:  a pointer to an index in the string
+ *
+ * parse PEReference declarations
+ *
+ * [69] PEReference ::= '%' Name ';'
+ *
+ * [ WFC: No Recursion ]
+ * A parsed entity must not contain a recursive
+ * reference to itself, either directly or indirectly.
+ *
+ * [ WFC: Entity Declared ]
+ * In a document without any DTD, a document with only an internal DTD
+ * subset which contains no parameter entity references, or a document
+ * with "standalone='yes'", ...  ... The declaration of a parameter
+ * entity must precede any reference to it...
+ *
+ * [ VC: Entity Declared ]
+ * In a document with an external subset or external parameter entities
+ * with "standalone='no'", ...  ... The declaration of a parameter entity
+ * must precede any reference to it...
+ *
+ * [ WFC: In DTD ]
+ * Parameter-entity references may only appear in the DTD.
+ * NOTE: misleading but this is handled.
+ *
+ * Returns the string of the entity content.
+ *         str is updated to the current value of the index
+ */
+static xmlEntityPtr
+xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
+    const xmlChar *ptr;
+    xmlChar cur;
+    xmlChar *name;
+    xmlEntityPtr entity = NULL;
+
+    if ((str == NULL) || (*str == NULL)) return(NULL);
+    ptr = *str;
+    cur = *ptr;
+    if (cur != '%')
+        return(NULL);
+    ptr++;
+    name = xmlParseStringName(ctxt, &ptr);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "xmlParseStringPEReference: no name\n");
+	*str = ptr;
+	return(NULL);
+    }
+    cur = *ptr;
+    if (cur != ';') {
+	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
+	xmlFree(name);
+	*str = ptr;
+	return(NULL);
+    }
+    ptr++;
+
+    /*
+     * Increate the number of entity references parsed
+     */
+    ctxt->nbentities++;
+
+    /*
+     * Request the entity from SAX
+     */
+    if ((ctxt->sax != NULL) &&
+	(ctxt->sax->getParameterEntity != NULL))
+	entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+    if (ctxt->instate == XML_PARSER_EOF) {
+	xmlFree(name);
+	return(NULL);
+    }
+    if (entity == NULL) {
+	/*
+	 * [ WFC: Entity Declared ]
+	 * In a document without any DTD, a document with only an
+	 * internal DTD subset which contains no parameter entity
+	 * references, or a document with "standalone='yes'", ...
+	 * ... The declaration of a parameter entity must precede
+	 * any reference to it...
+	 */
+	if ((ctxt->standalone == 1) ||
+	    ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
+		 "PEReference: %%%s; not found\n", name);
+	} else {
+	    /*
+	     * [ VC: Entity Declared ]
+	     * In a document with an external subset or external
+	     * parameter entities with "standalone='no'", ...
+	     * ... The declaration of a parameter entity must
+	     * precede any reference to it...
+	     */
+	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			  "PEReference: %%%s; not found\n",
+			  name, NULL);
+	    ctxt->valid = 0;
+	}
+    } else {
+	/*
+	 * Internal checking in case the entity quest barfed
+	 */
+	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
+	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
+	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+			  "%%%s; is not a parameter entity\n",
+			  name, NULL);
+	}
+    }
+    ctxt->hasPErefs = 1;
+    xmlFree(name);
+    *str = ptr;
+    return(entity);
+}
+
+/**
+ * xmlParseDocTypeDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse a DOCTYPE declaration
+ *
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
+ *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ *
+ * [ VC: Root Element Type ]
+ * The Name in the document type declaration must match the element
+ * type of the root element. 
+ */
+
+void
+xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name = NULL;
+    xmlChar *ExternalID = NULL;
+    xmlChar *URI = NULL;
+
+    /*
+     * We know that '<!DOCTYPE' has been detected.
+     */
+    SKIP(9);
+
+    SKIP_BLANKS;
+
+    /*
+     * Parse the DOCTYPE name.
+     */
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
+    }
+    ctxt->intSubName = name;
+
+    SKIP_BLANKS;
+
+    /*
+     * Check for SystemID and ExternalID
+     */
+    URI = xmlParseExternalID(ctxt, &ExternalID, 1);
+
+    if ((URI != NULL) || (ExternalID != NULL)) {
+        ctxt->hasExternalSubset = 1;
+    }
+    ctxt->extSubURI = URI;
+    ctxt->extSubSystem = ExternalID;
+
+    SKIP_BLANKS;
+
+    /*
+     * Create and update the internal subset.
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
+	(!ctxt->disableSAX))
+	ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return;
+
+    /*
+     * Is there any internal subset declarations ?
+     * they are handled separately in xmlParseInternalSubset()
+     */
+    if (RAW == '[')
+	return;
+
+    /*
+     * We should be at the end of the DOCTYPE declaration.
+     */
+    if (RAW != '>') {
+	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
+    }
+    NEXT;
+}
+
+/**
+ * xmlParseInternalSubset:
+ * @ctxt:  an XML parser context
+ *
+ * parse the internal subset declaration
+ *
+ * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ */
+
+static void
+xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
+    /*
+     * Is there any DTD definition ?
+     */
+    if (RAW == '[') {
+        ctxt->instate = XML_PARSER_DTD;
+        NEXT;
+	/*
+	 * Parse the succession of Markup declarations and 
+	 * PEReferences.
+	 * Subsequence (markupdecl | PEReference | S)*
+	 */
+	while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
+	    const xmlChar *check = CUR_PTR;
+	    unsigned int cons = ctxt->input->consumed;
+
+	    SKIP_BLANKS;
+	    xmlParseMarkupDecl(ctxt);
+	    xmlParsePEReference(ctxt);
+
+	    /*
+	     * Pop-up of finished entities.
+	     */
+	    while ((RAW == 0) && (ctxt->inputNr > 1))
+		xmlPopInput(ctxt);
+
+	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	     "xmlParseInternalSubset: error detected in Markup declaration\n");
+		break;
+	    }
+	}
+	if (RAW == ']') { 
+	    NEXT;
+	    SKIP_BLANKS;
+	}
+    }
+
+    /*
+     * We should be at the end of the DOCTYPE declaration.
+     */
+    if (RAW != '>') {
+	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
+    }
+    NEXT;
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlParseAttribute:
+ * @ctxt:  an XML parser context
+ * @value:  a xmlChar ** used to store the value of the attribute
+ *
+ * parse an attribute
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ *
+ * [ WFC: No External Entity References ]
+ * Attribute values cannot contain direct or indirect entity references
+ * to external entities.
+ *
+ * [ WFC: No < in Attribute Values ]
+ * The replacement text of any entity referred to directly or indirectly in
+ * an attribute value (other than "&lt;") must not contain a <. 
+ * 
+ * [ VC: Attribute Value Type ]
+ * The attribute must have been declared; the value must be of the type
+ * declared for it.
+ *
+ * [25] Eq ::= S? '=' S?
+ *
+ * With namespace:
+ *
+ * [NS 11] Attribute ::= QName Eq AttValue
+ *
+ * Also the case QName == xmlns:??? is handled independently as a namespace
+ * definition.
+ *
+ * Returns the attribute name, and the value in *value.
+ */
+
+const xmlChar *
+xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
+    const xmlChar *name;
+    xmlChar *val;
+
+    *value = NULL;
+    GROW;
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+	               "error parsing attribute name\n");
+        return(NULL);
+    }
+
+    /*
+     * read the value
+     */
+    SKIP_BLANKS;
+    if (RAW == '=') {
+        NEXT;
+	SKIP_BLANKS;
+	val = xmlParseAttValue(ctxt);
+	ctxt->instate = XML_PARSER_CONTENT;
+    } else {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
+	       "Specification mandate value for attribute %s\n", name);
+	return(NULL);
+    }
+
+    /*
+     * Check that xml:lang conforms to the specification
+     * No more registered as an error, just generate a warning now
+     * since this was deprecated in XML second edition
+     */
+    if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
+	if (!xmlCheckLanguageID(val)) {
+	    xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
+		          "Malformed value for xml:lang : %s\n",
+			  val, NULL);
+	}
+    }
+
+    /*
+     * Check that xml:space conforms to the specification
+     */
+    if (xmlStrEqual(name, BAD_CAST "xml:space")) {
+	if (xmlStrEqual(val, BAD_CAST "default"))
+	    *(ctxt->space) = 0;
+	else if (xmlStrEqual(val, BAD_CAST "preserve"))
+	    *(ctxt->space) = 1;
+	else {
+		xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
+"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
+                                 val, NULL);
+	}
+    }
+
+    *value = val;
+    return(name);
+}
+
+/**
+ * xmlParseStartTag:
+ * @ctxt:  an XML parser context
+ * 
+ * parse a start of tag either for rule element or
+ * EmptyElement. In both case we don't parse the tag closing chars.
+ *
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ *
+ * [ WFC: Unique Att Spec ]
+ * No attribute name may appear more than once in the same start-tag or
+ * empty-element tag. 
+ *
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ *
+ * [ WFC: Unique Att Spec ]
+ * No attribute name may appear more than once in the same start-tag or
+ * empty-element tag. 
+ *
+ * With namespace:
+ *
+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
+ *
+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
+ *
+ * Returns the element name parsed
+ */
+
+const xmlChar *
+xmlParseStartTag(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    const xmlChar *attname;
+    xmlChar *attvalue;
+    const xmlChar **atts = ctxt->atts;
+    int nbatts = 0;
+    int maxatts = ctxt->maxatts;
+    int i;
+
+    if (RAW != '<') return(NULL);
+    NEXT1;
+
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+	     "xmlParseStartTag: invalid element name\n");
+        return(NULL);
+    }
+
+    /*
+     * Now parse the attributes, it ends up with the ending
+     *
+     * (S Attribute)* S?
+     */
+    SKIP_BLANKS;
+    GROW;
+
+    while (((RAW != '>') && 
+	   ((RAW != '/') || (NXT(1) != '>')) &&
+	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
+	const xmlChar *q = CUR_PTR;
+	unsigned int cons = ctxt->input->consumed;
+
+	attname = xmlParseAttribute(ctxt, &attvalue);
+        if ((attname != NULL) && (attvalue != NULL)) {
+	    /*
+	     * [ WFC: Unique Att Spec ]
+	     * No attribute name may appear more than once in the same
+	     * start-tag or empty-element tag. 
+	     */
+	    for (i = 0; i < nbatts;i += 2) {
+	        if (xmlStrEqual(atts[i], attname)) {
+		    xmlErrAttributeDup(ctxt, NULL, attname);
+		    xmlFree(attvalue);
+		    goto failed;
+		}
+	    }
+	    /*
+	     * Add the pair to atts
+	     */
+	    if (atts == NULL) {
+	        maxatts = 22; /* allow for 10 attrs by default */
+	        atts = (const xmlChar **)
+		       xmlMalloc(maxatts * sizeof(xmlChar *));
+		if (atts == NULL) {
+		    xmlErrMemory(ctxt, NULL);
+		    if (attvalue != NULL)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+		ctxt->atts = atts;
+		ctxt->maxatts = maxatts;
+	    } else if (nbatts + 4 > maxatts) {
+	        const xmlChar **n;
+
+	        maxatts *= 2;
+	        n = (const xmlChar **) xmlRealloc((void *) atts,
+					     maxatts * sizeof(const xmlChar *));
+		if (n == NULL) {
+		    xmlErrMemory(ctxt, NULL);
+		    if (attvalue != NULL)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+		atts = n;
+		ctxt->atts = atts;
+		ctxt->maxatts = maxatts;
+	    }
+	    atts[nbatts++] = attname;
+	    atts[nbatts++] = attvalue;
+	    atts[nbatts] = NULL;
+	    atts[nbatts + 1] = NULL;
+	} else {
+	    if (attvalue != NULL)
+		xmlFree(attvalue);
+	}
+
+failed:     
+
+	GROW
+	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+	    break;
+	if (!IS_BLANK_CH(RAW)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "attributes construct error\n");
+	}
+	SKIP_BLANKS;
+        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
+            (attname == NULL) && (attvalue == NULL)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
+			   "xmlParseStartTag: problem parsing attributes\n");
+	    break;
+	}
+	SHRINK;
+        GROW;
+    }
+
+    /*
+     * SAX: Start of Element !
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
+	(!ctxt->disableSAX)) {
+	if (nbatts > 0)
+	    ctxt->sax->startElement(ctxt->userData, name, atts);
+	else
+	    ctxt->sax->startElement(ctxt->userData, name, NULL);
+    }
+
+    if (atts != NULL) {
+        /* Free only the content strings */
+        for (i = 1;i < nbatts;i+=2)
+	    if (atts[i] != NULL)
+	       xmlFree((xmlChar *) atts[i]);
+    }
+    return(name);
+}
+
+/**
+ * xmlParseEndTag1:
+ * @ctxt:  an XML parser context
+ * @line:  line of the start tag
+ * @nsNr:  number of namespaces on the start tag
+ *
+ * parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [NS 9] ETag ::= '</' QName S? '>'
+ */
+
+static void
+xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
+    const xmlChar *name;
+
+    GROW;
+    if ((RAW != '<') || (NXT(1) != '/')) {
+	xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
+		       "xmlParseEndTag: '</' not found\n");
+	return;
+    }
+    SKIP(2);
+
+    name = xmlParseNameAndCompare(ctxt,ctxt->name);
+
+    /*
+     * We should definitely be at the ending "S? '>'" part
+     */
+    GROW;
+    SKIP_BLANKS;
+    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
+	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
+    } else
+	NEXT1;
+
+    /*
+     * [ WFC: Element Type Match ]
+     * The Name in an element's end-tag must match the element type in the
+     * start-tag. 
+     *
+     */
+    if (name != (xmlChar*)1) {
+        if (name == NULL) name = BAD_CAST "unparseable";
+        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+		     "Opening and ending tag mismatch: %s line %d and %s\n",
+		                ctxt->name, line, name);
+    }
+
+    /*
+     * SAX: End of Tag
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
+	(!ctxt->disableSAX))
+        ctxt->sax->endElement(ctxt->userData, ctxt->name);
+
+    namePop(ctxt);
+    spacePop(ctxt);
+    return;
+}
+
+/**
+ * xmlParseEndTag:
+ * @ctxt:  an XML parser context
+ *
+ * parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [NS 9] ETag ::= '</' QName S? '>'
+ */
+
+void
+xmlParseEndTag(xmlParserCtxtPtr ctxt) {
+    xmlParseEndTag1(ctxt, 0);
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/************************************************************************
+ *									*
+ *		      SAX 2 specific operations				*
+ *									*
+ ************************************************************************/
+
+/*
+ * xmlGetNamespace:
+ * @ctxt:  an XML parser context
+ * @prefix:  the prefix to lookup
+ *
+ * Lookup the namespace name for the @prefix (which ca be NULL)
+ * The prefix must come from the @ctxt->dict dictionnary
+ *
+ * Returns the namespace name or NULL if not bound
+ */
+static const xmlChar *
+xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
+    int i;
+
+    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
+    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
+        if (ctxt->nsTab[i] == prefix) {
+	    if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
+	        return(NULL);
+	    return(ctxt->nsTab[i + 1]);
+	}
+    return(NULL);
+}
+
+/**
+ * xmlParseQName:
+ * @ctxt:  an XML parser context
+ * @prefix:  pointer to store the prefix part
+ *
+ * parse an XML Namespace QName
+ *
+ * [6]  QName  ::= (Prefix ':')? LocalPart
+ * [7]  Prefix  ::= NCName
+ * [8]  LocalPart  ::= NCName
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static const xmlChar *
+xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
+    const xmlChar *l, *p;
+
+    GROW;
+
+    l = xmlParseNCName(ctxt);
+    if (l == NULL) {
+        if (CUR == ':') {
+	    l = xmlParseName(ctxt);
+	    if (l != NULL) {
+	        xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
+		         "Failed to parse QName '%s'\n", l, NULL, NULL);
+		*prefix = NULL;
+		return(l);
+	    }
+	}
+        return(NULL);
+    }
+    if (CUR == ':') {
+        NEXT;
+	p = l;
+	l = xmlParseNCName(ctxt);
+	if (l == NULL) {
+	    xmlChar *tmp;
+
+            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
+	             "Failed to parse QName '%s:'\n", p, NULL, NULL);
+	    l = xmlParseNmtoken(ctxt);
+	    if (l == NULL)
+		tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
+	    else {
+		tmp = xmlBuildQName(l, p, NULL, 0);
+		xmlFree((char *)l);
+	    }
+	    p = xmlDictLookup(ctxt->dict, tmp, -1);
+	    if (tmp != NULL) xmlFree(tmp);
+	    *prefix = NULL;
+	    return(p);
+	}
+	if (CUR == ':') {
+	    xmlChar *tmp;
+
+            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
+	             "Failed to parse QName '%s:%s:'\n", p, l, NULL);
+	    NEXT;
+	    tmp = (xmlChar *) xmlParseName(ctxt);
+	    if (tmp != NULL) {
+	        tmp = xmlBuildQName(tmp, l, NULL, 0);
+		l = xmlDictLookup(ctxt->dict, tmp, -1);
+		if (tmp != NULL) xmlFree(tmp);
+		*prefix = p;
+		return(l);
+	    }
+	    tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
+	    l = xmlDictLookup(ctxt->dict, tmp, -1);
+	    if (tmp != NULL) xmlFree(tmp);
+	    *prefix = p;
+	    return(l);
+	}
+	*prefix = p;
+    } else
+        *prefix = NULL;
+    return(l);
+}
+
+/**
+ * xmlParseQNameAndCompare:
+ * @ctxt:  an XML parser context
+ * @name:  the localname
+ * @prefix:  the prefix, if any.
+ *
+ * parse an XML name and compares for match
+ * (specialized for endtag parsing)
+ *
+ * Returns NULL for an illegal name, (xmlChar*) 1 for success
+ * and the name for mismatch
+ */
+
+static const xmlChar *
+xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
+                        xmlChar const *prefix) {
+    const xmlChar *cmp;
+    const xmlChar *in;
+    const xmlChar *ret;
+    const xmlChar *prefix2;
+
+    if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
+
+    GROW;
+    in = ctxt->input->cur;
+
+    cmp = prefix;
+    while (*in != 0 && *in == *cmp) {
+    	++in;
+	++cmp;
+    }
+    if ((*cmp == 0) && (*in == ':')) {
+        in++;
+	cmp = name;
+	while (*in != 0 && *in == *cmp) {
+	    ++in;
+	    ++cmp;
+	}
+	if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
+	    /* success */
+	    ctxt->input->cur = in;
+	    return((const xmlChar*) 1);
+	}
+    }
+    /*
+     * all strings coms from the dictionary, equality can be done directly
+     */
+    ret = xmlParseQName (ctxt, &prefix2);
+    if ((ret == name) && (prefix == prefix2))
+	return((const xmlChar*) 1);
+    return ret;
+}
+
+/**
+ * xmlParseAttValueInternal:
+ * @ctxt:  an XML parser context
+ * @len:  attribute len result
+ * @alloc:  whether the attribute was reallocated as a new string
+ * @normalize:  if 1 then further non-CDATA normalization must be done
+ *
+ * parse a value for an attribute.
+ * NOTE: if no normalization is needed, the routine will return pointers
+ *       directly from the data buffer.
+ *
+ * 3.3.3 Attribute-Value Normalization:
+ * Before the value of an attribute is passed to the application or
+ * checked for validity, the XML processor must normalize it as follows: 
+ * - a character reference is processed by appending the referenced
+ *   character to the attribute value
+ * - an entity reference is processed by recursively processing the
+ *   replacement text of the entity 
+ * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
+ *   appending #x20 to the normalized value, except that only a single
+ *   #x20 is appended for a "#xD#xA" sequence that is part of an external
+ *   parsed entity or the literal entity value of an internal parsed entity 
+ * - other characters are processed by appending them to the normalized value 
+ * If the declared value is not CDATA, then the XML processor must further
+ * process the normalized attribute value by discarding any leading and
+ * trailing space (#x20) characters, and by replacing sequences of space
+ * (#x20) characters by a single space (#x20) character.  
+ * All attributes for which no declaration has been read should be treated
+ * by a non-validating parser as if declared CDATA.
+ *
+ * Returns the AttValue parsed or NULL. The value has to be freed by the
+ *     caller if it was copied, this can be detected by val[*len] == 0.
+ */
+
+static xmlChar *
+xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+                         int normalize)
+{
+    xmlChar limit = 0;
+    const xmlChar *in = NULL, *start, *end, *last;
+    xmlChar *ret = NULL;
+
+    GROW;
+    in = (xmlChar *) CUR_PTR;
+    if (*in != '"' && *in != '\'') {
+        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
+        return (NULL);
+    }
+    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
+
+    /*
+     * try to handle in this routine the most common case where no
+     * allocation of a new string is required and where content is
+     * pure ASCII.
+     */
+    limit = *in++;
+    end = ctxt->input->end;
+    start = in;
+    if (in >= end) {
+        const xmlChar *oldbase = ctxt->input->base;
+	GROW;
+	if (oldbase != ctxt->input->base) {
+	    long delta = ctxt->input->base - oldbase;
+	    start = start + delta;
+	    in = in + delta;
+	}
+	end = ctxt->input->end;
+    }
+    if (normalize) {
+        /*
+	 * Skip any leading spaces
+	 */
+	while ((in < end) && (*in != limit) && 
+	       ((*in == 0x20) || (*in == 0x9) ||
+	        (*in == 0xA) || (*in == 0xD))) {
+	    in++;
+	    start = in;
+	    if (in >= end) {
+		const xmlChar *oldbase = ctxt->input->base;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+		if (oldbase != ctxt->input->base) {
+		    long delta = ctxt->input->base - oldbase;
+		    start = start + delta;
+		    in = in + delta;
+		}
+		end = ctxt->input->end;
+	    }
+	}
+	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
+	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
+	    if ((*in++ == 0x20) && (*in == 0x20)) break;
+	    if (in >= end) {
+		const xmlChar *oldbase = ctxt->input->base;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+		if (oldbase != ctxt->input->base) {
+		    long delta = ctxt->input->base - oldbase;
+		    start = start + delta;
+		    in = in + delta;
+		}
+		end = ctxt->input->end;
+	    }
+	}
+	last = in;
+	/*
+	 * skip the trailing blanks
+	 */
+	while ((last[-1] == 0x20) && (last > start)) last--;
+	while ((in < end) && (*in != limit) && 
+	       ((*in == 0x20) || (*in == 0x9) ||
+	        (*in == 0xA) || (*in == 0xD))) {
+	    in++;
+	    if (in >= end) {
+		const xmlChar *oldbase = ctxt->input->base;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+		if (oldbase != ctxt->input->base) {
+		    long delta = ctxt->input->base - oldbase;
+		    start = start + delta;
+		    in = in + delta;
+		    last = last + delta;
+		}
+		end = ctxt->input->end;
+	    }
+	}
+	if (*in != limit) goto need_complex;
+    } else {
+	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
+	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
+	    in++;
+	    if (in >= end) {
+		const xmlChar *oldbase = ctxt->input->base;
+		GROW;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
+		if (oldbase != ctxt->input->base) {
+		    long delta = ctxt->input->base - oldbase;
+		    start = start + delta;
+		    in = in + delta;
+		}
+		end = ctxt->input->end;
+	    }
+	}
+	last = in;
+	if (*in != limit) goto need_complex;
+    }
+    in++;
+    if (len != NULL) {
+        *len = last - start;
+        ret = (xmlChar *) start;
+    } else {
+        if (alloc) *alloc = 1;
+        ret = xmlStrndup(start, last - start);
+    }
+    CUR_PTR = in;
+    if (alloc) *alloc = 0;
+    return ret;
+need_complex:
+    if (alloc) *alloc = 1;
+    return xmlParseAttValueComplex(ctxt, len, normalize);
+}
+
+/**
+ * xmlParseAttribute2:
+ * @ctxt:  an XML parser context
+ * @pref:  the element prefix
+ * @elem:  the element name
+ * @prefix:  a xmlChar ** used to store the value of the attribute prefix
+ * @value:  a xmlChar ** used to store the value of the attribute
+ * @len:  an int * to save the length of the attribute
+ * @alloc:  an int * to indicate if the attribute was allocated
+ *
+ * parse an attribute in the new SAX2 framework.
+ *
+ * Returns the attribute name, and the value in *value, .
+ */
+
+static const xmlChar *
+xmlParseAttribute2(xmlParserCtxtPtr ctxt,
+                   const xmlChar * pref, const xmlChar * elem,
+                   const xmlChar ** prefix, xmlChar ** value,
+                   int *len, int *alloc)
+{
+    const xmlChar *name;
+    xmlChar *val, *internal_val = NULL;
+    int normalize = 0;
+
+    *value = NULL;
+    GROW;
+    name = xmlParseQName(ctxt, prefix);
+    if (name == NULL) {
+        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+                       "error parsing attribute name\n");
+        return (NULL);
+    }
+
+    /*
+     * get the type if needed
+     */
+    if (ctxt->attsSpecial != NULL) {
+        int type;
+
+        type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
+                                            pref, elem, *prefix, name);
+        if (type != 0)
+            normalize = 1;
+    }
+
+    /*
+     * read the value
+     */
+    SKIP_BLANKS;
+    if (RAW == '=') {
+        NEXT;
+        SKIP_BLANKS;
+        val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
+	if (normalize) {
+	    /*
+	     * Sometimes a second normalisation pass for spaces is needed
+	     * but that only happens if charrefs or entities refernces
+	     * have been used in the attribute value, i.e. the attribute
+	     * value have been extracted in an allocated string already.
+	     */
+	    if (*alloc) {
+	        const xmlChar *val2;
+
+	        val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
+		if ((val2 != NULL) && (val2 != val)) {
+		    xmlFree(val);
+		    val = (xmlChar *) val2;
+		}
+	    }
+	}
+        ctxt->instate = XML_PARSER_CONTENT;
+    } else {
+        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
+                          "Specification mandate value for attribute %s\n",
+                          name);
+        return (NULL);
+    }
+
+    if (*prefix == ctxt->str_xml) {
+        /*
+         * Check that xml:lang conforms to the specification
+         * No more registered as an error, just generate a warning now
+         * since this was deprecated in XML second edition
+         */
+        if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
+            internal_val = xmlStrndup(val, *len);
+            if (!xmlCheckLanguageID(internal_val)) {
+                xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
+                              "Malformed value for xml:lang : %s\n",
+                              internal_val, NULL);
+            }
+        }
+
+        /*
+         * Check that xml:space conforms to the specification
+         */
+        if (xmlStrEqual(name, BAD_CAST "space")) {
+            internal_val = xmlStrndup(val, *len);
+            if (xmlStrEqual(internal_val, BAD_CAST "default"))
+                *(ctxt->space) = 0;
+            else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
+                *(ctxt->space) = 1;
+            else {
+                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
+                              "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
+                              internal_val, NULL);
+            }
+        }
+        if (internal_val) {
+            xmlFree(internal_val);
+        }
+    }
+
+    *value = val;
+    return (name);
+}
+/**
+ * xmlParseStartTag2:
+ * @ctxt:  an XML parser context
+ * 
+ * parse a start of tag either for rule element or
+ * EmptyElement. In both case we don't parse the tag closing chars.
+ * This routine is called when running SAX2 parsing
+ *
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ *
+ * [ WFC: Unique Att Spec ]
+ * No attribute name may appear more than once in the same start-tag or
+ * empty-element tag. 
+ *
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ *
+ * [ WFC: Unique Att Spec ]
+ * No attribute name may appear more than once in the same start-tag or
+ * empty-element tag. 
+ *
+ * With namespace:
+ *
+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
+ *
+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
+ *
+ * Returns the element name parsed
+ */
+
+static const xmlChar *
+xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
+                  const xmlChar **URI, int *tlen) {
+    const xmlChar *localname;
+    const xmlChar *prefix;
+    const xmlChar *attname;
+    const xmlChar *aprefix;
+    const xmlChar *nsname;
+    xmlChar *attvalue;
+    const xmlChar **atts = ctxt->atts;
+    int maxatts = ctxt->maxatts;
+    int nratts, nbatts, nbdef;
+    int i, j, nbNs, attval, oldline, oldcol;
+    const xmlChar *base;
+    unsigned long cur;
+    int nsNr = ctxt->nsNr;
+
+    if (RAW != '<') return(NULL);
+    NEXT1;
+
+    /*
+     * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
+     *       point since the attribute values may be stored as pointers to
+     *       the buffer and calling SHRINK would destroy them !
+     *       The Shrinking is only possible once the full set of attribute
+     *       callbacks have been done.
+     */
+reparse:
+    SHRINK;
+    base = ctxt->input->base;
+    cur = ctxt->input->cur - ctxt->input->base;
+    oldline = ctxt->input->line;
+    oldcol = ctxt->input->col;
+    nbatts = 0;
+    nratts = 0;
+    nbdef = 0;
+    nbNs = 0;
+    attval = 0;
+    /* Forget any namespaces added during an earlier parse of this element. */
+    ctxt->nsNr = nsNr;
+
+    localname = xmlParseQName(ctxt, &prefix);
+    if (localname == NULL) {
+	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
+		       "StartTag: invalid element name\n");
+        return(NULL);
+    }
+    *tlen = ctxt->input->cur - ctxt->input->base - cur;
+
+    /*
+     * Now parse the attributes, it ends up with the ending
+     *
+     * (S Attribute)* S?
+     */
+    SKIP_BLANKS;
+    GROW;
+    if (ctxt->input->base != base) goto base_changed;
+
+    while (((RAW != '>') && 
+	   ((RAW != '/') || (NXT(1) != '>')) &&
+	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
+	const xmlChar *q = CUR_PTR;
+	unsigned int cons = ctxt->input->consumed;
+	int len = -1, alloc = 0;
+
+	attname = xmlParseAttribute2(ctxt, prefix, localname,
+	                             &aprefix, &attvalue, &len, &alloc);
+	if (ctxt->input->base != base) {
+	    if ((attvalue != NULL) && (alloc != 0))
+	        xmlFree(attvalue);
+	    attvalue = NULL;
+	    goto base_changed;
+	}
+        if ((attname != NULL) && (attvalue != NULL)) {
+	    if (len < 0) len = xmlStrlen(attvalue);
+            if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
+	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
+		xmlURIPtr uri;
+
+                if (*URL != 0) {
+		    uri = xmlParseURI((const char *) URL);
+		    if (uri == NULL) {
+			xmlNsErr(ctxt, XML_WAR_NS_URI,
+			         "xmlns: '%s' is not a valid URI\n",
+					   URL, NULL, NULL);
+		    } else {
+			if (uri->scheme == NULL) {
+			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
+				      "xmlns: URI %s is not absolute\n",
+				      URL, NULL, NULL);
+			}
+			xmlFreeURI(uri);
+		    }
+		    if (URL == ctxt->str_xml_ns) {
+			if (attname != ctxt->str_xml) {
+			    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			 "xml namespace URI cannot be the default namespace\n",
+				     NULL, NULL, NULL);
+			}
+			goto skip_default_ns;
+		    }
+		    if ((len == 29) &&
+			(xmlStrEqual(URL,
+				 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
+			xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			     "reuse of the xmlns namespace name is forbidden\n",
+				 NULL, NULL, NULL);
+			goto skip_default_ns;
+		    }
+		}
+		/*
+		 * check that it's not a defined namespace
+		 */
+		for (j = 1;j <= nbNs;j++)
+		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
+			break;
+		if (j <= nbNs)
+		    xmlErrAttributeDup(ctxt, NULL, attname);
+		else
+		    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
+skip_default_ns:
+		if (alloc != 0) xmlFree(attvalue);
+		SKIP_BLANKS;
+		continue;
+	    }
+            if (aprefix == ctxt->str_xmlns) {
+	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
+		xmlURIPtr uri;
+
+                if (attname == ctxt->str_xml) {
+		    if (URL != ctxt->str_xml_ns) {
+		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			         "xml namespace prefix mapped to wrong URI\n",
+			         NULL, NULL, NULL);
+		    }
+		    /*
+		     * Do not keep a namespace definition node
+		     */
+		    goto skip_ns;
+		}
+                if (URL == ctxt->str_xml_ns) {
+		    if (attname != ctxt->str_xml) {
+		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			         "xml namespace URI mapped to wrong prefix\n",
+			         NULL, NULL, NULL);
+		    }
+		    goto skip_ns;
+		}
+                if (attname == ctxt->str_xmlns) {
+		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			     "redefinition of the xmlns prefix is forbidden\n",
+			     NULL, NULL, NULL);
+		    goto skip_ns;
+		}
+		if ((len == 29) &&
+		    (xmlStrEqual(URL,
+		                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
+		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+			     "reuse of the xmlns namespace name is forbidden\n",
+			     NULL, NULL, NULL);
+		    goto skip_ns;
+		}
+		if ((URL == NULL) || (URL[0] == 0)) {
+		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+		             "xmlns:%s: Empty XML namespace is not allowed\n",
+			          attname, NULL, NULL);
+		    goto skip_ns;
+		} else {
+		    uri = xmlParseURI((const char *) URL);
+		    if (uri == NULL) {
+			xmlNsErr(ctxt, XML_WAR_NS_URI,
+			     "xmlns:%s: '%s' is not a valid URI\n",
+					   attname, URL, NULL);
+		    } else {
+			if ((ctxt->pedantic) && (uri->scheme == NULL)) {
+			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
+				      "xmlns:%s: URI %s is not absolute\n",
+				      attname, URL, NULL);
+			}
+			xmlFreeURI(uri);
+		    }
+		}
+
+		/*
+		 * check that it's not a defined namespace
+		 */
+		for (j = 1;j <= nbNs;j++)
+		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
+			break;
+		if (j <= nbNs)
+		    xmlErrAttributeDup(ctxt, aprefix, attname);
+		else
+		    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
+skip_ns:
+		if (alloc != 0) xmlFree(attvalue);
+		SKIP_BLANKS;
+		if (ctxt->input->base != base) goto base_changed;
+		continue;
+	    }
+
+	    /*
+	     * Add the pair to atts
+	     */
+	    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
+	        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
+		    if (attvalue[len] == 0)
+			xmlFree(attvalue);
+		    goto failed;
+		}
+	        maxatts = ctxt->maxatts;
+		atts = ctxt->atts;
+	    }
+	    ctxt->attallocs[nratts++] = alloc;
+	    atts[nbatts++] = attname;
+	    atts[nbatts++] = aprefix;
+	    atts[nbatts++] = NULL; /* the URI will be fetched later */
+	    atts[nbatts++] = attvalue;
+	    attvalue += len;
+	    atts[nbatts++] = attvalue;
+	    /*
+	     * tag if some deallocation is needed
+	     */
+	    if (alloc != 0) attval = 1;
+	} else {
+	    if ((attvalue != NULL) && (attvalue[len] == 0))
+		xmlFree(attvalue);
+	}
+
+failed:
+
+	GROW
+        if (ctxt->instate == XML_PARSER_EOF)
+            break;
+	if (ctxt->input->base != base) goto base_changed;
+	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+	    break;
+	if (!IS_BLANK_CH(RAW)) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+			   "attributes construct error\n");
+	    break;
+	}
+	SKIP_BLANKS;
+        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
+            (attname == NULL) && (attvalue == NULL)) {
+	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	         "xmlParseStartTag: problem parsing attributes\n");
+	    break;
+	}
+        GROW;
+	if (ctxt->input->base != base) goto base_changed;
+    }
+
+    /*
+     * The attributes defaulting
+     */
+    if (ctxt->attsDefault != NULL) {
+        xmlDefAttrsPtr defaults;
+
+	defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
+	if (defaults != NULL) {
+	    for (i = 0;i < defaults->nbAttrs;i++) {
+	        attname = defaults->values[5 * i];
+		aprefix = defaults->values[5 * i + 1];
+
+                /*
+		 * special work for namespaces defaulted defs
+		 */
+		if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
+		    /*
+		     * check that it's not a defined namespace
+		     */
+		    for (j = 1;j <= nbNs;j++)
+		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
+			    break;
+	            if (j <= nbNs) continue;
+
+		    nsname = xmlGetNamespace(ctxt, NULL);
+		    if (nsname != defaults->values[5 * i + 2]) {
+			if (nsPush(ctxt, NULL,
+			           defaults->values[5 * i + 2]) > 0)
+			    nbNs++;
+		    }
+		} else if (aprefix == ctxt->str_xmlns) {
+		    /*
+		     * check that it's not a defined namespace
+		     */
+		    for (j = 1;j <= nbNs;j++)
+		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
+			    break;
+	            if (j <= nbNs) continue;
+
+		    nsname = xmlGetNamespace(ctxt, attname);
+		    if (nsname != defaults->values[2]) {
+			if (nsPush(ctxt, attname,
+			           defaults->values[5 * i + 2]) > 0)
+			    nbNs++;
+		    }
+		} else {
+		    /*
+		     * check that it's not a defined attribute
+		     */
+		    for (j = 0;j < nbatts;j+=5) {
+			if ((attname == atts[j]) && (aprefix == atts[j+1]))
+			    break;
+		    }
+		    if (j < nbatts) continue;
+
+		    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
+			if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
+			    return(NULL);
+			}
+			maxatts = ctxt->maxatts;
+			atts = ctxt->atts;
+		    }
+		    atts[nbatts++] = attname;
+		    atts[nbatts++] = aprefix;
+		    if (aprefix == NULL)
+			atts[nbatts++] = NULL;
+		    else
+		        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
+		    atts[nbatts++] = defaults->values[5 * i + 2];
+		    atts[nbatts++] = defaults->values[5 * i + 3];
+		    if ((ctxt->standalone == 1) &&
+		        (defaults->values[5 * i + 4] != NULL)) {
+			xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED, 
+	  "standalone: attribute %s on %s defaulted from external subset\n",
+	                                 attname, localname);
+		    }
+		    nbdef++;
+		}
+	    }
+	}
+    }
+
+    /*
+     * The attributes checkings
+     */
+    for (i = 0; i < nbatts;i += 5) {
+        /*
+	* The default namespace does not apply to attribute names.
+	*/
+	if (atts[i + 1] != NULL) {
+	    nsname = xmlGetNamespace(ctxt, atts[i + 1]);
+	    if (nsname == NULL) {
+		xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+		    "Namespace prefix %s for %s on %s is not defined\n",
+		    atts[i + 1], atts[i], localname);
+	    }
+	    atts[i + 2] = nsname;
+	} else
+	    nsname = NULL;
+	/*
+	 * [ WFC: Unique Att Spec ]
+	 * No attribute name may appear more than once in the same
+	 * start-tag or empty-element tag. 
+	 * As extended by the Namespace in XML REC.
+	 */
+        for (j = 0; j < i;j += 5) {
+	    if (atts[i] == atts[j]) {
+	        if (atts[i+1] == atts[j+1]) {
+		    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
+		    break;
+		}
+		if ((nsname != NULL) && (atts[j + 2] == nsname)) {
+		    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
+			     "Namespaced Attribute %s in '%s' redefined\n",
+			     atts[i], nsname, NULL);
+		    break;
+		}
+	    }
+	}
+    }
+
+    nsname = xmlGetNamespace(ctxt, prefix);
+    if ((prefix != NULL) && (nsname == NULL)) {
+	xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+	         "Namespace prefix %s on %s is not defined\n",
+		 prefix, localname, NULL);
+    }
+    *pref = prefix;
+    *URI = nsname;
+
+    /*
+     * SAX: Start of Element !
+     */
+    if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
+	(!ctxt->disableSAX)) {
+	if (nbNs > 0)
+	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
+			  nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
+			  nbatts / 5, nbdef, atts);
+	else
+	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
+	                  nsname, 0, NULL, nbatts / 5, nbdef, atts);
+    }
+
+    /*
+     * Free up attribute allocated strings if needed
+     */
+    if (attval != 0) {
+	for (i = 3,j = 0; j < nratts;i += 5,j++)
+	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
+	        xmlFree((xmlChar *) atts[i]);
+    }
+
+    return(localname);
+
+base_changed:
+    /*
+     * the attribute strings are valid iif the base didn't changed
+     */
+    if (attval != 0) {
+	for (i = 3,j = 0; j < nratts;i += 5,j++)
+	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
+	        xmlFree((xmlChar *) atts[i]);
+    }
+    ctxt->input->cur = ctxt->input->base + cur;
+    ctxt->input->line = oldline;
+    ctxt->input->col = oldcol;
+    if (ctxt->wellFormed == 1) {
+	goto reparse;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlParseEndTag2:
+ * @ctxt:  an XML parser context
+ * @line:  line of the start tag
+ * @nsNr:  number of namespaces on the start tag
+ *
+ * parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [NS 9] ETag ::= '</' QName S? '>'
+ */
+
+static void
+xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
+                const xmlChar *URI, int line, int nsNr, int tlen) {
+    const xmlChar *name;
+
+    GROW;
+    if ((RAW != '<') || (NXT(1) != '/')) {
+	xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
+	return;
+    }
+    SKIP(2);
+
+    if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
+        if (ctxt->input->cur[tlen] == '>') {
+	    ctxt->input->cur += tlen + 1;
+	    goto done;
+	}
+	ctxt->input->cur += tlen;
+	name = (xmlChar*)1;
+    } else {
+	if (prefix == NULL)
+	    name = xmlParseNameAndCompare(ctxt, ctxt->name);
+	else
+	    name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
+    }
+
+    /*
+     * We should definitely be at the ending "S? '>'" part
+     */
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+    SKIP_BLANKS;
+    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
+	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
+    } else
+	NEXT1;
+
+    /*
+     * [ WFC: Element Type Match ]
+     * The Name in an element's end-tag must match the element type in the
+     * start-tag. 
+     *
+     */
+    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);
+    }
+
+    /*
+     * SAX: End of Tag
+     */
+done:
+    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
+	(!ctxt->disableSAX))
+	ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
+
+    spacePop(ctxt);
+    if (nsNr != 0)
+	nsPop(ctxt, nsNr);
+    return;
+}
+
+/**
+ * xmlParseCDSect:
+ * @ctxt:  an XML parser context
+ * 
+ * Parse escaped pure raw content.
+ *
+ * [18] CDSect ::= CDStart CData CDEnd
+ *
+ * [19] CDStart ::= '<![CDATA['
+ *
+ * [20] Data ::= (Char* - (Char* ']]>' Char*))
+ *
+ * [21] CDEnd ::= ']]>'
+ */
+void
+xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = XML_PARSER_BUFFER_SIZE;
+    int r, rl;
+    int	s, sl;
+    int cur, l;
+    int count = 0;
+
+    /* Check 2.6.0 was NXT(0) not RAW */
+    if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
+	SKIP(9);
+    } else
+        return;
+
+    ctxt->instate = XML_PARSER_CDATA_SECTION;
+    r = CUR_CHAR(rl);
+    if (!IS_CHAR(r)) {
+	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
+	ctxt->instate = XML_PARSER_CONTENT;
+        return;
+    }
+    NEXTL(rl);
+    s = CUR_CHAR(sl);
+    if (!IS_CHAR(s)) {
+	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
+	ctxt->instate = XML_PARSER_CONTENT;
+        return;
+    }
+    NEXTL(sl);
+    cur = CUR_CHAR(l);
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+	xmlErrMemory(ctxt, NULL);
+	return;
+    }
+    while (IS_CHAR(cur) &&
+           ((r != ']') || (s != ']') || (cur != '>'))) {
+	if (len + 5 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+	        xmlFree(buf);
+		xmlErrMemory(ctxt, NULL);
+		return;
+	    }
+	    buf = tmp;
+	}
+	COPY_BUF(rl,buf,len,r);
+	r = s;
+	rl = sl;
+	s = cur;
+	sl = l;
+	count++;
+	if (count > 50) {
+	    GROW;
+            if (ctxt->instate == XML_PARSER_EOF) {
+		xmlFree(buf);
+		return;
+            }
+	    count = 0;
+	}
+	NEXTL(l);
+	cur = CUR_CHAR(l);
+    }
+    buf[len] = 0;
+    ctxt->instate = XML_PARSER_CONTENT;
+    if (cur != '>') {
+	xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
+	                     "CData section not finished\n%.50s\n", buf);
+	xmlFree(buf);
+        return;
+    }
+    NEXTL(l);
+
+    /*
+     * OK the buffer is to be consumed as cdata.
+     */
+    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+	if (ctxt->sax->cdataBlock != NULL)
+	    ctxt->sax->cdataBlock(ctxt->userData, buf, len);
+	else if (ctxt->sax->characters != NULL)
+	    ctxt->sax->characters(ctxt->userData, buf, len);
+    }
+    xmlFree(buf);
+}
+
+/**
+ * xmlParseContent:
+ * @ctxt:  an XML parser context
+ *
+ * Parse a content:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ */
+
+void
+xmlParseContent(xmlParserCtxtPtr ctxt) {
+    GROW;
+    while ((RAW != 0) &&
+	   ((RAW != '<') || (NXT(1) != '/')) &&
+	   (ctxt->instate != XML_PARSER_EOF)) {
+	const xmlChar *test = CUR_PTR;
+	unsigned int cons = ctxt->input->consumed;
+	const xmlChar *cur = ctxt->input->cur;
+
+	/*
+	 * First case : a Processing Instruction.
+	 */
+	if ((*cur == '<') && (cur[1] == '?')) {
+	    xmlParsePI(ctxt);
+	}
+
+	/*
+	 * Second case : a CDSection
+	 */
+	/* 2.6.0 test was *cur not RAW */
+	else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
+	    xmlParseCDSect(ctxt);
+	}
+
+	/*
+	 * Third case :  a comment
+	 */
+	else if ((*cur == '<') && (NXT(1) == '!') &&
+		 (NXT(2) == '-') && (NXT(3) == '-')) {
+	    xmlParseComment(ctxt);
+	    ctxt->instate = XML_PARSER_CONTENT;
+	}
+
+	/*
+	 * Fourth case :  a sub-element.
+	 */
+	else if (*cur == '<') {
+	    xmlParseElement(ctxt);
+	}
+
+	/*
+	 * Fifth case : a reference. If if has not been resolved,
+	 *    parsing returns it's Name, create the node 
+	 */
+
+	else if (*cur == '&') {
+	    xmlParseReference(ctxt);
+	}
+
+	/*
+	 * Last case, text. Note that References are handled directly.
+	 */
+	else {
+	    xmlParseCharData(ctxt, 0);
+	}
+
+	GROW;
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((RAW == 0) && (ctxt->inputNr > 1))
+	    xmlPopInput(ctxt);
+	SHRINK;
+
+	if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
+	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+	                "detected an error in element content\n");
+	    ctxt->instate = XML_PARSER_EOF;
+            break;
+	}
+    }
+}
+
+/**
+ * xmlParseElement:
+ * @ctxt:  an XML parser context
+ *
+ * parse an XML element, this is highly recursive
+ *
+ * [39] element ::= EmptyElemTag | STag content ETag
+ *
+ * [ WFC: Element Type Match ]
+ * The Name in an element's end-tag must match the element type in the
+ * start-tag. 
+ *
+ */
+
+void
+xmlParseElement(xmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    const xmlChar *prefix = NULL;
+    const xmlChar *URI = NULL;
+    xmlParserNodeInfo node_info;
+    int line, tlen;
+    xmlNodePtr ret;
+    int nsNr = ctxt->nsNr;
+
+    if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
+        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
+		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
+			  xmlParserMaxDepth);
+	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;
+    }
+
+    if (ctxt->spaceNr == 0)
+	spacePush(ctxt, -1);
+    else if (*ctxt->space == -2)
+	spacePush(ctxt, -1);
+    else
+	spacePush(ctxt, *ctxt->space);
+
+    line = ctxt->input->line;
+#ifdef LIBXML_SAX1_ENABLED
+    if (ctxt->sax2)
+#endif /* LIBXML_SAX1_ENABLED */
+        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
+#ifdef LIBXML_SAX1_ENABLED
+    else
+	name = xmlParseStartTag(ctxt);
+#endif /* LIBXML_SAX1_ENABLED */
+    if (ctxt->instate == XML_PARSER_EOF)
+	return;
+    if (name == NULL) {
+	spacePop(ctxt);
+        return;
+    }
+    namePush(ctxt, name);
+    ret = ctxt->node;
+
+#ifdef LIBXML_VALID_ENABLED
+    /*
+     * [ VC: Root Element Type ]
+     * The Name in the document type declaration must match the element
+     * type of the root element. 
+     */
+    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
+        ctxt->node && (ctxt->node == ctxt->myDoc->children))
+        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
+#endif /* LIBXML_VALID_ENABLED */
+
+    /*
+     * Check for an Empty Element.
+     */
+    if ((RAW == '/') && (NXT(1) == '>')) {
+        SKIP(2);
+	if (ctxt->sax2) {
+	    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
+		(!ctxt->disableSAX))
+		ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
+#ifdef LIBXML_SAX1_ENABLED
+	} else {
+	    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
+		(!ctxt->disableSAX))
+		ctxt->sax->endElement(ctxt->userData, name);
+#endif /* LIBXML_SAX1_ENABLED */
+	}
+	namePop(ctxt);
+	spacePop(ctxt);
+	if (nsNr != ctxt->nsNr)
+	    nsPop(ctxt, ctxt->nsNr - nsNr);
+	if ( ret != NULL && ctxt->record_info ) {
+	   node_info.end_pos = ctxt->input->consumed +
+			      (CUR_PTR - ctxt->input->base);
+	   node_info.end_line = ctxt->input->line;
+	   node_info.node = ret;
+	   xmlParserAddNodeInfo(ctxt, &node_info);
+	}
+	return;
+    }
+    if (RAW == '>') {
+        NEXT1;
+    } else {
+        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
+		     "Couldn't find end of Start Tag %s line %d\n",
+		                name, line, NULL);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	nodePop(ctxt);
+	namePop(ctxt);
+	spacePop(ctxt);
+	if (nsNr != ctxt->nsNr)
+	    nsPop(ctxt, ctxt->nsNr - nsNr);
+
+	/*
+	 * Capture end position and add node
+	 */
+	if ( ret != NULL && ctxt->record_info ) {
+	   node_info.end_pos = ctxt->input->consumed +
+			      (CUR_PTR - ctxt->input->base);
+	   node_info.end_line = ctxt->input->line;
+	   node_info.node = ret;
+	   xmlParserAddNodeInfo(ctxt, &node_info);
+	}
+	return;
+    }
+
+    /*
+     * Parse the content of the element:
+     */
+    xmlParseContent(ctxt);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return;
+    if (!IS_BYTE_CHAR(RAW)) {
+        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
+	 "Premature end of data in tag %s line %d\n",
+		                name, line, NULL);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	nodePop(ctxt);
+	namePop(ctxt);
+	spacePop(ctxt);
+	if (nsNr != ctxt->nsNr)
+	    nsPop(ctxt, ctxt->nsNr - nsNr);
+	return;
+    }
+
+    /*
+     * parse the end of tag: '</' should be here.
+     */
+    if (ctxt->sax2) {
+	xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
+	namePop(ctxt);
+    }
+#ifdef LIBXML_SAX1_ENABLED
+      else
+	xmlParseEndTag1(ctxt, line);
+#endif /* LIBXML_SAX1_ENABLED */
+
+    /*
+     * Capture end position and add node
+     */
+    if ( ret != NULL && ctxt->record_info ) {
+       node_info.end_pos = ctxt->input->consumed +
+                          (CUR_PTR - ctxt->input->base);
+       node_info.end_line = ctxt->input->line;
+       node_info.node = ret;
+       xmlParserAddNodeInfo(ctxt, &node_info);
+    }
+}
+
+/**
+ * xmlParseVersionNum:
+ * @ctxt:  an XML parser context
+ *
+ * parse the XML version value.
+ *
+ * [26] VersionNum ::= '1.' [0-9]+
+ *
+ * In practice allow [0-9].[0-9]+ at that level
+ *
+ * Returns the string giving the XML version number, or NULL
+ */
+xmlChar *
+xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = 10;
+    xmlChar cur;
+
+    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+    if (buf == NULL) {
+	xmlErrMemory(ctxt, NULL);
+	return(NULL);
+    }
+    cur = CUR;
+    if (!((cur >= '0') && (cur <= '9'))) {
+	xmlFree(buf);
+	return(NULL);
+    }
+    buf[len++] = cur;
+    NEXT;
+    cur=CUR;
+    if (cur != '.') {
+	xmlFree(buf);
+	return(NULL);
+    }
+    buf[len++] = cur;
+    NEXT;
+    cur=CUR;
+    while ((cur >= '0') && (cur <= '9')) {
+	if (len + 1 >= size) {
+	    xmlChar *tmp;
+
+	    size *= 2;
+	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+	    if (tmp == NULL) {
+	        xmlFree(buf);
+		xmlErrMemory(ctxt, NULL);
+		return(NULL);
+	    }
+	    buf = tmp;
+	}
+	buf[len++] = cur;
+	NEXT;
+	cur=CUR;
+    }
+    buf[len] = 0;
+    return(buf);
+}
+
+/**
+ * xmlParseVersionInfo:
+ * @ctxt:  an XML parser context
+ *
+ * parse the XML version.
+ *
+ * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
+ *
+ * [25] Eq ::= S? '=' S?
+ *
+ * Returns the version string, e.g. "1.0"
+ */
+
+xmlChar *
+xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
+    xmlChar *version = NULL;
+
+    if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
+	SKIP(7);
+	SKIP_BLANKS;
+	if (RAW != '=') {
+	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
+	    return(NULL);
+        }
+	NEXT;
+	SKIP_BLANKS;
+	if (RAW == '"') {
+	    NEXT;
+	    version = xmlParseVersionNum(ctxt);
+	    if (RAW != '"') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else if (RAW == '\''){
+	    NEXT;
+	    version = xmlParseVersionNum(ctxt);
+	    if (RAW != '\'') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
+	}
+    }
+    return(version);
+}
+
+/**
+ * xmlParseEncName:
+ * @ctxt:  an XML parser context
+ *
+ * parse the XML encoding name
+ *
+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
+ *
+ * Returns the encoding name value or NULL
+ */
+xmlChar *
+xmlParseEncName(xmlParserCtxtPtr ctxt) {
+    xmlChar *buf = NULL;
+    int len = 0;
+    int size = 10;
+    xmlChar cur;
+
+    cur = CUR;
+    if (((cur >= 'a') && (cur <= 'z')) ||
+        ((cur >= 'A') && (cur <= 'Z'))) {
+	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+	if (buf == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    return(NULL);
+	}
+
+	buf[len++] = cur;
+	NEXT;
+	cur = CUR;
+	while (((cur >= 'a') && (cur <= 'z')) ||
+	       ((cur >= 'A') && (cur <= 'Z')) ||
+	       ((cur >= '0') && (cur <= '9')) ||
+	       (cur == '.') || (cur == '_') ||
+	       (cur == '-')) {
+	    if (len + 1 >= size) {
+	        xmlChar *tmp;
+
+		size *= 2;
+		tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+		if (tmp == NULL) {
+		    xmlErrMemory(ctxt, NULL);
+		    xmlFree(buf);
+		    return(NULL);
+		}
+		buf = tmp;
+	    }
+	    buf[len++] = cur;
+	    NEXT;
+	    cur = CUR;
+	    if (cur == 0) {
+	        SHRINK;
+		GROW;
+		cur = CUR;
+	    }
+        }
+	buf[len] = 0;
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
+    }
+    return(buf);
+}
+
+/**
+ * xmlParseEncodingDecl:
+ * @ctxt:  an XML parser context
+ * 
+ * parse the XML encoding declaration
+ *
+ * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
+ *
+ * this setups the conversion filters.
+ *
+ * Returns the encoding value or NULL
+ */
+
+const xmlChar *
+xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
+    xmlChar *encoding = NULL;
+
+    SKIP_BLANKS;
+    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
+	SKIP(8);
+	SKIP_BLANKS;
+	if (RAW != '=') {
+	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
+	    return(NULL);
+        }
+	NEXT;
+	SKIP_BLANKS;
+	if (RAW == '"') {
+	    NEXT;
+	    encoding = xmlParseEncName(ctxt);
+	    if (RAW != '"') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else if (RAW == '\''){
+	    NEXT;
+	    encoding = xmlParseEncName(ctxt);
+	    if (RAW != '\'') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
+	}
+	/*
+	 * UTF-16 encoding stwich has already taken place at this stage,
+	 * more over the little-endian/big-endian selection is already done
+	 */
+        if ((encoding != NULL) &&
+	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
+	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
+	    /*
+	     * If no encoding was passed to the parser, that we are
+	     * using UTF-16 and no decoder is present i.e. the 
+	     * document is apparently UTF-8 compatible, then raise an
+	     * encoding mismatch fatal error
+	     */
+	    if ((ctxt->encoding == NULL) &&
+	        (ctxt->input->buf != NULL) &&
+	        (ctxt->input->buf->encoder == NULL)) {
+		xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
+		  "Document labelled UTF-16 but has UTF-8 content\n");
+	    }
+	    if (ctxt->encoding != NULL)
+		xmlFree((xmlChar *) ctxt->encoding);
+	    ctxt->encoding = encoding;
+	}
+	/*
+	 * UTF-8 encoding is handled natively
+	 */
+        else if ((encoding != NULL) &&
+	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
+	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
+	    if (ctxt->encoding != NULL)
+		xmlFree((xmlChar *) ctxt->encoding);
+	    ctxt->encoding = encoding;
+	}
+	else if (encoding != NULL) {
+	    xmlCharEncodingHandlerPtr handler;
+
+	    if (ctxt->input->encoding != NULL)
+		xmlFree((xmlChar *) ctxt->input->encoding);
+	    ctxt->input->encoding = encoding;
+
+            handler = xmlFindCharEncodingHandler((const char *) encoding);
+	    if (handler != NULL) {
+		xmlSwitchToEncoding(ctxt, handler);
+	    } else {
+		xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			"Unsupported encoding %s\n", encoding);
+		return(NULL);
+	    }
+	}
+    }
+    return(encoding);
+}
+
+/**
+ * xmlParseSDDecl:
+ * @ctxt:  an XML parser context
+ *
+ * parse the XML standalone declaration
+ *
+ * [32] SDDecl ::= S 'standalone' Eq
+ *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
+ *
+ * [ VC: Standalone Document Declaration ]
+ * TODO The standalone document declaration must have the value "no"
+ * if any external markup declarations contain declarations of:
+ *  - attributes with default values, if elements to which these
+ *    attributes apply appear in the document without specifications
+ *    of values for these attributes, or
+ *  - entities (other than amp, lt, gt, apos, quot), if references
+ *    to those entities appear in the document, or
+ *  - attributes with values subject to normalization, where the
+ *    attribute appears in the document with a value which will change
+ *    as a result of normalization, or
+ *  - element types with element content, if white space occurs directly
+ *    within any instance of those types.
+ *
+ * Returns:
+ *   1 if standalone="yes"
+ *   0 if standalone="no"
+ *  -2 if standalone attribute is missing or invalid
+ *	  (A standalone value of -2 means that the XML declaration was found,
+ *	   but no value was specified for the standalone attribute).
+ */
+
+int
+xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
+    int standalone = -2;
+
+    SKIP_BLANKS;
+    if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
+	SKIP(10);
+        SKIP_BLANKS;
+	if (RAW != '=') {
+	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
+	    return(standalone);
+        }
+	NEXT;
+	SKIP_BLANKS;
+        if (RAW == '\''){
+	    NEXT;
+	    if ((RAW == 'n') && (NXT(1) == 'o')) {
+	        standalone = 0;
+                SKIP(2);
+	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
+	               (NXT(2) == 's')) {
+	        standalone = 1;
+		SKIP(3);
+            } else {
+		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
+	    }
+	    if (RAW != '\'') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else if (RAW == '"'){
+	    NEXT;
+	    if ((RAW == 'n') && (NXT(1) == 'o')) {
+	        standalone = 0;
+		SKIP(2);
+	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
+	               (NXT(2) == 's')) {
+	        standalone = 1;
+                SKIP(3);
+            } else {
+		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
+	    }
+	    if (RAW != '"') {
+		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+	    } else
+	        NEXT;
+	} else {
+	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
+        }
+    }
+    return(standalone);
+}
+
+/**
+ * xmlParseXMLDecl:
+ * @ctxt:  an XML parser context
+ * 
+ * parse an XML declaration header
+ *
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ */
+
+void
+xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
+    xmlChar *version;
+
+    /*
+     * This value for standalone indicates that the document has an
+     * XML declaration but it does not have a standalone attribute.
+     * It will be overwritten later if a standalone attribute is found.
+     */
+    ctxt->input->standalone = -2;
+
+    /*
+     * We know that '<?xml' is here.
+     */
+    SKIP(5);
+
+    if (!IS_BLANK_CH(RAW)) {
+	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+	               "Blank needed after '<?xml'\n");
+    }
+    SKIP_BLANKS;
+
+    /*
+     * We must have the VersionInfo here.
+     */
+    version = xmlParseVersionInfo(ctxt);
+    if (version == NULL) {
+	xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
+    } else {
+	if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
+	    /*
+	     * Changed here for XML-1.0 5th edition
+	     */
+	    if (ctxt->options & XML_PARSE_OLD10) {
+		xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
+			          "Unsupported version '%s'\n",
+			          version);
+	    } else {
+	        if ((version[0] == '1') && ((version[1] == '.'))) {
+		    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
+		                  "Unsupported version '%s'\n",
+				  version, NULL);
+		} else {
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
+				      "Unsupported version '%s'\n",
+				      version);
+		}
+	    }
+	}
+	if (ctxt->version != NULL)
+	    xmlFree((void *) ctxt->version);
+	ctxt->version = version;
+    }
+
+    /*
+     * We may have the encoding declaration
+     */
+    if (!IS_BLANK_CH(RAW)) {
+        if ((RAW == '?') && (NXT(1) == '>')) {
+	    SKIP(2);
+	    return;
+	}
+	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
+    }
+    xmlParseEncodingDecl(ctxt);
+    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	/*
+	 * The XML REC instructs us to stop parsing right here
+	 */
+        return;
+    }
+
+    /*
+     * We may have the standalone status.
+     */
+    if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
+        if ((RAW == '?') && (NXT(1) == '>')) {
+	    SKIP(2);
+	    return;
+	}
+	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);
+
+    SKIP_BLANKS;
+    if ((RAW == '?') && (NXT(1) == '>')) {
+        SKIP(2);
+    } else if (RAW == '>') {
+        /* Deprecated old WD ... */
+	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
+	NEXT;
+    } else {
+	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
+	MOVETO_ENDTAG(CUR_PTR);
+	NEXT;
+    }
+}
+
+/**
+ * xmlParseMisc:
+ * @ctxt:  an XML parser context
+ * 
+ * parse an XML Misc* optional field.
+ *
+ * [27] Misc ::= Comment | PI |  S
+ */
+
+void
+xmlParseMisc(xmlParserCtxtPtr ctxt) {
+    while ((ctxt->instate != XML_PARSER_EOF) &&
+           (((RAW == '<') && (NXT(1) == '?')) ||
+            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
+            IS_BLANK_CH(CUR))) {
+        if ((RAW == '<') && (NXT(1) == '?')) {
+	    xmlParsePI(ctxt);
+	} else if (IS_BLANK_CH(CUR)) {
+	    NEXT;
+	} else
+	    xmlParseComment(ctxt);
+    }
+}
+
+/**
+ * xmlParseDocument:
+ * @ctxt:  an XML parser context
+ * 
+ * parse an XML document (and build a tree if using the standard SAX
+ * interface).
+ *
+ * [1] document ::= prolog element Misc*
+ *
+ * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
+ *
+ * Returns 0, -1 in case of error. the parser context is augmented
+ *                as a result of the parsing.
+ */
+
+int
+xmlParseDocument(xmlParserCtxtPtr ctxt) {
+    xmlChar start[4];
+    xmlCharEncoding enc;
+
+    xmlInitParser();
+
+    if ((ctxt == NULL) || (ctxt->input == NULL))
+        return(-1);
+
+    GROW;
+
+    /*
+     * SAX: detecting the level.
+     */
+    xmlDetectSAX2(ctxt);
+
+    /*
+     * SAX: beginning of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(-1);
+
+    if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
+	/* 
+	 * Get the 4 first bytes and decode the charset
+	 * if enc != XML_CHAR_ENCODING_NONE
+	 * plug some encoding conversion routines.
+	 */
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(&start[0], 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+
+    if (CUR == 0) {
+	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+    }
+
+    /*
+     * 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"
+     */
+    if ((ctxt->input->end - ctxt->input->cur) < 35) {
+       GROW;
+    }
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+
+	/*
+	 * Note that we will switch encoding on the fly.
+	 */
+	xmlParseXMLDecl(ctxt);
+	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	    /*
+	     * The XML REC instructs us to stop parsing right here
+	     */
+	    return(-1);
+	}
+	ctxt->standalone = ctxt->input->standalone;
+	SKIP_BLANKS;
+    } else {
+	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+    }
+    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
+        ctxt->sax->startDocument(ctxt->userData);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(-1);
+
+    /*
+     * The Misc part of the Prolog
+     */
+    GROW;
+    xmlParseMisc(ctxt);
+
+    /*
+     * Then possibly doc type declaration(s) and more Misc
+     * (doctypedecl Misc*)?
+     */
+    GROW;
+    if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
+
+	ctxt->inSubset = 1;
+	xmlParseDocTypeDecl(ctxt);
+	if (RAW == '[') {
+	    ctxt->instate = XML_PARSER_DTD;
+	    xmlParseInternalSubset(ctxt);
+	    if (ctxt->instate == XML_PARSER_EOF)
+		return(-1);
+	}
+
+	/*
+	 * Create and update the external subset.
+	 */
+	ctxt->inSubset = 2;
+	if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
+	    (!ctxt->disableSAX))
+	    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
+	                              ctxt->extSubSystem, ctxt->extSubURI);
+	if (ctxt->instate == XML_PARSER_EOF)
+	    return(-1);
+	ctxt->inSubset = 0;
+
+        xmlCleanSpecialAttr(ctxt);
+
+	ctxt->instate = XML_PARSER_PROLOG;
+	xmlParseMisc(ctxt);
+    }
+
+    /*
+     * Time to start parsing the tree itself
+     */
+    GROW;
+    if (RAW != '<') {
+	xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
+		       "Start tag expected, '<' not found\n");
+    } else {
+	ctxt->instate = XML_PARSER_CONTENT;
+	xmlParseElement(ctxt);
+	ctxt->instate = XML_PARSER_EPILOG;
+
+
+	/*
+	 * The Misc part at the end
+	 */
+	xmlParseMisc(ctxt);
+
+	if (RAW != 0) {
+	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+	}
+	ctxt->instate = XML_PARSER_EOF;
+    }
+
+    /*
+     * SAX: end of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+        ctxt->sax->endDocument(ctxt->userData);
+
+    /*
+     * Remove locally kept entity definitions if the tree was not built
+     */
+    if ((ctxt->myDoc != NULL) &&
+	(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
+	xmlFreeDoc(ctxt->myDoc);
+	ctxt->myDoc = NULL;
+    }
+
+    if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
+        ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
+	if (ctxt->valid)
+	    ctxt->myDoc->properties |= XML_DOC_DTDVALID;
+	if (ctxt->nsWellFormed)
+	    ctxt->myDoc->properties |= XML_DOC_NSVALID;
+	if (ctxt->options & XML_PARSE_OLD10)
+	    ctxt->myDoc->properties |= XML_DOC_OLD10;
+    }
+    if (! ctxt->wellFormed) {
+	ctxt->valid = 0;
+	return(-1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseExtParsedEnt:
+ * @ctxt:  an XML parser context
+ * 
+ * parse a general parsed entity
+ * An external general parsed entity is well-formed if it matches the
+ * production labeled extParsedEnt.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * Returns 0, -1 in case of error. the parser context is augmented
+ *                as a result of the parsing.
+ */
+
+int
+xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
+    xmlChar start[4];
+    xmlCharEncoding enc;
+
+    if ((ctxt == NULL) || (ctxt->input == NULL))
+        return(-1);
+
+    xmlDefaultSAXHandlerInit();
+
+    xmlDetectSAX2(ctxt);
+
+    GROW;
+
+    /*
+     * SAX: beginning of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
+
+    /* 
+     * Get the 4 first bytes and decode the charset
+     * if enc != XML_CHAR_ENCODING_NONE
+     * plug some encoding conversion routines.
+     */
+    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(start, 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+
+    if (CUR == 0) {
+	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+    }
+
+    /*
+     * Check for the XMLDecl in the Prolog.
+     */
+    GROW;
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+
+	/*
+	 * Note that we will switch encoding on the fly.
+	 */
+	xmlParseXMLDecl(ctxt);
+	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	    /*
+	     * The XML REC instructs us to stop parsing right here
+	     */
+	    return(-1);
+	}
+	SKIP_BLANKS;
+    } else {
+	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+    }
+    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
+        ctxt->sax->startDocument(ctxt->userData);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(-1);
+
+    /*
+     * Doing validity checking on chunk doesn't make sense
+     */
+    ctxt->instate = XML_PARSER_CONTENT;
+    ctxt->validate = 0;
+    ctxt->loadsubset = 0;
+    ctxt->depth = 0;
+
+    xmlParseContent(ctxt);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(-1);
+   
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+
+    /*
+     * SAX: end of the document processing.
+     */
+    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+        ctxt->sax->endDocument(ctxt->userData);
+
+    if (! ctxt->wellFormed) return(-1);
+    return(0);
+}
+
+#ifdef LIBXML_PUSH_ENABLED
+/************************************************************************
+ *									*
+ * 		Progressive parsing interfaces				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlParseLookupSequence:
+ * @ctxt:  an XML parser context
+ * @first:  the first char to lookup
+ * @next:  the next char to lookup or zero
+ * @third:  the next char to lookup or zero
+ *
+ * Try to find if a sequence (first, next, third) or  just (first next) or
+ * (first) 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 the full sequence
+ *      is available, -1 otherwise.
+ */
+static int
+xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
+                       xmlChar next, xmlChar third) {
+    int base, len;
+    xmlParserInputPtr in;
+    const xmlChar *buf;
+
+    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;
+    }
+    /* take into account the sequence length */
+    if (third) len -= 2;
+    else if (next) len --;
+    for (;base < len;base++) {
+        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;
+#ifdef DEBUG_PUSH
+	    if (next == 0)
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: lookup '%c' found at %d\n",
+			first, base);
+	    else if (third == 0)
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: lookup '%c%c' found at %d\n",
+			first, next, base);
+	    else 
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: lookup '%c%c%c' found at %d\n",
+			first, next, third, base);
+#endif
+	    return(base - (in->cur - in->base));
+	}
+    }
+    ctxt->checkIndex = base;
+#ifdef DEBUG_PUSH
+    if (next == 0)
+	xmlGenericError(xmlGenericErrorContext,
+		"PP: lookup '%c' failed\n", first);
+    else if (third == 0)
+	xmlGenericError(xmlGenericErrorContext,
+		"PP: lookup '%c%c' failed\n", first, next);
+    else	
+	xmlGenericError(xmlGenericErrorContext,
+		"PP: lookup '%c%c%c' failed\n", first, next, third);
+#endif
+    return(-1);
+}
+
+/**
+ * xmlParseGetLasts:
+ * @ctxt:  an XML parser context
+ * @lastlt:  pointer to store the last '<' from the input
+ * @lastgt:  pointer to store the last '>' from the input
+ *
+ * Lookup the last < and > in the current chunk
+ */
+static void
+xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
+                 const xmlChar **lastgt) {
+    const xmlChar *tmp;
+
+    if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
+	xmlGenericError(xmlGenericErrorContext,
+		    "Internal error: xmlParseGetLasts\n");
+	return;
+    }
+    if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
+        tmp = ctxt->input->end;
+	tmp--;
+	while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
+	if (tmp < ctxt->input->base) {
+	    *lastlt = NULL;
+	    *lastgt = NULL;
+	} else {
+	    *lastlt = tmp;
+	    tmp++;
+	    while ((tmp < ctxt->input->end) && (*tmp != '>')) {
+	        if (*tmp == '\'') {
+		    tmp++;
+		    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
+		    if (tmp < ctxt->input->end) tmp++;
+		} else if (*tmp == '"') {
+		    tmp++;
+		    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
+		    if (tmp < ctxt->input->end) tmp++;
+		} else
+		    tmp++;
+	    }
+	    if (tmp < ctxt->input->end)
+	        *lastgt = tmp;
+	    else {
+	        tmp = *lastlt;
+		tmp--;
+		while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
+		if (tmp >= ctxt->input->base)
+		    *lastgt = tmp;
+		else
+		    *lastgt = NULL;
+	    }
+	}
+    } else {
+        *lastlt = NULL;
+	*lastgt = NULL;
+    }
+}
+/**
+ * xmlCheckCdataPush:
+ * @cur: pointer to the bock of characters
+ * @len: length of the block in bytes
+ *
+ * Check that the block of characters is okay as SCdata content [20]
+ *
+ * Returns the number of bytes to pass if okay, a negative index where an
+ *         UTF-8 error occured otherwise
+ */
+static int
+xmlCheckCdataPush(const xmlChar *utf, int len) {
+    int ix;
+    unsigned char c;
+    int codepoint;
+
+    if ((utf == NULL) || (len <= 0))
+        return(0);
+    
+    for (ix = 0; ix < len;) {      /* string is 0-terminated */
+        c = utf[ix];
+        if ((c & 0x80) == 0x00) {	/* 1-byte code, starts with 10 */
+	    if (c >= 0x20)
+		ix++;
+	    else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
+	        ix++;
+	    else
+	        return(-ix);
+	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
+	    if (ix + 2 > len) return(ix);
+	    if ((utf[ix+1] & 0xc0 ) != 0x80)
+	        return(-ix);
+	    codepoint = (utf[ix] & 0x1f) << 6;
+	    codepoint |= utf[ix+1] & 0x3f;
+	    if (!xmlIsCharQ(codepoint))
+	        return(-ix);
+	    ix += 2;
+	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
+	    if (ix + 3 > len) return(ix);
+	    if (((utf[ix+1] & 0xc0) != 0x80) ||
+	        ((utf[ix+2] & 0xc0) != 0x80))
+		    return(-ix);
+	    codepoint = (utf[ix] & 0xf) << 12;
+	    codepoint |= (utf[ix+1] & 0x3f) << 6;
+	    codepoint |= utf[ix+2] & 0x3f;
+	    if (!xmlIsCharQ(codepoint))
+	        return(-ix);
+	    ix += 3;
+	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
+	    if (ix + 4 > len) return(ix);
+	    if (((utf[ix+1] & 0xc0) != 0x80) ||
+	        ((utf[ix+2] & 0xc0) != 0x80) ||
+		((utf[ix+3] & 0xc0) != 0x80))
+		    return(-ix);
+	    codepoint = (utf[ix] & 0x7) << 18;
+	    codepoint |= (utf[ix+1] & 0x3f) << 12;
+	    codepoint |= (utf[ix+2] & 0x3f) << 6;
+	    codepoint |= utf[ix+3] & 0x3f;
+	    if (!xmlIsCharQ(codepoint))
+	        return(-ix);
+	    ix += 4;
+	} else				/* unknown encoding */
+	    return(-ix);
+      }
+      return(ix);
+}
+
+/**
+ * xmlParseTryOrFinish:
+ * @ctxt:  an XML parser context
+ * @terminate:  last chunk indicator
+ *
+ * Try to progress on parsing
+ *
+ * Returns zero if no parsing was possible
+ */
+static int
+xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+    int ret = 0;
+    int avail, tlen;
+    xmlChar cur, next;
+    const xmlChar *lastlt, *lastgt;
+
+    if (ctxt->input == NULL)
+        return(0);
+
+#ifdef DEBUG_PUSH
+    switch (ctxt->instate) {
+	case XML_PARSER_EOF:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try EOF\n"); break;
+	case XML_PARSER_START:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try START\n"); break;
+	case XML_PARSER_MISC:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try MISC\n");break;
+	case XML_PARSER_COMMENT:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try COMMENT\n");break;
+	case XML_PARSER_PROLOG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try PROLOG\n");break;
+	case XML_PARSER_START_TAG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try START_TAG\n");break;
+	case XML_PARSER_CONTENT:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try CONTENT\n");break;
+	case XML_PARSER_CDATA_SECTION:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try CDATA_SECTION\n");break;
+	case XML_PARSER_END_TAG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try END_TAG\n");break;
+	case XML_PARSER_ENTITY_DECL:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try ENTITY_DECL\n");break;
+	case XML_PARSER_ENTITY_VALUE:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try ENTITY_VALUE\n");break;
+	case XML_PARSER_ATTRIBUTE_VALUE:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try ATTRIBUTE_VALUE\n");break;
+	case XML_PARSER_DTD:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try DTD\n");break;
+	case XML_PARSER_EPILOG:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try EPILOG\n");break;
+	case XML_PARSER_PI:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PP: try PI\n");break;
+        case XML_PARSER_IGNORE:
+            xmlGenericError(xmlGenericErrorContext,
+		    "PP: try IGNORE\n");break;
+    }
+#endif
+
+    if ((ctxt->input != NULL) &&
+        (ctxt->input->cur - ctxt->input->base > 4096)) {
+	xmlSHRINK(ctxt);
+	ctxt->checkIndex = 0;
+    }
+    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+
+    while (ctxt->instate != XML_PARSER_EOF) {
+	if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+	    return(0);
+
+        
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((RAW == 0) && (ctxt->inputNr > 1))
+	    xmlPopInput(ctxt);
+
+	if (ctxt->input == NULL) break;
+	if (ctxt->input->buf == NULL)
+	    avail = ctxt->input->length -
+	            (ctxt->input->cur - ctxt->input->base);
+	else {
+	    /*
+	     * If we are operating on converted input, try to flush
+	     * remainng chars to avoid them stalling in the non-converted
+	     * buffer.
+	     */
+	    if ((ctxt->input->buf->raw != NULL) &&
+		(ctxt->input->buf->raw->use > 0)) {
+		int base = ctxt->input->base -
+		           ctxt->input->buf->buffer->content;
+		int current = ctxt->input->cur - ctxt->input->base;
+
+		xmlParserInputBufferPush(ctxt->input->buf, 0, "");
+		ctxt->input->base = ctxt->input->buf->buffer->content + base;
+		ctxt->input->cur = ctxt->input->base + current;
+		ctxt->input->end =
+		    &ctxt->input->buf->buffer->content[
+		                       ctxt->input->buf->buffer->use];
+	    }
+	    avail = ctxt->input->buf->buffer->use -
+		    (ctxt->input->cur - ctxt->input->base);
+	}
+        if (avail < 1)
+	    goto done;
+        switch (ctxt->instate) {
+            case XML_PARSER_EOF:
+	        /*
+		 * Document parsing is done !
+		 */
+	        goto done;
+            case XML_PARSER_START:
+		if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
+		    xmlChar start[4];
+		    xmlCharEncoding enc;
+
+		    /*
+		     * Very first chars read from the document flow.
+		     */
+		    if (avail < 4)
+			goto done;
+
+		    /* 
+		     * Get the 4 first bytes and decode the charset
+		     * if enc != XML_CHAR_ENCODING_NONE
+		     * plug some encoding conversion routines,
+		     * else xmlSwitchEncoding will set to (default)
+		     * UTF8.
+		     */
+		    start[0] = RAW;
+		    start[1] = NXT(1);
+		    start[2] = NXT(2);
+		    start[3] = NXT(3);
+		    enc = xmlDetectCharEncoding(start, 4);
+		    xmlSwitchEncoding(ctxt, enc);
+		    break;
+		}
+
+		if (avail < 2)
+		    goto done;
+		cur = ctxt->input->cur[0];
+		next = ctxt->input->cur[1];
+		if (cur == 0) {
+		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+			ctxt->sax->setDocumentLocator(ctxt->userData,
+						      &xmlDefaultSAXLocator);
+		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+		    ctxt->instate = XML_PARSER_EOF;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering EOF\n");
+#endif
+		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+			ctxt->sax->endDocument(ctxt->userData);
+		    goto done;
+		}
+	        if ((cur == '<') && (next == '?')) {
+		    /* PI or XML decl */
+		    if (avail < 5) return(ret);
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+			return(ret);
+		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+			ctxt->sax->setDocumentLocator(ctxt->userData,
+						      &xmlDefaultSAXLocator);
+		    if ((ctxt->input->cur[2] == 'x') &&
+			(ctxt->input->cur[3] == 'm') &&
+			(ctxt->input->cur[4] == 'l') &&
+			(IS_BLANK_CH(ctxt->input->cur[5]))) {
+			ret += 5;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"PP: Parsing XML Decl\n");
+#endif
+			xmlParseXMLDecl(ctxt);
+			if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+			    /*
+			     * The XML REC instructs us to stop parsing right
+			     * here
+			     */
+			    ctxt->instate = XML_PARSER_EOF;
+			    return(0);
+			}
+			ctxt->standalone = ctxt->input->standalone;
+			if ((ctxt->encoding == NULL) &&
+			    (ctxt->input->encoding != NULL))
+			    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
+			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
+			    (!ctxt->disableSAX))
+			    ctxt->sax->startDocument(ctxt->userData);
+			ctxt->instate = XML_PARSER_MISC;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"PP: entering MISC\n");
+#endif
+		    } else {
+			ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
+			    (!ctxt->disableSAX))
+			    ctxt->sax->startDocument(ctxt->userData);
+			ctxt->instate = XML_PARSER_MISC;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"PP: entering MISC\n");
+#endif
+		    }
+		} else {
+		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
+			ctxt->sax->setDocumentLocator(ctxt->userData,
+						      &xmlDefaultSAXLocator);
+		    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
+		    if (ctxt->version == NULL) {
+		        xmlErrMemory(ctxt, NULL);
+			break;
+		    }
+		    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
+		        (!ctxt->disableSAX))
+			ctxt->sax->startDocument(ctxt->userData);
+		    ctxt->instate = XML_PARSER_MISC;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering MISC\n");
+#endif
+		}
+		break;
+            case XML_PARSER_START_TAG: {
+	        const xmlChar *name;
+		const xmlChar *prefix = NULL;
+		const xmlChar *URI = NULL;
+		int nsNr = ctxt->nsNr;
+
+		if ((avail < 2) && (ctxt->inputNr == 1))
+		    goto done;
+		cur = ctxt->input->cur[0];
+	        if (cur != '<') {
+		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+		    ctxt->instate = XML_PARSER_EOF;
+		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+			ctxt->sax->endDocument(ctxt->userData);
+		    goto done;
+		}
+		if (!terminate) {
+		    if (ctxt->progressive) {
+		        /* > can be found unescaped in attribute values */
+		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
+			    goto done;
+		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
+			goto done;
+		    }
+		}
+		if (ctxt->spaceNr == 0)
+		    spacePush(ctxt, -1);
+		else if (*ctxt->space == -2)
+		    spacePush(ctxt, -1);
+		else
+		    spacePush(ctxt, *ctxt->space);
+#ifdef LIBXML_SAX1_ENABLED
+		if (ctxt->sax2)
+#endif /* LIBXML_SAX1_ENABLED */
+		    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
+#ifdef LIBXML_SAX1_ENABLED
+		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;
+		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+			ctxt->sax->endDocument(ctxt->userData);
+		    goto done;
+		}
+#ifdef LIBXML_VALID_ENABLED
+		/*
+		 * [ VC: Root Element Type ]
+		 * The Name in the document type declaration must match
+		 * the element type of the root element. 
+		 */
+		if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
+		    ctxt->node && (ctxt->node == ctxt->myDoc->children))
+		    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
+#endif /* LIBXML_VALID_ENABLED */
+
+		/*
+		 * Check for an Empty Element.
+		 */
+		if ((RAW == '/') && (NXT(1) == '>')) {
+		    SKIP(2);
+
+		    if (ctxt->sax2) {
+			if ((ctxt->sax != NULL) &&
+			    (ctxt->sax->endElementNs != NULL) &&
+			    (!ctxt->disableSAX))
+			    ctxt->sax->endElementNs(ctxt->userData, name,
+			                            prefix, URI);
+			if (ctxt->nsNr - nsNr > 0)
+			    nsPop(ctxt, ctxt->nsNr - nsNr);
+#ifdef LIBXML_SAX1_ENABLED
+		    } else {
+			if ((ctxt->sax != NULL) &&
+			    (ctxt->sax->endElement != NULL) &&
+			    (!ctxt->disableSAX))
+			    ctxt->sax->endElement(ctxt->userData, name);
+#endif /* LIBXML_SAX1_ENABLED */
+		    }
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    spacePop(ctxt);
+		    if (ctxt->nameNr == 0) {
+			ctxt->instate = XML_PARSER_EPILOG;
+		    } else {
+			ctxt->instate = XML_PARSER_CONTENT;
+		    }
+		    break;
+		}
+		if (RAW == '>') {
+		    NEXT;
+		} else {
+		    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
+					 "Couldn't find end of Start Tag %s\n",
+					 name);
+		    nodePop(ctxt);
+		    spacePop(ctxt);
+		}
+		if (ctxt->sax2)
+		    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
+#ifdef LIBXML_SAX1_ENABLED
+		else
+		    namePush(ctxt, name);
+#endif /* LIBXML_SAX1_ENABLED */
+
+		ctxt->instate = XML_PARSER_CONTENT;
+                break;
+	    }
+            case XML_PARSER_CONTENT: {
+		const xmlChar *test;
+		unsigned int cons;
+		if ((avail < 2) && (ctxt->inputNr == 1))
+		    goto done;
+		cur = ctxt->input->cur[0];
+		next = ctxt->input->cur[1];
+
+		test = CUR_PTR;
+	        cons = ctxt->input->consumed;
+		if ((cur == '<') && (next == '/')) {
+		    ctxt->instate = XML_PARSER_END_TAG;
+		    break;
+	        } else if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+			goto done;
+		    xmlParsePI(ctxt);
+		} else if ((cur == '<') && (next != '!')) {
+		    ctxt->instate = XML_PARSER_START_TAG;
+		    break;
+		} else if ((cur == '<') && (next == '!') &&
+		           (ctxt->input->cur[2] == '-') &&
+			   (ctxt->input->cur[3] == '-')) {
+		    int term;
+
+	            if (avail < 4)
+		        goto done;
+		    ctxt->input->cur += 4;
+		    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
+		    ctxt->input->cur -= 4;
+		    if ((!terminate) && (term < 0))
+			goto done;
+		    xmlParseComment(ctxt);
+		    ctxt->instate = XML_PARSER_CONTENT;
+		} else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
+		    (ctxt->input->cur[2] == '[') &&
+		    (ctxt->input->cur[3] == 'C') &&
+		    (ctxt->input->cur[4] == 'D') &&
+		    (ctxt->input->cur[5] == 'A') &&
+		    (ctxt->input->cur[6] == 'T') &&
+		    (ctxt->input->cur[7] == 'A') &&
+		    (ctxt->input->cur[8] == '[')) {
+		    SKIP(9);
+		    ctxt->instate = XML_PARSER_CDATA_SECTION;
+		    break;
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 9)) {
+		    goto done;
+		} else if (cur == '&') {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
+			goto done;
+		    xmlParseReference(ctxt);
+		} else {
+		    /* TODO Avoid the extra copy, handle directly !!! */
+		    /*
+		     * Goal of the following test is:
+		     *  - minimize calls to the SAX 'character' callback
+		     *    when they are mergeable
+		     *  - handle an problem for isBlank when we only parse
+		     *    a sequence of blank chars and the next one is
+		     *    not available to check against '<' presence.
+		     *  - tries to homogenize the differences in SAX
+		     *    callbacks between the push and pull versions
+		     *    of the parser.
+		     */
+		    if ((ctxt->inputNr == 1) &&
+		        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
+			if (!terminate) {
+			    if (ctxt->progressive) {
+				if ((lastlt == NULL) ||
+				    (ctxt->input->cur > lastlt))
+				    goto done;
+			    } else if (xmlParseLookupSequence(ctxt,
+			                                      '<', 0, 0) < 0) {
+				goto done;
+			    }
+			}
+                    }
+		    ctxt->checkIndex = 0;
+		    xmlParseCharData(ctxt, 0);
+		}
+		/*
+		 * Pop-up of finished entities.
+		 */
+		while ((RAW == 0) && (ctxt->inputNr > 1))
+		    xmlPopInput(ctxt);
+		if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
+		    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		                "detected an error in element content\n");
+		    ctxt->instate = XML_PARSER_EOF;
+		    break;
+		}
+		break;
+	    }
+            case XML_PARSER_END_TAG:
+		if (avail < 2)
+		    goto done;
+		if (!terminate) {
+		    if (ctxt->progressive) {
+		        /* > can be found unescaped in attribute values */
+		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
+			    goto done;
+		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
+			goto done;
+		    }
+		}
+		if (ctxt->sax2) {
+		    xmlParseEndTag2(ctxt,
+		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
+		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
+		       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
+		    nameNsPop(ctxt);
+		}
+#ifdef LIBXML_SAX1_ENABLED
+		  else
+		    xmlParseEndTag1(ctxt, 0);
+#endif /* LIBXML_SAX1_ENABLED */
+		if (ctxt->instate == XML_PARSER_EOF) {
+		    /* Nothing */
+		} else if (ctxt->nameNr == 0) {
+		    ctxt->instate = XML_PARSER_EPILOG;
+		} else {
+		    ctxt->instate = XML_PARSER_CONTENT;
+		}
+		break;
+            case XML_PARSER_CDATA_SECTION: {
+	        /*
+		 * The Push mode need to have the SAX callback for 
+		 * cdataBlock merge back contiguous callbacks.
+		 */
+		int base;
+
+		base = xmlParseLookupSequence(ctxt, ']', ']', '>');
+		if (base < 0) {
+		    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
+		        int tmp;
+
+			tmp = xmlCheckCdataPush(ctxt->input->cur, 
+			                        XML_PARSER_BIG_BUFFER_SIZE);
+			if (tmp < 0) {
+			    tmp = -tmp;
+			    ctxt->input->cur += tmp;
+			    goto encoding_error;
+			}
+			if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+			    if (ctxt->sax->cdataBlock != NULL)
+				ctxt->sax->cdataBlock(ctxt->userData,
+				                      ctxt->input->cur, tmp);
+			    else if (ctxt->sax->characters != NULL)
+				ctxt->sax->characters(ctxt->userData,
+				                      ctxt->input->cur, tmp);
+			}
+			if (ctxt->instate == XML_PARSER_EOF)
+			    goto done;
+			SKIPL(tmp);
+			ctxt->checkIndex = 0;
+		    }
+		    goto done;
+		} else {
+		    int tmp;
+
+		    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
+		    if ((tmp < 0) || (tmp != base)) {
+			tmp = -tmp;
+			ctxt->input->cur += tmp;
+			goto encoding_error;
+		    }
+		    if ((ctxt->sax != NULL) && (base == 0) &&
+		        (ctxt->sax->cdataBlock != NULL) &&
+		        (!ctxt->disableSAX)) {
+			/*
+			 * Special case to provide identical behaviour
+			 * between pull and push parsers on enpty CDATA
+			 * sections
+			 */
+			 if ((ctxt->input->cur - ctxt->input->base >= 9) &&
+			     (!strncmp((const char *)&ctxt->input->cur[-9],
+			               "<![CDATA[", 9)))
+			     ctxt->sax->cdataBlock(ctxt->userData,
+			                           BAD_CAST "", 0);
+		    } else if ((ctxt->sax != NULL) && (base > 0) &&
+			(!ctxt->disableSAX)) {
+			if (ctxt->sax->cdataBlock != NULL)
+			    ctxt->sax->cdataBlock(ctxt->userData,
+						  ctxt->input->cur, base);
+			else if (ctxt->sax->characters != NULL)
+			    ctxt->sax->characters(ctxt->userData,
+						  ctxt->input->cur, base);
+		    }
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    SKIPL(base + 3);
+		    ctxt->checkIndex = 0;
+		    ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering CONTENT\n");
+#endif
+		}
+		break;
+	    }
+            case XML_PARSER_MISC:
+		SKIP_BLANKS;
+		if (ctxt->input->buf == NULL)
+		    avail = ctxt->input->length -
+		            (ctxt->input->cur - ctxt->input->base);
+		else
+		    avail = ctxt->input->buf->buffer->use -
+		            (ctxt->input->cur - ctxt->input->base);
+		if (avail < 2)
+		    goto done;
+		cur = ctxt->input->cur[0];
+		next = ctxt->input->cur[1];
+	        if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing PI\n");
+#endif
+		    xmlParsePI(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    ctxt->checkIndex = 0;
+		} else if ((cur == '<') && (next == '!') &&
+		    (ctxt->input->cur[2] == '-') &&
+		    (ctxt->input->cur[3] == '-')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing Comment\n");
+#endif
+		    xmlParseComment(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    ctxt->instate = XML_PARSER_MISC;
+		    ctxt->checkIndex = 0;
+		} else if ((cur == '<') && (next == '!') &&
+		    (ctxt->input->cur[2] == 'D') &&
+		    (ctxt->input->cur[3] == 'O') &&
+		    (ctxt->input->cur[4] == 'C') &&
+		    (ctxt->input->cur[5] == 'T') &&
+		    (ctxt->input->cur[6] == 'Y') &&
+		    (ctxt->input->cur[7] == 'P') &&
+		    (ctxt->input->cur[8] == 'E')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing internal subset\n");
+#endif
+		    ctxt->inSubset = 1;
+		    xmlParseDocTypeDecl(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    if (RAW == '[') {
+			ctxt->instate = XML_PARSER_DTD;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"PP: entering DTD\n");
+#endif
+		    } else {
+			/*
+			 * Create and update the external subset.
+			 */
+			ctxt->inSubset = 2;
+			if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+			    (ctxt->sax->externalSubset != NULL))
+			    ctxt->sax->externalSubset(ctxt->userData,
+				    ctxt->intSubName, ctxt->extSubSystem,
+				    ctxt->extSubURI);
+			ctxt->inSubset = 0;
+			xmlCleanSpecialAttr(ctxt);
+			ctxt->instate = XML_PARSER_PROLOG;
+#ifdef DEBUG_PUSH
+			xmlGenericError(xmlGenericErrorContext,
+				"PP: entering PROLOG\n");
+#endif
+		    }
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 9)) {
+		    goto done;
+		} else {
+		    ctxt->instate = XML_PARSER_START_TAG;
+		    ctxt->progressive = 1;
+		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering START_TAG\n");
+#endif
+		}
+		break;
+            case XML_PARSER_PROLOG:
+		SKIP_BLANKS;
+		if (ctxt->input->buf == NULL)
+		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
+		else
+		    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
+		if (avail < 2) 
+		    goto done;
+		cur = ctxt->input->cur[0];
+		next = ctxt->input->cur[1];
+	        if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing PI\n");
+#endif
+		    xmlParsePI(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		} else if ((cur == '<') && (next == '!') &&
+		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing Comment\n");
+#endif
+		    xmlParseComment(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    ctxt->instate = XML_PARSER_PROLOG;
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 4)) {
+		    goto done;
+		} else {
+		    ctxt->instate = XML_PARSER_START_TAG;
+		    if (ctxt->progressive == 0)
+			ctxt->progressive = 1;
+		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering START_TAG\n");
+#endif
+		}
+		break;
+            case XML_PARSER_EPILOG:
+		SKIP_BLANKS;
+		if (ctxt->input->buf == NULL)
+		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
+		else
+		    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
+		if (avail < 2)
+		    goto done;
+		cur = ctxt->input->cur[0];
+		next = ctxt->input->cur[1];
+	        if ((cur == '<') && (next == '?')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing PI\n");
+#endif
+		    xmlParsePI(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    ctxt->instate = XML_PARSER_EPILOG;
+		} else if ((cur == '<') && (next == '!') &&
+		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+		    if ((!terminate) &&
+		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+			goto done;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: Parsing Comment\n");
+#endif
+		    xmlParseComment(ctxt);
+		    if (ctxt->instate == XML_PARSER_EOF)
+			goto done;
+		    ctxt->instate = XML_PARSER_EPILOG;
+		} else if ((cur == '<') && (next == '!') &&
+		           (avail < 4)) {
+		    goto done;
+		} else {
+		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+		    ctxt->instate = XML_PARSER_EOF;
+#ifdef DEBUG_PUSH
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: entering EOF\n");
+#endif
+		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+			ctxt->sax->endDocument(ctxt->userData);
+		    goto done;
+		}
+		break;
+            case XML_PARSER_DTD: {
+	        /*
+		 * Sorry but progressive parsing of the internal subset
+		 * is not expected to be supported. We first check that
+		 * the full content of the internal subset is available and
+		 * the parsing is launched only at that point.
+		 * Internal subset ends up with "']' S? '>'" in an unescaped
+		 * section and not in a ']]>' sequence which are conditional
+		 * sections (whoever argued to keep that crap in XML deserve
+		 * a place in hell !).
+		 */
+		int base, i;
+		xmlChar *buf;
+	        xmlChar quote = 0;
+
+		base = ctxt->input->cur - ctxt->input->base;
+		if (base < 0) return(0);
+		if (ctxt->checkIndex > base)
+		    base = ctxt->checkIndex;
+		buf = ctxt->input->buf->buffer->content;
+		for (;(unsigned int) base < ctxt->input->buf->buffer->use;
+		     base++) {
+		    if (quote != 0) {
+		        if (buf[base] == quote)
+			    quote = 0;
+			continue;    
+		    }
+		    if ((quote == 0) && (buf[base] == '<')) {
+		        int found  = 0;
+			/* special handling of comments */
+		        if (((unsigned int) base + 4 <
+			     ctxt->input->buf->buffer->use) &&
+			    (buf[base + 1] == '!') &&
+			    (buf[base + 2] == '-') &&
+			    (buf[base + 3] == '-')) {
+			    for (;(unsigned int) base + 3 <
+			          ctxt->input->buf->buffer->use; base++) {
+				if ((buf[base] == '-') &&
+				    (buf[base + 1] == '-') &&
+				    (buf[base + 2] == '>')) {
+				    found = 1;
+				    base += 2;
+				    break;
+				}
+		            }
+			    if (!found) {
+#if 0
+			        fprintf(stderr, "unfinished comment\n");
+#endif
+			        break; /* for */
+		            }
+		            continue;
+			}
+		    }
+		    if (buf[base] == '"') {
+		        quote = '"';
+			continue;
+		    }
+		    if (buf[base] == '\'') {
+		        quote = '\'';
+			continue;
+		    }
+		    if (buf[base] == ']') {
+#if 0
+		        fprintf(stderr, "%c%c%c%c: ", buf[base],
+			        buf[base + 1], buf[base + 2], buf[base + 3]);
+#endif
+		        if ((unsigned int) base +1 >=
+		            ctxt->input->buf->buffer->use)
+			    break;
+			if (buf[base + 1] == ']') {
+			    /* conditional crap, skip both ']' ! */
+			    base++;
+			    continue;
+			}
+		        for (i = 1;
+		     (unsigned int) base + i < ctxt->input->buf->buffer->use;
+		             i++) {
+			    if (buf[base + i] == '>') {
+#if 0
+			        fprintf(stderr, "found\n");
+#endif
+			        goto found_end_int_subset;
+			    }
+			    if (!IS_BLANK_CH(buf[base + i])) {
+#if 0
+			        fprintf(stderr, "not found\n");
+#endif
+			        goto not_end_of_int_subset;
+			    }
+			}
+#if 0
+			fprintf(stderr, "end of stream\n");
+#endif
+		        break;
+                        
+		    }
+not_end_of_int_subset:
+                    continue; /* for */
+		}
+		/*
+		 * We didn't found the end of the Internal subset
+		 */
+#ifdef DEBUG_PUSH
+		if (next == 0)
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PP: lookup of int subset end filed\n");
+#endif
+	        goto done;
+
+found_end_int_subset:
+		xmlParseInternalSubset(ctxt);
+		if (ctxt->instate == XML_PARSER_EOF)
+		    goto done;
+		ctxt->inSubset = 2;
+		if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+		    (ctxt->sax->externalSubset != NULL))
+		    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
+			    ctxt->extSubSystem, ctxt->extSubURI);
+		ctxt->inSubset = 0;
+		xmlCleanSpecialAttr(ctxt);
+		if (ctxt->instate == XML_PARSER_EOF)
+		    goto done;
+		ctxt->instate = XML_PARSER_PROLOG;
+		ctxt->checkIndex = 0;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering PROLOG\n");
+#endif
+                break;
+	    }
+            case XML_PARSER_COMMENT:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == COMMENT\n");
+		ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_IGNORE:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == IGNORE");
+	        ctxt->instate = XML_PARSER_DTD;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering DTD\n");
+#endif
+	        break;
+            case XML_PARSER_PI:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == PI\n");
+		ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering CONTENT\n");
+#endif
+		break;
+            case XML_PARSER_ENTITY_DECL:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == ENTITY_DECL\n");
+		ctxt->instate = XML_PARSER_DTD;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering DTD\n");
+#endif
+		break;
+            case XML_PARSER_ENTITY_VALUE:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == ENTITY_VALUE\n");
+		ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering DTD\n");
+#endif
+		break;
+            case XML_PARSER_ATTRIBUTE_VALUE:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == ATTRIBUTE_VALUE\n");
+		ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering START_TAG\n");
+#endif
+		break;
+            case XML_PARSER_SYSTEM_LITERAL:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == SYSTEM_LITERAL\n");
+		ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering START_TAG\n");
+#endif
+		break;
+            case XML_PARSER_PUBLIC_LITERAL:
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: internal error, state == PUBLIC_LITERAL\n");
+		ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+		xmlGenericError(xmlGenericErrorContext,
+			"PP: entering START_TAG\n");
+#endif
+		break;
+	}
+    }
+done:    
+#ifdef DEBUG_PUSH
+    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
+#endif
+    return(ret);
+encoding_error:
+    {
+        char buffer[150];
+
+	snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+		     "Input is not proper UTF-8, indicate encoding !\n%s",
+		     BAD_CAST buffer, NULL);
+    }
+    return(0);
+}
+
+/**
+ * xmlParseChunk:
+ * @ctxt:  an XML parser context
+ * @chunk:  an char array
+ * @size:  the size in byte of the chunk
+ * @terminate:  last chunk indicator
+ *
+ * Parse a Chunk of memory
+ *
+ * Returns zero if no error, the xmlParserErrors otherwise.
+ */
+int
+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);
+    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+        return(ctxt->errNo);
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(-1);
+    if (ctxt->instate == XML_PARSER_START)
+        xmlDetectSAX2(ctxt);
+    if ((size > 0) && (chunk != NULL) && (!terminate) &&
+        (chunk[size - 1] == '\r')) {
+	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 (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;
+	    ctxt->disableSAX = 1;
+	    return (XML_PARSER_EOF);
+	}
+	ctxt->input->base = ctxt->input->buf->buffer->content + base;
+	ctxt->input->cur = ctxt->input->base + cur;
+	ctxt->input->end =
+	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
+#ifdef DEBUG_PUSH
+	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
+#endif
+
+    } 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) {
+		    /* TODO 2.6.0 */
+		    xmlGenericError(xmlGenericErrorContext,
+				    "xmlParseChunk: encoder error\n");
+		    return(XML_ERR_INVALID_ENCODING);
+		}
+	    }
+	}
+    }
+    if (remain != 0)
+        xmlParseTryOrFinish(ctxt, 0);
+    else
+        xmlParseTryOrFinish(ctxt, terminate);
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(ctxt->errNo);
+    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 (terminate) {
+	/*
+	 * Check for termination
+	 */
+	int avail = 0;
+
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->buf == NULL)
+		avail = ctxt->input->length -
+			(ctxt->input->cur - ctxt->input->base);
+	    else
+		avail = ctxt->input->buf->buffer->use -
+			(ctxt->input->cur - ctxt->input->base);
+	}
+			    
+	if ((ctxt->instate != XML_PARSER_EOF) &&
+	    (ctxt->instate != XML_PARSER_EPILOG)) {
+	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+	} 
+	if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
+	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+	}
+	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);	      
+}
+
+/************************************************************************
+ *									*
+ * 		I/O front end functions to the parser			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCreatePushParserCtxt:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @chunk:  a pointer to an array of chars
+ * @size:  number of chars in the array
+ * @filename:  an optional file name or URI
+ *
+ * Create a parser context for using the XML parser in push mode.
+ * If @buffer and @size are non-NULL, the data is used to detect
+ * the encoding.  The remaining characters will be parsed so they
+ * don't need to be fed in again through xmlParseChunk.
+ * To allow content encoding detection, @size should be >= 4
+ * The value of @filename is used for fetching external entities
+ * and error/warning reports.
+ *
+ * Returns the new parser context or NULL
+ */
+
+xmlParserCtxtPtr
+xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
+                        const char *chunk, int size, const char *filename) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr inputStream;
+    xmlParserInputBufferPtr buf;
+    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
+
+    /*
+     * plug some encoding conversion routines
+     */
+    if ((chunk != NULL) && (size >= 4))
+	enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
+
+    buf = xmlAllocParserInputBuffer(enc);
+    if (buf == NULL) return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlErrMemory(NULL, "creating parser: out of memory\n");
+	xmlFreeParserInputBuffer(buf);
+	return(NULL);
+    }
+    ctxt->dictNames = 1;
+    ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
+    if (ctxt->pushTab == NULL) {
+        xmlErrMemory(ctxt, NULL);
+	xmlFreeParserInputBuffer(buf);
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    if (sax != NULL) {
+#ifdef LIBXML_SAX1_ENABLED
+	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
+#endif /* LIBXML_SAX1_ENABLED */
+	    xmlFree(ctxt->sax);
+	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
+	if (ctxt->sax == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    xmlFreeParserInputBuffer(buf);
+	    xmlFreeParserCtxt(ctxt);
+	    return(NULL);
+	}
+	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
+	if (sax->initialized == XML_SAX2_MAGIC)
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+	else
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+	if (user_data != NULL)
+	    ctxt->userData = user_data;
+    }	
+    if (filename == NULL) {
+	ctxt->directory = NULL;
+    } else {
+        ctxt->directory = xmlParserGetDirectory(filename);
+    }
+
+    inputStream = xmlNewInputStream(ctxt);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	xmlFreeParserInputBuffer(buf);
+	return(NULL);
+    }
+
+    if (filename == NULL)
+	inputStream->filename = NULL;
+    else {
+	inputStream->filename = (char *)
+	    xmlCanonicPath((const xmlChar *) filename);
+	if (inputStream->filename == NULL) {
+	    xmlFreeParserCtxt(ctxt);
+	    xmlFreeParserInputBuffer(buf);
+	    return(NULL);
+	}
+    }
+    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];
+
+    inputPush(ctxt, inputStream);
+
+    /*
+     * If the caller didn't provide an initial 'chunk' for determining
+     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
+     * that it can be automatically determined later
+     */
+    if ((size == 0) || (chunk == NULL)) {
+	ctxt->charset = XML_CHAR_ENCODING_NONE;
+    } else if ((ctxt->input != 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);	      
+
+	ctxt->input->base = ctxt->input->buf->buffer->content + base;
+	ctxt->input->cur = ctxt->input->base + cur;
+	ctxt->input->end =
+	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
+#ifdef DEBUG_PUSH
+	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
+#endif
+    }
+
+    if (enc != XML_CHAR_ENCODING_NONE) {
+        xmlSwitchEncoding(ctxt, enc);
+    }
+
+    return(ctxt);
+}
+#endif /* LIBXML_PUSH_ENABLED */
+
+/**
+ * xmlStopParser:
+ * @ctxt:  an XML parser context
+ *
+ * Blocks further parser processing
+ */
+void           
+xmlStopParser(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    ctxt->instate = XML_PARSER_EOF;
+    ctxt->errNo = XML_ERR_USER_STOP;
+    ctxt->disableSAX = 1;
+    if (ctxt->input != NULL) {
+	ctxt->input->cur = BAD_CAST"";
+	ctxt->input->base = ctxt->input->cur;
+    }
+}
+
+/**
+ * xmlCreateIOParserCtxt:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @enc:  the charset encoding if known
+ *
+ * Create a parser context for using the XML parser with an existing
+ * I/O stream
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
+	xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
+	void *ioctx, xmlCharEncoding enc) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr inputStream;
+    xmlParserInputBufferPtr buf;
+    
+    if (ioread == NULL) return(NULL);
+
+    buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
+    if (buf == NULL) return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+	xmlFreeParserInputBuffer(buf);
+	return(NULL);
+    }
+    if (sax != NULL) {
+#ifdef LIBXML_SAX1_ENABLED
+	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
+#endif /* LIBXML_SAX1_ENABLED */
+	    xmlFree(ctxt->sax);
+	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
+	if (ctxt->sax == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+	    xmlFreeParserCtxt(ctxt);
+	    return(NULL);
+	}
+	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
+	if (sax->initialized == XML_SAX2_MAGIC)
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+	else
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+	if (user_data != NULL)
+	    ctxt->userData = user_data;
+    }	
+
+    inputStream = xmlNewIOInputStream(ctxt, buf, enc);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    inputPush(ctxt, inputStream);
+
+    return(ctxt);
+}
+
+#ifdef LIBXML_VALID_ENABLED
+/************************************************************************
+ *									*
+ * 		Front ends when parsing a DTD				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlIOParseDTD:
+ * @sax:  the SAX handler block or NULL
+ * @input:  an Input Buffer
+ * @enc:  the charset encoding if known
+ *
+ * Load and parse a DTD
+ * 
+ * Returns the resulting xmlDtdPtr or NULL in case of error.
+ * @input will be freed by the function in any case.
+ */
+
+xmlDtdPtr
+xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
+	      xmlCharEncoding enc) {
+    xmlDtdPtr ret = NULL;
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr pinput = NULL;
+    xmlChar start[4];
+
+    if (input == NULL)
+	return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(input);
+	return(NULL);
+    }
+
+    /*
+     * Set-up the SAX context
+     */
+    if (sax != NULL) { 
+	if (ctxt->sax != NULL)
+	    xmlFree(ctxt->sax);
+        ctxt->sax = sax;
+        ctxt->userData = ctxt;
+    }
+    xmlDetectSAX2(ctxt);
+
+    /*
+     * generate a parser input from the I/O handler
+     */
+
+    pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (pinput == NULL) {
+        if (sax != NULL) ctxt->sax = NULL;
+        xmlFreeParserInputBuffer(input);
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    /*
+     * plug some encoding conversion routines here.
+     */
+    if (xmlPushInput(ctxt, pinput) < 0) {
+        if (sax != NULL) ctxt->sax = NULL;
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    if (enc != XML_CHAR_ENCODING_NONE) {
+        xmlSwitchEncoding(ctxt, enc);
+    }
+
+    pinput->filename = NULL;
+    pinput->line = 1;
+    pinput->col = 1;
+    pinput->base = ctxt->input->cur;
+    pinput->cur = ctxt->input->cur;
+    pinput->free = NULL;
+
+    /*
+     * let's parse that entity knowing it's an external subset.
+     */
+    ctxt->inSubset = 2;
+    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
+    if (ctxt->myDoc == NULL) {
+	xmlErrMemory(ctxt, "New Doc failed");
+	return(NULL);
+    }
+    ctxt->myDoc->properties = XML_DOC_INTERNAL;
+    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
+	                               BAD_CAST "none", BAD_CAST "none");
+
+    if ((enc == XML_CHAR_ENCODING_NONE) &&
+        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
+	/* 
+	 * Get the 4 first bytes and decode the charset
+	 * if enc != XML_CHAR_ENCODING_NONE
+	 * plug some encoding conversion routines.
+	 */
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(start, 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+    xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
+
+    if (ctxt->myDoc != NULL) {
+	if (ctxt->wellFormed) {
+	    ret = ctxt->myDoc->extSubset;
+	    ctxt->myDoc->extSubset = NULL;
+	    if (ret != NULL) {
+		xmlNodePtr tmp;
+
+		ret->doc = NULL;
+		tmp = ret->children;
+		while (tmp != NULL) {
+		    tmp->doc = NULL;
+		    tmp = tmp->next;
+		}
+	    }
+	} else {
+	    ret = NULL;
+	}
+        xmlFreeDoc(ctxt->myDoc);
+        ctxt->myDoc = NULL;
+    }
+    if (sax != NULL) ctxt->sax = NULL;
+    xmlFreeParserCtxt(ctxt);
+    
+    return(ret);
+}
+
+/**
+ * xmlSAXParseDTD:
+ * @sax:  the SAX handler block
+ * @ExternalID:  a NAME* containing the External ID of the DTD
+ * @SystemID:  a NAME* containing the URL to the DTD
+ *
+ * Load and parse an external subset.
+ * 
+ * Returns the resulting xmlDtdPtr or NULL in case of error.
+ */
+
+xmlDtdPtr
+xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
+                          const xmlChar *SystemID) {
+    xmlDtdPtr ret = NULL;
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input = NULL;
+    xmlCharEncoding enc;
+    xmlChar* systemIdCanonic;
+
+    if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+	return(NULL);
+    }
+
+    /*
+     * Set-up the SAX context
+     */
+    if (sax != NULL) { 
+	if (ctxt->sax != NULL)
+	    xmlFree(ctxt->sax);
+        ctxt->sax = sax;
+        ctxt->userData = ctxt;
+    }
+    
+    /*
+     * Canonicalise the system ID
+     */
+    systemIdCanonic = xmlCanonicPath(SystemID);
+    if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    /*
+     * Ask the Entity resolver to load the damn thing
+     */
+
+    if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
+	input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
+	                                 systemIdCanonic);
+    if (input == NULL) {
+        if (sax != NULL) ctxt->sax = NULL;
+	xmlFreeParserCtxt(ctxt);
+	if (systemIdCanonic != NULL)
+	    xmlFree(systemIdCanonic);
+	return(NULL);
+    }
+
+    /*
+     * plug some encoding conversion routines here.
+     */
+    if (xmlPushInput(ctxt, input) < 0) {
+        if (sax != NULL) ctxt->sax = NULL;
+	xmlFreeParserCtxt(ctxt);
+	if (systemIdCanonic != NULL)
+	    xmlFree(systemIdCanonic);
+	return(NULL);
+    }
+    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
+	enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
+	xmlSwitchEncoding(ctxt, enc);
+    }
+
+    if (input->filename == NULL)
+	input->filename = (char *) systemIdCanonic;
+    else
+	xmlFree(systemIdCanonic);
+    input->line = 1;
+    input->col = 1;
+    input->base = ctxt->input->cur;
+    input->cur = ctxt->input->cur;
+    input->free = NULL;
+
+    /*
+     * let's parse that entity knowing it's an external subset.
+     */
+    ctxt->inSubset = 2;
+    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
+    if (ctxt->myDoc == NULL) {
+	xmlErrMemory(ctxt, "New Doc failed");
+        if (sax != NULL) ctxt->sax = NULL;
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    ctxt->myDoc->properties = XML_DOC_INTERNAL;
+    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
+	                               ExternalID, SystemID);
+    xmlParseExternalSubset(ctxt, ExternalID, SystemID);
+
+    if (ctxt->myDoc != NULL) {
+	if (ctxt->wellFormed) {
+	    ret = ctxt->myDoc->extSubset;
+	    ctxt->myDoc->extSubset = NULL;
+	    if (ret != NULL) {
+		xmlNodePtr tmp;
+
+		ret->doc = NULL;
+		tmp = ret->children;
+		while (tmp != NULL) {
+		    tmp->doc = NULL;
+		    tmp = tmp->next;
+		}
+	    }
+	} else {
+	    ret = NULL;
+	}
+        xmlFreeDoc(ctxt->myDoc);
+        ctxt->myDoc = NULL;
+    }
+    if (sax != NULL) ctxt->sax = NULL;
+    xmlFreeParserCtxt(ctxt);
+
+    return(ret);
+}
+
+
+/**
+ * xmlParseDTD:
+ * @ExternalID:  a NAME* containing the External ID of the DTD
+ * @SystemID:  a NAME* containing the URL to the DTD
+ *
+ * Load and parse an external subset.
+ *
+ * Returns the resulting xmlDtdPtr or NULL in case of error.
+ */
+
+xmlDtdPtr
+xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
+    return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
+}
+#endif /* LIBXML_VALID_ENABLED */
+
+/************************************************************************
+ *									*
+ * 		Front ends when parsing an Entity			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlParseCtxtExternalEntity:
+ * @ctx:  the existing parsing context
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @lst:  the return value for the set of parsed nodes
+ *
+ * Parse an external general entity within an existing parsing context
+ * An external general parsed entity is well-formed if it matches the
+ * production labeled extParsedEnt.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * Returns 0 if the entity is well formed, -1 in case of args problem and
+ *    the parser error code otherwise
+ */
+
+int
+xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
+	               const xmlChar *ID, xmlNodePtr *lst) {
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr newDoc;
+    xmlNodePtr newRoot;
+    xmlSAXHandlerPtr oldsax = NULL;
+    int ret = 0;
+    xmlChar start[4];
+    xmlCharEncoding enc;
+
+    if (ctx == NULL) return(-1);
+
+    if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
+        (ctx->depth > 1024)) {
+	return(XML_ERR_ENTITY_LOOP);
+    }
+
+    if (lst != NULL)
+        *lst = NULL;
+    if ((URL == NULL) && (ID == NULL))
+	return(-1);
+    if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
+	return(-1);
+
+    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
+    if (ctxt == NULL) {
+	return(-1);
+    }
+
+    oldsax = ctxt->sax;
+    ctxt->sax = ctx->sax;
+    xmlDetectSAX2(ctxt);
+    newDoc = xmlNewDoc(BAD_CAST "1.0");
+    if (newDoc == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(-1);
+    }
+    newDoc->properties = XML_DOC_INTERNAL;
+    if (ctx->myDoc->dict) {
+	newDoc->dict = ctx->myDoc->dict;
+	xmlDictReference(newDoc->dict);
+    }
+    if (ctx->myDoc != NULL) {
+	newDoc->intSubset = ctx->myDoc->intSubset;
+	newDoc->extSubset = ctx->myDoc->extSubset;
+    }
+    if (ctx->myDoc->URL != NULL) {
+	newDoc->URL = xmlStrdup(ctx->myDoc->URL);
+    }
+    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+    if (newRoot == NULL) {
+	ctxt->sax = oldsax;
+	xmlFreeParserCtxt(ctxt);
+	newDoc->intSubset = NULL;
+	newDoc->extSubset = NULL;
+        xmlFreeDoc(newDoc);
+	return(-1);
+    }
+    xmlAddChild((xmlNodePtr) newDoc, newRoot);
+    nodePush(ctxt, newDoc->children);
+    if (ctx->myDoc == NULL) {
+	ctxt->myDoc = newDoc;
+    } else {
+	ctxt->myDoc = ctx->myDoc;
+	newDoc->children->doc = ctx->myDoc;
+    }
+
+    /*
+     * Get the 4 first bytes and decode the charset
+     * if enc != XML_CHAR_ENCODING_NONE
+     * plug some encoding conversion routines.
+     */
+    GROW
+    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(start, 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+    /*
+     * Parse a possible text declaration first
+     */
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+	xmlParseTextDecl(ctxt);
+	/*
+	 * An XML-1.0 document can't reference an entity not XML-1.0
+	 */
+	if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
+	    (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
+	    xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, 
+	                   "Version mismatch between document and entity\n");
+	}
+    }
+
+    /*
+     * Doing validity checking on chunk doesn't make sense
+     */
+    ctxt->instate = XML_PARSER_CONTENT;
+    ctxt->validate = ctx->validate;
+    ctxt->valid = ctx->valid;
+    ctxt->loadsubset = ctx->loadsubset;
+    ctxt->depth = ctx->depth + 1;
+    ctxt->replaceEntities = ctx->replaceEntities;
+    if (ctxt->validate) {
+	ctxt->vctxt.error = ctx->vctxt.error;
+	ctxt->vctxt.warning = ctx->vctxt.warning;
+    } else {
+	ctxt->vctxt.error = NULL;
+	ctxt->vctxt.warning = NULL;
+    }
+    ctxt->vctxt.nodeTab = NULL;
+    ctxt->vctxt.nodeNr = 0;
+    ctxt->vctxt.nodeMax = 0;
+    ctxt->vctxt.node = NULL;
+    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
+    ctxt->dict = ctx->dict;
+    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+    ctxt->dictNames = ctx->dictNames;
+    ctxt->attsDefault = ctx->attsDefault;
+    ctxt->attsSpecial = ctx->attsSpecial;
+    ctxt->linenumbers = ctx->linenumbers;
+
+    xmlParseContent(ctxt);
+
+    ctx->validate = ctxt->validate;
+    ctx->valid = ctxt->valid;
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+    if (ctxt->node != newDoc->children) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    }
+
+    if (!ctxt->wellFormed) {
+        if (ctxt->errNo == 0)
+	    ret = 1;
+	else
+	    ret = ctxt->errNo;
+    } else {
+	if (lst != NULL) {
+	    xmlNodePtr cur;
+
+	    /*
+	     * Return the newly created nodeset after unlinking it from
+	     * they pseudo parent.
+	     */
+	    cur = newDoc->children->children;
+	    *lst = cur;
+	    while (cur != NULL) {
+		cur->parent = NULL;
+		cur = cur->next;
+	    }
+            newDoc->children->children = NULL;
+	}
+	ret = 0;
+    }
+    ctxt->sax = oldsax;
+    ctxt->dict = NULL;
+    ctxt->attsDefault = NULL;
+    ctxt->attsSpecial = NULL;
+    xmlFreeParserCtxt(ctxt);
+    newDoc->intSubset = NULL;
+    newDoc->extSubset = NULL;
+    xmlFreeDoc(newDoc);
+
+    return(ret);
+}
+
+/**
+ * xmlParseExternalEntityPrivate:
+ * @doc:  the document the chunk pertains to
+ * @oldctxt:  the previous parser context if available
+ * @sax:  the SAX handler bloc (possibly NULL)
+ * @user_data:  The user data returned on SAX callbacks (possibly NULL)
+ * @depth:  Used for loop detection, use 0
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @list:  the return value for the set of parsed nodes
+ *
+ * Private version of xmlParseExternalEntity()
+ *
+ * Returns 0 if the entity is well formed, -1 in case of args problem and
+ *    the parser error code otherwise
+ */
+
+static xmlParserErrors
+xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
+	              xmlSAXHandlerPtr sax,
+		      void *user_data, int depth, const xmlChar *URL,
+		      const xmlChar *ID, xmlNodePtr *list) {
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr newDoc;
+    xmlNodePtr newRoot;
+    xmlSAXHandlerPtr oldsax = NULL;
+    xmlParserErrors ret = XML_ERR_OK;
+    xmlChar start[4];
+    xmlCharEncoding enc;
+
+    if (((depth > 40) &&
+	((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
+	(depth > 1024)) {
+	return(XML_ERR_ENTITY_LOOP);
+    }
+
+    if (list != NULL)
+        *list = NULL;
+    if ((URL == NULL) && (ID == NULL))
+	return(XML_ERR_INTERNAL_ERROR);
+    if (doc == NULL)
+	return(XML_ERR_INTERNAL_ERROR);
+
+
+    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
+    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
+    ctxt->userData = ctxt;
+    if (oldctxt != NULL) {
+	ctxt->_private = oldctxt->_private;
+	ctxt->loadsubset = oldctxt->loadsubset;
+	ctxt->validate = oldctxt->validate;
+	ctxt->external = oldctxt->external;
+	ctxt->record_info = oldctxt->record_info;
+	ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
+	ctxt->node_seq.length = oldctxt->node_seq.length;
+	ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
+    } else {
+	/*
+	 * Doing validity checking on chunk without context
+	 * doesn't make sense
+	 */
+	ctxt->_private = NULL;
+	ctxt->validate = 0;
+	ctxt->external = 2;
+	ctxt->loadsubset = 0;
+    }
+    if (sax != NULL) {
+	oldsax = ctxt->sax;
+        ctxt->sax = sax;
+	if (user_data != NULL)
+	    ctxt->userData = user_data;
+    }
+    xmlDetectSAX2(ctxt);
+    newDoc = xmlNewDoc(BAD_CAST "1.0");
+    if (newDoc == NULL) {
+	ctxt->node_seq.maximum = 0;
+	ctxt->node_seq.length = 0;
+	ctxt->node_seq.buffer = NULL;
+	xmlFreeParserCtxt(ctxt);
+	return(XML_ERR_INTERNAL_ERROR);
+    }
+    newDoc->properties = XML_DOC_INTERNAL;
+    newDoc->intSubset = doc->intSubset;
+    newDoc->extSubset = doc->extSubset;
+    newDoc->dict = doc->dict;
+    xmlDictReference(newDoc->dict);
+
+    if (doc->URL != NULL) {
+	newDoc->URL = xmlStrdup(doc->URL);
+    }
+    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+    if (newRoot == NULL) {
+	if (sax != NULL)
+	    ctxt->sax = oldsax;
+	ctxt->node_seq.maximum = 0;
+	ctxt->node_seq.length = 0;
+	ctxt->node_seq.buffer = NULL;
+	xmlFreeParserCtxt(ctxt);
+	newDoc->intSubset = NULL;
+	newDoc->extSubset = NULL;
+        xmlFreeDoc(newDoc);
+	return(XML_ERR_INTERNAL_ERROR);
+    }
+    xmlAddChild((xmlNodePtr) newDoc, newRoot);
+    nodePush(ctxt, newDoc->children);
+    ctxt->myDoc = doc;
+    newRoot->doc = doc;
+
+    /*
+     * Get the 4 first bytes and decode the charset
+     * if enc != XML_CHAR_ENCODING_NONE
+     * plug some encoding conversion routines.
+     */
+    GROW;
+    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
+	start[0] = RAW;
+	start[1] = NXT(1);
+	start[2] = NXT(2);
+	start[3] = NXT(3);
+	enc = xmlDetectCharEncoding(start, 4);
+	if (enc != XML_CHAR_ENCODING_NONE) {
+	    xmlSwitchEncoding(ctxt, enc);
+	}
+    }
+
+    /*
+     * Parse a possible text declaration first
+     */
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+	xmlParseTextDecl(ctxt);
+    }
+
+    ctxt->instate = XML_PARSER_CONTENT;
+    ctxt->depth = depth;
+
+    xmlParseContent(ctxt);
+
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+    if (ctxt->node != newDoc->children) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    }
+
+    if (!ctxt->wellFormed) {
+        if (ctxt->errNo == 0)
+	    ret = XML_ERR_INTERNAL_ERROR;
+	else
+	    ret = (xmlParserErrors)ctxt->errNo;
+    } else {
+	if (list != NULL) {
+	    xmlNodePtr cur;
+
+	    /*
+	     * Return the newly created nodeset after unlinking it from
+	     * they pseudo parent.
+	     */
+	    cur = newDoc->children->children;
+	    *list = cur;
+	    while (cur != NULL) {
+		cur->parent = NULL;
+		cur = cur->next;
+	    }
+            newDoc->children->children = NULL;
+	}
+	ret = XML_ERR_OK;
+    }
+
+    /*
+     * Record in the parent context the number of entities replacement
+     * done when parsing that reference.
+     */
+    if (oldctxt != NULL)
+        oldctxt->nbentities += ctxt->nbentities;
+
+    /*
+     * Also record the size of the entity parsed
+     */
+    if (ctxt->input != NULL) {
+	oldctxt->sizeentities += ctxt->input->consumed;
+	oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
+    }
+    /*
+     * And record the last error if any
+     */
+    if (ctxt->lastError.code != XML_ERR_OK)
+        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
+
+    if (sax != NULL) 
+	ctxt->sax = oldsax;
+    oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
+    oldctxt->node_seq.length = ctxt->node_seq.length;
+    oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    ctxt->node_seq.maximum = 0;
+    ctxt->node_seq.length = 0;
+    ctxt->node_seq.buffer = NULL;
+    xmlFreeParserCtxt(ctxt);
+    newDoc->intSubset = NULL;
+    newDoc->extSubset = NULL;
+    xmlFreeDoc(newDoc);
+
+    return(ret);
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlParseExternalEntity:
+ * @doc:  the document the chunk pertains to
+ * @sax:  the SAX handler bloc (possibly NULL)
+ * @user_data:  The user data returned on SAX callbacks (possibly NULL)
+ * @depth:  Used for loop detection, use 0
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @lst:  the return value for the set of parsed nodes
+ *
+ * Parse an external general entity
+ * An external general parsed entity is well-formed if it matches the
+ * production labeled extParsedEnt.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * Returns 0 if the entity is well formed, -1 in case of args problem and
+ *    the parser error code otherwise
+ */
+
+int
+xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
+	  int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
+    return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
+		                       ID, lst));
+}
+
+/**
+ * xmlParseBalancedChunkMemory:
+ * @doc:  the document the chunk pertains to
+ * @sax:  the SAX handler bloc (possibly NULL)
+ * @user_data:  The user data returned on SAX callbacks (possibly NULL)
+ * @depth:  Used for loop detection, use 0
+ * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
+ * @lst:  the return value for the set of parsed nodes
+ *
+ * Parse a well-balanced chunk of an XML document
+ * called by the parser
+ * The allowed sequence for the Well Balanced Chunk is the one defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns 0 if the chunk is well balanced, -1 in case of args problem and
+ *    the parser error code otherwise
+ */
+
+int
+xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
+     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
+    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
+                                                depth, string, lst, 0 );
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/**
+ * xmlParseBalancedChunkMemoryInternal:
+ * @oldctxt:  the existing parsing context
+ * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
+ * @user_data:  the user data field for the parser context
+ * @lst:  the return value for the set of parsed nodes
+ *
+ *
+ * Parse a well-balanced chunk of an XML document
+ * called by the parser
+ * The allowed sequence for the Well Balanced Chunk is the one defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns XML_ERR_OK if the chunk is well balanced, and the parser
+ * error code otherwise
+ *
+ * In case recover is set to 1, the nodelist will not be empty even if
+ * the parsed chunk is not well balanced.
+ */
+static xmlParserErrors
+xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
+	const xmlChar *string, void *user_data, xmlNodePtr *lst) {
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr newDoc = NULL;
+    xmlNodePtr newRoot;
+    xmlSAXHandlerPtr oldsax = NULL;
+    xmlNodePtr content = NULL;
+    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)) {
+	return(XML_ERR_ENTITY_LOOP);
+    }
+
+
+    if (lst != NULL)
+        *lst = NULL;
+    if (string == NULL)
+        return(XML_ERR_INTERNAL_ERROR);
+
+    size = xmlStrlen(string);
+
+    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
+    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
+    if (user_data != NULL)
+	ctxt->userData = user_data;
+    else
+	ctxt->userData = ctxt;
+    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
+    ctxt->dict = oldctxt->dict;
+    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+
+#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;
+    xmlDetectSAX2(ctxt);
+    ctxt->replaceEntities = oldctxt->replaceEntities;
+    ctxt->options = oldctxt->options;
+
+    ctxt->_private = oldctxt->_private;
+    if (oldctxt->myDoc == NULL) {
+	newDoc = xmlNewDoc(BAD_CAST "1.0");
+	if (newDoc == NULL) {
+	    ctxt->sax = oldsax;
+	    ctxt->dict = NULL;
+	    xmlFreeParserCtxt(ctxt);
+	    return(XML_ERR_INTERNAL_ERROR);
+	}
+	newDoc->properties = XML_DOC_INTERNAL;
+	newDoc->dict = ctxt->dict;
+	xmlDictReference(newDoc->dict);
+	ctxt->myDoc = newDoc;
+    } else {
+	ctxt->myDoc = oldctxt->myDoc;
+        content = ctxt->myDoc->children;
+	last = ctxt->myDoc->last;
+    }
+    newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
+    if (newRoot == NULL) {
+	ctxt->sax = oldsax;
+	ctxt->dict = NULL;
+	xmlFreeParserCtxt(ctxt);
+	if (newDoc != NULL) {
+	    xmlFreeDoc(newDoc);
+	}
+	return(XML_ERR_INTERNAL_ERROR);
+    }
+    ctxt->myDoc->children = NULL;
+    ctxt->myDoc->last = NULL;
+    xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
+    nodePush(ctxt, ctxt->myDoc->children);
+    ctxt->instate = XML_PARSER_CONTENT;
+    ctxt->depth = oldctxt->depth + 1;
+
+    ctxt->validate = 0;
+    ctxt->loadsubset = oldctxt->loadsubset;
+    if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
+	/*
+	 * ID/IDREF registration will be done in xmlValidateElement below
+	 */
+	ctxt->loadsubset |= XML_SKIP_IDS;
+    }
+    ctxt->dictNames = oldctxt->dictNames;
+    ctxt->attsDefault = oldctxt->attsDefault;
+    ctxt->attsSpecial = oldctxt->attsSpecial;
+
+    xmlParseContent(ctxt);
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+    if (ctxt->node != ctxt->myDoc->children) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    }
+
+    if (!ctxt->wellFormed) {
+        if (ctxt->errNo == 0)
+	    ret = XML_ERR_INTERNAL_ERROR;
+	else
+	    ret = (xmlParserErrors)ctxt->errNo;
+    } else {
+      ret = XML_ERR_OK;
+    }
+
+    if ((lst != NULL) && (ret == XML_ERR_OK)) {
+	xmlNodePtr cur;
+
+	/*
+	 * Return the newly created nodeset after unlinking it from
+	 * they pseudo parent.
+	 */
+	cur = ctxt->myDoc->children->children;
+	*lst = cur;
+	while (cur != NULL) {
+#ifdef LIBXML_VALID_ENABLED
+	    if ((oldctxt->validate) && (oldctxt->wellFormed) &&
+		(oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
+		(cur->type == XML_ELEMENT_NODE)) {
+		oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
+			oldctxt->myDoc, cur);
+	    }
+#endif /* LIBXML_VALID_ENABLED */
+	    cur->parent = NULL;
+	    cur = cur->next;
+	}
+	ctxt->myDoc->children->children = NULL;
+    }
+    if (ctxt->myDoc != NULL) {
+	xmlFreeNode(ctxt->myDoc->children);
+        ctxt->myDoc->children = content;
+        ctxt->myDoc->last = last;
+    }
+
+    /*
+     * Record in the parent context the number of entities replacement
+     * done when parsing that reference.
+     */
+    if (oldctxt != NULL)
+        oldctxt->nbentities += ctxt->nbentities;
+
+    /*
+     * Also record the last error if any
+     */
+    if (ctxt->lastError.code != XML_ERR_OK)
+        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
+
+    ctxt->sax = oldsax;
+    ctxt->dict = NULL;
+    ctxt->attsDefault = NULL;
+    ctxt->attsSpecial = NULL;
+    xmlFreeParserCtxt(ctxt);
+    if (newDoc != NULL) {
+	xmlFreeDoc(newDoc);
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlParseInNodeContext:
+ * @node:  the context node
+ * @data:  the input string
+ * @datalen:  the input string length in bytes
+ * @options:  a combination of xmlParserOption
+ * @lst:  the return value for the set of parsed nodes
+ *
+ * Parse a well-balanced chunk of an XML document
+ * within the context (DTD, namespaces, etc ...) of the given node.
+ *
+ * The allowed sequence for the data is a Well Balanced Chunk defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns XML_ERR_OK if the chunk is well balanced, and the parser
+ * error code otherwise
+ */
+xmlParserErrors
+xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
+                      int options, xmlNodePtr *lst) {
+#ifdef SAX2
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr doc = NULL;
+    xmlNodePtr fake, cur;
+    int nsnr = 0;
+
+    xmlParserErrors ret = XML_ERR_OK;
+
+    /*
+     * check all input parameters, grab the document
+     */
+    if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
+        return(XML_ERR_INTERNAL_ERROR);
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+	    break;
+	default:
+	    return(XML_ERR_INTERNAL_ERROR);
+
+    }
+    while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
+           (node->type != XML_DOCUMENT_NODE) &&
+	   (node->type != XML_HTML_DOCUMENT_NODE))
+	node = node->parent;
+    if (node == NULL)
+	return(XML_ERR_INTERNAL_ERROR);
+    if (node->type == XML_ELEMENT_NODE)
+	doc = node->doc;
+    else
+        doc = (xmlDocPtr) node;
+    if (doc == NULL)
+	return(XML_ERR_INTERNAL_ERROR);
+
+    /*
+     * allocate a context and set-up everything not related to the
+     * node position in the tree
+     */
+    if (doc->type == XML_DOCUMENT_NODE)
+	ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
+#ifdef LIBXML_HTML_ENABLED
+    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);
+
+    /*
+     * 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.
+     */
+    if (doc->dict != NULL) {
+        if (ctxt->dict != NULL)
+	    xmlDictFree(ctxt->dict);
+	ctxt->dict = doc->dict;
+    } 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);
+	/*
+	 * initialize the SAX2 namespaces stack
+	 */
+	cur = node;
+	while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
+	    xmlNsPtr ns = cur->nsDef;
+	    const xmlChar *iprefix, *ihref;
+
+	    while (ns != NULL) {
+		if (ctxt->dict) {
+		    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
+		    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
+		} else {
+		    iprefix = ns->prefix;
+		    ihref = ns->href;
+		}
+
+	        if (xmlGetNamespace(ctxt, iprefix) == NULL) {
+		    nsPush(ctxt, iprefix, ihref);
+		    nsnr++;
+		}
+		ns = ns->next;
+	    }
+	    cur = cur->parent;
+	}
+	ctxt->instate = XML_PARSER_CONTENT;
+    }
+
+    if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
+	/*
+	 * ID/IDREF registration will be done in xmlValidateElement below
+	 */
+	ctxt->loadsubset |= XML_SKIP_IDS;
+    }
+
+#ifdef LIBXML_HTML_ENABLED
+    if (doc->type == XML_HTML_DOCUMENT_NODE)
+        __htmlParseContent(ctxt);
+    else
+#endif
+	xmlParseContent(ctxt);
+
+    nsPop(ctxt, nsnr);
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+    if ((ctxt->node != NULL) && (ctxt->node != node)) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+	ctxt->wellFormed = 0;
+    }
+
+    if (!ctxt->wellFormed) {
+        if (ctxt->errNo == 0)
+	    ret = XML_ERR_INTERNAL_ERROR;
+	else
+	    ret = (xmlParserErrors)ctxt->errNo;
+    } else {
+        ret = XML_ERR_OK;
+    }
+
+    /*
+     * Return the newly created nodeset after unlinking it from
+     * the pseudo sibling.
+     */
+
+    cur = fake->next;
+    fake->next = NULL;
+    node->last = fake;
+
+    if (cur != NULL) {
+	cur->prev = NULL;
+    }
+
+    *lst = cur;
+
+    while (cur != NULL) {
+	cur->parent = NULL;
+	cur = cur->next;
+    }
+
+    xmlUnlinkNode(fake);
+    xmlFreeNode(fake);
+
+
+    if (ret != XML_ERR_OK) {
+        xmlFreeNodeList(*lst);
+	*lst = NULL;
+    }
+
+    if (doc->dict != NULL)
+        ctxt->dict = NULL;
+    xmlFreeParserCtxt(ctxt);
+
+    return(ret);
+#else /* !SAX2 */
+    return(XML_ERR_INTERNAL_ERROR);
+#endif
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlParseBalancedChunkMemoryRecover:
+ * @doc:  the document the chunk pertains to
+ * @sax:  the SAX handler bloc (possibly NULL)
+ * @user_data:  The user data returned on SAX callbacks (possibly NULL)
+ * @depth:  Used for loop detection, use 0
+ * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
+ * @lst:  the return value for the set of parsed nodes
+ * @recover: return nodes even if the data is broken (use 0)
+ *
+ *
+ * Parse a well-balanced chunk of an XML document
+ * called by the parser
+ * The allowed sequence for the Well Balanced Chunk is the one defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns 0 if the chunk is well balanced, -1 in case of args problem and
+ *    the parser error code otherwise
+ *
+ * In case recover is set to 1, the nodelist will not be empty even if
+ * the parsed chunk is not well balanced, assuming the parsing succeeded to
+ * some extent.
+ */
+int
+xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
+     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
+     int recover) {
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr newDoc;
+    xmlSAXHandlerPtr oldsax = NULL;
+    xmlNodePtr content, newRoot;
+    int size;
+    int ret = 0;
+
+    if (depth > 40) {
+	return(XML_ERR_ENTITY_LOOP);
+    }
+
+
+    if (lst != NULL)
+        *lst = NULL;
+    if (string == NULL)
+        return(-1);
+
+    size = xmlStrlen(string);
+
+    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
+    if (ctxt == NULL) return(-1);
+    ctxt->userData = ctxt;
+    if (sax != NULL) {
+	oldsax = ctxt->sax;
+        ctxt->sax = sax;
+	if (user_data != NULL)
+	    ctxt->userData = user_data;
+    }
+    newDoc = xmlNewDoc(BAD_CAST "1.0");
+    if (newDoc == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(-1);
+    }
+    newDoc->properties = XML_DOC_INTERNAL;
+    if ((doc != NULL) && (doc->dict != NULL)) {
+        xmlDictFree(ctxt->dict);
+	ctxt->dict = doc->dict;
+	xmlDictReference(ctxt->dict);
+	ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+	ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+	ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+	ctxt->dictNames = 1;
+    } else {
+	xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
+    }
+    if (doc != NULL) {
+	newDoc->intSubset = doc->intSubset;
+	newDoc->extSubset = doc->extSubset;
+    }
+    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+    if (newRoot == NULL) {
+	if (sax != NULL)
+	    ctxt->sax = oldsax;
+	xmlFreeParserCtxt(ctxt);
+	newDoc->intSubset = NULL;
+	newDoc->extSubset = NULL;
+        xmlFreeDoc(newDoc);
+	return(-1);
+    }
+    xmlAddChild((xmlNodePtr) newDoc, newRoot);
+    nodePush(ctxt, newRoot);
+    if (doc == NULL) {
+	ctxt->myDoc = newDoc;
+    } else {
+	ctxt->myDoc = newDoc;
+	newDoc->children->doc = doc;
+	/* Ensure that doc has XML spec namespace */
+	xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
+	newDoc->oldNs = doc->oldNs;
+    }
+    ctxt->instate = XML_PARSER_CONTENT;
+    ctxt->depth = depth;
+
+    /*
+     * Doing validity checking on chunk doesn't make sense
+     */
+    ctxt->validate = 0;
+    ctxt->loadsubset = 0;
+    xmlDetectSAX2(ctxt);
+
+    if ( doc != NULL ){
+        content = doc->children;
+        doc->children = NULL;
+        xmlParseContent(ctxt);
+        doc->children = content;
+    }
+    else {
+        xmlParseContent(ctxt);
+    }
+    if ((RAW == '<') && (NXT(1) == '/')) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    } else if (RAW != 0) {
+	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
+    }
+    if (ctxt->node != newDoc->children) {
+	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
+    }
+
+    if (!ctxt->wellFormed) {
+        if (ctxt->errNo == 0)
+	    ret = 1;
+	else
+	    ret = ctxt->errNo;
+    } else {
+      ret = 0;
+    }
+
+    if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
+	xmlNodePtr cur;
+
+	/*
+	 * Return the newly created nodeset after unlinking it from
+	 * they pseudo parent.
+	 */
+	cur = newDoc->children->children;
+	*lst = cur;
+	while (cur != NULL) {
+	    xmlSetTreeDoc(cur, doc);
+	    cur->parent = NULL;
+	    cur = cur->next;
+	}
+	newDoc->children->children = NULL;
+    }
+
+    if (sax != NULL)
+	ctxt->sax = oldsax;
+    xmlFreeParserCtxt(ctxt);
+    newDoc->intSubset = NULL;
+    newDoc->extSubset = NULL;
+    newDoc->oldNs = NULL;
+    xmlFreeDoc(newDoc);
+
+    return(ret);
+}
+
+/**
+ * xmlSAXParseEntity:
+ * @sax:  the SAX handler block
+ * @filename:  the filename
+ *
+ * parse an XML external entity out of context and build a tree.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * This correspond to a "Well Balanced" chunk
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+
+    ctxt = xmlCreateFileParserCtxt(filename);
+    if (ctxt == NULL) {
+	return(NULL);
+    }
+    if (sax != NULL) {
+	if (ctxt->sax != NULL)
+	    xmlFree(ctxt->sax);
+        ctxt->sax = sax;
+        ctxt->userData = NULL;
+    }
+
+    xmlParseExtParsedEnt(ctxt);
+
+    if (ctxt->wellFormed)
+	ret = ctxt->myDoc;
+    else {
+        ret = NULL;
+        xmlFreeDoc(ctxt->myDoc);
+        ctxt->myDoc = NULL;
+    }
+    if (sax != NULL)
+        ctxt->sax = NULL;
+    xmlFreeParserCtxt(ctxt);
+
+    return(ret);
+}
+
+/**
+ * xmlParseEntity:
+ * @filename:  the filename
+ *
+ * parse an XML external entity out of context and build a tree.
+ *
+ * [78] extParsedEnt ::= TextDecl? content
+ *
+ * This correspond to a "Well Balanced" chunk
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlParseEntity(const char *filename) {
+    return(xmlSAXParseEntity(NULL, filename));
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/**
+ * 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
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+static xmlParserCtxtPtr
+xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+	                  const xmlChar *base, xmlParserCtxtPtr pctx) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr inputStream;
+    char *directory = NULL;
+    xmlChar *uri;
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+	return(NULL);
+    }
+
+    if (pctx != NULL) {
+        ctxt->options = pctx->options;
+        ctxt->_private = pctx->_private;
+    }
+
+    uri = xmlBuildURI(URL, base);
+
+    if (uri == NULL) {
+	inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
+	if (inputStream == NULL) {
+	    xmlFreeParserCtxt(ctxt);
+	    return(NULL);
+	}
+
+	inputPush(ctxt, inputStream);
+
+	if ((ctxt->directory == NULL) && (directory == NULL))
+	    directory = xmlParserGetDirectory((char *)URL);
+	if ((ctxt->directory == NULL) && (directory != NULL))
+	    ctxt->directory = directory;
+    } else {
+	inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
+	if (inputStream == NULL) {
+	    xmlFree(uri);
+	    xmlFreeParserCtxt(ctxt);
+	    return(NULL);
+	}
+
+	inputPush(ctxt, inputStream);
+
+	if ((ctxt->directory == NULL) && (directory == NULL))
+	    directory = xmlParserGetDirectory((char *)uri);
+	if ((ctxt->directory == NULL) && (directory != NULL))
+	    ctxt->directory = directory;
+	xmlFree(uri);
+    }
+    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			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCreateURLParserCtxt:
+ * @filename:  the filename or URL
+ * @options:  a combination of xmlParserOption
+ *
+ * Create a parser context for a file or URL content. 
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time and for file accesses
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateURLParserCtxt(const char *filename, int options)
+{
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr inputStream;
+    char *directory = NULL;
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+	xmlErrMemory(NULL, "cannot allocate parser context");
+	return(NULL);
+    }
+
+    if (options)
+	xmlCtxtUseOptionsInternal(ctxt, options, NULL);
+    ctxt->linenumbers = 1;
+
+    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    inputPush(ctxt, inputStream);
+    if ((ctxt->directory == NULL) && (directory == NULL))
+        directory = xmlParserGetDirectory(filename);
+    if ((ctxt->directory == NULL) && (directory != NULL))
+        ctxt->directory = directory;
+
+    return(ctxt);
+}
+
+/**
+ * xmlCreateFileParserCtxt:
+ * @filename:  the filename
+ *
+ * Create a parser context for a file content. 
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateFileParserCtxt(const char *filename)
+{
+    return(xmlCreateURLParserCtxt(filename, 0));
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlSAXParseFileWithData:
+ * @sax:  the SAX handler block
+ * @filename:  the filename
+ * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
+ *             documents
+ * @data:  the userdata
+ *
+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ *
+ * User data (void *) is stored within the parser context in the
+ * context's _private member, so it is available nearly everywhere in libxml
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
+                        int recovery, void *data) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+
+    xmlInitParser();
+
+    ctxt = xmlCreateFileParserCtxt(filename);
+    if (ctxt == NULL) {
+	return(NULL);
+    }
+    if (sax != NULL) {
+	if (ctxt->sax != NULL)
+	    xmlFree(ctxt->sax);
+        ctxt->sax = sax;
+    }
+    xmlDetectSAX2(ctxt);
+    if (data!=NULL) {
+	ctxt->_private = data;
+    }
+
+    if (ctxt->directory == NULL)
+        ctxt->directory = xmlParserGetDirectory(filename);
+
+    ctxt->recovery = recovery;
+
+    xmlParseDocument(ctxt);
+
+    if ((ctxt->wellFormed) || recovery) {
+        ret = ctxt->myDoc;
+	if (ret != NULL) {
+	    if (ctxt->input->buf->compressed > 0)
+		ret->compression = 9;
+	    else
+		ret->compression = ctxt->input->buf->compressed;
+	}
+    }
+    else {
+       ret = NULL;
+       xmlFreeDoc(ctxt->myDoc);
+       ctxt->myDoc = NULL;
+    }
+    if (sax != NULL)
+        ctxt->sax = NULL;
+    xmlFreeParserCtxt(ctxt);
+    
+    return(ret);
+}
+
+/**
+ * xmlSAXParseFile:
+ * @sax:  the SAX handler block
+ * @filename:  the filename
+ * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
+ *             documents
+ *
+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
+                          int recovery) {
+    return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
+}
+
+/**
+ * xmlRecoverDoc:
+ * @cur:  a pointer to an array of xmlChar
+ *
+ * parse an XML in-memory document and build a tree.
+ * In the case the document is not Well Formed, a attempt to build a
+ * tree is tried anyway
+ *
+ * Returns the resulting document tree or NULL in case of failure
+ */
+
+xmlDocPtr
+xmlRecoverDoc(const xmlChar *cur) {
+    return(xmlSAXParseDoc(NULL, cur, 1));
+}
+
+/**
+ * xmlParseFile:
+ * @filename:  the filename
+ *
+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ *
+ * Returns the resulting document tree if the file was wellformed,
+ * NULL otherwise.
+ */
+
+xmlDocPtr
+xmlParseFile(const char *filename) {
+    return(xmlSAXParseFile(NULL, filename, 0));
+}
+
+/**
+ * xmlRecoverFile:
+ * @filename:  the filename
+ *
+ * parse an XML file and build a tree. Automatic support for ZLIB/Compress
+ * compressed document is provided by default if found at compile-time.
+ * In the case the document is not Well Formed, it attempts to build
+ * a tree anyway
+ *
+ * Returns the resulting document tree or NULL in case of failure
+ */
+
+xmlDocPtr
+xmlRecoverFile(const char *filename) {
+    return(xmlSAXParseFile(NULL, filename, 1));
+}
+
+
+/**
+ * xmlSetupParserForBuffer:
+ * @ctxt:  an XML parser context
+ * @buffer:  a xmlChar * buffer
+ * @filename:  a file name
+ *
+ * Setup the parser context to parse a new buffer; Clears any prior
+ * contents from the parser context. The buffer parameter must not be
+ * NULL, but the filename parameter can be
+ */
+void
+xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
+                             const char* filename)
+{
+    xmlParserInputPtr input;
+
+    if ((ctxt == NULL) || (buffer == NULL))
+        return;
+
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+        xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
+        xmlClearParserCtxt(ctxt);
+        return;
+    }
+  
+    xmlClearParserCtxt(ctxt);
+    if (filename != NULL)
+        input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
+    input->base = buffer;
+    input->cur = buffer;
+    input->end = &buffer[xmlStrlen(buffer)];
+    inputPush(ctxt, input);
+}
+
+/**
+ * xmlSAXUserParseFile:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @filename:  a file name
+ *
+ * parse an XML file and call the given SAX handler routines.
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * 
+ * Returns 0 in case of success or a error number otherwise
+ */
+int
+xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
+                    const char *filename) {
+    int ret = 0;
+    xmlParserCtxtPtr ctxt;
+    
+    ctxt = xmlCreateFileParserCtxt(filename);
+    if (ctxt == NULL) return -1;
+    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
+	xmlFree(ctxt->sax);
+    ctxt->sax = sax;
+    xmlDetectSAX2(ctxt);
+
+    if (user_data != NULL)
+	ctxt->userData = user_data;
+    
+    xmlParseDocument(ctxt);
+    
+    if (ctxt->wellFormed)
+	ret = 0;
+    else {
+        if (ctxt->errNo != 0)
+	    ret = ctxt->errNo;
+	else
+	    ret = -1;
+    }
+    if (sax != NULL)
+	ctxt->sax = NULL;
+    if (ctxt->myDoc != NULL) {
+        xmlFreeDoc(ctxt->myDoc);
+	ctxt->myDoc = NULL;
+    }
+    xmlFreeParserCtxt(ctxt);
+    
+    return ret;
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/************************************************************************
+ *									*
+ * 		Front ends when parsing from memory			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCreateMemoryParserCtxt:
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ *
+ * Create a parser context for an XML in-memory document.
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateMemoryParserCtxt(const char *buffer, int size) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+    xmlParserInputBufferPtr buf;
+
+    if (buffer == NULL)
+	return(NULL);
+    if (size <= 0)
+	return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL)
+	return(NULL);
+
+    /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
+    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+	xmlFreeParserInputBuffer(buf);
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+
+    input->filename = NULL;
+    input->buf = buf;
+    input->base = input->buf->buffer->content;
+    input->cur = input->buf->buffer->content;
+    input->end = &input->buf->buffer->content[input->buf->buffer->use];
+
+    inputPush(ctxt, input);
+    return(ctxt);
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlSAXParseMemoryWithData:
+ * @sax:  the SAX handler block
+ * @buffer:  an pointer to a char array
+ * @size:  the size of the array
+ * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
+ *             documents
+ * @data:  the userdata
+ *
+ * parse an XML in-memory block and use the given SAX function block
+ * to handle the parsing callback. If sax is NULL, fallback to the default
+ * DOM tree building routines.
+ *
+ * User data (void *) is stored within the parser context in the
+ * context's _private member, so it is available nearly everywhere in libxml
+ *
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
+	          int size, int recovery, void *data) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+
+    xmlInitParser();
+
+    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
+    if (ctxt == NULL) return(NULL);
+    if (sax != NULL) {
+	if (ctxt->sax != NULL)
+	    xmlFree(ctxt->sax);
+        ctxt->sax = sax;
+    }
+    xmlDetectSAX2(ctxt);
+    if (data!=NULL) {
+	ctxt->_private=data;
+    }
+
+    ctxt->recovery = recovery;
+
+    xmlParseDocument(ctxt);
+
+    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
+    else {
+       ret = NULL;
+       xmlFreeDoc(ctxt->myDoc);
+       ctxt->myDoc = NULL;
+    }
+    if (sax != NULL) 
+	ctxt->sax = NULL;
+    xmlFreeParserCtxt(ctxt);
+
+    return(ret);
+}
+
+/**
+ * xmlSAXParseMemory:
+ * @sax:  the SAX handler block
+ * @buffer:  an pointer to a char array
+ * @size:  the size of the array
+ * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
+ *             documents
+ *
+ * parse an XML in-memory block and use the given SAX function block
+ * to handle the parsing callback. If sax is NULL, fallback to the default
+ * DOM tree building routines.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
+	          int size, int recovery) {
+    return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
+}
+
+/**
+ * xmlParseMemory:
+ * @buffer:  an pointer to a char array
+ * @size:  the size of the array
+ *
+ * parse an XML in-memory block and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr xmlParseMemory(const char *buffer, int size) {
+   return(xmlSAXParseMemory(NULL, buffer, size, 0));
+}
+
+/**
+ * xmlRecoverMemory:
+ * @buffer:  an pointer to a char array
+ * @size:  the size of the array
+ *
+ * parse an XML in-memory block and build a tree.
+ * In the case the document is not Well Formed, an attempt to
+ * build a tree is tried anyway
+ *
+ * Returns the resulting document tree or NULL in case of error
+ */
+
+xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
+   return(xmlSAXParseMemory(NULL, buffer, size, 1));
+}
+
+/**
+ * xmlSAXUserParseMemory:
+ * @sax:  a SAX handler
+ * @user_data:  The user data returned on SAX callbacks
+ * @buffer:  an in-memory XML document input
+ * @size:  the length of the XML document in bytes
+ *
+ * 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)
+        xmlFree(ctxt->sax);
+    ctxt->sax = sax;
+    xmlDetectSAX2(ctxt);
+
+    if (user_data != NULL)
+	ctxt->userData = user_data;
+
+    xmlParseDocument(ctxt);
+    
+    if (ctxt->wellFormed)
+	ret = 0;
+    else {
+        if (ctxt->errNo != 0)
+	    ret = ctxt->errNo;
+	else
+	    ret = -1;
+    }
+    if (sax != NULL)
+        ctxt->sax = NULL;
+    if (ctxt->myDoc != NULL) {
+        xmlFreeDoc(ctxt->myDoc);
+	ctxt->myDoc = NULL;
+    }
+    xmlFreeParserCtxt(ctxt);
+    
+    return ret;
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+/**
+ * xmlCreateDocParserCtxt:
+ * @cur:  a pointer to an array of xmlChar
+ *
+ * Creates a parser context for an XML in-memory document.
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateDocParserCtxt(const xmlChar *cur) {
+    int len;
+
+    if (cur == NULL)
+	return(NULL);
+    len = xmlStrlen(cur);
+    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
+}
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * xmlSAXParseDoc:
+ * @sax:  the SAX handler block
+ * @cur:  a pointer to an array of xmlChar
+ * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
+ *             documents
+ *
+ * parse an XML in-memory document and build a tree.
+ * It use the given SAX function block to handle the parsing callback.
+ * If sax is NULL, fallback to the default DOM tree building routines.
+ * 
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+    xmlSAXHandlerPtr oldsax = NULL;
+
+    if (cur == NULL) return(NULL);
+
+
+    ctxt = xmlCreateDocParserCtxt(cur);
+    if (ctxt == NULL) return(NULL);
+    if (sax != NULL) { 
+        oldsax = ctxt->sax;
+        ctxt->sax = sax;
+        ctxt->userData = NULL;
+    }
+    xmlDetectSAX2(ctxt);
+
+    xmlParseDocument(ctxt);
+    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
+    else {
+       ret = NULL;
+       xmlFreeDoc(ctxt->myDoc);
+       ctxt->myDoc = NULL;
+    }
+    if (sax != NULL)
+	ctxt->sax = oldsax;
+    xmlFreeParserCtxt(ctxt);
+    
+    return(ret);
+}
+
+/**
+ * xmlParseDoc:
+ * @cur:  a pointer to an array of xmlChar
+ *
+ * parse an XML in-memory document and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+
+xmlDocPtr
+xmlParseDoc(const xmlChar *cur) {
+    return(xmlSAXParseDoc(NULL, cur, 0));
+}
+#endif /* LIBXML_SAX1_ENABLED */
+
+#ifdef LIBXML_LEGACY_ENABLED
+/************************************************************************
+ *									*
+ * 	Specific function to keep track of entities references		*
+ * 	and used by the XSLT debugger					*
+ *									*
+ ************************************************************************/
+
+static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
+
+/**
+ * xmlAddEntityReference:
+ * @ent : A valid entity
+ * @firstNode : A valid first node for children of entity
+ * @lastNode : A valid last node of children entity 
+ *
+ * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
+ */
+static void
+xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
+                      xmlNodePtr lastNode)
+{
+    if (xmlEntityRefFunc != NULL) {
+        (*xmlEntityRefFunc) (ent, firstNode, lastNode);
+    }
+}
+
+
+/**
+ * xmlSetEntityReferenceFunc:
+ * @func: A valid function
+ *
+ * Set the function to call call back when a xml reference has been made
+ */
+void
+xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
+{
+    xmlEntityRefFunc = func;
+}
+#endif /* LIBXML_LEGACY_ENABLED */
+
+/************************************************************************
+ *									*
+ * 				Miscellaneous				*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_XPATH_ENABLED
+#include <libxml/xpath.h>
+#endif
+
+extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
+static int xmlParserInitialized = 0;
+
+/**
+ * xmlInitParser:
+ *
+ * Initialization function for the XML parser.
+ * This is not reentrant. Call once before processing in case of
+ * use in multithreaded programs.
+ */
+
+void
+xmlInitParser(void) {
+    if (xmlParserInitialized != 0)
+	return;
+
+#ifdef LIBXML_THREAD_ENABLED
+    __xmlGlobalInitMutexLock();
+    if (xmlParserInitialized == 0) {
+#endif
+	xmlInitGlobals();
+	xmlInitThreads();
+	if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
+	    (xmlGenericError == NULL))
+	    initGenericErrorDefaultFunc(NULL);
+	xmlInitMemory();
+	xmlInitCharEncodingHandlers();
+	xmlDefaultSAXHandlerInit();
+	xmlRegisterDefaultInputCallbacks();
+#ifdef LIBXML_OUTPUT_ENABLED
+	xmlRegisterDefaultOutputCallbacks();
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_HTML_ENABLED
+	htmlInitAutoClose();
+	htmlDefaultSAXHandlerInit();
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+	xmlXPathInit();
+#endif
+	xmlParserInitialized = 1;
+#ifdef LIBXML_THREAD_ENABLED
+    }
+    __xmlGlobalInitMutexUnlock();
+#endif
+}
+
+/**
+ * xmlCleanupParser:
+ *
+ * This function name is somewhat misleading. It does not clean up
+ * parser state, it cleans up memory allocated by the library itself.
+ * It is a cleanup function for the XML library. It tries to reclaim all
+ * related global memory allocated for the library processing.
+ * It doesn't deallocate any document related memory. One should
+ * call xmlCleanupParser() only when the process has finished using
+ * 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
+xmlCleanupParser(void) {
+    if (!xmlParserInitialized)
+	return;
+
+    xmlCleanupCharEncodingHandlers();
+#ifdef LIBXML_CATALOG_ENABLED
+    xmlCatalogCleanup();
+#endif
+    xmlDictCleanup();
+    xmlCleanupInputCallbacks();
+#ifdef LIBXML_OUTPUT_ENABLED
+    xmlCleanupOutputCallbacks();
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlSchemaCleanupTypes();
+    xmlRelaxNGCleanupTypes();
+#endif
+    xmlCleanupGlobals();
+    xmlResetLastError();
+    xmlCleanupThreads(); /* must be last if called not from the main thread */
+    xmlCleanupMemory();
+    xmlParserInitialized = 0;
+}
+
+/************************************************************************
+ *									*
+ *	New set (2.6.0) of simpler and more flexible APIs		*
+ *									*
+ ************************************************************************/
+
+/**
+ * DICT_FREE:
+ * @str:  a string
+ *
+ * Free a string if it is not owned by the "dict" dictionnary in the
+ * current scope
+ */
+#define DICT_FREE(str)						\
+	if ((str) && ((!dict) || 				\
+	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
+	    xmlFree((char *)(str));
+
+/**
+ * xmlCtxtReset:
+ * @ctxt: an XML parser context
+ *
+ * Reset a parser context
+ */
+void
+xmlCtxtReset(xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr input;
+    xmlDictPtr dict;
+    
+    if (ctxt == NULL)
+        return;
+
+    dict = ctxt->dict;
+
+    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
+        xmlFreeInputStream(input);
+    }
+    ctxt->inputNr = 0;
+    ctxt->input = NULL;
+
+    ctxt->spaceNr = 0;
+    if (ctxt->spaceTab != NULL) {
+	ctxt->spaceTab[0] = -1;
+	ctxt->space = &ctxt->spaceTab[0];
+    } else {
+        ctxt->space = NULL;
+    }
+
+
+    ctxt->nodeNr = 0;
+    ctxt->node = NULL;
+
+    ctxt->nameNr = 0;
+    ctxt->name = NULL;
+
+    DICT_FREE(ctxt->version);
+    ctxt->version = NULL;
+    DICT_FREE(ctxt->encoding);
+    ctxt->encoding = NULL;
+    DICT_FREE(ctxt->directory);
+    ctxt->directory = NULL;
+    DICT_FREE(ctxt->extSubURI);
+    ctxt->extSubURI = NULL;
+    DICT_FREE(ctxt->extSubSystem);
+    ctxt->extSubSystem = NULL;
+    if (ctxt->myDoc != NULL)
+        xmlFreeDoc(ctxt->myDoc);
+    ctxt->myDoc = NULL;
+
+    ctxt->standalone = -1;
+    ctxt->hasExternalSubset = 0;
+    ctxt->hasPErefs = 0;
+    ctxt->html = 0;
+    ctxt->external = 0;
+    ctxt->instate = XML_PARSER_START;
+    ctxt->token = 0;
+
+    ctxt->wellFormed = 1;
+    ctxt->nsWellFormed = 1;
+    ctxt->disableSAX = 0;
+    ctxt->valid = 1;
+#if 0
+    ctxt->vctxt.userData = ctxt;
+    ctxt->vctxt.error = xmlParserValidityError;
+    ctxt->vctxt.warning = xmlParserValidityWarning;
+#endif
+    ctxt->record_info = 0;
+    ctxt->nbChars = 0;
+    ctxt->checkIndex = 0;
+    ctxt->inSubset = 0;
+    ctxt->errNo = XML_ERR_OK;
+    ctxt->depth = 0;
+    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    ctxt->catalogs = NULL;
+    ctxt->nbentities = 0;
+    ctxt->sizeentities = 0;
+    xmlInitNodeInfoSeq(&ctxt->node_seq);
+
+    if (ctxt->attsDefault != NULL) {
+        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
+        ctxt->attsDefault = NULL;
+    }
+    if (ctxt->attsSpecial != NULL) {
+        xmlHashFree(ctxt->attsSpecial, NULL);
+        ctxt->attsSpecial = NULL;
+    }
+
+#ifdef LIBXML_CATALOG_ENABLED
+    if (ctxt->catalogs != NULL)
+	xmlCatalogFreeLocal(ctxt->catalogs);
+#endif
+    if (ctxt->lastError.code != XML_ERR_OK)
+        xmlResetError(&ctxt->lastError);
+}
+
+/**
+ * xmlCtxtResetPush:
+ * @ctxt: an XML parser context
+ * @chunk:  a pointer to an array of chars
+ * @size:  number of chars in the array
+ * @filename:  an optional file name or URI
+ * @encoding:  the document encoding, or NULL
+ *
+ * Reset a push parser context
+ *
+ * Returns 0 in case of success and 1 in case of error
+ */
+int
+xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
+                 int size, const char *filename, const char *encoding)
+{
+    xmlParserInputPtr inputStream;
+    xmlParserInputBufferPtr buf;
+    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
+
+    if (ctxt == NULL)
+        return(1);
+
+    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
+        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
+
+    buf = xmlAllocParserInputBuffer(enc);
+    if (buf == NULL)
+        return(1);
+
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(buf);
+        return(1);
+    }
+
+    xmlCtxtReset(ctxt);
+
+    if (ctxt->pushTab == NULL) {
+        ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
+	                                    sizeof(xmlChar *));
+        if (ctxt->pushTab == NULL) {
+	    xmlErrMemory(ctxt, NULL);
+            xmlFreeParserInputBuffer(buf);
+            return(1);
+        }
+    }
+
+    if (filename == NULL) {
+        ctxt->directory = NULL;
+    } else {
+        ctxt->directory = xmlParserGetDirectory(filename);
+    }
+
+    inputStream = xmlNewInputStream(ctxt);
+    if (inputStream == NULL) {
+        xmlFreeParserInputBuffer(buf);
+        return(1);
+    }
+
+    if (filename == NULL)
+        inputStream->filename = NULL;
+    else
+        inputStream->filename = (char *)
+            xmlCanonicPath((const xmlChar *) filename);
+    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];
+
+    inputPush(ctxt, inputStream);
+
+    if ((size > 0) && (chunk != NULL) && (ctxt->input != 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);
+
+        ctxt->input->base = ctxt->input->buf->buffer->content + base;
+        ctxt->input->cur = ctxt->input->base + cur;
+        ctxt->input->end =
+            &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
+                                               use];
+#ifdef DEBUG_PUSH
+        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
+#endif
+    }
+
+    if (encoding != NULL) {
+        xmlCharEncodingHandlerPtr hdlr;
+
+        if (ctxt->encoding != NULL)
+	    xmlFree((xmlChar *) ctxt->encoding);
+        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
+
+        hdlr = xmlFindCharEncodingHandler(encoding);
+        if (hdlr != NULL) {
+            xmlSwitchToEncoding(ctxt, hdlr);
+	} else {
+	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			      "Unsupported encoding %s\n", BAD_CAST encoding);
+        }
+    } else if (enc != XML_CHAR_ENCODING_NONE) {
+        xmlSwitchEncoding(ctxt, enc);
+    }
+
+    return(0);
+}
+
+
+/**
+ * xmlCtxtUseOptionsInternal:
+ * @ctxt: an XML parser context
+ * @options:  a combination of xmlParserOption
+ * @encoding:  the user provided encoding to use
+ *
+ * Applies the options to the parser context
+ *
+ * Returns 0 in case of success, the set of unknown or unimplemented options
+ *         in case of error.
+ */
+static int
+xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
+{
+    if (ctxt == NULL)
+        return(-1);
+    if (encoding != NULL) {
+        if (ctxt->encoding != NULL)
+	    xmlFree((xmlChar *) ctxt->encoding);
+        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
+    }
+    if (options & XML_PARSE_RECOVER) {
+        ctxt->recovery = 1;
+        options -= XML_PARSE_RECOVER;
+	ctxt->options |= XML_PARSE_RECOVER;
+    } else
+        ctxt->recovery = 0;
+    if (options & XML_PARSE_DTDLOAD) {
+        ctxt->loadsubset = XML_DETECT_IDS;
+        options -= XML_PARSE_DTDLOAD;
+	ctxt->options |= XML_PARSE_DTDLOAD;
+    } else
+        ctxt->loadsubset = 0;
+    if (options & XML_PARSE_DTDATTR) {
+        ctxt->loadsubset |= XML_COMPLETE_ATTRS;
+        options -= XML_PARSE_DTDATTR;
+	ctxt->options |= XML_PARSE_DTDATTR;
+    }
+    if (options & XML_PARSE_NOENT) {
+        ctxt->replaceEntities = 1;
+        /* ctxt->loadsubset |= XML_DETECT_IDS; */
+        options -= XML_PARSE_NOENT;
+	ctxt->options |= XML_PARSE_NOENT;
+    } else
+        ctxt->replaceEntities = 0;
+    if (options & XML_PARSE_PEDANTIC) {
+        ctxt->pedantic = 1;
+        options -= XML_PARSE_PEDANTIC;
+	ctxt->options |= XML_PARSE_PEDANTIC;
+    } else
+        ctxt->pedantic = 0;
+    if (options & XML_PARSE_NOBLANKS) {
+        ctxt->keepBlanks = 0;
+        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+        options -= XML_PARSE_NOBLANKS;
+	ctxt->options |= XML_PARSE_NOBLANKS;
+    } else
+        ctxt->keepBlanks = 1;
+    if (options & XML_PARSE_DTDVALID) {
+        ctxt->validate = 1;
+        if (options & XML_PARSE_NOWARNING)
+            ctxt->vctxt.warning = NULL;
+        if (options & XML_PARSE_NOERROR)
+            ctxt->vctxt.error = NULL;
+        options -= XML_PARSE_DTDVALID;
+	ctxt->options |= XML_PARSE_DTDVALID;
+    } else
+        ctxt->validate = 0;
+    if (options & XML_PARSE_NOWARNING) {
+        ctxt->sax->warning = NULL;
+        options -= XML_PARSE_NOWARNING;
+    }
+    if (options & XML_PARSE_NOERROR) {
+        ctxt->sax->error = NULL;
+        ctxt->sax->fatalError = NULL;
+        options -= XML_PARSE_NOERROR;
+    }
+#ifdef LIBXML_SAX1_ENABLED
+    if (options & XML_PARSE_SAX1) {
+        ctxt->sax->startElement = xmlSAX2StartElement;
+        ctxt->sax->endElement = xmlSAX2EndElement;
+        ctxt->sax->startElementNs = NULL;
+        ctxt->sax->endElementNs = NULL;
+        ctxt->sax->initialized = 1;
+        options -= XML_PARSE_SAX1;
+	ctxt->options |= XML_PARSE_SAX1;
+    }
+#endif /* LIBXML_SAX1_ENABLED */
+    if (options & XML_PARSE_NODICT) {
+        ctxt->dictNames = 0;
+        options -= XML_PARSE_NODICT;
+	ctxt->options |= XML_PARSE_NODICT;
+    } else {
+        ctxt->dictNames = 1;
+    }
+    if (options & XML_PARSE_NOCDATA) {
+        ctxt->sax->cdataBlock = NULL;
+        options -= XML_PARSE_NOCDATA;
+	ctxt->options |= XML_PARSE_NOCDATA;
+    }
+    if (options & XML_PARSE_NSCLEAN) {
+	ctxt->options |= XML_PARSE_NSCLEAN;
+        options -= XML_PARSE_NSCLEAN;
+    }
+    if (options & XML_PARSE_NONET) {
+	ctxt->options |= XML_PARSE_NONET;
+        options -= XML_PARSE_NONET;
+    }
+    if (options & XML_PARSE_COMPACT) {
+	ctxt->options |= XML_PARSE_COMPACT;
+        options -= XML_PARSE_COMPACT;
+    }
+    if (options & XML_PARSE_OLD10) {
+	ctxt->options |= XML_PARSE_OLD10;
+        options -= XML_PARSE_OLD10;
+    }
+    if (options & XML_PARSE_NOBASEFIX) {
+	ctxt->options |= XML_PARSE_NOBASEFIX;
+        options -= XML_PARSE_NOBASEFIX;
+    }
+    if (options & XML_PARSE_HUGE) {
+	ctxt->options |= XML_PARSE_HUGE;
+        options -= XML_PARSE_HUGE;
+    }
+    if (options & XML_PARSE_OLDSAX) {
+	ctxt->options |= XML_PARSE_OLDSAX;
+        options -= XML_PARSE_OLDSAX;
+    }
+    ctxt->linenumbers = 1;
+    return (options);
+}
+
+/**
+ * xmlCtxtUseOptions:
+ * @ctxt: an XML parser context
+ * @options:  a combination of xmlParserOption
+ *
+ * Applies the options to the parser context
+ *
+ * Returns 0 in case of success, the set of unknown or unimplemented options
+ *         in case of error.
+ */
+int
+xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
+{
+   return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
+}
+
+/**
+ * xmlDoRead:
+ * @ctxt:  an XML parser context
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ * @reuse:  keep the context for reuse
+ *
+ * Common front-end for the xmlRead functions
+ *
+ * Returns the resulting document tree or NULL
+ */
+static xmlDocPtr
+xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
+          int options, int reuse)
+{
+    xmlDocPtr ret;
+
+    xmlCtxtUseOptionsInternal(ctxt, options, encoding);
+    if (encoding != NULL) {
+        xmlCharEncodingHandlerPtr hdlr;
+
+	hdlr = xmlFindCharEncodingHandler(encoding);
+	if (hdlr != NULL)
+	    xmlSwitchToEncoding(ctxt, hdlr);
+    }
+    if ((URL != NULL) && (ctxt->input != NULL) &&
+        (ctxt->input->filename == NULL))
+        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
+    xmlParseDocument(ctxt);
+    if ((ctxt->wellFormed) || ctxt->recovery)
+        ret = ctxt->myDoc;
+    else {
+        ret = NULL;
+	if (ctxt->myDoc != NULL) {
+	    xmlFreeDoc(ctxt->myDoc);
+	}
+    }
+    ctxt->myDoc = NULL;
+    if (!reuse) {
+	xmlFreeParserCtxt(ctxt);
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlReadDoc:
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML in-memory document and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
+{
+    xmlParserCtxtPtr ctxt;
+
+    if (cur == NULL)
+        return (NULL);
+
+    ctxt = xmlCreateDocParserCtxt(cur);
+    if (ctxt == NULL)
+        return (NULL);
+    return (xmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * xmlReadFile:
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML file from the filesystem or the network.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlReadFile(const char *filename, const char *encoding, int options)
+{
+    xmlParserCtxtPtr ctxt;
+
+    ctxt = xmlCreateURLParserCtxt(filename, options);
+    if (ctxt == NULL)
+        return (NULL);
+    return (xmlDoRead(ctxt, NULL, encoding, options, 0));
+}
+
+/**
+ * xmlReadMemory:
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML in-memory document and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
+{
+    xmlParserCtxtPtr ctxt;
+
+    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
+    if (ctxt == NULL)
+        return (NULL);
+    return (xmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * xmlReadFd:
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML from a file descriptor and build a tree.
+ * NOTE that the file descriptor will not be closed when the
+ *      reader is closed or reset.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlReadFd(int fd, const char *URL, const char *encoding, int options)
+{
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (fd < 0)
+        return (NULL);
+
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    input->closecallback = NULL;
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+	xmlFreeParserCtxt(ctxt);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * xmlReadIO:
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML document from I/O functions and source and build a tree.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
+          void *ioctx, const char *URL, const char *encoding, int options)
+{
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ioread == NULL)
+        return (NULL);
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+	xmlFreeParserCtxt(ctxt);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 0));
+}
+
+/**
+ * xmlCtxtReadDoc:
+ * @ctxt:  an XML parser context
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML in-memory document and build a tree.
+ * This reuses the existing @ctxt parser context
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
+               const char *URL, const char *encoding, int options)
+{
+    xmlParserInputPtr stream;
+
+    if (cur == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    xmlCtxtReset(ctxt);
+
+    stream = xmlNewStringInputStream(ctxt, cur);
+    if (stream == NULL) {
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * xmlCtxtReadFile:
+ * @ctxt:  an XML parser context
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML file from the filesystem or the network.
+ * This reuses the existing @ctxt parser context
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
+                const char *encoding, int options)
+{
+    xmlParserInputPtr stream;
+
+    if (filename == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    xmlCtxtReset(ctxt);
+
+    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
+    if (stream == NULL) {
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, NULL, encoding, options, 1));
+}
+
+/**
+ * xmlCtxtReadMemory:
+ * @ctxt:  an XML parser context
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML in-memory document and build a tree.
+ * This reuses the existing @ctxt parser context
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
+                  const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ctxt == NULL)
+        return (NULL);
+    if (buffer == NULL)
+        return (NULL);
+
+    xmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+    if (input == NULL) {
+	return(NULL);
+    }
+
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+	xmlFreeParserInputBuffer(input);
+	return(NULL);
+    }
+
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * xmlCtxtReadFd:
+ * @ctxt:  an XML parser context
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML from a file descriptor and build a tree.
+ * This reuses the existing @ctxt parser context
+ * NOTE that the file descriptor will not be closed when the
+ *      reader is closed or reset.
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
+              const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (fd < 0)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    xmlCtxtReset(ctxt);
+
+
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    input->closecallback = NULL;
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+/**
+ * xmlCtxtReadIO:
+ * @ctxt:  an XML parser context
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * parse an XML document from I/O functions and source and build a tree.
+ * This reuses the existing @ctxt parser context
+ * 
+ * Returns the resulting document tree
+ */
+xmlDocPtr
+xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
+              xmlInputCloseCallback ioclose, void *ioctx,
+	      const char *URL,
+              const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ioread == NULL)
+        return (NULL);
+    if (ctxt == NULL)
+        return (NULL);
+
+    xmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 1));
+}
+
+#define bottom_parser
+#include "elfgcchack.h"
diff --git a/src/parserInternals.c b/src/parserInternals.c
new file mode 100644
index 0000000..2404ddf
--- /dev/null
+++ b/src/parserInternals.c
@@ -0,0 +1,2162 @@
+/*
+ * parserInternals.c : Internal routines (and obsolete ones) needed for the
+ *                     XML and HTML parsers.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#if defined(WIN32) && !defined (__CYGWIN__)
+#define XML_DIR_SEP '\\'
+#else
+#define XML_DIR_SEP '/'
+#endif
+
+#include <string.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/valid.h>
+#include <libxml/entities.h>
+#include <libxml/xmlerror.h>
+#include <libxml/encoding.h>
+#include <libxml/valid.h>
+#include <libxml/xmlIO.h>
+#include <libxml/uri.h>
+#include <libxml/dict.h>
+#include <libxml/SAX.h>
+#ifdef LIBXML_CATALOG_ENABLED
+#include <libxml/catalog.h>
+#endif
+#include <libxml/globals.h>
+#include <libxml/chvalid.h>
+
+/*
+ * Various global defaults for parsing
+ */
+
+/**
+ * xmlCheckVersion:
+ * @version: the include version number
+ *
+ * check the compiled lib version against the include one.
+ * This can warn or immediately kill the application
+ */
+void
+xmlCheckVersion(int version) {
+    int myversion = (int) LIBXML_VERSION;
+
+    xmlInitParser();
+
+    if ((myversion / 10000) != (version / 10000)) {
+	xmlGenericError(xmlGenericErrorContext, 
+		"Fatal: program compiled against libxml %d using libxml %d\n",
+		(version / 10000), (myversion / 10000));
+	fprintf(stderr, 
+		"Fatal: program compiled against libxml %d using libxml %d\n",
+		(version / 10000), (myversion / 10000));
+    }
+    if ((myversion / 100) < (version / 100)) {
+	xmlGenericError(xmlGenericErrorContext, 
+		"Warning: program compiled against libxml %d using older %d\n",
+		(version / 100), (myversion / 100));
+    }
+}
+
+
+/************************************************************************
+ *									*
+ * 		Some factorized error routines				*
+ *									*
+ ************************************************************************/
+
+
+/**
+ * xmlErrMemory:
+ * @ctxt:  an XML parser context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+void
+xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL) {
+        ctxt->errNo = XML_ERR_NO_MEMORY;
+        ctxt->instate = XML_PARSER_EOF;
+        ctxt->disableSAX = 1;
+    }
+    if (extra)
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+                        NULL, NULL, 0, 0,
+                        "Memory allocation failed : %s\n", extra);
+    else
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
+                        NULL, NULL, 0, 0, "Memory allocation failed\n");
+}
+
+/**
+ * __xmlErrEncoding:
+ * @ctxt:  an XML parser context
+ * @xmlerr:  the error number
+ * @msg:  the error message
+ * @str1:  an string info
+ * @str2:  an string info
+ *
+ * Handle an encoding error
+ */
+void
+__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
+                 const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL)
+        ctxt->errNo = xmlerr;
+    __xmlRaiseError(NULL, NULL, NULL,
+                    ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
+                    NULL, 0, (const char *) str1, (const char *) str2,
+                    NULL, 0, 0, msg, str1, str2);
+    if (ctxt != NULL) {
+        ctxt->wellFormed = 0;
+        if (ctxt->recovery == 0)
+            ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlErrInternal:
+ * @ctxt:  an XML parser context
+ * @msg:  the error message
+ * @str:  error informations
+ *
+ * Handle an internal error
+ */
+static void
+xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
+{
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if (ctxt != NULL)
+        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+    __xmlRaiseError(NULL, NULL, NULL,
+                    ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
+                    XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
+                    0, 0, msg, str);
+    if (ctxt != NULL) {
+        ctxt->wellFormed = 0;
+        if (ctxt->recovery == 0)
+            ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlErrEncodingInt:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  an integer value
+ *
+ * n encoding error
+ */
+static void
+xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+                  const char *msg, int val)
+{
+    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_PARSER, error, XML_ERR_FATAL,
+                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
+    if (ctxt != NULL) {
+        ctxt->wellFormed = 0;
+        if (ctxt->recovery == 0)
+            ctxt->disableSAX = 1;
+    }
+}
+
+/**
+ * xmlIsLetter:
+ * @c:  an unicode character (int)
+ *
+ * Check whether the character is allowed by the production
+ * [84] Letter ::= BaseChar | Ideographic
+ *
+ * Returns 0 if not, non-zero otherwise
+ */
+int
+xmlIsLetter(int c) {
+    return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
+}
+
+/************************************************************************
+ *									*
+ * 		Input handling functions for progressive parsing	*
+ *									*
+ ************************************************************************/
+
+/* #define DEBUG_INPUT */
+/* #define DEBUG_STACK */
+/* #define DEBUG_PUSH */
+
+
+/* we need to keep enough input to show errors in context */
+#define LINE_LEN        80
+
+#ifdef DEBUG_INPUT
+#define CHECK_BUFFER(in) check_buffer(in)
+
+static
+void check_buffer(xmlParserInputPtr in) {
+    if (in->base != in->buf->buffer->content) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlParserInput: base mismatch problem\n");
+    }
+    if (in->cur < in->base) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlParserInput: cur < base problem\n");
+    }
+    if (in->cur > in->base + in->buf->buffer->use) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlParserInput: cur > base + use problem\n");
+    }
+    xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d, size %d\n",
+            (int) in, (int) in->buf->buffer->content, in->cur - in->base,
+	    in->buf->buffer->use, in->buf->buffer->size);
+}
+
+#else
+#define CHECK_BUFFER(in) 
+#endif
+
+
+/**
+ * xmlParserInputRead:
+ * @in:  an XML parser input
+ * @len:  an indicative size for the lookahead
+ *
+ * This function refresh the input for the parser. It doesn't try to
+ * preserve pointers to the input buffer, and discard already read data
+ *
+ * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
+ * end of this entity
+ */
+int
+xmlParserInputRead(xmlParserInputPtr in, int len) {
+    int ret;
+    int used;
+    int indx;
+
+    if (in == NULL) return(-1);
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext, "Read\n");
+#endif
+    if (in->buf == NULL) return(-1);
+    if (in->base == NULL) return(-1);
+    if (in->cur == NULL) return(-1);
+    if (in->buf->buffer == NULL) return(-1);
+    if (in->buf->readcallback == NULL) return(-1);
+
+    CHECK_BUFFER(in);
+
+    used = in->cur - in->buf->buffer->content;
+    ret = xmlBufferShrink(in->buf->buffer, used);
+    if (ret > 0) {
+	in->cur -= ret;
+	in->consumed += ret;
+    }
+    ret = xmlParserInputBufferRead(in->buf, len);
+    if (in->base != in->buf->buffer->content) {
+        /*
+	 * the buffer has been reallocated
+	 */
+	indx = in->cur - in->base;
+	in->base = in->buf->buffer->content;
+	in->cur = &in->buf->buffer->content[indx];
+    }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
+
+    CHECK_BUFFER(in);
+
+    return(ret);
+}
+
+/**
+ * xmlParserInputGrow:
+ * @in:  an XML parser input
+ * @len:  an indicative size for the lookahead
+ *
+ * This function increase the input for the parser. It tries to
+ * preserve pointers to the input buffer, and keep already read data
+ *
+ * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
+ * end of this entity
+ */
+int
+xmlParserInputGrow(xmlParserInputPtr in, int len) {
+    int ret;
+    int indx;
+
+    if (in == NULL) return(-1);
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext, "Grow\n");
+#endif
+    if (in->buf == NULL) return(-1);
+    if (in->base == NULL) return(-1);
+    if (in->cur == NULL) return(-1);
+    if (in->buf->buffer == NULL) return(-1);
+
+    CHECK_BUFFER(in);
+
+    indx = in->cur - in->base;
+    if (in->buf->buffer->use > (unsigned int) indx + INPUT_CHUNK) {
+
+	CHECK_BUFFER(in);
+
+        return(0);
+    }
+    if (in->buf->readcallback != NULL)
+	ret = xmlParserInputBufferGrow(in->buf, len);
+    else	
+        return(0);
+
+    /*
+     * NOTE : in->base may be a "dangling" i.e. freed pointer in this
+     *        block, but we use it really as an integer to do some
+     *        pointer arithmetic. Insure will raise it as a bug but in
+     *        that specific case, that's not !
+     */
+    if (in->base != in->buf->buffer->content) {
+        /*
+	 * the buffer has been reallocated
+	 */
+	indx = in->cur - in->base;
+	in->base = in->buf->buffer->content;
+	in->cur = &in->buf->buffer->content[indx];
+    }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
+
+    CHECK_BUFFER(in);
+
+    return(ret);
+}
+
+/**
+ * xmlParserInputShrink:
+ * @in:  an XML parser input
+ *
+ * This function removes used input for the parser.
+ */
+void
+xmlParserInputShrink(xmlParserInputPtr in) {
+    int used;
+    int ret;
+    int indx;
+
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext, "Shrink\n");
+#endif
+    if (in == NULL) return;
+    if (in->buf == NULL) return;
+    if (in->base == NULL) return;
+    if (in->cur == NULL) return;
+    if (in->buf->buffer == NULL) return;
+
+    CHECK_BUFFER(in);
+
+    used = in->cur - in->buf->buffer->content;
+    /*
+     * Do not shrink on large buffers whose only a tiny fraction
+     * was consumed
+     */
+    if (used > INPUT_CHUNK) {
+	ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
+	if (ret > 0) {
+	    in->cur -= ret;
+	    in->consumed += ret;
+	}
+	in->end = &in->buf->buffer->content[in->buf->buffer->use];
+    }
+
+    CHECK_BUFFER(in);
+
+    if (in->buf->buffer->use > INPUT_CHUNK) {
+        return;
+    }
+    xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
+    if (in->base != in->buf->buffer->content) {
+        /*
+	 * the buffer has been reallocated
+	 */
+	indx = in->cur - in->base;
+	in->base = in->buf->buffer->content;
+	in->cur = &in->buf->buffer->content[indx];
+    }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
+
+    CHECK_BUFFER(in);
+}
+
+/************************************************************************
+ *									*
+ * 		UTF8 character input and related functions		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlNextChar:
+ * @ctxt:  the XML parser context
+ *
+ * Skip to the next char input char.
+ */
+
+void
+xmlNextChar(xmlParserCtxtPtr ctxt)
+{
+    if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
+        (ctxt->input == NULL))
+        return;
+
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+        if ((*ctxt->input->cur == 0) &&
+            (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
+            (ctxt->instate != XML_PARSER_COMMENT)) {
+            /*
+             * If we are at the end of the current entity and
+             * the context allows it, we pop consumed entities
+             * automatically.
+             * the auto closing should be blocked in other cases
+             */
+            xmlPopInput(ctxt);
+        } else {
+            const unsigned char *cur;
+            unsigned char c;
+
+            /*
+             *   2.11 End-of-Line Handling
+             *   the literal two-character sequence "#xD#xA" or a standalone
+             *   literal #xD, an XML processor must pass to the application
+             *   the single character #xA.
+             */
+            if (*(ctxt->input->cur) == '\n') {
+                ctxt->input->line++; ctxt->input->col = 1;
+            } else
+                ctxt->input->col++;
+
+            /*
+             * We are supposed to handle UTF8, check it's valid
+             * From rfc2044: encoding of the Unicode values on UTF-8:
+             *
+             * 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 
+             *
+             * Check for the 0x110000 limit too
+             */
+            cur = ctxt->input->cur;
+
+            c = *cur;
+            if (c & 0x80) {
+	        if (c == 0xC0)
+		    goto encoding_error;
+                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) {
+                        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) {
+                            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                            cur = ctxt->input->cur;
+                        }
+                        if (((c & 0xf8) != 0xf0) ||
+                            ((cur[3] & 0xc0) != 0x80))
+                            goto encoding_error;
+                        /* 4-byte code */
+                        ctxt->input->cur += 4;
+                        val = (cur[0] & 0x7) << 18;
+                        val |= (cur[1] & 0x3f) << 12;
+                        val |= (cur[2] & 0x3f) << 6;
+                        val |= cur[3] & 0x3f;
+                    } else {
+                        /* 3-byte code */
+                        ctxt->input->cur += 3;
+                        val = (cur[0] & 0xf) << 12;
+                        val |= (cur[1] & 0x3f) << 6;
+                        val |= cur[2] & 0x3f;
+                    }
+                    if (((val > 0xd7ff) && (val < 0xe000)) ||
+                        ((val > 0xfffd) && (val < 0x10000)) ||
+                        (val >= 0x110000)) {
+			xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+					  "Char 0x%X out of allowed range\n",
+					  val);
+                    }
+                } else
+                    /* 2-byte code */
+                    ctxt->input->cur += 2;
+            } else
+                /* 1-byte code */
+                ctxt->input->cur++;
+
+            ctxt->nbChars++;
+            if (*ctxt->input->cur == 0)
+                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+        }
+    } else {
+        /*
+         * Assume it's a fixed length encoding (1) with
+         * a compatible encoding for the ASCII set, since
+         * XML constructs only use < 128 chars
+         */
+
+        if (*(ctxt->input->cur) == '\n') {
+            ctxt->input->line++; ctxt->input->col = 1;
+        } else
+            ctxt->input->col++;
+        ctxt->input->cur++;
+        ctxt->nbChars++;
+        if (*ctxt->input->cur == 0)
+            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+    }
+    if ((*ctxt->input->cur == '%') && (!ctxt->html))
+        xmlParserHandlePEReference(ctxt);
+    if ((*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
+        xmlPopInput(ctxt);
+    return;
+encoding_error:
+    /*
+     * If we detect an UTF8 error that probably mean that the
+     * input encoding didn't get properly advertised in the
+     * declaration header. Report the error and switch the encoding
+     * to ISO-Latin-1 (if you don't like this policy, just declare the
+     * encoding !)
+     */
+    if ((ctxt == NULL) || (ctxt->input == NULL) ||
+        (ctxt->input->end - ctxt->input->cur < 4)) {
+	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+		     "Input is not proper UTF-8, indicate encoding !\n",
+		     NULL, NULL);
+    } else {
+        char buffer[150];
+
+	snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+		     "Input is not proper UTF-8, indicate encoding !\n%s",
+		     BAD_CAST buffer, NULL);
+    }
+    ctxt->charset = XML_CHAR_ENCODING_8859_1;
+    ctxt->input->cur++;
+    return;
+}
+
+/**
+ * xmlCurrentChar:
+ * @ctxt:  the XML parser context
+ * @len:  pointer to the length of the char read
+ *
+ * The current char value, if using UTF-8 this may actually span multiple
+ * bytes in the input buffer. Implement the end of line normalization:
+ * 2.11 End-of-Line Handling
+ * Wherever an external parsed entity or the literal entity value
+ * of an internal parsed entity contains either the literal two-character
+ * sequence "#xD#xA" or a standalone literal #xD, an XML processor
+ * must pass to the application the single character #xA.
+ * This behavior can conveniently be produced by normalizing all
+ * line breaks to #xA on input, before parsing.)
+ *
+ * Returns the current char value and its length
+ */
+
+int
+xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
+    if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
+    if (ctxt->instate == XML_PARSER_EOF)
+	return(0);
+
+    if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
+	    *len = 1;
+	    return((int) *ctxt->input->cur);
+    }
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+	/*
+	 * We are supposed to handle UTF8, check it's valid
+	 * From rfc2044: encoding of the Unicode values on UTF-8:
+	 *
+	 * 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 
+	 *
+	 * Check for the 0x110000 limit too
+	 */
+	const unsigned char *cur = ctxt->input->cur;
+	unsigned char c;
+	unsigned int val;
+
+	c = *cur;
+	if (c & 0x80) {
+	    if (((c & 0x40) == 0) || (c == 0xC0))
+		goto encoding_error;
+	    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) {
+		    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) {
+			xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                        cur = ctxt->input->cur;
+                    }
+		    if (((c & 0xf8) != 0xf0) ||
+			((cur[3] & 0xc0) != 0x80))
+			goto encoding_error;
+		    /* 4-byte code */
+		    *len = 4;
+		    val = (cur[0] & 0x7) << 18;
+		    val |= (cur[1] & 0x3f) << 12;
+		    val |= (cur[2] & 0x3f) << 6;
+		    val |= cur[3] & 0x3f;
+		    if (val < 0x10000)
+			goto encoding_error;
+		} else {
+		  /* 3-byte code */
+		    *len = 3;
+		    val = (cur[0] & 0xf) << 12;
+		    val |= (cur[1] & 0x3f) << 6;
+		    val |= cur[2] & 0x3f;
+		    if (val < 0x800)
+			goto encoding_error;
+		}
+	    } else {
+	      /* 2-byte code */
+		*len = 2;
+		val = (cur[0] & 0x1f) << 6;
+		val |= cur[1] & 0x3f;
+		if (val < 0x80)
+		    goto encoding_error;
+	    }
+	    if (!IS_CHAR(val)) {
+	        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x%X out of allowed range\n", val);
+	    }    
+	    return(val);
+	} else {
+	    /* 1-byte code */
+	    *len = 1;
+	    if (*ctxt->input->cur == 0)
+		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+	    if ((*ctxt->input->cur == 0) &&
+	        (ctxt->input->end > ctxt->input->cur)) {
+	        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x0 out of allowed range\n", 0);
+	    }
+	    if (*ctxt->input->cur == 0xD) {
+		if (ctxt->input->cur[1] == 0xA) {
+		    ctxt->nbChars++;
+		    ctxt->input->cur++;
+		}
+		return(0xA);
+	    }
+	    return((int) *ctxt->input->cur);
+	}
+    }
+    /*
+     * Assume it's a fixed length encoding (1) with
+     * a compatible encoding for the ASCII set, since
+     * XML constructs only use < 128 chars
+     */
+    *len = 1;
+    if (*ctxt->input->cur == 0xD) {
+	if (ctxt->input->cur[1] == 0xA) {
+	    ctxt->nbChars++;
+	    ctxt->input->cur++;
+	}
+	return(0xA);
+    }
+    return((int) *ctxt->input->cur);
+encoding_error:
+    /*
+     * An encoding problem may arise from a truncated input buffer
+     * splitting a character in the middle. In that case do not raise
+     * an error but return 0 to endicate an end of stream problem
+     */
+    if (ctxt->input->end - ctxt->input->cur < 4) {
+	*len = 0;
+	return(0);
+    }
+
+    /*
+     * If we detect an UTF8 error that probably mean that the
+     * input encoding didn't get properly advertised in the
+     * declaration header. Report the error and switch the encoding
+     * to ISO-Latin-1 (if you don't like this policy, just declare the
+     * encoding !)
+     */
+    {
+        char buffer[150];
+
+	snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+		     "Input is not proper UTF-8, indicate encoding !\n%s",
+		     BAD_CAST buffer, NULL);
+    }
+    ctxt->charset = XML_CHAR_ENCODING_8859_1; 
+    *len = 1;
+    return((int) *ctxt->input->cur);
+}
+
+/**
+ * xmlStringCurrentChar:
+ * @ctxt:  the XML parser context
+ * @cur:  pointer to the beginning of the char
+ * @len:  pointer to the length of the char read
+ *
+ * The current char value, if using UTF-8 this may actually span multiple
+ * bytes in the input buffer.
+ *
+ * Returns the current char value and its length
+ */
+
+int
+xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
+{
+    if ((len == NULL) || (cur == NULL)) return(0);
+    if ((ctxt == NULL) || (ctxt->charset == XML_CHAR_ENCODING_UTF8)) {
+        /*
+         * We are supposed to handle UTF8, check it's valid
+         * From rfc2044: encoding of the Unicode values on UTF-8:
+         *
+         * 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 
+         *
+         * Check for the 0x110000 limit too
+         */
+        unsigned char c;
+        unsigned int val;
+
+        c = *cur;
+        if (c & 0x80) {
+            if ((cur[1] & 0xc0) != 0x80)
+                goto encoding_error;
+            if ((c & 0xe0) == 0xe0) {
+
+                if ((cur[2] & 0xc0) != 0x80)
+                    goto encoding_error;
+                if ((c & 0xf0) == 0xf0) {
+                    if (((c & 0xf8) != 0xf0) || ((cur[3] & 0xc0) != 0x80))
+                        goto encoding_error;
+                    /* 4-byte code */
+                    *len = 4;
+                    val = (cur[0] & 0x7) << 18;
+                    val |= (cur[1] & 0x3f) << 12;
+                    val |= (cur[2] & 0x3f) << 6;
+                    val |= cur[3] & 0x3f;
+                } else {
+                    /* 3-byte code */
+                    *len = 3;
+                    val = (cur[0] & 0xf) << 12;
+                    val |= (cur[1] & 0x3f) << 6;
+                    val |= cur[2] & 0x3f;
+                }
+            } else {
+                /* 2-byte code */
+                *len = 2;
+                val = (cur[0] & 0x1f) << 6;
+                val |= cur[1] & 0x3f;
+            }
+            if (!IS_CHAR(val)) {
+	        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x%X out of allowed range\n", val);
+            }
+            return (val);
+        } else {
+            /* 1-byte code */
+            *len = 1;
+            return ((int) *cur);
+        }
+    }
+    /*
+     * Assume it's a fixed length encoding (1) with
+     * a compatible encoding for the ASCII set, since
+     * XML constructs only use < 128 chars
+     */
+    *len = 1;
+    return ((int) *cur);
+encoding_error:
+
+    /*
+     * An encoding problem may arise from a truncated input buffer
+     * splitting a character in the middle. In that case do not raise
+     * an error but return 0 to endicate an end of stream problem
+     */
+    if ((ctxt == NULL) || (ctxt->input == NULL) ||
+        (ctxt->input->end - ctxt->input->cur < 4)) {
+	*len = 0;
+	return(0);
+    }
+    /*
+     * If we detect an UTF8 error that probably mean that the
+     * input encoding didn't get properly advertised in the
+     * declaration header. Report the error and switch the encoding
+     * to ISO-Latin-1 (if you don't like this policy, just declare the
+     * encoding !)
+     */
+    {
+        char buffer[150];
+
+	snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+		     "Input is not proper UTF-8, indicate encoding !\n%s",
+		     BAD_CAST buffer, NULL);
+    }
+    *len = 1;
+    return ((int) *cur);
+}
+
+/**
+ * xmlCopyCharMultiByte:
+ * @out:  pointer to an array of xmlChar
+ * @val:  the char value
+ *
+ * append the char value in the array 
+ *
+ * Returns the number of xmlChar written
+ */
+int
+xmlCopyCharMultiByte(xmlChar *out, int val) {
+    if (out == NULL) return(0);
+    /*
+     * We are supposed to handle UTF8, check it's valid
+     * From rfc2044: encoding of the Unicode values on UTF-8:
+     *
+     * 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 
+     */
+    if  (val >= 0x80) {
+	xmlChar *savedout = out;
+	int bits;
+	if (val <   0x800) { *out++= (val >>  6) | 0xC0;  bits=  0; }
+	else if (val < 0x10000) { *out++= (val >> 12) | 0xE0;  bits=  6;}
+	else if (val < 0x110000)  { *out++= (val >> 18) | 0xF0;  bits=  12; }
+	else {
+	    xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
+		    "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
+			      val);
+	    return(0);
+	}
+	for ( ; bits >= 0; bits-= 6)
+	    *out++= ((val >> bits) & 0x3F) | 0x80 ;
+	return (out - savedout);
+    }
+    *out = (xmlChar) val;
+    return 1;
+}
+
+/**
+ * xmlCopyChar:
+ * @len:  Ignored, compatibility
+ * @out:  pointer to an array of xmlChar
+ * @val:  the char value
+ *
+ * append the char value in the array 
+ *
+ * Returns the number of xmlChar written
+ */
+
+int
+xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
+    if (out == NULL) return(0);
+    /* the len parameter is ignored */
+    if  (val >= 0x80) {
+	return(xmlCopyCharMultiByte (out, val));
+    }
+    *out = (xmlChar) val;
+    return 1;
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions to switch encodings			*
+ *									*
+ ************************************************************************/
+
+/* 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
+ * @enc:  the encoding value (number)
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+int
+xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
+{
+    xmlCharEncodingHandlerPtr handler;
+    int len = -1;
+
+    if (ctxt == NULL) return(-1);
+    switch (enc) {
+	case XML_CHAR_ENCODING_ERROR:
+	    __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
+	                   "encoding unknown\n", NULL, NULL);
+	    return(-1);
+	case XML_CHAR_ENCODING_NONE:
+	    /* let's assume it's UTF-8 without the XML decl */
+	    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+	    return(0);
+	case XML_CHAR_ENCODING_UTF8:
+	    /* default encoding, no conversion should be needed */
+	    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+
+	    /*
+	     * Errata on XML-1.0 June 20 2001
+	     * Specific handling of the Byte Order Mark for
+	     * UTF-8
+	     */
+	    if ((ctxt->input != NULL) &&
+		(ctxt->input->cur[0] == 0xEF) &&
+		(ctxt->input->cur[1] == 0xBB) &&
+		(ctxt->input->cur[2] == 0xBF)) {
+		ctxt->input->cur += 3;
+	    }
+	    return(0);
+    case XML_CHAR_ENCODING_UTF16LE:
+    case XML_CHAR_ENCODING_UTF16BE:
+        /*The raw input characters are encoded
+         *in UTF-16. As we expect this function
+         *to be called after xmlCharEncInFunc, we expect
+         *ctxt->input->cur to contain UTF-8 encoded characters.
+         *So the raw UTF16 Byte Order Mark
+         *has also been converted into
+         *an UTF-8 BOM. Let's skip that BOM.
+         */
+        if ((ctxt->input != NULL) && (ctxt->input->cur != NULL) &&
+            (ctxt->input->cur[0] == 0xEF) &&
+            (ctxt->input->cur[1] == 0xBB) &&
+            (ctxt->input->cur[2] == 0xBF)) {
+            ctxt->input->cur += 3;
+        }
+        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) {
+	/*
+	 * Default handlers.
+	 */
+	switch (enc) {
+	    case XML_CHAR_ENCODING_ASCII:
+		/* default encoding, no conversion should be needed */
+		ctxt->charset = XML_CHAR_ENCODING_UTF8;
+		return(0);
+	    case XML_CHAR_ENCODING_UTF16LE:
+		break;
+	    case XML_CHAR_ENCODING_UTF16BE:
+		break;
+	    case XML_CHAR_ENCODING_UCS4LE:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "USC4 little endian", NULL);
+		break;
+	    case XML_CHAR_ENCODING_UCS4BE:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "USC4 big endian", NULL);
+		break;
+	    case XML_CHAR_ENCODING_EBCDIC:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "EBCDIC", NULL);
+		break;
+	    case XML_CHAR_ENCODING_UCS4_2143:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "UCS4 2143", NULL);
+		break;
+	    case XML_CHAR_ENCODING_UCS4_3412:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "UCS4 3412", NULL);
+		break;
+	    case XML_CHAR_ENCODING_UCS2:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "UCS2", NULL);
+		break;
+	    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:
+		/*
+		 * We used to keep the internal content in the
+		 * document encoding however this turns being unmaintainable
+		 * So xmlGetCharEncodingHandler() will return non-null
+		 * values for this now.
+		 */
+		if ((ctxt->inputNr == 1) &&
+		    (ctxt->encoding == NULL) &&
+		    (ctxt->input != NULL) &&
+		    (ctxt->input->encoding != NULL)) {
+		    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
+		}
+		ctxt->charset = enc;
+		return(0);
+	    case XML_CHAR_ENCODING_2022_JP:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "ISO-2022-JP", NULL);
+		break;
+	    case XML_CHAR_ENCODING_SHIFT_JIS:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "Shift_JIS", NULL);
+		break;
+	    case XML_CHAR_ENCODING_EUC_JP:
+		__xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+			       "encoding not supported %s\n",
+			       BAD_CAST "EUC-JP", NULL);
+		break;
+	    default:
+	        break;
+	}
+    }
+    if (handler == NULL)
+	return(-1);
+    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    return(xmlSwitchToEncodingInt(ctxt, handler, len));
+}
+
+/**
+ * xmlSwitchInputEncoding:
+ * @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
+ */
+static int
+xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+                          xmlCharEncodingHandlerPtr handler, int len)
+{
+    int nbchars;
+
+    if (handler == NULL)
+        return (-1);
+    if (input == NULL)
+        return (-1);
+    if (input->buf != NULL) {
+        if (input->buf->encoder != NULL) {
+            /*
+             * Check in case the auto encoding detetection triggered
+             * in already.
+             */
+            if (input->buf->encoder == handler)
+                return (0);
+
+            /*
+             * "UTF-16" can be used for both LE and BE
+             if ((!xmlStrncmp(BAD_CAST input->buf->encoder->name,
+             BAD_CAST "UTF-16", 6)) &&
+             (!xmlStrncmp(BAD_CAST handler->name,
+             BAD_CAST "UTF-16", 6))) {
+             return(0);
+             }
+             */
+
+            /*
+             * Note: this is a bit dangerous, but that's what it
+             * takes to use nearly compatible signature for different
+             * encodings.
+             */
+            xmlCharEncCloseFunc(input->buf->encoder);
+            input->buf->encoder = handler;
+            return (0);
+        }
+        input->buf->encoder = handler;
+
+        /*
+         * Is there already some content down the pipe to convert ?
+         */
+        if ((input->buf->buffer != NULL) && (input->buf->buffer->use > 0)) {
+            int processed;
+	    unsigned int use;
+
+            /*
+             * Specific handling of the Byte Order Mark for 
+             * UTF-16
+             */
+            if ((handler->name != NULL) &&
+                (!strcmp(handler->name, "UTF-16LE") ||
+                 !strcmp(handler->name, "UTF-16")) &&
+                (input->cur[0] == 0xFF) && (input->cur[1] == 0xFE)) {
+                input->cur += 2;
+            }
+            if ((handler->name != NULL) &&
+                (!strcmp(handler->name, "UTF-16BE")) &&
+                (input->cur[0] == 0xFE) && (input->cur[1] == 0xFF)) {
+                input->cur += 2;
+            }
+            /*
+             * Errata on XML-1.0 June 20 2001
+             * Specific handling of the Byte Order Mark for
+             * UTF-8
+             */
+            if ((handler->name != NULL) &&
+                (!strcmp(handler->name, "UTF-8")) &&
+                (input->cur[0] == 0xEF) &&
+                (input->cur[1] == 0xBB) && (input->cur[2] == 0xBF)) {
+                input->cur += 3;
+            }
+
+            /*
+             * Shrink the current input buffer.
+             * Move it as the raw buffer and create a new input buffer
+             */
+            processed = input->cur - input->base;
+            xmlBufferShrink(input->buf->buffer, processed);
+            input->buf->raw = input->buf->buffer;
+            input->buf->buffer = xmlBufferCreate();
+	    input->buf->rawconsumed = processed;
+	    use = input->buf->raw->use;
+
+            if (ctxt->html) {
+                /*
+                 * convert as much as possible of the buffer
+                 */
+                nbchars = xmlCharEncInFunc(input->buf->encoder,
+                                           input->buf->buffer,
+                                           input->buf->raw);
+            } else {
+                /*
+                 * convert just enough to get
+                 * '<?xml version="1.0" encoding="xxx"?>'
+                 * parsed with the autodetected encoding
+                 * into the parser reading buffer.
+                 */
+                nbchars = xmlCharEncFirstLineInt(input->buf->encoder,
+                                                 input->buf->buffer,
+                                                 input->buf->raw,
+                                                 len);
+            }
+            if (nbchars < 0) {
+                xmlErrInternal(ctxt,
+                               "switching encoding: encoder error\n",
+                               NULL);
+                return (-1);
+            }
+	    input->buf->rawconsumed += use - input->buf->raw->use;
+            input->base = input->cur = input->buf->buffer->content;
+            input->end = &input->base[input->buf->buffer->use];
+
+        }
+        return (0);
+    } else if (input->length == 0) {
+	/*
+	 * When parsing a static memory array one must know the
+	 * size to be able to convert the buffer.
+	 */
+	xmlErrInternal(ctxt, "switching encoding : no input\n", NULL);
+	return (-1);
+    }
+    return (0);
+}
+
+/**
+ * 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
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+int
+xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler) 
+{
+    return (xmlSwitchToEncodingInt(ctxt, handler, -1));
+}
+
+/************************************************************************
+ *									*
+ *	Commodity functions to handle entities processing		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlFreeInputStream:
+ * @input:  an xmlParserInputPtr
+ *
+ * Free up an input stream.
+ */
+void
+xmlFreeInputStream(xmlParserInputPtr input) {
+    if (input == NULL) return;
+
+    if (input->filename != NULL) xmlFree((char *) input->filename);
+    if (input->directory != NULL) xmlFree((char *) input->directory);
+    if (input->encoding != NULL) xmlFree((char *) input->encoding);
+    if (input->version != NULL) xmlFree((char *) input->version);
+    if ((input->free != NULL) && (input->base != NULL))
+        input->free((xmlChar *) input->base);
+    if (input->buf != NULL) 
+        xmlFreeParserInputBuffer(input->buf);
+    xmlFree(input);
+}
+
+/**
+ * xmlNewInputStream:
+ * @ctxt:  an XML parser context
+ *
+ * Create a new input stream structure
+ * Returns the new input stream or NULL
+ */
+xmlParserInputPtr
+xmlNewInputStream(xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr input;
+    static int id = 0;
+
+    input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
+    if (input == NULL) {
+        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
+	return(NULL);
+    }
+    memset(input, 0, sizeof(xmlParserInput));
+    input->line = 1;
+    input->col = 1;
+    input->standalone = -1;
+    /*
+     * we don't care about thread reentrancy unicity for a single
+     * parser context (and hence thread) is sufficient.
+     */
+    input->id = id++;
+    return(input);
+}
+
+/**
+ * xmlNewIOInputStream:
+ * @ctxt:  an XML parser context
+ * @input:  an I/O Input
+ * @enc:  the charset encoding if known
+ *
+ * Create a new input stream structure encapsulating the @input into
+ * a stream suitable for the parser.
+ *
+ * Returns the new input stream or NULL
+ */
+xmlParserInputPtr
+xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
+	            xmlCharEncoding enc) {
+    xmlParserInputPtr inputStream;
+
+    if (input == NULL) return(NULL);
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
+    inputStream = xmlNewInputStream(ctxt);
+    if (inputStream == NULL) {
+	return(NULL);
+    }
+    inputStream->filename = NULL;
+    inputStream->buf = input;
+    inputStream->base = inputStream->buf->buffer->content;
+    inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
+    if (enc != XML_CHAR_ENCODING_NONE) {
+        xmlSwitchEncoding(ctxt, enc);
+    }
+
+    return(inputStream);
+}
+
+/**
+ * xmlNewEntityInputStream:
+ * @ctxt:  an XML parser context
+ * @entity:  an Entity pointer
+ *
+ * Create a new input stream based on an xmlEntityPtr
+ *
+ * Returns the new input stream or NULL
+ */
+xmlParserInputPtr
+xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+    xmlParserInputPtr input;
+
+    if (entity == NULL) {
+        xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
+	               NULL);
+	return(NULL);
+    }
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"new input from entity: %s\n", entity->name);
+    if (entity->content == NULL) {
+	switch (entity->etype) {
+            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	        xmlErrInternal(ctxt, "Cannot parse entity %s\n",
+		               entity->name);
+                break;
+            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+            case XML_EXTERNAL_PARAMETER_ENTITY:
+		return(xmlLoadExternalEntity((char *) entity->URI,
+		       (char *) entity->ExternalID, ctxt));
+            case XML_INTERNAL_GENERAL_ENTITY:
+	        xmlErrInternal(ctxt,
+		      "Internal entity %s without content !\n",
+		               entity->name);
+                break;
+            case XML_INTERNAL_PARAMETER_ENTITY:
+	        xmlErrInternal(ctxt,
+		      "Internal parameter entity %s without content !\n",
+		               entity->name);
+                break;
+            case XML_INTERNAL_PREDEFINED_ENTITY:
+	        xmlErrInternal(ctxt,
+		      "Predefined entity %s without content !\n",
+		               entity->name);
+                break;
+	}
+	return(NULL);
+    }
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+	return(NULL);
+    }
+    if (entity->URI != NULL)
+	input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
+    input->base = entity->content;
+    input->cur = entity->content;
+    input->length = entity->length;
+    input->end = &entity->content[input->length];
+    return(input);
+}
+
+/**
+ * xmlNewStringInputStream:
+ * @ctxt:  an XML parser context
+ * @buffer:  an memory buffer
+ *
+ * Create a new input stream based on a memory buffer.
+ * Returns the new input stream
+ */
+xmlParserInputPtr
+xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
+    xmlParserInputPtr input;
+
+    if (buffer == NULL) {
+        xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
+	               NULL);
+	return(NULL);
+    }
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"new fixed input: %.30s\n", buffer);
+    input = xmlNewInputStream(ctxt);
+    if (input == NULL) {
+        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
+	return(NULL);
+    }
+    input->base = buffer;
+    input->cur = buffer;
+    input->length = xmlStrlen(buffer);
+    input->end = &buffer[input->length];
+    return(input);
+}
+
+/**
+ * xmlNewInputFromFile:
+ * @ctxt:  an XML parser context
+ * @filename:  the filename to use as entity
+ *
+ * Create a new input stream based on a file or an URL.
+ *
+ * Returns the new input stream or NULL in case of error
+ */
+xmlParserInputPtr
+xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
+    xmlParserInputBufferPtr buf;
+    xmlParserInputPtr inputStream;
+    char *directory = NULL;
+    xmlChar *URI = NULL;
+
+    if (xmlParserDebugEntities)
+	xmlGenericError(xmlGenericErrorContext,
+		"new input from file: %s\n", filename);
+    if (ctxt == NULL) return(NULL);
+    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) {
+	if (filename == NULL)
+	    __xmlLoaderErr(ctxt,
+	                   "failed to load external entity: NULL filename \n",
+			   NULL);
+	else
+	    __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
+			   (const char *) filename);
+	return(NULL);
+    }
+
+    inputStream = xmlNewInputStream(ctxt);
+    if (inputStream == NULL)
+	return(NULL);
+
+    inputStream->buf = buf;
+    inputStream = xmlCheckHTTPInput(ctxt, inputStream);
+    if (inputStream == NULL)
+        return(NULL);
+    
+    if (inputStream->filename == NULL)
+	URI = xmlStrdup((xmlChar *) filename);
+    else
+	URI = xmlStrdup((xmlChar *) inputStream->filename);
+    directory = xmlParserGetDirectory((const char *) URI);
+    if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
+    inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
+    if (URI != NULL) xmlFree((char *) URI);
+    inputStream->directory = directory;
+
+    inputStream->base = inputStream->buf->buffer->content;
+    inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
+    if ((ctxt->directory == NULL) && (directory != NULL))
+        ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
+    return(inputStream);
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions to handle parser contexts		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlInitParserCtxt:
+ * @ctxt:  an XML parser context
+ *
+ * Initialize a parser context
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+
+int
+xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr input;
+
+    if(ctxt==NULL) {
+        xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
+        return(-1);
+    }
+
+    xmlDefaultSAXHandlerInit();
+
+    if (ctxt->dict == NULL)
+	ctxt->dict = xmlDictCreate();
+    if (ctxt->dict == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	return(-1);
+    }
+    if (ctxt->sax == NULL)
+	ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
+    if (ctxt->sax == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	return(-1);
+    }
+    else
+        xmlSAXVersion(ctxt->sax, 2);
+
+    ctxt->maxatts = 0;
+    ctxt->atts = NULL;
+    /* Allocate the Input stack */
+    if (ctxt->inputTab == NULL) {
+	ctxt->inputTab = (xmlParserInputPtr *)
+		    xmlMalloc(5 * sizeof(xmlParserInputPtr));
+	ctxt->inputMax = 5;
+    }
+    if (ctxt->inputTab == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return(-1);
+    }
+    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
+        xmlFreeInputStream(input);
+    }
+    ctxt->inputNr = 0;
+    ctxt->input = NULL;
+
+    ctxt->version = NULL;
+    ctxt->encoding = NULL;
+    ctxt->standalone = -1;
+    ctxt->hasExternalSubset = 0;
+    ctxt->hasPErefs = 0;
+    ctxt->html = 0;
+    ctxt->external = 0;
+    ctxt->instate = XML_PARSER_START;
+    ctxt->token = 0;
+    ctxt->directory = NULL;
+
+    /* Allocate the Node stack */
+    if (ctxt->nodeTab == NULL) {
+	ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
+	ctxt->nodeMax = 10;
+    }
+    if (ctxt->nodeTab == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return(-1);
+    }
+    ctxt->nodeNr = 0;
+    ctxt->node = NULL;
+
+    /* Allocate the Name stack */
+    if (ctxt->nameTab == NULL) {
+	ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
+	ctxt->nameMax = 10;
+    }
+    if (ctxt->nameTab == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 0;
+	ctxt->name = NULL;
+	return(-1);
+    }
+    ctxt->nameNr = 0;
+    ctxt->name = NULL;
+
+    /* Allocate the space stack */
+    if (ctxt->spaceTab == NULL) {
+	ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
+	ctxt->spaceMax = 10;
+    }
+    if (ctxt->spaceTab == NULL) {
+        xmlErrMemory(NULL, "cannot initialize parser context\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 0;
+	ctxt->name = NULL;
+	ctxt->spaceNr = 0;
+	ctxt->spaceMax = 0;
+	ctxt->space = NULL;
+	return(-1);
+    }
+    ctxt->spaceNr = 1;
+    ctxt->spaceMax = 10;
+    ctxt->spaceTab[0] = -1;
+    ctxt->space = &ctxt->spaceTab[0];
+    ctxt->userData = ctxt;
+    ctxt->myDoc = NULL;
+    ctxt->wellFormed = 1;
+    ctxt->nsWellFormed = 1;
+    ctxt->valid = 1;
+    ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
+    ctxt->validate = xmlDoValidityCheckingDefaultValue;
+    ctxt->pedantic = xmlPedanticParserDefaultValue;
+    ctxt->linenumbers = xmlLineNumbersDefaultValue;
+    ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
+    if (ctxt->keepBlanks == 0)
+	ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+
+    ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
+    ctxt->vctxt.userData = ctxt;
+    ctxt->vctxt.error = xmlParserValidityError;
+    ctxt->vctxt.warning = xmlParserValidityWarning;
+    if (ctxt->validate) {
+	if (xmlGetWarningsDefaultValue == 0)
+	    ctxt->vctxt.warning = NULL;
+	else
+	    ctxt->vctxt.warning = xmlParserValidityWarning;
+	ctxt->vctxt.nodeMax = 0;
+    }
+    ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
+    ctxt->record_info = 0;
+    ctxt->nbChars = 0;
+    ctxt->checkIndex = 0;
+    ctxt->inSubset = 0;
+    ctxt->errNo = XML_ERR_OK;
+    ctxt->depth = 0;
+    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    ctxt->catalogs = NULL;
+    ctxt->nbentities = 0;
+    xmlInitNodeInfoSeq(&ctxt->node_seq);
+    return(0);
+}
+
+/**
+ * xmlFreeParserCtxt:
+ * @ctxt:  an XML parser context
+ *
+ * Free all the memory used by a parser context. However the parsed
+ * document in ctxt->myDoc is not freed.
+ */
+
+void
+xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr input;
+
+    if (ctxt == NULL) return;
+
+    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
+        xmlFreeInputStream(input);
+    }
+    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);
+    if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
+    if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
+#ifdef LIBXML_SAX1_ENABLED
+    if ((ctxt->sax != NULL) &&
+        (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
+#else
+    if (ctxt->sax != NULL)
+#endif /* LIBXML_SAX1_ENABLED */
+        xmlFree(ctxt->sax);
+    if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
+    if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
+    if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
+    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
+    if (ctxt->nsTab != NULL) xmlFree((char *) ctxt->nsTab);
+    if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
+    if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
+    if (ctxt->attsDefault != NULL) 
+        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
+    if (ctxt->attsSpecial != NULL)
+        xmlHashFree(ctxt->attsSpecial, NULL);
+    if (ctxt->freeElems != NULL) {
+        xmlNodePtr cur, next;
+
+	cur = ctxt->freeElems;
+	while (cur != NULL) {
+	    next = cur->next;
+	    xmlFree(cur);
+	    cur = next;
+	}
+    }
+    if (ctxt->freeAttrs != NULL) {
+        xmlAttrPtr cur, next;
+
+	cur = ctxt->freeAttrs;
+	while (cur != NULL) {
+	    next = cur->next;
+	    xmlFree(cur);
+	    cur = next;
+	}
+    }
+    /*
+     * cleanup the error strings
+     */
+    if (ctxt->lastError.message != NULL)
+        xmlFree(ctxt->lastError.message);
+    if (ctxt->lastError.file != NULL)
+        xmlFree(ctxt->lastError.file);
+    if (ctxt->lastError.str1 != NULL)
+        xmlFree(ctxt->lastError.str1);
+    if (ctxt->lastError.str2 != NULL)
+        xmlFree(ctxt->lastError.str2);
+    if (ctxt->lastError.str3 != NULL)
+        xmlFree(ctxt->lastError.str3);
+
+#ifdef LIBXML_CATALOG_ENABLED
+    if (ctxt->catalogs != NULL)
+	xmlCatalogFreeLocal(ctxt->catalogs);
+#endif
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlNewParserCtxt:
+ *
+ * Allocate and initialize a new parser context.
+ *
+ * Returns the xmlParserCtxtPtr or NULL
+ */
+
+xmlParserCtxtPtr
+xmlNewParserCtxt(void)
+{
+    xmlParserCtxtPtr ctxt;
+
+    ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
+    if (ctxt == NULL) {
+	xmlErrMemory(NULL, "cannot allocate parser context\n");
+	return(NULL);
+    }
+    memset(ctxt, 0, sizeof(xmlParserCtxt));
+    if (xmlInitParserCtxt(ctxt) < 0) {
+        xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    return(ctxt);
+}
+
+/************************************************************************
+ *									*
+ *		Handling of node informations				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlClearParserCtxt:
+ * @ctxt:  an XML parser context
+ *
+ * Clear (release owned resources) and reinitialize a parser context
+ */
+
+void
+xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
+{
+  if (ctxt==NULL)
+    return;
+  xmlClearNodeInfoSeq(&ctxt->node_seq);
+  xmlCtxtReset(ctxt);
+}
+
+
+/**
+ * xmlParserFindNodeInfo:
+ * @ctx:  an XML parser context
+ * @node:  an XML node within the tree
+ *
+ * Find the parser node info struct for a given node
+ * 
+ * Returns an xmlParserNodeInfo block pointer or NULL
+ */
+const xmlParserNodeInfo *
+xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
+{
+    unsigned long pos;
+
+    if ((ctx == NULL) || (node == NULL))
+        return (NULL);
+    /* Find position where node should be at */
+    pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
+    if (pos < ctx->node_seq.length
+        && ctx->node_seq.buffer[pos].node == node)
+        return &ctx->node_seq.buffer[pos];
+    else
+        return NULL;
+}
+
+
+/**
+ * xmlInitNodeInfoSeq:
+ * @seq:  a node info sequence pointer
+ *
+ * -- Initialize (set to initial state) node info sequence
+ */
+void
+xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+    if (seq == NULL)
+        return;
+    seq->length = 0;
+    seq->maximum = 0;
+    seq->buffer = NULL;
+}
+
+/**
+ * xmlClearNodeInfoSeq:
+ * @seq:  a node info sequence pointer
+ *
+ * -- Clear (release memory and reinitialize) node
+ *   info sequence
+ */
+void
+xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+    if (seq == NULL)
+        return;
+    if (seq->buffer != NULL)
+        xmlFree(seq->buffer);
+    xmlInitNodeInfoSeq(seq);
+}
+
+/**
+ * xmlParserFindNodeInfoIndex:
+ * @seq:  a node info sequence pointer
+ * @node:  an XML node pointer
+ *
+ * 
+ * xmlParserFindNodeInfoIndex : Find the index that the info record for
+ *   the given node is or should be at in a sorted sequence
+ *
+ * Returns a long indicating the position of the record
+ */
+unsigned long
+xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
+                           const xmlNodePtr node)
+{
+    unsigned long upper, lower, middle;
+    int found = 0;
+
+    if ((seq == NULL) || (node == NULL))
+        return ((unsigned long) -1);
+
+    /* Do a binary search for the key */
+    lower = 1;
+    upper = seq->length;
+    middle = 0;
+    while (lower <= upper && !found) {
+        middle = lower + (upper - lower) / 2;
+        if (node == seq->buffer[middle - 1].node)
+            found = 1;
+        else if (node < seq->buffer[middle - 1].node)
+            upper = middle - 1;
+        else
+            lower = middle + 1;
+    }
+
+    /* Return position */
+    if (middle == 0 || seq->buffer[middle - 1].node < node)
+        return middle;
+    else
+        return middle - 1;
+}
+
+
+/**
+ * xmlParserAddNodeInfo:
+ * @ctxt:  an XML parser context
+ * @info:  a node info sequence pointer
+ *
+ * Insert node info record into the sorted sequence
+ */
+void
+xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
+                     const xmlParserNodeInfoPtr info)
+{
+    unsigned long pos;
+
+    if ((ctxt == NULL) || (info == NULL)) return;
+
+    /* Find pos and check to see if node is already in the sequence */
+    pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
+                                     info->node);
+
+    if ((pos < ctxt->node_seq.length) && 
+        (ctxt->node_seq.buffer != NULL) &&
+        (ctxt->node_seq.buffer[pos].node == info->node)) {
+        ctxt->node_seq.buffer[pos] = *info;
+    }
+
+    /* Otherwise, we need to add new node to buffer */
+    else {
+        if (ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) {
+            xmlParserNodeInfo *tmp_buffer;
+            unsigned int byte_size;
+
+            if (ctxt->node_seq.maximum == 0)
+                ctxt->node_seq.maximum = 2;
+            byte_size = (sizeof(*ctxt->node_seq.buffer) *
+			(2 * ctxt->node_seq.maximum));
+
+            if (ctxt->node_seq.buffer == NULL)
+                tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
+            else
+                tmp_buffer =
+                    (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
+                                                     byte_size);
+
+            if (tmp_buffer == NULL) {
+		xmlErrMemory(ctxt, "failed to allocate buffer\n");
+                return;
+            }
+            ctxt->node_seq.buffer = tmp_buffer;
+            ctxt->node_seq.maximum *= 2;
+        }
+
+        /* If position is not at end, move elements out of the way */
+        if (pos != ctxt->node_seq.length) {
+            unsigned long i;
+
+            for (i = ctxt->node_seq.length; i > pos; i--)
+                ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
+        }
+
+        /* Copy element and increase length */
+        ctxt->node_seq.buffer[pos] = *info;
+        ctxt->node_seq.length++;
+    }
+}
+
+/************************************************************************
+ *									*
+ *		Defaults settings					*
+ *									*
+ ************************************************************************/
+/**
+ * xmlPedanticParserDefault:
+ * @val:  int 0 or 1 
+ *
+ * Set and return the previous value for enabling pedantic warnings.
+ *
+ * Returns the last value for 0 for no substitution, 1 for substitution.
+ */
+
+int
+xmlPedanticParserDefault(int val) {
+    int old = xmlPedanticParserDefaultValue;
+
+    xmlPedanticParserDefaultValue = val;
+    return(old);
+}
+
+/**
+ * xmlLineNumbersDefault:
+ * @val:  int 0 or 1 
+ *
+ * Set and return the previous value for enabling line numbers in elements
+ * contents. This may break on old application and is turned off by default.
+ *
+ * Returns the last value for 0 for no substitution, 1 for substitution.
+ */
+
+int
+xmlLineNumbersDefault(int val) {
+    int old = xmlLineNumbersDefaultValue;
+
+    xmlLineNumbersDefaultValue = val;
+    return(old);
+}
+
+/**
+ * xmlSubstituteEntitiesDefault:
+ * @val:  int 0 or 1 
+ *
+ * Set and return the previous value for default entity support.
+ * Initially the parser always keep entity references instead of substituting
+ * entity values in the output. This function has to be used to change the
+ * default parser behavior
+ * SAX::substituteEntities() has to be used for changing that on a file by
+ * file basis.
+ *
+ * Returns the last value for 0 for no substitution, 1 for substitution.
+ */
+
+int
+xmlSubstituteEntitiesDefault(int val) {
+    int old = xmlSubstituteEntitiesDefaultValue;
+
+    xmlSubstituteEntitiesDefaultValue = val;
+    return(old);
+}
+
+/**
+ * xmlKeepBlanksDefault:
+ * @val:  int 0 or 1 
+ *
+ * Set and return the previous value for default blanks text nodes support.
+ * The 1.x version of the parser used an heuristic to try to detect
+ * ignorable white spaces. As a result the SAX callback was generating
+ * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
+ * using the DOM output text nodes containing those blanks were not generated.
+ * The 2.x and later version will switch to the XML standard way and
+ * ignorableWhitespace() are only generated when running the parser in
+ * validating mode and when the current element doesn't allow CDATA or
+ * mixed content.
+ * This function is provided as a way to force the standard behavior 
+ * on 1.X libs and to switch back to the old mode for compatibility when
+ * running 1.X client code on 2.X . Upgrade of 1.X code should be done
+ * by using xmlIsBlankNode() commodity function to detect the "empty"
+ * nodes generated.
+ * This value also affect autogeneration of indentation when saving code
+ * if blanks sections are kept, indentation is not generated.
+ *
+ * Returns the last value for 0 for no substitution, 1 for substitution.
+ */
+
+int
+xmlKeepBlanksDefault(int val) {
+    int old = xmlKeepBlanksDefaultValue;
+
+    xmlKeepBlanksDefaultValue = val;
+    if (!val) xmlIndentTreeOutput = 1;
+    return(old);
+}
+
+#define bottom_parserInternals
+#include "elfgcchack.h"
diff --git a/src/pattern.c b/src/pattern.c
new file mode 100644
index 0000000..0e38c2d
--- /dev/null
+++ b/src/pattern.c
@@ -0,0 +1,2613 @@
+/*
+ * pattern.c: Implemetation of selectors for nodes
+ *
+ * Reference:
+ *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
+ *   to some extent 
+ *   http://www.w3.org/TR/1999/REC-xml-19991116
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+/*
+ * TODO:
+ * - compilation flags to check for specific syntaxes
+ *   using flags of xmlPatterncompile()
+ * - making clear how pattern starting with / or . need to be handled,
+ *   currently push(NULL, NULL) means a reset of the streaming context
+ *   and indicating we are on / (the document node), probably need
+ *   something similar for .
+ * - get rid of the "compile" starting with lowercase
+ * - DONE (2006-05-16): get rid of the Strdup/Strndup in case of dictionary
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/hash.h>
+#include <libxml/dict.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parserInternals.h>
+#include <libxml/pattern.h>
+
+#ifdef LIBXML_PATTERN_ENABLED
+
+/* #define DEBUG_STREAMING */
+
+#define ERROR(a, b, c, d)
+#define ERROR5(a, b, c, d, e)
+
+#define XML_STREAM_STEP_DESC	1
+#define XML_STREAM_STEP_FINAL	2
+#define XML_STREAM_STEP_ROOT	4
+#define XML_STREAM_STEP_ATTR	8
+#define XML_STREAM_STEP_NODE	16
+#define XML_STREAM_STEP_IN_SET	32
+
+/*
+* NOTE: Those private flags (XML_STREAM_xxx) are used
+*   in _xmlStreamCtxt->flag. They extend the public
+*   xmlPatternFlags, so be carefull not to interfere with the
+*   reserved values for xmlPatternFlags. 
+*/
+#define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
+#define XML_STREAM_FROM_ROOT 1<<15
+#define XML_STREAM_DESC 1<<16
+
+/*
+* XML_STREAM_ANY_NODE is used for comparison against
+* xmlElementType enums, to indicate a node of any type.
+*/
+#define XML_STREAM_ANY_NODE 100
+
+#define XML_PATTERN_NOTPATTERN  (XML_PATTERN_XPATH | \
+				 XML_PATTERN_XSSEL | \
+				 XML_PATTERN_XSFIELD)
+
+#define XML_STREAM_XS_IDC(c) ((c)->flags & \
+    (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))
+
+#define XML_STREAM_XS_IDC_SEL(c) ((c)->flags & XML_PATTERN_XSSEL)
+
+#define XML_STREAM_XS_IDC_FIELD(c) ((c)->flags & XML_PATTERN_XSFIELD)
+
+#define XML_PAT_COPY_NSNAME(c, r, nsname) \
+    if ((c)->comp->dict) \
+	r = (xmlChar *) xmlDictLookup((c)->comp->dict, BAD_CAST nsname, -1); \
+    else r = xmlStrdup(BAD_CAST nsname);
+
+#define XML_PAT_FREE_STRING(c, r) if ((c)->comp->dict == NULL) xmlFree(r);
+
+typedef struct _xmlStreamStep xmlStreamStep;
+typedef xmlStreamStep *xmlStreamStepPtr;
+struct _xmlStreamStep {
+    int flags;			/* properties of that step */
+    const xmlChar *name;	/* first string value if NULL accept all */
+    const xmlChar *ns;		/* second string value */
+    int nodeType;		/* type of node */
+};
+
+typedef struct _xmlStreamComp xmlStreamComp;
+typedef xmlStreamComp *xmlStreamCompPtr;
+struct _xmlStreamComp {
+    xmlDict *dict;		/* the dictionary if any */
+    int nbStep;			/* number of steps in the automata */
+    int maxStep;		/* allocated number of steps */
+    xmlStreamStepPtr steps;	/* the array of steps */
+    int flags;
+};
+
+struct _xmlStreamCtxt {
+    struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
+    xmlStreamCompPtr comp;	/* the compiled stream */
+    int nbState;		/* number of states in the automata */
+    int maxState;		/* allocated number of states */
+    int level;			/* how deep are we ? */
+    int *states;		/* the array of step indexes */
+    int flags;			/* validation options */
+    int blockLevel;
+};
+
+static void xmlFreeStreamComp(xmlStreamCompPtr comp);
+
+/*
+ * Types are private:
+ */
+
+typedef enum {
+    XML_OP_END=0,
+    XML_OP_ROOT,
+    XML_OP_ELEM,
+    XML_OP_CHILD,
+    XML_OP_ATTR,
+    XML_OP_PARENT,
+    XML_OP_ANCESTOR,
+    XML_OP_NS,
+    XML_OP_ALL
+} xmlPatOp;
+
+
+typedef struct _xmlStepState xmlStepState;
+typedef xmlStepState *xmlStepStatePtr;
+struct _xmlStepState {
+    int step;
+    xmlNodePtr node;
+};
+
+typedef struct _xmlStepStates xmlStepStates;
+typedef xmlStepStates *xmlStepStatesPtr;
+struct _xmlStepStates {
+    int nbstates;
+    int maxstates;
+    xmlStepStatePtr states;
+};
+
+typedef struct _xmlStepOp xmlStepOp;
+typedef xmlStepOp *xmlStepOpPtr;
+struct _xmlStepOp {
+    xmlPatOp op;
+    const xmlChar *value;
+    const xmlChar *value2; /* The namespace name */
+};
+
+#define PAT_FROM_ROOT	(1<<8)
+#define PAT_FROM_CUR	(1<<9)
+
+struct _xmlPattern {
+    void *data;    		/* the associated template */
+    xmlDictPtr dict;		/* the optional dictionary */
+    struct _xmlPattern *next;	/* next pattern if | is used */
+    const xmlChar *pattern;	/* the pattern */
+    int flags;			/* flags */
+    int nbStep;
+    int maxStep;
+    xmlStepOpPtr steps;        /* ops for computation */
+    xmlStreamCompPtr stream;	/* the streaming data if any */
+};
+
+typedef struct _xmlPatParserContext xmlPatParserContext;
+typedef xmlPatParserContext *xmlPatParserContextPtr;
+struct _xmlPatParserContext {
+    const xmlChar *cur;			/* the current char being parsed */
+    const xmlChar *base;		/* the full expression */
+    int	           error;		/* error code */
+    xmlDictPtr     dict;		/* the dictionary if any */
+    xmlPatternPtr  comp;		/* the result */
+    xmlNodePtr     elem;		/* the current node if any */    
+    const xmlChar **namespaces;		/* the namespaces definitions */
+    int   nb_namespaces;		/* the number of namespaces */
+};
+
+/************************************************************************
+ * 									*
+ * 			Type functions 					*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlNewPattern:
+ *
+ * Create a new XSLT Pattern
+ *
+ * Returns the newly allocated xmlPatternPtr or NULL in case of error
+ */
+static xmlPatternPtr
+xmlNewPattern(void) {
+    xmlPatternPtr cur;
+
+    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
+    if (cur == NULL) {
+	ERROR(NULL, NULL, NULL,
+		"xmlNewPattern : malloc failed\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlPattern));
+    cur->maxStep = 10;
+    cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
+    if (cur->steps == NULL) {
+        xmlFree(cur);
+	ERROR(NULL, NULL, NULL,
+		"xmlNewPattern : malloc failed\n");
+	return(NULL);
+    }
+    return(cur);
+}
+
+/**
+ * xmlFreePattern:
+ * @comp:  an XSLT comp
+ *
+ * Free up the memory allocated by @comp
+ */
+void
+xmlFreePattern(xmlPatternPtr comp) {
+    xmlStepOpPtr op;
+    int i;
+
+    if (comp == NULL)
+	return;
+    if (comp->next != NULL)
+        xmlFreePattern(comp->next);
+    if (comp->stream != NULL)
+        xmlFreeStreamComp(comp->stream);
+    if (comp->pattern != NULL)
+	xmlFree((xmlChar *)comp->pattern);
+    if (comp->steps != NULL) {
+        if (comp->dict == NULL) {
+	    for (i = 0;i < comp->nbStep;i++) {
+		op = &comp->steps[i];
+		if (op->value != NULL)
+		    xmlFree((xmlChar *) op->value);
+		if (op->value2 != NULL)
+		    xmlFree((xmlChar *) op->value2);
+	    }
+	}
+	xmlFree(comp->steps);
+    }
+    if (comp->dict != NULL)
+        xmlDictFree(comp->dict);
+
+    memset(comp, -1, sizeof(xmlPattern));
+    xmlFree(comp);
+}
+
+/**
+ * xmlFreePatternList:
+ * @comp:  an XSLT comp list
+ *
+ * Free up the memory allocated by all the elements of @comp
+ */
+void
+xmlFreePatternList(xmlPatternPtr comp) {
+    xmlPatternPtr cur;
+
+    while (comp != NULL) {
+	cur = comp;
+	comp = comp->next;
+	cur->next = NULL;
+	xmlFreePattern(cur);
+    }
+}
+
+/**
+ * xmlNewPatParserContext:
+ * @pattern:  the pattern context
+ * @dict:  the inherited dictionary or NULL
+ * @namespaces: the prefix definitions, array of [URI, prefix] terminated
+ *              with [NULL, NULL] or NULL if no namespace is used
+ *
+ * Create a new XML pattern parser context
+ *
+ * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
+ */
+static xmlPatParserContextPtr
+xmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
+                       const xmlChar **namespaces) {
+    xmlPatParserContextPtr cur;
+
+    if (pattern == NULL)
+        return(NULL);
+
+    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
+    if (cur == NULL) {
+	ERROR(NULL, NULL, NULL,
+		"xmlNewPatParserContext : malloc failed\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlPatParserContext));
+    cur->dict = dict;
+    cur->cur = pattern;
+    cur->base = pattern;
+    if (namespaces != NULL) {
+        int i;
+	for (i = 0;namespaces[2 * i] != NULL;i++);
+        cur->nb_namespaces = i;
+    } else {
+        cur->nb_namespaces = 0;
+    }
+    cur->namespaces = namespaces;
+    return(cur);
+}
+
+/**
+ * xmlFreePatParserContext:
+ * @ctxt:  an XSLT parser context
+ *
+ * Free up the memory allocated by @ctxt
+ */
+static void
+xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
+    if (ctxt == NULL)
+	return;    
+    memset(ctxt, -1, sizeof(xmlPatParserContext));
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlPatternAdd:
+ * @comp:  the compiled match expression
+ * @op:  an op
+ * @value:  the first value
+ * @value2:  the second value
+ *
+ * Add a step to an XSLT Compiled Match
+ *
+ * Returns -1 in case of failure, 0 otherwise.
+ */
+static int
+xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
+                xmlPatternPtr comp,
+                xmlPatOp op, xmlChar * value, xmlChar * value2)
+{
+    if (comp->nbStep >= comp->maxStep) {
+        xmlStepOpPtr temp;
+	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
+	                                 sizeof(xmlStepOp));
+        if (temp == NULL) {
+	    ERROR(ctxt, NULL, NULL,
+			     "xmlPatternAdd: realloc failed\n");
+	    return (-1);
+	}
+	comp->steps = temp;
+	comp->maxStep *= 2;
+    }
+    comp->steps[comp->nbStep].op = op;
+    comp->steps[comp->nbStep].value = value;
+    comp->steps[comp->nbStep].value2 = value2;
+    comp->nbStep++;
+    return (0);
+}
+
+#if 0
+/**
+ * xsltSwapTopPattern:
+ * @comp:  the compiled match expression
+ *
+ * reverse the two top steps.
+ */
+static void
+xsltSwapTopPattern(xmlPatternPtr comp) {
+    int i;
+    int j = comp->nbStep - 1;
+
+    if (j > 0) {
+	register const xmlChar *tmp;
+	register xmlPatOp op;
+	i = j - 1;
+	tmp = comp->steps[i].value;
+	comp->steps[i].value = comp->steps[j].value;
+	comp->steps[j].value = tmp;
+	tmp = comp->steps[i].value2;
+	comp->steps[i].value2 = comp->steps[j].value2;
+	comp->steps[j].value2 = tmp;
+	op = comp->steps[i].op;
+	comp->steps[i].op = comp->steps[j].op;
+	comp->steps[j].op = op;
+    }
+}
+#endif
+
+/**
+ * xmlReversePattern:
+ * @comp:  the compiled match expression
+ *
+ * reverse all the stack of expressions
+ *
+ * returns 0 in case of success and -1 in case of error.
+ */
+static int
+xmlReversePattern(xmlPatternPtr comp) {
+    int i, j;
+
+    /*
+     * remove the leading // for //a or .//a
+     */
+    if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) {
+        for (i = 0, j = 1;j < comp->nbStep;i++,j++) {
+	    comp->steps[i].value = comp->steps[j].value;
+	    comp->steps[i].value2 = comp->steps[j].value2;
+	    comp->steps[i].op = comp->steps[j].op;
+	}
+	comp->nbStep--;
+    }
+    if (comp->nbStep >= comp->maxStep) {
+        xmlStepOpPtr temp;
+	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
+	                                 sizeof(xmlStepOp));
+        if (temp == NULL) {
+	    ERROR(ctxt, NULL, NULL,
+			     "xmlReversePattern: realloc failed\n");
+	    return (-1);
+	}
+	comp->steps = temp;
+	comp->maxStep *= 2;
+    }
+    i = 0;
+    j = comp->nbStep - 1;
+    while (j > i) {
+	register const xmlChar *tmp;
+	register xmlPatOp op;
+	tmp = comp->steps[i].value;
+	comp->steps[i].value = comp->steps[j].value;
+	comp->steps[j].value = tmp;
+	tmp = comp->steps[i].value2;
+	comp->steps[i].value2 = comp->steps[j].value2;
+	comp->steps[j].value2 = tmp;
+	op = comp->steps[i].op;
+	comp->steps[i].op = comp->steps[j].op;
+	comp->steps[j].op = op;
+	j--;
+	i++;
+    }
+    comp->steps[comp->nbStep].value = NULL;
+    comp->steps[comp->nbStep].value2 = NULL;
+    comp->steps[comp->nbStep++].op = XML_OP_END;
+    return(0);
+}
+
+/************************************************************************
+ * 									*
+ * 		The interpreter for the precompiled patterns		*
+ * 									*
+ ************************************************************************/
+
+static int
+xmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) {
+    if ((states->states == NULL) || (states->maxstates <= 0)) {
+        states->maxstates = 4;
+	states->nbstates = 0;
+	states->states = xmlMalloc(4 * sizeof(xmlStepState));
+    }
+    else if (states->maxstates <= states->nbstates) {
+        xmlStepState *tmp;
+
+	tmp = (xmlStepStatePtr) xmlRealloc(states->states,
+			       2 * states->maxstates * sizeof(xmlStepState));
+	if (tmp == NULL)
+	    return(-1);
+	states->states = tmp;
+	states->maxstates *= 2;
+    }
+    states->states[states->nbstates].step = step;
+    states->states[states->nbstates++].node = node;
+#if 0
+    fprintf(stderr, "Push: %d, %s\n", step, node->name);
+#endif
+    return(0);
+}
+
+/**
+ * xmlPatMatch:
+ * @comp: the precompiled pattern
+ * @node: a node
+ *
+ * Test whether the node matches the pattern
+ *
+ * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
+ */
+static int
+xmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
+    int i;
+    xmlStepOpPtr step;
+    xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */
+
+    if ((comp == NULL) || (node == NULL)) return(-1);
+    i = 0;
+restart:
+    for (;i < comp->nbStep;i++) {
+	step = &comp->steps[i];
+	switch (step->op) {
+            case XML_OP_END:
+		goto found;
+            case XML_OP_ROOT:
+		if (node->type == XML_NAMESPACE_DECL)
+		    goto rollback;
+		node = node->parent;
+		if ((node->type == XML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+		    (node->type == XML_HTML_DOCUMENT_NODE))
+		    continue;
+		goto rollback;
+            case XML_OP_ELEM:
+		if (node->type != XML_ELEMENT_NODE)
+		    goto rollback;
+		if (step->value == NULL)
+		    continue;
+		if (step->value[0] != node->name[0])
+		    goto rollback;
+		if (!xmlStrEqual(step->value, node->name))
+		    goto rollback;
+
+		/* Namespace test */
+		if (node->ns == NULL) {
+		    if (step->value2 != NULL)
+			goto rollback;
+		} else if (node->ns->href != NULL) {
+		    if (step->value2 == NULL)
+			goto rollback;
+		    if (!xmlStrEqual(step->value2, node->ns->href))
+			goto rollback;
+		}
+		continue;
+            case XML_OP_CHILD: {
+		xmlNodePtr lst;
+
+		if ((node->type != XML_ELEMENT_NODE) &&
+		    (node->type != XML_DOCUMENT_NODE) &&
+#ifdef LIBXML_DOCB_ENABLED
+		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
+#endif
+		    (node->type != XML_HTML_DOCUMENT_NODE))
+		    goto rollback;
+
+		lst = node->children;
+
+		if (step->value != NULL) {
+		    while (lst != NULL) {
+			if ((lst->type == XML_ELEMENT_NODE) &&
+			    (step->value[0] == lst->name[0]) &&
+			    (xmlStrEqual(step->value, lst->name)))
+			    break;
+			lst = lst->next;
+		    }
+		    if (lst != NULL)
+			continue;
+		}
+		goto rollback;
+	    }
+            case XML_OP_ATTR:
+		if (node->type != XML_ATTRIBUTE_NODE)
+		    goto rollback;
+		if (step->value != NULL) {
+		    if (step->value[0] != node->name[0])
+			goto rollback;
+		    if (!xmlStrEqual(step->value, node->name))
+			goto rollback;
+		}
+		/* Namespace test */
+		if (node->ns == NULL) {
+		    if (step->value2 != NULL)
+			goto rollback;
+		} else if (step->value2 != NULL) {
+		    if (!xmlStrEqual(step->value2, node->ns->href))
+			goto rollback;
+		}
+		continue;
+            case XML_OP_PARENT:
+		if ((node->type == XML_DOCUMENT_NODE) ||
+		    (node->type == XML_HTML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+		    (node->type == XML_NAMESPACE_DECL))
+		    goto rollback;
+		node = node->parent;
+		if (node == NULL)
+		    goto rollback;
+		if (step->value == NULL)
+		    continue;
+		if (step->value[0] != node->name[0])
+		    goto rollback;
+		if (!xmlStrEqual(step->value, node->name))
+		    goto rollback;
+		/* Namespace test */
+		if (node->ns == NULL) {
+		    if (step->value2 != NULL)
+			goto rollback;
+		} else if (node->ns->href != NULL) {
+		    if (step->value2 == NULL)
+			goto rollback;
+		    if (!xmlStrEqual(step->value2, node->ns->href))
+			goto rollback;
+		}
+		continue;
+            case XML_OP_ANCESTOR:
+		/* TODO: implement coalescing of ANCESTOR/NODE ops */
+		if (step->value == NULL) {
+		    i++;
+		    step = &comp->steps[i];
+		    if (step->op == XML_OP_ROOT)
+			goto found;
+		    if (step->op != XML_OP_ELEM)
+			goto rollback;
+		    if (step->value == NULL)
+			return(-1);
+		}
+		if (node == NULL)
+		    goto rollback;
+		if ((node->type == XML_DOCUMENT_NODE) ||
+		    (node->type == XML_HTML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+		    (node->type == XML_NAMESPACE_DECL))
+		    goto rollback;
+		node = node->parent;
+		while (node != NULL) {
+		    if ((node->type == XML_ELEMENT_NODE) &&
+			(step->value[0] == node->name[0]) &&
+			(xmlStrEqual(step->value, node->name))) {
+			/* Namespace test */
+			if (node->ns == NULL) {
+			    if (step->value2 == NULL)
+				break;
+			} else if (node->ns->href != NULL) {
+			    if ((step->value2 != NULL) &&
+			        (xmlStrEqual(step->value2, node->ns->href)))
+				break;
+			}
+		    }
+		    node = node->parent;
+		}
+		if (node == NULL)
+		    goto rollback;
+		/*
+		 * prepare a potential rollback from here
+		 * for ancestors of that node.
+		 */
+		if (step->op == XML_OP_ANCESTOR)
+		    xmlPatPushState(&states, i, node);
+		else
+		    xmlPatPushState(&states, i - 1, node);
+		continue;
+            case XML_OP_NS:
+		if (node->type != XML_ELEMENT_NODE)
+		    goto rollback;
+		if (node->ns == NULL) {
+		    if (step->value != NULL)
+			goto rollback;
+		} else if (node->ns->href != NULL) {
+		    if (step->value == NULL)
+			goto rollback;
+		    if (!xmlStrEqual(step->value, node->ns->href))
+			goto rollback;
+		}
+		break;
+            case XML_OP_ALL:
+		if (node->type != XML_ELEMENT_NODE)
+		    goto rollback;
+		break;
+	}
+    }
+found:
+    if (states.states != NULL) {
+        /* Free the rollback states */
+	xmlFree(states.states);
+    }
+    return(1);
+rollback:
+    /* got an error try to rollback */
+    if (states.states == NULL)
+	return(0);
+    if (states.nbstates <= 0) {
+	xmlFree(states.states);
+	return(0);
+    }
+    states.nbstates--;
+    i = states.states[states.nbstates].step;
+    node = states.states[states.nbstates].node;
+#if 0
+    fprintf(stderr, "Pop: %d, %s\n", i, node->name);
+#endif
+    goto restart;
+}
+
+/************************************************************************
+ *									*
+ *			Dedicated parser for templates			*
+ *									*
+ ************************************************************************/
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+#define CUR (*ctxt->cur)
+#define SKIP(val) ctxt->cur += (val)
+#define NXT(val) ctxt->cur[(val)]
+#define PEEKPREV(val) ctxt->cur[-(val)]
+#define CUR_PTR ctxt->cur
+
+#define SKIP_BLANKS 							\
+    while (IS_BLANK_CH(CUR)) NEXT
+
+#define CURRENT (*ctxt->cur)
+#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
+
+
+#define PUSH(op, val, val2) 						\
+    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
+
+#define XSLT_ERROR(X)							\
+    { xsltError(ctxt, __FILE__, __LINE__, X);				\
+      ctxt->error = (X); return; }
+
+#define XSLT_ERROR0(X)							\
+    { xsltError(ctxt, __FILE__, __LINE__, X);				\
+      ctxt->error = (X); return(0); }
+
+#if 0
+/**
+ * xmlPatScanLiteral:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parse an XPath Litteral:
+ *
+ * [29] Literal ::= '"' [^"]* '"'
+ *                | "'" [^']* "'"
+ *
+ * Returns the Literal parsed or NULL
+ */
+
+static xmlChar *
+xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
+    const xmlChar *q, *cur;
+    xmlChar *ret = NULL;
+    int val, len;
+
+    SKIP_BLANKS;
+    if (CUR == '"') {
+        NEXT;
+	cur = q = CUR_PTR;
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	while ((IS_CHAR(val)) && (val != '"')) {
+	    cur += len;
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	}
+	if (!IS_CHAR(val)) {
+	    ctxt->error = 1;
+	    return(NULL);
+	} else {
+	    if (ctxt->dict)
+		ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
+	    else
+		ret = xmlStrndup(q, cur - q);	    
+        }
+	cur += len;
+	CUR_PTR = cur;
+    } else if (CUR == '\'') {
+        NEXT;
+	cur = q = CUR_PTR;
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	while ((IS_CHAR(val)) && (val != '\'')) {
+	    cur += len;
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	}
+	if (!IS_CHAR(val)) {
+	    ctxt->error = 1;
+	    return(NULL);
+	} else {
+	    if (ctxt->dict)
+		ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
+	    else
+		ret = xmlStrndup(q, cur - q);	    
+        }
+	cur += len;
+	CUR_PTR = cur;
+    } else {
+	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
+	ctxt->error = 1;
+	return(NULL);
+    }
+    return(ret);
+}
+#endif
+
+/**
+ * xmlPatScanName:
+ * @ctxt:  the XPath Parser context
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | 
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (S Name)*
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static xmlChar *
+xmlPatScanName(xmlPatParserContextPtr ctxt) {
+    const xmlChar *q, *cur;
+    xmlChar *ret = NULL;
+    int val, len;
+
+    SKIP_BLANKS;
+
+    cur = q = CUR_PTR;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
+	return(NULL);
+
+    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
+           (val == '.') || (val == '-') ||
+	   (val == '_') || 
+	   (IS_COMBINING(val)) ||
+	   (IS_EXTENDER(val))) {
+	cur += len;
+	val = xmlStringCurrentChar(NULL, cur, &len);
+    }
+    if (ctxt->dict)
+	ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
+    else
+	ret = xmlStrndup(q, cur - q);    
+    CUR_PTR = cur;
+    return(ret);
+}
+
+/**
+ * xmlPatScanNCName:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parses a non qualified name
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static xmlChar *
+xmlPatScanNCName(xmlPatParserContextPtr ctxt) {
+    const xmlChar *q, *cur;
+    xmlChar *ret = NULL;
+    int val, len;
+
+    SKIP_BLANKS;
+
+    cur = q = CUR_PTR;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    if (!IS_LETTER(val) && (val != '_'))
+	return(NULL);
+
+    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
+           (val == '.') || (val == '-') ||
+	   (val == '_') ||
+	   (IS_COMBINING(val)) ||
+	   (IS_EXTENDER(val))) {
+	cur += len;
+	val = xmlStringCurrentChar(NULL, cur, &len);
+    }
+    if (ctxt->dict)
+	ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
+    else
+	ret = xmlStrndup(q, cur - q);
+    CUR_PTR = cur;
+    return(ret);
+}
+
+#if 0
+/**
+ * xmlPatScanQName:
+ * @ctxt:  the XPath Parser context
+ * @prefix:  the place to store the prefix
+ *
+ * Parse a qualified name
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static xmlChar *
+xmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
+    xmlChar *ret = NULL;
+
+    *prefix = NULL;
+    ret = xmlPatScanNCName(ctxt);
+    if (CUR == ':') {
+        *prefix = ret;
+	NEXT;
+	ret = xmlPatScanNCName(ctxt);
+    }
+    return(ret);
+}
+#endif
+
+/**
+ * xmlCompileAttributeTest:
+ * @ctxt:  the compilation context
+ *
+ * Compile an attribute test.
+ */
+static void
+xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
+    xmlChar *token = NULL;
+    xmlChar *name = NULL;
+    xmlChar *URL = NULL;
+    
+    SKIP_BLANKS;
+    name = xmlPatScanNCName(ctxt);
+    if (name == NULL) {
+	if (CUR == '*') {
+	    PUSH(XML_OP_ATTR, NULL, NULL);
+	    NEXT;
+	} else {
+	    ERROR(NULL, NULL, NULL,
+		"xmlCompileAttributeTest : Name expected\n");
+	    ctxt->error = 1;
+	}
+	return;
+    }
+    if (CUR == ':') {
+	int i;
+	xmlChar *prefix = name;
+	
+	NEXT;
+
+	if (IS_BLANK_CH(CUR)) {	    
+	    ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
+	    XML_PAT_FREE_STRING(ctxt, prefix);
+	    ctxt->error = 1;
+	    goto error;
+	}
+	/*
+	* This is a namespace match
+	*/
+	token = xmlPatScanName(ctxt);
+	if ((prefix[0] == 'x') &&
+	    (prefix[1] == 'm') &&
+	    (prefix[2] == 'l') &&
+	    (prefix[3] == 0))
+	{
+	    XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);	    
+	} else {
+	    for (i = 0;i < ctxt->nb_namespaces;i++) {
+		if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+		    XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])		    
+		    break;
+		}
+	    }
+	    if (i >= ctxt->nb_namespaces) {
+		ERROR5(NULL, NULL, NULL,
+		    "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
+		    prefix);
+		ctxt->error = 1;	    
+		goto error;
+	    }
+	}
+	XML_PAT_FREE_STRING(ctxt, prefix);
+	if (token == NULL) {
+	    if (CUR == '*') {
+		NEXT;
+		PUSH(XML_OP_ATTR, NULL, URL);
+	    } else {
+		ERROR(NULL, NULL, NULL,
+		    "xmlCompileAttributeTest : Name expected\n");
+		ctxt->error = 1;
+		goto error;
+	    }	    
+	} else {
+	    PUSH(XML_OP_ATTR, token, URL);
+	}
+    } else {
+	PUSH(XML_OP_ATTR, name, NULL);
+    }
+    return;
+error:
+    if (URL != NULL)
+	XML_PAT_FREE_STRING(ctxt, URL)	
+    if (token != NULL)
+	XML_PAT_FREE_STRING(ctxt, token);
+}
+
+/**
+ * xmlCompileStepPattern:
+ * @ctxt:  the compilation context
+ *
+ * Compile the Step Pattern and generates a precompiled
+ * form suitable for fast matching.
+ *
+ * [3]    Step    ::=    '.' | NameTest
+ * [4]    NameTest    ::=    QName | '*' | NCName ':' '*' 
+ */
+
+static void
+xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
+    xmlChar *token = NULL;
+    xmlChar *name = NULL;
+    xmlChar *URL = NULL;
+    int hasBlanks = 0;
+
+    SKIP_BLANKS;
+    if (CUR == '.') {
+	/*
+	* Context node.
+	*/
+	NEXT;
+	PUSH(XML_OP_ELEM, NULL, NULL);
+	return;
+    }
+    if (CUR == '@') {
+	/*
+	* Attribute test.
+	*/
+	if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
+	    ERROR5(NULL, NULL, NULL,
+		"Unexpected attribute axis in '%s'.\n", ctxt->base);
+	    ctxt->error = 1;
+	    return;
+	}
+	NEXT;
+	xmlCompileAttributeTest(ctxt);
+	if (ctxt->error != 0) 
+	    goto error;
+	return;
+    }
+    name = xmlPatScanNCName(ctxt);
+    if (name == NULL) {
+	if (CUR == '*') {
+	    NEXT;
+	    PUSH(XML_OP_ALL, NULL, NULL);
+	    return;
+	} else {
+	    ERROR(NULL, NULL, NULL,
+		    "xmlCompileStepPattern : Name expected\n");
+	    ctxt->error = 1;
+	    return;
+	}
+    }
+    if (IS_BLANK_CH(CUR)) {
+	hasBlanks = 1;
+	SKIP_BLANKS;
+    }
+    if (CUR == ':') {
+	NEXT;
+	if (CUR != ':') {
+	    xmlChar *prefix = name;
+	    int i;	    
+
+	    if (hasBlanks || IS_BLANK_CH(CUR)) {
+		ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
+		ctxt->error = 1;
+		goto error;
+	    }
+	    /*
+	     * This is a namespace match
+	     */
+	    token = xmlPatScanName(ctxt);
+	    if ((prefix[0] == 'x') &&
+		(prefix[1] == 'm') &&
+		(prefix[2] == 'l') &&
+		(prefix[3] == 0))
+	    {
+		XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
+	    } else {
+		for (i = 0;i < ctxt->nb_namespaces;i++) {
+		    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+			XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
+			break;
+		    }
+		}
+		if (i >= ctxt->nb_namespaces) {
+		    ERROR5(NULL, NULL, NULL,
+			"xmlCompileStepPattern : no namespace bound to prefix %s\n",
+			prefix);
+		    ctxt->error = 1;
+		    goto error;
+		}
+	    }
+	    XML_PAT_FREE_STRING(ctxt, prefix);
+	    name = NULL;
+	    if (token == NULL) {
+		if (CUR == '*') {
+		    NEXT;
+		    PUSH(XML_OP_NS, URL, NULL);
+		} else {
+		    ERROR(NULL, NULL, NULL,
+			    "xmlCompileStepPattern : Name expected\n");
+		    ctxt->error = 1;
+		    goto error;
+		}
+	    } else {
+		PUSH(XML_OP_ELEM, token, URL);
+	    }
+	} else {
+	    NEXT;
+	    if (xmlStrEqual(name, (const xmlChar *) "child")) {		
+		XML_PAT_FREE_STRING(ctxt, name);
+		name = xmlPatScanName(ctxt);
+		if (name == NULL) {
+		    if (CUR == '*') {
+			NEXT;
+			PUSH(XML_OP_ALL, NULL, NULL);
+			return;
+		    } else {
+			ERROR(NULL, NULL, NULL,
+			    "xmlCompileStepPattern : QName expected\n");
+			ctxt->error = 1;
+			goto error;
+		    }
+		}
+		if (CUR == ':') {
+		    xmlChar *prefix = name;
+		    int i;
+		    
+		    NEXT;
+		    if (IS_BLANK_CH(CUR)) {
+			ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
+			ctxt->error = 1;
+			goto error;
+		    }
+		    /*
+		    * This is a namespace match
+		    */
+		    token = xmlPatScanName(ctxt);
+		    if ((prefix[0] == 'x') &&
+			(prefix[1] == 'm') &&
+			(prefix[2] == 'l') &&
+			(prefix[3] == 0))
+		    {
+			XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)			
+		    } else {
+			for (i = 0;i < ctxt->nb_namespaces;i++) {
+			    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+				XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])				
+				break;
+			    }
+			}
+			if (i >= ctxt->nb_namespaces) {
+			    ERROR5(NULL, NULL, NULL,
+				"xmlCompileStepPattern : no namespace bound "
+				"to prefix %s\n", prefix);
+			    ctxt->error = 1;
+			    goto error;
+			}
+		    }
+		    XML_PAT_FREE_STRING(ctxt, prefix);
+		    name = NULL;
+		    if (token == NULL) {
+			if (CUR == '*') {
+			    NEXT;
+			    PUSH(XML_OP_NS, URL, NULL);
+			} else {
+			    ERROR(NULL, NULL, NULL,
+				"xmlCompileStepPattern : Name expected\n");
+			    ctxt->error = 1;
+			    goto error;
+			}
+		    } else {
+			PUSH(XML_OP_CHILD, token, URL);
+		    }
+		} else
+		    PUSH(XML_OP_CHILD, name, NULL);
+		return;
+	    } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {
+		XML_PAT_FREE_STRING(ctxt, name)
+		name = NULL;
+		if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
+		    ERROR5(NULL, NULL, NULL,
+			"Unexpected attribute axis in '%s'.\n", ctxt->base);
+		    ctxt->error = 1;
+		    goto error;
+		}
+		xmlCompileAttributeTest(ctxt);
+		if (ctxt->error != 0)
+		    goto error;
+		return;
+	    } else {
+		ERROR5(NULL, NULL, NULL,
+		    "The 'element' or 'attribute' axis is expected.\n", NULL);
+		ctxt->error = 1;
+		goto error;
+	    }	    
+	}
+    } else if (CUR == '*') {
+        if (name != NULL) {
+	    ctxt->error = 1;
+	    goto error;
+	}
+	NEXT;
+	PUSH(XML_OP_ALL, token, NULL);
+    } else {
+	PUSH(XML_OP_ELEM, name, NULL);
+    }
+    return;
+error:
+    if (URL != NULL)
+	XML_PAT_FREE_STRING(ctxt, URL)	
+    if (token != NULL)
+	XML_PAT_FREE_STRING(ctxt, token)
+    if (name != NULL)
+	XML_PAT_FREE_STRING(ctxt, name)
+}
+
+/**
+ * xmlCompilePathPattern:
+ * @ctxt:  the compilation context
+ *
+ * Compile the Path Pattern and generates a precompiled
+ * form suitable for fast matching.
+ *
+ * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 
+ */
+static void
+xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
+    SKIP_BLANKS;
+    if (CUR == '/') {
+        ctxt->comp->flags |= PAT_FROM_ROOT;
+    } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
+        ctxt->comp->flags |= PAT_FROM_CUR;
+    }
+	
+    if ((CUR == '/') && (NXT(1) == '/')) {
+	PUSH(XML_OP_ANCESTOR, NULL, NULL);
+	NEXT;
+	NEXT;
+    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
+	PUSH(XML_OP_ANCESTOR, NULL, NULL);
+	NEXT;
+	NEXT;
+	NEXT;
+	/* Check for incompleteness. */
+	SKIP_BLANKS;
+	if (CUR == 0) {
+	    ERROR5(NULL, NULL, NULL,
+	       "Incomplete expression '%s'.\n", ctxt->base);
+	    ctxt->error = 1;
+	    goto error;
+	}
+    }
+    if (CUR == '@') {
+	NEXT;
+	xmlCompileAttributeTest(ctxt);
+	SKIP_BLANKS;
+	/* TODO: check for incompleteness */
+	if (CUR != 0) {
+	    xmlCompileStepPattern(ctxt);
+	    if (ctxt->error != 0)
+		goto error;
+	}
+    } else {
+        if (CUR == '/') {
+	    PUSH(XML_OP_ROOT, NULL, NULL);
+	    NEXT;
+	    /* Check for incompleteness. */
+	    SKIP_BLANKS;
+	    if (CUR == 0) {
+		ERROR5(NULL, NULL, NULL,
+		    "Incomplete expression '%s'.\n", ctxt->base);
+		ctxt->error = 1;
+		goto error;
+	    }
+	}
+	xmlCompileStepPattern(ctxt);
+	if (ctxt->error != 0)
+	    goto error;
+	SKIP_BLANKS;
+	while (CUR == '/') {
+	    if (NXT(1) == '/') {
+	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
+		NEXT;
+		NEXT;
+		SKIP_BLANKS;
+		xmlCompileStepPattern(ctxt);
+		if (ctxt->error != 0)
+		    goto error;
+	    } else {
+	        PUSH(XML_OP_PARENT, NULL, NULL);
+		NEXT;
+		SKIP_BLANKS;
+		if (CUR == 0) {
+		    ERROR5(NULL, NULL, NULL,
+		    "Incomplete expression '%s'.\n", ctxt->base);
+		    ctxt->error = 1;
+		    goto error;		    
+		}
+		xmlCompileStepPattern(ctxt);
+		if (ctxt->error != 0)
+		    goto error;
+	    }
+	}
+    }
+    if (CUR != 0) {
+	ERROR5(NULL, NULL, NULL,
+	       "Failed to compile pattern %s\n", ctxt->base);
+	ctxt->error = 1;
+    }
+error:
+    return;
+}
+
+/**
+ * xmlCompileIDCXPathPath:
+ * @ctxt:  the compilation context
+ *
+ * Compile the Path Pattern and generates a precompiled
+ * form suitable for fast matching.
+ *
+ * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 
+ */
+static void
+xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
+    SKIP_BLANKS;
+    if (CUR == '/') {
+	ERROR5(NULL, NULL, NULL,
+	    "Unexpected selection of the document root in '%s'.\n",
+	    ctxt->base);
+	goto error;
+    }
+    ctxt->comp->flags |= PAT_FROM_CUR;
+
+    if (CUR == '.') {
+	/* "." - "self::node()" */
+	NEXT;
+	SKIP_BLANKS;
+	if (CUR == 0) {
+	    /*
+	    * Selection of the context node.
+	    */
+	    PUSH(XML_OP_ELEM, NULL, NULL);
+	    return;
+	}
+	if (CUR != '/') {
+	    /* TODO: A more meaningful error message. */
+	    ERROR5(NULL, NULL, NULL,
+	    "Unexpected token after '.' in '%s'.\n", ctxt->base);
+	    goto error;
+	}
+	/* "./" - "self::node()/" */
+	NEXT;
+	SKIP_BLANKS;
+	if (CUR == '/') {
+	    if (IS_BLANK_CH(PEEKPREV(1))) {
+		/*
+		* Disallow "./ /"
+		*/
+		ERROR5(NULL, NULL, NULL,
+		    "Unexpected '/' token in '%s'.\n", ctxt->base);
+		goto error;
+	    }
+	    /* ".//" - "self:node()/descendant-or-self::node()/" */
+	    PUSH(XML_OP_ANCESTOR, NULL, NULL);
+	    NEXT;
+	    SKIP_BLANKS;
+	}
+	if (CUR == 0)
+	    goto error_unfinished;
+    }
+    /*
+    * Process steps.
+    */
+    do {
+	xmlCompileStepPattern(ctxt);
+	if (ctxt->error != 0) 
+	    goto error;
+	SKIP_BLANKS;
+	if (CUR != '/')
+	    break;
+	PUSH(XML_OP_PARENT, NULL, NULL);
+	NEXT;
+	SKIP_BLANKS;
+	if (CUR == '/') {
+	    /*
+	    * Disallow subsequent '//'.
+	    */
+	    ERROR5(NULL, NULL, NULL,
+		"Unexpected subsequent '//' in '%s'.\n",
+		ctxt->base);
+	    goto error;
+	}
+	if (CUR == 0)
+	    goto error_unfinished;
+	
+    } while (CUR != 0);
+
+    if (CUR != 0) {
+	ERROR5(NULL, NULL, NULL,
+	    "Failed to compile expression '%s'.\n", ctxt->base);
+	ctxt->error = 1;
+    }
+    return;
+error:
+    ctxt->error = 1;
+    return;
+
+error_unfinished:
+    ctxt->error = 1;
+    ERROR5(NULL, NULL, NULL,
+	"Unfinished expression '%s'.\n", ctxt->base);    
+    return;
+}
+
+/************************************************************************
+ *									*
+ *			The streaming code				*
+ *									*
+ ************************************************************************/
+
+#ifdef DEBUG_STREAMING
+static void
+xmlDebugStreamComp(xmlStreamCompPtr stream) {
+    int i;
+
+    if (stream == NULL) {
+        printf("Stream: NULL\n");
+	return;
+    }
+    printf("Stream: %d steps\n", stream->nbStep);
+    for (i = 0;i < stream->nbStep;i++) {
+	if (stream->steps[i].ns != NULL) {
+	    printf("{%s}", stream->steps[i].ns);
+	}
+        if (stream->steps[i].name == NULL) {
+	    printf("* ");
+	} else {
+	    printf("%s ", stream->steps[i].name);
+	}
+	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
+	    printf("root ");
+	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
+	    printf("// ");
+	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
+	    printf("final ");
+	printf("\n");
+    }
+}
+static void
+xmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
+    int i;
+
+    if (ctxt == NULL) {
+        printf("Stream: NULL\n");
+	return;
+    }
+    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
+    if (match)
+        printf("matches\n");
+    else
+        printf("\n");
+    for (i = 0;i < ctxt->nbState;i++) {
+        if (ctxt->states[2 * i] < 0)
+	    printf(" %d: free\n", i);
+	else {
+	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
+	           ctxt->states[(2 * i) + 1]);
+            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
+	        XML_STREAM_STEP_DESC)
+	        printf(" //\n");
+	    else
+	        printf("\n");
+	}
+    }
+}
+#endif
+/**
+ * xmlNewStreamComp:
+ * @size: the number of expected steps
+ *
+ * build a new compiled pattern for streaming
+ *
+ * Returns the new structure or NULL in case of error.
+ */
+static xmlStreamCompPtr
+xmlNewStreamComp(int size) {
+    xmlStreamCompPtr cur;
+
+    if (size < 4)
+        size  = 4;
+
+    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
+    if (cur == NULL) {
+	ERROR(NULL, NULL, NULL,
+		"xmlNewStreamComp: malloc failed\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlStreamComp));
+    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
+    if (cur->steps == NULL) {
+	xmlFree(cur);
+	ERROR(NULL, NULL, NULL,
+	      "xmlNewStreamComp: malloc failed\n");
+	return(NULL);
+    }
+    cur->nbStep = 0;
+    cur->maxStep = size;
+    return(cur);
+}
+
+/**
+ * xmlFreeStreamComp:
+ * @comp: the compiled pattern for streaming
+ *
+ * Free the compiled pattern for streaming
+ */
+static void
+xmlFreeStreamComp(xmlStreamCompPtr comp) {
+    if (comp != NULL) {
+        if (comp->steps != NULL)
+	    xmlFree(comp->steps);
+	if (comp->dict != NULL)
+	    xmlDictFree(comp->dict);
+        xmlFree(comp);
+    }
+}
+
+/**
+ * xmlStreamCompAddStep:
+ * @comp: the compiled pattern for streaming
+ * @name: the first string, the name, or NULL for *
+ * @ns: the second step, the namespace name
+ * @flags: the flags for that step
+ *
+ * Add a new step to the compiled pattern
+ *
+ * Returns -1 in case of error or the step index if successful
+ */
+static int
+xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
+                     const xmlChar *ns, int nodeType, int flags) {
+    xmlStreamStepPtr cur;
+
+    if (comp->nbStep >= comp->maxStep) {
+	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
+				 comp->maxStep * 2 * sizeof(xmlStreamStep));
+	if (cur == NULL) {
+	    ERROR(NULL, NULL, NULL,
+		  "xmlNewStreamComp: malloc failed\n");
+	    return(-1);
+	}
+	comp->steps = cur;
+        comp->maxStep *= 2;
+    }
+    cur = &comp->steps[comp->nbStep++];
+    cur->flags = flags;
+    cur->name = name;
+    cur->ns = ns;
+    cur->nodeType = nodeType;
+    return(comp->nbStep - 1);
+}
+
+/**
+ * xmlStreamCompile:
+ * @comp: the precompiled pattern
+ * 
+ * Tries to stream compile a pattern
+ *
+ * Returns -1 in case of failure and 0 in case of success.
+ */
+static int
+xmlStreamCompile(xmlPatternPtr comp) {
+    xmlStreamCompPtr stream;
+    int i, s = 0, root = 0, flags = 0, prevs = -1;
+    xmlStepOp step;
+
+    if ((comp == NULL) || (comp->steps == NULL))
+        return(-1);
+    /*
+     * special case for .
+     */
+    if ((comp->nbStep == 1) &&
+        (comp->steps[0].op == XML_OP_ELEM) &&
+	(comp->steps[0].value == NULL) &&
+	(comp->steps[0].value2 == NULL)) {
+	stream = xmlNewStreamComp(0);
+	if (stream == NULL)
+	    return(-1);
+	/* Note that the stream will have no steps in this case. */
+	stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
+	comp->stream = stream;
+	return(0);
+    }
+
+    stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
+    if (stream == NULL)
+        return(-1);
+    if (comp->dict != NULL) {
+        stream->dict = comp->dict;
+	xmlDictReference(stream->dict);
+    }
+
+    i = 0;        
+    if (comp->flags & PAT_FROM_ROOT)
+	stream->flags |= XML_STREAM_FROM_ROOT;
+
+    for (;i < comp->nbStep;i++) {
+	step = comp->steps[i];
+        switch (step.op) {
+	    case XML_OP_END:
+	        break;
+	    case XML_OP_ROOT:
+	        if (i != 0)
+		    goto error;
+		root = 1;
+		break;
+	    case XML_OP_NS:
+		s = xmlStreamCompAddStep(stream, NULL, step.value,
+		    XML_ELEMENT_NODE, flags);		
+		if (s < 0)
+		    goto error;
+		prevs = s;
+		flags = 0;		
+		break;	    
+	    case XML_OP_ATTR:
+		flags |= XML_STREAM_STEP_ATTR;
+		prevs = -1;
+		s = xmlStreamCompAddStep(stream,
+		    step.value, step.value2, XML_ATTRIBUTE_NODE, flags);
+		flags = 0;
+		if (s < 0)
+		    goto error;
+		break;
+	    case XML_OP_ELEM:		
+	        if ((step.value == NULL) && (step.value2 == NULL)) {
+		    /*
+		    * We have a "." or "self::node()" here.
+		    * Eliminate redundant self::node() tests like in "/./."
+		    * or "//./"
+		    * The only case we won't eliminate is "//.", i.e. if
+		    * self::node() is the last node test and we had
+		    * continuation somewhere beforehand.
+		    */
+		    if ((comp->nbStep == i + 1) &&
+			(flags & XML_STREAM_STEP_DESC)) {
+			/*
+			* Mark the special case where the expression resolves
+			* to any type of node.
+			*/
+			if (comp->nbStep == i + 1) {
+			    stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
+			}
+			flags |= XML_STREAM_STEP_NODE;			
+			s = xmlStreamCompAddStep(stream, NULL, NULL,
+			    XML_STREAM_ANY_NODE, flags);
+			if (s < 0)
+			    goto error;
+			flags = 0;
+			/*
+			* If there was a previous step, mark it to be added to
+			* the result node-set; this is needed since only
+			* the last step will be marked as "final" and only
+			* "final" nodes are added to the resulting set.
+			*/
+			if (prevs != -1) {
+			    stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;
+			    prevs = -1;
+			}
+			break;	
+
+		    } else {
+			/* Just skip this one. */
+			continue;
+		    }
+		}
+		/* An element node. */		
+	        s = xmlStreamCompAddStep(stream, step.value, step.value2,
+		    XML_ELEMENT_NODE, flags);		
+		if (s < 0)
+		    goto error;
+		prevs = s;
+		flags = 0;		
+		break;		
+	    case XML_OP_CHILD:
+		/* An element node child. */
+	        s = xmlStreamCompAddStep(stream, step.value, step.value2,
+		    XML_ELEMENT_NODE, flags);		
+		if (s < 0)
+		    goto error;
+		prevs = s;
+		flags = 0;
+		break;	    
+	    case XML_OP_ALL:
+	        s = xmlStreamCompAddStep(stream, NULL, NULL,
+		    XML_ELEMENT_NODE, flags);		
+		if (s < 0)
+		    goto error;
+		prevs = s;
+		flags = 0;
+		break;
+	    case XML_OP_PARENT:	
+	        break;
+	    case XML_OP_ANCESTOR:
+		/* Skip redundant continuations. */
+		if (flags & XML_STREAM_STEP_DESC)
+		    break;
+	        flags |= XML_STREAM_STEP_DESC;
+		/*
+		* Mark the expression as having "//".
+		*/
+		if ((stream->flags & XML_STREAM_DESC) == 0)
+		    stream->flags |= XML_STREAM_DESC;
+		break;
+	}
+    }    
+    if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
+	/*
+	* If this should behave like a real pattern, we will mark
+	* the first step as having "//", to be reentrant on every
+	* tree level.
+	*/
+	if ((stream->flags & XML_STREAM_DESC) == 0)
+	    stream->flags |= XML_STREAM_DESC;
+
+	if (stream->nbStep > 0) {
+	    if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
+		stream->steps[0].flags |= XML_STREAM_STEP_DESC;	    
+	}
+    }
+    if (stream->nbStep <= s)
+	goto error;
+    stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
+    if (root)
+	stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
+#ifdef DEBUG_STREAMING
+    xmlDebugStreamComp(stream);
+#endif
+    comp->stream = stream;
+    return(0);
+error:
+    xmlFreeStreamComp(stream);
+    return(0);
+}
+
+/**
+ * xmlNewStreamCtxt:
+ * @size: the number of expected states
+ *
+ * build a new stream context
+ *
+ * Returns the new structure or NULL in case of error.
+ */
+static xmlStreamCtxtPtr
+xmlNewStreamCtxt(xmlStreamCompPtr stream) {
+    xmlStreamCtxtPtr cur;
+
+    cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
+    if (cur == NULL) {
+	ERROR(NULL, NULL, NULL,
+		"xmlNewStreamCtxt: malloc failed\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlStreamCtxt));
+    cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
+    if (cur->states == NULL) {
+	xmlFree(cur);
+	ERROR(NULL, NULL, NULL,
+	      "xmlNewStreamCtxt: malloc failed\n");
+	return(NULL);
+    }
+    cur->nbState = 0;
+    cur->maxState = 4;
+    cur->level = 0;
+    cur->comp = stream;
+    cur->blockLevel = -1;
+    return(cur);
+}
+
+/**
+ * xmlFreeStreamCtxt:
+ * @stream: the stream context
+ *
+ * Free the stream context
+ */
+void
+xmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
+    xmlStreamCtxtPtr next;
+
+    while (stream != NULL) {
+        next = stream->next;
+        if (stream->states != NULL)
+	    xmlFree(stream->states);
+        xmlFree(stream);
+	stream = next;
+    }
+}
+
+/**
+ * xmlStreamCtxtAddState:
+ * @comp: the stream context
+ * @idx: the step index for that streaming state
+ *
+ * Add a new state to the stream context
+ *
+ * Returns -1 in case of error or the state index if successful
+ */
+static int
+xmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
+    int i;
+    for (i = 0;i < comp->nbState;i++) {
+        if (comp->states[2 * i] < 0) {
+	    comp->states[2 * i] = idx;
+	    comp->states[2 * i + 1] = level;
+	    return(i);
+	}
+    }
+    if (comp->nbState >= comp->maxState) {
+        int *cur;
+
+	cur = (int *) xmlRealloc(comp->states,
+				 comp->maxState * 4 * sizeof(int));
+	if (cur == NULL) {
+	    ERROR(NULL, NULL, NULL,
+		  "xmlNewStreamCtxt: malloc failed\n");
+	    return(-1);
+	}
+	comp->states = cur;
+        comp->maxState *= 2;
+    }
+    comp->states[2 * comp->nbState] = idx;
+    comp->states[2 * comp->nbState++ + 1] = level;
+    return(comp->nbState - 1);
+}
+
+/**
+ * xmlStreamPushInternal:
+ * @stream: the stream context
+ * @name: the current name
+ * @ns: the namespace name
+ * @nodeType: the type of the node
+ *
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
+ * indicated a dictionary, then strings for name and ns will be expected
+ * to come from the dictionary.
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
+ * This can also act as a reset.
+ *
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
+ *    match and 0 otherwise.
+ */
+static int
+xmlStreamPushInternal(xmlStreamCtxtPtr stream,
+		      const xmlChar *name, const xmlChar *ns,
+		      int nodeType) {
+    int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
+    xmlStreamCompPtr comp;
+    xmlStreamStep step;
+#ifdef DEBUG_STREAMING
+    xmlStreamCtxtPtr orig = stream;
+#endif
+
+    if ((stream == NULL) || (stream->nbState < 0))
+        return(-1);
+
+    while (stream != NULL) {
+	comp = stream->comp;
+
+	if ((nodeType == XML_ELEMENT_NODE) &&
+	    (name == NULL) && (ns == NULL)) {
+	    /* We have a document node here (or a reset). */
+	    stream->nbState = 0;
+	    stream->level = 0;
+	    stream->blockLevel = -1;
+	    if (comp->flags & XML_STREAM_FROM_ROOT) {
+		if (comp->nbStep == 0) {
+		    /* TODO: We have a "/." here? */
+		    ret = 1;
+		} else {
+		    if ((comp->nbStep == 1) &&
+			(comp->steps[0].nodeType == XML_STREAM_ANY_NODE) &&
+			(comp->steps[0].flags & XML_STREAM_STEP_DESC))
+		    {
+			/*
+			* In the case of "//." the document node will match
+			* as well.
+			*/
+			ret = 1;
+		    } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
+			/* TODO: Do we need this ? */
+			tmp = xmlStreamCtxtAddState(stream, 0, 0);
+			if (tmp < 0)
+			    err++;
+		    }
+		}
+	    }
+	    stream = stream->next;
+	    continue; /* while */
+	}
+
+	/*
+	* Fast check for ".".
+	*/
+	if (comp->nbStep == 0) {
+	    /*
+	     * / and . are handled at the XPath node set creation
+	     * level by checking min depth
+	     */
+	    if (stream->flags & XML_PATTERN_XPATH) {
+		stream = stream->next;
+		continue; /* while */
+	    }
+	    /*
+	    * For non-pattern like evaluation like XML Schema IDCs
+	    * or traditional XPath expressions, this will match if
+	    * we are at the first level only, otherwise on every level.
+	    */
+	    if ((nodeType != XML_ATTRIBUTE_NODE) &&
+		(((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
+		(stream->level == 0))) {
+		    ret = 1;		
+	    }
+	    stream->level++;
+	    goto stream_next;
+	}
+	if (stream->blockLevel != -1) {
+	    /*
+	    * Skip blocked expressions.
+	    */
+    	    stream->level++;
+	    goto stream_next;
+	}
+
+	if ((nodeType != XML_ELEMENT_NODE) &&
+	    (nodeType != XML_ATTRIBUTE_NODE) &&
+	    ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) {
+	    /*
+	    * No need to process nodes of other types if we don't
+	    * resolve to those types.
+	    * TODO: Do we need to block the context here?
+	    */
+	    stream->level++;
+	    goto stream_next;
+	}
+
+	/*
+	 * Check evolution of existing states
+	 */
+	i = 0;
+	m = stream->nbState;
+	while (i < m) {
+	    if ((comp->flags & XML_STREAM_DESC) == 0) {
+		/*
+		* If there is no "//", then only the last
+		* added state is of interest.
+		*/
+		stepNr = stream->states[2 * (stream->nbState -1)];
+		/*
+		* TODO: Security check, should not happen, remove it.
+		*/
+		if (stream->states[(2 * (stream->nbState -1)) + 1] <
+		    stream->level) {
+		    return (-1);
+		}
+		desc = 0;
+		/* loop-stopper */
+		i = m;
+	    } else {
+		/*
+		* If there are "//", then we need to process every "//"
+		* occuring in the states, plus any other state for this
+		* level.
+		*/		
+		stepNr = stream->states[2 * i];
+
+		/* TODO: should not happen anymore: dead states */
+		if (stepNr < 0)
+		    goto next_state;
+
+		tmp = stream->states[(2 * i) + 1];
+
+		/* skip new states just added */
+		if (tmp > stream->level)
+		    goto next_state;
+
+		/* skip states at ancestor levels, except if "//" */
+		desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC;
+		if ((tmp < stream->level) && (!desc))
+		    goto next_state;
+	    }
+	    /* 
+	    * Check for correct node-type.
+	    */
+	    step = comp->steps[stepNr];
+	    if (step.nodeType != nodeType) {
+		if (step.nodeType == XML_ATTRIBUTE_NODE) {
+		    /*
+		    * Block this expression for deeper evaluation.
+		    */
+		    if ((comp->flags & XML_STREAM_DESC) == 0)
+			stream->blockLevel = stream->level +1;
+		    goto next_state;
+		} else if (step.nodeType != XML_STREAM_ANY_NODE)
+		    goto next_state;
+	    }	    
+	    /*
+	    * Compare local/namespace-name.
+	    */
+	    match = 0;
+	    if (step.nodeType == XML_STREAM_ANY_NODE) {
+		match = 1;
+	    } else if (step.name == NULL) {
+		if (step.ns == NULL) {
+		    /*
+		    * This lets through all elements/attributes.
+		    */
+		    match = 1;
+		} else if (ns != NULL)
+		    match = xmlStrEqual(step.ns, ns);
+	    } else if (((step.ns != NULL) == (ns != NULL)) &&
+		(name != NULL) &&
+		(step.name[0] == name[0]) &&
+		xmlStrEqual(step.name, name) &&
+		((step.ns == ns) || xmlStrEqual(step.ns, ns)))
+	    {
+		match = 1;	    
+	    }	 
+#if 0 
+/*
+* TODO: Pointer comparison won't work, since not guaranteed that the given
+*  values are in the same dict; especially if it's the namespace name,
+*  normally coming from ns->href. We need a namespace dict mechanism !
+*/
+	    } else if (comp->dict) {
+		if (step.name == NULL) {
+		    if (step.ns == NULL)
+			match = 1;
+		    else
+			match = (step.ns == ns);
+		} else {
+		    match = ((step.name == name) && (step.ns == ns));
+		}
+#endif /* if 0 ------------------------------------------------------- */	    
+	    if (match) {		
+		final = step.flags & XML_STREAM_STEP_FINAL;
+		if (desc) {
+		    if (final) {
+			ret = 1;
+		    } else {
+			/* descending match create a new state */
+			xmlStreamCtxtAddState(stream, stepNr + 1,
+			                      stream->level + 1);
+		    }
+		} else {
+		    if (final) {
+			ret = 1;
+		    } else {
+			xmlStreamCtxtAddState(stream, stepNr + 1,
+			                      stream->level + 1);
+		    }
+		}
+		if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
+		    /*
+		    * Check if we have a special case like "foo/bar//.", where
+		    * "foo" is selected as well.
+		    */
+		    ret = 1;
+		}
+	    }	    
+	    if (((comp->flags & XML_STREAM_DESC) == 0) &&
+		((! match) || final))  {
+		/*
+		* Mark this expression as blocked for any evaluation at
+		* deeper levels. Note that this includes "/foo"
+		* expressions if the *pattern* behaviour is used.
+		*/
+		stream->blockLevel = stream->level +1;
+	    }
+next_state:
+	    i++;
+	}
+
+	stream->level++;
+
+	/*
+	* Re/enter the expression.
+	* Don't reenter if it's an absolute expression like "/foo",
+	*   except "//foo".
+	*/
+	step = comp->steps[0];
+	if (step.flags & XML_STREAM_STEP_ROOT)
+	    goto stream_next;
+
+	desc = step.flags & XML_STREAM_STEP_DESC;
+	if (stream->flags & XML_PATTERN_NOTPATTERN) {
+	    /*
+	    * Re/enter the expression if it is a "descendant" one,
+	    * or if we are at the 1st level of evaluation.
+	    */
+	    
+	    if (stream->level == 1) {
+		if (XML_STREAM_XS_IDC(stream)) {
+		    /*
+		    * XS-IDC: The missing "self::node()" will always
+		    * match the first given node.
+		    */
+		    goto stream_next;
+		} else
+		    goto compare;
+	    }	    
+	    /*
+	    * A "//" is always reentrant.
+	    */
+	    if (desc)
+		goto compare;
+
+	    /*
+	    * XS-IDC: Process the 2nd level, since the missing
+	    * "self::node()" is responsible for the 2nd level being
+	    * the real start level.	    
+	    */	    
+	    if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
+		goto compare;
+
+	    goto stream_next;
+	}
+	
+compare:
+	/*
+	* Check expected node-type.
+	*/
+	if (step.nodeType != nodeType) {
+	    if (nodeType == XML_ATTRIBUTE_NODE)
+		goto stream_next;
+	    else if (step.nodeType != XML_STREAM_ANY_NODE)
+		goto stream_next;	     
+	}
+	/*
+	* Compare local/namespace-name.
+	*/
+	match = 0;
+	if (step.nodeType == XML_STREAM_ANY_NODE) {
+	    match = 1;
+	} else if (step.name == NULL) {
+	    if (step.ns == NULL) {
+		/*
+		* This lets through all elements/attributes.
+		*/
+		match = 1;
+	    } else if (ns != NULL)
+		match = xmlStrEqual(step.ns, ns);
+	} else if (((step.ns != NULL) == (ns != NULL)) &&
+	    (name != NULL) &&
+	    (step.name[0] == name[0]) &&
+	    xmlStrEqual(step.name, name) &&
+	    ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
+	{
+	    match = 1;	    
+	}	    
+	final = step.flags & XML_STREAM_STEP_FINAL;
+	if (match) {	    
+	    if (final)
+		ret = 1;
+	    else
+		xmlStreamCtxtAddState(stream, 1, stream->level);
+	    if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
+		/*
+		* Check if we have a special case like "foo//.", where
+		* "foo" is selected as well.
+		*/
+		ret = 1;
+	    }
+	}
+	if (((comp->flags & XML_STREAM_DESC) == 0) &&
+	    ((! match) || final))  {
+	    /*
+	    * Mark this expression as blocked for any evaluation at
+	    * deeper levels.
+	    */
+	    stream->blockLevel = stream->level;
+	}
+
+stream_next:
+        stream = stream->next;
+    } /* while stream != NULL */
+ 
+    if (err > 0)
+        ret = -1;
+#ifdef DEBUG_STREAMING
+    xmlDebugStreamCtxt(orig, ret);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlStreamPush:
+ * @stream: the stream context
+ * @name: the current name
+ * @ns: the namespace name
+ *
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
+ * indicated a dictionary, then strings for name and ns will be expected
+ * to come from the dictionary.
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
+ * This can also act as a reset.
+ * Otherwise the function will act as if it has been given an element-node.
+ *
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
+ *    match and 0 otherwise.
+ */
+int
+xmlStreamPush(xmlStreamCtxtPtr stream,
+              const xmlChar *name, const xmlChar *ns) {
+    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ELEMENT_NODE));
+}
+
+/**
+ * xmlStreamPushNode:
+ * @stream: the stream context
+ * @name: the current name
+ * @ns: the namespace name
+ * @nodeType: the type of the node being pushed
+ *
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
+ * indicated a dictionary, then strings for name and ns will be expected
+ * to come from the dictionary.
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
+ * This can also act as a reset.
+ * Different from xmlStreamPush() this function can be fed with nodes of type:
+ * element-, attribute-, text-, cdata-section-, comment- and
+ * processing-instruction-node.
+ *
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
+ *    match and 0 otherwise.
+ */
+int
+xmlStreamPushNode(xmlStreamCtxtPtr stream,
+		  const xmlChar *name, const xmlChar *ns,
+		  int nodeType)
+{
+    return (xmlStreamPushInternal(stream, name, ns,
+	nodeType));
+}
+
+/**
+* xmlStreamPushAttr:
+* @stream: the stream context
+* @name: the current name
+* @ns: the namespace name
+*
+* Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile()
+* indicated a dictionary, then strings for name and ns will be expected
+* to come from the dictionary.
+* Both @name and @ns being NULL means the / i.e. the root of the document.
+* This can also act as a reset.
+* Otherwise the function will act as if it has been given an attribute-node.
+*
+* Returns: -1 in case of error, 1 if the current state in the stream is a
+*    match and 0 otherwise.
+*/
+int
+xmlStreamPushAttr(xmlStreamCtxtPtr stream,
+		  const xmlChar *name, const xmlChar *ns) {
+    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ATTRIBUTE_NODE));
+}
+
+/**
+ * xmlStreamPop:
+ * @stream: the stream context
+ *
+ * push one level from the stream.
+ *
+ * Returns: -1 in case of error, 0 otherwise.
+ */
+int
+xmlStreamPop(xmlStreamCtxtPtr stream) {
+    int i, lev;
+    
+    if (stream == NULL)
+        return(-1);
+    while (stream != NULL) {
+	/*
+	* Reset block-level.
+	*/
+	if (stream->blockLevel == stream->level)
+	    stream->blockLevel = -1;
+
+	/*
+	 *  stream->level can be zero when XML_FINAL_IS_ANY_NODE is set
+	 *  (see the thread at
+	 *  http://mail.gnome.org/archives/xslt/2008-July/msg00027.html)
+	 */
+	if (stream->level)
+	    stream->level--;
+	/*
+	 * Check evolution of existing states
+	 */	
+	for (i = stream->nbState -1; i >= 0; i--) {
+	    /* discard obsoleted states */
+	    lev = stream->states[(2 * i) + 1];
+	    if (lev > stream->level)
+		stream->nbState--;
+	    if (lev <= stream->level)
+		break;
+	}
+	stream = stream->next;
+    }
+    return(0);
+}
+
+/**
+ * xmlStreamWantsAnyNode:
+ * @streamCtxt: the stream context
+ *
+ * Query if the streaming pattern additionally needs to be fed with
+ * text-, cdata-section-, comment- and processing-instruction-nodes.
+ * If the result is 0 then only element-nodes and attribute-nodes
+ * need to be pushed.
+ *
+ * Returns: 1 in case of need of nodes of the above described types,
+ *          0 otherwise. -1 on API errors.
+ */
+int
+xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
+{    
+    if (streamCtxt == NULL)
+	return(-1);
+    while (streamCtxt != NULL) {
+	if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)	
+	    return(1);
+	streamCtxt = streamCtxt->next;
+    }
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			The public interfaces				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlPatterncompile:
+ * @pattern: the pattern to compile
+ * @dict: an optional dictionary for interned strings
+ * @flags: compilation flags, see xmlPatternFlags
+ * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
+ *
+ * Compile a pattern.
+ *
+ * Returns the compiled form of the pattern or NULL in case of error
+ */
+xmlPatternPtr
+xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
+                  const xmlChar **namespaces) {
+    xmlPatternPtr ret = NULL, cur;
+    xmlPatParserContextPtr ctxt = NULL;
+    const xmlChar *or, *start;
+    xmlChar *tmp = NULL;
+    int type = 0;
+    int streamable = 1;
+
+    if (pattern == NULL)
+        return(NULL);
+
+    start = pattern;
+    or = start;
+    while (*or != 0) {
+	tmp = NULL;
+	while ((*or != 0) && (*or != '|')) or++;
+        if (*or == 0)
+	    ctxt = xmlNewPatParserContext(start, dict, namespaces);
+	else {
+	    tmp = xmlStrndup(start, or - start);
+	    if (tmp != NULL) {
+		ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
+	    }
+	    or++;
+	}
+	if (ctxt == NULL) goto error;	
+	cur = xmlNewPattern();
+	if (cur == NULL) goto error;
+	/*
+	* Assign string dict.
+	*/
+	if (dict) {	    
+	    cur->dict = dict;
+	    xmlDictReference(dict);
+	}
+	if (ret == NULL)
+	    ret = cur;
+	else {
+	    cur->next = ret->next;
+	    ret->next = cur;
+	}
+	cur->flags = flags;
+	ctxt->comp = cur;
+
+	if (XML_STREAM_XS_IDC(cur))
+	    xmlCompileIDCXPathPath(ctxt);
+	else
+	    xmlCompilePathPattern(ctxt);
+	if (ctxt->error != 0)
+	    goto error;
+	xmlFreePatParserContext(ctxt);
+	ctxt = NULL;
+
+
+        if (streamable) {
+	    if (type == 0) {
+	        type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
+	    } else if (type == PAT_FROM_ROOT) {
+	        if (cur->flags & PAT_FROM_CUR)
+		    streamable = 0;
+	    } else if (type == PAT_FROM_CUR) {
+	        if (cur->flags & PAT_FROM_ROOT)
+		    streamable = 0;
+	    }
+	}
+	if (streamable)
+	    xmlStreamCompile(cur);
+	if (xmlReversePattern(cur) < 0)
+	    goto error;
+	if (tmp != NULL) {
+	    xmlFree(tmp);
+	    tmp = NULL;
+	}
+	start = or;
+    }
+    if (streamable == 0) {
+        cur = ret;
+	while (cur != NULL) {
+	    if (cur->stream != NULL) {
+		xmlFreeStreamComp(cur->stream);
+		cur->stream = NULL;
+	    }
+	    cur = cur->next;
+	}
+    }
+
+    return(ret);
+error:
+    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
+    if (ret != NULL) xmlFreePattern(ret);
+    if (tmp != NULL) xmlFree(tmp);
+    return(NULL);
+}
+
+/**
+ * xmlPatternMatch:
+ * @comp: the precompiled pattern
+ * @node: a node
+ *
+ * Test whether the node matches the pattern
+ *
+ * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
+ */
+int
+xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
+{
+    int ret = 0;
+
+    if ((comp == NULL) || (node == NULL))
+        return(-1);
+
+    while (comp != NULL) {
+        ret = xmlPatMatch(comp, node);
+	if (ret != 0)
+	    return(ret);
+	comp = comp->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlPatternGetStreamCtxt:
+ * @comp: the precompiled pattern
+ *
+ * Get a streaming context for that pattern
+ * Use xmlFreeStreamCtxt to free the context.
+ *
+ * Returns a pointer to the context or NULL in case of failure
+ */
+xmlStreamCtxtPtr
+xmlPatternGetStreamCtxt(xmlPatternPtr comp)
+{
+    xmlStreamCtxtPtr ret = NULL, cur;
+
+    if ((comp == NULL) || (comp->stream == NULL))
+        return(NULL);
+
+    while (comp != NULL) {
+        if (comp->stream == NULL)
+	    goto failed;
+	cur = xmlNewStreamCtxt(comp->stream);
+	if (cur == NULL)
+	    goto failed;
+	if (ret == NULL)
+	    ret = cur;
+	else {
+	    cur->next = ret->next;
+	    ret->next = cur;
+	}
+	cur->flags = comp->flags;
+	comp = comp->next;
+    }
+    return(ret);
+failed:
+    xmlFreeStreamCtxt(ret);
+    return(NULL);
+}
+
+/**
+ * xmlPatternStreamable:
+ * @comp: the precompiled pattern
+ *
+ * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt()
+ * should work.
+ *
+ * Returns 1 if streamable, 0 if not and -1 in case of error.
+ */
+int
+xmlPatternStreamable(xmlPatternPtr comp) {
+    if (comp == NULL)
+        return(-1);
+    while (comp != NULL) {
+        if (comp->stream == NULL)
+	    return(0);
+	comp = comp->next;
+    }
+    return(1);
+}
+
+/**
+ * xmlPatternMaxDepth:
+ * @comp: the precompiled pattern
+ *
+ * Check the maximum depth reachable by a pattern
+ *
+ * Returns -2 if no limit (using //), otherwise the depth,
+ *         and -1 in case of error
+ */
+int
+xmlPatternMaxDepth(xmlPatternPtr comp) {
+    int ret = 0, i;
+    if (comp == NULL)
+        return(-1);
+    while (comp != NULL) {
+        if (comp->stream == NULL)
+	    return(-1);
+	for (i = 0;i < comp->stream->nbStep;i++)
+	    if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)
+	        return(-2);
+	if (comp->stream->nbStep > ret)
+	    ret = comp->stream->nbStep;
+	comp = comp->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlPatternMinDepth:
+ * @comp: the precompiled pattern
+ *
+ * Check the minimum depth reachable by a pattern, 0 mean the / or . are
+ * part of the set.
+ *
+ * Returns -1 in case of error otherwise the depth,
+ *         
+ */
+int
+xmlPatternMinDepth(xmlPatternPtr comp) {
+    int ret = 12345678;
+    if (comp == NULL)
+        return(-1);
+    while (comp != NULL) {
+        if (comp->stream == NULL)
+	    return(-1);
+	if (comp->stream->nbStep < ret)
+	    ret = comp->stream->nbStep;
+	if (ret == 0)
+	    return(0);
+	comp = comp->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlPatternFromRoot:
+ * @comp: the precompiled pattern
+ *
+ * Check if the pattern must be looked at from the root.
+ *
+ * Returns 1 if true, 0 if false and -1 in case of error
+ */
+int
+xmlPatternFromRoot(xmlPatternPtr comp) {
+    if (comp == NULL)
+        return(-1);
+    while (comp != NULL) {
+        if (comp->stream == NULL)
+	    return(-1);
+	if (comp->flags & PAT_FROM_ROOT)
+	    return(1);
+	comp = comp->next;
+    }
+    return(0);
+
+}
+
+#define bottom_pattern
+#include "elfgcchack.h"
+#endif /* LIBXML_PATTERN_ENABLED */
diff --git a/src/regressions.py b/src/regressions.py
new file mode 100755
index 0000000..b068ce1
--- /dev/null
+++ b/src/regressions.py
@@ -0,0 +1,351 @@
+#!/usr/bin/env python3 -u
+
+import glob, os, string, sys, _thread, time
+# import difflib
+import libxml2
+
+###
+#
+# This is a "Work in Progress" attempt at a python script to run the
+# various regression tests.  The rationale for this is that it should be
+# possible to run this on most major platforms, including those (such as
+# Windows) which don't support gnu Make.
+#
+# The script is driven by a parameter file which defines the various tests
+# to be run, together with the unique settings for each of these tests.  A
+# script for Linux is included (regressions.xml), with comments indicating
+# the significance of the various parameters.  To run the tests under Windows,
+# edit regressions.xml and remove the comment around the default parameter
+# "<execpath>" (i.e. make it point to the location of the binary executables).
+#
+# Note that this current version requires the Python bindings for libxml2 to
+# have been previously installed and accessible
+#
+# See Copyright for the status of this software.
+# William Brack (wbrack@mmm.com.hk)
+#
+###
+defaultParams = {}	# will be used as a dictionary to hold the parsed params
+
+# This routine is used for comparing the expected stdout / stdin with the results.
+# The expected data has already been read in; the result is a file descriptor.
+# Within the two sets of data, lines may begin with a path string.  If so, the
+# code "relativises" it by removing the path component.  The first argument is a
+# list already read in by a separate thread; the second is a file descriptor.
+# The two 'base' arguments are to let me "relativise" the results files, allowing
+# the script to be run from any directory.
+def compFiles(res, expected, base1, base2):
+    l1 = len(base1)
+    exp = expected.readlines()
+    expected.close()
+    # the "relativisation" is done here
+    for i in range(len(res)):
+        j = string.find(res[i],base1)
+        if (j == 0) or ((j == 2) and (res[i][0:2] == './')):
+            col = string.find(res[i],':')
+            if col > 0:
+                start = string.rfind(res[i][:col], '/')
+                if start > 0:
+                    res[i] = res[i][start+1:]
+
+    for i in range(len(exp)):
+        j = string.find(exp[i],base2)
+        if (j == 0) or ((j == 2) and (exp[i][0:2] == './')):
+            col = string.find(exp[i],':')
+            if col > 0:
+                start = string.rfind(exp[i][:col], '/')
+                if start > 0:
+                    exp[i] = exp[i][start+1:]
+
+    ret = 0
+    # ideally we would like to use difflib functions here to do a
+    # nice comparison of the two sets.  Unfortunately, during testing
+    # (using python 2.3.3 and 2.3.4) the following code went into
+    # a dead loop under windows.  I'll pursue this later.
+#    diff = difflib.ndiff(res, exp)
+#    diff = list(diff)
+#    for line in diff:
+#        if line[:2] != '  ':
+#            print string.strip(line)
+#            ret = -1
+
+    # the following simple compare is fine for when the two data sets
+    # (actual result vs. expected result) are equal, which should be true for
+    # us.  Unfortunately, if the test fails it's not nice at all.
+    rl = len(res)
+    el = len(exp)
+    if el != rl:
+        print('Length of expected is %d, result is %d' % (el, rl))
+	ret = -1
+    for i in range(min(el, rl)):
+        if string.strip(res[i]) != string.strip(exp[i]):
+            print('+:%s-:%s' % (res[i], exp[i]))
+            ret = -1
+    if el > rl:
+        for i in range(rl, el):
+            print('-:%s' % exp[i])
+            ret = -1
+    elif rl > el:
+        for i in range (el, rl):
+            print('+:%s' % res[i])
+            ret = -1
+    return ret
+
+# Separate threads to handle stdout and stderr are created to run this function
+def readPfile(file, list, flag):
+    data = file.readlines()	# no call by reference, so I cheat
+    for l in data:
+        list.append(l)
+    file.close()
+    flag.append('ok')
+
+# This routine runs the test program (e.g. xmllint)
+def runOneTest(testDescription, filename, inbase, errbase):
+    if 'execpath' in testDescription:
+        dir = testDescription['execpath'] + '/'
+    else:
+        dir = ''
+    cmd = os.path.abspath(dir + testDescription['testprog'])
+    if 'flag' in testDescription:
+        for f in string.split(testDescription['flag']):
+            cmd += ' ' + f
+    if 'stdin' not in testDescription:
+        cmd += ' ' + inbase + filename
+    if 'extarg' in testDescription:
+        cmd += ' ' + testDescription['extarg']
+
+    noResult = 0
+    expout = None
+    if 'resext' in testDescription:
+        if testDescription['resext'] == 'None':
+            noResult = 1
+        else:
+            ext = '.' + testDescription['resext']
+    else:
+        ext = ''
+    if not noResult:
+        try:
+            fname = errbase + filename + ext
+            expout = open(fname, 'rt')
+        except:
+            print("Can't open result file %s - bypassing test" % fname)
+            return
+
+    noErrors = 0
+    if 'reserrext' in testDescription:
+        if testDescription['reserrext'] == 'None':
+            noErrors = 1
+        else:
+            if len(testDescription['reserrext'])>0:
+                ext = '.' + testDescription['reserrext']
+            else:
+                ext = ''
+    else:
+        ext = ''
+    if not noErrors:
+        try:
+            fname = errbase + filename + ext
+            experr = open(fname, 'rt')
+        except:
+            experr = None
+    else:
+        experr = None
+
+    pin, pout, perr = os.popen3(cmd)
+    if 'stdin' in testDescription:
+        infile = open(inbase + filename, 'rt')
+        pin.writelines(infile.readlines())
+        infile.close()
+        pin.close()
+
+    # popen is great fun, but can lead to the old "deadly embrace", because
+    # synchronizing the writing (by the task being run) of stdout and stderr
+    # with respect to the reading (by this task) is basically impossible.  I
+    # tried several ways to cheat, but the only way I have found which works
+    # is to do a *very* elementary multi-threading approach.  We can only hope
+    # that Python threads are implemented on the target system (it's okay for
+    # Linux and Windows)
+
+    th1Flag = []	# flags to show when threads finish
+    th2Flag = []
+    outfile = []	# lists to contain the pipe data
+    errfile = []
+    th1 = _thread.start_new_thread(readPfile, (pout, outfile, th1Flag))
+    th2 = _thread.start_new_thread(readPfile, (perr, errfile, th2Flag))
+    while (len(th1Flag)==0) or (len(th2Flag)==0):
+        time.sleep(0.001)
+    if not noResult:
+        ret = compFiles(outfile, expout, inbase, 'test/')
+        if ret != 0:
+            print('trouble with %s' % cmd)
+    else:
+        if len(outfile) != 0:
+            for l in outfile:
+                print(l)
+            print('trouble with %s' % cmd)
+    if experr != None:
+        ret = compFiles(errfile, experr, inbase, 'test/')
+        if ret != 0:
+            print('trouble with %s' % cmd)
+    else:
+        if not noErrors:
+            if len(errfile) != 0:
+                for l in errfile:
+                    print(l)
+                print('trouble with %s' % cmd)
+
+    if 'stdin' not in testDescription:
+        pin.close()
+
+# This routine is called by the parameter decoding routine whenever the end of a
+# 'test' section is encountered.  Depending upon file globbing, a large number of
+# individual tests may be run.
+def runTest(description):
+    testDescription = defaultParams.copy()		# set defaults
+    testDescription.update(description)			# override with current ent
+    if 'testname' in testDescription:
+        print("## %s" % testDescription['testname'])
+    if not 'file' in testDescription:
+        print("No file specified - can't run this test!")
+        return
+    # Set up the source and results directory paths from the decoded params
+    dir = ''
+    if 'srcdir' in testDescription:
+        dir += testDescription['srcdir'] + '/'
+    if 'srcsub' in testDescription:
+        dir += testDescription['srcsub'] + '/'
+
+    rdir = ''
+    if 'resdir' in testDescription:
+        rdir += testDescription['resdir'] + '/'
+    if 'ressub' in testDescription:
+        rdir += testDescription['ressub'] + '/'
+
+    testFiles = glob.glob(os.path.abspath(dir + testDescription['file']))
+    if testFiles == []:
+        print("No files result from '%s'" % testDescription['file'])
+        return
+
+    # Some test programs just don't work (yet).  For now we exclude them.
+    count = 0
+    excl = []
+    if 'exclfile' in testDescription:
+        for f in string.split(testDescription['exclfile']):
+            glb = glob.glob(dir + f)
+            for g in glb:
+                excl.append(os.path.abspath(g))
+
+    # Run the specified test program
+    for f in testFiles:
+        if not os.path.isdir(f):
+            if f not in excl:
+                count = count + 1
+                runOneTest(testDescription, os.path.basename(f), dir, rdir)
+
+#
+# The following classes are used with the xmlreader interface to interpret the
+# parameter file.  Once a test section has been identified, runTest is called
+# with a dictionary containing the parsed results of the interpretation.
+#
+
+class testDefaults:
+    curText = ''	# accumulates text content of parameter
+
+    def addToDict(self, key):
+        txt = string.strip(self.curText)
+#        if txt == '':
+#            return
+        if key not in defaultParams:
+            defaultParams[key] = txt
+        else:
+            defaultParams[key] += ' ' + txt
+        
+    def processNode(self, reader, curClass):
+        if reader.Depth() == 2:
+            if reader.NodeType() == 1:
+                self.curText = ''	# clear the working variable
+            elif reader.NodeType() == 15:
+                if (reader.Name() != '#text') and (reader.Name() != '#comment'):
+                    self.addToDict(reader.Name())
+        elif reader.Depth() == 3:
+            if reader.Name() == '#text':
+                self.curText += reader.Value()
+
+        elif reader.NodeType() == 15:	# end of element
+            print("Defaults have been set to:")
+            for k in list(defaultParams.keys()):
+                print("   %s : '%s'" % (k, defaultParams[k]))
+            curClass = rootClass()
+        return curClass
+
+
+class testClass:
+    def __init__(self):
+        self.testParams = {}	# start with an empty set of params
+        self.curText = ''	# and empty text
+
+    def addToDict(self, key):
+        data = string.strip(self.curText)
+        if key not in self.testParams:
+            self.testParams[key] = data
+        else:
+            if self.testParams[key] != '':
+                data = ' ' + data
+            self.testParams[key] += data
+
+    def processNode(self, reader, curClass):
+        if reader.Depth() == 2:
+            if reader.NodeType() == 1:
+                self.curText = ''	# clear the working variable
+                if reader.Name() not in self.testParams:
+                    self.testParams[reader.Name()] = ''
+            elif reader.NodeType() == 15:
+                if (reader.Name() != '#text') and (reader.Name() != '#comment'):
+                    self.addToDict(reader.Name())
+        elif reader.Depth() == 3:
+            if reader.Name() == '#text':
+                self.curText += reader.Value()
+
+        elif reader.NodeType() == 15:	# end of element
+            runTest(self.testParams)
+            curClass = rootClass()
+        return curClass
+
+
+class rootClass:
+    def processNode(self, reader, curClass):
+        if reader.Depth() == 0:
+            return curClass
+        if reader.Depth() != 1:
+            print("Unexpected junk: Level %d, type %d, name %s" % (
+                  reader.Depth(), reader.NodeType(), reader.Name()))
+            return curClass
+        if reader.Name() == 'test':
+            curClass = testClass()
+            curClass.testParams = {}
+        elif reader.Name() == 'defaults':
+            curClass = testDefaults()
+        return curClass
+
+def streamFile(filename):
+    try:
+        reader = libxml2.newTextReaderFilename(filename)
+    except:
+        print("unable to open %s" % (filename))
+        return
+
+    curClass = rootClass()
+    ret = reader.Read()
+    while ret == 1:
+        curClass = curClass.processNode(reader, curClass)
+        ret = reader.Read()
+
+    if ret != 0:
+        print("%s : failed to parse" % (filename))
+
+# OK, we're finished with all the routines.  Now for the main program:-
+if len(sys.argv) != 2:
+    print("Usage: maketest {filename}")
+    sys.exit(-1)
+
+streamFile(sys.argv[1])
diff --git a/src/regressions.xml b/src/regressions.xml
new file mode 100644
index 0000000..c78838a
--- /dev/null
+++ b/src/regressions.xml
@@ -0,0 +1,226 @@
+<RegressionTests>
+<!--
+  Within the following test descriptions the possible elements are:
+    Element Name    Description
+     testname       Plain text name of test
+     execpath       pathname for test program(s)
+     testprog       program to run for the test 
+     flag           flags for program (may have several)
+     file           filename of input file (several, or glob ok)
+     exclfile       filename to be excuded (several, or glob ok)
+     srcdir         global source directory for input file(s)
+     srcsub         subdirectory for input
+     resdir         directory for results file(s)
+     ressub         subdirectory for results    
+     resext         extension for expected result
+     reserrext      extension for error result ('None' => no chk)
+     extarg         additional argument for command
+     errexcl        string to ignore when checking diffs
+     stdin          pipe input file to stdin
+-->
+
+<!--
+  Note:  These defaults are set to run from the root of the build directory
+-->
+  <defaults>
+    <testname>noname</testname>
+<!--    <execpath>win32/bin.msvc</execpath> -->
+    <execpath>.</execpath>
+    <testprog>xmllint</testprog>
+    <srcdir>test</srcdir>
+    <resdir>result</resdir>
+    <file>*.xml</file>
+    <reserrext>err</reserrext>
+    <errexcl/>
+  </defaults>
+
+  <test>
+    <testname>XML Regression Tests</testname>
+    <errexcl>failed to load external entity</errexcl>
+  </test>
+  <test>
+    <testname>XML Entity Subst Regression Tests</testname>
+    <ressub>noent</ressub>
+    <flag>--noent</flag>
+  </test>
+  <test>
+    <testname>XML Namespaces Regression Tests</testname>
+    <srcsub>namespaces</srcsub>
+    <ressub>namespaces</ressub>
+  </test>
+  <test>
+    <testname>xml:id Regression Tests</testname>
+    <testprog>testXPath</testprog>
+    <srcsub>xmlid</srcsub>
+    <ressub>xmlid</ressub>
+    <flag>-i</flag>
+    <file>id_*.xml</file>
+    <extarg>"id('bar')"</extarg>
+  </test>
+  <test>
+    <testname>Error Cases Regression Tests</testname>
+    <srcsub>errors</srcsub>
+    <ressub>errors</ressub>
+  </test>
+  <test>
+    <testname>Error Cases Stream Regression Tests</testname>
+    <srcsub>errors</srcsub>
+    <ressub>errors</ressub>
+    <reserrext>str</reserrext>
+    <flag>--stream</flag>
+  </test>
+  <test>
+    <testname>Reader Regression Tests</testname>
+    <resext>rdr</resext>
+    <flag>--nonet</flag>
+    <flag>--debug</flag>
+    <flag>--stream</flag>
+    <file>*</file>
+    <reserrext>None</reserrext>
+  </test>
+  <test>
+    <testname>Walker Regression Tests</testname>
+    <resext>rdr</resext>
+    <flag>--nonet</flag>
+    <flag>--debug</flag>
+    <flag>--walker</flag>
+    <file>*</file>
+    <reserrext>None</reserrext>
+  </test>
+  <test>
+    <testname>Reader Entities Substitution Regression Tests</testname>
+    <resext>rde</resext>
+    <flag>--nonet</flag>
+    <flag>--debug</flag>
+    <flag>--stream</flag>
+    <flag>--noent</flag>
+    <file>*</file>
+    <reserrext>None</reserrext>
+  </test>
+  <test>
+    <testname>SAX Callbacks Regression Tests</testname>
+    <testprog>testSAX</testprog>
+    <resext>sax</resext>
+    <file>*</file>
+    <exclfile>utf16*.xml</exclfile>
+    <reserrext>None</reserrext>
+  </test>
+  <test>
+    <testname>XML Push Regression Tests</testname>
+    <flag>--push</flag>
+    <errexcl>failed to load external entity</errexcl>
+  </test>
+  <test>
+    <testname>HTML Regression Tests</testname>
+    <testprog>testHTML</testprog>
+    <srcsub>HTML</srcsub>
+    <ressub>HTML</ressub>
+    <file>*</file>
+    <exclfile>wired.html</exclfile>
+  </test>
+  <test>
+    <testname>Push HTML Regression Tests</testname>
+    <testprog>testHTML</testprog>
+    <flag>--push</flag>
+    <srcsub>HTML</srcsub>
+    <ressub>HTML</ressub>
+    <file>*</file>
+  </test>
+  <test>
+    <testname>HTML SAX Regression Tests</testname>
+    <testprog>testHTML</testprog>
+    <flag>--sax</flag>
+    <srcsub>HTML</srcsub>
+    <ressub>HTML</ressub>
+    <resext>sax</resext>
+    <reserrext>None</reserrext>
+    <file>*</file>
+  </test>
+  <test>
+    <testname>Push HTML SAX Regression Tests</testname>
+    <testprog>testHTML</testprog>
+    <flag>--sax</flag>
+    <flag>--push</flag>
+    <srcsub>HTML</srcsub>
+    <ressub>HTML</ressub>
+    <resext>sax</resext>
+    <reserrext>None</reserrext>
+    <file>*</file>
+  </test>
+  <test>
+    <testname>Valid Documents Regression Tests</testname>
+    <srcsub>VCM</srcsub>
+    <ressub>VCM</ressub>
+    <resext>None</resext>
+    <reserrext>None</reserrext>
+    <file>*</file>
+    <flag>--valid</flag>
+    <flag>--noout</flag>
+    <flag>--nowarning</flag>
+  </test>
+  <test>
+    <testname>Validity Checking Regression Tests</testname>
+    <srcsub>VC</srcsub>
+    <ressub>VC</ressub>
+    <resext>None</resext>
+    <reserrext/>
+    <file>*</file>
+    <flag>--valid</flag>
+    <flag>--noout</flag>
+  </test>
+  <test>
+    <testname>General Documents Valid Regression Tests</testname>
+    <srcsub>valid</srcsub>
+    <ressub>valid</ressub>
+    <file>*</file>
+    <flag>--valid</flag>
+  </test>
+  <test>
+    <testname>URI Module Regression Tests (1)</testname>
+    <testprog>testURI</testprog>
+    <srcsub>URI</srcsub>
+    <stdin/>
+    <ressub>URI</ressub>
+    <reserrext>None</reserrext>
+    <file>*.data</file>
+    <!-- Note - the following arg needs to use ", not ' -->
+    <flag>-base "http://foo.com/path/to/index.html?orig#help"</flag>
+  </test>
+  <test>
+    <testname>URI Module Regression Tests (2)</testname>
+    <testprog>testURI</testprog>
+    <srcsub>URI</srcsub>
+    <stdin/>
+    <ressub>URI</ressub>
+    <reserrext>None</reserrext>
+    <file>*.uri</file>
+  </test>
+  <test>
+    <testname>XPath Regression Tests (1)</testname>
+    <testprog>testXPath</testprog>
+    <srcsub>XPath/expr</srcsub>
+    <ressub>XPath/expr</ressub>
+    <file>*</file>
+    <flag>-f</flag>
+    <flag>--expr</flag>
+  </test>
+  <test>
+    <testname>XInclude Regression Tests</testname>
+    <srcsub>XInclude/docs</srcsub>
+    <ressub>XInclude</ressub>
+    <file>*</file>
+    <flag>--nowarning</flag>
+    <flag>--xinclude</flag>
+  </test>
+  <test>
+    <testname>XInclude xmlReader Regression Tests</testname>
+    <srcsub>XInclude/docs</srcsub>
+    <ressub>XInclude</ressub>
+    <resext>rdr</resext>
+    <file>*</file>
+    <flag>--nowarning</flag>
+    <flag>--xinclude</flag>
+    <flag>--stream</flag>
+    <flag>--debug</flag>
+  </test>
+</RegressionTests>
diff --git a/src/relaxng.c b/src/relaxng.c
new file mode 100644
index 0000000..6dbc499
--- /dev/null
+++ b/src/relaxng.c
@@ -0,0 +1,11003 @@
+/*
+ * relaxng.c : implementation of the Relax-NG handling and validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+/**
+ * TODO:
+ * - add support for DTD compatibility spec
+ *   http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
+ * - report better mem allocations pbms at runtime and abort immediately.
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <string.h>
+#include <stdio.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/hash.h>
+#include <libxml/uri.h>
+
+#include <libxml/relaxng.h>
+
+#include <libxml/xmlschemastypes.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlschemastypes.h>
+
+/*
+ * The Relax-NG namespace
+ */
+static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
+    "http://relaxng.org/ns/structure/1.0";
+
+#define IS_RELAXNG(node, type)						\
+   ((node != NULL) && (node->ns != NULL) &&				\
+    (xmlStrEqual(node->name, (const xmlChar *) type)) &&		\
+    (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
+
+
+#if 0
+#define DEBUG 1
+
+#define DEBUG_GRAMMAR 1
+
+#define DEBUG_CONTENT 1
+
+#define DEBUG_TYPE 1
+
+#define DEBUG_VALID 1
+
+#define DEBUG_INTERLEAVE 1
+
+#define DEBUG_LIST 1
+
+#define DEBUG_INCLUDE 1 
+
+#define DEBUG_ERROR 1
+
+#define DEBUG_COMPILE 1
+
+#define DEBUG_PROGRESSIVE 1
+#endif
+
+#define MAX_ERROR 5
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
+typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
+
+typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
+typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
+
+typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
+typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
+
+typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
+typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
+
+typedef enum {
+    XML_RELAXNG_COMBINE_UNDEFINED = 0,  /* undefined */
+    XML_RELAXNG_COMBINE_CHOICE, /* choice */
+    XML_RELAXNG_COMBINE_INTERLEAVE      /* interleave */
+} xmlRelaxNGCombine;
+
+typedef enum {
+    XML_RELAXNG_CONTENT_ERROR = -1,
+    XML_RELAXNG_CONTENT_EMPTY = 0,
+    XML_RELAXNG_CONTENT_SIMPLE,
+    XML_RELAXNG_CONTENT_COMPLEX
+} xmlRelaxNGContentType;
+
+typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
+typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
+
+struct _xmlRelaxNGGrammar {
+    xmlRelaxNGGrammarPtr parent;        /* the parent grammar if any */
+    xmlRelaxNGGrammarPtr children;      /* the children grammar if any */
+    xmlRelaxNGGrammarPtr next;  /* the next grammar if any */
+    xmlRelaxNGDefinePtr start;  /* <start> content */
+    xmlRelaxNGCombine combine;  /* the default combine value */
+    xmlRelaxNGDefinePtr startList;      /* list of <start> definitions */
+    xmlHashTablePtr defs;       /* define* */
+    xmlHashTablePtr refs;       /* references */
+};
+
+
+typedef enum {
+    XML_RELAXNG_NOOP = -1,      /* a no operation from simplification  */
+    XML_RELAXNG_EMPTY = 0,      /* an empty pattern */
+    XML_RELAXNG_NOT_ALLOWED,    /* not allowed top */
+    XML_RELAXNG_EXCEPT,         /* except present in nameclass defs */
+    XML_RELAXNG_TEXT,           /* textual content */
+    XML_RELAXNG_ELEMENT,        /* an element */
+    XML_RELAXNG_DATATYPE,       /* extenal data type definition */
+    XML_RELAXNG_PARAM,          /* extenal data type parameter */
+    XML_RELAXNG_VALUE,          /* value from an extenal data type definition */
+    XML_RELAXNG_LIST,           /* a list of patterns */
+    XML_RELAXNG_ATTRIBUTE,      /* an attrbute following a pattern */
+    XML_RELAXNG_DEF,            /* a definition */
+    XML_RELAXNG_REF,            /* reference to a definition */
+    XML_RELAXNG_EXTERNALREF,    /* reference to an external def */
+    XML_RELAXNG_PARENTREF,      /* reference to a def in the parent grammar */
+    XML_RELAXNG_OPTIONAL,       /* optional patterns */
+    XML_RELAXNG_ZEROORMORE,     /* zero or more non empty patterns */
+    XML_RELAXNG_ONEORMORE,      /* one or more non empty patterns */
+    XML_RELAXNG_CHOICE,         /* a choice between non empty patterns */
+    XML_RELAXNG_GROUP,          /* a pair/group of non empty patterns */
+    XML_RELAXNG_INTERLEAVE,     /* interleaving choice of non-empty patterns */
+    XML_RELAXNG_START           /* Used to keep track of starts on grammars */
+} xmlRelaxNGType;
+
+#define IS_NULLABLE		(1 << 0)
+#define IS_NOT_NULLABLE		(1 << 1)
+#define IS_INDETERMINIST	(1 << 2)
+#define IS_MIXED		(1 << 3)
+#define IS_TRIABLE		(1 << 4)
+#define IS_PROCESSED		(1 << 5)
+#define IS_COMPILABLE		(1 << 6)
+#define IS_NOT_COMPILABLE	(1 << 7)
+#define IS_EXTERNAL_REF	        (1 << 8)
+
+struct _xmlRelaxNGDefine {
+    xmlRelaxNGType type;        /* the type of definition */
+    xmlNodePtr node;            /* the node in the source */
+    xmlChar *name;              /* the element local name if present */
+    xmlChar *ns;                /* the namespace local name if present */
+    xmlChar *value;             /* value when available */
+    void *data;                 /* data lib or specific pointer */
+    xmlRelaxNGDefinePtr content;        /* the expected content */
+    xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
+    xmlRelaxNGDefinePtr next;   /* list within grouping sequences */
+    xmlRelaxNGDefinePtr attrs;  /* list of attributes for elements */
+    xmlRelaxNGDefinePtr nameClass;      /* the nameClass definition if any */
+    xmlRelaxNGDefinePtr nextHash;       /* next define in defs/refs hash tables */
+    short depth;                /* used for the cycle detection */
+    short dflags;               /* define related flags */
+    xmlRegexpPtr contModel;     /* a compiled content model if available */
+};
+
+/**
+ * _xmlRelaxNG:
+ *
+ * A RelaxNGs definition
+ */
+struct _xmlRelaxNG {
+    void *_private;             /* unused by the library for users or bindings */
+    xmlRelaxNGGrammarPtr topgrammar;
+    xmlDocPtr doc;
+
+    int idref;                  /* requires idref checking */
+
+    xmlHashTablePtr defs;       /* define */
+    xmlHashTablePtr refs;       /* references */
+    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
+    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
+    int defNr;                  /* number of defines used */
+    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */
+
+};
+
+#define XML_RELAXNG_IN_ATTRIBUTE	(1 << 0)
+#define XML_RELAXNG_IN_ONEORMORE	(1 << 1)
+#define XML_RELAXNG_IN_LIST		(1 << 2)
+#define XML_RELAXNG_IN_DATAEXCEPT	(1 << 3)
+#define XML_RELAXNG_IN_START		(1 << 4)
+#define XML_RELAXNG_IN_OOMGROUP		(1 << 5)
+#define XML_RELAXNG_IN_OOMINTERLEAVE	(1 << 6)
+#define XML_RELAXNG_IN_EXTERNALREF	(1 << 7)
+#define XML_RELAXNG_IN_ANYEXCEPT	(1 << 8)
+#define XML_RELAXNG_IN_NSEXCEPT		(1 << 9)
+
+struct _xmlRelaxNGParserCtxt {
+    void *userData;             /* user specific data block */
+    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
+    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
+    xmlRelaxNGValidErr err;
+
+    xmlRelaxNGPtr schema;       /* The schema in use */
+    xmlRelaxNGGrammarPtr grammar;       /* the current grammar */
+    xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
+    int flags;                  /* parser flags */
+    int nbErrors;               /* number of errors at parse time */
+    int nbWarnings;             /* number of warnings at parse time */
+    const xmlChar *define;      /* the current define scope */
+    xmlRelaxNGDefinePtr def;    /* the current define */
+
+    int nbInterleaves;
+    xmlHashTablePtr interleaves;        /* keep track of all the interleaves */
+
+    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
+    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
+    xmlChar *URL;
+    xmlDocPtr document;
+
+    int defNr;                  /* number of defines used */
+    int defMax;                 /* number of defines aloocated */
+    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */
+
+    const char *buffer;
+    int size;
+
+    /* the document stack */
+    xmlRelaxNGDocumentPtr doc;  /* Current parsed external ref */
+    int docNr;                  /* Depth of the parsing stack */
+    int docMax;                 /* Max depth of the parsing stack */
+    xmlRelaxNGDocumentPtr *docTab;      /* array of docs */
+
+    /* the include stack */
+    xmlRelaxNGIncludePtr inc;   /* Current parsed include */
+    int incNr;                  /* Depth of the include parsing stack */
+    int incMax;                 /* Max depth of the parsing stack */
+    xmlRelaxNGIncludePtr *incTab;       /* array of incs */
+
+    int idref;                  /* requires idref checking */
+
+    /* used to compile content models */
+    xmlAutomataPtr am;          /* the automata */
+    xmlAutomataStatePtr state;  /* used to build the automata */
+
+    int crng;			/* compact syntax and other flags */
+    int freedoc;		/* need to free the document */
+};
+
+#define FLAGS_IGNORABLE		1
+#define FLAGS_NEGATIVE		2
+#define FLAGS_MIXED_CONTENT	4
+#define FLAGS_NOERROR		8
+
+/**
+ * xmlRelaxNGInterleaveGroup:
+ *
+ * A RelaxNGs partition set associated to lists of definitions
+ */
+typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
+typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
+struct _xmlRelaxNGInterleaveGroup {
+    xmlRelaxNGDefinePtr rule;   /* the rule to satisfy */
+    xmlRelaxNGDefinePtr *defs;  /* the array of element definitions */
+    xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
+};
+
+#define IS_DETERMINIST		1
+#define IS_NEEDCHECK		2
+
+/**
+ * xmlRelaxNGPartitions:
+ *
+ * A RelaxNGs partition associated to an interleave group
+ */
+typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
+typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
+struct _xmlRelaxNGPartition {
+    int nbgroups;               /* number of groups in the partitions */
+    xmlHashTablePtr triage;     /* hash table used to direct nodes to the
+                                 * right group when possible */
+    int flags;                  /* determinist ? */
+    xmlRelaxNGInterleaveGroupPtr *groups;
+};
+
+/**
+ * xmlRelaxNGValidState:
+ *
+ * A RelaxNGs validation state
+ */
+#define MAX_ATTR 20
+typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
+typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
+struct _xmlRelaxNGValidState {
+    xmlNodePtr node;            /* the current node */
+    xmlNodePtr seq;             /* the sequence of children left to validate */
+    int nbAttrs;                /* the number of attributes */
+    int maxAttrs;               /* the size of attrs */
+    int nbAttrLeft;             /* the number of attributes left to validate */
+    xmlChar *value;             /* the value when operating on string */
+    xmlChar *endvalue;          /* the end value when operating on string */
+    xmlAttrPtr *attrs;          /* the array of attributes */
+};
+
+/**
+ * xmlRelaxNGStates:
+ *
+ * A RelaxNGs container for validation state
+ */
+typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
+typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
+struct _xmlRelaxNGStates {
+    int nbState;                /* the number of states */
+    int maxState;               /* the size of the array */
+    xmlRelaxNGValidStatePtr *tabState;
+};
+
+#define ERROR_IS_DUP	1
+
+/**
+ * xmlRelaxNGValidError:
+ *
+ * A RelaxNGs validation error
+ */
+typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
+typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
+struct _xmlRelaxNGValidError {
+    xmlRelaxNGValidErr err;     /* the error number */
+    int flags;                  /* flags */
+    xmlNodePtr node;            /* the current node */
+    xmlNodePtr seq;             /* the current child */
+    const xmlChar *arg1;        /* first arg */
+    const xmlChar *arg2;        /* second arg */
+};
+
+/**
+ * xmlRelaxNGValidCtxt:
+ *
+ * A RelaxNGs validation context
+ */
+
+struct _xmlRelaxNGValidCtxt {
+    void *userData;             /* user specific data block */
+    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
+    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
+    int nbErrors;               /* number of errors in validation */
+
+    xmlRelaxNGPtr schema;       /* The schema in use */
+    xmlDocPtr doc;              /* the document being validated */
+    int flags;                  /* validation flags */
+    int depth;                  /* validation depth */
+    int idref;                  /* requires idref checking */
+    int errNo;                  /* the first error found */
+
+    /*
+     * Errors accumulated in branches may have to be stacked to be
+     * provided back when it's sure they affect validation.
+     */
+    xmlRelaxNGValidErrorPtr err;        /* Last error */
+    int errNr;                  /* Depth of the error stack */
+    int errMax;                 /* Max depth of the error stack */
+    xmlRelaxNGValidErrorPtr errTab;     /* stack of errors */
+
+    xmlRelaxNGValidStatePtr state;      /* the current validation state */
+    xmlRelaxNGStatesPtr states; /* the accumulated state list */
+
+    xmlRelaxNGStatesPtr freeState;      /* the pool of free valid states */
+    int freeStatesNr;
+    int freeStatesMax;
+    xmlRelaxNGStatesPtr *freeStates;    /* the pool of free state groups */
+
+    /*
+     * This is used for "progressive" validation
+     */
+    xmlRegExecCtxtPtr elem;     /* the current element regexp */
+    int elemNr;                 /* the number of element validated */
+    int elemMax;                /* the max depth of elements */
+    xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
+    int pstate;                 /* progressive state */
+    xmlNodePtr pnode;           /* the current node */
+    xmlRelaxNGDefinePtr pdef;   /* the non-streamable definition */
+    int perr;                   /* signal error in content model
+                                 * outside the regexp */
+};
+
+/**
+ * xmlRelaxNGInclude:
+ *
+ * Structure associated to a RelaxNGs document element
+ */
+struct _xmlRelaxNGInclude {
+    xmlRelaxNGIncludePtr next;  /* keep a chain of includes */
+    xmlChar *href;              /* the normalized href value */
+    xmlDocPtr doc;              /* the associated XML document */
+    xmlRelaxNGDefinePtr content;        /* the definitions */
+    xmlRelaxNGPtr schema;       /* the schema */
+};
+
+/**
+ * xmlRelaxNGDocument:
+ *
+ * Structure associated to a RelaxNGs document element
+ */
+struct _xmlRelaxNGDocument {
+    xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
+    xmlChar *href;              /* the normalized href value */
+    xmlDocPtr doc;              /* the associated XML document */
+    xmlRelaxNGDefinePtr content;        /* the definitions */
+    xmlRelaxNGPtr schema;       /* the schema */
+    int externalRef;            /* 1 if an external ref */
+};
+
+
+/************************************************************************
+ *									*
+ * 		Some factorized error routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlRngPErrMemory:
+ * @ctxt:  an Relax-NG parser context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        if (ctxt->serror != NULL)
+	    schannel = ctxt->serror;
+	else
+	    channel = ctxt->error;
+        data = ctxt->userData;
+        ctxt->nbErrors++;
+    }
+    if (extra)
+        __xmlRaiseError(schannel, channel, data,
+                        NULL, NULL, XML_FROM_RELAXNGP,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+                        NULL, NULL, 0, 0,
+                        "Memory allocation failed : %s\n", extra);
+    else
+        __xmlRaiseError(schannel, channel, data,
+                        NULL, NULL, XML_FROM_RELAXNGP,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
+                        NULL, NULL, 0, 0, "Memory allocation failed\n");
+}
+
+/**
+ * xmlRngVErrMemory:
+ * @ctxt:  a Relax-NG validation context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        if (ctxt->serror != NULL)
+	    schannel = ctxt->serror;
+	else
+	    channel = ctxt->error;
+        data = ctxt->userData;
+        ctxt->nbErrors++;
+    }
+    if (extra)
+        __xmlRaiseError(schannel, channel, data,
+                        NULL, NULL, XML_FROM_RELAXNGV,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+                        NULL, NULL, 0, 0,
+                        "Memory allocation failed : %s\n", extra);
+    else
+        __xmlRaiseError(schannel, channel, data,
+                        NULL, NULL, XML_FROM_RELAXNGV,
+                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
+                        NULL, NULL, 0, 0, "Memory allocation failed\n");
+}
+
+/**
+ * xmlRngPErr:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the node raising the error
+ * @error:  the error code
+ * @msg:  message
+ * @str1:  extra info
+ * @str2:  extra info
+ *
+ * Handle a Relax NG Parsing error
+ */
+static void
+xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
+           const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        if (ctxt->serror != NULL)
+	    schannel = ctxt->serror;
+	else
+	    channel = ctxt->error;
+        data = ctxt->userData;
+        ctxt->nbErrors++;
+    }
+    __xmlRaiseError(schannel, channel, data,
+                    NULL, node, XML_FROM_RELAXNGP,
+                    error, XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1, (const char *) str2, NULL, 0, 0,
+                    msg, str1, str2);
+}
+
+/**
+ * xmlRngVErr:
+ * @ctxt:  a Relax-NG validation context
+ * @node:  the node raising the error
+ * @error:  the error code
+ * @msg:  message
+ * @str1:  extra info
+ * @str2:  extra info
+ *
+ * Handle a Relax NG Validation error
+ */
+static void
+xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
+           const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        if (ctxt->serror != NULL)
+	    schannel = ctxt->serror;
+	else
+	    channel = ctxt->error;
+        data = ctxt->userData;
+        ctxt->nbErrors++;
+    }
+    __xmlRaiseError(schannel, channel, data,
+                    NULL, node, XML_FROM_RELAXNGV,
+                    error, XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1, (const char *) str2, NULL, 0, 0,
+                    msg, str1, str2);
+}
+
+/************************************************************************
+ * 									*
+ * 		Preliminary type checking interfaces			*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlRelaxNGTypeHave:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value:  the value to check
+ *
+ * Function provided by a type library to check if a type is exported
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);
+
+/**
+ * xmlRelaxNGTypeCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value:  the value to check
+ * @result:  place to store the result if needed
+ *
+ * Function provided by a type library to check if a value match a type
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
+                                    const xmlChar * value, void **result,
+                                    xmlNodePtr node);
+
+/**
+ * xmlRelaxNGFacetCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @facet:  the facet name
+ * @val:  the facet value
+ * @strval:  the string value
+ * @value:  the value to check
+ *
+ * Function provided by a type library to check a value facet
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
+                                     const xmlChar * facet,
+                                     const xmlChar * val,
+                                     const xmlChar * strval, void *value);
+
+/**
+ * xmlRelaxNGTypeFree:
+ * @data:  data needed for the library
+ * @result:  the value to free
+ *
+ * Function provided by a type library to free a returned result
+ */
+typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
+
+/**
+ * xmlRelaxNGTypeCompare:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value1:  the first value
+ * @value2:  the second value
+ *
+ * Function provided by a type library to compare two values accordingly
+ * to a type.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+typedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
+                                      const xmlChar * value1,
+                                      xmlNodePtr ctxt1,
+                                      void *comp1,
+                                      const xmlChar * value2,
+                                      xmlNodePtr ctxt2);
+typedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
+typedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
+struct _xmlRelaxNGTypeLibrary {
+    const xmlChar *namespace;   /* the datatypeLibrary value */
+    void *data;                 /* data needed for the library */
+    xmlRelaxNGTypeHave have;    /* the export function */
+    xmlRelaxNGTypeCheck check;  /* the checking function */
+    xmlRelaxNGTypeCompare comp; /* the compare function */
+    xmlRelaxNGFacetCheck facet; /* the facet check function */
+    xmlRelaxNGTypeFree freef;   /* the freeing function */
+};
+
+/************************************************************************
+ * 									*
+ * 			Allocation functions				*
+ * 									*
+ ************************************************************************/
+static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
+static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
+static void xmlRelaxNGNormExtSpace(xmlChar * value);
+static void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
+static int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
+                                     ATTRIBUTE_UNUSED,
+                                     xmlRelaxNGValidStatePtr state1,
+                                     xmlRelaxNGValidStatePtr state2);
+static void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
+                                     xmlRelaxNGValidStatePtr state);
+
+/**
+ * xmlRelaxNGFreeDocument:
+ * @docu:  a document structure
+ *
+ * Deallocate a RelaxNG document structure.
+ */
+static void
+xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
+{
+    if (docu == NULL)
+        return;
+
+    if (docu->href != NULL)
+        xmlFree(docu->href);
+    if (docu->doc != NULL)
+        xmlFreeDoc(docu->doc);
+    if (docu->schema != NULL)
+        xmlRelaxNGFreeInnerSchema(docu->schema);
+    xmlFree(docu);
+}
+
+/**
+ * xmlRelaxNGFreeDocumentList:
+ * @docu:  a list of  document structure
+ *
+ * Deallocate a RelaxNG document structures.
+ */
+static void
+xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
+{
+    xmlRelaxNGDocumentPtr next;
+
+    while (docu != NULL) {
+        next = docu->next;
+        xmlRelaxNGFreeDocument(docu);
+        docu = next;
+    }
+}
+
+/**
+ * xmlRelaxNGFreeInclude:
+ * @incl:  a include structure
+ *
+ * Deallocate a RelaxNG include structure.
+ */
+static void
+xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
+{
+    if (incl == NULL)
+        return;
+
+    if (incl->href != NULL)
+        xmlFree(incl->href);
+    if (incl->doc != NULL)
+        xmlFreeDoc(incl->doc);
+    if (incl->schema != NULL)
+        xmlRelaxNGFree(incl->schema);
+    xmlFree(incl);
+}
+
+/**
+ * xmlRelaxNGFreeIncludeList:
+ * @incl:  a include structure list
+ *
+ * Deallocate a RelaxNG include structure.
+ */
+static void
+xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
+{
+    xmlRelaxNGIncludePtr next;
+
+    while (incl != NULL) {
+        next = incl->next;
+        xmlRelaxNGFreeInclude(incl);
+        incl = next;
+    }
+}
+
+/**
+ * xmlRelaxNGNewRelaxNG:
+ * @ctxt:  a Relax-NG validation context (optional)
+ *
+ * Allocate a new RelaxNG structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGPtr
+xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    xmlRelaxNGPtr ret;
+
+    ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
+    if (ret == NULL) {
+        xmlRngPErrMemory(ctxt, NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNG));
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGFreeInnerSchema:
+ * @schema:  a schema structure
+ *
+ * Deallocate a RelaxNG schema structure.
+ */
+static void
+xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
+{
+    if (schema == NULL)
+        return;
+
+    if (schema->doc != NULL)
+        xmlFreeDoc(schema->doc);
+    if (schema->defTab != NULL) {
+        int i;
+
+        for (i = 0; i < schema->defNr; i++)
+            xmlRelaxNGFreeDefine(schema->defTab[i]);
+        xmlFree(schema->defTab);
+    }
+
+    xmlFree(schema);
+}
+
+/**
+ * xmlRelaxNGFree:
+ * @schema:  a schema structure
+ *
+ * Deallocate a RelaxNG structure.
+ */
+void
+xmlRelaxNGFree(xmlRelaxNGPtr schema)
+{
+    if (schema == NULL)
+        return;
+
+    if (schema->topgrammar != NULL)
+        xmlRelaxNGFreeGrammar(schema->topgrammar);
+    if (schema->doc != NULL)
+        xmlFreeDoc(schema->doc);
+    if (schema->documents != NULL)
+        xmlRelaxNGFreeDocumentList(schema->documents);
+    if (schema->includes != NULL)
+        xmlRelaxNGFreeIncludeList(schema->includes);
+    if (schema->defTab != NULL) {
+        int i;
+
+        for (i = 0; i < schema->defNr; i++)
+            xmlRelaxNGFreeDefine(schema->defTab[i]);
+        xmlFree(schema->defTab);
+    }
+
+    xmlFree(schema);
+}
+
+/**
+ * xmlRelaxNGNewGrammar:
+ * @ctxt:  a Relax-NG validation context (optional)
+ *
+ * Allocate a new RelaxNG grammar.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGGrammarPtr
+xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    xmlRelaxNGGrammarPtr ret;
+
+    ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
+    if (ret == NULL) {
+        xmlRngPErrMemory(ctxt, NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGGrammar));
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGFreeGrammar:
+ * @grammar:  a grammar structure
+ *
+ * Deallocate a RelaxNG grammar structure.
+ */
+static void
+xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
+{
+    if (grammar == NULL)
+        return;
+
+    if (grammar->children != NULL) {
+        xmlRelaxNGFreeGrammar(grammar->children);
+    }
+    if (grammar->next != NULL) {
+        xmlRelaxNGFreeGrammar(grammar->next);
+    }
+    if (grammar->refs != NULL) {
+        xmlHashFree(grammar->refs, NULL);
+    }
+    if (grammar->defs != NULL) {
+        xmlHashFree(grammar->defs, NULL);
+    }
+
+    xmlFree(grammar);
+}
+
+/**
+ * xmlRelaxNGNewDefine:
+ * @ctxt:  a Relax-NG validation context
+ * @node:  the node in the input document.
+ *
+ * Allocate a new RelaxNG define.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr ret;
+
+    if (ctxt->defMax == 0) {
+        ctxt->defMax = 16;
+        ctxt->defNr = 0;
+        ctxt->defTab = (xmlRelaxNGDefinePtr *)
+            xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
+        if (ctxt->defTab == NULL) {
+            xmlRngPErrMemory(ctxt, "allocating define\n");
+            return (NULL);
+        }
+    } else if (ctxt->defMax <= ctxt->defNr) {
+        xmlRelaxNGDefinePtr *tmp;
+
+        ctxt->defMax *= 2;
+        tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
+                                                 ctxt->defMax *
+                                                 sizeof
+                                                 (xmlRelaxNGDefinePtr));
+        if (tmp == NULL) {
+            xmlRngPErrMemory(ctxt, "allocating define\n");
+            return (NULL);
+        }
+        ctxt->defTab = tmp;
+    }
+    ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
+    if (ret == NULL) {
+        xmlRngPErrMemory(ctxt, "allocating define\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGDefine));
+    ctxt->defTab[ctxt->defNr++] = ret;
+    ret->node = node;
+    ret->depth = -1;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGFreePartition:
+ * @partitions:  a partition set structure
+ *
+ * Deallocate RelaxNG partition set structures.
+ */
+static void
+xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
+{
+    xmlRelaxNGInterleaveGroupPtr group;
+    int j;
+
+    if (partitions != NULL) {
+        if (partitions->groups != NULL) {
+            for (j = 0; j < partitions->nbgroups; j++) {
+                group = partitions->groups[j];
+                if (group != NULL) {
+                    if (group->defs != NULL)
+                        xmlFree(group->defs);
+                    if (group->attrs != NULL)
+                        xmlFree(group->attrs);
+                    xmlFree(group);
+                }
+            }
+            xmlFree(partitions->groups);
+        }
+        if (partitions->triage != NULL) {
+            xmlHashFree(partitions->triage, NULL);
+        }
+        xmlFree(partitions);
+    }
+}
+
+/**
+ * xmlRelaxNGFreeDefine:
+ * @define:  a define structure
+ *
+ * Deallocate a RelaxNG define structure.
+ */
+static void
+xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
+{
+    if (define == NULL)
+        return;
+
+    if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL)) {
+        xmlRelaxNGTypeLibraryPtr lib;
+
+        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
+        if ((lib != NULL) && (lib->freef != NULL))
+            lib->freef(lib->data, (void *) define->attrs);
+    }
+    if ((define->data != NULL) && (define->type == XML_RELAXNG_INTERLEAVE))
+        xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
+    if ((define->data != NULL) && (define->type == XML_RELAXNG_CHOICE))
+        xmlHashFree((xmlHashTablePtr) define->data, NULL);
+    if (define->name != NULL)
+        xmlFree(define->name);
+    if (define->ns != NULL)
+        xmlFree(define->ns);
+    if (define->value != NULL)
+        xmlFree(define->value);
+    if (define->contModel != NULL)
+        xmlRegFreeRegexp(define->contModel);
+    xmlFree(define);
+}
+
+/**
+ * xmlRelaxNGNewStates:
+ * @ctxt:  a Relax-NG validation context
+ * @size:  the default size for the container
+ *
+ * Allocate a new RelaxNG validation state container
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGStatesPtr
+xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
+{
+    xmlRelaxNGStatesPtr ret;
+
+    if ((ctxt != NULL) &&
+        (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
+        ctxt->freeStatesNr--;
+        ret = ctxt->freeStates[ctxt->freeStatesNr];
+        ret->nbState = 0;
+        return (ret);
+    }
+    if (size < 16)
+        size = 16;
+
+    ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
+                                          (size -
+                                           1) *
+                                          sizeof(xmlRelaxNGValidStatePtr));
+    if (ret == NULL) {
+        xmlRngVErrMemory(ctxt, "allocating states\n");
+        return (NULL);
+    }
+    ret->nbState = 0;
+    ret->maxState = size;
+    ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
+                                                          sizeof
+                                                          (xmlRelaxNGValidStatePtr));
+    if (ret->tabState == NULL) {
+        xmlRngVErrMemory(ctxt, "allocating states\n");
+        xmlFree(ret);
+        return (NULL);
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGAddStateUniq:
+ * @ctxt:  a Relax-NG validation context
+ * @states:  the states container
+ * @state:  the validation state
+ *
+ * Add a RelaxNG validation state to the container without checking
+ * for unicity.
+ *
+ * Return 1 in case of success and 0 if this is a duplicate and -1 on error
+ */
+static int
+xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
+                        xmlRelaxNGStatesPtr states,
+                        xmlRelaxNGValidStatePtr state)
+{
+    if (state == NULL) {
+        return (-1);
+    }
+    if (states->nbState >= states->maxState) {
+        xmlRelaxNGValidStatePtr *tmp;
+        int size;
+
+        size = states->maxState * 2;
+        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
+                                                     (size) *
+                                                     sizeof
+                                                     (xmlRelaxNGValidStatePtr));
+        if (tmp == NULL) {
+            xmlRngVErrMemory(ctxt, "adding states\n");
+            return (-1);
+        }
+        states->tabState = tmp;
+        states->maxState = size;
+    }
+    states->tabState[states->nbState++] = state;
+    return (1);
+}
+
+/**
+ * xmlRelaxNGAddState:
+ * @ctxt:  a Relax-NG validation context
+ * @states:  the states container
+ * @state:  the validation state
+ *
+ * Add a RelaxNG validation state to the container
+ *
+ * Return 1 in case of success and 0 if this is a duplicate and -1 on error
+ */
+static int
+xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
+                    xmlRelaxNGStatesPtr states,
+                    xmlRelaxNGValidStatePtr state)
+{
+    int i;
+
+    if (state == NULL) {
+        return (-1);
+    }
+    if (states->nbState >= states->maxState) {
+        xmlRelaxNGValidStatePtr *tmp;
+        int size;
+
+        size = states->maxState * 2;
+        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
+                                                     (size) *
+                                                     sizeof
+                                                     (xmlRelaxNGValidStatePtr));
+        if (tmp == NULL) {
+            xmlRngVErrMemory(ctxt, "adding states\n");
+            return (-1);
+        }
+        states->tabState = tmp;
+        states->maxState = size;
+    }
+    for (i = 0; i < states->nbState; i++) {
+        if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
+            xmlRelaxNGFreeValidState(ctxt, state);
+            return (0);
+        }
+    }
+    states->tabState[states->nbState++] = state;
+    return (1);
+}
+
+/**
+ * xmlRelaxNGFreeStates:
+ * @ctxt:  a Relax-NG validation context
+ * @states:  teh container
+ *
+ * Free a RelaxNG validation state container
+ */
+static void
+xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
+                     xmlRelaxNGStatesPtr states)
+{
+    if (states == NULL)
+        return;
+    if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
+        ctxt->freeStatesMax = 40;
+        ctxt->freeStatesNr = 0;
+        ctxt->freeStates = (xmlRelaxNGStatesPtr *)
+            xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
+        if (ctxt->freeStates == NULL) {
+            xmlRngVErrMemory(ctxt, "storing states\n");
+        }
+    } else if ((ctxt != NULL)
+               && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
+        xmlRelaxNGStatesPtr *tmp;
+
+        tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
+                                                 2 * ctxt->freeStatesMax *
+                                                 sizeof
+                                                 (xmlRelaxNGStatesPtr));
+        if (tmp == NULL) {
+            xmlRngVErrMemory(ctxt, "storing states\n");
+            xmlFree(states->tabState);
+            xmlFree(states);
+            return;
+        }
+        ctxt->freeStates = tmp;
+        ctxt->freeStatesMax *= 2;
+    }
+    if ((ctxt == NULL) || (ctxt->freeStates == NULL)) {
+        xmlFree(states->tabState);
+        xmlFree(states);
+    } else {
+        ctxt->freeStates[ctxt->freeStatesNr++] = states;
+    }
+}
+
+/**
+ * xmlRelaxNGNewValidState:
+ * @ctxt:  a Relax-NG validation context
+ * @node:  the current node or NULL for the document
+ *
+ * Allocate a new RelaxNG validation state
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGValidStatePtr
+xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGValidStatePtr ret;
+    xmlAttrPtr attr;
+    xmlAttrPtr attrs[MAX_ATTR];
+    int nbAttrs = 0;
+    xmlNodePtr root = NULL;
+
+    if (node == NULL) {
+        root = xmlDocGetRootElement(ctxt->doc);
+        if (root == NULL)
+            return (NULL);
+    } else {
+        attr = node->properties;
+        while (attr != NULL) {
+            if (nbAttrs < MAX_ATTR)
+                attrs[nbAttrs++] = attr;
+            else
+                nbAttrs++;
+            attr = attr->next;
+        }
+    }
+    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
+        ctxt->freeState->nbState--;
+        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
+    } else {
+        ret =
+            (xmlRelaxNGValidStatePtr)
+            xmlMalloc(sizeof(xmlRelaxNGValidState));
+        if (ret == NULL) {
+            xmlRngVErrMemory(ctxt, "allocating states\n");
+            return (NULL);
+        }
+        memset(ret, 0, sizeof(xmlRelaxNGValidState));
+    }
+    ret->value = NULL;
+    ret->endvalue = NULL;
+    if (node == NULL) {
+        ret->node = (xmlNodePtr) ctxt->doc;
+        ret->seq = root;
+    } else {
+        ret->node = node;
+        ret->seq = node->children;
+    }
+    ret->nbAttrs = 0;
+    if (nbAttrs > 0) {
+        if (ret->attrs == NULL) {
+            if (nbAttrs < 4)
+                ret->maxAttrs = 4;
+            else
+                ret->maxAttrs = nbAttrs;
+            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
+                                                  sizeof(xmlAttrPtr));
+            if (ret->attrs == NULL) {
+                xmlRngVErrMemory(ctxt, "allocating states\n");
+                return (ret);
+            }
+        } else if (ret->maxAttrs < nbAttrs) {
+            xmlAttrPtr *tmp;
+
+            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
+                                            sizeof(xmlAttrPtr));
+            if (tmp == NULL) {
+                xmlRngVErrMemory(ctxt, "allocating states\n");
+                return (ret);
+            }
+            ret->attrs = tmp;
+            ret->maxAttrs = nbAttrs;
+        }
+        ret->nbAttrs = nbAttrs;
+        if (nbAttrs < MAX_ATTR) {
+            memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
+        } else {
+            attr = node->properties;
+            nbAttrs = 0;
+            while (attr != NULL) {
+                ret->attrs[nbAttrs++] = attr;
+                attr = attr->next;
+            }
+        }
+    }
+    ret->nbAttrLeft = ret->nbAttrs;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGCopyValidState:
+ * @ctxt:  a Relax-NG validation context
+ * @state:  a validation state
+ *
+ * Copy the validation state
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlRelaxNGValidStatePtr
+xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidStatePtr state)
+{
+    xmlRelaxNGValidStatePtr ret;
+    unsigned int maxAttrs;
+    xmlAttrPtr *attrs;
+
+    if (state == NULL)
+        return (NULL);
+    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
+        ctxt->freeState->nbState--;
+        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
+    } else {
+        ret =
+            (xmlRelaxNGValidStatePtr)
+            xmlMalloc(sizeof(xmlRelaxNGValidState));
+        if (ret == NULL) {
+            xmlRngVErrMemory(ctxt, "allocating states\n");
+            return (NULL);
+        }
+        memset(ret, 0, sizeof(xmlRelaxNGValidState));
+    }
+    attrs = ret->attrs;
+    maxAttrs = ret->maxAttrs;
+    memcpy(ret, state, sizeof(xmlRelaxNGValidState));
+    ret->attrs = attrs;
+    ret->maxAttrs = maxAttrs;
+    if (state->nbAttrs > 0) {
+        if (ret->attrs == NULL) {
+            ret->maxAttrs = state->maxAttrs;
+            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
+                                                  sizeof(xmlAttrPtr));
+            if (ret->attrs == NULL) {
+                xmlRngVErrMemory(ctxt, "allocating states\n");
+                ret->nbAttrs = 0;
+                return (ret);
+            }
+        } else if (ret->maxAttrs < state->nbAttrs) {
+            xmlAttrPtr *tmp;
+
+            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
+                                            sizeof(xmlAttrPtr));
+            if (tmp == NULL) {
+                xmlRngVErrMemory(ctxt, "allocating states\n");
+                ret->nbAttrs = 0;
+                return (ret);
+            }
+            ret->maxAttrs = state->maxAttrs;
+            ret->attrs = tmp;
+        }
+        memcpy(ret->attrs, state->attrs,
+               state->nbAttrs * sizeof(xmlAttrPtr));
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGEqualValidState:
+ * @ctxt:  a Relax-NG validation context
+ * @state1:  a validation state
+ * @state2:  a validation state
+ *
+ * Compare the validation states for equality
+ *
+ * Returns 1 if equald, 0 otherwise
+ */
+static int
+xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                          xmlRelaxNGValidStatePtr state1,
+                          xmlRelaxNGValidStatePtr state2)
+{
+    int i;
+
+    if ((state1 == NULL) || (state2 == NULL))
+        return (0);
+    if (state1 == state2)
+        return (1);
+    if (state1->node != state2->node)
+        return (0);
+    if (state1->seq != state2->seq)
+        return (0);
+    if (state1->nbAttrLeft != state2->nbAttrLeft)
+        return (0);
+    if (state1->nbAttrs != state2->nbAttrs)
+        return (0);
+    if (state1->endvalue != state2->endvalue)
+        return (0);
+    if ((state1->value != state2->value) &&
+        (!xmlStrEqual(state1->value, state2->value)))
+        return (0);
+    for (i = 0; i < state1->nbAttrs; i++) {
+        if (state1->attrs[i] != state2->attrs[i])
+            return (0);
+    }
+    return (1);
+}
+
+/**
+ * xmlRelaxNGFreeValidState:
+ * @state:  a validation state structure
+ *
+ * Deallocate a RelaxNG validation state structure.
+ */
+static void
+xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidStatePtr state)
+{
+    if (state == NULL)
+        return;
+
+    if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
+        ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
+    }
+    if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
+        if (state->attrs != NULL)
+            xmlFree(state->attrs);
+        xmlFree(state);
+    } else {
+        xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
+    }
+}
+
+/************************************************************************
+ * 									*
+ * 			Semi internal functions				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlRelaxParserSetFlag:
+ * @ctxt: a RelaxNG parser context
+ * @flags: a set of flags values
+ *
+ * Semi private function used to pass informations to a parser context
+ * which are a combination of xmlRelaxNGParserFlag .
+ *
+ * Returns 0 if success and -1 in case of error
+ */
+int
+xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
+{
+    if (ctxt == NULL) return(-1);
+    if (flags & XML_RELAXNGP_FREE_DOC) {
+        ctxt->crng |= XML_RELAXNGP_FREE_DOC;
+	flags -= XML_RELAXNGP_FREE_DOC;
+    }
+    if (flags & XML_RELAXNGP_CRNG) {
+        ctxt->crng |= XML_RELAXNGP_CRNG;
+	flags -= XML_RELAXNGP_CRNG;
+    }
+    if (flags != 0) return(-1);
+    return(0);
+}
+
+/************************************************************************
+ * 									*
+ * 			Document functions				*
+ * 									*
+ ************************************************************************/
+static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
+                                      xmlDocPtr doc);
+
+/**
+ * xmlRelaxNGIncludePush:
+ * @ctxt:  the parser context
+ * @value:  the element doc
+ *
+ * Pushes a new include on top of the include stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
+                      xmlRelaxNGIncludePtr value)
+{
+    if (ctxt->incTab == NULL) {
+        ctxt->incMax = 4;
+        ctxt->incNr = 0;
+        ctxt->incTab =
+            (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
+                                               sizeof(ctxt->incTab[0]));
+        if (ctxt->incTab == NULL) {
+            xmlRngPErrMemory(ctxt, "allocating include\n");
+            return (0);
+        }
+    }
+    if (ctxt->incNr >= ctxt->incMax) {
+        ctxt->incMax *= 2;
+        ctxt->incTab =
+            (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
+                                                ctxt->incMax *
+                                                sizeof(ctxt->incTab[0]));
+        if (ctxt->incTab == NULL) {
+            xmlRngPErrMemory(ctxt, "allocating include\n");
+            return (0);
+        }
+    }
+    ctxt->incTab[ctxt->incNr] = value;
+    ctxt->inc = value;
+    return (ctxt->incNr++);
+}
+
+/**
+ * xmlRelaxNGIncludePop:
+ * @ctxt: the parser context
+ *
+ * Pops the top include from the include stack
+ *
+ * Returns the include just removed
+ */
+static xmlRelaxNGIncludePtr
+xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    xmlRelaxNGIncludePtr ret;
+
+    if (ctxt->incNr <= 0)
+        return (NULL);
+    ctxt->incNr--;
+    if (ctxt->incNr > 0)
+        ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
+    else
+        ctxt->inc = NULL;
+    ret = ctxt->incTab[ctxt->incNr];
+    ctxt->incTab[ctxt->incNr] = NULL;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGRemoveRedefine:
+ * @ctxt: the parser context
+ * @URL:  the normalized URL
+ * @target:  the included target
+ * @name:  the define name to eliminate
+ *
+ * Applies the elimination algorithm of 4.7
+ *
+ * Returns 0 in case of error, 1 in case of success.
+ */
+static int
+xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
+                         const xmlChar * URL ATTRIBUTE_UNUSED,
+                         xmlNodePtr target, const xmlChar * name)
+{
+    int found = 0;
+    xmlNodePtr tmp, tmp2;
+    xmlChar *name2;
+
+#ifdef DEBUG_INCLUDE
+    if (name == NULL)
+        xmlGenericError(xmlGenericErrorContext,
+                        "Elimination of <include> start from %s\n", URL);
+    else
+        xmlGenericError(xmlGenericErrorContext,
+                        "Elimination of <include> define %s from %s\n",
+                        name, URL);
+#endif
+    tmp = target;
+    while (tmp != NULL) {
+        tmp2 = tmp->next;
+        if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
+            found = 1;
+            xmlUnlinkNode(tmp);
+            xmlFreeNode(tmp);
+        } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
+            name2 = xmlGetProp(tmp, BAD_CAST "name");
+            xmlRelaxNGNormExtSpace(name2);
+            if (name2 != NULL) {
+                if (xmlStrEqual(name, name2)) {
+                    found = 1;
+                    xmlUnlinkNode(tmp);
+                    xmlFreeNode(tmp);
+                }
+                xmlFree(name2);
+            }
+        } else if (IS_RELAXNG(tmp, "include")) {
+            xmlChar *href = NULL;
+            xmlRelaxNGDocumentPtr inc = tmp->psvi;
+
+            if ((inc != NULL) && (inc->doc != NULL) &&
+                (inc->doc->children != NULL)) {
+
+                if (xmlStrEqual
+                    (inc->doc->children->name, BAD_CAST "grammar")) {
+#ifdef DEBUG_INCLUDE
+                    href = xmlGetProp(tmp, BAD_CAST "href");
+#endif
+                    if (xmlRelaxNGRemoveRedefine(ctxt, href,
+                                                 inc->doc->children->
+                                                 children, name) == 1) {
+                        found = 1;
+                    }
+#ifdef DEBUG_INCLUDE
+                    if (href != NULL)
+                        xmlFree(href);
+#endif
+                }
+            }
+        }
+        tmp = tmp2;
+    }
+    return (found);
+}
+
+/**
+ * xmlRelaxNGLoadInclude:
+ * @ctxt: the parser context
+ * @URL:  the normalized URL
+ * @node: the include node.
+ * @ns:  the namespace passed from the context.
+ *
+ * First lookup if the document is already loaded into the parser context,
+ * check against recursion. If not found the resource is loaded and
+ * the content is preprocessed before being returned back to the caller.
+ *
+ * Returns the xmlRelaxNGIncludePtr or NULL in case of error
+ */
+static xmlRelaxNGIncludePtr
+xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
+                      xmlNodePtr node, const xmlChar * ns)
+{
+    xmlRelaxNGIncludePtr ret = NULL;
+    xmlDocPtr doc;
+    int i;
+    xmlNodePtr root, cur;
+
+#ifdef DEBUG_INCLUDE
+    xmlGenericError(xmlGenericErrorContext,
+                    "xmlRelaxNGLoadInclude(%s)\n", URL);
+#endif
+
+    /*
+     * check against recursion in the stack
+     */
+    for (i = 0; i < ctxt->incNr; i++) {
+        if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
+            xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
+                       "Detected an Include recursion for %s\n", URL,
+                       NULL);
+            return (NULL);
+        }
+    }
+
+    /*
+     * load the document
+     */
+    doc = xmlReadFile((const char *) URL,NULL,0);
+    if (doc == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
+                   "xmlRelaxNG: could not load %s\n", URL, NULL);
+        return (NULL);
+    }
+#ifdef DEBUG_INCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Parsed %s Okay\n", URL);
+#endif
+
+    /*
+     * Allocate the document structures and register it first.
+     */
+    ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
+    if (ret == NULL) {
+        xmlRngPErrMemory(ctxt, "allocating include\n");
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGInclude));
+    ret->doc = doc;
+    ret->href = xmlStrdup(URL);
+    ret->next = ctxt->includes;
+    ctxt->includes = ret;
+
+    /*
+     * transmit the ns if needed
+     */
+    if (ns != NULL) {
+        root = xmlDocGetRootElement(doc);
+        if (root != NULL) {
+            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
+                xmlSetProp(root, BAD_CAST "ns", ns);
+            }
+        }
+    }
+
+    /*
+     * push it on the stack
+     */
+    xmlRelaxNGIncludePush(ctxt, ret);
+
+    /*
+     * Some preprocessing of the document content, this include recursing
+     * in the include stack.
+     */
+#ifdef DEBUG_INCLUDE
+    xmlGenericError(xmlGenericErrorContext, "cleanup of %s\n", URL);
+#endif
+
+    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
+    if (doc == NULL) {
+        ctxt->inc = NULL;
+        return (NULL);
+    }
+
+    /*
+     * Pop up the include from the stack
+     */
+    xmlRelaxNGIncludePop(ctxt);
+
+#ifdef DEBUG_INCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Checking of %s\n", URL);
+#endif
+    /*
+     * Check that the top element is a grammar
+     */
+    root = xmlDocGetRootElement(doc);
+    if (root == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
+                   "xmlRelaxNG: included document is empty %s\n", URL,
+                   NULL);
+        return (NULL);
+    }
+    if (!IS_RELAXNG(root, "grammar")) {
+        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
+                   "xmlRelaxNG: included document %s root is not a grammar\n",
+                   URL, NULL);
+        return (NULL);
+    }
+
+    /*
+     * Elimination of redefined rules in the include.
+     */
+    cur = node->children;
+    while (cur != NULL) {
+        if (IS_RELAXNG(cur, "start")) {
+            int found = 0;
+
+            found =
+                xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL);
+            if (!found) {
+                xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
+                           "xmlRelaxNG: include %s has a start but not the included grammar\n",
+                           URL, NULL);
+            }
+        } else if (IS_RELAXNG(cur, "define")) {
+            xmlChar *name;
+
+            name = xmlGetProp(cur, BAD_CAST "name");
+            if (name == NULL) {
+                xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
+                           "xmlRelaxNG: include %s has define without name\n",
+                           URL, NULL);
+            } else {
+                int found;
+
+                xmlRelaxNGNormExtSpace(name);
+                found = xmlRelaxNGRemoveRedefine(ctxt, URL,
+                                                 root->children, name);
+                if (!found) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
+                               "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
+                               URL, name);
+                }
+                xmlFree(name);
+            }
+        }
+        cur = cur->next;
+    }
+
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidErrorPush:
+ * @ctxt:  the validation context
+ * @err:  the error code
+ * @arg1:  the first string argument
+ * @arg2:  the second string argument
+ * @dup:  arg need to be duplicated
+ *
+ * Pushes a new error on top of the error stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidErr err, const xmlChar * arg1,
+                         const xmlChar * arg2, int dup)
+{
+    xmlRelaxNGValidErrorPtr cur;
+
+#ifdef DEBUG_ERROR
+    xmlGenericError(xmlGenericErrorContext,
+                    "Pushing error %d at %d on stack\n", err, ctxt->errNr);
+#endif
+    if (ctxt->errTab == NULL) {
+        ctxt->errMax = 8;
+        ctxt->errNr = 0;
+        ctxt->errTab =
+            (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
+                                                sizeof
+                                                (xmlRelaxNGValidError));
+        if (ctxt->errTab == NULL) {
+            xmlRngVErrMemory(ctxt, "pushing error\n");
+            return (0);
+        }
+        ctxt->err = NULL;
+    }
+    if (ctxt->errNr >= ctxt->errMax) {
+        ctxt->errMax *= 2;
+        ctxt->errTab =
+            (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
+                                                 ctxt->errMax *
+                                                 sizeof
+                                                 (xmlRelaxNGValidError));
+        if (ctxt->errTab == NULL) {
+            xmlRngVErrMemory(ctxt, "pushing error\n");
+            return (0);
+        }
+        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
+    }
+    if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
+        (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
+        return (ctxt->errNr);
+    cur = &ctxt->errTab[ctxt->errNr];
+    cur->err = err;
+    if (dup) {
+        cur->arg1 = xmlStrdup(arg1);
+        cur->arg2 = xmlStrdup(arg2);
+        cur->flags = ERROR_IS_DUP;
+    } else {
+        cur->arg1 = arg1;
+        cur->arg2 = arg2;
+        cur->flags = 0;
+    }
+    if (ctxt->state != NULL) {
+        cur->node = ctxt->state->node;
+        cur->seq = ctxt->state->seq;
+    } else {
+        cur->node = NULL;
+        cur->seq = NULL;
+    }
+    ctxt->err = cur;
+    return (ctxt->errNr++);
+}
+
+/**
+ * xmlRelaxNGValidErrorPop:
+ * @ctxt: the validation context
+ *
+ * Pops the top error from the error stack
+ */
+static void
+xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    xmlRelaxNGValidErrorPtr cur;
+
+    if (ctxt->errNr <= 0) {
+        ctxt->err = NULL;
+        return;
+    }
+    ctxt->errNr--;
+    if (ctxt->errNr > 0)
+        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
+    else
+        ctxt->err = NULL;
+    cur = &ctxt->errTab[ctxt->errNr];
+    if (cur->flags & ERROR_IS_DUP) {
+        if (cur->arg1 != NULL)
+            xmlFree((xmlChar *) cur->arg1);
+        cur->arg1 = NULL;
+        if (cur->arg2 != NULL)
+            xmlFree((xmlChar *) cur->arg2);
+        cur->arg2 = NULL;
+        cur->flags = 0;
+    }
+}
+
+/**
+ * xmlRelaxNGDocumentPush:
+ * @ctxt:  the parser context
+ * @value:  the element doc
+ *
+ * Pushes a new doc on top of the doc stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
+                       xmlRelaxNGDocumentPtr value)
+{
+    if (ctxt->docTab == NULL) {
+        ctxt->docMax = 4;
+        ctxt->docNr = 0;
+        ctxt->docTab =
+            (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
+                                                sizeof(ctxt->docTab[0]));
+        if (ctxt->docTab == NULL) {
+            xmlRngPErrMemory(ctxt, "adding document\n");
+            return (0);
+        }
+    }
+    if (ctxt->docNr >= ctxt->docMax) {
+        ctxt->docMax *= 2;
+        ctxt->docTab =
+            (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
+                                                 ctxt->docMax *
+                                                 sizeof(ctxt->docTab[0]));
+        if (ctxt->docTab == NULL) {
+            xmlRngPErrMemory(ctxt, "adding document\n");
+            return (0);
+        }
+    }
+    ctxt->docTab[ctxt->docNr] = value;
+    ctxt->doc = value;
+    return (ctxt->docNr++);
+}
+
+/**
+ * xmlRelaxNGDocumentPop:
+ * @ctxt: the parser context
+ *
+ * Pops the top doc from the doc stack
+ *
+ * Returns the doc just removed
+ */
+static xmlRelaxNGDocumentPtr
+xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    xmlRelaxNGDocumentPtr ret;
+
+    if (ctxt->docNr <= 0)
+        return (NULL);
+    ctxt->docNr--;
+    if (ctxt->docNr > 0)
+        ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
+    else
+        ctxt->doc = NULL;
+    ret = ctxt->docTab[ctxt->docNr];
+    ctxt->docTab[ctxt->docNr] = NULL;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGLoadExternalRef:
+ * @ctxt: the parser context
+ * @URL:  the normalized URL
+ * @ns:  the inherited ns if any
+ *
+ * First lookup if the document is already loaded into the parser context,
+ * check against recursion. If not found the resource is loaded and
+ * the content is preprocessed before being returned back to the caller.
+ *
+ * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
+ */
+static xmlRelaxNGDocumentPtr
+xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
+                          const xmlChar * URL, const xmlChar * ns)
+{
+    xmlRelaxNGDocumentPtr ret = NULL;
+    xmlDocPtr doc;
+    xmlNodePtr root;
+    int i;
+
+    /*
+     * check against recursion in the stack
+     */
+    for (i = 0; i < ctxt->docNr; i++) {
+        if (xmlStrEqual(ctxt->docTab[i]->href, URL)) {
+            xmlRngPErr(ctxt, NULL, XML_RNGP_EXTERNALREF_RECURSE,
+                       "Detected an externalRef recursion for %s\n", URL,
+                       NULL);
+            return (NULL);
+        }
+    }
+
+    /*
+     * load the document
+     */
+    doc = xmlReadFile((const char *) URL,NULL,0);
+    if (doc == NULL) {
+        xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
+                   "xmlRelaxNG: could not load %s\n", URL, NULL);
+        return (NULL);
+    }
+
+    /*
+     * Allocate the document structures and register it first.
+     */
+    ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
+    if (ret == NULL) {
+        xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY,
+                   "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL);
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGDocument));
+    ret->doc = doc;
+    ret->href = xmlStrdup(URL);
+    ret->next = ctxt->documents;
+    ret->externalRef = 1;
+    ctxt->documents = ret;
+
+    /*
+     * transmit the ns if needed
+     */
+    if (ns != NULL) {
+        root = xmlDocGetRootElement(doc);
+        if (root != NULL) {
+            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
+                xmlSetProp(root, BAD_CAST "ns", ns);
+            }
+        }
+    }
+
+    /*
+     * push it on the stack and register it in the hash table
+     */
+    xmlRelaxNGDocumentPush(ctxt, ret);
+
+    /*
+     * Some preprocessing of the document content
+     */
+    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
+    if (doc == NULL) {
+        ctxt->doc = NULL;
+        return (NULL);
+    }
+
+    xmlRelaxNGDocumentPop(ctxt);
+
+    return (ret);
+}
+
+/************************************************************************
+ * 									*
+ * 			Error functions					*
+ * 									*
+ ************************************************************************/
+
+#define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
+#define VALID_ERR2(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 0);
+#define VALID_ERR3(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
+#define VALID_ERR2P(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 1);
+#define VALID_ERR3P(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 1);
+
+static const char *
+xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
+{
+    if (def == NULL)
+        return ("none");
+    switch (def->type) {
+        case XML_RELAXNG_EMPTY:
+            return ("empty");
+        case XML_RELAXNG_NOT_ALLOWED:
+            return ("notAllowed");
+        case XML_RELAXNG_EXCEPT:
+            return ("except");
+        case XML_RELAXNG_TEXT:
+            return ("text");
+        case XML_RELAXNG_ELEMENT:
+            return ("element");
+        case XML_RELAXNG_DATATYPE:
+            return ("datatype");
+        case XML_RELAXNG_VALUE:
+            return ("value");
+        case XML_RELAXNG_LIST:
+            return ("list");
+        case XML_RELAXNG_ATTRIBUTE:
+            return ("attribute");
+        case XML_RELAXNG_DEF:
+            return ("def");
+        case XML_RELAXNG_REF:
+            return ("ref");
+        case XML_RELAXNG_EXTERNALREF:
+            return ("externalRef");
+        case XML_RELAXNG_PARENTREF:
+            return ("parentRef");
+        case XML_RELAXNG_OPTIONAL:
+            return ("optional");
+        case XML_RELAXNG_ZEROORMORE:
+            return ("zeroOrMore");
+        case XML_RELAXNG_ONEORMORE:
+            return ("oneOrMore");
+        case XML_RELAXNG_CHOICE:
+            return ("choice");
+        case XML_RELAXNG_GROUP:
+            return ("group");
+        case XML_RELAXNG_INTERLEAVE:
+            return ("interleave");
+        case XML_RELAXNG_START:
+            return ("start");
+        case XML_RELAXNG_NOOP:
+            return ("noop");
+        case XML_RELAXNG_PARAM:
+            return ("param");
+    }
+    return ("unknown");
+}
+
+/**
+ * xmlRelaxNGGetErrorString:
+ * @err:  the error code
+ * @arg1:  the first string argument
+ * @arg2:  the second string argument
+ *
+ * computes a formatted error string for the given error code and args
+ *
+ * Returns the error string, it must be deallocated by the caller
+ */
+static xmlChar *
+xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
+                         const xmlChar * arg2)
+{
+    char msg[1000];
+
+    if (arg1 == NULL)
+        arg1 = BAD_CAST "";
+    if (arg2 == NULL)
+        arg2 = BAD_CAST "";
+
+    msg[0] = 0;
+    switch (err) {
+        case XML_RELAXNG_OK:
+            return (NULL);
+        case XML_RELAXNG_ERR_MEMORY:
+            return (xmlCharStrdup("out of memory\n"));
+        case XML_RELAXNG_ERR_TYPE:
+            snprintf(msg, 1000, "failed to validate type %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_TYPEVAL:
+            snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
+                     arg2);
+            break;
+        case XML_RELAXNG_ERR_DUPID:
+            snprintf(msg, 1000, "ID %s redefined\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_TYPECMP:
+            snprintf(msg, 1000, "failed to compare type %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_NOSTATE:
+            return (xmlCharStrdup("Internal error: no state\n"));
+        case XML_RELAXNG_ERR_NODEFINE:
+            return (xmlCharStrdup("Internal error: no define\n"));
+        case XML_RELAXNG_ERR_INTERNAL:
+            snprintf(msg, 1000, "Internal error: %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_LISTEXTRA:
+            snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_INTERNODATA:
+            return (xmlCharStrdup
+                    ("Internal: interleave block has no data\n"));
+        case XML_RELAXNG_ERR_INTERSEQ:
+            return (xmlCharStrdup("Invalid sequence in interleave\n"));
+        case XML_RELAXNG_ERR_INTEREXTRA:
+            snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_ELEMNAME:
+            snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
+                     arg2);
+            break;
+        case XML_RELAXNG_ERR_ELEMNONS:
+            snprintf(msg, 1000, "Expecting a namespace for element %s\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_ELEMWRONGNS:
+            snprintf(msg, 1000,
+                     "Element %s has wrong namespace: expecting %s\n", arg1,
+                     arg2);
+            break;
+        case XML_RELAXNG_ERR_ELEMWRONG:
+            snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_TEXTWRONG:
+            snprintf(msg, 1000,
+                     "Did not expect text in element %s content\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_ELEMEXTRANS:
+            snprintf(msg, 1000, "Expecting no namespace for element %s\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_ELEMNOTEMPTY:
+            snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_NOELEM:
+            snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_NOTELEM:
+            return (xmlCharStrdup("Expecting an element got text\n"));
+        case XML_RELAXNG_ERR_ATTRVALID:
+            snprintf(msg, 1000, "Element %s failed to validate attributes\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_CONTENTVALID:
+            snprintf(msg, 1000, "Element %s failed to validate content\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_EXTRACONTENT:
+            snprintf(msg, 1000, "Element %s has extra content: %s\n",
+                     arg1, arg2);
+            break;
+        case XML_RELAXNG_ERR_INVALIDATTR:
+            snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
+                     arg1, arg2);
+            break;
+        case XML_RELAXNG_ERR_LACKDATA:
+            snprintf(msg, 1000, "Datatype element %s contains no data\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_DATAELEM:
+            snprintf(msg, 1000, "Datatype element %s has child elements\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_VALELEM:
+            snprintf(msg, 1000, "Value element %s has child elements\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_LISTELEM:
+            snprintf(msg, 1000, "List element %s has child elements\n",
+                     arg1);
+            break;
+        case XML_RELAXNG_ERR_DATATYPE:
+            snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_VALUE:
+            snprintf(msg, 1000, "Error validating value %s\n", arg1);
+            break;
+        case XML_RELAXNG_ERR_LIST:
+            return (xmlCharStrdup("Error validating list\n"));
+        case XML_RELAXNG_ERR_NOGRAMMAR:
+            return (xmlCharStrdup("No top grammar defined\n"));
+        case XML_RELAXNG_ERR_EXTRADATA:
+            return (xmlCharStrdup("Extra data in the document\n"));
+        default:
+            return (xmlCharStrdup("Unknown error !\n"));
+    }
+    if (msg[0] == 0) {
+        snprintf(msg, 1000, "Unknown error code %d\n", err);
+    }
+    msg[1000 - 1] = 0;
+    return (xmlStrdup((xmlChar *) msg));
+}
+
+/**
+ * xmlRelaxNGShowValidError:
+ * @ctxt:  the validation context
+ * @err:  the error number
+ * @node:  the node
+ * @child:  the node child generating the problem.
+ * @arg1:  the first argument
+ * @arg2:  the second argument
+ *
+ * Show a validation error.
+ */
+static void
+xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidErr err, xmlNodePtr node,
+                         xmlNodePtr child, const xmlChar * arg1,
+                         const xmlChar * arg2)
+{
+    xmlChar *msg;
+
+    if (ctxt->flags & FLAGS_NOERROR)
+        return;
+
+#ifdef DEBUG_ERROR
+    xmlGenericError(xmlGenericErrorContext, "Show error %d\n", err);
+#endif
+    msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
+    if (msg == NULL)
+        return;
+
+    if (ctxt->errNo == XML_RELAXNG_OK)
+        ctxt->errNo = err;
+    xmlRngVErr(ctxt, (child == NULL ? node : child), err,
+               (const char *) msg, arg1, arg2);
+    xmlFree(msg);
+}
+
+/**
+ * xmlRelaxNGPopErrors:
+ * @ctxt:  the validation context
+ * @level:  the error level in the stack
+ *
+ * pop and discard all errors until the given level is reached
+ */
+static void
+xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
+{
+    int i;
+    xmlRelaxNGValidErrorPtr err;
+
+#ifdef DEBUG_ERROR
+    xmlGenericError(xmlGenericErrorContext,
+                    "Pop errors till level %d\n", level);
+#endif
+    for (i = level; i < ctxt->errNr; i++) {
+        err = &ctxt->errTab[i];
+        if (err->flags & ERROR_IS_DUP) {
+            if (err->arg1 != NULL)
+                xmlFree((xmlChar *) err->arg1);
+            err->arg1 = NULL;
+            if (err->arg2 != NULL)
+                xmlFree((xmlChar *) err->arg2);
+            err->arg2 = NULL;
+            err->flags = 0;
+        }
+    }
+    ctxt->errNr = level;
+    if (ctxt->errNr <= 0)
+        ctxt->err = NULL;
+}
+
+/**
+ * xmlRelaxNGDumpValidError:
+ * @ctxt:  the validation context
+ *
+ * Show all validation error over a given index.
+ */
+static void
+xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    int i, j, k;
+    xmlRelaxNGValidErrorPtr err, dup;
+
+#ifdef DEBUG_ERROR
+    xmlGenericError(xmlGenericErrorContext,
+                    "Dumping error stack %d errors\n", ctxt->errNr);
+#endif
+    for (i = 0, k = 0; i < ctxt->errNr; i++) {
+        err = &ctxt->errTab[i];
+        if (k < MAX_ERROR) {
+            for (j = 0; j < i; j++) {
+                dup = &ctxt->errTab[j];
+                if ((err->err == dup->err) && (err->node == dup->node) &&
+                    (xmlStrEqual(err->arg1, dup->arg1)) &&
+                    (xmlStrEqual(err->arg2, dup->arg2))) {
+                    goto skip;
+                }
+            }
+            xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
+                                     err->arg1, err->arg2);
+            k++;
+        }
+      skip:
+        if (err->flags & ERROR_IS_DUP) {
+            if (err->arg1 != NULL)
+                xmlFree((xmlChar *) err->arg1);
+            err->arg1 = NULL;
+            if (err->arg2 != NULL)
+                xmlFree((xmlChar *) err->arg2);
+            err->arg2 = NULL;
+            err->flags = 0;
+        }
+    }
+    ctxt->errNr = 0;
+}
+
+/**
+ * xmlRelaxNGAddValidError:
+ * @ctxt:  the validation context
+ * @err:  the error number
+ * @arg1:  the first argument
+ * @arg2:  the second argument
+ * @dup:  need to dup the args
+ *
+ * Register a validation error, either generating it if it's sure
+ * or stacking it for later handling if unsure.
+ */
+static void
+xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
+                        xmlRelaxNGValidErr err, const xmlChar * arg1,
+                        const xmlChar * arg2, int dup)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->flags & FLAGS_NOERROR)
+        return;
+
+#ifdef DEBUG_ERROR
+    xmlGenericError(xmlGenericErrorContext, "Adding error %d\n", err);
+#endif
+    /*
+     * generate the error directly
+     */
+    if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
+    	 (ctxt->flags & FLAGS_NEGATIVE)) {
+        xmlNodePtr node, seq;
+
+        /*
+         * Flush first any stacked error which might be the
+         * real cause of the problem.
+         */
+        if (ctxt->errNr != 0)
+            xmlRelaxNGDumpValidError(ctxt);
+        if (ctxt->state != NULL) {
+            node = ctxt->state->node;
+            seq = ctxt->state->seq;
+        } else {
+            node = seq = NULL;
+        }
+        if ((node == NULL) && (seq == NULL)) {
+            node = ctxt->pnode;
+        }
+        xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
+    }
+    /*
+     * Stack the error for later processing if needed
+     */
+    else {
+        xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
+    }
+}
+
+
+/************************************************************************
+ * 									*
+ * 			Type library hooks				*
+ * 									*
+ ************************************************************************/
+static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
+                                    const xmlChar * str);
+
+/**
+ * xmlRelaxNGSchemaTypeHave:
+ * @data:  data needed for the library
+ * @type:  the type name
+ *
+ * Check if the given type is provided by
+ * the W3C XMLSchema Datatype library.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar * type)
+{
+    xmlSchemaTypePtr typ;
+
+    if (type == NULL)
+        return (-1);
+    typ = xmlSchemaGetPredefinedType(type,
+                                     BAD_CAST
+                                     "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+        return (0);
+    return (1);
+}
+
+/**
+ * xmlRelaxNGSchemaTypeCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value:  the value to check
+ * @node:  the node
+ *
+ * Check if the given type and value are validated by
+ * the W3C XMLSchema Datatype library.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
+                          const xmlChar * type,
+                          const xmlChar * value,
+                          void **result, xmlNodePtr node)
+{
+    xmlSchemaTypePtr typ;
+    int ret;
+
+    if ((type == NULL) || (value == NULL))
+        return (-1);
+    typ = xmlSchemaGetPredefinedType(type,
+                                     BAD_CAST
+                                     "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+        return (-1);
+    ret = xmlSchemaValPredefTypeNode(typ, value,
+                                     (xmlSchemaValPtr *) result, node);
+    if (ret == 2)               /* special ID error code */
+        return (2);
+    if (ret == 0)
+        return (1);
+    if (ret > 0)
+        return (0);
+    return (-1);
+}
+
+/**
+ * xmlRelaxNGSchemaFacetCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @facet:  the facet name
+ * @val:  the facet value
+ * @strval:  the string value
+ * @value:  the value to check
+ *
+ * Function provided by a type library to check a value facet
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED,
+                           const xmlChar * type, const xmlChar * facetname,
+                           const xmlChar * val, const xmlChar * strval,
+                           void *value)
+{
+    xmlSchemaFacetPtr facet;
+    xmlSchemaTypePtr typ;
+    int ret;
+
+    if ((type == NULL) || (strval == NULL))
+        return (-1);
+    typ = xmlSchemaGetPredefinedType(type,
+                                     BAD_CAST
+                                     "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+        return (-1);
+
+    facet = xmlSchemaNewFacet();
+    if (facet == NULL)
+        return (-1);
+
+    if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) {
+        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) {
+        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) {
+        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) {
+        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) {
+        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
+    } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) {
+        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
+    } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) {
+        facet->type = XML_SCHEMA_FACET_PATTERN;
+    } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) {
+        facet->type = XML_SCHEMA_FACET_ENUMERATION;
+    } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) {
+        facet->type = XML_SCHEMA_FACET_WHITESPACE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "length")) {
+        facet->type = XML_SCHEMA_FACET_LENGTH;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) {
+        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
+    } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
+        facet->type = XML_SCHEMA_FACET_MINLENGTH;
+    } else {
+        xmlSchemaFreeFacet(facet);
+        return (-1);
+    }
+    facet->value = val;
+    ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
+    if (ret != 0) {
+        xmlSchemaFreeFacet(facet);
+        return (-1);
+    }
+    ret = xmlSchemaValidateFacet(typ, facet, strval, value);
+    xmlSchemaFreeFacet(facet);
+    if (ret != 0)
+        return (-1);
+    return (0);
+}
+
+/**
+ * xmlRelaxNGSchemaFreeValue:
+ * @data:  data needed for the library
+ * @value:  the value to free
+ *
+ * Function provided by a type library to free a Schemas value
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static void
+xmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED, void *value)
+{
+    xmlSchemaFreeValue(value);
+}
+
+/**
+ * xmlRelaxNGSchemaTypeCompare:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value1:  the first value
+ * @value2:  the second value
+ *
+ * Compare two values for equality accordingly a type from the W3C XMLSchema
+ * Datatype library.
+ *
+ * Returns 1 if equal, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
+                            const xmlChar * type,
+                            const xmlChar * value1,
+                            xmlNodePtr ctxt1,
+                            void *comp1,
+                            const xmlChar * value2, xmlNodePtr ctxt2)
+{
+    int ret;
+    xmlSchemaTypePtr typ;
+    xmlSchemaValPtr res1 = NULL, res2 = NULL;
+
+    if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
+        return (-1);
+    typ = xmlSchemaGetPredefinedType(type,
+                                     BAD_CAST
+                                     "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+        return (-1);
+    if (comp1 == NULL) {
+        ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, ctxt1);
+        if (ret != 0)
+            return (-1);
+        if (res1 == NULL)
+            return (-1);
+    } else {
+        res1 = (xmlSchemaValPtr) comp1;
+    }
+    ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
+    if (ret != 0) {
+	if ((comp1 == NULL) && (res1 != NULL))
+	    xmlSchemaFreeValue(res1);
+        return (-1);
+    }
+    if (res1 == NULL) {
+        return (-1);
+    }
+    ret = xmlSchemaCompareValues(res1, res2);
+    if (res1 != (xmlSchemaValPtr) comp1)
+        xmlSchemaFreeValue(res1);
+    xmlSchemaFreeValue(res2);
+    if (ret == -2)
+        return (-1);
+    if (ret == 0)
+        return (1);
+    return (0);
+}
+
+/**
+ * xmlRelaxNGDefaultTypeHave:
+ * @data:  data needed for the library
+ * @type:  the type name
+ *
+ * Check if the given type is provided by
+ * the default datatype library.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED,
+                          const xmlChar * type)
+{
+    if (type == NULL)
+        return (-1);
+    if (xmlStrEqual(type, BAD_CAST "string"))
+        return (1);
+    if (xmlStrEqual(type, BAD_CAST "token"))
+        return (1);
+    return (0);
+}
+
+/**
+ * xmlRelaxNGDefaultTypeCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value:  the value to check
+ * @node:  the node
+ *
+ * Check if the given type and value are validated by
+ * the default datatype library.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
+                           const xmlChar * type ATTRIBUTE_UNUSED,
+                           const xmlChar * value ATTRIBUTE_UNUSED,
+                           void **result ATTRIBUTE_UNUSED,
+                           xmlNodePtr node ATTRIBUTE_UNUSED)
+{
+    if (value == NULL)
+        return (-1);
+    if (xmlStrEqual(type, BAD_CAST "string"))
+        return (1);
+    if (xmlStrEqual(type, BAD_CAST "token")) {
+        return (1);
+    }
+
+    return (0);
+}
+
+/**
+ * xmlRelaxNGDefaultTypeCompare:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @value1:  the first value
+ * @value2:  the second value
+ *
+ * Compare two values accordingly a type from the default
+ * datatype library.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED,
+                             const xmlChar * type,
+                             const xmlChar * value1,
+                             xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,
+                             void *comp1 ATTRIBUTE_UNUSED,
+                             const xmlChar * value2,
+                             xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)
+{
+    int ret = -1;
+
+    if (xmlStrEqual(type, BAD_CAST "string")) {
+        ret = xmlStrEqual(value1, value2);
+    } else if (xmlStrEqual(type, BAD_CAST "token")) {
+        if (!xmlStrEqual(value1, value2)) {
+            xmlChar *nval, *nvalue;
+
+            /*
+             * TODO: trivial optimizations are possible by
+             * computing at compile-time
+             */
+            nval = xmlRelaxNGNormalize(NULL, value1);
+            nvalue = xmlRelaxNGNormalize(NULL, value2);
+
+            if ((nval == NULL) || (nvalue == NULL))
+                ret = -1;
+            else if (xmlStrEqual(nval, nvalue))
+                ret = 1;
+            else
+                ret = 0;
+            if (nval != NULL)
+                xmlFree(nval);
+            if (nvalue != NULL)
+                xmlFree(nvalue);
+        } else
+            ret = 1;
+    }
+    return (ret);
+}
+
+static int xmlRelaxNGTypeInitialized = 0;
+static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL;
+
+/**
+ * xmlRelaxNGFreeTypeLibrary:
+ * @lib:  the type library structure
+ * @namespace:  the URI bound to the library
+ *
+ * Free the structure associated to the type library
+ */
+static void
+xmlRelaxNGFreeTypeLibrary(xmlRelaxNGTypeLibraryPtr lib,
+                          const xmlChar * namespace ATTRIBUTE_UNUSED)
+{
+    if (lib == NULL)
+        return;
+    if (lib->namespace != NULL)
+        xmlFree((xmlChar *) lib->namespace);
+    xmlFree(lib);
+}
+
+/**
+ * xmlRelaxNGRegisterTypeLibrary:
+ * @namespace:  the URI bound to the library
+ * @data:  data associated to the library
+ * @have:  the provide function
+ * @check:  the checking function
+ * @comp:  the comparison function
+ *
+ * Register a new type library
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+static int
+xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
+                              xmlRelaxNGTypeHave have,
+                              xmlRelaxNGTypeCheck check,
+                              xmlRelaxNGTypeCompare comp,
+                              xmlRelaxNGFacetCheck facet,
+                              xmlRelaxNGTypeFree freef)
+{
+    xmlRelaxNGTypeLibraryPtr lib;
+    int ret;
+
+    if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
+        (check == NULL) || (comp == NULL))
+        return (-1);
+    if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Relax-NG types library '%s' already registered\n",
+                        namespace);
+        return (-1);
+    }
+    lib =
+        (xmlRelaxNGTypeLibraryPtr)
+        xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
+    if (lib == NULL) {
+        xmlRngVErrMemory(NULL, "adding types library\n");
+        return (-1);
+    }
+    memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
+    lib->namespace = xmlStrdup(namespace);
+    lib->data = data;
+    lib->have = have;
+    lib->comp = comp;
+    lib->check = check;
+    lib->facet = facet;
+    lib->freef = freef;
+    ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
+    if (ret < 0) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Relax-NG types library failed to register '%s'\n",
+                        namespace);
+        xmlRelaxNGFreeTypeLibrary(lib, namespace);
+        return (-1);
+    }
+    return (0);
+}
+
+/**
+ * xmlRelaxNGInitTypes:
+ *
+ * Initilize the default type libraries.
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xmlRelaxNGInitTypes(void)
+{
+    if (xmlRelaxNGTypeInitialized != 0)
+        return (0);
+    xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
+    if (xmlRelaxNGRegisteredTypes == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Failed to allocate sh table for Relax-NG types\n");
+        return (-1);
+    }
+    xmlRelaxNGRegisterTypeLibrary(BAD_CAST
+                                  "http://www.w3.org/2001/XMLSchema-datatypes",
+                                  NULL, xmlRelaxNGSchemaTypeHave,
+                                  xmlRelaxNGSchemaTypeCheck,
+                                  xmlRelaxNGSchemaTypeCompare,
+                                  xmlRelaxNGSchemaFacetCheck,
+                                  xmlRelaxNGSchemaFreeValue);
+    xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL,
+                                  xmlRelaxNGDefaultTypeHave,
+                                  xmlRelaxNGDefaultTypeCheck,
+                                  xmlRelaxNGDefaultTypeCompare, NULL,
+                                  NULL);
+    xmlRelaxNGTypeInitialized = 1;
+    return (0);
+}
+
+/**
+ * xmlRelaxNGCleanupTypes:
+ *
+ * Cleanup the default Schemas type library associated to RelaxNG
+ */
+void
+xmlRelaxNGCleanupTypes(void)
+{
+    xmlSchemaCleanupTypes();
+    if (xmlRelaxNGTypeInitialized == 0)
+        return;
+    xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
+                xmlRelaxNGFreeTypeLibrary);
+    xmlRelaxNGTypeInitialized = 0;
+}
+
+/************************************************************************
+ * 									*
+ * 		Compiling element content into regexp			*
+ * 									*
+ * Sometime the element content can be compiled into a pure regexp,	*
+ * This allows a faster execution and streamability at that level	*
+ * 									*
+ ************************************************************************/
+
+/* from automata.c but not exported */
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
+
+static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
+                                xmlRelaxNGDefinePtr def);
+
+/**
+ * xmlRelaxNGIsCompileable:
+ * @define:  the definition to check
+ *
+ * Check if a definition is nullable.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error
+ */
+static int
+xmlRelaxNGIsCompileable(xmlRelaxNGDefinePtr def)
+{
+    int ret = -1;
+
+    if (def == NULL) {
+        return (-1);
+    }
+    if ((def->type != XML_RELAXNG_ELEMENT) &&
+        (def->dflags & IS_COMPILABLE))
+        return (1);
+    if ((def->type != XML_RELAXNG_ELEMENT) &&
+        (def->dflags & IS_NOT_COMPILABLE))
+        return (0);
+    switch (def->type) {
+        case XML_RELAXNG_NOOP:
+            ret = xmlRelaxNGIsCompileable(def->content);
+            break;
+        case XML_RELAXNG_TEXT:
+        case XML_RELAXNG_EMPTY:
+            ret = 1;
+            break;
+        case XML_RELAXNG_ELEMENT:
+            /*
+             * Check if the element content is compileable
+             */
+            if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
+                ((def->dflags & IS_COMPILABLE) == 0)) {
+                xmlRelaxNGDefinePtr list;
+
+                list = def->content;
+                while (list != NULL) {
+                    ret = xmlRelaxNGIsCompileable(list);
+                    if (ret != 1)
+                        break;
+                    list = list->next;
+                }
+		/*
+		 * Because the routine is recursive, we must guard against
+		 * discovering both COMPILABLE and NOT_COMPILABLE
+		 */
+                if (ret == 0) {
+		    def->dflags &= ~IS_COMPILABLE;
+                    def->dflags |= IS_NOT_COMPILABLE;
+		}
+                if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
+                    def->dflags |= IS_COMPILABLE;
+#ifdef DEBUG_COMPILE
+                if (ret == 1) {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "element content for %s is compilable\n",
+                                    def->name);
+                } else if (ret == 0) {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "element content for %s is not compilable\n",
+                                    def->name);
+                } else {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "Problem in RelaxNGIsCompileable for element %s\n",
+                                    def->name);
+                }
+#endif
+            }
+            /*
+             * All elements return a compileable status unless they
+             * are generic like anyName
+             */
+            if ((def->nameClass != NULL) || (def->name == NULL))
+                ret = 0;
+            else
+                ret = 1;
+            return (ret);
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_EXTERNALREF:
+        case XML_RELAXNG_PARENTREF:
+            if (def->depth == -20) {
+                return (1);
+            } else {
+                xmlRelaxNGDefinePtr list;
+
+                def->depth = -20;
+                list = def->content;
+                while (list != NULL) {
+                    ret = xmlRelaxNGIsCompileable(list);
+                    if (ret != 1)
+                        break;
+                    list = list->next;
+                }
+            }
+            break;
+        case XML_RELAXNG_START:
+        case XML_RELAXNG_OPTIONAL:
+        case XML_RELAXNG_ZEROORMORE:
+        case XML_RELAXNG_ONEORMORE:
+        case XML_RELAXNG_CHOICE:
+        case XML_RELAXNG_GROUP:
+        case XML_RELAXNG_DEF:{
+                xmlRelaxNGDefinePtr list;
+
+                list = def->content;
+                while (list != NULL) {
+                    ret = xmlRelaxNGIsCompileable(list);
+                    if (ret != 1)
+                        break;
+                    list = list->next;
+                }
+                break;
+            }
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_ATTRIBUTE:
+        case XML_RELAXNG_INTERLEAVE:
+        case XML_RELAXNG_DATATYPE:
+        case XML_RELAXNG_LIST:
+        case XML_RELAXNG_PARAM:
+        case XML_RELAXNG_VALUE:
+        case XML_RELAXNG_NOT_ALLOWED:
+            ret = 0;
+            break;
+    }
+    if (ret == 0)
+        def->dflags |= IS_NOT_COMPILABLE;
+    if (ret == 1)
+        def->dflags |= IS_COMPILABLE;
+#ifdef DEBUG_COMPILE
+    if (ret == 1) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "RelaxNGIsCompileable %s : true\n",
+                        xmlRelaxNGDefName(def));
+    } else if (ret == 0) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "RelaxNGIsCompileable %s : false\n",
+                        xmlRelaxNGDefName(def));
+    } else {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Problem in RelaxNGIsCompileable %s\n",
+                        xmlRelaxNGDefName(def));
+    }
+#endif
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGCompile:
+ * ctxt:  the RelaxNG parser context
+ * @define:  the definition tree to compile
+ *
+ * Compile the set of definitions, it works recursively, till the
+ * element boundaries, where it tries to compile the content if possible
+ *
+ * Returns 0 if success and -1 in case of error
+ */
+static int
+xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
+{
+    int ret = 0;
+    xmlRelaxNGDefinePtr list;
+
+    if ((ctxt == NULL) || (def == NULL))
+        return (-1);
+
+    switch (def->type) {
+        case XML_RELAXNG_START:
+            if ((xmlRelaxNGIsCompileable(def) == 1) && (def->depth != -25)) {
+                xmlAutomataPtr oldam = ctxt->am;
+                xmlAutomataStatePtr oldstate = ctxt->state;
+
+                def->depth = -25;
+
+                list = def->content;
+                ctxt->am = xmlNewAutomata();
+                if (ctxt->am == NULL)
+                    return (-1);
+
+                /*
+                 * 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);
+                    list = list->next;
+                }
+                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
+                def->contModel = xmlAutomataCompile(ctxt->am);
+                xmlRegexpIsDeterminist(def->contModel);
+
+                xmlFreeAutomata(ctxt->am);
+                ctxt->state = oldstate;
+                ctxt->am = oldam;
+            }
+            break;
+        case XML_RELAXNG_ELEMENT:
+            if ((ctxt->am != NULL) && (def->name != NULL)) {
+                ctxt->state = xmlAutomataNewTransition2(ctxt->am,
+                                                        ctxt->state, NULL,
+                                                        def->name, def->ns,
+                                                        def);
+            }
+            if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
+                xmlAutomataPtr oldam = ctxt->am;
+                xmlAutomataStatePtr oldstate = ctxt->state;
+
+                def->depth = -25;
+
+                list = def->content;
+                ctxt->am = xmlNewAutomata();
+                if (ctxt->am == NULL)
+                    return (-1);
+                xmlAutomataSetFlags(ctxt->am, 1);
+                ctxt->state = xmlAutomataGetInitState(ctxt->am);
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
+                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
+                def->contModel = xmlAutomataCompile(ctxt->am);
+                if (!xmlRegexpIsDeterminist(def->contModel)) {
+#ifdef DEBUG_COMPILE
+                    xmlGenericError(xmlGenericErrorContext,
+                        "Content model not determinist %s\n",
+                                    def->name);
+#endif
+                    /*
+                     * we can only use the automata if it is determinist
+                     */
+                    xmlRegFreeRegexp(def->contModel);
+                    def->contModel = NULL;
+                }
+                xmlFreeAutomata(ctxt->am);
+                ctxt->state = oldstate;
+                ctxt->am = oldam;
+            } else {
+                xmlAutomataPtr oldam = ctxt->am;
+
+                /*
+                 * we can't build the content model for this element content
+                 * but it still might be possible to build it for some of its
+                 * children, recurse.
+                 */
+                ret = xmlRelaxNGTryCompile(ctxt, def);
+                ctxt->am = oldam;
+            }
+            break;
+        case XML_RELAXNG_NOOP:
+            ret = xmlRelaxNGCompile(ctxt, def->content);
+            break;
+        case XML_RELAXNG_OPTIONAL:{
+                xmlAutomataStatePtr oldstate = ctxt->state;
+
+                list = def->content;
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
+                xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+                break;
+            }
+        case XML_RELAXNG_ZEROORMORE:{
+                xmlAutomataStatePtr oldstate;
+
+                ctxt->state =
+                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
+                oldstate = ctxt->state;
+                list = def->content;
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
+                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
+                ctxt->state =
+                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
+                break;
+            }
+        case XML_RELAXNG_ONEORMORE:{
+                xmlAutomataStatePtr oldstate;
+
+                list = def->content;
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
+                oldstate = ctxt->state;
+                list = def->content;
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
+                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
+                ctxt->state =
+                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
+                break;
+            }
+        case XML_RELAXNG_CHOICE:{
+                xmlAutomataStatePtr target = NULL;
+                xmlAutomataStatePtr oldstate = ctxt->state;
+
+                list = def->content;
+                while (list != NULL) {
+                    ctxt->state = oldstate;
+                    ret = xmlRelaxNGCompile(ctxt, list);
+                    if (ret != 0)
+                        break;
+                    if (target == NULL)
+                        target = ctxt->state;
+                    else {
+                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
+                                              target);
+                    }
+                    list = list->next;
+                }
+                ctxt->state = target;
+
+                break;
+            }
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_EXTERNALREF:
+        case XML_RELAXNG_PARENTREF:
+        case XML_RELAXNG_GROUP:
+        case XML_RELAXNG_DEF:
+            list = def->content;
+            while (list != NULL) {
+                ret = xmlRelaxNGCompile(ctxt, list);
+                if (ret != 0)
+                    break;
+                list = list->next;
+            }
+            break;
+        case XML_RELAXNG_TEXT:{
+                xmlAutomataStatePtr oldstate;
+
+                ctxt->state =
+                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
+                oldstate = ctxt->state;
+                xmlRelaxNGCompile(ctxt, def->content);
+                xmlAutomataNewTransition(ctxt->am, ctxt->state,
+                                         ctxt->state, BAD_CAST "#text",
+                                         NULL);
+                ctxt->state =
+                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
+                break;
+            }
+        case XML_RELAXNG_EMPTY:
+            ctxt->state =
+                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
+            break;
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_ATTRIBUTE:
+        case XML_RELAXNG_INTERLEAVE:
+        case XML_RELAXNG_NOT_ALLOWED:
+        case XML_RELAXNG_DATATYPE:
+        case XML_RELAXNG_LIST:
+        case XML_RELAXNG_PARAM:
+        case XML_RELAXNG_VALUE:
+            /* This should not happen and generate an internal error */
+            fprintf(stderr, "RNG internal error trying to compile %s\n",
+                    xmlRelaxNGDefName(def));
+            break;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGTryCompile:
+ * ctxt:  the RelaxNG parser context
+ * @define:  the definition tree to compile
+ *
+ * Try to compile the set of definitions, it works recursively,
+ * possibly ignoring parts which cannot be compiled.
+ *
+ * Returns 0 if success and -1 in case of error
+ */
+static int
+xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
+{
+    int ret = 0;
+    xmlRelaxNGDefinePtr list;
+
+    if ((ctxt == NULL) || (def == NULL))
+        return (-1);
+
+    if ((def->type == XML_RELAXNG_START) ||
+        (def->type == XML_RELAXNG_ELEMENT)) {
+        ret = xmlRelaxNGIsCompileable(def);
+        if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
+            ctxt->am = NULL;
+            ret = xmlRelaxNGCompile(ctxt, def);
+#ifdef DEBUG_PROGRESSIVE
+            if (ret == 0) {
+                if (def->type == XML_RELAXNG_START)
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "compiled the start\n");
+                else
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "compiled element %s\n", def->name);
+            } else {
+                if (def->type == XML_RELAXNG_START)
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "failed to compile the start\n");
+                else
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "failed to compile element %s\n",
+                                    def->name);
+            }
+#endif
+            return (ret);
+        }
+    }
+    switch (def->type) {
+        case XML_RELAXNG_NOOP:
+            ret = xmlRelaxNGTryCompile(ctxt, def->content);
+            break;
+        case XML_RELAXNG_TEXT:
+        case XML_RELAXNG_DATATYPE:
+        case XML_RELAXNG_LIST:
+        case XML_RELAXNG_PARAM:
+        case XML_RELAXNG_VALUE:
+        case XML_RELAXNG_EMPTY:
+        case XML_RELAXNG_ELEMENT:
+            ret = 0;
+            break;
+        case XML_RELAXNG_OPTIONAL:
+        case XML_RELAXNG_ZEROORMORE:
+        case XML_RELAXNG_ONEORMORE:
+        case XML_RELAXNG_CHOICE:
+        case XML_RELAXNG_GROUP:
+        case XML_RELAXNG_DEF:
+        case XML_RELAXNG_START:
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_EXTERNALREF:
+        case XML_RELAXNG_PARENTREF:
+            list = def->content;
+            while (list != NULL) {
+                ret = xmlRelaxNGTryCompile(ctxt, list);
+                if (ret != 0)
+                    break;
+                list = list->next;
+            }
+            break;
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_ATTRIBUTE:
+        case XML_RELAXNG_INTERLEAVE:
+        case XML_RELAXNG_NOT_ALLOWED:
+            ret = 0;
+            break;
+    }
+    return (ret);
+}
+
+/************************************************************************
+ * 									*
+ * 			Parsing functions				*
+ * 									*
+ ************************************************************************/
+
+static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
+                                                    ctxt, xmlNodePtr node);
+static xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
+                                                  ctxt, xmlNodePtr node);
+static xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
+                                                   ctxt, xmlNodePtr nodes,
+                                                   int group);
+static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
+                                                  ctxt, xmlNodePtr node);
+static xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
+                                             xmlNodePtr node);
+static int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
+                                         xmlNodePtr nodes);
+static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
+                                                    ctxt, xmlNodePtr node,
+                                                    xmlRelaxNGDefinePtr
+                                                    def);
+static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
+                                                   ctxt, xmlNodePtr nodes);
+static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
+                                  xmlRelaxNGDefinePtr define,
+                                  xmlNodePtr elem);
+
+
+#define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))
+
+/**
+ * xmlRelaxNGIsNullable:
+ * @define:  the definition to verify
+ *
+ * Check if a definition is nullable.
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error
+ */
+static int
+xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
+{
+    int ret;
+
+    if (define == NULL)
+        return (-1);
+
+    if (define->dflags & IS_NULLABLE)
+        return (1);
+    if (define->dflags & IS_NOT_NULLABLE)
+        return (0);
+    switch (define->type) {
+        case XML_RELAXNG_EMPTY:
+        case XML_RELAXNG_TEXT:
+            ret = 1;
+            break;
+        case XML_RELAXNG_NOOP:
+        case XML_RELAXNG_DEF:
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_EXTERNALREF:
+        case XML_RELAXNG_PARENTREF:
+        case XML_RELAXNG_ONEORMORE:
+            ret = xmlRelaxNGIsNullable(define->content);
+            break;
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_NOT_ALLOWED:
+        case XML_RELAXNG_ELEMENT:
+        case XML_RELAXNG_DATATYPE:
+        case XML_RELAXNG_PARAM:
+        case XML_RELAXNG_VALUE:
+        case XML_RELAXNG_LIST:
+        case XML_RELAXNG_ATTRIBUTE:
+            ret = 0;
+            break;
+        case XML_RELAXNG_CHOICE:{
+                xmlRelaxNGDefinePtr list = define->content;
+
+                while (list != NULL) {
+                    ret = xmlRelaxNGIsNullable(list);
+                    if (ret != 0)
+                        goto done;
+                    list = list->next;
+                }
+                ret = 0;
+                break;
+            }
+        case XML_RELAXNG_START:
+        case XML_RELAXNG_INTERLEAVE:
+        case XML_RELAXNG_GROUP:{
+                xmlRelaxNGDefinePtr list = define->content;
+
+                while (list != NULL) {
+                    ret = xmlRelaxNGIsNullable(list);
+                    if (ret != 1)
+                        goto done;
+                    list = list->next;
+                }
+                return (1);
+            }
+        default:
+            return (-1);
+    }
+  done:
+    if (ret == 0)
+        define->dflags |= IS_NOT_NULLABLE;
+    if (ret == 1)
+        define->dflags |= IS_NULLABLE;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGIsBlank:
+ * @str:  a string
+ *
+ * Check if a string is ignorable c.f. 4.2. Whitespace
+ *
+ * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
+ */
+static int
+xmlRelaxNGIsBlank(xmlChar * str)
+{
+    if (str == NULL)
+        return (1);
+    while (*str != 0) {
+        if (!(IS_BLANK_CH(*str)))
+            return (0);
+        str++;
+    }
+    return (1);
+}
+
+/**
+ * xmlRelaxNGGetDataTypeLibrary:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the current data or value element
+ *
+ * Applies algorithm from 4.3. datatypeLibrary attribute
+ *
+ * Returns the datatypeLibary value or NULL if not found
+ */
+static xmlChar *
+xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                             xmlNodePtr node)
+{
+    xmlChar *ret, *escape;
+
+    if (node == NULL)
+        return(NULL);
+
+    if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
+        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
+        if (ret != NULL) {
+            if (ret[0] == 0) {
+                xmlFree(ret);
+                return (NULL);
+            }
+            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
+            if (escape == NULL) {
+                return (ret);
+            }
+            xmlFree(ret);
+            return (escape);
+        }
+    }
+    node = node->parent;
+    while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
+        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
+        if (ret != NULL) {
+            if (ret[0] == 0) {
+                xmlFree(ret);
+                return (NULL);
+            }
+            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
+            if (escape == NULL) {
+                return (ret);
+            }
+            xmlFree(ret);
+            return (escape);
+        }
+        node = node->parent;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlRelaxNGParseValue:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the data node.
+ *
+ * parse the content of a RelaxNG value node.
+ *
+ * Returns the definition pointer or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr def = NULL;
+    xmlRelaxNGTypeLibraryPtr lib = NULL;
+    xmlChar *type;
+    xmlChar *library;
+    int success = 0;
+
+    def = xmlRelaxNGNewDefine(ctxt, node);
+    if (def == NULL)
+        return (NULL);
+    def->type = XML_RELAXNG_VALUE;
+
+    type = xmlGetProp(node, BAD_CAST "type");
+    if (type != NULL) {
+        xmlRelaxNGNormExtSpace(type);
+        if (xmlValidateNCName(type, 0)) {
+            xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
+                       "value type '%s' is not an NCName\n", type, NULL);
+        }
+        library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
+        if (library == NULL)
+            library =
+                xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
+
+        def->name = type;
+        def->ns = library;
+
+        lib = (xmlRelaxNGTypeLibraryPtr)
+            xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
+        if (lib == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
+                       "Use of unregistered type library '%s'\n", library,
+                       NULL);
+            def->data = NULL;
+        } else {
+            def->data = lib;
+            if (lib->have == NULL) {
+                xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
+                           "Internal error with type library '%s': no 'have'\n",
+                           library, NULL);
+            } else {
+                success = lib->have(lib->data, def->name);
+                if (success != 1) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
+                               "Error type '%s' is not exported by type library '%s'\n",
+                               def->name, library);
+                }
+            }
+        }
+    }
+    if (node->children == NULL) {
+        def->value = xmlStrdup(BAD_CAST "");
+    } else if (((node->children->type != XML_TEXT_NODE) &&
+                (node->children->type != XML_CDATA_SECTION_NODE)) ||
+               (node->children->next != NULL)) {
+        xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
+                   "Expecting a single text value for <value>content\n",
+                   NULL, NULL);
+    } else if (def != NULL) {
+        def->value = xmlNodeGetContent(node);
+        if (def->value == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
+                       "Element <value> has no content\n", NULL, NULL);
+        } else if ((lib != NULL) && (lib->check != NULL) && (success == 1)) {
+            void *val = NULL;
+
+            success =
+                lib->check(lib->data, def->name, def->value, &val, node);
+            if (success != 1) {
+                xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
+                           "Value '%s' is not acceptable for type '%s'\n",
+                           def->value, def->name);
+            } else {
+                if (val != NULL)
+                    def->attrs = val;
+            }
+        }
+    }
+    return (def);
+}
+
+/**
+ * xmlRelaxNGParseData:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the data node.
+ *
+ * parse the content of a RelaxNG data node.
+ *
+ * Returns the definition pointer or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr def = NULL, except;
+    xmlRelaxNGDefinePtr param, lastparam = NULL;
+    xmlRelaxNGTypeLibraryPtr lib;
+    xmlChar *type;
+    xmlChar *library;
+    xmlNodePtr content;
+    int tmp;
+
+    type = xmlGetProp(node, BAD_CAST "type");
+    if (type == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL,
+                   NULL);
+        return (NULL);
+    }
+    xmlRelaxNGNormExtSpace(type);
+    if (xmlValidateNCName(type, 0)) {
+        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
+                   "data type '%s' is not an NCName\n", type, NULL);
+    }
+    library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
+    if (library == NULL)
+        library =
+            xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
+
+    def = xmlRelaxNGNewDefine(ctxt, node);
+    if (def == NULL) {
+        xmlFree(type);
+        return (NULL);
+    }
+    def->type = XML_RELAXNG_DATATYPE;
+    def->name = type;
+    def->ns = library;
+
+    lib = (xmlRelaxNGTypeLibraryPtr)
+        xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
+    if (lib == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
+                   "Use of unregistered type library '%s'\n", library,
+                   NULL);
+        def->data = NULL;
+    } else {
+        def->data = lib;
+        if (lib->have == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
+                       "Internal error with type library '%s': no 'have'\n",
+                       library, NULL);
+        } else {
+            tmp = lib->have(lib->data, def->name);
+            if (tmp != 1) {
+                xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
+                           "Error type '%s' is not exported by type library '%s'\n",
+                           def->name, library);
+            } else
+                if ((xmlStrEqual
+                     (library,
+                      BAD_CAST
+                      "http://www.w3.org/2001/XMLSchema-datatypes"))
+                    && ((xmlStrEqual(def->name, BAD_CAST "IDREF"))
+                        || (xmlStrEqual(def->name, BAD_CAST "IDREFS")))) {
+                ctxt->idref = 1;
+            }
+        }
+    }
+    content = node->children;
+
+    /*
+     * Handle optional params
+     */
+    while (content != NULL) {
+        if (!xmlStrEqual(content->name, BAD_CAST "param"))
+            break;
+        if (xmlStrEqual(library,
+                        BAD_CAST "http://relaxng.org/ns/structure/1.0")) {
+            xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
+                       "Type library '%s' does not allow type parameters\n",
+                       library, NULL);
+            content = content->next;
+            while ((content != NULL) &&
+                   (xmlStrEqual(content->name, BAD_CAST "param")))
+                content = content->next;
+        } else {
+            param = xmlRelaxNGNewDefine(ctxt, node);
+            if (param != NULL) {
+                param->type = XML_RELAXNG_PARAM;
+                param->name = xmlGetProp(content, BAD_CAST "name");
+                if (param->name == NULL) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
+                               "param has no name\n", NULL, NULL);
+                }
+                param->value = xmlNodeGetContent(content);
+                if (lastparam == NULL) {
+                    def->attrs = lastparam = param;
+                } else {
+                    lastparam->next = param;
+                    lastparam = param;
+                }
+                if (lib != NULL) {
+                }
+            }
+            content = content->next;
+        }
+    }
+    /*
+     * Handle optional except
+     */
+    if ((content != NULL)
+        && (xmlStrEqual(content->name, BAD_CAST "except"))) {
+        xmlNodePtr child;
+        xmlRelaxNGDefinePtr tmp2, last = NULL;
+
+        except = xmlRelaxNGNewDefine(ctxt, node);
+        if (except == NULL) {
+            return (def);
+        }
+        except->type = XML_RELAXNG_EXCEPT;
+        child = content->children;
+	def->content = except;
+        if (child == NULL) {
+            xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
+                       "except has no content\n", NULL, NULL);
+        }
+        while (child != NULL) {
+            tmp2 = xmlRelaxNGParsePattern(ctxt, child);
+            if (tmp2 != NULL) {
+                if (last == NULL) {
+                    except->content = last = tmp2;
+                } else {
+                    last->next = tmp2;
+                    last = tmp2;
+                }
+            }
+            child = child->next;
+        }
+        content = content->next;
+    }
+    /*
+     * Check there is no unhandled data
+     */
+    if (content != NULL) {
+        xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
+                   "Element data has unexpected content %s\n",
+                   content->name, NULL);
+    }
+
+    return (def);
+}
+
+static const xmlChar *invalidName = BAD_CAST "\1";
+
+/**
+ * xmlRelaxNGCompareNameClasses:
+ * @defs1:  the first element/attribute defs
+ * @defs2:  the second element/attribute defs
+ * @name:  the restriction on the name
+ * @ns:  the restriction on the namespace
+ *
+ * Compare the 2 lists of element definitions. The comparison is
+ * that if both lists do not accept the same QNames, it returns 1
+ * If the 2 lists can accept the same QName the comparison returns 0
+ *
+ * Returns 1 disttinct, 0 if equal
+ */
+static int
+xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
+                             xmlRelaxNGDefinePtr def2)
+{
+    int ret = 1;
+    xmlNode node;
+    xmlNs ns;
+    xmlRelaxNGValidCtxt ctxt;
+
+    memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));
+
+    ctxt.flags = FLAGS_IGNORABLE | FLAGS_NOERROR;
+
+    if ((def1->type == XML_RELAXNG_ELEMENT) ||
+        (def1->type == XML_RELAXNG_ATTRIBUTE)) {
+        if (def2->type == XML_RELAXNG_TEXT)
+            return (1);
+        if (def1->name != NULL) {
+            node.name = def1->name;
+        } else {
+            node.name = invalidName;
+        }
+        if (def1->ns != NULL) {
+            if (def1->ns[0] == 0) {
+                node.ns = NULL;
+            } else {
+	        node.ns = &ns;
+                ns.href = def1->ns;
+            }
+        } else {
+            node.ns = NULL;
+        }
+        if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
+            if (def1->nameClass != NULL) {
+                ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
+            } else {
+                ret = 0;
+            }
+        } else {
+            ret = 1;
+        }
+    } else if (def1->type == XML_RELAXNG_TEXT) {
+        if (def2->type == XML_RELAXNG_TEXT)
+            return (0);
+        return (1);
+    } else if (def1->type == XML_RELAXNG_EXCEPT) {
+        TODO ret = 0;
+    } else {
+        TODO ret = 0;
+    }
+    if (ret == 0)
+        return (ret);
+    if ((def2->type == XML_RELAXNG_ELEMENT) ||
+        (def2->type == XML_RELAXNG_ATTRIBUTE)) {
+        if (def2->name != NULL) {
+            node.name = def2->name;
+        } else {
+            node.name = invalidName;
+        }
+        node.ns = &ns;
+        if (def2->ns != NULL) {
+            if (def2->ns[0] == 0) {
+                node.ns = NULL;
+            } else {
+                ns.href = def2->ns;
+            }
+        } else {
+            ns.href = invalidName;
+        }
+        if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
+            if (def2->nameClass != NULL) {
+                ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
+            } else {
+                ret = 0;
+            }
+        } else {
+            ret = 1;
+        }
+    } else {
+        TODO ret = 0;
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGCompareElemDefLists:
+ * @ctxt:  a Relax-NG parser context
+ * @defs1:  the first list of element/attribute defs
+ * @defs2:  the second list of element/attribute defs
+ *
+ * Compare the 2 lists of element or attribute definitions. The comparison
+ * is that if both lists do not accept the same QNames, it returns 1
+ * If the 2 lists can accept the same QName the comparison returns 0
+ *
+ * Returns 1 disttinct, 0 if equal
+ */
+static int
+xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt
+                              ATTRIBUTE_UNUSED, xmlRelaxNGDefinePtr * def1,
+                              xmlRelaxNGDefinePtr * def2)
+{
+    xmlRelaxNGDefinePtr *basedef2 = def2;
+
+    if ((def1 == NULL) || (def2 == NULL))
+        return (1);
+    if ((*def1 == NULL) || (*def2 == NULL))
+        return (1);
+    while (*def1 != NULL) {
+        while ((*def2) != NULL) {
+            if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
+                return (0);
+            def2++;
+        }
+        def2 = basedef2;
+        def1++;
+    }
+    return (1);
+}
+
+/**
+ * xmlRelaxNGGenerateAttributes:
+ * @ctxt:  a Relax-NG parser context
+ * @def:  the definition definition
+ *
+ * Check if the definition can only generate attributes
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,
+                             xmlRelaxNGDefinePtr def)
+{
+    xmlRelaxNGDefinePtr parent, cur, tmp;
+
+    /*
+     * Don't run that check in case of error. Infinite recursion
+     * becomes possible.
+     */
+    if (ctxt->nbErrors != 0)
+        return (-1);
+
+    parent = NULL;
+    cur = def;
+    while (cur != NULL) {
+        if ((cur->type == XML_RELAXNG_ELEMENT) ||
+            (cur->type == XML_RELAXNG_TEXT) ||
+            (cur->type == XML_RELAXNG_DATATYPE) ||
+            (cur->type == XML_RELAXNG_PARAM) ||
+            (cur->type == XML_RELAXNG_LIST) ||
+            (cur->type == XML_RELAXNG_VALUE) ||
+            (cur->type == XML_RELAXNG_EMPTY))
+            return (0);
+        if ((cur->type == XML_RELAXNG_CHOICE) ||
+            (cur->type == XML_RELAXNG_INTERLEAVE) ||
+            (cur->type == XML_RELAXNG_GROUP) ||
+            (cur->type == XML_RELAXNG_ONEORMORE) ||
+            (cur->type == XML_RELAXNG_ZEROORMORE) ||
+            (cur->type == XML_RELAXNG_OPTIONAL) ||
+            (cur->type == XML_RELAXNG_PARENTREF) ||
+            (cur->type == XML_RELAXNG_EXTERNALREF) ||
+            (cur->type == XML_RELAXNG_REF) ||
+            (cur->type == XML_RELAXNG_DEF)) {
+            if (cur->content != NULL) {
+                parent = cur;
+                cur = cur->content;
+                tmp = cur;
+                while (tmp != NULL) {
+                    tmp->parent = parent;
+                    tmp = tmp->next;
+                }
+                continue;
+            }
+        }
+        if (cur == def)
+            break;
+        if (cur->next != NULL) {
+            cur = cur->next;
+            continue;
+        }
+        do {
+            cur = cur->parent;
+            if (cur == NULL)
+                break;
+            if (cur == def)
+                return (1);
+            if (cur->next != NULL) {
+                cur = cur->next;
+                break;
+            }
+        } while (cur != NULL);
+    }
+    return (1);
+}
+
+/**
+ * xmlRelaxNGGetElements:
+ * @ctxt:  a Relax-NG parser context
+ * @def:  the definition definition
+ * @eora:  gather elements (0) or attributes (1)
+ *
+ * Compute the list of top elements a definition can generate
+ *
+ * Returns a list of elements or NULL if none was found.
+ */
+static xmlRelaxNGDefinePtr *
+xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
+                      xmlRelaxNGDefinePtr def, int eora)
+{
+    xmlRelaxNGDefinePtr *ret = NULL, parent, cur, tmp;
+    int len = 0;
+    int max = 0;
+
+    /*
+     * Don't run that check in case of error. Infinite recursion
+     * becomes possible.
+     */
+    if (ctxt->nbErrors != 0)
+        return (NULL);
+
+    parent = NULL;
+    cur = def;
+    while (cur != NULL) {
+        if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) ||
+                             (cur->type == XML_RELAXNG_TEXT))) ||
+            ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE))) {
+            if (ret == NULL) {
+                max = 10;
+                ret = (xmlRelaxNGDefinePtr *)
+                    xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
+                if (ret == NULL) {
+                    xmlRngPErrMemory(ctxt, "getting element list\n");
+                    return (NULL);
+                }
+            } else if (max <= len) {
+	        xmlRelaxNGDefinePtr *temp;
+
+                max *= 2;
+                temp = xmlRealloc(ret,
+                               (max + 1) * sizeof(xmlRelaxNGDefinePtr));
+                if (temp == NULL) {
+                    xmlRngPErrMemory(ctxt, "getting element list\n");
+		    xmlFree(ret);
+                    return (NULL);
+                }
+		ret = temp;
+            }
+            ret[len++] = cur;
+            ret[len] = NULL;
+        } else if ((cur->type == XML_RELAXNG_CHOICE) ||
+                   (cur->type == XML_RELAXNG_INTERLEAVE) ||
+                   (cur->type == XML_RELAXNG_GROUP) ||
+                   (cur->type == XML_RELAXNG_ONEORMORE) ||
+                   (cur->type == XML_RELAXNG_ZEROORMORE) ||
+                   (cur->type == XML_RELAXNG_OPTIONAL) ||
+                   (cur->type == XML_RELAXNG_PARENTREF) ||
+                   (cur->type == XML_RELAXNG_REF) ||
+                   (cur->type == XML_RELAXNG_DEF) ||
+		   (cur->type == XML_RELAXNG_EXTERNALREF)) {
+            /*
+             * Don't go within elements or attributes or string values.
+             * Just gather the element top list
+             */
+            if (cur->content != NULL) {
+                parent = cur;
+                cur = cur->content;
+                tmp = cur;
+                while (tmp != NULL) {
+                    tmp->parent = parent;
+                    tmp = tmp->next;
+                }
+                continue;
+            }
+        }
+        if (cur == def)
+            break;
+        if (cur->next != NULL) {
+            cur = cur->next;
+            continue;
+        }
+        do {
+            cur = cur->parent;
+            if (cur == NULL)
+                break;
+            if (cur == def)
+                return (ret);
+            if (cur->next != NULL) {
+                cur = cur->next;
+                break;
+            }
+        } while (cur != NULL);
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGCheckChoiceDeterminism:
+ * @ctxt:  a Relax-NG parser context
+ * @def:  the choice definition
+ *
+ * Also used to find indeterministic pattern in choice
+ */
+static void
+xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
+                                 xmlRelaxNGDefinePtr def)
+{
+    xmlRelaxNGDefinePtr **list;
+    xmlRelaxNGDefinePtr cur;
+    int nbchild = 0, i, j, ret;
+    int is_nullable = 0;
+    int is_indeterminist = 0;
+    xmlHashTablePtr triage = NULL;
+    int is_triable = 1;
+
+    if ((def == NULL) || (def->type != XML_RELAXNG_CHOICE))
+        return;
+
+    if (def->dflags & IS_PROCESSED)
+        return;
+
+    /*
+     * Don't run that check in case of error. Infinite recursion
+     * becomes possible.
+     */
+    if (ctxt->nbErrors != 0)
+        return;
+
+    is_nullable = xmlRelaxNGIsNullable(def);
+
+    cur = def->content;
+    while (cur != NULL) {
+        nbchild++;
+        cur = cur->next;
+    }
+
+    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
+                                              sizeof(xmlRelaxNGDefinePtr
+                                                     *));
+    if (list == NULL) {
+        xmlRngPErrMemory(ctxt, "building choice\n");
+        return;
+    }
+    i = 0;
+    /*
+     * a bit strong but safe
+     */
+    if (is_nullable == 0) {
+        triage = xmlHashCreate(10);
+    } else {
+        is_triable = 0;
+    }
+    cur = def->content;
+    while (cur != NULL) {
+        list[i] = xmlRelaxNGGetElements(ctxt, cur, 0);
+        if ((list[i] == NULL) || (list[i][0] == NULL)) {
+            is_triable = 0;
+        } else if (is_triable == 1) {
+            xmlRelaxNGDefinePtr *tmp;
+            int res;
+
+            tmp = list[i];
+            while ((*tmp != NULL) && (is_triable == 1)) {
+                if ((*tmp)->type == XML_RELAXNG_TEXT) {
+                    res = xmlHashAddEntry2(triage,
+                                           BAD_CAST "#text", NULL,
+                                           (void *) cur);
+                    if (res != 0)
+                        is_triable = -1;
+                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
+                           ((*tmp)->name != NULL)) {
+                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
+                        res = xmlHashAddEntry2(triage,
+                                               (*tmp)->name, NULL,
+                                               (void *) cur);
+                    else
+                        res = xmlHashAddEntry2(triage,
+                                               (*tmp)->name, (*tmp)->ns,
+                                               (void *) cur);
+                    if (res != 0)
+                        is_triable = -1;
+                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
+                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
+                        res = xmlHashAddEntry2(triage,
+                                               BAD_CAST "#any", NULL,
+                                               (void *) cur);
+                    else
+                        res = xmlHashAddEntry2(triage,
+                                               BAD_CAST "#any", (*tmp)->ns,
+                                               (void *) cur);
+                    if (res != 0)
+                        is_triable = -1;
+                } else {
+                    is_triable = -1;
+                }
+                tmp++;
+            }
+        }
+        i++;
+        cur = cur->next;
+    }
+
+    for (i = 0; i < nbchild; i++) {
+        if (list[i] == NULL)
+            continue;
+        for (j = 0; j < i; j++) {
+            if (list[j] == NULL)
+                continue;
+            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
+            if (ret == 0) {
+                is_indeterminist = 1;
+            }
+        }
+    }
+    for (i = 0; i < nbchild; i++) {
+        if (list[i] != NULL)
+            xmlFree(list[i]);
+    }
+
+    xmlFree(list);
+    if (is_indeterminist) {
+        def->dflags |= IS_INDETERMINIST;
+    }
+    if (is_triable == 1) {
+        def->dflags |= IS_TRIABLE;
+        def->data = triage;
+    } else if (triage != NULL) {
+        xmlHashFree(triage, NULL);
+    }
+    def->dflags |= IS_PROCESSED;
+}
+
+/**
+ * xmlRelaxNGCheckGroupAttrs:
+ * @ctxt:  a Relax-NG parser context
+ * @def:  the group definition
+ *
+ * Detects violations of rule 7.3
+ */
+static void
+xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
+                          xmlRelaxNGDefinePtr def)
+{
+    xmlRelaxNGDefinePtr **list;
+    xmlRelaxNGDefinePtr cur;
+    int nbchild = 0, i, j, ret;
+
+    if ((def == NULL) ||
+        ((def->type != XML_RELAXNG_GROUP) &&
+         (def->type != XML_RELAXNG_ELEMENT)))
+        return;
+
+    if (def->dflags & IS_PROCESSED)
+        return;
+
+    /*
+     * Don't run that check in case of error. Infinite recursion
+     * becomes possible.
+     */
+    if (ctxt->nbErrors != 0)
+        return;
+
+    cur = def->attrs;
+    while (cur != NULL) {
+        nbchild++;
+        cur = cur->next;
+    }
+    cur = def->content;
+    while (cur != NULL) {
+        nbchild++;
+        cur = cur->next;
+    }
+
+    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
+                                              sizeof(xmlRelaxNGDefinePtr
+                                                     *));
+    if (list == NULL) {
+        xmlRngPErrMemory(ctxt, "building group\n");
+        return;
+    }
+    i = 0;
+    cur = def->attrs;
+    while (cur != NULL) {
+        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
+        i++;
+        cur = cur->next;
+    }
+    cur = def->content;
+    while (cur != NULL) {
+        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
+        i++;
+        cur = cur->next;
+    }
+
+    for (i = 0; i < nbchild; i++) {
+        if (list[i] == NULL)
+            continue;
+        for (j = 0; j < i; j++) {
+            if (list[j] == NULL)
+                continue;
+            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
+            if (ret == 0) {
+                xmlRngPErr(ctxt, def->node, XML_RNGP_GROUP_ATTR_CONFLICT,
+                           "Attributes conflicts in group\n", NULL, NULL);
+            }
+        }
+    }
+    for (i = 0; i < nbchild; i++) {
+        if (list[i] != NULL)
+            xmlFree(list[i]);
+    }
+
+    xmlFree(list);
+    def->dflags |= IS_PROCESSED;
+}
+
+/**
+ * xmlRelaxNGComputeInterleaves:
+ * @def:  the interleave definition
+ * @ctxt:  a Relax-NG parser context
+ * @name:  the definition name
+ *
+ * A lot of work for preprocessing interleave definitions
+ * is potentially needed to get a decent execution speed at runtime
+ *   - trying to get a total order on the element nodes generated
+ *     by the interleaves, order the list of interleave definitions
+ *     following that order.
+ *   - if <text/> is used to handle mixed content, it is better to
+ *     flag this in the define and simplify the runtime checking
+ *     algorithm
+ */
+static void
+xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
+                             xmlRelaxNGParserCtxtPtr ctxt,
+                             xmlChar * name ATTRIBUTE_UNUSED)
+{
+    xmlRelaxNGDefinePtr cur, *tmp;
+
+    xmlRelaxNGPartitionPtr partitions = NULL;
+    xmlRelaxNGInterleaveGroupPtr *groups = NULL;
+    xmlRelaxNGInterleaveGroupPtr group;
+    int i, j, ret, res;
+    int nbgroups = 0;
+    int nbchild = 0;
+    int is_mixed = 0;
+    int is_determinist = 1;
+
+    /*
+     * Don't run that check in case of error. Infinite recursion
+     * becomes possible.
+     */
+    if (ctxt->nbErrors != 0)
+        return;
+
+#ifdef DEBUG_INTERLEAVE
+    xmlGenericError(xmlGenericErrorContext,
+                    "xmlRelaxNGComputeInterleaves(%s)\n", name);
+#endif
+    cur = def->content;
+    while (cur != NULL) {
+        nbchild++;
+        cur = cur->next;
+    }
+
+#ifdef DEBUG_INTERLEAVE
+    xmlGenericError(xmlGenericErrorContext, "  %d child\n", nbchild);
+#endif
+    groups = (xmlRelaxNGInterleaveGroupPtr *)
+        xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
+    if (groups == NULL)
+        goto error;
+    cur = def->content;
+    while (cur != NULL) {
+        groups[nbgroups] = (xmlRelaxNGInterleaveGroupPtr)
+            xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
+        if (groups[nbgroups] == NULL)
+            goto error;
+        if (cur->type == XML_RELAXNG_TEXT)
+            is_mixed++;
+        groups[nbgroups]->rule = cur;
+        groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 0);
+        groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
+        nbgroups++;
+        cur = cur->next;
+    }
+#ifdef DEBUG_INTERLEAVE
+    xmlGenericError(xmlGenericErrorContext, "  %d groups\n", nbgroups);
+#endif
+
+    /*
+     * Let's check that all rules makes a partitions according to 7.4
+     */
+    partitions = (xmlRelaxNGPartitionPtr)
+        xmlMalloc(sizeof(xmlRelaxNGPartition));
+    if (partitions == NULL)
+        goto error;
+    memset(partitions, 0, sizeof(xmlRelaxNGPartition));
+    partitions->nbgroups = nbgroups;
+    partitions->triage = xmlHashCreate(nbgroups);
+    for (i = 0; i < nbgroups; i++) {
+        group = groups[i];
+        for (j = i + 1; j < nbgroups; j++) {
+            if (groups[j] == NULL)
+                continue;
+
+            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->defs,
+                                                groups[j]->defs);
+            if (ret == 0) {
+                xmlRngPErr(ctxt, def->node, XML_RNGP_ELEM_TEXT_CONFLICT,
+                           "Element or text conflicts in interleave\n",
+                           NULL, NULL);
+            }
+            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
+                                                groups[j]->attrs);
+            if (ret == 0) {
+                xmlRngPErr(ctxt, def->node, XML_RNGP_ATTR_CONFLICT,
+                           "Attributes conflicts in interleave\n", NULL,
+                           NULL);
+            }
+        }
+        tmp = group->defs;
+        if ((tmp != NULL) && (*tmp != NULL)) {
+            while (*tmp != NULL) {
+                if ((*tmp)->type == XML_RELAXNG_TEXT) {
+                    res = xmlHashAddEntry2(partitions->triage,
+                                           BAD_CAST "#text", NULL,
+                                           (void *) (long) (i + 1));
+                    if (res != 0)
+                        is_determinist = -1;
+                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
+                           ((*tmp)->name != NULL)) {
+                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
+                        res = xmlHashAddEntry2(partitions->triage,
+                                               (*tmp)->name, NULL,
+                                               (void *) (long) (i + 1));
+                    else
+                        res = xmlHashAddEntry2(partitions->triage,
+                                               (*tmp)->name, (*tmp)->ns,
+                                               (void *) (long) (i + 1));
+                    if (res != 0)
+                        is_determinist = -1;
+                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
+                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
+                        res = xmlHashAddEntry2(partitions->triage,
+                                               BAD_CAST "#any", NULL,
+                                               (void *) (long) (i + 1));
+                    else
+                        res = xmlHashAddEntry2(partitions->triage,
+                                               BAD_CAST "#any", (*tmp)->ns,
+                                               (void *) (long) (i + 1));
+                    if ((*tmp)->nameClass != NULL)
+                        is_determinist = 2;
+                    if (res != 0)
+                        is_determinist = -1;
+                } else {
+                    is_determinist = -1;
+                }
+                tmp++;
+            }
+        } else {
+            is_determinist = 0;
+        }
+    }
+    partitions->groups = groups;
+
+    /*
+     * and save the partition list back in the def
+     */
+    def->data = partitions;
+    if (is_mixed != 0)
+        def->dflags |= IS_MIXED;
+    if (is_determinist == 1)
+        partitions->flags = IS_DETERMINIST;
+    if (is_determinist == 2)
+        partitions->flags = IS_DETERMINIST | IS_NEEDCHECK;
+    return;
+
+  error:
+    xmlRngPErrMemory(ctxt, "in interleave computation\n");
+    if (groups != NULL) {
+        for (i = 0; i < nbgroups; i++)
+            if (groups[i] != NULL) {
+                if (groups[i]->defs != NULL)
+                    xmlFree(groups[i]->defs);
+                xmlFree(groups[i]);
+            }
+        xmlFree(groups);
+    }
+    xmlRelaxNGFreePartition(partitions);
+}
+
+/**
+ * xmlRelaxNGParseInterleave:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the data node.
+ *
+ * parse the content of a RelaxNG interleave node.
+ *
+ * Returns the definition pointer or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr def = NULL;
+    xmlRelaxNGDefinePtr last = NULL, cur;
+    xmlNodePtr child;
+
+    def = xmlRelaxNGNewDefine(ctxt, node);
+    if (def == NULL) {
+        return (NULL);
+    }
+    def->type = XML_RELAXNG_INTERLEAVE;
+
+    if (ctxt->interleaves == NULL)
+        ctxt->interleaves = xmlHashCreate(10);
+    if (ctxt->interleaves == NULL) {
+        xmlRngPErrMemory(ctxt, "create interleaves\n");
+    } else {
+        char name[32];
+
+        snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
+        if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
+            xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_ADD,
+                       "Failed to add %s to hash table\n",
+		       (const xmlChar *) name, NULL);
+        }
+    }
+    child = node->children;
+    if (child == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_NO_CONTENT,
+                   "Element interleave is empty\n", NULL, NULL);
+    }
+    while (child != NULL) {
+        if (IS_RELAXNG(child, "element")) {
+            cur = xmlRelaxNGParseElement(ctxt, child);
+        } else {
+            cur = xmlRelaxNGParsePattern(ctxt, child);
+        }
+        if (cur != NULL) {
+            cur->parent = def;
+            if (last == NULL) {
+                def->content = last = cur;
+            } else {
+                last->next = cur;
+                last = cur;
+            }
+        }
+        child = child->next;
+    }
+
+    return (def);
+}
+
+/**
+ * xmlRelaxNGParseInclude:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the include node
+ *
+ * Integrate the content of an include node in the current grammar
+ *
+ * Returns 0 in case of success or -1 in case of error
+ */
+static int
+xmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGIncludePtr incl;
+    xmlNodePtr root;
+    int ret = 0, tmp;
+
+    incl = node->psvi;
+    if (incl == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_INCLUDE_EMPTY,
+                   "Include node has no data\n", NULL, NULL);
+        return (-1);
+    }
+    root = xmlDocGetRootElement(incl->doc);
+    if (root == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "Include document is empty\n",
+                   NULL, NULL);
+        return (-1);
+    }
+    if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
+        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
+                   "Include document root is not a grammar\n", NULL, NULL);
+        return (-1);
+    }
+
+    /*
+     * Merge the definition from both the include and the internal list
+     */
+    if (root->children != NULL) {
+        tmp = xmlRelaxNGParseGrammarContent(ctxt, root->children);
+        if (tmp != 0)
+            ret = -1;
+    }
+    if (node->children != NULL) {
+        tmp = xmlRelaxNGParseGrammarContent(ctxt, node->children);
+        if (tmp != 0)
+            ret = -1;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseDefine:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the define node
+ *
+ * parse the content of a RelaxNG define element node.
+ *
+ * Returns 0 in case of success or -1 in case of error
+ */
+static int
+xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlChar *name;
+    int ret = 0, tmp;
+    xmlRelaxNGDefinePtr def;
+    const xmlChar *olddefine;
+
+    name = xmlGetProp(node, BAD_CAST "name");
+    if (name == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_NAME_MISSING,
+                   "define has no name\n", NULL, NULL);
+    } else {
+        xmlRelaxNGNormExtSpace(name);
+        if (xmlValidateNCName(name, 0)) {
+            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_DEFINE_NAME,
+                       "define name '%s' is not an NCName\n", name, NULL);
+        }
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL) {
+            xmlFree(name);
+            return (-1);
+        }
+        def->type = XML_RELAXNG_DEF;
+        def->name = name;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_EMPTY,
+                       "define has no children\n", NULL, NULL);
+        } else {
+            olddefine = ctxt->define;
+            ctxt->define = name;
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
+            ctxt->define = olddefine;
+        }
+        if (ctxt->grammar->defs == NULL)
+            ctxt->grammar->defs = xmlHashCreate(10);
+        if (ctxt->grammar->defs == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
+                       "Could not create definition hash\n", NULL, NULL);
+            ret = -1;
+        } else {
+            tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
+            if (tmp < 0) {
+                xmlRelaxNGDefinePtr prev;
+
+                prev = xmlHashLookup(ctxt->grammar->defs, name);
+                if (prev == NULL) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
+                               "Internal error on define aggregation of %s\n",
+                               name, NULL);
+                    ret = -1;
+                } else {
+                    while (prev->nextHash != NULL)
+                        prev = prev->nextHash;
+                    prev->nextHash = def;
+                }
+            }
+        }
+    }
+    return (ret);
+}
+
+/**
+ * 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
+ *
+ * Process and compile an externlRef node
+ *
+ * Returns the xmlRelaxNGDefinePtr or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDocumentPtr docu;
+    xmlNodePtr root, tmp;
+    xmlChar *ns;
+    int newNs = 0, oldflags;
+    xmlRelaxNGDefinePtr def;
+
+    docu = node->psvi;
+    if (docu != NULL) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_EXTERNALREF;
+
+        if (docu->content == NULL) {
+            /*
+             * Then do the parsing for good
+             */
+            root = xmlDocGetRootElement(docu->doc);
+            if (root == NULL) {
+                xmlRngPErr(ctxt, node, XML_RNGP_EXTERNALREF_EMTPY,
+                           "xmlRelaxNGParse: %s is empty\n", ctxt->URL,
+                           NULL);
+                return (NULL);
+            }
+            /*
+             * ns transmission rules
+             */
+            ns = xmlGetProp(root, BAD_CAST "ns");
+            if (ns == NULL) {
+                tmp = node;
+                while ((tmp != NULL) && (tmp->type == XML_ELEMENT_NODE)) {
+                    ns = xmlGetProp(tmp, BAD_CAST "ns");
+                    if (ns != NULL) {
+                        break;
+                    }
+                    tmp = tmp->parent;
+                }
+                if (ns != NULL) {
+                    xmlSetProp(root, BAD_CAST "ns", ns);
+                    newNs = 1;
+                    xmlFree(ns);
+                }
+            } else {
+                xmlFree(ns);
+            }
+
+            /*
+             * Parsing to get a precompiled schemas.
+             */
+            oldflags = ctxt->flags;
+            ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
+            docu->schema = xmlRelaxNGParseDocument(ctxt, root);
+            ctxt->flags = oldflags;
+            if ((docu->schema != NULL) &&
+                (docu->schema->topgrammar != NULL)) {
+                docu->content = docu->schema->topgrammar->start;
+                if (docu->schema->topgrammar->refs)
+                    xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
+            }
+
+            /*
+             * the externalRef may be reused in a different ns context
+             */
+            if (newNs == 1) {
+                xmlUnsetProp(root, BAD_CAST "ns");
+            }
+        }
+        def->content = docu->content;
+    } else {
+        def = NULL;
+    }
+    return (def);
+}
+
+/**
+ * xmlRelaxNGParsePattern:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the pattern node.
+ *
+ * parse the content of a RelaxNG pattern node.
+ *
+ * Returns the definition pointer or NULL in case of error or if no
+ *     pattern is generated.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr def = NULL;
+
+    if (node == NULL) {
+        return (NULL);
+    }
+    if (IS_RELAXNG(node, "element")) {
+        def = xmlRelaxNGParseElement(ctxt, node);
+    } else if (IS_RELAXNG(node, "attribute")) {
+        def = xmlRelaxNGParseAttribute(ctxt, node);
+    } else if (IS_RELAXNG(node, "empty")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_EMPTY;
+        if (node->children != NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_NOT_EMPTY,
+                       "empty: had a child node\n", NULL, NULL);
+        }
+    } else if (IS_RELAXNG(node, "text")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_TEXT;
+        if (node->children != NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_TEXT_HAS_CHILD,
+                       "text: had a child node\n", NULL, NULL);
+        }
+    } else if (IS_RELAXNG(node, "zeroOrMore")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_ZEROORMORE;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
+        }
+    } else if (IS_RELAXNG(node, "oneOrMore")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_ONEORMORE;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
+        }
+    } else if (IS_RELAXNG(node, "optional")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_OPTIONAL;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
+        }
+    } else if (IS_RELAXNG(node, "choice")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_CHOICE;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
+        }
+    } else if (IS_RELAXNG(node, "group")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_GROUP;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
+        }
+    } else if (IS_RELAXNG(node, "ref")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_REF;
+        def->name = xmlGetProp(node, BAD_CAST "name");
+        if (def->name == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_REF_NO_NAME, "ref has no name\n",
+                       NULL, NULL);
+        } else {
+            xmlRelaxNGNormExtSpace(def->name);
+            if (xmlValidateNCName(def->name, 0)) {
+                xmlRngPErr(ctxt, node, XML_RNGP_REF_NAME_INVALID,
+                           "ref name '%s' is not an NCName\n", def->name,
+                           NULL);
+            }
+        }
+        if (node->children != NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_REF_NOT_EMPTY, "ref is not empty\n",
+                       NULL, NULL);
+        }
+        if (ctxt->grammar->refs == NULL)
+            ctxt->grammar->refs = xmlHashCreate(10);
+        if (ctxt->grammar->refs == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
+                       "Could not create references hash\n", NULL, NULL);
+            def = NULL;
+        } else {
+            int tmp;
+
+            tmp = xmlHashAddEntry(ctxt->grammar->refs, def->name, def);
+            if (tmp < 0) {
+                xmlRelaxNGDefinePtr prev;
+
+                prev = (xmlRelaxNGDefinePtr)
+                    xmlHashLookup(ctxt->grammar->refs, def->name);
+                if (prev == NULL) {
+                    if (def->name != NULL) {
+		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
+				   "Error refs definitions '%s'\n",
+				   def->name, NULL);
+                    } else {
+		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
+				   "Error refs definitions\n",
+				   NULL, NULL);
+                    }
+                    def = NULL;
+                } else {
+                    def->nextHash = prev->nextHash;
+                    prev->nextHash = def;
+                }
+            }
+        }
+    } else if (IS_RELAXNG(node, "data")) {
+        def = xmlRelaxNGParseData(ctxt, node);
+    } else if (IS_RELAXNG(node, "value")) {
+        def = xmlRelaxNGParseValue(ctxt, node);
+    } else if (IS_RELAXNG(node, "list")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_LIST;
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
+                       "Element %s is empty\n", node->name, NULL);
+        } else {
+            def->content =
+                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
+        }
+    } else if (IS_RELAXNG(node, "interleave")) {
+        def = xmlRelaxNGParseInterleave(ctxt, node);
+    } else if (IS_RELAXNG(node, "externalRef")) {
+        def = xmlRelaxNGProcessExternalRef(ctxt, node);
+    } else if (IS_RELAXNG(node, "notAllowed")) {
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_NOT_ALLOWED;
+        if (node->children != NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_NOTALLOWED_NOT_EMPTY,
+                       "xmlRelaxNGParse: notAllowed element is not empty\n",
+                       NULL, NULL);
+        }
+    } else if (IS_RELAXNG(node, "grammar")) {
+        xmlRelaxNGGrammarPtr grammar, old;
+        xmlRelaxNGGrammarPtr oldparent;
+
+#ifdef DEBUG_GRAMMAR
+        xmlGenericError(xmlGenericErrorContext,
+                        "Found <grammar> pattern\n");
+#endif
+
+        oldparent = ctxt->parentgrammar;
+        old = ctxt->grammar;
+        ctxt->parentgrammar = old;
+        grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+        if (old != NULL) {
+            ctxt->grammar = old;
+            ctxt->parentgrammar = oldparent;
+#if 0
+            if (grammar != NULL) {
+                grammar->next = old->next;
+                old->next = grammar;
+            }
+#endif
+        }
+        if (grammar != NULL)
+            def = grammar->start;
+        else
+            def = NULL;
+    } else if (IS_RELAXNG(node, "parentRef")) {
+        if (ctxt->parentgrammar == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_PARENT,
+                       "Use of parentRef without a parent grammar\n", NULL,
+                       NULL);
+            return (NULL);
+        }
+        def = xmlRelaxNGNewDefine(ctxt, node);
+        if (def == NULL)
+            return (NULL);
+        def->type = XML_RELAXNG_PARENTREF;
+        def->name = xmlGetProp(node, BAD_CAST "name");
+        if (def->name == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_NAME,
+                       "parentRef has no name\n", NULL, NULL);
+        } else {
+            xmlRelaxNGNormExtSpace(def->name);
+            if (xmlValidateNCName(def->name, 0)) {
+                xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NAME_INVALID,
+                           "parentRef name '%s' is not an NCName\n",
+                           def->name, NULL);
+            }
+        }
+        if (node->children != NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NOT_EMPTY,
+                       "parentRef is not empty\n", NULL, NULL);
+        }
+        if (ctxt->parentgrammar->refs == NULL)
+            ctxt->parentgrammar->refs = xmlHashCreate(10);
+        if (ctxt->parentgrammar->refs == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
+                       "Could not create references hash\n", NULL, NULL);
+            def = NULL;
+        } else if (def->name != NULL) {
+            int tmp;
+
+            tmp =
+                xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
+            if (tmp < 0) {
+                xmlRelaxNGDefinePtr prev;
+
+                prev = (xmlRelaxNGDefinePtr)
+                    xmlHashLookup(ctxt->parentgrammar->refs, def->name);
+                if (prev == NULL) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
+                               "Internal error parentRef definitions '%s'\n",
+                               def->name, NULL);
+                    def = NULL;
+                } else {
+                    def->nextHash = prev->nextHash;
+                    prev->nextHash = def;
+                }
+            }
+        }
+    } else if (IS_RELAXNG(node, "mixed")) {
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT, "Mixed is empty\n",
+                       NULL, NULL);
+            def = NULL;
+        } else {
+            def = xmlRelaxNGParseInterleave(ctxt, node);
+            if (def != NULL) {
+                xmlRelaxNGDefinePtr tmp;
+
+                if ((def->content != NULL) && (def->content->next != NULL)) {
+                    tmp = xmlRelaxNGNewDefine(ctxt, node);
+                    if (tmp != NULL) {
+                        tmp->type = XML_RELAXNG_GROUP;
+                        tmp->content = def->content;
+                        def->content = tmp;
+                    }
+                }
+
+                tmp = xmlRelaxNGNewDefine(ctxt, node);
+                if (tmp == NULL)
+                    return (def);
+                tmp->type = XML_RELAXNG_TEXT;
+                tmp->next = def->content;
+                def->content = tmp;
+            }
+        }
+    } else {
+        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_CONSTRUCT,
+                   "Unexpected node %s is not a pattern\n", node->name,
+                   NULL);
+        def = NULL;
+    }
+    return (def);
+}
+
+/**
+ * xmlRelaxNGParseAttribute:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the element node
+ *
+ * parse the content of a RelaxNG attribute node.
+ *
+ * Returns the definition pointer or NULL in case of error.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr ret, cur;
+    xmlNodePtr child;
+    int old_flags;
+
+    ret = xmlRelaxNGNewDefine(ctxt, node);
+    if (ret == NULL)
+        return (NULL);
+    ret->type = XML_RELAXNG_ATTRIBUTE;
+    ret->parent = ctxt->def;
+    child = node->children;
+    if (child == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
+                   "xmlRelaxNGParseattribute: attribute has no children\n",
+                   NULL, NULL);
+        return (ret);
+    }
+    old_flags = ctxt->flags;
+    ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
+    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
+    if (cur != NULL)
+        child = child->next;
+
+    if (child != NULL) {
+        cur = xmlRelaxNGParsePattern(ctxt, child);
+        if (cur != NULL) {
+            switch (cur->type) {
+                case XML_RELAXNG_EMPTY:
+                case XML_RELAXNG_NOT_ALLOWED:
+                case XML_RELAXNG_TEXT:
+                case XML_RELAXNG_ELEMENT:
+                case XML_RELAXNG_DATATYPE:
+                case XML_RELAXNG_VALUE:
+                case XML_RELAXNG_LIST:
+                case XML_RELAXNG_REF:
+                case XML_RELAXNG_PARENTREF:
+                case XML_RELAXNG_EXTERNALREF:
+                case XML_RELAXNG_DEF:
+                case XML_RELAXNG_ONEORMORE:
+                case XML_RELAXNG_ZEROORMORE:
+                case XML_RELAXNG_OPTIONAL:
+                case XML_RELAXNG_CHOICE:
+                case XML_RELAXNG_GROUP:
+                case XML_RELAXNG_INTERLEAVE:
+                case XML_RELAXNG_ATTRIBUTE:
+                    ret->content = cur;
+                    cur->parent = ret;
+                    break;
+                case XML_RELAXNG_START:
+                case XML_RELAXNG_PARAM:
+                case XML_RELAXNG_EXCEPT:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
+                               "attribute has invalid content\n", NULL,
+                               NULL);
+                    break;
+                case XML_RELAXNG_NOOP:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
+                               "RNG Internal error, noop found in attribute\n",
+                               NULL, NULL);
+                    break;
+            }
+        }
+        child = child->next;
+    }
+    if (child != NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
+                   "attribute has multiple children\n", NULL, NULL);
+    }
+    ctxt->flags = old_flags;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseExceptNameClass:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the except node
+ * @attr:  1 if within an attribute, 0 if within an element
+ *
+ * parse the content of a RelaxNG nameClass node.
+ *
+ * Returns the definition pointer or NULL in case of error.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,
+                               xmlNodePtr node, int attr)
+{
+    xmlRelaxNGDefinePtr ret, cur, last = NULL;
+    xmlNodePtr child;
+
+    if (!IS_RELAXNG(node, "except")) {
+        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MISSING,
+                   "Expecting an except node\n", NULL, NULL);
+        return (NULL);
+    }
+    if (node->next != NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MULTIPLE,
+                   "exceptNameClass allows only a single except node\n",
+                   NULL, NULL);
+    }
+    if (node->children == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_EMPTY, "except has no content\n",
+                   NULL, NULL);
+        return (NULL);
+    }
+
+    ret = xmlRelaxNGNewDefine(ctxt, node);
+    if (ret == NULL)
+        return (NULL);
+    ret->type = XML_RELAXNG_EXCEPT;
+    child = node->children;
+    while (child != NULL) {
+        cur = xmlRelaxNGNewDefine(ctxt, child);
+        if (cur == NULL)
+            break;
+        if (attr)
+            cur->type = XML_RELAXNG_ATTRIBUTE;
+        else
+            cur->type = XML_RELAXNG_ELEMENT;
+
+        if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
+            if (last == NULL) {
+                ret->content = cur;
+            } else {
+                last->next = cur;
+            }
+            last = cur;
+        }
+        child = child->next;
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseNameClass:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the nameClass node
+ * @def:  the current definition
+ *
+ * parse the content of a RelaxNG nameClass node.
+ *
+ * Returns the definition pointer or NULL in case of error.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
+                         xmlRelaxNGDefinePtr def)
+{
+    xmlRelaxNGDefinePtr ret, tmp;
+    xmlChar *val;
+
+    ret = def;
+    if ((IS_RELAXNG(node, "name")) || (IS_RELAXNG(node, "anyName")) ||
+        (IS_RELAXNG(node, "nsName"))) {
+        if ((def->type != XML_RELAXNG_ELEMENT) &&
+            (def->type != XML_RELAXNG_ATTRIBUTE)) {
+            ret = xmlRelaxNGNewDefine(ctxt, node);
+            if (ret == NULL)
+                return (NULL);
+            ret->parent = def;
+            if (ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE)
+                ret->type = XML_RELAXNG_ATTRIBUTE;
+            else
+                ret->type = XML_RELAXNG_ELEMENT;
+        }
+    }
+    if (IS_RELAXNG(node, "name")) {
+        val = xmlNodeGetContent(node);
+        xmlRelaxNGNormExtSpace(val);
+        if (xmlValidateNCName(val, 0)) {
+	    if (node->parent != NULL)
+		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
+			   "Element %s name '%s' is not an NCName\n",
+			   node->parent->name, val);
+	    else
+		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
+			   "name '%s' is not an NCName\n",
+			   val, NULL);
+        }
+        ret->name = val;
+        val = xmlGetProp(node, BAD_CAST "ns");
+        ret->ns = val;
+        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
+            (val != NULL) &&
+            (xmlStrEqual(val, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
+	    xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
+                        "Attribute with namespace '%s' is not allowed\n",
+                        val, NULL);
+        }
+        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
+            (val != NULL) &&
+            (val[0] == 0) && (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
+	    xmlRngPErr(ctxt, node, XML_RNGP_XMLNS_NAME,
+                       "Attribute with QName 'xmlns' is not allowed\n",
+                       val, NULL);
+        }
+    } else if (IS_RELAXNG(node, "anyName")) {
+        ret->name = NULL;
+        ret->ns = NULL;
+        if (node->children != NULL) {
+            ret->nameClass =
+                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
+                                               (def->type ==
+                                                XML_RELAXNG_ATTRIBUTE));
+        }
+    } else if (IS_RELAXNG(node, "nsName")) {
+        ret->name = NULL;
+        ret->ns = xmlGetProp(node, BAD_CAST "ns");
+        if (ret->ns == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_NSNAME_NO_NS,
+                       "nsName has no ns attribute\n", NULL, NULL);
+        }
+        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
+            (ret->ns != NULL) &&
+            (xmlStrEqual
+             (ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
+            xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
+                       "Attribute with namespace '%s' is not allowed\n",
+                       ret->ns, NULL);
+        }
+        if (node->children != NULL) {
+            ret->nameClass =
+                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
+                                               (def->type ==
+                                                XML_RELAXNG_ATTRIBUTE));
+        }
+    } else if (IS_RELAXNG(node, "choice")) {
+        xmlNodePtr child;
+        xmlRelaxNGDefinePtr last = NULL;
+
+        ret = xmlRelaxNGNewDefine(ctxt, node);
+        if (ret == NULL)
+            return (NULL);
+        ret->parent = def;
+        ret->type = XML_RELAXNG_CHOICE;
+
+        if (node->children == NULL) {
+            xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY,
+                       "Element choice is empty\n", NULL, NULL);
+        } else {
+
+            child = node->children;
+            while (child != NULL) {
+                tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
+                if (tmp != NULL) {
+                    if (last == NULL) {
+                        last = ret->nameClass = tmp;
+                    } else {
+                        last->next = tmp;
+                        last = tmp;
+                    }
+                }
+                child = child->next;
+            }
+        }
+    } else {
+        xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
+                   "expecting name, anyName, nsName or choice : got %s\n",
+                   (node == NULL ? (const xmlChar *) "nothing" : node->name),
+		   NULL);
+        return (NULL);
+    }
+    if (ret != def) {
+        if (def->nameClass == NULL) {
+            def->nameClass = ret;
+        } else {
+            tmp = def->nameClass;
+            while (tmp->next != NULL) {
+                tmp = tmp->next;
+            }
+            tmp->next = ret;
+        }
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseElement:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the element node
+ *
+ * parse the content of a RelaxNG element node.
+ *
+ * Returns the definition pointer or NULL in case of error.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGDefinePtr ret, cur, last;
+    xmlNodePtr child;
+    const xmlChar *olddefine;
+
+    ret = xmlRelaxNGNewDefine(ctxt, node);
+    if (ret == NULL)
+        return (NULL);
+    ret->type = XML_RELAXNG_ELEMENT;
+    ret->parent = ctxt->def;
+    child = node->children;
+    if (child == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_EMPTY,
+                   "xmlRelaxNGParseElement: element has no children\n",
+                   NULL, NULL);
+        return (ret);
+    }
+    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
+    if (cur != NULL)
+        child = child->next;
+
+    if (child == NULL) {
+        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NO_CONTENT,
+                   "xmlRelaxNGParseElement: element has no content\n",
+                   NULL, NULL);
+        return (ret);
+    }
+    olddefine = ctxt->define;
+    ctxt->define = NULL;
+    last = NULL;
+    while (child != NULL) {
+        cur = xmlRelaxNGParsePattern(ctxt, child);
+        if (cur != NULL) {
+            cur->parent = ret;
+            switch (cur->type) {
+                case XML_RELAXNG_EMPTY:
+                case XML_RELAXNG_NOT_ALLOWED:
+                case XML_RELAXNG_TEXT:
+                case XML_RELAXNG_ELEMENT:
+                case XML_RELAXNG_DATATYPE:
+                case XML_RELAXNG_VALUE:
+                case XML_RELAXNG_LIST:
+                case XML_RELAXNG_REF:
+                case XML_RELAXNG_PARENTREF:
+                case XML_RELAXNG_EXTERNALREF:
+                case XML_RELAXNG_DEF:
+                case XML_RELAXNG_ZEROORMORE:
+                case XML_RELAXNG_ONEORMORE:
+                case XML_RELAXNG_OPTIONAL:
+                case XML_RELAXNG_CHOICE:
+                case XML_RELAXNG_GROUP:
+                case XML_RELAXNG_INTERLEAVE:
+                    if (last == NULL) {
+                        ret->content = last = cur;
+                    } else {
+                        if ((last->type == XML_RELAXNG_ELEMENT) &&
+                            (ret->content == last)) {
+                            ret->content = xmlRelaxNGNewDefine(ctxt, node);
+                            if (ret->content != NULL) {
+                                ret->content->type = XML_RELAXNG_GROUP;
+                                ret->content->content = last;
+                            } else {
+                                ret->content = last;
+                            }
+                        }
+                        last->next = cur;
+                        last = cur;
+                    }
+                    break;
+                case XML_RELAXNG_ATTRIBUTE:
+                    cur->next = ret->attrs;
+                    ret->attrs = cur;
+                    break;
+                case XML_RELAXNG_START:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
+                               "RNG Internal error, start found in element\n",
+                               NULL, NULL);
+                    break;
+                case XML_RELAXNG_PARAM:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
+                               "RNG Internal error, param found in element\n",
+                               NULL, NULL);
+                    break;
+                case XML_RELAXNG_EXCEPT:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
+                               "RNG Internal error, except found in element\n",
+                               NULL, NULL);
+                    break;
+                case XML_RELAXNG_NOOP:
+                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
+                               "RNG Internal error, noop found in element\n",
+                               NULL, NULL);
+                    break;
+            }
+        }
+        child = child->next;
+    }
+    ctxt->define = olddefine;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParsePatterns:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  list of nodes
+ * @group:  use an implicit <group> for elements
+ *
+ * parse the content of a RelaxNG start node.
+ *
+ * Returns the definition pointer or NULL in case of error.
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes,
+                        int group)
+{
+    xmlRelaxNGDefinePtr def = NULL, last = NULL, cur, parent;
+
+    parent = ctxt->def;
+    while (nodes != NULL) {
+        if (IS_RELAXNG(nodes, "element")) {
+            cur = xmlRelaxNGParseElement(ctxt, nodes);
+            if (def == NULL) {
+                def = last = cur;
+            } else {
+                if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
+                    (def == last)) {
+                    def = xmlRelaxNGNewDefine(ctxt, nodes);
+                    def->type = XML_RELAXNG_GROUP;
+                    def->content = last;
+                }
+                last->next = cur;
+                last = cur;
+            }
+            cur->parent = parent;
+        } else {
+            cur = xmlRelaxNGParsePattern(ctxt, nodes);
+            if (cur != NULL) {
+                if (def == NULL) {
+                    def = last = cur;
+                } else {
+                    last->next = cur;
+                    last = cur;
+                }
+            }
+        }
+        nodes = nodes->next;
+    }
+    return (def);
+}
+
+/**
+ * xmlRelaxNGParseStart:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  start children nodes
+ *
+ * parse the content of a RelaxNG start node.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+static int
+xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
+{
+    int ret = 0;
+    xmlRelaxNGDefinePtr def = NULL, last;
+
+    if (nodes == NULL) {
+        xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY, "start has no children\n",
+                   NULL, NULL);
+        return (-1);
+    }
+    if (IS_RELAXNG(nodes, "empty")) {
+        def = xmlRelaxNGNewDefine(ctxt, nodes);
+        if (def == NULL)
+            return (-1);
+        def->type = XML_RELAXNG_EMPTY;
+        if (nodes->children != NULL) {
+            xmlRngPErr(ctxt, nodes, XML_RNGP_EMPTY_CONTENT,
+                       "element empty is not empty\n", NULL, NULL);
+        }
+    } else if (IS_RELAXNG(nodes, "notAllowed")) {
+        def = xmlRelaxNGNewDefine(ctxt, nodes);
+        if (def == NULL)
+            return (-1);
+        def->type = XML_RELAXNG_NOT_ALLOWED;
+        if (nodes->children != NULL) {
+            xmlRngPErr(ctxt, nodes, XML_RNGP_NOTALLOWED_NOT_EMPTY,
+                       "element notAllowed is not empty\n", NULL, NULL);
+        }
+    } else {
+        def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
+    }
+    if (ctxt->grammar->start != NULL) {
+        last = ctxt->grammar->start;
+        while (last->next != NULL)
+            last = last->next;
+        last->next = def;
+    } else {
+        ctxt->grammar->start = def;
+    }
+    nodes = nodes->next;
+    if (nodes != NULL) {
+        xmlRngPErr(ctxt, nodes, XML_RNGP_START_CONTENT,
+                   "start more than one children\n", NULL, NULL);
+        return (-1);
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseGrammarContent:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  grammar children nodes
+ *
+ * parse the content of a RelaxNG grammar node.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+static int
+xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
+                              xmlNodePtr nodes)
+{
+    int ret = 0, tmp;
+
+    if (nodes == NULL) {
+        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_EMPTY,
+                   "grammar has no children\n", NULL, NULL);
+        return (-1);
+    }
+    while (nodes != NULL) {
+        if (IS_RELAXNG(nodes, "start")) {
+            if (nodes->children == NULL) {
+                xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY,
+                           "start has no children\n", NULL, NULL);
+            } else {
+                tmp = xmlRelaxNGParseStart(ctxt, nodes->children);
+                if (tmp != 0)
+                    ret = -1;
+            }
+        } else if (IS_RELAXNG(nodes, "define")) {
+            tmp = xmlRelaxNGParseDefine(ctxt, nodes);
+            if (tmp != 0)
+                ret = -1;
+        } else if (IS_RELAXNG(nodes, "include")) {
+            tmp = xmlRelaxNGParseInclude(ctxt, nodes);
+            if (tmp != 0)
+                ret = -1;
+        } else {
+            xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
+                       "grammar has unexpected child %s\n", nodes->name,
+                       NULL);
+            ret = -1;
+        }
+        nodes = nodes->next;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGCheckReference:
+ * @ref:  the ref
+ * @ctxt:  a Relax-NG parser context
+ * @name:  the name associated to the defines
+ *
+ * Applies the 4.17. combine attribute rule for all the define
+ * element of a given grammar using the same name.
+ */
+static void
+xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref,
+                         xmlRelaxNGParserCtxtPtr ctxt,
+                         const xmlChar * name)
+{
+    xmlRelaxNGGrammarPtr grammar;
+    xmlRelaxNGDefinePtr def, cur;
+
+    /*
+     * 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,
+                   "Internal error: no grammar in CheckReference %s\n",
+                   name, NULL);
+        return;
+    }
+    if (ref->content != NULL) {
+        xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
+                   "Internal error: reference has content in CheckReference %s\n",
+                   name, NULL);
+        return;
+    }
+    if (grammar->defs != NULL) {
+        def = xmlHashLookup(grammar->defs, name);
+        if (def != NULL) {
+            cur = ref;
+            while (cur != NULL) {
+                cur->content = def;
+                cur = cur->nextHash;
+            }
+        } else {
+            xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
+                       "Reference %s has no matching definition\n", name,
+                       NULL);
+        }
+    } else {
+        xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
+                   "Reference %s has no matching definition\n", name,
+                   NULL);
+    }
+}
+
+/**
+ * xmlRelaxNGCheckCombine:
+ * @define:  the define(s) list
+ * @ctxt:  a Relax-NG parser context
+ * @name:  the name associated to the defines
+ *
+ * Applies the 4.17. combine attribute rule for all the define
+ * element of a given grammar using the same name.
+ */
+static void
+xmlRelaxNGCheckCombine(xmlRelaxNGDefinePtr define,
+                       xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * name)
+{
+    xmlChar *combine;
+    int choiceOrInterleave = -1;
+    int missing = 0;
+    xmlRelaxNGDefinePtr cur, last, tmp, tmp2;
+
+    if (define->nextHash == NULL)
+        return;
+    cur = define;
+    while (cur != NULL) {
+        combine = xmlGetProp(cur->node, BAD_CAST "combine");
+        if (combine != NULL) {
+            if (xmlStrEqual(combine, BAD_CAST "choice")) {
+                if (choiceOrInterleave == -1)
+                    choiceOrInterleave = 1;
+                else if (choiceOrInterleave == 0) {
+                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
+                               "Defines for %s use both 'choice' and 'interleave'\n",
+                               name, NULL);
+                }
+            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
+                if (choiceOrInterleave == -1)
+                    choiceOrInterleave = 0;
+                else if (choiceOrInterleave == 1) {
+                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
+                               "Defines for %s use both 'choice' and 'interleave'\n",
+                               name, NULL);
+                }
+            } else {
+                xmlRngPErr(ctxt, define->node, XML_RNGP_UNKNOWN_COMBINE,
+                           "Defines for %s use unknown combine value '%s''\n",
+                           name, combine);
+            }
+            xmlFree(combine);
+        } else {
+            if (missing == 0)
+                missing = 1;
+            else {
+                xmlRngPErr(ctxt, define->node, XML_RNGP_NEED_COMBINE,
+                           "Some defines for %s needs the combine attribute\n",
+                           name, NULL);
+            }
+        }
+
+        cur = cur->nextHash;
+    }
+#ifdef DEBUG
+    xmlGenericError(xmlGenericErrorContext,
+                    "xmlRelaxNGCheckCombine(): merging %s defines: %d\n",
+                    name, choiceOrInterleave);
+#endif
+    if (choiceOrInterleave == -1)
+        choiceOrInterleave = 0;
+    cur = xmlRelaxNGNewDefine(ctxt, define->node);
+    if (cur == NULL)
+        return;
+    if (choiceOrInterleave == 0)
+        cur->type = XML_RELAXNG_INTERLEAVE;
+    else
+        cur->type = XML_RELAXNG_CHOICE;
+    tmp = define;
+    last = NULL;
+    while (tmp != NULL) {
+        if (tmp->content != NULL) {
+            if (tmp->content->next != NULL) {
+                /*
+                 * we need first to create a wrapper.
+                 */
+                tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
+                if (tmp2 == NULL)
+                    break;
+                tmp2->type = XML_RELAXNG_GROUP;
+                tmp2->content = tmp->content;
+            } else {
+                tmp2 = tmp->content;
+            }
+            if (last == NULL) {
+                cur->content = tmp2;
+            } else {
+                last->next = tmp2;
+            }
+            last = tmp2;
+        }
+        tmp->content = cur;
+        tmp = tmp->nextHash;
+    }
+    define->content = cur;
+    if (choiceOrInterleave == 0) {
+        if (ctxt->interleaves == NULL)
+            ctxt->interleaves = xmlHashCreate(10);
+        if (ctxt->interleaves == NULL) {
+            xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
+                       "Failed to create interleaves hash table\n", NULL,
+                       NULL);
+        } else {
+            char tmpname[32];
+
+            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
+            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
+                0) {
+                xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
+                           "Failed to add %s to hash table\n",
+			   (const xmlChar *) tmpname, NULL);
+            }
+        }
+    }
+}
+
+/**
+ * xmlRelaxNGCombineStart:
+ * @ctxt:  a Relax-NG parser context
+ * @grammar:  the grammar
+ *
+ * Applies the 4.17. combine rule for all the start
+ * element of a given grammar.
+ */
+static void
+xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
+                       xmlRelaxNGGrammarPtr grammar)
+{
+    xmlRelaxNGDefinePtr starts;
+    xmlChar *combine;
+    int choiceOrInterleave = -1;
+    int missing = 0;
+    xmlRelaxNGDefinePtr cur;
+
+    starts = grammar->start;
+    if ((starts == NULL) || (starts->next == NULL))
+        return;
+    cur = starts;
+    while (cur != NULL) {
+        if ((cur->node == NULL) || (cur->node->parent == NULL) ||
+            (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
+            combine = NULL;
+            xmlRngPErr(ctxt, cur->node, XML_RNGP_START_MISSING,
+                       "Internal error: start element not found\n", NULL,
+                       NULL);
+        } else {
+            combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
+        }
+
+        if (combine != NULL) {
+            if (xmlStrEqual(combine, BAD_CAST "choice")) {
+                if (choiceOrInterleave == -1)
+                    choiceOrInterleave = 1;
+                else if (choiceOrInterleave == 0) {
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
+                               "<start> use both 'choice' and 'interleave'\n",
+                               NULL, NULL);
+                }
+            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
+                if (choiceOrInterleave == -1)
+                    choiceOrInterleave = 0;
+                else if (choiceOrInterleave == 1) {
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
+                               "<start> use both 'choice' and 'interleave'\n",
+                               NULL, NULL);
+                }
+            } else {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_UNKNOWN_COMBINE,
+                           "<start> uses unknown combine value '%s''\n",
+                           combine, NULL);
+            }
+            xmlFree(combine);
+        } else {
+            if (missing == 0)
+                missing = 1;
+            else {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_NEED_COMBINE,
+                           "Some <start> element miss the combine attribute\n",
+                           NULL, NULL);
+            }
+        }
+
+        cur = cur->next;
+    }
+#ifdef DEBUG
+    xmlGenericError(xmlGenericErrorContext,
+                    "xmlRelaxNGCombineStart(): merging <start>: %d\n",
+                    choiceOrInterleave);
+#endif
+    if (choiceOrInterleave == -1)
+        choiceOrInterleave = 0;
+    cur = xmlRelaxNGNewDefine(ctxt, starts->node);
+    if (cur == NULL)
+        return;
+    if (choiceOrInterleave == 0)
+        cur->type = XML_RELAXNG_INTERLEAVE;
+    else
+        cur->type = XML_RELAXNG_CHOICE;
+    cur->content = grammar->start;
+    grammar->start = cur;
+    if (choiceOrInterleave == 0) {
+        if (ctxt->interleaves == NULL)
+            ctxt->interleaves = xmlHashCreate(10);
+        if (ctxt->interleaves == NULL) {
+            xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
+                       "Failed to create interleaves hash table\n", NULL,
+                       NULL);
+        } else {
+            char tmpname[32];
+
+            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
+            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
+                0) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
+                           "Failed to add %s to hash table\n",
+			   (const xmlChar *) tmpname, NULL);
+            }
+        }
+    }
+}
+
+/**
+ * xmlRelaxNGCheckCycles:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  grammar children nodes
+ * @depth:  the counter
+ *
+ * Check for cycles.
+ *
+ * Returns 0 if check passed, and -1 in case of error
+ */
+static int
+xmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,
+                      xmlRelaxNGDefinePtr cur, int depth)
+{
+    int ret = 0;
+
+    while ((ret == 0) && (cur != NULL)) {
+        if ((cur->type == XML_RELAXNG_REF) ||
+            (cur->type == XML_RELAXNG_PARENTREF)) {
+            if (cur->depth == -1) {
+                cur->depth = depth;
+                ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
+                cur->depth = -2;
+            } else if (depth == cur->depth) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_CYCLE,
+                           "Detected a cycle in %s references\n",
+                           cur->name, NULL);
+                return (-1);
+            }
+        } else if (cur->type == XML_RELAXNG_ELEMENT) {
+            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
+        } else {
+            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
+        }
+        cur = cur->next;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGTryUnlink:
+ * @ctxt:  a Relax-NG parser context
+ * @cur:  the definition to unlink
+ * @parent:  the parent definition
+ * @prev:  the previous sibling definition
+ *
+ * Try to unlink a definition. If not possble make it a NOOP
+ *
+ * Returns the new prev definition
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                    xmlRelaxNGDefinePtr cur,
+                    xmlRelaxNGDefinePtr parent, xmlRelaxNGDefinePtr prev)
+{
+    if (prev != NULL) {
+        prev->next = cur->next;
+    } else {
+        if (parent != NULL) {
+            if (parent->content == cur)
+                parent->content = cur->next;
+            else if (parent->attrs == cur)
+                parent->attrs = cur->next;
+            else if (parent->nameClass == cur)
+                parent->nameClass = cur->next;
+        } else {
+            cur->type = XML_RELAXNG_NOOP;
+            prev = cur;
+        }
+    }
+    return (prev);
+}
+
+/**
+ * xmlRelaxNGSimplify:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  grammar children nodes
+ *
+ * Check for simplification of empty and notAllowed
+ */
+static void
+xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
+                   xmlRelaxNGDefinePtr cur, xmlRelaxNGDefinePtr parent)
+{
+    xmlRelaxNGDefinePtr prev = NULL;
+
+    while (cur != NULL) {
+        if ((cur->type == XML_RELAXNG_REF) ||
+            (cur->type == XML_RELAXNG_PARENTREF)) {
+            if (cur->depth != -3) {
+                cur->depth = -3;
+                xmlRelaxNGSimplify(ctxt, cur->content, cur);
+            }
+        } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
+            cur->parent = parent;
+            if ((parent != NULL) &&
+                ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
+                 (parent->type == XML_RELAXNG_LIST) ||
+                 (parent->type == XML_RELAXNG_GROUP) ||
+                 (parent->type == XML_RELAXNG_INTERLEAVE) ||
+                 (parent->type == XML_RELAXNG_ONEORMORE) ||
+                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
+                parent->type = XML_RELAXNG_NOT_ALLOWED;
+                break;
+            }
+            if ((parent != NULL) && (parent->type == XML_RELAXNG_CHOICE)) {
+                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
+            } else
+                prev = cur;
+        } else if (cur->type == XML_RELAXNG_EMPTY) {
+            cur->parent = parent;
+            if ((parent != NULL) &&
+                ((parent->type == XML_RELAXNG_ONEORMORE) ||
+                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
+                parent->type = XML_RELAXNG_EMPTY;
+                break;
+            }
+            if ((parent != NULL) &&
+                ((parent->type == XML_RELAXNG_GROUP) ||
+                 (parent->type == XML_RELAXNG_INTERLEAVE))) {
+                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
+            } else
+                prev = cur;
+        } else {
+            cur->parent = parent;
+            if (cur->content != NULL)
+                xmlRelaxNGSimplify(ctxt, cur->content, cur);
+            if ((cur->type != XML_RELAXNG_VALUE) && (cur->attrs != NULL))
+                xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
+            if (cur->nameClass != NULL)
+                xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
+            /*
+             * On Elements, try to move attribute only generating rules on
+             * the attrs rules.
+             */
+            if (cur->type == XML_RELAXNG_ELEMENT) {
+                int attronly;
+                xmlRelaxNGDefinePtr tmp, pre;
+
+                while (cur->content != NULL) {
+                    attronly =
+                        xmlRelaxNGGenerateAttributes(ctxt, cur->content);
+                    if (attronly == 1) {
+                        /*
+                         * migrate cur->content to attrs
+                         */
+                        tmp = cur->content;
+                        cur->content = tmp->next;
+                        tmp->next = cur->attrs;
+                        cur->attrs = tmp;
+                    } else {
+                        /*
+                         * cur->content can generate elements or text
+                         */
+                        break;
+                    }
+                }
+                pre = cur->content;
+                while ((pre != NULL) && (pre->next != NULL)) {
+                    tmp = pre->next;
+                    attronly = xmlRelaxNGGenerateAttributes(ctxt, tmp);
+                    if (attronly == 1) {
+                        /*
+                         * migrate tmp to attrs
+                         */
+                        pre->next = tmp->next;
+                        tmp->next = cur->attrs;
+                        cur->attrs = tmp;
+                    } else {
+                        pre = tmp;
+                    }
+                }
+            }
+            /*
+             * This may result in a simplification
+             */
+            if ((cur->type == XML_RELAXNG_GROUP) ||
+                (cur->type == XML_RELAXNG_INTERLEAVE)) {
+                if (cur->content == NULL)
+                    cur->type = XML_RELAXNG_EMPTY;
+                else if (cur->content->next == NULL) {
+                    if ((parent == NULL) && (prev == NULL)) {
+                        cur->type = XML_RELAXNG_NOOP;
+                    } else if (prev == NULL) {
+                        parent->content = cur->content;
+                        cur->content->next = cur->next;
+                        cur = cur->content;
+                    } else {
+                        cur->content->next = cur->next;
+                        prev->next = cur->content;
+                        cur = cur->content;
+                    }
+                }
+            }
+            /*
+             * the current node may have been transformed back
+             */
+            if ((cur->type == XML_RELAXNG_EXCEPT) &&
+                (cur->content != NULL) &&
+                (cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
+                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
+            } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
+                if ((parent != NULL) &&
+                    ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
+                     (parent->type == XML_RELAXNG_LIST) ||
+                     (parent->type == XML_RELAXNG_GROUP) ||
+                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
+                     (parent->type == XML_RELAXNG_ONEORMORE) ||
+                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
+                    parent->type = XML_RELAXNG_NOT_ALLOWED;
+                    break;
+                }
+                if ((parent != NULL) &&
+                    (parent->type == XML_RELAXNG_CHOICE)) {
+                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
+                } else
+                    prev = cur;
+            } else if (cur->type == XML_RELAXNG_EMPTY) {
+                if ((parent != NULL) &&
+                    ((parent->type == XML_RELAXNG_ONEORMORE) ||
+                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
+                    parent->type = XML_RELAXNG_EMPTY;
+                    break;
+                }
+                if ((parent != NULL) &&
+                    ((parent->type == XML_RELAXNG_GROUP) ||
+                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
+                     (parent->type == XML_RELAXNG_CHOICE))) {
+                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
+                } else
+                    prev = cur;
+            } else {
+                prev = cur;
+            }
+        }
+        cur = cur->next;
+    }
+}
+
+/**
+ * xmlRelaxNGGroupContentType:
+ * @ct1:  the first content type
+ * @ct2:  the second content type
+ *
+ * Try to group 2 content types
+ *
+ * Returns the content type
+ */
+static xmlRelaxNGContentType
+xmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,
+                           xmlRelaxNGContentType ct2)
+{
+    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
+        (ct2 == XML_RELAXNG_CONTENT_ERROR))
+        return (XML_RELAXNG_CONTENT_ERROR);
+    if (ct1 == XML_RELAXNG_CONTENT_EMPTY)
+        return (ct2);
+    if (ct2 == XML_RELAXNG_CONTENT_EMPTY)
+        return (ct1);
+    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) &&
+        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
+        return (XML_RELAXNG_CONTENT_COMPLEX);
+    return (XML_RELAXNG_CONTENT_ERROR);
+}
+
+/**
+ * xmlRelaxNGMaxContentType:
+ * @ct1:  the first content type
+ * @ct2:  the second content type
+ *
+ * Compute the max content-type
+ *
+ * Returns the content type
+ */
+static xmlRelaxNGContentType
+xmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,
+                         xmlRelaxNGContentType ct2)
+{
+    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
+        (ct2 == XML_RELAXNG_CONTENT_ERROR))
+        return (XML_RELAXNG_CONTENT_ERROR);
+    if ((ct1 == XML_RELAXNG_CONTENT_SIMPLE) ||
+        (ct2 == XML_RELAXNG_CONTENT_SIMPLE))
+        return (XML_RELAXNG_CONTENT_SIMPLE);
+    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) ||
+        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
+        return (XML_RELAXNG_CONTENT_COMPLEX);
+    return (XML_RELAXNG_CONTENT_EMPTY);
+}
+
+/**
+ * xmlRelaxNGCheckRules:
+ * @ctxt:  a Relax-NG parser context
+ * @cur:  the current definition
+ * @flags:  some accumulated flags
+ * @ptype:  the parent type
+ *
+ * Check for rules in section 7.1 and 7.2
+ *
+ * Returns the content type of @cur
+ */
+static xmlRelaxNGContentType
+xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
+                     xmlRelaxNGDefinePtr cur, int flags,
+                     xmlRelaxNGType ptype)
+{
+    int nflags;
+    xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
+
+    while (cur != NULL) {
+        ret = XML_RELAXNG_CONTENT_EMPTY;
+        if ((cur->type == XML_RELAXNG_REF) ||
+            (cur->type == XML_RELAXNG_PARENTREF)) {
+           /*
+            * This should actually be caught by list//element(ref) at the
+            * element boundaries, c.f. Bug #159968 local refs are dropped
+            * in step 4.19.
+            */
+#if 0
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF,
+                           "Found forbidden pattern list//ref\n", NULL,
+                           NULL);
+            }
+#endif
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF,
+                           "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,
+                                           flags, cur->type);
+                cur->depth = ret - 15;
+            } else if (cur->depth == -4) {
+                ret = XML_RELAXNG_CONTENT_COMPLEX;
+            } else {
+                ret = (xmlRelaxNGContentType) (cur->depth + 15);
+            }
+        } else if (cur->type == XML_RELAXNG_ELEMENT) {
+            /*
+             * The 7.3 Attribute derivation rule for groups is plugged there
+             */
+            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ELEM,
+                           "Found forbidden pattern data/except//element(ref)\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ELEM,
+                           "Found forbidden pattern list//element(ref)\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
+                           "Found forbidden pattern attribute//element(ref)\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
+                           "Found forbidden pattern attribute//element(ref)\n",
+                           NULL, NULL);
+            }
+            /*
+             * reset since in the simple form elements are only child
+             * of grammar/define
+             */
+            nflags = 0;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags, cur->type);
+            if (ret != XML_RELAXNG_CONTENT_EMPTY) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_EMPTY,
+                           "Element %s attributes have a content type error\n",
+                           cur->name, NULL);
+            }
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+            if (ret == XML_RELAXNG_CONTENT_ERROR) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_ERROR,
+                           "Element %s has a content type error\n",
+                           cur->name, NULL);
+            } else {
+                ret = XML_RELAXNG_CONTENT_COMPLEX;
+            }
+        } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
+            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ATTR,
+                           "Found forbidden pattern attribute//attribute\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ATTR,
+                           "Found forbidden pattern list//attribute\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_OOMGROUP) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_GROUP_ATTR,
+                           "Found forbidden pattern oneOrMore//group//attribute\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR,
+                           "Found forbidden pattern oneOrMore//interleave//attribute\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ATTR,
+                           "Found forbidden pattern data/except//attribute\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ATTR,
+                           "Found forbidden pattern start//attribute\n",
+                           NULL, NULL);
+            }
+            if ((!(flags & XML_RELAXNG_IN_ONEORMORE))
+                && (cur->name == NULL)) {
+                if (cur->ns == NULL) {
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_ANYNAME_ATTR_ANCESTOR,
+                               "Found anyName attribute without oneOrMore ancestor\n",
+                               NULL, NULL);
+                } else {
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_NSNAME_ATTR_ANCESTOR,
+                               "Found nsName attribute without oneOrMore ancestor\n",
+                               NULL, NULL);
+                }
+            }
+            nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
+            xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
+            ret = XML_RELAXNG_CONTENT_EMPTY;
+        } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
+                   (cur->type == XML_RELAXNG_ZEROORMORE)) {
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ONEMORE,
+                           "Found forbidden pattern data/except//oneOrMore\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ONEMORE,
+                           "Found forbidden pattern start//oneOrMore\n",
+                           NULL, NULL);
+            }
+            nflags = flags | XML_RELAXNG_IN_ONEORMORE;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+            ret = xmlRelaxNGGroupContentType(ret, ret);
+        } else if (cur->type == XML_RELAXNG_LIST) {
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_LIST,
+                           "Found forbidden pattern list//list\n", NULL,
+                           NULL);
+            }
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_LIST,
+                           "Found forbidden pattern data/except//list\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_LIST,
+                           "Found forbidden pattern start//list\n", NULL,
+                           NULL);
+            }
+            nflags = flags | XML_RELAXNG_IN_LIST;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+        } else if (cur->type == XML_RELAXNG_GROUP) {
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_GROUP,
+                           "Found forbidden pattern data/except//group\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_GROUP,
+                           "Found forbidden pattern start//group\n", NULL,
+                           NULL);
+            }
+            if (flags & XML_RELAXNG_IN_ONEORMORE)
+                nflags = flags | XML_RELAXNG_IN_OOMGROUP;
+            else
+                nflags = flags;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+            /*
+             * The 7.3 Attribute derivation rule for groups is plugged there
+             */
+            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
+        } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_INTERLEAVE,
+                           "Found forbidden pattern list//interleave\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
+                           "Found forbidden pattern data/except//interleave\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
+                           "Found forbidden pattern start//interleave\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_ONEORMORE)
+                nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
+            else
+                nflags = flags;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+        } else if (cur->type == XML_RELAXNG_EXCEPT) {
+            if ((cur->parent != NULL) &&
+                (cur->parent->type == XML_RELAXNG_DATATYPE))
+                nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
+            else
+                nflags = flags;
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
+                                     cur->type);
+        } else if (cur->type == XML_RELAXNG_DATATYPE) {
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_DATA,
+                           "Found forbidden pattern start//data\n", NULL,
+                           NULL);
+            }
+            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
+            ret = XML_RELAXNG_CONTENT_SIMPLE;
+        } else if (cur->type == XML_RELAXNG_VALUE) {
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_VALUE,
+                           "Found forbidden pattern start//value\n", NULL,
+                           NULL);
+            }
+            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
+            ret = XML_RELAXNG_CONTENT_SIMPLE;
+        } else if (cur->type == XML_RELAXNG_TEXT) {
+            if (flags & XML_RELAXNG_IN_LIST) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_TEXT,
+                           "Found forbidden pattern list//text\n", NULL,
+                           NULL);
+            }
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_TEXT,
+                           "Found forbidden pattern data/except//text\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_TEXT,
+                           "Found forbidden pattern start//text\n", NULL,
+                           NULL);
+            }
+            ret = XML_RELAXNG_CONTENT_COMPLEX;
+        } else if (cur->type == XML_RELAXNG_EMPTY) {
+            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_EMPTY,
+                           "Found forbidden pattern data/except//empty\n",
+                           NULL, NULL);
+            }
+            if (flags & XML_RELAXNG_IN_START) {
+                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_EMPTY,
+                           "Found forbidden pattern start//empty\n", NULL,
+                           NULL);
+            }
+            ret = XML_RELAXNG_CONTENT_EMPTY;
+        } else if (cur->type == XML_RELAXNG_CHOICE) {
+            xmlRelaxNGCheckChoiceDeterminism(ctxt, cur);
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
+        } else {
+            ret =
+                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
+        }
+        cur = cur->next;
+        if (ptype == XML_RELAXNG_GROUP) {
+            val = xmlRelaxNGGroupContentType(val, ret);
+        } else if (ptype == XML_RELAXNG_INTERLEAVE) {
+            /*
+             * 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);
+        } else if (ptype == XML_RELAXNG_CHOICE) {
+            val = xmlRelaxNGMaxContentType(val, ret);
+        } else if (ptype == XML_RELAXNG_LIST) {
+            val = XML_RELAXNG_CONTENT_SIMPLE;
+        } else if (ptype == XML_RELAXNG_EXCEPT) {
+            if (ret == XML_RELAXNG_CONTENT_ERROR)
+                val = XML_RELAXNG_CONTENT_ERROR;
+            else
+                val = XML_RELAXNG_CONTENT_SIMPLE;
+        } else {
+            val = xmlRelaxNGGroupContentType(val, ret);
+        }
+
+    }
+    return (val);
+}
+
+/**
+ * xmlRelaxNGParseGrammar:
+ * @ctxt:  a Relax-NG parser context
+ * @nodes:  grammar children nodes
+ *
+ * parse a Relax-NG <grammar> node
+ *
+ * Returns the internal xmlRelaxNGGrammarPtr built or
+ *         NULL in case of error
+ */
+static xmlRelaxNGGrammarPtr
+xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
+{
+    xmlRelaxNGGrammarPtr ret, tmp, old;
+
+#ifdef DEBUG_GRAMMAR
+    xmlGenericError(xmlGenericErrorContext, "Parsing a new grammar\n");
+#endif
+
+    ret = xmlRelaxNGNewGrammar(ctxt);
+    if (ret == NULL)
+        return (NULL);
+
+    /*
+     * Link the new grammar in the tree
+     */
+    ret->parent = ctxt->grammar;
+    if (ctxt->grammar != NULL) {
+        tmp = ctxt->grammar->children;
+        if (tmp == NULL) {
+            ctxt->grammar->children = ret;
+        } else {
+            while (tmp->next != NULL)
+                tmp = tmp->next;
+            tmp->next = ret;
+        }
+    }
+
+    old = ctxt->grammar;
+    ctxt->grammar = ret;
+    xmlRelaxNGParseGrammarContent(ctxt, nodes);
+    ctxt->grammar = ret;
+    if (ctxt->grammar == NULL) {
+        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
+                   "Failed to parse <grammar> content\n", NULL, NULL);
+    } else if (ctxt->grammar->start == NULL) {
+        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_NO_START,
+                   "Element <grammar> has no <start>\n", NULL, NULL);
+    }
+
+    /*
+     * Apply 4.17 mergingd rules to defines and starts
+     */
+    xmlRelaxNGCombineStart(ctxt, ret);
+    if (ret->defs != NULL) {
+        xmlHashScan(ret->defs, (xmlHashScanner) xmlRelaxNGCheckCombine,
+                    ctxt);
+    }
+
+    /*
+     * link together defines and refs in this grammar
+     */
+    if (ret->refs != NULL) {
+        xmlHashScan(ret->refs, (xmlHashScanner) xmlRelaxNGCheckReference,
+                    ctxt);
+    }
+
+
+    /* @@@@ */
+
+    ctxt->grammar = old;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGParseDocument:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  the root node of the RelaxNG schema
+ *
+ * parse a Relax-NG definition resource and build an internal
+ * xmlRelaxNG struture which can be used to validate instances.
+ *
+ * Returns the internal XML RelaxNG structure built or
+ *         NULL in case of error
+ */
+static xmlRelaxNGPtr
+xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlRelaxNGPtr schema = NULL;
+    const xmlChar *olddefine;
+    xmlRelaxNGGrammarPtr old;
+
+    if ((ctxt == NULL) || (node == NULL))
+        return (NULL);
+
+    schema = xmlRelaxNGNewRelaxNG(ctxt);
+    if (schema == NULL)
+        return (NULL);
+
+    olddefine = ctxt->define;
+    ctxt->define = NULL;
+    if (IS_RELAXNG(node, "grammar")) {
+        schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+    } else {
+        xmlRelaxNGGrammarPtr tmp, ret;
+
+        schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
+        if (schema->topgrammar == NULL) {
+            return (schema);
+        }
+        /*
+         * Link the new grammar in the tree
+         */
+        ret->parent = ctxt->grammar;
+        if (ctxt->grammar != NULL) {
+            tmp = ctxt->grammar->children;
+            if (tmp == NULL) {
+                ctxt->grammar->children = ret;
+            } else {
+                while (tmp->next != NULL)
+                    tmp = tmp->next;
+                tmp->next = ret;
+            }
+        }
+        old = ctxt->grammar;
+        ctxt->grammar = ret;
+        xmlRelaxNGParseStart(ctxt, node);
+        if (old != NULL)
+            ctxt->grammar = old;
+    }
+    ctxt->define = olddefine;
+    if (schema->topgrammar->start != NULL) {
+        xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
+        if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
+            xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
+            while ((schema->topgrammar->start != NULL) &&
+                   (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
+                   (schema->topgrammar->start->next != NULL))
+                schema->topgrammar->start =
+                    schema->topgrammar->start->content;
+            xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
+                                 XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
+        }
+    }
+#ifdef DEBUG
+    if (schema == NULL)
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlRelaxNGParseDocument() failed\n");
+#endif
+
+    return (schema);
+}
+
+/************************************************************************
+ * 									*
+ * 			Reading RelaxNGs				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlRelaxNGNewParserCtxt:
+ * @URL:  the location of the schema
+ *
+ * Create an XML RelaxNGs parse context for that file/resource expected
+ * to contain an XML RelaxNGs file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlRelaxNGParserCtxtPtr
+xmlRelaxNGNewParserCtxt(const char *URL)
+{
+    xmlRelaxNGParserCtxtPtr ret;
+
+    if (URL == NULL)
+        return (NULL);
+
+    ret =
+        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
+    if (ret == NULL) {
+        xmlRngPErrMemory(NULL, "building parser\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
+    ret->URL = xmlStrdup((const xmlChar *) URL);
+    ret->error = xmlGenericError;
+    ret->userData = xmlGenericErrorContext;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGNewMemParserCtxt:
+ * @buffer:  a pointer to a char array containing the schemas
+ * @size:  the size of the array
+ *
+ * Create an XML RelaxNGs parse context for that memory buffer expected
+ * to contain an XML RelaxNGs file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlRelaxNGParserCtxtPtr
+xmlRelaxNGNewMemParserCtxt(const char *buffer, int size)
+{
+    xmlRelaxNGParserCtxtPtr ret;
+
+    if ((buffer == NULL) || (size <= 0))
+        return (NULL);
+
+    ret =
+        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
+    if (ret == NULL) {
+        xmlRngPErrMemory(NULL, "building parser\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
+    ret->buffer = buffer;
+    ret->size = size;
+    ret->error = xmlGenericError;
+    ret->userData = xmlGenericErrorContext;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGNewDocParserCtxt:
+ * @doc:  a preparsed document tree
+ *
+ * Create an XML RelaxNGs parser context for that document.
+ * Note: since the process of compiling a RelaxNG schemas modifies the
+ *       document, the @doc parameter is duplicated internally.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlRelaxNGParserCtxtPtr
+xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
+{
+    xmlRelaxNGParserCtxtPtr ret;
+    xmlDocPtr copy;
+
+    if (doc == NULL)
+        return (NULL);
+    copy = xmlCopyDoc(doc, 1);
+    if (copy == NULL)
+        return (NULL);
+
+    ret =
+        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
+    if (ret == NULL) {
+        xmlRngPErrMemory(NULL, "building parser\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
+    ret->document = copy;
+    ret->freedoc = 1;
+    ret->userData = xmlGenericErrorContext;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGFreeParserCtxt:
+ * @ctxt:  the schema parser context
+ *
+ * Free the resources associated to the schema parser context
+ */
+void
+xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->URL != NULL)
+        xmlFree(ctxt->URL);
+    if (ctxt->doc != NULL)
+        xmlRelaxNGFreeDocument(ctxt->doc);
+    if (ctxt->interleaves != NULL)
+        xmlHashFree(ctxt->interleaves, NULL);
+    if (ctxt->documents != NULL)
+        xmlRelaxNGFreeDocumentList(ctxt->documents);
+    if (ctxt->includes != NULL)
+        xmlRelaxNGFreeIncludeList(ctxt->includes);
+    if (ctxt->docTab != NULL)
+        xmlFree(ctxt->docTab);
+    if (ctxt->incTab != NULL)
+        xmlFree(ctxt->incTab);
+    if (ctxt->defTab != NULL) {
+        int i;
+
+        for (i = 0; i < ctxt->defNr; i++)
+            xmlRelaxNGFreeDefine(ctxt->defTab[i]);
+        xmlFree(ctxt->defTab);
+    }
+    if ((ctxt->document != NULL) && (ctxt->freedoc))
+        xmlFreeDoc(ctxt->document);
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlRelaxNGNormExtSpace:
+ * @value:  a value
+ *
+ * Removes the leading and ending spaces of the value
+ * The string is modified "in situ"
+ */
+static void
+xmlRelaxNGNormExtSpace(xmlChar * value)
+{
+    xmlChar *start = value;
+    xmlChar *cur = value;
+
+    if (value == NULL)
+        return;
+
+    while (IS_BLANK_CH(*cur))
+        cur++;
+    if (cur == start) {
+        do {
+            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
+                cur++;
+            if (*cur == 0)
+                return;
+            start = cur;
+            while (IS_BLANK_CH(*cur))
+                cur++;
+            if (*cur == 0) {
+                *start = 0;
+                return;
+            }
+        } while (1);
+    } else {
+        do {
+            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
+                *start++ = *cur++;
+            if (*cur == 0) {
+                *start = 0;
+                return;
+            }
+            /* don't try to normalize the inner spaces */
+            while (IS_BLANK_CH(*cur))
+                cur++;
+            if (*cur == 0) {
+                *start = 0;
+                return;
+            }
+            *start++ = *cur++;
+        } while (1);
+    }
+}
+
+/**
+ * xmlRelaxNGCleanupAttributes:
+ * @ctxt:  a Relax-NG parser context
+ * @node:  a Relax-NG node
+ *
+ * Check all the attributes on the given node
+ */
+static void
+xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlAttrPtr cur, next;
+
+    cur = node->properties;
+    while (cur != NULL) {
+        next = cur->next;
+        if ((cur->ns == NULL) ||
+            (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
+            if (xmlStrEqual(cur->name, BAD_CAST "name")) {
+                if ((!xmlStrEqual(node->name, BAD_CAST "element")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "ref")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "param")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
+                               "Attribute %s is not allowed on %s\n",
+                               cur->name, node->name);
+                }
+            } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
+                if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "data"))) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
+                               "Attribute %s is not allowed on %s\n",
+                               cur->name, node->name);
+                }
+            } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
+                if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "include"))) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
+                               "Attribute %s is not allowed on %s\n",
+                               cur->name, node->name);
+                }
+            } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
+                if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
+                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
+                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
+                               "Attribute %s is not allowed on %s\n",
+                               cur->name, node->name);
+                }
+            } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) {
+                xmlChar *val;
+                xmlURIPtr uri;
+
+                val = xmlNodeListGetString(node->doc, cur->children, 1);
+                if (val != NULL) {
+                    if (val[0] != 0) {
+                        uri = xmlParseURI((const char *) val);
+                        if (uri == NULL) {
+                            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_URI,
+                                       "Attribute %s contains invalid URI %s\n",
+                                       cur->name, val);
+                        } else {
+                            if (uri->scheme == NULL) {
+                                xmlRngPErr(ctxt, node, XML_RNGP_URI_NOT_ABSOLUTE,
+                                           "Attribute %s URI %s is not absolute\n",
+                                           cur->name, val);
+                            }
+                            if (uri->fragment != NULL) {
+                                xmlRngPErr(ctxt, node, XML_RNGP_URI_FRAGMENT,
+                                           "Attribute %s URI %s has a fragment ID\n",
+                                           cur->name, val);
+                            }
+                            xmlFreeURI(uri);
+                        }
+                    }
+                    xmlFree(val);
+                }
+            } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
+                xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_ATTRIBUTE,
+                           "Unknown attribute %s on %s\n", cur->name,
+                           node->name);
+            }
+        }
+        cur = next;
+    }
+}
+
+/**
+ * xmlRelaxNGCleanupTree:
+ * @ctxt:  a Relax-NG parser context
+ * @root:  an xmlNodePtr subtree
+ *
+ * Cleanup the subtree from unwanted nodes for parsing, resolve
+ * Include and externalRef lookups.
+ */
+static void
+xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
+{
+    xmlNodePtr cur, delete;
+
+    delete = NULL;
+    cur = root;
+    while (cur != NULL) {
+        if (delete != NULL) {
+            xmlUnlinkNode(delete);
+            xmlFreeNode(delete);
+            delete = NULL;
+        }
+        if (cur->type == XML_ELEMENT_NODE) {
+            /*
+             * Simplification 4.1. Annotations
+             */
+            if ((cur->ns == NULL) ||
+                (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
+                if ((cur->parent != NULL) &&
+                    (cur->parent->type == XML_ELEMENT_NODE) &&
+                    ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) ||
+                     (xmlStrEqual(cur->parent->name, BAD_CAST "value")) ||
+                     (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) {
+                    xmlRngPErr(ctxt, cur, XML_RNGP_FOREIGN_ELEMENT,
+                               "element %s doesn't allow foreign elements\n",
+                               cur->parent->name, NULL);
+                }
+                delete = cur;
+                goto skip_children;
+            } else {
+                xmlRelaxNGCleanupAttributes(ctxt, cur);
+                if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) {
+                    xmlChar *href, *ns, *base, *URL;
+                    xmlRelaxNGDocumentPtr docu;
+                    xmlNodePtr tmp;
+		    xmlURIPtr uri;
+
+                    ns = xmlGetProp(cur, BAD_CAST "ns");
+                    if (ns == NULL) {
+                        tmp = cur->parent;
+                        while ((tmp != NULL) &&
+                               (tmp->type == XML_ELEMENT_NODE)) {
+                            ns = xmlGetProp(tmp, BAD_CAST "ns");
+                            if (ns != NULL)
+                                break;
+                            tmp = tmp->parent;
+                        }
+                    }
+                    href = xmlGetProp(cur, BAD_CAST "href");
+                    if (href == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
+                                   "xmlRelaxNGParse: externalRef has no href attribute\n",
+                                   NULL, NULL);
+                        if (ns != NULL)
+                            xmlFree(ns);
+                        delete = cur;
+                        goto skip_children;
+                    }
+		    uri = xmlParseURI((const char *) href);
+		    if (uri == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
+                                   "Incorrect URI for externalRef %s\n",
+                                   href, NULL);
+                        if (ns != NULL)
+                            xmlFree(ns);
+                        if (href != NULL)
+                            xmlFree(href);
+                        delete = cur;
+                        goto skip_children;
+		    }
+		    if (uri->fragment != NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
+			       "Fragment forbidden in URI for externalRef %s\n",
+                                   href, NULL);
+                        if (ns != NULL)
+                            xmlFree(ns);
+		        xmlFreeURI(uri);
+                        if (href != NULL)
+                            xmlFree(href);
+                        delete = cur;
+                        goto skip_children;
+		    }
+		    xmlFreeURI(uri);
+                    base = xmlNodeGetBase(cur->doc, cur);
+                    URL = xmlBuildURI(href, base);
+                    if (URL == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
+                                   "Failed to compute URL for externalRef %s\n",
+                                   href, NULL);
+                        if (ns != NULL)
+                            xmlFree(ns);
+                        if (href != NULL)
+                            xmlFree(href);
+                        if (base != NULL)
+                            xmlFree(base);
+                        delete = cur;
+                        goto skip_children;
+                    }
+                    if (href != NULL)
+                        xmlFree(href);
+                    if (base != NULL)
+                        xmlFree(base);
+                    docu = xmlRelaxNGLoadExternalRef(ctxt, URL, ns);
+                    if (docu == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_EXTERNAL_REF_FAILURE,
+                                   "Failed to load externalRef %s\n", URL,
+                                   NULL);
+                        if (ns != NULL)
+                            xmlFree(ns);
+                        xmlFree(URL);
+                        delete = cur;
+                        goto skip_children;
+                    }
+                    if (ns != NULL)
+                        xmlFree(ns);
+                    xmlFree(URL);
+                    cur->psvi = docu;
+                } else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
+                    xmlChar *href, *ns, *base, *URL;
+                    xmlRelaxNGIncludePtr incl;
+                    xmlNodePtr tmp;
+
+                    href = xmlGetProp(cur, BAD_CAST "href");
+                    if (href == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
+                                   "xmlRelaxNGParse: include has no href attribute\n",
+                                   NULL, NULL);
+                        delete = cur;
+                        goto skip_children;
+                    }
+                    base = xmlNodeGetBase(cur->doc, cur);
+                    URL = xmlBuildURI(href, base);
+                    if (URL == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
+                                   "Failed to compute URL for include %s\n",
+                                   href, NULL);
+                        if (href != NULL)
+                            xmlFree(href);
+                        if (base != NULL)
+                            xmlFree(base);
+                        delete = cur;
+                        goto skip_children;
+                    }
+                    if (href != NULL)
+                        xmlFree(href);
+                    if (base != NULL)
+                        xmlFree(base);
+                    ns = xmlGetProp(cur, BAD_CAST "ns");
+                    if (ns == NULL) {
+                        tmp = cur->parent;
+                        while ((tmp != NULL) &&
+                               (tmp->type == XML_ELEMENT_NODE)) {
+                            ns = xmlGetProp(tmp, BAD_CAST "ns");
+                            if (ns != NULL)
+                                break;
+                            tmp = tmp->parent;
+                        }
+                    }
+                    incl = xmlRelaxNGLoadInclude(ctxt, URL, cur, ns);
+                    if (ns != NULL)
+                        xmlFree(ns);
+                    if (incl == NULL) {
+                        xmlRngPErr(ctxt, cur, XML_RNGP_INCLUDE_FAILURE,
+                                   "Failed to load include %s\n", URL,
+                                   NULL);
+                        xmlFree(URL);
+                        delete = cur;
+                        goto skip_children;
+                    }
+                    xmlFree(URL);
+                    cur->psvi = incl;
+                } else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
+                           (xmlStrEqual(cur->name, BAD_CAST "attribute")))
+                {
+                    xmlChar *name, *ns;
+                    xmlNodePtr text = NULL;
+
+                    /*
+                     * Simplification 4.8. name attribute of element
+                     * and attribute elements
+                     */
+                    name = xmlGetProp(cur, BAD_CAST "name");
+                    if (name != NULL) {
+                        if (cur->children == NULL) {
+                            text =
+                                xmlNewChild(cur, cur->ns, BAD_CAST "name",
+                                            name);
+                        } else {
+                            xmlNodePtr node;
+
+                            node = xmlNewDocNode(cur->doc, cur->ns,
+			                         BAD_CAST "name", NULL);
+                            if (node != NULL) {
+                                xmlAddPrevSibling(cur->children, node);
+                                text = xmlNewText(name);
+                                xmlAddChild(node, text);
+                                text = node;
+                            }
+                        }
+                        if (text == NULL) {
+                            xmlRngPErr(ctxt, cur, XML_RNGP_CREATE_FAILURE,
+                                       "Failed to create a name %s element\n",
+                                       name, NULL);
+                        }
+                        xmlUnsetProp(cur, BAD_CAST "name");
+                        xmlFree(name);
+                        ns = xmlGetProp(cur, BAD_CAST "ns");
+                        if (ns != NULL) {
+                            if (text != NULL) {
+                                xmlSetProp(text, BAD_CAST "ns", ns);
+                                /* xmlUnsetProp(cur, BAD_CAST "ns"); */
+                            }
+                            xmlFree(ns);
+                        } else if (xmlStrEqual(cur->name,
+                                               BAD_CAST "attribute")) {
+                            xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
+                        }
+                    }
+                } else if ((xmlStrEqual(cur->name, BAD_CAST "name")) ||
+                           (xmlStrEqual(cur->name, BAD_CAST "nsName")) ||
+                           (xmlStrEqual(cur->name, BAD_CAST "value"))) {
+                    /*
+                     * Simplification 4.8. name attribute of element
+                     * and attribute elements
+                     */
+                    if (xmlHasProp(cur, BAD_CAST "ns") == NULL) {
+                        xmlNodePtr node;
+                        xmlChar *ns = NULL;
+
+                        node = cur->parent;
+                        while ((node != NULL) &&
+                               (node->type == XML_ELEMENT_NODE)) {
+                            ns = xmlGetProp(node, BAD_CAST "ns");
+                            if (ns != NULL) {
+                                break;
+                            }
+                            node = node->parent;
+                        }
+                        if (ns == NULL) {
+                            xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
+                        } else {
+                            xmlSetProp(cur, BAD_CAST "ns", ns);
+                            xmlFree(ns);
+                        }
+                    }
+                    if (xmlStrEqual(cur->name, BAD_CAST "name")) {
+                        xmlChar *name, *local, *prefix;
+
+                        /*
+                         * Simplification: 4.10. QNames
+                         */
+                        name = xmlNodeGetContent(cur);
+                        if (name != NULL) {
+                            local = xmlSplitQName2(name, &prefix);
+                            if (local != NULL) {
+                                xmlNsPtr ns;
+
+                                ns = xmlSearchNs(cur->doc, cur, prefix);
+                                if (ns == NULL) {
+                                    xmlRngPErr(ctxt, cur,
+                                               XML_RNGP_PREFIX_UNDEFINED,
+                                               "xmlRelaxNGParse: no namespace for prefix %s\n",
+                                               prefix, NULL);
+                                } else {
+                                    xmlSetProp(cur, BAD_CAST "ns",
+                                               ns->href);
+                                    xmlNodeSetContent(cur, local);
+                                }
+                                xmlFree(local);
+                                xmlFree(prefix);
+                            }
+                            xmlFree(name);
+                        }
+                    }
+                    /*
+                     * 4.16
+                     */
+                    if (xmlStrEqual(cur->name, BAD_CAST "nsName")) {
+                        if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
+                            xmlRngPErr(ctxt, cur,
+                                       XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME,
+                                       "Found nsName/except//nsName forbidden construct\n",
+                                       NULL, NULL);
+                        }
+                    }
+                } else if ((xmlStrEqual(cur->name, BAD_CAST "except")) &&
+                           (cur != root)) {
+                    int oldflags = ctxt->flags;
+
+                    /*
+                     * 4.16
+                     */
+                    if ((cur->parent != NULL) &&
+                        (xmlStrEqual
+                         (cur->parent->name, BAD_CAST "anyName"))) {
+                        ctxt->flags |= XML_RELAXNG_IN_ANYEXCEPT;
+                        xmlRelaxNGCleanupTree(ctxt, cur);
+                        ctxt->flags = oldflags;
+                        goto skip_children;
+                    } else if ((cur->parent != NULL) &&
+                               (xmlStrEqual
+                                (cur->parent->name, BAD_CAST "nsName"))) {
+                        ctxt->flags |= XML_RELAXNG_IN_NSEXCEPT;
+                        xmlRelaxNGCleanupTree(ctxt, cur);
+                        ctxt->flags = oldflags;
+                        goto skip_children;
+                    }
+                } else if (xmlStrEqual(cur->name, BAD_CAST "anyName")) {
+                    /*
+                     * 4.16
+                     */
+                    if (ctxt->flags & XML_RELAXNG_IN_ANYEXCEPT) {
+                        xmlRngPErr(ctxt, cur,
+                                   XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME,
+                                   "Found anyName/except//anyName forbidden construct\n",
+                                   NULL, NULL);
+                    } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
+                        xmlRngPErr(ctxt, cur,
+                                   XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME,
+                                   "Found nsName/except//anyName forbidden construct\n",
+                                   NULL, NULL);
+                    }
+                }
+                /*
+                 * Thisd is not an else since "include" is transformed
+                 * into a div
+                 */
+                if (xmlStrEqual(cur->name, BAD_CAST "div")) {
+                    xmlChar *ns;
+                    xmlNodePtr child, ins, tmp;
+
+                    /*
+                     * implements rule 4.11
+                     */
+
+                    ns = xmlGetProp(cur, BAD_CAST "ns");
+
+                    child = cur->children;
+                    ins = cur;
+                    while (child != NULL) {
+                        if (ns != NULL) {
+                            if (!xmlHasProp(child, BAD_CAST "ns")) {
+                                xmlSetProp(child, BAD_CAST "ns", ns);
+                            }
+                        }
+                        tmp = child->next;
+                        xmlUnlinkNode(child);
+                        ins = xmlAddNextSibling(ins, child);
+                        child = tmp;
+                    }
+                    if (ns != NULL)
+                        xmlFree(ns);
+		    /*
+		     * Since we are about to delete cur, if it's nsDef is non-NULL we
+		     * need to preserve it (it contains the ns definitions for the
+		     * children we just moved).  We'll just stick it on to the end
+		     * of cur->parent's list, since it's never going to be re-serialized
+		     * (bug 143738).
+		     */
+		    if (cur->nsDef != NULL) {
+			xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
+			while (parDef->next != NULL)
+			    parDef = parDef->next;
+			parDef->next = cur->nsDef;
+			cur->nsDef = NULL;
+		    }
+                    delete = cur;
+                    goto skip_children;
+                }
+            }
+        }
+        /*
+         * Simplification 4.2 whitespaces
+         */
+        else if ((cur->type == XML_TEXT_NODE) ||
+                 (cur->type == XML_CDATA_SECTION_NODE)) {
+            if (IS_BLANK_NODE(cur)) {
+                if (cur->parent->type == XML_ELEMENT_NODE) {
+                    if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
+                        &&
+                        (!xmlStrEqual
+                         (cur->parent->name, BAD_CAST "param")))
+                        delete = cur;
+                } else {
+                    delete = cur;
+                    goto skip_children;
+                }
+            }
+        } else {
+            delete = cur;
+            goto skip_children;
+        }
+
+        /*
+         * Skip to next node
+         */
+        if (cur->children != NULL) {
+            if ((cur->children->type != XML_ENTITY_DECL) &&
+                (cur->children->type != XML_ENTITY_REF_NODE) &&
+                (cur->children->type != XML_ENTITY_NODE)) {
+                cur = cur->children;
+                continue;
+            }
+        }
+      skip_children:
+        if (cur->next != NULL) {
+            cur = cur->next;
+            continue;
+        }
+
+        do {
+            cur = cur->parent;
+            if (cur == NULL)
+                break;
+            if (cur == root) {
+                cur = NULL;
+                break;
+            }
+            if (cur->next != NULL) {
+                cur = cur->next;
+                break;
+            }
+        } while (cur != NULL);
+    }
+    if (delete != NULL) {
+        xmlUnlinkNode(delete);
+        xmlFreeNode(delete);
+        delete = NULL;
+    }
+}
+
+/**
+ * xmlRelaxNGCleanupDoc:
+ * @ctxt:  a Relax-NG parser context
+ * @doc:  an xmldocPtr document pointer
+ *
+ * Cleanup the document from unwanted nodes for parsing, resolve
+ * Include and externalRef lookups.
+ *
+ * Returns the cleaned up document or NULL in case of error
+ */
+static xmlDocPtr
+xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc)
+{
+    xmlNodePtr root;
+
+    /*
+     * Extract the root
+     */
+    root = xmlDocGetRootElement(doc);
+    if (root == NULL) {
+        xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
+                   ctxt->URL, NULL);
+        return (NULL);
+    }
+    xmlRelaxNGCleanupTree(ctxt, root);
+    return (doc);
+}
+
+/**
+ * xmlRelaxNGParse:
+ * @ctxt:  a Relax-NG parser context
+ *
+ * parse a schema definition resource and build an internal
+ * XML Shema struture which can be used to validate instances.
+ *
+ * Returns the internal XML RelaxNG structure built from the resource or
+ *         NULL in case of error
+ */
+xmlRelaxNGPtr
+xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
+{
+    xmlRelaxNGPtr ret = NULL;
+    xmlDocPtr doc;
+    xmlNodePtr root;
+
+    xmlRelaxNGInitTypes();
+
+    if (ctxt == NULL)
+        return (NULL);
+
+    /*
+     * First step is to parse the input document into an DOM/Infoset
+     */
+    if (ctxt->URL != NULL) {
+        doc = xmlReadFile((const char *) ctxt->URL,NULL,0);
+        if (doc == NULL) {
+            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
+                       "xmlRelaxNGParse: could not load %s\n", ctxt->URL,
+                       NULL);
+            return (NULL);
+        }
+    } else if (ctxt->buffer != NULL) {
+        doc = xmlReadMemory(ctxt->buffer, ctxt->size,NULL,NULL,0);
+        if (doc == NULL) {
+            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
+                       "xmlRelaxNGParse: could not parse schemas\n", NULL,
+                       NULL);
+            return (NULL);
+        }
+        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
+        ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
+    } else if (ctxt->document != NULL) {
+        doc = ctxt->document;
+    } else {
+        xmlRngPErr(ctxt, NULL, XML_RNGP_EMPTY,
+                   "xmlRelaxNGParse: nothing to parse\n", NULL, NULL);
+        return (NULL);
+    }
+    ctxt->document = doc;
+
+    /*
+     * Some preprocessing of the document content
+     */
+    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
+    if (doc == NULL) {
+        xmlFreeDoc(ctxt->document);
+        ctxt->document = NULL;
+        return (NULL);
+    }
+
+    /*
+     * Then do the parsing for good
+     */
+    root = xmlDocGetRootElement(doc);
+    if (root == NULL) {
+        xmlRngPErr(ctxt, (xmlNodePtr) doc,
+	           XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
+                   (ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);
+	
+        xmlFreeDoc(ctxt->document);
+        ctxt->document = NULL;
+        return (NULL);
+    }
+    ret = xmlRelaxNGParseDocument(ctxt, root);
+    if (ret == NULL) {
+        xmlFreeDoc(ctxt->document);
+        ctxt->document = NULL;
+        return (NULL);
+    }
+
+    /*
+     * Check the ref/defines links
+     */
+    /*
+     * try to preprocess interleaves
+     */
+    if (ctxt->interleaves != NULL) {
+        xmlHashScan(ctxt->interleaves,
+                    (xmlHashScanner) xmlRelaxNGComputeInterleaves, ctxt);
+    }
+
+    /*
+     * if there was a parsing error return NULL
+     */
+    if (ctxt->nbErrors > 0) {
+        xmlRelaxNGFree(ret);
+        ctxt->document = NULL;
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+
+    /*
+     * try to compile (parts of) the schemas
+     */
+    if ((ret->topgrammar != NULL) && (ret->topgrammar->start != NULL)) {
+        if (ret->topgrammar->start->type != XML_RELAXNG_START) {
+            xmlRelaxNGDefinePtr def;
+
+            def = xmlRelaxNGNewDefine(ctxt, NULL);
+            if (def != NULL) {
+                def->type = XML_RELAXNG_START;
+                def->content = ret->topgrammar->start;
+                ret->topgrammar->start = def;
+            }
+        }
+        xmlRelaxNGTryCompile(ctxt, ret->topgrammar->start);
+    }
+
+    /*
+     * Transfer the pointer for cleanup at the schema level.
+     */
+    ret->doc = doc;
+    ctxt->document = NULL;
+    ret->documents = ctxt->documents;
+    ctxt->documents = NULL;
+
+    ret->includes = ctxt->includes;
+    ctxt->includes = NULL;
+    ret->defNr = ctxt->defNr;
+    ret->defTab = ctxt->defTab;
+    ctxt->defTab = NULL;
+    if (ctxt->idref == 1)
+        ret->idref = 1;
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGSetParserErrors:
+ * @ctxt:  a Relax-NG validation context
+ * @err:  the error callback
+ * @warn:  the warning callback
+ * @ctx:  contextual data for the callbacks
+ *
+ * Set the callback functions used to handle errors for a validation context
+ */
+void
+xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
+                          xmlRelaxNGValidityErrorFunc err,
+                          xmlRelaxNGValidityWarningFunc warn, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->error = err;
+    ctxt->warning = warn;
+    ctxt->serror = NULL;
+    ctxt->userData = ctx;
+}
+
+/**
+ * xmlRelaxNGGetParserErrors:
+ * @ctxt:  a Relax-NG validation context
+ * @err:  the error callback result
+ * @warn:  the warning callback result
+ * @ctx:  contextual data for the callbacks result
+ *
+ * Get the callback information used to handle errors for a validation context
+ *
+ * Returns -1 in case of failure, 0 otherwise.
+ */
+int
+xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
+                          xmlRelaxNGValidityErrorFunc * err,
+                          xmlRelaxNGValidityWarningFunc * warn, void **ctx)
+{
+    if (ctxt == NULL)
+        return (-1);
+    if (err != NULL)
+        *err = ctxt->error;
+    if (warn != NULL)
+        *warn = ctxt->warning;
+    if (ctx != NULL)
+        *ctx = ctxt->userData;
+    return (0);
+}
+
+/**
+ * xmlRelaxNGSetParserStructuredErrors:
+ * @ctxt:  a Relax-NG parser context
+ * @serror:  the error callback
+ * @ctx:  contextual data for the callbacks
+ *
+ * Set the callback functions used to handle errors for a parsing context
+ */
+void
+xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
+				    xmlStructuredErrorFunc serror,
+				    void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->serror = serror;
+    ctxt->error = NULL;
+    ctxt->warning = NULL;
+    ctxt->userData = ctx;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+
+/************************************************************************
+ * 									*
+ * 			Dump back a compiled form			*
+ * 									*
+ ************************************************************************/
+static void xmlRelaxNGDumpDefine(FILE * output,
+                                 xmlRelaxNGDefinePtr define);
+
+/**
+ * xmlRelaxNGDumpDefines:
+ * @output:  the file output
+ * @defines:  a list of define structures
+ *
+ * Dump a RelaxNG structure back
+ */
+static void
+xmlRelaxNGDumpDefines(FILE * output, xmlRelaxNGDefinePtr defines)
+{
+    while (defines != NULL) {
+        xmlRelaxNGDumpDefine(output, defines);
+        defines = defines->next;
+    }
+}
+
+/**
+ * xmlRelaxNGDumpDefine:
+ * @output:  the file output
+ * @define:  a define structure
+ *
+ * Dump a RelaxNG structure back
+ */
+static void
+xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
+{
+    if (define == NULL)
+        return;
+    switch (define->type) {
+        case XML_RELAXNG_EMPTY:
+            fprintf(output, "<empty/>\n");
+            break;
+        case XML_RELAXNG_NOT_ALLOWED:
+            fprintf(output, "<notAllowed/>\n");
+            break;
+        case XML_RELAXNG_TEXT:
+            fprintf(output, "<text/>\n");
+            break;
+        case XML_RELAXNG_ELEMENT:
+            fprintf(output, "<element>\n");
+            if (define->name != NULL) {
+                fprintf(output, "<name");
+                if (define->ns != NULL)
+                    fprintf(output, " ns=\"%s\"", define->ns);
+                fprintf(output, ">%s</name>\n", define->name);
+            }
+            xmlRelaxNGDumpDefines(output, define->attrs);
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</element>\n");
+            break;
+        case XML_RELAXNG_LIST:
+            fprintf(output, "<list>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</list>\n");
+            break;
+        case XML_RELAXNG_ONEORMORE:
+            fprintf(output, "<oneOrMore>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</oneOrMore>\n");
+            break;
+        case XML_RELAXNG_ZEROORMORE:
+            fprintf(output, "<zeroOrMore>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</zeroOrMore>\n");
+            break;
+        case XML_RELAXNG_CHOICE:
+            fprintf(output, "<choice>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</choice>\n");
+            break;
+        case XML_RELAXNG_GROUP:
+            fprintf(output, "<group>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</group>\n");
+            break;
+        case XML_RELAXNG_INTERLEAVE:
+            fprintf(output, "<interleave>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</interleave>\n");
+            break;
+        case XML_RELAXNG_OPTIONAL:
+            fprintf(output, "<optional>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</optional>\n");
+            break;
+        case XML_RELAXNG_ATTRIBUTE:
+            fprintf(output, "<attribute>\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</attribute>\n");
+            break;
+        case XML_RELAXNG_DEF:
+            fprintf(output, "<define");
+            if (define->name != NULL)
+                fprintf(output, " name=\"%s\"", define->name);
+            fprintf(output, ">\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</define>\n");
+            break;
+        case XML_RELAXNG_REF:
+            fprintf(output, "<ref");
+            if (define->name != NULL)
+                fprintf(output, " name=\"%s\"", define->name);
+            fprintf(output, ">\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</ref>\n");
+            break;
+        case XML_RELAXNG_PARENTREF:
+            fprintf(output, "<parentRef");
+            if (define->name != NULL)
+                fprintf(output, " name=\"%s\"", define->name);
+            fprintf(output, ">\n");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</parentRef>\n");
+            break;
+        case XML_RELAXNG_EXTERNALREF:
+            fprintf(output, "<externalRef>");
+            xmlRelaxNGDumpDefines(output, define->content);
+            fprintf(output, "</externalRef>\n");
+            break;
+        case XML_RELAXNG_DATATYPE:
+        case XML_RELAXNG_VALUE:
+            TODO break;
+        case XML_RELAXNG_START:
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_PARAM:
+            TODO break;
+        case XML_RELAXNG_NOOP:
+            xmlRelaxNGDumpDefines(output, define->content);
+            break;
+    }
+}
+
+/**
+ * xmlRelaxNGDumpGrammar:
+ * @output:  the file output
+ * @grammar:  a grammar structure
+ * @top:  is this a top grammar 
+ *
+ * Dump a RelaxNG structure back
+ */
+static void
+xmlRelaxNGDumpGrammar(FILE * output, xmlRelaxNGGrammarPtr grammar, int top)
+{
+    if (grammar == NULL)
+        return;
+
+    fprintf(output, "<grammar");
+    if (top)
+        fprintf(output, " xmlns=\"http://relaxng.org/ns/structure/1.0\"");
+    switch (grammar->combine) {
+        case XML_RELAXNG_COMBINE_UNDEFINED:
+            break;
+        case XML_RELAXNG_COMBINE_CHOICE:
+            fprintf(output, " combine=\"choice\"");
+            break;
+        case XML_RELAXNG_COMBINE_INTERLEAVE:
+            fprintf(output, " combine=\"interleave\"");
+            break;
+        default:
+            fprintf(output, " <!-- invalid combine value -->");
+    }
+    fprintf(output, ">\n");
+    if (grammar->start == NULL) {
+        fprintf(output, " <!-- grammar had no start -->");
+    } else {
+        fprintf(output, "<start>\n");
+        xmlRelaxNGDumpDefine(output, grammar->start);
+        fprintf(output, "</start>\n");
+    }
+    /* TODO ? Dump the defines ? */
+    fprintf(output, "</grammar>\n");
+}
+
+/**
+ * xmlRelaxNGDump:
+ * @output:  the file output
+ * @schema:  a schema structure
+ *
+ * Dump a RelaxNG structure back
+ */
+void
+xmlRelaxNGDump(FILE * output, xmlRelaxNGPtr schema)
+{
+    if (output == NULL)
+        return;
+    if (schema == NULL) {
+        fprintf(output, "RelaxNG empty or failed to compile\n");
+        return;
+    }
+    fprintf(output, "RelaxNG: ");
+    if (schema->doc == NULL) {
+        fprintf(output, "no document\n");
+    } else if (schema->doc->URL != NULL) {
+        fprintf(output, "%s\n", schema->doc->URL);
+    } else {
+        fprintf(output, "\n");
+    }
+    if (schema->topgrammar == NULL) {
+        fprintf(output, "RelaxNG has no top grammar\n");
+        return;
+    }
+    xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
+}
+
+/**
+ * xmlRelaxNGDumpTree:
+ * @output:  the file output
+ * @schema:  a schema structure
+ *
+ * Dump the transformed RelaxNG tree.
+ */
+void
+xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
+{
+    if (output == NULL)
+        return;
+    if (schema == NULL) {
+        fprintf(output, "RelaxNG empty or failed to compile\n");
+        return;
+    }
+    if (schema->doc == NULL) {
+        fprintf(output, "no document\n");
+    } else {
+        xmlDocDump(output, schema->doc);
+    }
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ * 									*
+ * 		Validation of compiled content				*
+ * 									*
+ ************************************************************************/
+static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
+                                        xmlRelaxNGDefinePtr define);
+
+/**
+ * xmlRelaxNGValidateCompiledCallback:
+ * @exec:  the regular expression instance
+ * @token:  the token which matched
+ * @transdata:  callback data, the define for the subelement if available
+ @ @inputdata:  callback data, the Relax NG validation context
+ *
+ * Handle the callback and if needed validate the element children.
+ */
+static void
+xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
+                                   const xmlChar * token,
+                                   void *transdata, void *inputdata)
+{
+    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
+    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
+    int ret;
+
+#ifdef DEBUG_COMPILE
+    xmlGenericError(xmlGenericErrorContext,
+                    "Compiled callback for: '%s'\n", token);
+#endif
+    if (ctxt == NULL) {
+        fprintf(stderr, "callback on %s missing context\n", token);
+        return;
+    }
+    if (define == NULL) {
+        if (token[0] == '#')
+            return;
+        fprintf(stderr, "callback on %s missing define\n", token);
+        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        return;
+    }
+    if ((ctxt == NULL) || (define == NULL)) {
+        fprintf(stderr, "callback on %s missing info\n", token);
+        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        return;
+    } else if (define->type != XML_RELAXNG_ELEMENT) {
+        fprintf(stderr, "callback on %s define is not element\n", token);
+        if (ctxt->errNo == XML_RELAXNG_OK)
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        return;
+    }
+    ret = xmlRelaxNGValidateDefinition(ctxt, define);
+    if (ret != 0)
+        ctxt->perr = ret;
+}
+
+/**
+ * xmlRelaxNGValidateCompiledContent:
+ * @ctxt:  the RelaxNG validation context
+ * @regexp:  the regular expression as compiled
+ * @content:  list of children to test against the regexp
+ *
+ * Validate the content model of an element or start using the regexp
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+static int
+xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
+                                  xmlRegexpPtr regexp, xmlNodePtr content)
+{
+    xmlRegExecCtxtPtr exec;
+    xmlNodePtr cur;
+    int ret = 0;
+    int oldperr;
+
+    if ((ctxt == NULL) || (regexp == NULL))
+        return (-1);
+    oldperr = ctxt->perr;
+    exec = xmlRegNewExecCtxt(regexp,
+                             xmlRelaxNGValidateCompiledCallback, ctxt);
+    ctxt->perr = 0;
+    cur = content;
+    while (cur != NULL) {
+        ctxt->state->seq = cur;
+        switch (cur->type) {
+            case XML_TEXT_NODE:
+            case XML_CDATA_SECTION_NODE:
+                if (xmlIsBlankNode(cur))
+                    break;
+                ret = xmlRegExecPushString(exec, BAD_CAST "#text", ctxt);
+                if (ret < 0) {
+                    VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG,
+                               cur->parent->name);
+                }
+                break;
+            case XML_ELEMENT_NODE:
+                if (cur->ns != NULL) {
+                    ret = xmlRegExecPushString2(exec, cur->name,
+                                                cur->ns->href, ctxt);
+                } else {
+                    ret = xmlRegExecPushString(exec, cur->name, ctxt);
+                }
+                if (ret < 0) {
+                    VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, cur->name);
+                }
+                break;
+            default:
+                break;
+        }
+        if (ret < 0)
+            break;
+        /*
+         * Switch to next element
+         */
+        cur = cur->next;
+    }
+    ret = xmlRegExecPushString(exec, NULL, NULL);
+    if (ret == 1) {
+        ret = 0;
+        ctxt->state->seq = NULL;
+    } else if (ret == 0) {
+        /*
+         * TODO: get some of the names needed to exit the current state of exec
+         */
+        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
+        ret = -1;
+        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+            xmlRelaxNGDumpValidError(ctxt);
+    } else {
+        ret = -1;
+    }
+    xmlRegFreeExecCtxt(exec);
+    /*
+     * There might be content model errors outside of the pure
+     * regexp validation, e.g. for attribute values.
+     */
+    if ((ret == 0) && (ctxt->perr != 0)) {
+        ret = ctxt->perr;
+    }
+    ctxt->perr = oldperr;
+    return (ret);
+}
+
+/************************************************************************
+ * 									*
+ * 		Progressive validation of when possible			*
+ * 									*
+ ************************************************************************/
+static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
+                                           xmlRelaxNGDefinePtr defines);
+static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,
+                                        int dolog);
+static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
+
+/**
+ * xmlRelaxNGElemPush:
+ * @ctxt:  the validation context
+ * @exec:  the regexp runtime for the new content model
+ *
+ * Push a new regexp for the current node content model on the stack
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+static int
+xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
+{
+    if (ctxt->elemTab == NULL) {
+        ctxt->elemMax = 10;
+        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlMalloc(ctxt->elemMax *
+                                                        sizeof
+                                                        (xmlRegExecCtxtPtr));
+        if (ctxt->elemTab == NULL) {
+            xmlRngVErrMemory(ctxt, "validating\n");
+            return (-1);
+        }
+    }
+    if (ctxt->elemNr >= ctxt->elemMax) {
+        ctxt->elemMax *= 2;
+        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
+                                                         ctxt->elemMax *
+                                                         sizeof
+                                                         (xmlRegExecCtxtPtr));
+        if (ctxt->elemTab == NULL) {
+            xmlRngVErrMemory(ctxt, "validating\n");
+            return (-1);
+        }
+    }
+    ctxt->elemTab[ctxt->elemNr++] = exec;
+    ctxt->elem = exec;
+    return (0);
+}
+
+/**
+ * xmlRelaxNGElemPop:
+ * @ctxt:  the validation context
+ *
+ * Pop the regexp of the current node content model from the stack
+ *
+ * Returns the exec or NULL if empty
+ */
+static xmlRegExecCtxtPtr
+xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    xmlRegExecCtxtPtr ret;
+
+    if (ctxt->elemNr <= 0)
+        return (NULL);
+    ctxt->elemNr--;
+    ret = ctxt->elemTab[ctxt->elemNr];
+    ctxt->elemTab[ctxt->elemNr] = NULL;
+    if (ctxt->elemNr > 0)
+        ctxt->elem = ctxt->elemTab[ctxt->elemNr - 1];
+    else
+        ctxt->elem = NULL;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateProgressiveCallback:
+ * @exec:  the regular expression instance
+ * @token:  the token which matched
+ * @transdata:  callback data, the define for the subelement if available
+ @ @inputdata:  callback data, the Relax NG validation context
+ *
+ * Handle the callback and if needed validate the element children.
+ * some of the in/out informations are passed via the context in @inputdata.
+ */
+static void
+xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
+                                      ATTRIBUTE_UNUSED,
+                                      const xmlChar * token,
+                                      void *transdata, void *inputdata)
+{
+    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
+    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
+    xmlRelaxNGValidStatePtr state, oldstate;
+    xmlNodePtr node;
+    int ret = 0, oldflags;
+
+#ifdef DEBUG_PROGRESSIVE
+    xmlGenericError(xmlGenericErrorContext,
+                    "Progressive callback for: '%s'\n", token);
+#endif
+    if (ctxt == NULL) {
+        fprintf(stderr, "callback on %s missing context\n", token);
+        return;
+    }
+    node = ctxt->pnode;
+    ctxt->pstate = 1;
+    if (define == NULL) {
+        if (token[0] == '#')
+            return;
+        fprintf(stderr, "callback on %s missing define\n", token);
+        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        ctxt->pstate = -1;
+        return;
+    }
+    if ((ctxt == NULL) || (define == NULL)) {
+        fprintf(stderr, "callback on %s missing info\n", token);
+        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        ctxt->pstate = -1;
+        return;
+    } else if (define->type != XML_RELAXNG_ELEMENT) {
+        fprintf(stderr, "callback on %s define is not element\n", token);
+        if (ctxt->errNo == XML_RELAXNG_OK)
+            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
+        ctxt->pstate = -1;
+        return;
+    }
+    if (node->type != XML_ELEMENT_NODE) {
+        VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
+        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+            xmlRelaxNGDumpValidError(ctxt);
+        ctxt->pstate = -1;
+        return;
+    }
+    if (define->contModel == NULL) {
+        /*
+         * this node cannot be validated in a streamable fashion
+         */
+#ifdef DEBUG_PROGRESSIVE
+        xmlGenericError(xmlGenericErrorContext,
+                        "Element '%s' validation is not streamable\n",
+                        token);
+#endif
+        ctxt->pstate = 0;
+        ctxt->pdef = define;
+        return;
+    }
+    exec = xmlRegNewExecCtxt(define->contModel,
+                             xmlRelaxNGValidateProgressiveCallback, ctxt);
+    if (exec == NULL) {
+        ctxt->pstate = -1;
+        return;
+    }
+    xmlRelaxNGElemPush(ctxt, exec);
+
+    /*
+     * Validate the attributes part of the content.
+     */
+    state = xmlRelaxNGNewValidState(ctxt, node);
+    if (state == NULL) {
+        ctxt->pstate = -1;
+        return;
+    }
+    oldstate = ctxt->state;
+    ctxt->state = state;
+    if (define->attrs != NULL) {
+        ret = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
+        if (ret != 0) {
+            ctxt->pstate = -1;
+            VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
+        }
+    }
+    if (ctxt->state != NULL) {
+        ctxt->state->seq = NULL;
+        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
+        if (ret != 0) {
+            ctxt->pstate = -1;
+        }
+        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+    } else if (ctxt->states != NULL) {
+        int tmp = -1, i;
+
+        oldflags = ctxt->flags;
+
+        for (i = 0; i < ctxt->states->nbState; i++) {
+            state = ctxt->states->tabState[i];
+            ctxt->state = state;
+            ctxt->state->seq = NULL;
+
+            if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
+                tmp = 0;
+                break;
+            }
+        }
+        if (tmp != 0) {
+            /*
+             * validation error, log the message for the "best" one
+             */
+            ctxt->flags |= FLAGS_IGNORABLE;
+            xmlRelaxNGLogBestError(ctxt);
+        }
+        for (i = 0; i < ctxt->states->nbState; i++) {
+            xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[i]);
+        }
+        xmlRelaxNGFreeStates(ctxt, ctxt->states);
+        ctxt->states = NULL;
+        if ((ret == 0) && (tmp == -1))
+            ctxt->pstate = -1;
+        ctxt->flags = oldflags;
+    }
+    if (ctxt->pstate == -1) {
+        if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
+            xmlRelaxNGDumpValidError(ctxt);
+        }
+    }
+    ctxt->state = oldstate;
+}
+
+/**
+ * xmlRelaxNGValidatePushElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Push a new element start on the RelaxNG validation stack.
+ *
+ * returns 1 if no validation problem was found or 0 if validating the
+ *         element requires a full node, and -1 in case of error.
+ */
+int
+xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
+                              xmlDocPtr doc ATTRIBUTE_UNUSED,
+                              xmlNodePtr elem)
+{
+    int ret = 1;
+
+    if ((ctxt == NULL) || (elem == NULL))
+        return (-1);
+
+#ifdef DEBUG_PROGRESSIVE
+    xmlGenericError(xmlGenericErrorContext, "PushElem %s\n", elem->name);
+#endif
+    if (ctxt->elem == 0) {
+        xmlRelaxNGPtr schema;
+        xmlRelaxNGGrammarPtr grammar;
+        xmlRegExecCtxtPtr exec;
+        xmlRelaxNGDefinePtr define;
+
+        schema = ctxt->schema;
+        if (schema == NULL) {
+            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
+            return (-1);
+        }
+        grammar = schema->topgrammar;
+        if ((grammar == NULL) || (grammar->start == NULL)) {
+            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
+            return (-1);
+        }
+        define = grammar->start;
+        if (define->contModel == NULL) {
+            ctxt->pdef = define;
+            return (0);
+        }
+        exec = xmlRegNewExecCtxt(define->contModel,
+                                 xmlRelaxNGValidateProgressiveCallback,
+                                 ctxt);
+        if (exec == NULL) {
+            return (-1);
+        }
+        xmlRelaxNGElemPush(ctxt, exec);
+    }
+    ctxt->pnode = elem;
+    ctxt->pstate = 0;
+    if (elem->ns != NULL) {
+        ret =
+            xmlRegExecPushString2(ctxt->elem, elem->name, elem->ns->href,
+                                  ctxt);
+    } else {
+        ret = xmlRegExecPushString(ctxt->elem, elem->name, ctxt);
+    }
+    if (ret < 0) {
+        VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, elem->name);
+    } else {
+        if (ctxt->pstate == 0)
+            ret = 0;
+        else if (ctxt->pstate < 0)
+            ret = -1;
+        else
+            ret = 1;
+    }
+#ifdef DEBUG_PROGRESSIVE
+    if (ret < 0)
+        xmlGenericError(xmlGenericErrorContext, "PushElem %s failed\n",
+                        elem->name);
+#endif
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidatePushCData:
+ * @ctxt:  the RelaxNG validation context
+ * @data:  some character data read
+ * @len:  the lenght of the data
+ *
+ * check the CData parsed for validation in the current stack
+ *
+ * returns 1 if no validation problem was found or -1 otherwise
+ */
+int
+xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
+                            const xmlChar * data, int len ATTRIBUTE_UNUSED)
+{
+    int ret = 1;
+
+    if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
+        return (-1);
+
+#ifdef DEBUG_PROGRESSIVE
+    xmlGenericError(xmlGenericErrorContext, "CDATA %s %d\n", data, len);
+#endif
+
+    while (*data != 0) {
+        if (!IS_BLANK_CH(*data))
+            break;
+        data++;
+    }
+    if (*data == 0)
+        return (1);
+
+    ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
+    if (ret < 0) {
+        VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");
+#ifdef DEBUG_PROGRESSIVE
+        xmlGenericError(xmlGenericErrorContext, "CDATA failed\n");
+#endif
+
+        return (-1);
+    }
+    return (1);
+}
+
+/**
+ * xmlRelaxNGValidatePopElement:
+ * @ctxt:  the RelaxNG validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Pop the element end from the RelaxNG validation stack.
+ *
+ * returns 1 if no validation problem was found or 0 otherwise
+ */
+int
+xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
+                             xmlDocPtr doc ATTRIBUTE_UNUSED,
+                             xmlNodePtr elem)
+{
+    int ret;
+    xmlRegExecCtxtPtr exec;
+
+    if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
+        return (-1);
+#ifdef DEBUG_PROGRESSIVE
+    xmlGenericError(xmlGenericErrorContext, "PopElem %s\n", elem->name);
+#endif
+    /*
+     * verify that we reached a terminal state of the content model.
+     */
+    exec = xmlRelaxNGElemPop(ctxt);
+    ret = xmlRegExecPushString(exec, NULL, NULL);
+    if (ret == 0) {
+        /*
+         * TODO: get some of the names needed to exit the current state of exec
+         */
+        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
+        ret = -1;
+    } else if (ret < 0) {
+        ret = -1;
+    } else {
+        ret = 1;
+    }
+    xmlRegFreeExecCtxt(exec);
+#ifdef DEBUG_PROGRESSIVE
+    if (ret < 0)
+        xmlGenericError(xmlGenericErrorContext, "PopElem %s failed\n",
+                        elem->name);
+#endif
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateFullElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Validate a full subtree when xmlRelaxNGValidatePushElement() returned
+ * 0 and the content of the node has been expanded.
+ *
+ * returns 1 if no validation problem was found or -1 in case of error.
+ */
+int
+xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
+                              xmlDocPtr doc ATTRIBUTE_UNUSED,
+                              xmlNodePtr elem)
+{
+    int ret;
+    xmlRelaxNGValidStatePtr state;
+
+    if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
+        return (-1);
+#ifdef DEBUG_PROGRESSIVE
+    xmlGenericError(xmlGenericErrorContext, "FullElem %s\n", elem->name);
+#endif
+    state = xmlRelaxNGNewValidState(ctxt, elem->parent);
+    if (state == NULL) {
+        return (-1);
+    }
+    state->seq = elem;
+    ctxt->state = state;
+    ctxt->errNo = XML_RELAXNG_OK;
+    ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef);
+    if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK))
+        ret = -1;
+    else
+        ret = 1;
+    xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+    ctxt->state = NULL;
+#ifdef DEBUG_PROGRESSIVE
+    if (ret < 0)
+        xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n",
+                        elem->name);
+#endif
+    return (ret);
+}
+
+/************************************************************************
+ * 									*
+ * 		Generic interpreted validation implementation		*
+ * 									*
+ ************************************************************************/
+static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
+                                   xmlRelaxNGDefinePtr define);
+
+/**
+ * xmlRelaxNGSkipIgnored:
+ * @ctxt:  a schema validation context
+ * @node:  the top node.
+ *
+ * Skip ignorable nodes in that context
+ *
+ * Returns the new sibling or NULL in case of error.
+ */
+static xmlNodePtr
+xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                      xmlNodePtr node)
+{
+    /*
+     * TODO complete and handle entities
+     */
+    while ((node != NULL) &&
+           ((node->type == XML_COMMENT_NODE) ||
+            (node->type == XML_PI_NODE) ||
+	    (node->type == XML_XINCLUDE_START) ||
+	    (node->type == XML_XINCLUDE_END) ||
+            (((node->type == XML_TEXT_NODE) ||
+              (node->type == XML_CDATA_SECTION_NODE)) &&
+             ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
+              (IS_BLANK_NODE(node)))))) {
+        node = node->next;
+    }
+    return (node);
+}
+
+/**
+ * xmlRelaxNGNormalize:
+ * @ctxt:  a schema validation context
+ * @str:  the string to normalize
+ *
+ * Implements the  normalizeWhiteSpace( s ) function from
+ * section 6.2.9 of the spec
+ *
+ * Returns the new string or NULL in case of error.
+ */
+static xmlChar *
+xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
+{
+    xmlChar *ret, *p;
+    const xmlChar *tmp;
+    int len;
+
+    if (str == NULL)
+        return (NULL);
+    tmp = str;
+    while (*tmp != 0)
+        tmp++;
+    len = tmp - str;
+
+    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlRngVErrMemory(ctxt, "validating\n");
+        return (NULL);
+    }
+    p = ret;
+    while (IS_BLANK_CH(*str))
+        str++;
+    while (*str != 0) {
+        if (IS_BLANK_CH(*str)) {
+            while (IS_BLANK_CH(*str))
+                str++;
+            if (*str == 0)
+                break;
+            *p++ = ' ';
+        } else
+            *p++ = *str++;
+    }
+    *p = 0;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateDatatype:
+ * @ctxt:  a Relax-NG validation context
+ * @value:  the string value
+ * @type:  the datatype definition
+ * @node:  the node
+ *
+ * Validate the given value against the dataype
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,
+                           const xmlChar * value,
+                           xmlRelaxNGDefinePtr define, xmlNodePtr node)
+{
+    int ret, tmp;
+    xmlRelaxNGTypeLibraryPtr lib;
+    void *result = NULL;
+    xmlRelaxNGDefinePtr cur;
+
+    if ((define == NULL) || (define->data == NULL)) {
+        return (-1);
+    }
+    lib = (xmlRelaxNGTypeLibraryPtr) define->data;
+    if (lib->check != NULL) {
+        if ((define->attrs != NULL) &&
+            (define->attrs->type == XML_RELAXNG_PARAM)) {
+            ret =
+                lib->check(lib->data, define->name, value, &result, node);
+        } else {
+            ret = lib->check(lib->data, define->name, value, NULL, node);
+        }
+    } else
+        ret = -1;
+    if (ret < 0) {
+        VALID_ERR2(XML_RELAXNG_ERR_TYPE, define->name);
+        if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
+            lib->freef(lib->data, result);
+        return (-1);
+    } else if (ret == 1) {
+        ret = 0;
+    } else if (ret == 2) {
+        VALID_ERR2P(XML_RELAXNG_ERR_DUPID, value);
+    } else {
+        VALID_ERR3P(XML_RELAXNG_ERR_TYPEVAL, define->name, value);
+        ret = -1;
+    }
+    cur = define->attrs;
+    while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
+        if (lib->facet != NULL) {
+            tmp = lib->facet(lib->data, define->name, cur->name,
+                             cur->value, value, result);
+            if (tmp != 0)
+                ret = -1;
+        }
+        cur = cur->next;
+    }
+    if ((ret == 0) && (define->content != NULL)) {
+        const xmlChar *oldvalue, *oldendvalue;
+
+        oldvalue = ctxt->state->value;
+        oldendvalue = ctxt->state->endvalue;
+        ctxt->state->value = (xmlChar *) value;
+        ctxt->state->endvalue = NULL;
+        ret = xmlRelaxNGValidateValue(ctxt, define->content);
+        ctxt->state->value = (xmlChar *) oldvalue;
+        ctxt->state->endvalue = (xmlChar *) oldendvalue;
+    }
+    if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
+        lib->freef(lib->data, result);
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGNextValue:
+ * @ctxt:  a Relax-NG validation context
+ *
+ * Skip to the next value when validating within a list
+ *
+ * Returns 0 if the operation succeeded or an error code.
+ */
+static int
+xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    xmlChar *cur;
+
+    cur = ctxt->state->value;
+    if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
+        ctxt->state->value = NULL;
+        ctxt->state->endvalue = NULL;
+        return (0);
+    }
+    while (*cur != 0)
+        cur++;
+    while ((cur != ctxt->state->endvalue) && (*cur == 0))
+        cur++;
+    if (cur == ctxt->state->endvalue)
+        ctxt->state->value = NULL;
+    else
+        ctxt->state->value = cur;
+    return (0);
+}
+
+/**
+ * xmlRelaxNGValidateValueList:
+ * @ctxt:  a Relax-NG validation context
+ * @defines:  the list of definitions to verify
+ *
+ * Validate the given set of definitions for the current value
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,
+                            xmlRelaxNGDefinePtr defines)
+{
+    int ret = 0;
+
+    while (defines != NULL) {
+        ret = xmlRelaxNGValidateValue(ctxt, defines);
+        if (ret != 0)
+            break;
+        defines = defines->next;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateValue:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to verify
+ *
+ * Validate the given definition for the current value
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
+                        xmlRelaxNGDefinePtr define)
+{
+    int ret = 0, oldflags;
+    xmlChar *value;
+
+    value = ctxt->state->value;
+    switch (define->type) {
+        case XML_RELAXNG_EMPTY:{
+                if ((value != NULL) && (value[0] != 0)) {
+                    int idx = 0;
+
+                    while (IS_BLANK_CH(value[idx]))
+                        idx++;
+                    if (value[idx] != 0)
+                        ret = -1;
+                }
+                break;
+            }
+        case XML_RELAXNG_TEXT:
+            break;
+        case XML_RELAXNG_VALUE:{
+                if (!xmlStrEqual(value, define->value)) {
+                    if (define->name != NULL) {
+                        xmlRelaxNGTypeLibraryPtr lib;
+
+                        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
+                        if ((lib != NULL) && (lib->comp != NULL)) {
+                            ret = lib->comp(lib->data, define->name,
+                                            define->value, define->node,
+                                            (void *) define->attrs,
+                                            value, ctxt->state->node);
+                        } else
+                            ret = -1;
+                        if (ret < 0) {
+                            VALID_ERR2(XML_RELAXNG_ERR_TYPECMP,
+                                       define->name);
+                            return (-1);
+                        } else if (ret == 1) {
+                            ret = 0;
+                        } else {
+                            ret = -1;
+                        }
+                    } else {
+                        xmlChar *nval, *nvalue;
+
+                        /*
+                         * TODO: trivial optimizations are possible by
+                         * computing at compile-time
+                         */
+                        nval = xmlRelaxNGNormalize(ctxt, define->value);
+                        nvalue = xmlRelaxNGNormalize(ctxt, value);
+
+                        if ((nval == NULL) || (nvalue == NULL) ||
+                            (!xmlStrEqual(nval, nvalue)))
+                            ret = -1;
+                        if (nval != NULL)
+                            xmlFree(nval);
+                        if (nvalue != NULL)
+                            xmlFree(nvalue);
+                    }
+                }
+                if (ret == 0)
+                    xmlRelaxNGNextValue(ctxt);
+                break;
+            }
+        case XML_RELAXNG_DATATYPE:{
+                ret = xmlRelaxNGValidateDatatype(ctxt, value, define,
+                                                 ctxt->state->seq);
+                if (ret == 0)
+                    xmlRelaxNGNextValue(ctxt);
+
+                break;
+            }
+        case XML_RELAXNG_CHOICE:{
+                xmlRelaxNGDefinePtr list = define->content;
+                xmlChar *oldvalue;
+
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+
+                oldvalue = ctxt->state->value;
+                while (list != NULL) {
+                    ret = xmlRelaxNGValidateValue(ctxt, list);
+                    if (ret == 0) {
+                        break;
+                    }
+                    ctxt->state->value = oldvalue;
+                    list = list->next;
+                }
+                ctxt->flags = oldflags;
+                if (ret != 0) {
+                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                        xmlRelaxNGDumpValidError(ctxt);
+                } else {
+                    if (ctxt->errNr > 0)
+                        xmlRelaxNGPopErrors(ctxt, 0);
+                }
+                break;
+            }
+        case XML_RELAXNG_LIST:{
+                xmlRelaxNGDefinePtr list = define->content;
+                xmlChar *oldvalue, *oldend, *val, *cur;
+
+#ifdef DEBUG_LIST
+                int nb_values = 0;
+#endif
+
+                oldvalue = ctxt->state->value;
+                oldend = ctxt->state->endvalue;
+
+                val = xmlStrdup(oldvalue);
+                if (val == NULL) {
+                    val = xmlStrdup(BAD_CAST "");
+                }
+                if (val == NULL) {
+                    VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
+                    return (-1);
+                }
+                cur = val;
+                while (*cur != 0) {
+                    if (IS_BLANK_CH(*cur)) {
+                        *cur = 0;
+                        cur++;
+#ifdef DEBUG_LIST
+                        nb_values++;
+#endif
+                        while (IS_BLANK_CH(*cur))
+                            *cur++ = 0;
+                    } else
+                        cur++;
+                }
+#ifdef DEBUG_LIST
+                xmlGenericError(xmlGenericErrorContext,
+                                "list value: '%s' found %d items\n",
+                                oldvalue, nb_values);
+                nb_values = 0;
+#endif
+                ctxt->state->endvalue = cur;
+                cur = val;
+                while ((*cur == 0) && (cur != ctxt->state->endvalue))
+                    cur++;
+
+                ctxt->state->value = cur;
+
+                while (list != NULL) {
+                    if (ctxt->state->value == ctxt->state->endvalue)
+                        ctxt->state->value = NULL;
+                    ret = xmlRelaxNGValidateValue(ctxt, list);
+                    if (ret != 0) {
+#ifdef DEBUG_LIST
+                        xmlGenericError(xmlGenericErrorContext,
+                                        "Failed to validate value: '%s' with %d rule\n",
+                                        ctxt->state->value, nb_values);
+#endif
+                        break;
+                    }
+#ifdef DEBUG_LIST
+                    nb_values++;
+#endif
+                    list = list->next;
+                }
+
+                if ((ret == 0) && (ctxt->state->value != NULL) &&
+                    (ctxt->state->value != ctxt->state->endvalue)) {
+                    VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA,
+                               ctxt->state->value);
+                    ret = -1;
+                }
+                xmlFree(val);
+                ctxt->state->value = oldvalue;
+                ctxt->state->endvalue = oldend;
+                break;
+            }
+        case XML_RELAXNG_ONEORMORE:
+            ret = xmlRelaxNGValidateValueList(ctxt, define->content);
+            if (ret != 0) {
+                break;
+            }
+            /* no break on purpose */
+        case XML_RELAXNG_ZEROORMORE:{
+                xmlChar *cur, *temp;
+
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+                cur = ctxt->state->value;
+                temp = NULL;
+                while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
+                       (temp != cur)) {
+                    temp = cur;
+                    ret =
+                        xmlRelaxNGValidateValueList(ctxt, define->content);
+                    if (ret != 0) {
+                        ctxt->state->value = temp;
+                        ret = 0;
+                        break;
+                    }
+                    cur = ctxt->state->value;
+                }
+                ctxt->flags = oldflags;
+		if (ctxt->errNr > 0)
+		    xmlRelaxNGPopErrors(ctxt, 0);
+                break;
+            }
+        case XML_RELAXNG_EXCEPT:{
+                xmlRelaxNGDefinePtr list;
+
+                list = define->content;
+                while (list != NULL) {
+                    ret = xmlRelaxNGValidateValue(ctxt, list);
+                    if (ret == 0) {
+                        ret = -1;
+                        break;
+                    } else
+                        ret = 0;
+                    list = list->next;
+                }
+                break;
+            }
+        case XML_RELAXNG_DEF:
+        case XML_RELAXNG_GROUP:{
+                xmlRelaxNGDefinePtr list;
+
+                list = define->content;
+                while (list != NULL) {
+                    ret = xmlRelaxNGValidateValue(ctxt, list);
+                    if (ret != 0) {
+                        ret = -1;
+                        break;
+                    } else
+                        ret = 0;
+                    list = list->next;
+                }
+                break;
+            }
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_PARENTREF:
+	    if (define->content == NULL) {
+                VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+                ret = -1;
+	    } else {
+                ret = xmlRelaxNGValidateValue(ctxt, define->content);
+            }
+            break;
+        default:
+            TODO ret = -1;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateValueContent:
+ * @ctxt:  a Relax-NG validation context
+ * @defines:  the list of definitions to verify
+ *
+ * Validate the given definitions for the current value
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,
+                               xmlRelaxNGDefinePtr defines)
+{
+    int ret = 0;
+
+    while (defines != NULL) {
+        ret = xmlRelaxNGValidateValue(ctxt, defines);
+        if (ret != 0)
+            break;
+        defines = defines->next;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGAttributeMatch:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to check
+ * @prop:  the attribute
+ *
+ * Check if the attribute matches the definition nameClass
+ *
+ * Returns 1 if the attribute matches, 0 if no, or -1 in case of error
+ */
+static int
+xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGDefinePtr define, xmlAttrPtr prop)
+{
+    int ret;
+
+    if (define->name != NULL) {
+        if (!xmlStrEqual(define->name, prop->name))
+            return (0);
+    }
+    if (define->ns != NULL) {
+        if (define->ns[0] == 0) {
+            if (prop->ns != NULL)
+                return (0);
+        } else {
+            if ((prop->ns == NULL) ||
+                (!xmlStrEqual(define->ns, prop->ns->href)))
+                return (0);
+        }
+    }
+    if (define->nameClass == NULL)
+        return (1);
+    define = define->nameClass;
+    if (define->type == XML_RELAXNG_EXCEPT) {
+        xmlRelaxNGDefinePtr list;
+
+        list = define->content;
+        while (list != NULL) {
+            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
+            if (ret == 1)
+                return (0);
+            if (ret < 0)
+                return (ret);
+            list = list->next;
+        }
+    } else {
+    TODO}
+    return (1);
+}
+
+/**
+ * xmlRelaxNGValidateAttribute:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to verify
+ *
+ * Validate the given attribute definition for that node
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
+                            xmlRelaxNGDefinePtr define)
+{
+    int ret = 0, i;
+    xmlChar *value, *oldvalue;
+    xmlAttrPtr prop = NULL, tmp;
+    xmlNodePtr oldseq;
+
+    if (ctxt->state->nbAttrLeft <= 0)
+        return (-1);
+    if (define->name != NULL) {
+        for (i = 0; i < ctxt->state->nbAttrs; i++) {
+            tmp = ctxt->state->attrs[i];
+            if ((tmp != NULL) && (xmlStrEqual(define->name, tmp->name))) {
+                if ((((define->ns == NULL) || (define->ns[0] == 0)) &&
+                     (tmp->ns == NULL)) ||
+                    ((tmp->ns != NULL) &&
+                     (xmlStrEqual(define->ns, tmp->ns->href)))) {
+                    prop = tmp;
+                    break;
+                }
+            }
+        }
+        if (prop != NULL) {
+            value = xmlNodeListGetString(prop->doc, prop->children, 1);
+            oldvalue = ctxt->state->value;
+            oldseq = ctxt->state->seq;
+            ctxt->state->seq = (xmlNodePtr) prop;
+            ctxt->state->value = value;
+            ctxt->state->endvalue = NULL;
+            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
+            if (ctxt->state->value != NULL)
+                value = ctxt->state->value;
+            if (value != NULL)
+                xmlFree(value);
+            ctxt->state->value = oldvalue;
+            ctxt->state->seq = oldseq;
+            if (ret == 0) {
+                /*
+                 * flag the attribute as processed
+                 */
+                ctxt->state->attrs[i] = NULL;
+                ctxt->state->nbAttrLeft--;
+            }
+        } else {
+            ret = -1;
+        }
+#ifdef DEBUG
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlRelaxNGValidateAttribute(%s): %d\n",
+                        define->name, ret);
+#endif
+    } else {
+        for (i = 0; i < ctxt->state->nbAttrs; i++) {
+            tmp = ctxt->state->attrs[i];
+            if ((tmp != NULL) &&
+                (xmlRelaxNGAttributeMatch(ctxt, define, tmp) == 1)) {
+                prop = tmp;
+                break;
+            }
+        }
+        if (prop != NULL) {
+            value = xmlNodeListGetString(prop->doc, prop->children, 1);
+            oldvalue = ctxt->state->value;
+            oldseq = ctxt->state->seq;
+            ctxt->state->seq = (xmlNodePtr) prop;
+            ctxt->state->value = value;
+            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
+            if (ctxt->state->value != NULL)
+                value = ctxt->state->value;
+            if (value != NULL)
+                xmlFree(value);
+            ctxt->state->value = oldvalue;
+            ctxt->state->seq = oldseq;
+            if (ret == 0) {
+                /*
+                 * flag the attribute as processed
+                 */
+                ctxt->state->attrs[i] = NULL;
+                ctxt->state->nbAttrLeft--;
+            }
+        } else {
+            ret = -1;
+        }
+#ifdef DEBUG
+        if (define->ns != NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlRelaxNGValidateAttribute(nsName ns = %s): %d\n",
+                            define->ns, ret);
+        } else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlRelaxNGValidateAttribute(anyName): %d\n",
+                            ret);
+        }
+#endif
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateAttributeList:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the list of definition to verify
+ *
+ * Validate the given node against the list of attribute definitions
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
+                                xmlRelaxNGDefinePtr defines)
+{
+    int ret = 0, res;
+    int needmore = 0;
+    xmlRelaxNGDefinePtr cur;
+
+    cur = defines;
+    while (cur != NULL) {
+        if (cur->type == XML_RELAXNG_ATTRIBUTE) {
+            if (xmlRelaxNGValidateAttribute(ctxt, cur) != 0)
+                ret = -1;
+        } else
+            needmore = 1;
+        cur = cur->next;
+    }
+    if (!needmore)
+        return (ret);
+    cur = defines;
+    while (cur != NULL) {
+        if (cur->type != XML_RELAXNG_ATTRIBUTE) {
+            if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
+                res = xmlRelaxNGValidateDefinition(ctxt, cur);
+                if (res < 0)
+                    ret = -1;
+            } else {
+                VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
+                return (-1);
+            }
+            if (res == -1)      /* continues on -2 */
+                break;
+        }
+        cur = cur->next;
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGNodeMatchesList:
+ * @node:  the node
+ * @list:  a NULL terminated array of definitions
+ *
+ * Check if a node can be matched by one of the definitions
+ *
+ * Returns 1 if matches 0 otherwise
+ */
+static int
+xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list)
+{
+    xmlRelaxNGDefinePtr cur;
+    int i = 0, tmp;
+
+    if ((node == NULL) || (list == NULL))
+        return (0);
+
+    cur = list[i++];
+    while (cur != NULL) {
+        if ((node->type == XML_ELEMENT_NODE) &&
+            (cur->type == XML_RELAXNG_ELEMENT)) {
+            tmp = xmlRelaxNGElementMatch(NULL, cur, node);
+            if (tmp == 1)
+                return (1);
+        } else if (((node->type == XML_TEXT_NODE) ||
+                    (node->type == XML_CDATA_SECTION_NODE)) &&
+                   (cur->type == XML_RELAXNG_TEXT)) {
+            return (1);
+        }
+        cur = list[i++];
+    }
+    return (0);
+}
+
+/**
+ * xmlRelaxNGValidateInterleave:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to verify
+ *
+ * Validate an interleave definition for a node.
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
+                             xmlRelaxNGDefinePtr define)
+{
+    int ret = 0, i, nbgroups;
+    int errNr = ctxt->errNr;
+    int oldflags;
+
+    xmlRelaxNGValidStatePtr oldstate;
+    xmlRelaxNGPartitionPtr partitions;
+    xmlRelaxNGInterleaveGroupPtr group = NULL;
+    xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
+    xmlNodePtr *list = NULL, *lasts = NULL;
+
+    if (define->data != NULL) {
+        partitions = (xmlRelaxNGPartitionPtr) define->data;
+        nbgroups = partitions->nbgroups;
+    } else {
+        VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
+        return (-1);
+    }
+    /*
+     * Optimizations for MIXED
+     */
+    oldflags = ctxt->flags;
+    if (define->dflags & IS_MIXED) {
+        ctxt->flags |= FLAGS_MIXED_CONTENT;
+        if (nbgroups == 2) {
+            /*
+             * this is a pure <mixed> case
+             */
+            if (ctxt->state != NULL)
+                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
+                                                         ctxt->state->seq);
+            if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
+                ret = xmlRelaxNGValidateDefinition(ctxt,
+                                                   partitions->groups[1]->
+                                                   rule);
+            else
+                ret = xmlRelaxNGValidateDefinition(ctxt,
+                                                   partitions->groups[0]->
+                                                   rule);
+            if (ret == 0) {
+                if (ctxt->state != NULL)
+                    ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
+                                                             ctxt->state->
+                                                             seq);
+            }
+            ctxt->flags = oldflags;
+            return (ret);
+        }
+    }
+
+    /*
+     * Build arrays to store the first and last node of the chain
+     * pertaining to each group
+     */
+    list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
+    if (list == NULL) {
+        xmlRngVErrMemory(ctxt, "validating\n");
+        return (-1);
+    }
+    memset(list, 0, nbgroups * sizeof(xmlNodePtr));
+    lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
+    if (lasts == NULL) {
+        xmlRngVErrMemory(ctxt, "validating\n");
+        return (-1);
+    }
+    memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));
+
+    /*
+     * Walk the sequence of children finding the right group and
+     * sorting them in sequences.
+     */
+    cur = ctxt->state->seq;
+    cur = xmlRelaxNGSkipIgnored(ctxt, cur);
+    start = cur;
+    while (cur != NULL) {
+        ctxt->state->seq = cur;
+        if ((partitions->triage != NULL) &&
+            (partitions->flags & IS_DETERMINIST)) {
+            void *tmp = NULL;
+
+            if ((cur->type == XML_TEXT_NODE) ||
+                (cur->type == XML_CDATA_SECTION_NODE)) {
+                tmp = xmlHashLookup2(partitions->triage, BAD_CAST "#text",
+                                     NULL);
+            } else if (cur->type == XML_ELEMENT_NODE) {
+                if (cur->ns != NULL) {
+                    tmp = xmlHashLookup2(partitions->triage, cur->name,
+                                         cur->ns->href);
+                    if (tmp == NULL)
+                        tmp = xmlHashLookup2(partitions->triage,
+                                             BAD_CAST "#any",
+                                             cur->ns->href);
+                } else
+                    tmp =
+                        xmlHashLookup2(partitions->triage, cur->name,
+                                       NULL);
+                if (tmp == NULL)
+                    tmp =
+                        xmlHashLookup2(partitions->triage, BAD_CAST "#any",
+                                       NULL);
+            }
+
+            if (tmp == NULL) {
+                i = nbgroups;
+            } else {
+                i = ((long) tmp) - 1;
+                if (partitions->flags & IS_NEEDCHECK) {
+                    group = partitions->groups[i];
+                    if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
+                        i = nbgroups;
+                }
+            }
+        } else {
+            for (i = 0; i < nbgroups; i++) {
+                group = partitions->groups[i];
+                if (group == NULL)
+                    continue;
+                if (xmlRelaxNGNodeMatchesList(cur, group->defs))
+                    break;
+            }
+        }
+        /*
+         * We break as soon as an element not matched is found
+         */
+        if (i >= nbgroups) {
+            break;
+        }
+        if (lasts[i] != NULL) {
+            lasts[i]->next = cur;
+            lasts[i] = cur;
+        } else {
+            list[i] = cur;
+            lasts[i] = cur;
+        }
+        if (cur->next != NULL)
+            lastchg = cur->next;
+        else
+            lastchg = cur;
+        cur = xmlRelaxNGSkipIgnored(ctxt, cur->next);
+    }
+    if (ret != 0) {
+        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
+        ret = -1;
+        goto done;
+    }
+    lastelem = cur;
+    oldstate = ctxt->state;
+    for (i = 0; i < nbgroups; i++) {
+        ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
+        group = partitions->groups[i];
+        if (lasts[i] != NULL) {
+            last = lasts[i]->next;
+            lasts[i]->next = NULL;
+        }
+        ctxt->state->seq = list[i];
+        ret = xmlRelaxNGValidateDefinition(ctxt, group->rule);
+        if (ret != 0)
+            break;
+        if (ctxt->state != NULL) {
+            cur = ctxt->state->seq;
+            cur = xmlRelaxNGSkipIgnored(ctxt, cur);
+            xmlRelaxNGFreeValidState(ctxt, oldstate);
+            oldstate = ctxt->state;
+            ctxt->state = NULL;
+            if (cur != NULL) {
+                VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+                ret = -1;
+                ctxt->state = oldstate;
+                goto done;
+            }
+        } else if (ctxt->states != NULL) {
+            int j;
+            int found = 0;
+	    int best = -1;
+	    int lowattr = -1;
+
+	    /*
+	     * PBM: what happen if there is attributes checks in the interleaves
+	     */
+
+            for (j = 0; j < ctxt->states->nbState; j++) {
+                cur = ctxt->states->tabState[j]->seq;
+                cur = xmlRelaxNGSkipIgnored(ctxt, cur);
+                if (cur == NULL) {
+		    if (found == 0) {
+		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
+			best = j;
+		    }
+                    found = 1;
+		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
+		        /* try  to keep the latest one to mach old heuristic */
+		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
+			best = j;
+		    }
+                    if (lowattr == 0)
+		        break;
+                } else if (found == 0) {
+                    if (lowattr == -1) {
+		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
+			best = j;
+		    } else
+		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr)  {
+		        /* try  to keep the latest one to mach old heuristic */
+		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
+			best = j;
+		    }
+		}
+            }
+	    /*
+	     * BIG PBM: here we pick only one restarting point :-(
+	     */
+            if (ctxt->states->nbState > 0) {
+                xmlRelaxNGFreeValidState(ctxt, oldstate);
+		if (best != -1) {
+		    oldstate = ctxt->states->tabState[best];
+		    ctxt->states->tabState[best] = NULL;
+		} else {
+		    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++) {
+                xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]);
+            }
+            xmlRelaxNGFreeStates(ctxt, ctxt->states);
+            ctxt->states = NULL;
+            if (found == 0) {
+                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;
+            }
+        } else {
+            ret = -1;
+            break;
+        }
+        if (lasts[i] != NULL) {
+            lasts[i]->next = last;
+        }
+    }
+    if (ctxt->state != NULL)
+        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+    ctxt->state = oldstate;
+    ctxt->state->seq = lastelem;
+    if (ret != 0) {
+        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
+        ret = -1;
+        goto done;
+    }
+
+  done:
+    ctxt->flags = oldflags;
+    /*
+     * builds the next links chain from the prev one
+     */
+    cur = lastchg;
+    while (cur != NULL) {
+        if ((cur == start) || (cur->prev == NULL))
+            break;
+        cur->prev->next = cur;
+        cur = cur->prev;
+    }
+    if (ret == 0) {
+        if (ctxt->errNr > errNr)
+            xmlRelaxNGPopErrors(ctxt, errNr);
+    }
+
+    xmlFree(list);
+    xmlFree(lasts);
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateDefinitionList:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the list of definition to verify
+ *
+ * Validate the given node content against the (list) of definitions
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,
+                                 xmlRelaxNGDefinePtr defines)
+{
+    int ret = 0, res;
+
+
+    if (defines == NULL) {
+        VALID_ERR2(XML_RELAXNG_ERR_INTERNAL,
+                   BAD_CAST "NULL definition list");
+        return (-1);
+    }
+    while (defines != NULL) {
+        if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
+            res = xmlRelaxNGValidateDefinition(ctxt, defines);
+            if (res < 0)
+                ret = -1;
+        } else {
+            VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
+            return (-1);
+        }
+        if (res == -1)          /* continues on -2 */
+            break;
+        defines = defines->next;
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGElementMatch:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to check
+ * @elem:  the element
+ *
+ * Check if the element matches the definition nameClass
+ *
+ * Returns 1 if the element matches, 0 if no, or -1 in case of error
+ */
+static int
+xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
+                       xmlRelaxNGDefinePtr define, xmlNodePtr elem)
+{
+    int ret = 0, oldflags = 0;
+
+    if (define->name != NULL) {
+        if (!xmlStrEqual(elem->name, define->name)) {
+            VALID_ERR3(XML_RELAXNG_ERR_ELEMNAME, define->name, elem->name);
+            return (0);
+        }
+    }
+    if ((define->ns != NULL) && (define->ns[0] != 0)) {
+        if (elem->ns == NULL) {
+            VALID_ERR2(XML_RELAXNG_ERR_ELEMNONS, elem->name);
+            return (0);
+        } else if (!xmlStrEqual(elem->ns->href, define->ns)) {
+            VALID_ERR3(XML_RELAXNG_ERR_ELEMWRONGNS,
+                       elem->name, define->ns);
+            return (0);
+        }
+    } else if ((elem->ns != NULL) && (define->ns != NULL) &&
+               (define->name == NULL)) {
+        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, elem->name);
+        return (0);
+    } else if ((elem->ns != NULL) && (define->name != NULL)) {
+        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, define->name);
+        return (0);
+    }
+
+    if (define->nameClass == NULL)
+        return (1);
+
+    define = define->nameClass;
+    if (define->type == XML_RELAXNG_EXCEPT) {
+        xmlRelaxNGDefinePtr list;
+
+        if (ctxt != NULL) {
+            oldflags = ctxt->flags;
+            ctxt->flags |= FLAGS_IGNORABLE;
+        }
+
+        list = define->content;
+        while (list != NULL) {
+            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
+            if (ret == 1) {
+                if (ctxt != NULL)
+                    ctxt->flags = oldflags;
+                return (0);
+            }
+            if (ret < 0) {
+                if (ctxt != NULL)
+                    ctxt->flags = oldflags;
+                return (ret);
+            }
+            list = list->next;
+        }
+        ret = 1;
+        if (ctxt != NULL) {
+            ctxt->flags = oldflags;
+        }
+    } else if (define->type == XML_RELAXNG_CHOICE) {
+        xmlRelaxNGDefinePtr list;
+
+        if (ctxt != NULL) {
+            oldflags = ctxt->flags;
+            ctxt->flags |= FLAGS_IGNORABLE;
+        }
+
+        list = define->nameClass;
+        while (list != NULL) {
+            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
+            if (ret == 1) {
+                if (ctxt != NULL)
+                    ctxt->flags = oldflags;
+                return (1);
+            }
+            if (ret < 0) {
+                if (ctxt != NULL)
+                    ctxt->flags = oldflags;
+                return (ret);
+            }
+            list = list->next;
+        }
+        if (ctxt != NULL) {
+            if (ret != 0) {
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                    xmlRelaxNGDumpValidError(ctxt);
+            } else {
+                if (ctxt->errNr > 0)
+                    xmlRelaxNGPopErrors(ctxt, 0);
+            }
+        }
+        ret = 0;
+        if (ctxt != NULL) {
+            ctxt->flags = oldflags;
+        }
+    } else {
+        TODO ret = -1;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGBestState:
+ * @ctxt:  a Relax-NG validation context
+ *
+ * Find the "best" state in the ctxt->states list of states to report
+ * errors about. I.e. a state with no element left in the child list
+ * or the one with the less attributes left.
+ * This is called only if a falidation error was detected
+ *
+ * Returns the index of the "best" state or -1 in case of error
+ */
+static int
+xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    xmlRelaxNGValidStatePtr state;
+    int i, tmp;
+    int best = -1;
+    int value = 1000000;
+
+    if ((ctxt == NULL) || (ctxt->states == NULL) ||
+        (ctxt->states->nbState <= 0))
+        return (-1);
+
+    for (i = 0; i < ctxt->states->nbState; i++) {
+        state = ctxt->states->tabState[i];
+        if (state == NULL)
+            continue;
+        if (state->seq != NULL) {
+            if ((best == -1) || (value > 100000)) {
+                value = 100000;
+                best = i;
+            }
+        } else {
+            tmp = state->nbAttrLeft;
+            if ((best == -1) || (value > tmp)) {
+                value = tmp;
+                best = i;
+            }
+        }
+    }
+    return (best);
+}
+
+/**
+ * xmlRelaxNGLogBestError:
+ * @ctxt:  a Relax-NG validation context
+ *
+ * Find the "best" state in the ctxt->states list of states to report
+ * errors about and log it.
+ */
+static void
+xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    int best;
+
+    if ((ctxt == NULL) || (ctxt->states == NULL) ||
+        (ctxt->states->nbState <= 0))
+        return;
+
+    best = xmlRelaxNGBestState(ctxt);
+    if ((best >= 0) && (best < ctxt->states->nbState)) {
+        ctxt->state = ctxt->states->tabState[best];
+
+        xmlRelaxNGValidateElementEnd(ctxt, 1);
+    }
+}
+
+/**
+ * xmlRelaxNGValidateElementEnd:
+ * @ctxt:  a Relax-NG validation context
+ * @dolog:  indicate that error logging should be done
+ *
+ * Validate the end of the element, implements check that
+ * there is nothing left not consumed in the element content
+ * or in the attribute list.
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int dolog)
+{
+    int i;
+    xmlRelaxNGValidStatePtr state;
+
+    state = ctxt->state;
+    if (state->seq != NULL) {
+        state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
+        if (state->seq != NULL) {
+            if (dolog) {
+                VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
+                           state->node->name, state->seq->name);
+            }
+            return (-1);
+        }
+    }
+    for (i = 0; i < state->nbAttrs; i++) {
+        if (state->attrs[i] != NULL) {
+            if (dolog) {
+                VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
+                           state->attrs[i]->name, state->node->name);
+            }
+            return (-1 - i);
+        }
+    }
+    return (0);
+}
+
+/**
+ * xmlRelaxNGValidateState:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to verify
+ *
+ * Validate the current state against the definition
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
+                        xmlRelaxNGDefinePtr define)
+{
+    xmlNodePtr node;
+    int ret = 0, i, tmp, oldflags, errNr;
+    xmlRelaxNGValidStatePtr oldstate = NULL, state;
+
+    if (define == NULL) {
+        VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+        return (-1);
+    }
+
+    if (ctxt->state != NULL) {
+        node = ctxt->state->seq;
+    } else {
+        node = NULL;
+    }
+#ifdef DEBUG
+    for (i = 0; i < ctxt->depth; i++)
+        xmlGenericError(xmlGenericErrorContext, " ");
+    xmlGenericError(xmlGenericErrorContext,
+                    "Start validating %s ", xmlRelaxNGDefName(define));
+    if (define->name != NULL)
+        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
+    if ((node != NULL) && (node->name != NULL))
+        xmlGenericError(xmlGenericErrorContext, "on %s\n", node->name);
+    else
+        xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+    ctxt->depth++;
+    switch (define->type) {
+        case XML_RELAXNG_EMPTY:
+            node = xmlRelaxNGSkipIgnored(ctxt, node);
+            ret = 0;
+            break;
+        case XML_RELAXNG_NOT_ALLOWED:
+            ret = -1;
+            break;
+        case XML_RELAXNG_TEXT:
+            while ((node != NULL) &&
+                   ((node->type == XML_TEXT_NODE) ||
+                    (node->type == XML_COMMENT_NODE) ||
+                    (node->type == XML_PI_NODE) ||
+                    (node->type == XML_CDATA_SECTION_NODE)))
+                node = node->next;
+            ctxt->state->seq = node;
+            break;
+        case XML_RELAXNG_ELEMENT:
+            errNr = ctxt->errNr;
+            node = xmlRelaxNGSkipIgnored(ctxt, node);
+            if (node == NULL) {
+                VALID_ERR2(XML_RELAXNG_ERR_NOELEM, define->name);
+                ret = -1;
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                    xmlRelaxNGDumpValidError(ctxt);
+                break;
+            }
+            if (node->type != XML_ELEMENT_NODE) {
+                VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
+                ret = -1;
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                    xmlRelaxNGDumpValidError(ctxt);
+                break;
+            }
+            /*
+             * This node was already validated successfully against
+             * this definition.
+             */
+            if (node->psvi == define) {
+                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
+                if (ctxt->errNr > errNr)
+                    xmlRelaxNGPopErrors(ctxt, errNr);
+                if (ctxt->errNr != 0) {
+                    while ((ctxt->err != NULL) &&
+                           (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME)
+                             && (xmlStrEqual(ctxt->err->arg2, node->name)))
+                            ||
+                            ((ctxt->err->err ==
+                              XML_RELAXNG_ERR_ELEMEXTRANS)
+                             && (xmlStrEqual(ctxt->err->arg1, node->name)))
+                            || (ctxt->err->err == XML_RELAXNG_ERR_NOELEM)
+                            || (ctxt->err->err ==
+                                XML_RELAXNG_ERR_NOTELEM)))
+                        xmlRelaxNGValidErrorPop(ctxt);
+                }
+                break;
+            }
+
+            ret = xmlRelaxNGElementMatch(ctxt, define, node);
+            if (ret <= 0) {
+                ret = -1;
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                    xmlRelaxNGDumpValidError(ctxt);
+                break;
+            }
+            ret = 0;
+            if (ctxt->errNr != 0) {
+                if (ctxt->errNr > errNr)
+                    xmlRelaxNGPopErrors(ctxt, errNr);
+                while ((ctxt->err != NULL) &&
+                       (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
+                         (xmlStrEqual(ctxt->err->arg2, node->name))) ||
+                        ((ctxt->err->err == XML_RELAXNG_ERR_ELEMEXTRANS) &&
+                         (xmlStrEqual(ctxt->err->arg1, node->name))) ||
+                        (ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
+                        (ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
+                    xmlRelaxNGValidErrorPop(ctxt);
+            }
+            errNr = ctxt->errNr;
+
+            oldflags = ctxt->flags;
+            if (ctxt->flags & FLAGS_MIXED_CONTENT) {
+                ctxt->flags -= FLAGS_MIXED_CONTENT;
+            }
+            state = xmlRelaxNGNewValidState(ctxt, node);
+            if (state == NULL) {
+                ret = -1;
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
+                    xmlRelaxNGDumpValidError(ctxt);
+                break;
+            }
+
+            oldstate = ctxt->state;
+            ctxt->state = state;
+            if (define->attrs != NULL) {
+                tmp = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
+                if (tmp != 0) {
+                    ret = -1;
+                    VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
+                }
+            }
+            if (define->contModel != NULL) {
+                xmlRelaxNGValidStatePtr nstate, tmpstate = ctxt->state;
+                xmlRelaxNGStatesPtr tmpstates = ctxt->states;
+                xmlNodePtr nseq;
+
+                nstate = xmlRelaxNGNewValidState(ctxt, node);
+                ctxt->state = nstate;
+                ctxt->states = NULL;
+
+                tmp = xmlRelaxNGValidateCompiledContent(ctxt,
+                                                        define->contModel,
+                                                        ctxt->state->seq);
+                nseq = ctxt->state->seq;
+                ctxt->state = tmpstate;
+                ctxt->states = tmpstates;
+                xmlRelaxNGFreeValidState(ctxt, nstate);
+
+#ifdef DEBUG_COMPILE
+                xmlGenericError(xmlGenericErrorContext,
+                                "Validating content of '%s' : %d\n",
+                                define->name, tmp);
+#endif
+                if (tmp != 0)
+                    ret = -1;
+
+                if (ctxt->states != NULL) {
+                    tmp = -1;
+
+                    for (i = 0; i < ctxt->states->nbState; i++) {
+                        state = ctxt->states->tabState[i];
+                        ctxt->state = state;
+                        ctxt->state->seq = nseq;
+
+                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
+                            tmp = 0;
+                            break;
+                        }
+                    }
+                    if (tmp != 0) {
+                        /*
+                         * validation error, log the message for the "best" one
+                         */
+                        ctxt->flags |= FLAGS_IGNORABLE;
+                        xmlRelaxNGLogBestError(ctxt);
+                    }
+                    for (i = 0; i < ctxt->states->nbState; i++) {
+                        xmlRelaxNGFreeValidState(ctxt,
+                                                 ctxt->states->
+                                                 tabState[i]);
+                    }
+                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
+                    ctxt->flags = oldflags;
+                    ctxt->states = NULL;
+                    if ((ret == 0) && (tmp == -1))
+                        ret = -1;
+                } else {
+                    state = ctxt->state;
+		    if (ctxt->state != NULL)
+			ctxt->state->seq = nseq;
+                    if (ret == 0)
+                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
+                    xmlRelaxNGFreeValidState(ctxt, state);
+                }
+            } else {
+                if (define->content != NULL) {
+                    tmp = xmlRelaxNGValidateDefinitionList(ctxt,
+                                                           define->
+                                                           content);
+                    if (tmp != 0) {
+                        ret = -1;
+                        if (ctxt->state == NULL) {
+                            ctxt->state = oldstate;
+                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
+                                       node->name);
+                            ctxt->state = NULL;
+                        } else {
+                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
+                                       node->name);
+                        }
+
+                    }
+                }
+                if (ctxt->states != NULL) {
+                    tmp = -1;
+
+                    for (i = 0; i < ctxt->states->nbState; i++) {
+                        state = ctxt->states->tabState[i];
+                        ctxt->state = state;
+
+                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
+                            tmp = 0;
+                            break;
+                        }
+                    }
+                    if (tmp != 0) {
+                        /*
+                         * validation error, log the message for the "best" one
+                         */
+                        ctxt->flags |= FLAGS_IGNORABLE;
+                        xmlRelaxNGLogBestError(ctxt);
+                    }
+                    for (i = 0; i < ctxt->states->nbState; i++) {
+                        xmlRelaxNGFreeValidState(ctxt,
+                                                 ctxt->states->tabState[i]);
+                        ctxt->states->tabState[i] = NULL;
+                    }
+                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
+                    ctxt->flags = oldflags;
+                    ctxt->states = NULL;
+                    if ((ret == 0) && (tmp == -1))
+                        ret = -1;
+                } else {
+                    state = ctxt->state;
+                    if (ret == 0)
+                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
+                    xmlRelaxNGFreeValidState(ctxt, state);
+                }
+            }
+            if (ret == 0) {
+                node->psvi = define;
+            }
+            ctxt->flags = oldflags;
+            ctxt->state = oldstate;
+            if (oldstate != NULL)
+                oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
+            if (ret != 0) {
+                if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
+                    xmlRelaxNGDumpValidError(ctxt);
+                    ret = 0;
+#if 0
+                } else {
+                    ret = -2;
+#endif
+                }
+            } else {
+                if (ctxt->errNr > errNr)
+                    xmlRelaxNGPopErrors(ctxt, errNr);
+            }
+
+#ifdef DEBUG
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlRelaxNGValidateDefinition(): validated %s : %d",
+                            node->name, ret);
+            if (oldstate == NULL)
+                xmlGenericError(xmlGenericErrorContext, ": no state\n");
+            else if (oldstate->seq == NULL)
+                xmlGenericError(xmlGenericErrorContext, ": done\n");
+            else if (oldstate->seq->type == XML_ELEMENT_NODE)
+                xmlGenericError(xmlGenericErrorContext, ": next elem %s\n",
+                                oldstate->seq->name);
+            else
+                xmlGenericError(xmlGenericErrorContext, ": next %s %d\n",
+                                oldstate->seq->name, oldstate->seq->type);
+#endif
+            break;
+        case XML_RELAXNG_OPTIONAL:{
+                errNr = ctxt->errNr;
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+                oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
+                ret =
+                    xmlRelaxNGValidateDefinitionList(ctxt,
+                                                     define->content);
+                if (ret != 0) {
+                    if (ctxt->state != NULL)
+                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+                    ctxt->state = oldstate;
+                    ctxt->flags = oldflags;
+                    ret = 0;
+                    if (ctxt->errNr > errNr)
+                        xmlRelaxNGPopErrors(ctxt, errNr);
+                    break;
+                }
+                if (ctxt->states != NULL) {
+                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
+                } else {
+                    ctxt->states = xmlRelaxNGNewStates(ctxt, 1);
+                    if (ctxt->states == NULL) {
+                        xmlRelaxNGFreeValidState(ctxt, oldstate);
+                        ctxt->flags = oldflags;
+                        ret = -1;
+                        if (ctxt->errNr > errNr)
+                            xmlRelaxNGPopErrors(ctxt, errNr);
+                        break;
+                    }
+                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
+                    xmlRelaxNGAddStates(ctxt, ctxt->states, ctxt->state);
+                    ctxt->state = NULL;
+                }
+                ctxt->flags = oldflags;
+                ret = 0;
+                if (ctxt->errNr > errNr)
+                    xmlRelaxNGPopErrors(ctxt, errNr);
+                break;
+            }
+        case XML_RELAXNG_ONEORMORE:
+            errNr = ctxt->errNr;
+            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
+            if (ret != 0) {
+                break;
+            }
+            if (ctxt->errNr > errNr)
+                xmlRelaxNGPopErrors(ctxt, errNr);
+            /* no break on purpose */
+        case XML_RELAXNG_ZEROORMORE:{
+                int progress;
+                xmlRelaxNGStatesPtr states = NULL, res = NULL;
+                int base, j;
+
+                errNr = ctxt->errNr;
+                res = xmlRelaxNGNewStates(ctxt, 1);
+                if (res == NULL) {
+                    ret = -1;
+                    break;
+                }
+                /*
+                 * All the input states are also exit states
+                 */
+                if (ctxt->state != NULL) {
+                    xmlRelaxNGAddStates(ctxt, res,
+                                        xmlRelaxNGCopyValidState(ctxt,
+                                                                 ctxt->
+                                                                 state));
+                } else {
+                    for (j = 0; j < ctxt->states->nbState; j++) {
+                        xmlRelaxNGAddStates(ctxt, res,
+                            xmlRelaxNGCopyValidState(ctxt,
+                                            ctxt->states->tabState[j]));
+                    }
+                }
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+                do {
+                    progress = 0;
+                    base = res->nbState;
+
+                    if (ctxt->states != NULL) {
+                        states = ctxt->states;
+                        for (i = 0; i < states->nbState; i++) {
+                            ctxt->state = states->tabState[i];
+                            ctxt->states = NULL;
+                            ret = xmlRelaxNGValidateDefinitionList(ctxt,
+                                                                   define->
+                                                                   content);
+                            if (ret == 0) {
+                                if (ctxt->state != NULL) {
+                                    tmp = xmlRelaxNGAddStates(ctxt, res,
+                                                              ctxt->state);
+                                    ctxt->state = NULL;
+                                    if (tmp == 1)
+                                        progress = 1;
+                                } else if (ctxt->states != NULL) {
+                                    for (j = 0; j < ctxt->states->nbState;
+                                         j++) {
+                                        tmp =
+                                            xmlRelaxNGAddStates(ctxt, res,
+                                                   ctxt->states->tabState[j]);
+                                        if (tmp == 1)
+                                            progress = 1;
+                                    }
+                                    xmlRelaxNGFreeStates(ctxt,
+                                                         ctxt->states);
+                                    ctxt->states = NULL;
+                                }
+                            } else {
+                                if (ctxt->state != NULL) {
+                                    xmlRelaxNGFreeValidState(ctxt,
+                                                             ctxt->state);
+                                    ctxt->state = NULL;
+                                }
+                            }
+                        }
+                    } else {
+                        ret = xmlRelaxNGValidateDefinitionList(ctxt,
+                                                               define->
+                                                               content);
+                        if (ret != 0) {
+                            xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+                            ctxt->state = NULL;
+                        } else {
+                            base = res->nbState;
+                            if (ctxt->state != NULL) {
+                                tmp = xmlRelaxNGAddStates(ctxt, res,
+                                                          ctxt->state);
+                                ctxt->state = NULL;
+                                if (tmp == 1)
+                                    progress = 1;
+                            } else if (ctxt->states != NULL) {
+                                for (j = 0; j < ctxt->states->nbState; j++) {
+                                    tmp = xmlRelaxNGAddStates(ctxt, res,
+                                               ctxt->states->tabState[j]);
+                                    if (tmp == 1)
+                                        progress = 1;
+                                }
+                                if (states == NULL) {
+                                    states = ctxt->states;
+                                } else {
+                                    xmlRelaxNGFreeStates(ctxt,
+                                                         ctxt->states);
+                                }
+                                ctxt->states = NULL;
+                            }
+                        }
+                    }
+                    if (progress) {
+                        /*
+                         * Collect all the new nodes added at that step
+                         * and make them the new node set
+                         */
+                        if (res->nbState - base == 1) {
+                            ctxt->state = xmlRelaxNGCopyValidState(ctxt,
+                                                                   res->
+                                                                   tabState
+                                                                   [base]);
+                        } else {
+                            if (states == NULL) {
+                                xmlRelaxNGNewStates(ctxt,
+                                                    res->nbState - base);
+			        states = ctxt->states;
+				if (states == NULL) {
+				    progress = 0;
+				    break;
+				}
+                            }
+                            states->nbState = 0;
+                            for (i = base; i < res->nbState; i++)
+                                xmlRelaxNGAddStates(ctxt, states,
+                                                    xmlRelaxNGCopyValidState
+                                                    (ctxt, res->tabState[i]));
+                            ctxt->states = states;
+                        }
+                    }
+                } while (progress == 1);
+                if (states != NULL) {
+                    xmlRelaxNGFreeStates(ctxt, states);
+                }
+                ctxt->states = res;
+                ctxt->flags = oldflags;
+#if 0
+                /*
+                 * errors may have to be propagated back...
+                 */
+                if (ctxt->errNr > errNr)
+                    xmlRelaxNGPopErrors(ctxt, errNr);
+#endif
+                ret = 0;
+                break;
+            }
+        case XML_RELAXNG_CHOICE:{
+                xmlRelaxNGDefinePtr list = NULL;
+                xmlRelaxNGStatesPtr states = NULL;
+
+                node = xmlRelaxNGSkipIgnored(ctxt, node);
+
+                errNr = ctxt->errNr;
+                if ((define->dflags & IS_TRIABLE) && (define->data != NULL) &&
+		    (node != NULL)) {
+		    /*
+		     * node == NULL can't be optimized since IS_TRIABLE
+		     * doesn't account for choice which may lead to
+		     * only attributes.
+		     */
+                    xmlHashTablePtr triage =
+                        (xmlHashTablePtr) define->data;
+
+                    /*
+                     * Something we can optimize cleanly there is only one
+                     * possble branch out !
+                     */
+                    if ((node->type == XML_TEXT_NODE) ||
+                        (node->type == XML_CDATA_SECTION_NODE)) {
+                        list =
+                            xmlHashLookup2(triage, BAD_CAST "#text", NULL);
+                    } else if (node->type == XML_ELEMENT_NODE) {
+                        if (node->ns != NULL) {
+                            list = xmlHashLookup2(triage, node->name,
+                                                  node->ns->href);
+                            if (list == NULL)
+                                list =
+                                    xmlHashLookup2(triage, BAD_CAST "#any",
+                                                   node->ns->href);
+                        } else
+                            list =
+                                xmlHashLookup2(triage, node->name, NULL);
+                        if (list == NULL)
+                            list =
+                                xmlHashLookup2(triage, BAD_CAST "#any",
+                                               NULL);
+                    }
+                    if (list == NULL) {
+                        ret = -1;
+			VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, node->name);
+                        break;
+                    }
+                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
+                    if (ret == 0) {
+                    }
+                    break;
+                }
+
+                list = define->content;
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+
+                while (list != NULL) {
+                    oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
+                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
+                    if (ret == 0) {
+                        if (states == NULL) {
+                            states = xmlRelaxNGNewStates(ctxt, 1);
+                        }
+                        if (ctxt->state != NULL) {
+                            xmlRelaxNGAddStates(ctxt, states, ctxt->state);
+                        } else if (ctxt->states != NULL) {
+                            for (i = 0; i < ctxt->states->nbState; i++) {
+                                xmlRelaxNGAddStates(ctxt, states,
+                                                    ctxt->states->
+                                                    tabState[i]);
+                            }
+                            xmlRelaxNGFreeStates(ctxt, ctxt->states);
+                            ctxt->states = NULL;
+                        }
+                    } else {
+                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+                    }
+                    ctxt->state = oldstate;
+                    list = list->next;
+                }
+                if (states != NULL) {
+                    xmlRelaxNGFreeValidState(ctxt, oldstate);
+                    ctxt->states = states;
+                    ctxt->state = NULL;
+                    ret = 0;
+                } else {
+                    ctxt->states = NULL;
+                }
+                ctxt->flags = oldflags;
+                if (ret != 0) {
+                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
+                        xmlRelaxNGDumpValidError(ctxt);
+                    }
+                } else {
+                    if (ctxt->errNr > errNr)
+                        xmlRelaxNGPopErrors(ctxt, errNr);
+                }
+                break;
+            }
+        case XML_RELAXNG_DEF:
+        case XML_RELAXNG_GROUP:
+            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
+            break;
+        case XML_RELAXNG_INTERLEAVE:
+            ret = xmlRelaxNGValidateInterleave(ctxt, define);
+            break;
+        case XML_RELAXNG_ATTRIBUTE:
+            ret = xmlRelaxNGValidateAttribute(ctxt, define);
+            break;
+        case XML_RELAXNG_START:
+        case XML_RELAXNG_NOOP:
+        case XML_RELAXNG_REF:
+        case XML_RELAXNG_EXTERNALREF:
+        case XML_RELAXNG_PARENTREF:
+            ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
+            break;
+        case XML_RELAXNG_DATATYPE:{
+                xmlNodePtr child;
+                xmlChar *content = NULL;
+
+                child = node;
+                while (child != NULL) {
+                    if (child->type == XML_ELEMENT_NODE) {
+                        VALID_ERR2(XML_RELAXNG_ERR_DATAELEM,
+                                   node->parent->name);
+                        ret = -1;
+                        break;
+                    } else if ((child->type == XML_TEXT_NODE) ||
+                               (child->type == XML_CDATA_SECTION_NODE)) {
+                        content = xmlStrcat(content, child->content);
+                    }
+                    /* TODO: handle entities ... */
+                    child = child->next;
+                }
+                if (ret == -1) {
+                    if (content != NULL)
+                        xmlFree(content);
+                    break;
+                }
+                if (content == NULL) {
+                    content = xmlStrdup(BAD_CAST "");
+                    if (content == NULL) {
+                        xmlRngVErrMemory(ctxt, "validating\n");
+                        ret = -1;
+                        break;
+                    }
+                }
+                ret = xmlRelaxNGValidateDatatype(ctxt, content, define,
+                                                 ctxt->state->seq);
+                if (ret == -1) {
+                    VALID_ERR2(XML_RELAXNG_ERR_DATATYPE, define->name);
+                } else if (ret == 0) {
+                    ctxt->state->seq = NULL;
+                }
+                if (content != NULL)
+                    xmlFree(content);
+                break;
+            }
+        case XML_RELAXNG_VALUE:{
+                xmlChar *content = NULL;
+                xmlChar *oldvalue;
+                xmlNodePtr child;
+
+                child = node;
+                while (child != NULL) {
+                    if (child->type == XML_ELEMENT_NODE) {
+                        VALID_ERR2(XML_RELAXNG_ERR_VALELEM,
+                                   node->parent->name);
+                        ret = -1;
+                        break;
+                    } else if ((child->type == XML_TEXT_NODE) ||
+                               (child->type == XML_CDATA_SECTION_NODE)) {
+                        content = xmlStrcat(content, child->content);
+                    }
+                    /* TODO: handle entities ... */
+                    child = child->next;
+                }
+                if (ret == -1) {
+                    if (content != NULL)
+                        xmlFree(content);
+                    break;
+                }
+                if (content == NULL) {
+                    content = xmlStrdup(BAD_CAST "");
+                    if (content == NULL) {
+                        xmlRngVErrMemory(ctxt, "validating\n");
+                        ret = -1;
+                        break;
+                    }
+                }
+                oldvalue = ctxt->state->value;
+                ctxt->state->value = content;
+                ret = xmlRelaxNGValidateValue(ctxt, define);
+                ctxt->state->value = oldvalue;
+                if (ret == -1) {
+                    VALID_ERR2(XML_RELAXNG_ERR_VALUE, define->name);
+                } else if (ret == 0) {
+                    ctxt->state->seq = NULL;
+                }
+                if (content != NULL)
+                    xmlFree(content);
+                break;
+            }
+        case XML_RELAXNG_LIST:{
+                xmlChar *content;
+                xmlNodePtr child;
+                xmlChar *oldvalue, *oldendvalue;
+                int len;
+
+                /*
+                 * Make sure it's only text nodes
+                 */
+
+                content = NULL;
+                child = node;
+                while (child != NULL) {
+                    if (child->type == XML_ELEMENT_NODE) {
+                        VALID_ERR2(XML_RELAXNG_ERR_LISTELEM,
+                                   node->parent->name);
+                        ret = -1;
+                        break;
+                    } else if ((child->type == XML_TEXT_NODE) ||
+                               (child->type == XML_CDATA_SECTION_NODE)) {
+                        content = xmlStrcat(content, child->content);
+                    }
+                    /* TODO: handle entities ... */
+                    child = child->next;
+                }
+                if (ret == -1) {
+                    if (content != NULL)
+                        xmlFree(content);
+                    break;
+                }
+                if (content == NULL) {
+                    content = xmlStrdup(BAD_CAST "");
+                    if (content == NULL) {
+                        xmlRngVErrMemory(ctxt, "validating\n");
+                        ret = -1;
+                        break;
+                    }
+                }
+                len = xmlStrlen(content);
+                oldvalue = ctxt->state->value;
+                oldendvalue = ctxt->state->endvalue;
+                ctxt->state->value = content;
+                ctxt->state->endvalue = content + len;
+                ret = xmlRelaxNGValidateValue(ctxt, define);
+                ctxt->state->value = oldvalue;
+                ctxt->state->endvalue = oldendvalue;
+                if (ret == -1) {
+                    VALID_ERR(XML_RELAXNG_ERR_LIST);
+                } else if ((ret == 0) && (node != NULL)) {
+                    ctxt->state->seq = node->next;
+                }
+                if (content != NULL)
+                    xmlFree(content);
+                break;
+            }
+        case XML_RELAXNG_EXCEPT:
+        case XML_RELAXNG_PARAM:
+            TODO ret = -1;
+            break;
+    }
+    ctxt->depth--;
+#ifdef DEBUG
+    for (i = 0; i < ctxt->depth; i++)
+        xmlGenericError(xmlGenericErrorContext, " ");
+    xmlGenericError(xmlGenericErrorContext,
+                    "Validating %s ", xmlRelaxNGDefName(define));
+    if (define->name != NULL)
+        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
+    if (ret == 0)
+        xmlGenericError(xmlGenericErrorContext, "suceeded\n");
+    else
+        xmlGenericError(xmlGenericErrorContext, "failed\n");
+#endif
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateDefinition:
+ * @ctxt:  a Relax-NG validation context
+ * @define:  the definition to verify
+ *
+ * Validate the current node lists against the definition
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
+                             xmlRelaxNGDefinePtr define)
+{
+    xmlRelaxNGStatesPtr states, res;
+    int i, j, k, ret, oldflags;
+
+    /*
+     * We should NOT have both ctxt->state and ctxt->states
+     */
+    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
+        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+        ctxt->state = NULL;
+    }
+
+    if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
+        if (ctxt->states != NULL) {
+            ctxt->state = ctxt->states->tabState[0];
+            xmlRelaxNGFreeStates(ctxt, ctxt->states);
+            ctxt->states = NULL;
+        }
+        ret = xmlRelaxNGValidateState(ctxt, define);
+        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
+            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+            ctxt->state = NULL;
+        }
+        if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
+            ctxt->state = ctxt->states->tabState[0];
+            xmlRelaxNGFreeStates(ctxt, ctxt->states);
+            ctxt->states = NULL;
+        }
+        return (ret);
+    }
+
+    states = ctxt->states;
+    ctxt->states = NULL;
+    res = NULL;
+    j = 0;
+    oldflags = ctxt->flags;
+    ctxt->flags |= FLAGS_IGNORABLE;
+    for (i = 0; i < states->nbState; i++) {
+        ctxt->state = states->tabState[i];
+        ctxt->states = NULL;
+        ret = xmlRelaxNGValidateState(ctxt, define);
+        /*
+         * We should NOT have both ctxt->state and ctxt->states
+         */
+        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
+            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+            ctxt->state = NULL;
+        }
+        if (ret == 0) {
+            if (ctxt->states == NULL) {
+                if (res != NULL) {
+                    /* add the state to the container */
+                    xmlRelaxNGAddStates(ctxt, res, ctxt->state);
+                    ctxt->state = NULL;
+                } else {
+                    /* add the state directly in states */
+                    states->tabState[j++] = ctxt->state;
+                    ctxt->state = NULL;
+                }
+            } else {
+                if (res == NULL) {
+                    /* make it the new container and copy other results */
+                    res = ctxt->states;
+                    ctxt->states = NULL;
+                    for (k = 0; k < j; k++)
+                        xmlRelaxNGAddStates(ctxt, res,
+                                            states->tabState[k]);
+                } else {
+                    /* add all the new results to res and reff the container */
+                    for (k = 0; k < ctxt->states->nbState; k++)
+                        xmlRelaxNGAddStates(ctxt, res,
+                                            ctxt->states->tabState[k]);
+                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
+                    ctxt->states = NULL;
+                }
+            }
+        } else {
+            if (ctxt->state != NULL) {
+                xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+                ctxt->state = NULL;
+            } else if (ctxt->states != NULL) {
+                for (k = 0; k < ctxt->states->nbState; k++)
+                    xmlRelaxNGFreeValidState(ctxt,
+                                             ctxt->states->tabState[k]);
+                xmlRelaxNGFreeStates(ctxt, ctxt->states);
+                ctxt->states = NULL;
+            }
+        }
+    }
+    ctxt->flags = oldflags;
+    if (res != NULL) {
+        xmlRelaxNGFreeStates(ctxt, states);
+        ctxt->states = res;
+        ret = 0;
+    } else if (j > 1) {
+        states->nbState = j;
+        ctxt->states = states;
+        ret = 0;
+    } else if (j == 1) {
+        ctxt->state = states->tabState[0];
+        xmlRelaxNGFreeStates(ctxt, states);
+        ret = 0;
+    } else {
+        ret = -1;
+        xmlRelaxNGFreeStates(ctxt, states);
+        if (ctxt->states != NULL) {
+            xmlRelaxNGFreeStates(ctxt, ctxt->states);
+            ctxt->states = NULL;
+        }
+    }
+    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
+        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+        ctxt->state = NULL;
+    }
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGValidateDocument:
+ * @ctxt:  a Relax-NG validation context
+ * @doc:  the document
+ *
+ * Validate the given document
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
+{
+    int ret;
+    xmlRelaxNGPtr schema;
+    xmlRelaxNGGrammarPtr grammar;
+    xmlRelaxNGValidStatePtr state;
+    xmlNodePtr node;
+
+    if ((ctxt == NULL) || (ctxt->schema == NULL) || (doc == NULL))
+        return (-1);
+
+    ctxt->errNo = XML_RELAXNG_OK;
+    schema = ctxt->schema;
+    grammar = schema->topgrammar;
+    if (grammar == NULL) {
+        VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
+        return (-1);
+    }
+    state = xmlRelaxNGNewValidState(ctxt, NULL);
+    ctxt->state = state;
+    ret = xmlRelaxNGValidateDefinition(ctxt, grammar->start);
+    if ((ctxt->state != NULL) && (state->seq != NULL)) {
+        state = ctxt->state;
+        node = state->seq;
+        node = xmlRelaxNGSkipIgnored(ctxt, node);
+        if (node != NULL) {
+            if (ret != -1) {
+                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
+                ret = -1;
+            }
+        }
+    } else if (ctxt->states != NULL) {
+        int i;
+        int tmp = -1;
+
+        for (i = 0; i < ctxt->states->nbState; i++) {
+            state = ctxt->states->tabState[i];
+            node = state->seq;
+            node = xmlRelaxNGSkipIgnored(ctxt, node);
+            if (node == NULL)
+                tmp = 0;
+            xmlRelaxNGFreeValidState(ctxt, state);
+        }
+        if (tmp == -1) {
+            if (ret != -1) {
+                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
+                ret = -1;
+            }
+        }
+    }
+    if (ctxt->state != NULL) {
+        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
+        ctxt->state = NULL;
+    }
+    if (ret != 0)
+        xmlRelaxNGDumpValidError(ctxt);
+#ifdef DEBUG
+    else if (ctxt->errNr != 0) {
+        ctxt->error(ctxt->userData,
+                    "%d Extra error messages left on stack !\n",
+                    ctxt->errNr);
+        xmlRelaxNGDumpValidError(ctxt);
+    }
+#endif
+#ifdef LIBXML_VALID_ENABLED
+    if (ctxt->idref == 1) {
+        xmlValidCtxt vctxt;
+
+        memset(&vctxt, 0, sizeof(xmlValidCtxt));
+        vctxt.valid = 1;
+        vctxt.error = ctxt->error;
+        vctxt.warning = ctxt->warning;
+        vctxt.userData = ctxt->userData;
+
+        if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
+            ret = -1;
+    }
+#endif /* LIBXML_VALID_ENABLED */
+    if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK))
+        ret = -1;
+
+    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				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlRelaxNGNewValidCtxt:
+ * @schema:  a precompiled XML RelaxNGs
+ *
+ * Create an XML RelaxNGs validation context based on the given schema
+ *
+ * Returns the validation context or NULL in case of error
+ */
+xmlRelaxNGValidCtxtPtr
+xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
+{
+    xmlRelaxNGValidCtxtPtr ret;
+
+    ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
+    if (ret == NULL) {
+        xmlRngVErrMemory(NULL, "building context\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
+    ret->schema = schema;
+    ret->error = xmlGenericError;
+    ret->userData = xmlGenericErrorContext;
+    ret->errNr = 0;
+    ret->errMax = 0;
+    ret->err = NULL;
+    ret->errTab = NULL;
+    if (schema != NULL)
+	ret->idref = schema->idref;
+    ret->states = NULL;
+    ret->freeState = NULL;
+    ret->freeStates = NULL;
+    ret->errNo = XML_RELAXNG_OK;
+    return (ret);
+}
+
+/**
+ * xmlRelaxNGFreeValidCtxt:
+ * @ctxt:  the schema validation context
+ *
+ * Free the resources associated to the schema validation context
+ */
+void
+xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
+{
+    int k;
+
+    if (ctxt == NULL)
+        return;
+    if (ctxt->states != NULL)
+        xmlRelaxNGFreeStates(NULL, ctxt->states);
+    if (ctxt->freeState != NULL) {
+        for (k = 0; k < ctxt->freeState->nbState; k++) {
+            xmlRelaxNGFreeValidState(NULL, ctxt->freeState->tabState[k]);
+        }
+        xmlRelaxNGFreeStates(NULL, ctxt->freeState);
+    }
+    if (ctxt->freeStates != NULL) {
+        for (k = 0; k < ctxt->freeStatesNr; k++) {
+            xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
+        }
+        xmlFree(ctxt->freeStates);
+    }
+    if (ctxt->errTab != NULL)
+        xmlFree(ctxt->errTab);
+    if (ctxt->elemTab != NULL) {
+        xmlRegExecCtxtPtr exec;
+
+        exec = xmlRelaxNGElemPop(ctxt);
+        while (exec != NULL) {
+            xmlRegFreeExecCtxt(exec);
+            exec = xmlRelaxNGElemPop(ctxt);
+        }
+        xmlFree(ctxt->elemTab);
+    }
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlRelaxNGSetValidErrors:
+ * @ctxt:  a Relax-NG validation context
+ * @err:  the error function
+ * @warn: the warning function
+ * @ctx: the functions context
+ *
+ * Set the error and warning callback informations
+ */
+void
+xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidityErrorFunc err,
+                         xmlRelaxNGValidityWarningFunc warn, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->error = err;
+    ctxt->warning = warn;
+    ctxt->userData = ctx;
+    ctxt->serror = NULL;
+}
+
+/**
+ * xmlRelaxNGSetValidStructuredErrors:
+ * @ctxt:  a Relax-NG validation context
+ * @serror:  the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
+                                   xmlStructuredErrorFunc serror, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->serror = serror;
+    ctxt->error = NULL;
+    ctxt->warning = NULL;
+    ctxt->userData = ctx;
+}
+
+/**
+ * xmlRelaxNGGetValidErrors:
+ * @ctxt:  a Relax-NG validation context
+ * @err:  the error function result
+ * @warn: the warning function result
+ * @ctx: the functions context result
+ *
+ * Get the error and warning callback informations
+ *
+ * Returns -1 in case of error and 0 otherwise
+ */
+int
+xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
+                         xmlRelaxNGValidityErrorFunc * err,
+                         xmlRelaxNGValidityWarningFunc * warn, void **ctx)
+{
+    if (ctxt == NULL)
+        return (-1);
+    if (err != NULL)
+        *err = ctxt->error;
+    if (warn != NULL)
+        *warn = ctxt->warning;
+    if (ctx != NULL)
+        *ctx = ctxt->userData;
+    return (0);
+}
+
+/**
+ * xmlRelaxNGValidateDoc:
+ * @ctxt:  a Relax-NG validation context
+ * @doc:  a parsed document tree
+ *
+ * Validate a document tree in memory.
+ *
+ * Returns 0 if the document is valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
+{
+    int ret;
+
+    if ((ctxt == NULL) || (doc == NULL))
+        return (-1);
+
+    ctxt->doc = doc;
+
+    ret = xmlRelaxNGValidateDocument(ctxt, doc);
+    /*
+     * Remove all left PSVI
+     */
+    xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
+
+    /*
+     * TODO: build error codes
+     */
+    if (ret == -1)
+        return (1);
+    return (ret);
+}
+
+#define bottom_relaxng
+#include "elfgcchack.h"
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/runsuite.c b/src/runsuite.c
new file mode 100644
index 0000000..e6545fb
--- /dev/null
+++ b/src/runsuite.c
@@ -0,0 +1,1184 @@
+/*
+ * runsuite.c: C program to run libxml2 againts published testsuites 
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "libxml.h"
+#else
+#include <stdio.h>
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+#include <libxml/xmlreader.h>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+
+#define LOGFILE "runsuite.log"
+static FILE *logfile = NULL;
+static int verbose = 0;
+
+
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#define vsnprintf _vsnprintf
+
+#define snprintf _snprintf
+
+#endif
+
+/************************************************************************
+ *									*
+ *		File name and path utilities				*
+ *									*
+ ************************************************************************/
+
+static int checkTestFile(const char *filename) {
+    struct stat buf;
+
+    if (stat(filename, &buf) == -1)
+        return(0);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    if (!(buf.st_mode & _S_IFREG))
+        return(0);
+#else
+    if (!S_ISREG(buf.st_mode))
+        return(0);
+#endif
+
+    return(1);
+}
+
+static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
+    char buf[500];
+
+    if (dir == NULL) return(xmlStrdup(path));
+    if (path == NULL) return(NULL);
+
+    snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
+    return(xmlStrdup((const xmlChar *) buf));
+}
+
+/************************************************************************
+ *									*
+ *		Libxml2 specific routines				*
+ *									*
+ ************************************************************************/
+
+static int nb_tests = 0;
+static int nb_errors = 0;
+static int nb_internals = 0;
+static int nb_schematas = 0;
+static int nb_unimplemented = 0;
+static int nb_leaks = 0;
+static int extraMemoryFromResolver = 0;
+
+static int
+fatalError(void) {
+    fprintf(stderr, "Exitting tests on fatal error\n");
+    exit(1);
+}
+
+/*
+ * that's needed to implement <resource>
+ */
+#define MAX_ENTITIES 20
+static char *testEntitiesName[MAX_ENTITIES];
+static char *testEntitiesValue[MAX_ENTITIES];
+static int nb_entities = 0;
+static void resetEntities(void) {
+    int i;
+
+    for (i = 0;i < nb_entities;i++) {
+        if (testEntitiesName[i] != NULL)
+	    xmlFree(testEntitiesName[i]);
+        if (testEntitiesValue[i] != NULL)
+	    xmlFree(testEntitiesValue[i]);
+    }
+    nb_entities = 0;
+}
+static int addEntity(char *name, char *content) {
+    if (nb_entities >= MAX_ENTITIES) {
+	fprintf(stderr, "Too many entities defined\n");
+	return(-1);
+    }
+    testEntitiesName[nb_entities] = name;
+    testEntitiesValue[nb_entities] = content;
+    nb_entities++;
+    return(0);
+}
+
+/*
+ * We need to trap calls to the resolver to not account memory for the catalog
+ * which is shared to the current running test. We also don't want to have
+ * network downloads modifying tests.
+ */
+static xmlParserInputPtr 
+testExternalEntityLoader(const char *URL, const char *ID,
+			 xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr ret;
+    int i;
+
+    for (i = 0;i < nb_entities;i++) {
+        if (!strcmp(testEntitiesName[i], URL)) {
+	    ret = xmlNewStringInputStream(ctxt,
+	                (const xmlChar *) testEntitiesValue[i]);
+	    if (ret != NULL) {
+	        ret->filename = (const char *)
+		                xmlStrdup((xmlChar *)testEntitiesName[i]);
+	    }
+	    return(ret);
+	}
+    }
+    if (checkTestFile(URL)) {
+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+    } else {
+	int memused = xmlMemUsed();
+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+	extraMemoryFromResolver += xmlMemUsed() - memused;
+    }
+#if 0
+    if (ret == NULL) {
+        fprintf(stderr, "Failed to find resource %s\n", URL);
+    }
+#endif
+      
+    return(ret);
+}
+
+/*
+ * Trapping the error messages at the generic level to grab the equivalent of
+ * stderr messages on CLI tools.
+ */
+static char testErrors[32769];
+static int testErrorsSize = 0;
+
+static void test_log(const char *msg, ...) {
+    va_list args;
+    if (logfile != NULL) {
+        fprintf(logfile, "\n------------\n");
+	va_start(args, msg);
+	vfprintf(logfile, msg, args);
+	va_end(args);
+	fprintf(logfile, "%s", testErrors);
+	testErrorsSize = 0; testErrors[0] = 0;
+    }
+    if (verbose) {
+	va_start(args, msg);
+	vfprintf(stderr, msg, args);
+	va_end(args);
+    }
+}
+
+static void
+testErrorHandler(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
+    va_list args;
+    int res;
+
+    if (testErrorsSize >= 32768)
+        return;
+    va_start(args, msg);
+    res = vsnprintf(&testErrors[testErrorsSize],
+                    32768 - testErrorsSize,
+		    msg, args);
+    va_end(args);
+    if (testErrorsSize + res >= 32768) {
+        /* buffer is full */
+	testErrorsSize = 32768;
+	testErrors[testErrorsSize] = 0;
+    } else {
+        testErrorsSize += res;
+    }
+    testErrors[testErrorsSize] = 0;
+}
+
+static xmlXPathContextPtr ctxtXPath;
+
+static void
+initializeLibxml2(void) {
+    xmlGetWarningsDefaultValue = 0;
+    xmlPedanticParserDefault(0);
+
+    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
+    xmlInitParser();
+    xmlSetExternalEntityLoader(testExternalEntityLoader);
+    ctxtXPath = xmlXPathNewContext(NULL);
+    /*
+    * Deactivate the cache if created; otherwise we have to create/free it
+    * for every test, since it will confuse the memory leak detection.
+    * Note that normally this need not be done, since the cache is not
+    * created until set explicitely with xmlXPathContextSetCache();
+    * but for test purposes it is sometimes usefull to activate the
+    * cache by default for the whole library.
+    */
+    if (ctxtXPath->cache != NULL)
+	xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
+    /* used as default nanemspace in xstc tests */
+    xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
+    xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
+                       BAD_CAST "http://www.w3.org/1999/xlink");
+    xmlSetGenericErrorFunc(NULL, testErrorHandler);
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlSchemaInitTypes();
+    xmlRelaxNGInitTypes();
+#endif
+}
+
+static xmlNodePtr
+getNext(xmlNodePtr cur, const char *xpath) {
+    xmlNodePtr ret = NULL;
+    xmlXPathObjectPtr res;
+    xmlXPathCompExprPtr comp;
+
+    if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
+        return(NULL);
+    ctxtXPath->doc = cur->doc;
+    ctxtXPath->node = cur;
+    comp = xmlXPathCompile(BAD_CAST xpath);
+    if (comp == NULL) {
+        fprintf(stderr, "Failed to compile %s\n", xpath);
+	return(NULL);
+    }
+    res = xmlXPathCompiledEval(comp, ctxtXPath);
+    xmlXPathFreeCompExpr(comp);
+    if (res == NULL)
+        return(NULL);
+    if ((res->type == XPATH_NODESET) &&
+        (res->nodesetval != NULL) &&
+	(res->nodesetval->nodeNr > 0) &&
+	(res->nodesetval->nodeTab != NULL))
+	ret = res->nodesetval->nodeTab[0];
+    xmlXPathFreeObject(res);
+    return(ret);
+}
+
+static xmlChar *
+getString(xmlNodePtr cur, const char *xpath) {
+    xmlChar *ret = NULL;
+    xmlXPathObjectPtr res;
+    xmlXPathCompExprPtr comp;
+
+    if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
+        return(NULL);
+    ctxtXPath->doc = cur->doc;
+    ctxtXPath->node = cur;
+    comp = xmlXPathCompile(BAD_CAST xpath);
+    if (comp == NULL) {
+        fprintf(stderr, "Failed to compile %s\n", xpath);
+	return(NULL);
+    }
+    res = xmlXPathCompiledEval(comp, ctxtXPath);
+    xmlXPathFreeCompExpr(comp);
+    if (res == NULL)
+        return(NULL);
+    if (res->type == XPATH_STRING) {
+        ret = res->stringval;
+	res->stringval = NULL;
+    }
+    xmlXPathFreeObject(res);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		Test test/xsdtest/xsdtestsuite.xml			*
+ *									*
+ ************************************************************************/
+
+static int
+xsdIncorectTestCase(xmlNodePtr cur) {
+    xmlNodePtr test;
+    xmlBufferPtr buf;
+    xmlRelaxNGParserCtxtPtr pctxt;
+    xmlRelaxNGPtr rng = NULL;
+    int ret = 0, memt;
+
+    cur = getNext(cur, "./incorrect[1]");
+    if (cur == NULL) {
+        return(0);
+    }
+
+    test = getNext(cur, "./*");
+    if (test == NULL) {
+        test_log("Failed to find test in correct line %ld\n",
+	        xmlGetLineNo(cur));
+        return(1);
+    }
+
+    memt = xmlMemUsed();
+    extraMemoryFromResolver = 0;
+    /*
+     * dump the schemas to a buffer, then reparse it and compile the schemas
+     */
+    buf = xmlBufferCreate();
+    if (buf == NULL) {
+        fprintf(stderr, "out of memory !\n");
+	fatalError();
+    }
+    xmlNodeDump(buf, test->doc, test, 0, 0);
+    pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
+    xmlRelaxNGSetParserErrors(pctxt,
+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+	 pctxt);
+    rng = xmlRelaxNGParse(pctxt);
+    xmlRelaxNGFreeParserCtxt(pctxt);
+    if (rng != NULL) {
+	test_log("Failed to detect incorect RNG line %ld\n",
+		    xmlGetLineNo(test));
+        ret = 1;
+	goto done;
+    }
+
+done:
+    if (buf != NULL)
+	xmlBufferFree(buf);
+    if (rng != NULL)
+        xmlRelaxNGFree(rng);
+    xmlResetLastError();
+    if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
+	test_log("Validation of tests starting line %ld leaked %d\n",
+		xmlGetLineNo(cur), xmlMemUsed() - memt);
+	nb_leaks++;
+    }
+    return(ret);
+}
+
+static void
+installResources(xmlNodePtr tst, const xmlChar *base) {
+    xmlNodePtr test;
+    xmlBufferPtr buf;
+    xmlChar *name, *content, *res;
+
+    buf = xmlBufferCreate();
+    if (buf == NULL) {
+        fprintf(stderr, "out of memory !\n");
+	fatalError();
+    }
+    xmlNodeDump(buf, tst->doc, tst, 0, 0);
+
+    while (tst != NULL) {
+	test = getNext(tst, "./*");
+	if (test != NULL) {
+	    xmlBufferEmpty(buf);
+	    xmlNodeDump(buf, test->doc, test, 0, 0);
+	    name = getString(tst, "string(@name)");
+	    content = xmlStrdup(buf->content);
+	    if ((name != NULL) && (content != NULL)) {
+	        res = composeDir(base, name);
+		xmlFree(name);
+	        addEntity((char *) res, (char *) content);
+	    } else {
+	        if (name != NULL) xmlFree(name);
+	        if (content != NULL) xmlFree(content);
+	    }
+	}
+	tst = getNext(tst, "following-sibling::resource[1]");
+    }
+    if (buf != NULL)
+	xmlBufferFree(buf);
+}
+
+static void
+installDirs(xmlNodePtr tst, const xmlChar *base) {
+    xmlNodePtr test;
+    xmlChar *name, *res;
+
+    name = getString(tst, "string(@name)");
+    if (name == NULL)
+        return;
+    res = composeDir(base, name);
+    xmlFree(name);
+    if (res == NULL) {
+	return;
+    }
+    /* Now process resources and subdir recursively */
+    test = getNext(tst, "./resource[1]");
+    if (test != NULL) {
+        installResources(test, res);
+    }
+    test = getNext(tst, "./dir[1]");
+    while (test != NULL) {
+        installDirs(test, res);
+	test = getNext(test, "following-sibling::dir[1]");
+    }
+    xmlFree(res);
+}
+
+static int 
+xsdTestCase(xmlNodePtr tst) {
+    xmlNodePtr test, tmp, cur;
+    xmlBufferPtr buf;
+    xmlDocPtr doc = NULL;
+    xmlRelaxNGParserCtxtPtr pctxt;
+    xmlRelaxNGValidCtxtPtr ctxt;
+    xmlRelaxNGPtr rng = NULL;
+    int ret = 0, mem, memt;
+    xmlChar *dtd;
+
+    resetEntities();
+    testErrorsSize = 0; testErrors[0] = 0;
+
+    tmp = getNext(tst, "./dir[1]");
+    if (tmp != NULL) {
+        installDirs(tmp, NULL);
+    }
+    tmp = getNext(tst, "./resource[1]");
+    if (tmp != NULL) {
+        installResources(tmp, NULL);
+    }
+
+    cur = getNext(tst, "./correct[1]");
+    if (cur == NULL) {
+        return(xsdIncorectTestCase(tst));
+    }
+    
+    test = getNext(cur, "./*");
+    if (test == NULL) {
+        fprintf(stderr, "Failed to find test in correct line %ld\n",
+	        xmlGetLineNo(cur));
+        return(1);
+    }
+
+    memt = xmlMemUsed();
+    extraMemoryFromResolver = 0;
+    /*
+     * dump the schemas to a buffer, then reparse it and compile the schemas
+     */
+    buf = xmlBufferCreate();
+    if (buf == NULL) {
+        fprintf(stderr, "out of memory !\n");
+	fatalError();
+    }
+    xmlNodeDump(buf, test->doc, test, 0, 0);
+    pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
+    xmlRelaxNGSetParserErrors(pctxt,
+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+	 pctxt);
+    rng = xmlRelaxNGParse(pctxt);
+    xmlRelaxNGFreeParserCtxt(pctxt);
+    if (extraMemoryFromResolver)
+        memt = 0;
+
+    if (rng == NULL) {
+        test_log("Failed to parse RNGtest line %ld\n",
+	        xmlGetLineNo(test));
+	nb_errors++;
+        ret = 1;
+	goto done;
+    }
+    /*
+     * now scan all the siblings of correct to process the <valid> tests
+     */
+    tmp = getNext(cur, "following-sibling::valid[1]");
+    while (tmp != NULL) {
+	dtd = xmlGetProp(tmp, BAD_CAST "dtd");
+	test = getNext(tmp, "./*");
+	if (test == NULL) {
+	    fprintf(stderr, "Failed to find test in <valid> line %ld\n",
+		    xmlGetLineNo(tmp));
+	    
+	} else {
+	    xmlBufferEmpty(buf);
+	    if (dtd != NULL)
+		xmlBufferAdd(buf, dtd, -1);
+	    xmlNodeDump(buf, test->doc, test, 0, 0);
+
+	    /*
+	     * We are ready to run the test
+	     */
+	    mem = xmlMemUsed();
+	    extraMemoryFromResolver = 0;
+            doc = xmlReadMemory((const char *)buf->content, buf->use,
+	                        "test", NULL, 0);
+	    if (doc == NULL) {
+		test_log("Failed to parse valid instance line %ld\n",
+			xmlGetLineNo(tmp));
+		nb_errors++;
+	    } else {
+		nb_tests++;
+	        ctxt = xmlRelaxNGNewValidCtxt(rng);
+		xmlRelaxNGSetValidErrors(ctxt,
+		     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+		     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+		     ctxt);
+		ret = xmlRelaxNGValidateDoc(ctxt, doc);
+		xmlRelaxNGFreeValidCtxt(ctxt);
+		if (ret > 0) {
+		    test_log("Failed to validate valid instance line %ld\n",
+				xmlGetLineNo(tmp));
+		    nb_errors++;
+		} else if (ret < 0) {
+		    test_log("Internal error validating instance line %ld\n",
+			    xmlGetLineNo(tmp));
+		    nb_errors++;
+		}
+		xmlFreeDoc(doc);
+	    }
+	    xmlResetLastError();
+	    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
+	        test_log("Validation of instance line %ld leaked %d\n",
+		        xmlGetLineNo(tmp), xmlMemUsed() - mem);
+		xmlMemoryDump();
+	        nb_leaks++;
+	    }
+	}
+	if (dtd != NULL)
+	    xmlFree(dtd);
+	tmp = getNext(tmp, "following-sibling::valid[1]");
+    }
+    /*
+     * now scan all the siblings of correct to process the <invalid> tests
+     */
+    tmp = getNext(cur, "following-sibling::invalid[1]");
+    while (tmp != NULL) {
+	test = getNext(tmp, "./*");
+	if (test == NULL) {
+	    fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
+		    xmlGetLineNo(tmp));
+	    
+	} else {
+	    xmlBufferEmpty(buf);
+	    xmlNodeDump(buf, test->doc, test, 0, 0);
+
+	    /*
+	     * We are ready to run the test
+	     */
+	    mem = xmlMemUsed();
+	    extraMemoryFromResolver = 0;
+            doc = xmlReadMemory((const char *)buf->content, buf->use,
+	                        "test", NULL, 0);
+	    if (doc == NULL) {
+		test_log("Failed to parse valid instance line %ld\n",
+			xmlGetLineNo(tmp));
+		nb_errors++;
+	    } else {
+		nb_tests++;
+	        ctxt = xmlRelaxNGNewValidCtxt(rng);
+		xmlRelaxNGSetValidErrors(ctxt,
+		     (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+		     (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+		     ctxt);
+		ret = xmlRelaxNGValidateDoc(ctxt, doc);
+		xmlRelaxNGFreeValidCtxt(ctxt);
+		if (ret == 0) {
+		    test_log("Failed to detect invalid instance line %ld\n",
+				xmlGetLineNo(tmp));
+		    nb_errors++;
+		} else if (ret < 0) {
+		    test_log("Internal error validating instance line %ld\n",
+			    xmlGetLineNo(tmp));
+		    nb_errors++;
+		}
+		xmlFreeDoc(doc);
+	    }
+	    xmlResetLastError();
+	    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
+	        test_log("Validation of instance line %ld leaked %d\n",
+		        xmlGetLineNo(tmp), xmlMemUsed() - mem);
+		xmlMemoryDump();
+	        nb_leaks++;
+	    }
+	}
+	tmp = getNext(tmp, "following-sibling::invalid[1]");
+    }
+
+done:
+    if (buf != NULL)
+	xmlBufferFree(buf);
+    if (rng != NULL)
+        xmlRelaxNGFree(rng);
+    xmlResetLastError();
+    if ((memt != xmlMemUsed()) && (memt != 0)) {
+	test_log("Validation of tests starting line %ld leaked %d\n",
+		xmlGetLineNo(cur), xmlMemUsed() - memt);
+	nb_leaks++;
+    }
+    return(ret);
+}
+
+static int 
+xsdTestSuite(xmlNodePtr cur) {
+    if (verbose) {
+	xmlChar *doc = getString(cur, "string(documentation)");
+
+	if (doc != NULL) {
+	    printf("Suite %s\n", doc);
+	    xmlFree(doc);
+	}
+    }
+    cur = getNext(cur, "./testCase[1]");
+    while (cur != NULL) {
+        xsdTestCase(cur);
+	cur = getNext(cur, "following-sibling::testCase[1]");
+    }
+        
+    return(0);
+}
+
+static int 
+xsdTest(void) {
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    const char *filename = "test/xsdtest/xsdtestsuite.xml";
+    int ret = 0;
+
+    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
+    if (doc == NULL) {
+        fprintf(stderr, "Failed to parse %s\n", filename);
+	return(-1);
+    }
+    printf("## XML Schemas datatypes test suite from James Clark\n");
+
+    cur = xmlDocGetRootElement(doc);
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+
+    cur = getNext(cur, "./testSuite[1]");
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+    while (cur != NULL) {
+        xsdTestSuite(cur);
+	cur = getNext(cur, "following-sibling::testSuite[1]");
+    }
+
+done:
+    if (doc != NULL)
+	xmlFreeDoc(doc);
+    return(ret);
+}
+
+static int 
+rngTestSuite(xmlNodePtr cur) {
+    if (verbose) {
+	xmlChar *doc = getString(cur, "string(documentation)");
+
+	if (doc != NULL) {
+	    printf("Suite %s\n", doc);
+	    xmlFree(doc);
+	} else {
+	    doc = getString(cur, "string(section)");
+	    if (doc != NULL) {
+		printf("Section %s\n", doc);
+		xmlFree(doc);
+	    }
+	}
+    }
+    cur = getNext(cur, "./testSuite[1]");
+    while (cur != NULL) {
+        xsdTestSuite(cur);
+	cur = getNext(cur, "following-sibling::testSuite[1]");
+    }
+        
+    return(0);
+}
+
+static int 
+rngTest1(void) {
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    const char *filename = "test/relaxng/OASIS/spectest.xml";
+    int ret = 0;
+
+    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
+    if (doc == NULL) {
+        fprintf(stderr, "Failed to parse %s\n", filename);
+	return(-1);
+    }
+    printf("## Relax NG test suite from James Clark\n");
+
+    cur = xmlDocGetRootElement(doc);
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+
+    cur = getNext(cur, "./testSuite[1]");
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+    while (cur != NULL) {
+        rngTestSuite(cur);
+	cur = getNext(cur, "following-sibling::testSuite[1]");
+    }
+
+done:
+    if (doc != NULL)
+	xmlFreeDoc(doc);
+    return(ret);
+}
+
+static int 
+rngTest2(void) {
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    const char *filename = "test/relaxng/testsuite.xml";
+    int ret = 0;
+
+    doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
+    if (doc == NULL) {
+        fprintf(stderr, "Failed to parse %s\n", filename);
+	return(-1);
+    }
+    printf("## Relax NG test suite for libxml2\n");
+
+    cur = xmlDocGetRootElement(doc);
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+
+    cur = getNext(cur, "./testSuite[1]");
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
+        fprintf(stderr, "Unexpected format %s\n", filename);
+	ret = -1;
+	goto done;
+    }
+    while (cur != NULL) {
+        xsdTestSuite(cur);
+	cur = getNext(cur, "following-sibling::testSuite[1]");
+    }
+
+done:
+    if (doc != NULL)
+	xmlFreeDoc(doc);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		Schemas test suites from W3C/NIST/MS/Sun		*
+ *									*
+ ************************************************************************/
+
+static int
+xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
+                 const xmlChar *spath, const char *base) {
+    xmlChar *href = NULL;
+    xmlChar *path = NULL;
+    xmlChar *validity = NULL;
+    xmlSchemaValidCtxtPtr ctxt = NULL;
+    xmlDocPtr doc = NULL;
+    int ret = 0, mem;
+
+    xmlResetLastError();
+    testErrorsSize = 0; testErrors[0] = 0;
+    mem = xmlMemUsed();
+    href = getString(cur,
+                     "string(ts:instanceDocument/@xlink:href)");
+    if ((href == NULL) || (href[0] == 0)) {
+	test_log("testGroup line %ld misses href for schemaDocument\n",
+		    xmlGetLineNo(cur));
+	ret = -1;
+	goto done;
+    }
+    path = xmlBuildURI(href, BAD_CAST base);
+    if (path == NULL) {
+	fprintf(stderr,
+	        "Failed to build path to schemas testGroup line %ld : %s\n",
+		xmlGetLineNo(cur), href);
+	ret = -1;
+	goto done;
+    }
+    if (checkTestFile((const char *) path) <= 0) {
+	test_log("schemas for testGroup line %ld is missing: %s\n",
+		xmlGetLineNo(cur), path);
+	ret = -1;
+	goto done;
+    }
+    validity = getString(cur,
+                         "string(ts:expected/@validity)");
+    if (validity == NULL) {
+        fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
+	        xmlGetLineNo(cur));
+	ret = -1;
+	goto done;
+    }
+    nb_tests++;
+    doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
+    if (doc == NULL) {
+        fprintf(stderr, "instance %s fails to parse\n", path);
+	ret = -1;
+	nb_errors++;
+	goto done;
+    }
+
+    ctxt = xmlSchemaNewValidCtxt(schemas);
+    xmlSchemaSetValidErrors(ctxt,
+         (xmlSchemaValidityErrorFunc) testErrorHandler,
+         (xmlSchemaValidityWarningFunc) testErrorHandler,
+	 ctxt);
+    ret = xmlSchemaValidateDoc(ctxt, doc);
+
+    if (xmlStrEqual(validity, BAD_CAST "valid")) {
+	if (ret > 0) {
+	    test_log("valid instance %s failed to validate against %s\n",
+			path, spath);
+	    nb_errors++;
+	} else if (ret < 0) {
+	    test_log("valid instance %s got internal error validating %s\n",
+			path, spath);
+	    nb_internals++;
+	    nb_errors++;
+	}
+    } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
+	if (ret == 0) {
+	    test_log("Failed to detect invalid instance %s against %s\n",
+			path, spath);
+	    nb_errors++;
+	}
+    } else {
+        test_log("instanceDocument line %ld has unexpected validity value%s\n",
+	        xmlGetLineNo(cur), validity);
+	ret = -1;
+	goto done;
+    }
+
+done:
+    if (href != NULL) xmlFree(href);
+    if (path != NULL) xmlFree(path);
+    if (validity != NULL) xmlFree(validity);
+    if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
+    if (doc != NULL) xmlFreeDoc(doc);
+    xmlResetLastError();
+    if (mem != xmlMemUsed()) {
+	test_log("Validation of tests starting line %ld leaked %d\n",
+		xmlGetLineNo(cur), xmlMemUsed() - mem);
+	nb_leaks++;
+    }
+    return(ret);
+}
+
+static int
+xstcTestGroup(xmlNodePtr cur, const char *base) {
+    xmlChar *href = NULL;
+    xmlChar *path = NULL;
+    xmlChar *validity = NULL;
+    xmlSchemaPtr schemas = NULL;
+    xmlSchemaParserCtxtPtr ctxt;
+    xmlNodePtr instance;
+    int ret = 0, mem;
+
+    xmlResetLastError();
+    testErrorsSize = 0; testErrors[0] = 0;
+    mem = xmlMemUsed();
+    href = getString(cur,
+                     "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
+    if ((href == NULL) || (href[0] == 0)) {
+        test_log("testGroup line %ld misses href for schemaDocument\n",
+		    xmlGetLineNo(cur));
+	ret = -1;
+	goto done;
+    }
+    path = xmlBuildURI(href, BAD_CAST base);
+    if (path == NULL) {
+	test_log("Failed to build path to schemas testGroup line %ld : %s\n",
+		xmlGetLineNo(cur), href);
+	ret = -1;
+	goto done;
+    }
+    if (checkTestFile((const char *) path) <= 0) {
+	test_log("schemas for testGroup line %ld is missing: %s\n",
+		xmlGetLineNo(cur), path);
+	ret = -1;
+	goto done;
+    }
+    validity = getString(cur,
+                         "string(ts:schemaTest/ts:expected/@validity)");
+    if (validity == NULL) {
+        test_log("testGroup line %ld misses expected validity\n",
+	        xmlGetLineNo(cur));
+	ret = -1;
+	goto done;
+    }
+    nb_tests++;
+    if (xmlStrEqual(validity, BAD_CAST "valid")) {
+        nb_schematas++;
+	ctxt = xmlSchemaNewParserCtxt((const char *) path);
+	xmlSchemaSetParserErrors(ctxt,
+	     (xmlSchemaValidityErrorFunc) testErrorHandler,
+	     (xmlSchemaValidityWarningFunc) testErrorHandler,
+	     ctxt);
+	schemas = xmlSchemaParse(ctxt);
+	xmlSchemaFreeParserCtxt(ctxt);
+	if (schemas == NULL) {
+	    test_log("valid schemas %s failed to parse\n",
+			path);
+	    ret = 1;
+	    nb_errors++;
+	}
+	if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
+	    test_log("valid schemas %s hit an unimplemented block\n",
+			path);
+	    ret = 1;
+	    nb_unimplemented++;
+	    nb_errors++;
+	}
+	instance = getNext(cur, "./ts:instanceTest[1]");
+	while (instance != NULL) {
+	    if (schemas != NULL) {
+		xstcTestInstance(instance, schemas, path, base);		
+	    } else {
+		/*
+		* We'll automatically mark the instances as failed
+		* if the schema was broken.
+		*/
+		nb_errors++;
+	    }
+	    instance = getNext(instance,
+		"following-sibling::ts:instanceTest[1]");
+	}
+    } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
+        nb_schematas++;
+	ctxt = xmlSchemaNewParserCtxt((const char *) path);
+	xmlSchemaSetParserErrors(ctxt,
+	     (xmlSchemaValidityErrorFunc) testErrorHandler,
+	     (xmlSchemaValidityWarningFunc) testErrorHandler,
+	     ctxt);
+	schemas = xmlSchemaParse(ctxt);
+	xmlSchemaFreeParserCtxt(ctxt);
+	if (schemas != NULL) {
+	    test_log("Failed to detect error in schemas %s\n",
+			path);
+	    nb_errors++;
+	    ret = 1;
+	}
+	if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
+	    nb_unimplemented++;
+	    test_log("invalid schemas %s hit an unimplemented block\n",
+			path);
+	    ret = 1;
+	    nb_errors++;
+	}
+    } else {
+        test_log("testGroup line %ld misses unexpected validity value%s\n",
+	        xmlGetLineNo(cur), validity);
+	ret = -1;
+	goto done;
+    }
+
+done:
+    if (href != NULL) xmlFree(href);
+    if (path != NULL) xmlFree(path);
+    if (validity != NULL) xmlFree(validity);
+    if (schemas != NULL) xmlSchemaFree(schemas);
+    xmlResetLastError();
+    if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
+	test_log("Processing test line %ld %s leaked %d\n",
+		xmlGetLineNo(cur), path, xmlMemUsed() - mem);
+	nb_leaks++;
+    }
+    return(ret);
+}
+
+static int
+xstcMetadata(const char *metadata, const char *base) {
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    xmlChar *contributor;
+    xmlChar *name;
+    int ret = 0;
+
+    doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
+    if (doc == NULL) {
+        fprintf(stderr, "Failed to parse %s\n", metadata);
+	return(-1);
+    }
+
+    cur = xmlDocGetRootElement(doc);
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
+        fprintf(stderr, "Unexpected format %s\n", metadata);
+	return(-1);
+    }
+    contributor = xmlGetProp(cur, BAD_CAST "contributor");
+    if (contributor == NULL) {
+        contributor = xmlStrdup(BAD_CAST "Unknown");
+    }
+    name = xmlGetProp(cur, BAD_CAST "name");
+    if (name == NULL) {
+        name = xmlStrdup(BAD_CAST "Unknown");
+    }
+    printf("## %s test suite for Schemas version %s\n", contributor, name);
+    xmlFree(contributor);
+    xmlFree(name);
+
+    cur = getNext(cur, "./ts:testGroup[1]");
+    if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
+        fprintf(stderr, "Unexpected format %s\n", metadata);
+	ret = -1;
+	goto done;
+    }
+    while (cur != NULL) {
+        xstcTestGroup(cur, base);
+	cur = getNext(cur, "following-sibling::ts:testGroup[1]");
+    }
+
+done:
+    xmlFreeDoc(doc);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		The driver for the tests				*
+ *									*
+ ************************************************************************/
+
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    int ret = 0;
+    int old_errors, old_tests, old_leaks;
+
+    logfile = fopen(LOGFILE, "w");
+    if (logfile == NULL) {
+        fprintf(stderr,
+	        "Could not open the log file, running in verbose mode\n");
+	verbose = 1;
+    }
+    initializeLibxml2();
+
+    if ((argc >= 2) && (!strcmp(argv[1], "-v")))
+        verbose = 1;
+
+
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    xsdTest();
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+    else
+	printf("Ran %d tests, %d errors, %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_errors - old_errors,
+	       nb_leaks - old_leaks);
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    rngTest1();
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+    else
+	printf("Ran %d tests, %d errors, %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_errors - old_errors,
+	       nb_leaks - old_leaks);
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    rngTest2();
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+    else
+	printf("Ran %d tests, %d errors, %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_errors - old_errors,
+	       nb_leaks - old_leaks);
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    nb_internals = 0;
+    nb_schematas = 0;
+    xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
+		 "xstc/Tests/Metadata/");
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests (%d schemata), no errors\n",
+	       nb_tests - old_tests, nb_schematas);
+    else
+	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_schematas,
+	       nb_errors - old_errors,
+	       nb_internals,
+	       nb_leaks - old_leaks);
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    nb_internals = 0;
+    nb_schematas = 0;
+    xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
+		 "xstc/Tests/");
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests (%d schemata), no errors\n",
+	       nb_tests - old_tests, nb_schematas);
+    else
+	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_schematas,
+	       nb_errors - old_errors,
+	       nb_internals,
+	       nb_leaks - old_leaks);
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    nb_internals = 0;
+    nb_schematas = 0;
+    xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
+		 "xstc/Tests/");
+    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	printf("Ran %d tests (%d schemata), no errors\n",
+	       nb_tests - old_tests, nb_schematas);
+    else
+	printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
+	       nb_tests - old_tests,
+	       nb_schematas,
+	       nb_errors - old_errors,
+	       nb_internals,
+	       nb_leaks - old_leaks);
+
+    if ((nb_errors == 0) && (nb_leaks == 0)) {
+        ret = 0;
+	printf("Total %d tests, no errors\n",
+	       nb_tests);
+    } else {
+        ret = 1;
+	printf("Total %d tests, %d errors, %d leaks\n",
+	       nb_tests, nb_errors, nb_leaks);
+    }
+    xmlXPathFreeContext(ctxtXPath);
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    if (logfile != NULL)
+        fclose(logfile);
+    return(ret);
+}
+#else /* !SCHEMAS */
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
+}
+#endif
diff --git a/src/runtest.c b/src/runtest.c
new file mode 100644
index 0000000..bc28795
--- /dev/null
+++ b/src/runtest.c
@@ -0,0 +1,4471 @@
+/*
+ * runtest.c: C program to run libxml2 regression tests without
+ *            requiring make or Python, and reducing platform dependancies
+ *            to a strict minimum.
+ *
+ * To compile on Unixes:
+ * cc -o runtest `xml2-config --cflags` runtest.c `xml2-config --libs` -lpthread
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "libxml.h"
+#else
+#include <stdio.h>
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef LIBXML_READER_ENABLED
+#include <libxml/xmlreader.h>
+#endif
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#ifdef LIBXML_XPTR_ENABLED
+#include <libxml/xpointer.h>
+#endif
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+#endif
+
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
+
+#ifdef LIBXML_C14N_ENABLED
+#include <libxml/c14n.h>
+#endif
+
+#ifdef LIBXML_HTML_ENABLED
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+
+/*
+ * pseudo flag for the unification of HTML and XML tests
+ */
+#define XML_PARSE_HTML 1 << 24
+#endif
+
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
+#include <libxml/globals.h>
+#include <libxml/threads.h>
+#include <libxml/parser.h>
+#include <libxml/catalog.h>
+#include <string.h>
+#endif
+
+/*
+ * O_BINARY is just for Windows compatibility - if it isn't defined
+ * on this system, avoid any compilation error
+ */
+#ifdef	O_BINARY
+#define RD_FLAGS	O_RDONLY | O_BINARY
+#else
+#define	RD_FLAGS	O_RDONLY
+#endif
+
+typedef int (*functest) (const char *filename, const char *result,
+                         const char *error, int options);
+
+typedef struct testDesc testDesc;
+typedef testDesc *testDescPtr;
+struct testDesc {
+    const char *desc; /* descripton of the test */
+    functest    func; /* function implementing the test */
+    const char *in;   /* glob to path for input files */
+    const char *out;  /* output directory */
+    const char *suffix;/* suffix for output files */
+    const char *err;  /* suffix for error output files */
+    int     options;  /* parser options for the test */
+};
+
+static int checkTestFile(const char *filename);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include <windows.h>
+#include <io.h>
+
+typedef struct
+{
+      size_t gl_pathc;    /* Count of paths matched so far  */
+      char **gl_pathv;    /* List of matched pathnames.  */
+      size_t gl_offs;     /* Slots to reserve in 'gl_pathv'.  */
+} glob_t;
+
+#define GLOB_DOOFFS 0
+static int glob(const char *pattern, int flags,
+                int errfunc(const char *epath, int eerrno),
+                glob_t *pglob) {
+    glob_t *ret;
+    WIN32_FIND_DATA FindFileData;
+    HANDLE hFind;
+    unsigned int nb_paths = 0;
+    char directory[500];
+    int len;
+
+    if ((pattern == NULL) || (pglob == NULL)) return(-1);
+
+    strncpy(directory, pattern, 499);
+    for (len = strlen(directory);len >= 0;len--) {
+        if (directory[len] == '/') {
+	    len++;
+	    directory[len] = 0;
+	    break;
+	}
+    }
+    if (len <= 0)
+        len = 0;
+
+
+    ret = pglob;
+    memset(ret, 0, sizeof(glob_t));
+
+    hFind = FindFirstFileA(pattern, &FindFileData);
+    if (hFind == INVALID_HANDLE_VALUE)
+        return(0);
+    nb_paths = 20;
+    ret->gl_pathv = (char **) malloc(nb_paths * sizeof(char *));
+    if (ret->gl_pathv == NULL) {
+	FindClose(hFind);
+        return(-1);
+    }
+    strncpy(directory + len, FindFileData.cFileName, 499 - len);
+    ret->gl_pathv[ret->gl_pathc] = strdup(directory);
+    if (ret->gl_pathv[ret->gl_pathc] == NULL)
+        goto done;
+    ret->gl_pathc++;
+    while(FindNextFileA(hFind, &FindFileData)) {
+        if (FindFileData.cFileName[0] == '.')
+	    continue;
+        if (ret->gl_pathc + 2 > nb_paths) {
+            char **tmp = realloc(ret->gl_pathv, nb_paths * 2 * sizeof(char *));
+            if (tmp == NULL)
+                break;
+            ret->gl_pathv = tmp;
+            nb_paths *= 2;
+	}
+	strncpy(directory + len, FindFileData.cFileName, 499 - len);
+	ret->gl_pathv[ret->gl_pathc] = strdup(directory);
+        if (ret->gl_pathv[ret->gl_pathc] == NULL)
+            break;
+        ret->gl_pathc++;
+    }
+    ret->gl_pathv[ret->gl_pathc] = NULL;
+
+done:
+    FindClose(hFind);
+    return(0);
+}
+
+
+
+static void globfree(glob_t *pglob) {
+    unsigned int i;
+    if (pglob == NULL)
+        return;
+
+    for (i = 0;i < pglob->gl_pathc;i++) {
+         if (pglob->gl_pathv[i] != NULL)
+             free(pglob->gl_pathv[i]);
+    }
+}
+#define vsnprintf _vsnprintf
+#define snprintf _snprintf
+#else
+#include <glob.h>
+#endif
+
+/************************************************************************
+ *									*
+ *		Libxml2 specific routines				*
+ *									*
+ ************************************************************************/
+
+static int nb_tests = 0;
+static int nb_errors = 0;
+static int nb_leaks = 0;
+static int extraMemoryFromResolver = 0;
+
+static int
+fatalError(void) {
+    fprintf(stderr, "Exitting tests on fatal error\n");
+    exit(1);
+}
+
+/*
+ * We need to trap calls to the resolver to not account memory for the catalog
+ * which is shared to the current running test. We also don't want to have
+ * network downloads modifying tests.
+ */
+static xmlParserInputPtr
+testExternalEntityLoader(const char *URL, const char *ID,
+			 xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr ret;
+
+    if (checkTestFile(URL)) {
+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+    } else {
+	int memused = xmlMemUsed();
+	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+	extraMemoryFromResolver += xmlMemUsed() - memused;
+    }
+
+    return(ret);
+}
+
+/*
+ * Trapping the error messages at the generic level to grab the equivalent of
+ * stderr messages on CLI tools.
+ */
+static char testErrors[32769];
+static int testErrorsSize = 0;
+
+static void XMLCDECL
+testErrorHandler(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
+    va_list args;
+    int res;
+
+    if (testErrorsSize >= 32768)
+        return;
+    va_start(args, msg);
+    res = vsnprintf(&testErrors[testErrorsSize],
+                    32768 - testErrorsSize,
+		    msg, args);
+    va_end(args);
+    if (testErrorsSize + res >= 32768) {
+        /* buffer is full */
+	testErrorsSize = 32768;
+	testErrors[testErrorsSize] = 0;
+    } else {
+        testErrorsSize += res;
+    }
+    testErrors[testErrorsSize] = 0;
+}
+
+static void XMLCDECL
+channel(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
+    va_list args;
+    int res;
+
+    if (testErrorsSize >= 32768)
+        return;
+    va_start(args, msg);
+    res = vsnprintf(&testErrors[testErrorsSize],
+                    32768 - testErrorsSize,
+		    msg, args);
+    va_end(args);
+    if (testErrorsSize + res >= 32768) {
+        /* buffer is full */
+	testErrorsSize = 32768;
+	testErrors[testErrorsSize] = 0;
+    } else {
+        testErrorsSize += res;
+    }
+    testErrors[testErrorsSize] = 0;
+}
+
+/**
+ * xmlParserPrintFileContext:
+ * @input:  an xmlParserInputPtr input
+ *
+ * Displays current context within the input content for error tracking
+ */
+
+static void
+xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
+		xmlGenericErrorFunc chanl, void *data ) {
+    const xmlChar *cur, *base;
+    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
+    xmlChar  content[81]; /* space for 80 chars + line terminator */
+    xmlChar *ctnt;
+
+    if (input == NULL) return;
+    cur = input->cur;
+    base = input->base;
+    /* skip backwards over any end-of-lines */
+    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
+	cur--;
+    }
+    n = 0;
+    /* search backwards for beginning-of-line (to max buff size) */
+    while ((n++ < (sizeof(content)-1)) && (cur > base) &&
+   (*(cur) != '\n') && (*(cur) != '\r'))
+        cur--;
+    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+    /* calculate the error position in terms of the current position */
+    col = input->cur - cur;
+    /* search forward for end-of-line (to max buff size) */
+    n = 0;
+    ctnt = content;
+    /* copy selected text to our buffer */
+    while ((*cur != 0) && (*(cur) != '\n') &&
+   (*(cur) != '\r') && (n < sizeof(content)-1)) {
+		*ctnt++ = *cur++;
+	n++;
+    }
+    *ctnt = 0;
+    /* print out the selected text */
+    chanl(data ,"%s\n", content);
+    /* create blank line with problem pointer */
+    n = 0;
+    ctnt = content;
+    /* (leave buffer space for pointer + line terminator) */
+    while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
+	if (*(ctnt) != '\t')
+	    *(ctnt) = ' ';
+	ctnt++;
+    }
+    *ctnt++ = '^';
+    *ctnt = 0;
+    chanl(data ,"%s\n", content);
+}
+
+static void
+testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+    char *file = NULL;
+    int line = 0;
+    int code = -1;
+    int domain;
+    void *data = NULL;
+    const char *str;
+    const xmlChar *name = NULL;
+    xmlNodePtr node;
+    xmlErrorLevel level;
+    xmlParserInputPtr input = NULL;
+    xmlParserInputPtr cur = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+
+    if (err == NULL)
+        return;
+
+    file = err->file;
+    line = err->line;
+    code = err->code;
+    domain = err->domain;
+    level = err->level;
+    node = err->node;
+    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
+        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
+	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
+	ctxt = err->ctxt;
+    }
+    str = err->message;
+
+    if (code == XML_ERR_OK)
+        return;
+
+    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+        name = node->name;
+
+    /*
+     * Maintain the compatibility with the legacy error handling
+     */
+    if (ctxt != NULL) {
+        input = ctxt->input;
+        if ((input != NULL) && (input->filename == NULL) &&
+            (ctxt->inputNr > 1)) {
+            cur = input;
+            input = ctxt->inputTab[ctxt->inputNr - 2];
+        }
+        if (input != NULL) {
+            if (input->filename)
+                channel(data, "%s:%d: ", input->filename, input->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: ", input->line);
+        }
+    } else {
+        if (file != NULL)
+            channel(data, "%s:%d: ", file, line);
+        else if ((line != 0) && (domain == XML_FROM_PARSER))
+            channel(data, "Entity: line %d: ", line);
+    }
+    if (name != NULL) {
+        channel(data, "element %s: ", name);
+    }
+    if (code == XML_ERR_OK)
+        return;
+    switch (domain) {
+        case XML_FROM_PARSER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_NAMESPACE:
+            channel(data, "namespace ");
+            break;
+        case XML_FROM_DTD:
+        case XML_FROM_VALID:
+            channel(data, "validity ");
+            break;
+        case XML_FROM_HTML:
+            channel(data, "HTML parser ");
+            break;
+        case XML_FROM_MEMORY:
+            channel(data, "memory ");
+            break;
+        case XML_FROM_OUTPUT:
+            channel(data, "output ");
+            break;
+        case XML_FROM_IO:
+            channel(data, "I/O ");
+            break;
+        case XML_FROM_XINCLUDE:
+            channel(data, "XInclude ");
+            break;
+        case XML_FROM_XPATH:
+            channel(data, "XPath ");
+            break;
+        case XML_FROM_XPOINTER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_REGEXP:
+            channel(data, "regexp ");
+            break;
+        case XML_FROM_MODULE:
+            channel(data, "module ");
+            break;
+        case XML_FROM_SCHEMASV:
+            channel(data, "Schemas validity ");
+            break;
+        case XML_FROM_SCHEMASP:
+            channel(data, "Schemas parser ");
+            break;
+        case XML_FROM_RELAXNGP:
+            channel(data, "Relax-NG parser ");
+            break;
+        case XML_FROM_RELAXNGV:
+            channel(data, "Relax-NG validity ");
+            break;
+        case XML_FROM_CATALOG:
+            channel(data, "Catalog ");
+            break;
+        case XML_FROM_C14N:
+            channel(data, "C14N ");
+            break;
+        case XML_FROM_XSLT:
+            channel(data, "XSLT ");
+            break;
+        default:
+            break;
+    }
+    if (code == XML_ERR_OK)
+        return;
+    switch (level) {
+        case XML_ERR_NONE:
+            channel(data, ": ");
+            break;
+        case XML_ERR_WARNING:
+            channel(data, "warning : ");
+            break;
+        case XML_ERR_ERROR:
+            channel(data, "error : ");
+            break;
+        case XML_ERR_FATAL:
+            channel(data, "error : ");
+            break;
+    }
+    if (code == XML_ERR_OK)
+        return;
+    if (str != NULL) {
+        int len;
+	len = xmlStrlen((const xmlChar *)str);
+	if ((len > 0) && (str[len - 1] != '\n'))
+	    channel(data, "%s\n", str);
+	else
+	    channel(data, "%s", str);
+    } else {
+        channel(data, "%s\n", "out of memory error");
+    }
+    if (code == XML_ERR_OK)
+        return;
+
+    if (ctxt != NULL) {
+        xmlParserPrintFileContextInternal(input, channel, data);
+        if (cur != NULL) {
+            if (cur->filename)
+                channel(data, "%s:%d: \n", cur->filename, cur->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: \n", cur->line);
+            xmlParserPrintFileContextInternal(cur, channel, data);
+        }
+    }
+    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
+        (err->int1 < 100) &&
+	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
+	xmlChar buf[150];
+	int i;
+
+	channel(data, "%s\n", err->str1);
+	for (i=0;i < err->int1;i++)
+	     buf[i] = ' ';
+	buf[i++] = '^';
+	buf[i] = 0;
+	channel(data, "%s\n", buf);
+    }
+}
+
+static void
+initializeLibxml2(void) {
+    xmlGetWarningsDefaultValue = 0;
+    xmlPedanticParserDefault(0);
+
+    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
+    xmlInitParser();
+    xmlSetExternalEntityLoader(testExternalEntityLoader);
+    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlSchemaInitTypes();
+    xmlRelaxNGInitTypes();
+#endif
+}
+
+
+/************************************************************************
+ *									*
+ *		File name and path utilities				*
+ *									*
+ ************************************************************************/
+
+static const char *baseFilename(const char *filename) {
+    const char *cur;
+    if (filename == NULL)
+        return(NULL);
+    cur = &filename[strlen(filename)];
+    while ((cur > filename) && (*cur != '/'))
+        cur--;
+    if (*cur == '/')
+        return(cur + 1);
+    return(cur);
+}
+
+static char *resultFilename(const char *filename, const char *out,
+                            const char *suffix) {
+    const char *base;
+    char res[500];
+    char suffixbuff[500];
+
+/*************
+    if ((filename[0] == 't') && (filename[1] == 'e') &&
+        (filename[2] == 's') && (filename[3] == 't') &&
+	(filename[4] == '/'))
+	filename = &filename[5];
+ *************/
+
+    base = baseFilename(filename);
+    if (suffix == NULL)
+        suffix = ".tmp";
+    if (out == NULL)
+        out = "";
+
+    strncpy(suffixbuff,suffix,499);
+#ifdef VMS
+    if(strstr(base,".") && suffixbuff[0]=='.')
+      suffixbuff[0]='_';
+#endif
+
+    snprintf(res, 499, "%s%s%s", out, base, suffixbuff);
+    res[499] = 0;
+    return(strdup(res));
+}
+
+static int checkTestFile(const char *filename) {
+    struct stat buf;
+
+    if (stat(filename, &buf) == -1)
+        return(0);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    if (!(buf.st_mode & _S_IFREG))
+        return(0);
+#else
+    if (!S_ISREG(buf.st_mode))
+        return(0);
+#endif
+
+    return(1);
+}
+
+static int compareFiles(const char *r1, const char *r2) {
+    int res1, res2;
+    int fd1, fd2;
+    char bytes1[4096];
+    char bytes2[4096];
+
+    fd1 = open(r1, RD_FLAGS);
+    if (fd1 < 0)
+        return(-1);
+    fd2 = open(r2, RD_FLAGS);
+    if (fd2 < 0) {
+        close(fd1);
+        return(-1);
+    }
+    while (1) {
+        res1 = read(fd1, bytes1, 4096);
+        res2 = read(fd2, bytes2, 4096);
+	if ((res1 != res2) || (res1 < 0)) {
+	    close(fd1);
+	    close(fd2);
+	    return(1);
+	}
+	if (res1 == 0)
+	    break;
+	if (memcmp(bytes1, bytes2, res1) != 0) {
+	    close(fd1);
+	    close(fd2);
+	    return(1);
+	}
+    }
+    close(fd1);
+    close(fd2);
+    return(0);
+}
+
+static int compareFileMem(const char *filename, const char *mem, int size) {
+    int res;
+    int fd;
+    char bytes[4096];
+    int idx = 0;
+    struct stat info;
+
+    if (stat(filename, &info) < 0)
+	return(-1);
+    if (info.st_size != size)
+        return(-1);
+    fd = open(filename, RD_FLAGS);
+    if (fd < 0)
+        return(-1);
+    while (idx < size) {
+        res = read(fd, bytes, 4096);
+	if (res <= 0)
+	    break;
+	if (res + idx > size)
+	    break;
+	if (memcmp(bytes, &mem[idx], res) != 0) {
+	    int ix;
+	    for (ix=0; ix<res; ix++)
+		if (bytes[ix] != mem[idx+ix])
+			break;
+	    fprintf(stderr,"Compare error at position %d\n", idx+ix);
+	    close(fd);
+	    return(1);
+	}
+	idx += res;
+    }
+    close(fd);
+    return(idx != size);
+}
+
+static int loadMem(const char *filename, const char **mem, int *size) {
+    int fd, res;
+    struct stat info;
+    char *base;
+    int siz = 0;
+    if (stat(filename, &info) < 0)
+	return(-1);
+    base = malloc(info.st_size + 1);
+    if (base == NULL)
+	return(-1);
+    if ((fd = open(filename, RD_FLAGS)) < 0) {
+        free(base);
+	return(-1);
+    }
+    while ((res = read(fd, &base[siz], info.st_size - siz)) > 0) {
+        siz += res;
+    }
+    close(fd);
+#if !defined(_WIN32)
+    if (siz != info.st_size) {
+        free(base);
+	return(-1);
+    }
+#endif
+    base[siz] = 0;
+    *mem = base;
+    *size = siz;
+    return(0);
+}
+
+static int unloadMem(const char *mem) {
+    free((char *)mem);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *		Tests implementations					*
+ *									*
+ ************************************************************************/
+
+/************************************************************************
+ *									*
+ *		Parse to SAX based tests				*
+ *									*
+ ************************************************************************/
+
+static FILE *SAXdebug = NULL;
+
+/*
+ * empty SAX block
+ */
+static xmlSAXHandler emptySAXHandlerStruct = {
+    NULL, /* internalSubset */
+    NULL, /* isStandalone */
+    NULL, /* hasInternalSubset */
+    NULL, /* hasExternalSubset */
+    NULL, /* resolveEntity */
+    NULL, /* getEntity */
+    NULL, /* entityDecl */
+    NULL, /* notationDecl */
+    NULL, /* attributeDecl */
+    NULL, /* elementDecl */
+    NULL, /* unparsedEntityDecl */
+    NULL, /* setDocumentLocator */
+    NULL, /* startDocument */
+    NULL, /* endDocument */
+    NULL, /* startElement */
+    NULL, /* endElement */
+    NULL, /* reference */
+    NULL, /* characters */
+    NULL, /* ignorableWhitespace */
+    NULL, /* processingInstruction */
+    NULL, /* comment */
+    NULL, /* xmlParserWarning */
+    NULL, /* xmlParserError */
+    NULL, /* xmlParserError */
+    NULL, /* getParameterEntity */
+    NULL, /* cdataBlock; */
+    NULL, /* externalSubset; */
+    1,
+    NULL,
+    NULL, /* startElementNs */
+    NULL, /* endElementNs */
+    NULL  /* xmlStructuredErrorFunc */
+};
+
+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
+static int callbacks = 0;
+static int quiet = 0;
+
+/**
+ * isStandaloneDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(SAXdebug, "SAX.isStandalone()\n");
+    return(0);
+}
+
+/**
+ * hasInternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(SAXdebug, "SAX.hasInternalSubset()\n");
+    return(0);
+}
+
+/**
+ * hasExternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(SAXdebug, "SAX.hasExternalSubset()\n");
+    return(0);
+}
+
+/**
+ * internalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.internalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(SAXdebug, " ,");
+    else
+	fprintf(SAXdebug, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(SAXdebug, " )\n");
+    else
+	fprintf(SAXdebug, " %s)\n", SystemID);
+}
+
+/**
+ * externalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.externalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(SAXdebug, " ,");
+    else
+	fprintf(SAXdebug, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(SAXdebug, " )\n");
+    else
+	fprintf(SAXdebug, " %s)\n", SystemID);
+}
+
+/**
+ * resolveEntityDebug:
+ * @ctxt:  An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+
+
+    fprintf(SAXdebug, "SAX.resolveEntity(");
+    if (publicId != NULL)
+	fprintf(SAXdebug, "%s", (char *)publicId);
+    else
+	fprintf(SAXdebug, " ");
+    if (systemId != NULL)
+	fprintf(SAXdebug, ", %s)\n", (char *)systemId);
+    else
+	fprintf(SAXdebug, ", )\n");
+/*********
+    if (systemId != NULL) {
+        return(xmlNewInputFromFile(ctxt, (char *) systemId));
+    }
+ *********/
+    return(NULL);
+}
+
+/**
+ * getEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    fprintf(SAXdebug, "SAX.getEntity(%s)\n", name);
+    return(NULL);
+}
+
+/**
+ * getParameterEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    fprintf(SAXdebug, "SAX.getParameterEntity(%s)\n", name);
+    return(NULL);
+}
+
+
+/**
+ * entityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @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).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+    /* not all libraries handle printing null pointers nicely */
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (content == NULL)
+        content = (xmlChar *)nullstr;
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
+            name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the attribute name
+ * @type:  the attribute type
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
+                   const xmlChar * name, int type, int def,
+                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
+{
+    callbacks++;
+    if (quiet)
+        return;
+    if (defaultValue == NULL)
+        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
+                elem, name, type, def);
+    else
+        fprintf(SAXdebug, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
+                elem, name, type, def, defaultValue);
+    xmlFreeEnumeration(tree);
+}
+
+/**
+ * elementDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the element name
+ * @type:  the element type
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.elementDecl(%s, %d, ...)\n",
+            name, type);
+}
+
+/**
+ * notationDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.notationDecl(%s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId);
+}
+
+/**
+ * unparsedEntityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (notationName == NULL)
+        notationName = nullstr;
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId,
+	    (char *) notationName);
+}
+
+/**
+ * setDocumentLocatorDebug:
+ * @ctxt:  An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.setDocumentLocator()\n");
+}
+
+/**
+ * startDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.startDocument()\n");
+}
+
+/**
+ * endDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.endDocument()\n");
+}
+
+/**
+ * startElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+	    fprintf(SAXdebug, ", %s='", atts[i++]);
+	    if (atts[i] != NULL)
+	        fprintf(SAXdebug, "%s'", atts[i]);
+	}
+    }
+    fprintf(SAXdebug, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.endElement(%s)\n", (char *) name);
+}
+
+/**
+ * charactersDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char output[40];
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	output[i] = ch[i];
+    output[i] = 0;
+
+    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);
+}
+
+/**
+ * referenceDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected.
+ */
+static void
+referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.reference(%s)\n", name);
+}
+
+/**
+ * ignorableWhitespaceDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char output[40];
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	output[i] = ch[i];
+    output[i] = 0;
+    fprintf(SAXdebug, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
+}
+
+/**
+ * processingInstructionDebug:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+                      const xmlChar *data)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    if (data != NULL)
+	fprintf(SAXdebug, "SAX.processingInstruction(%s, %s)\n",
+		(char *) target, (char *) data);
+    else
+	fprintf(SAXdebug, "SAX.processingInstruction(%s, NULL)\n",
+		(char *) target);
+}
+
+/**
+ * cdataBlockDebug:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.pcdata(%.20s, %d)\n",
+	    (char *) value, len);
+}
+
+/**
+ * commentDebug:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.comment(%s)\n", value);
+}
+
+/**
+ * warningDebug:
+ * @ctxt:  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.
+ */
+static void XMLCDECL
+warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(SAXdebug, "SAX.warning: ");
+    vfprintf(SAXdebug, msg, args);
+    va_end(args);
+}
+
+/**
+ * errorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(SAXdebug, "SAX.error: ");
+    vfprintf(SAXdebug, msg, args);
+    va_end(args);
+}
+
+/**
+ * fatalErrorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(SAXdebug, "SAX.fatalError: ");
+    vfprintf(SAXdebug, msg, args);
+    va_end(args);
+}
+
+static xmlSAXHandler debugSAXHandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    startElementDebug,
+    endElementDebug,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    1,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+static xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
+
+/*
+ * SAX2 specific callbacks
+ */
+/**
+ * startElementNsDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                    const xmlChar *localname,
+                    const xmlChar *prefix,
+                    const xmlChar *URI,
+		    int nb_namespaces,
+		    const xmlChar **namespaces,
+		    int nb_attributes,
+		    int nb_defaulted,
+		    const xmlChar **attributes)
+{
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.startElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(SAXdebug, ", NULL");
+    else
+	fprintf(SAXdebug, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(SAXdebug, ", NULL");
+    else
+	fprintf(SAXdebug, ", '%s'", (char *) URI);
+    fprintf(SAXdebug, ", %d", nb_namespaces);
+
+    if (namespaces != NULL) {
+        for (i = 0;i < nb_namespaces * 2;i++) {
+	    fprintf(SAXdebug, ", xmlns");
+	    if (namespaces[i] != NULL)
+	        fprintf(SAXdebug, ":%s", namespaces[i]);
+	    i++;
+	    fprintf(SAXdebug, "='%s'", namespaces[i]);
+	}
+    }
+    fprintf(SAXdebug, ", %d, %d", nb_attributes, nb_defaulted);
+    if (attributes != NULL) {
+        for (i = 0;i < nb_attributes * 5;i += 5) {
+	    if (attributes[i + 1] != NULL)
+		fprintf(SAXdebug, ", %s:%s='", attributes[i + 1], attributes[i]);
+	    else
+		fprintf(SAXdebug, ", %s='", attributes[i]);
+	    fprintf(SAXdebug, "%.4s...', %d", attributes[i + 3],
+		    (int)(attributes[i + 4] - attributes[i + 3]));
+	}
+    }
+    fprintf(SAXdebug, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                  const xmlChar *localname,
+                  const xmlChar *prefix,
+                  const xmlChar *URI)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(SAXdebug, "SAX.endElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(SAXdebug, ", NULL");
+    else
+	fprintf(SAXdebug, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(SAXdebug, ", NULL)\n");
+    else
+	fprintf(SAXdebug, ", '%s')\n", (char *) URI);
+}
+
+static xmlSAXHandler debugSAX2HandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    NULL,
+    NULL,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    XML_SAX2_MAGIC,
+    NULL,
+    startElementNsDebug,
+    endElementNsDebug,
+    NULL
+};
+
+static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
+
+#ifdef LIBXML_HTML_ENABLED
+/**
+ * htmlstartElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+htmlstartElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    fprintf(SAXdebug, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+	    fprintf(SAXdebug, ", %s", atts[i++]);
+	    if (atts[i] != NULL) {
+		unsigned char output[40];
+		const unsigned char *att = atts[i];
+		int outlen, attlen;
+	        fprintf(SAXdebug, "='");
+		while ((attlen = strlen((char*)att)) > 0) {
+		    outlen = sizeof output - 1;
+		    htmlEncodeEntities(output, &outlen, att, &attlen, '\'');
+		    output[outlen] = 0;
+		    fprintf(SAXdebug, "%s", (char *) output);
+		    att += attlen;
+		}
+		fprintf(SAXdebug, "'");
+	    }
+	}
+    }
+    fprintf(SAXdebug, ")\n");
+}
+
+/**
+ * htmlcharactersDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+htmlcharactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    unsigned char output[40];
+    int inlen = len, outlen = 30;
+
+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
+    output[outlen] = 0;
+
+    fprintf(SAXdebug, "SAX.characters(%s, %d)\n", output, len);
+}
+
+/**
+ * htmlcdataDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some cdata chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+htmlcdataDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    unsigned char output[40];
+    int inlen = len, outlen = 30;
+
+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
+    output[outlen] = 0;
+
+    fprintf(SAXdebug, "SAX.cdata(%s, %d)\n", output, len);
+}
+
+static xmlSAXHandler debugHTMLSAXHandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    htmlstartElementDebug,
+    endElementDebug,
+    referenceDebug,
+    htmlcharactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    htmlcdataDebug,
+    externalSubsetDebug,
+    1,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+static xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;
+#endif /* LIBXML_HTML_ENABLED */
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * saxParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file using the SAX API and check for errors.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+saxParseTest(const char *filename, const char *result,
+             const char *err ATTRIBUTE_UNUSED,
+             int options) {
+    int ret;
+    char *temp;
+
+    nb_tests++;
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "out of memory\n");
+        fatalError();
+    }
+    SAXdebug = fopen(temp, "wb");
+    if (SAXdebug == NULL) {
+        fprintf(stderr, "Failed to write to %s\n", temp);
+	free(temp);
+	return(-1);
+    }
+
+    /* for SAX we really want the callbacks though the context handlers */
+    xmlSetStructuredErrorFunc(NULL, NULL);
+    xmlSetGenericErrorFunc(NULL, testErrorHandler);
+
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML) {
+	htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
+	ret = 0;
+    } else
+#endif
+    ret = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
+    if (ret == XML_WAR_UNDECLARED_ENTITY) {
+        fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
+        ret = 0;
+    }
+    if (ret != 0) {
+        fprintf(stderr, "Failed to parse %s\n", filename);
+	return(1);
+    }
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML) {
+	htmlSAXParseFile(filename, NULL, debugHTMLSAXHandler, NULL);
+	ret = 0;
+    } else
+#endif
+    if (options & XML_PARSE_SAX1) {
+	ret = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
+    } else {
+	ret = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
+    }
+    if (ret == XML_WAR_UNDECLARED_ENTITY) {
+        fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret);
+        ret = 0;
+    }
+    fclose(SAXdebug);
+    if (compareFiles(temp, result)) {
+        fprintf(stderr, "Got a difference for %s\n", filename);
+        ret = 1;
+    }
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+
+    /* switch back to structured error handling */
+    xmlSetGenericErrorFunc(NULL, NULL);
+    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+
+    return(ret);
+}
+#endif
+
+/************************************************************************
+ *									*
+ *		Parse to tree based tests				*
+ *									*
+ ************************************************************************/
+/**
+ * oldParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages: unused
+ *
+ * Parse a file using the old xmlParseFile API, then serialize back
+ * reparse the result and serialize again, then check for deviation
+ * in serialization.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+oldParseTest(const char *filename, const char *result,
+             const char *err ATTRIBUTE_UNUSED,
+	     int options ATTRIBUTE_UNUSED) {
+    xmlDocPtr doc;
+    char *temp;
+    int res = 0;
+
+    nb_tests++;
+    /*
+     * base of the test, parse with the old API
+     */
+#ifdef LIBXML_SAX1_ENABLED
+    doc = xmlParseFile(filename);
+#else
+    doc = xmlReadFile(filename, NULL, 0);
+#endif
+    if (doc == NULL)
+        return(1);
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "out of memory\n");
+        fatalError();
+    }
+    xmlSaveFile(temp, doc);
+    if (compareFiles(temp, result)) {
+        res = 1;
+    }
+    xmlFreeDoc(doc);
+
+    /*
+     * Parse the saved result to make sure the round trip is okay
+     */
+#ifdef LIBXML_SAX1_ENABLED
+    doc = xmlParseFile(temp);
+#else
+    doc = xmlReadFile(temp, NULL, 0);
+#endif
+    if (doc == NULL)
+        return(1);
+    xmlSaveFile(temp, doc);
+    if (compareFiles(temp, result)) {
+        res = 1;
+    }
+    xmlFreeDoc(doc);
+
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    return(res);
+}
+
+#ifdef LIBXML_PUSH_ENABLED
+/**
+ * pushParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages: unused
+ *
+ * Parse a file using the Push API, then serialize back
+ * to check for content.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+pushParseTest(const char *filename, const char *result,
+             const char *err ATTRIBUTE_UNUSED,
+	     int options) {
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr doc;
+    const char *base;
+    int size, res;
+    int cur = 0;
+
+    nb_tests++;
+    /*
+     * load the document in memory and work from there.
+     */
+    if (loadMem(filename, &base, &size) != 0) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML)
+	ctxt = htmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename,
+	                                XML_CHAR_ENCODING_NONE);
+    else
+#endif
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);
+    xmlCtxtUseOptions(ctxt, options);
+    cur += 4;
+    while (cur < size) {
+        if (cur + 1024 >= size) {
+#ifdef LIBXML_HTML_ENABLED
+	    if (options & XML_PARSE_HTML)
+		htmlParseChunk(ctxt, base + cur, size - cur, 1);
+	    else
+#endif
+	    xmlParseChunk(ctxt, base + cur, size - cur, 1);
+	    break;
+	} else {
+#ifdef LIBXML_HTML_ENABLED
+	    if (options & XML_PARSE_HTML)
+		htmlParseChunk(ctxt, base + cur, 1024, 0);
+	    else
+#endif
+	    xmlParseChunk(ctxt, base + cur, 1024, 0);
+	    cur += 1024;
+	}
+    }
+    doc = ctxt->myDoc;
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML)
+        res = 1;
+    else
+#endif
+    res = ctxt->wellFormed;
+    xmlFreeParserCtxt(ctxt);
+    free((char *)base);
+    if (!res) {
+	xmlFreeDoc(doc);
+	fprintf(stderr, "Failed to parse %s\n", filename);
+	return(-1);
+    }
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML)
+	htmlDocDumpMemory(doc, (xmlChar **) &base, &size);
+    else
+#endif
+    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
+    xmlFreeDoc(doc);
+    res = compareFileMem(result, base, size);
+    if ((base == NULL) || (res != 0)) {
+	if (base != NULL)
+	    xmlFree((char *)base);
+        fprintf(stderr, "Result for %s failed\n", filename);
+	return(-1);
+    }
+    xmlFree((char *)base);
+    if (err != NULL) {
+	res = compareFileMem(err, testErrors, testErrorsSize);
+	if (res != 0) {
+	    fprintf(stderr, "Error for %s failed\n", filename);
+	    return(-1);
+	}
+    }
+    return(0);
+}
+#endif
+
+/**
+ * memParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages: unused
+ *
+ * Parse a file using the old xmlReadMemory API, then serialize back
+ * reparse the result and serialize again, then check for deviation
+ * in serialization.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+memParseTest(const char *filename, const char *result,
+             const char *err ATTRIBUTE_UNUSED,
+	     int options ATTRIBUTE_UNUSED) {
+    xmlDocPtr doc;
+    const char *base;
+    int size, res;
+
+    nb_tests++;
+    /*
+     * load and parse the memory
+     */
+    if (loadMem(filename, &base, &size) != 0) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+
+    doc = xmlReadMemory(base, size, filename, NULL, 0);
+    unloadMem(base);
+    if (doc == NULL) {
+        return(1);
+    }
+    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
+    xmlFreeDoc(doc);
+    res = compareFileMem(result, base, size);
+    if ((base == NULL) || (res != 0)) {
+	if (base != NULL)
+	    xmlFree((char *)base);
+        fprintf(stderr, "Result for %s failed\n", filename);
+	return(-1);
+    }
+    xmlFree((char *)base);
+    return(0);
+}
+
+/**
+ * noentParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages: unused
+ *
+ * Parse a file with entity resolution, then serialize back
+ * reparse the result and serialize again, then check for deviation
+ * in serialization.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+noentParseTest(const char *filename, const char *result,
+               const char *err  ATTRIBUTE_UNUSED,
+	       int options) {
+    xmlDocPtr doc;
+    char *temp;
+    int res = 0;
+
+    nb_tests++;
+    /*
+     * base of the test, parse with the old API
+     */
+    doc = xmlReadFile(filename, NULL, options);
+    if (doc == NULL)
+        return(1);
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    xmlSaveFile(temp, doc);
+    if (compareFiles(temp, result)) {
+        res = 1;
+    }
+    xmlFreeDoc(doc);
+
+    /*
+     * Parse the saved result to make sure the round trip is okay
+     */
+    doc = xmlReadFile(filename, NULL, options);
+    if (doc == NULL)
+        return(1);
+    xmlSaveFile(temp, doc);
+    if (compareFiles(temp, result)) {
+        res = 1;
+    }
+    xmlFreeDoc(doc);
+
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    return(res);
+}
+
+/**
+ * errParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file using the xmlReadFile API and check for errors.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+errParseTest(const char *filename, const char *result, const char *err,
+             int options) {
+    xmlDocPtr doc;
+    const char *base = NULL;
+    int size, res = 0;
+
+    nb_tests++;
+#ifdef LIBXML_HTML_ENABLED
+    if (options & XML_PARSE_HTML) {
+        doc = htmlReadFile(filename, NULL, options);
+    } else
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+    if (options & XML_PARSE_XINCLUDE) {
+	doc = xmlReadFile(filename, NULL, options);
+	xmlXIncludeProcessFlags(doc, options);
+    } else
+#endif
+    {
+	xmlGetWarningsDefaultValue = 1;
+	doc = xmlReadFile(filename, NULL, options);
+    }
+    xmlGetWarningsDefaultValue = 0;
+    if (result) {
+	if (doc == NULL) {
+	    base = "";
+	    size = 0;
+	} else {
+#ifdef LIBXML_HTML_ENABLED
+	    if (options & XML_PARSE_HTML) {
+		htmlDocDumpMemory(doc, (xmlChar **) &base, &size);
+	    } else
+#endif
+	    xmlDocDumpMemory(doc, (xmlChar **) &base, &size);
+	}
+	res = compareFileMem(result, base, size);
+    }
+    if (doc != NULL) {
+	if (base != NULL)
+	    xmlFree((char *)base);
+	xmlFreeDoc(doc);
+    }
+    if (res != 0) {
+        fprintf(stderr, "Result for %s failed\n", filename);
+	return(-1);
+    }
+    if (err != NULL) {
+	res = compareFileMem(err, testErrors, testErrorsSize);
+	if (res != 0) {
+	    fprintf(stderr, "Error for %s failed\n", filename);
+	    return(-1);
+	}
+    } else if (options & XML_PARSE_DTDVALID) {
+        if (testErrorsSize != 0)
+	    fprintf(stderr, "Validation for %s failed\n", filename);
+    }
+
+    return(0);
+}
+
+#ifdef LIBXML_READER_ENABLED
+/************************************************************************
+ *									*
+ *		Reader based tests					*
+ *									*
+ ************************************************************************/
+
+static void processNode(FILE *out, xmlTextReaderPtr reader) {
+    const xmlChar *name, *value;
+    int type, empty;
+
+    type = xmlTextReaderNodeType(reader);
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    name = xmlTextReaderConstName(reader);
+    if (name == NULL)
+	name = BAD_CAST "--";
+
+    value = xmlTextReaderConstValue(reader);
+
+
+    fprintf(out, "%d %d %s %d %d",
+	    xmlTextReaderDepth(reader),
+	    type,
+	    name,
+	    empty,
+	    xmlTextReaderHasValue(reader));
+    if (value == NULL)
+	fprintf(out, "\n");
+    else {
+	fprintf(out, " %s\n", value);
+    }
+}
+static int
+streamProcessTest(const char *filename, const char *result, const char *err,
+                  xmlTextReaderPtr reader, const char *rng) {
+    int ret;
+    char *temp = NULL;
+    FILE *t = NULL;
+
+    if (reader == NULL)
+        return(-1);
+
+    nb_tests++;
+    if (result != NULL) {
+	temp = resultFilename(filename, "", ".res");
+	if (temp == NULL) {
+	    fprintf(stderr, "Out of memory\n");
+	    fatalError();
+	}
+	t = fopen(temp, "wb");
+	if (t == NULL) {
+	    fprintf(stderr, "Can't open temp file %s\n", temp);
+	    free(temp);
+	    return(-1);
+	}
+    }
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (rng != NULL) {
+	ret = xmlTextReaderRelaxNGValidate(reader, rng);
+	if (ret < 0) {
+	    testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n",
+	                     rng);
+	    fclose(t);
+            if (temp != NULL) {
+                unlink(temp);
+                free(temp);
+            }
+	    return(0);
+	}
+    }
+#endif
+    xmlGetWarningsDefaultValue = 1;
+    ret = xmlTextReaderRead(reader);
+    while (ret == 1) {
+	if ((t != NULL) && (rng == NULL))
+	    processNode(t, reader);
+        ret = xmlTextReaderRead(reader);
+    }
+    if (ret != 0) {
+        testErrorHandler(NULL, "%s : failed to parse\n", filename);
+    }
+    if (rng != NULL) {
+        if (xmlTextReaderIsValid(reader) != 1) {
+	    testErrorHandler(NULL, "%s fails to validate\n", filename);
+	} else {
+	    testErrorHandler(NULL, "%s validates\n", filename);
+	}
+    }
+    xmlGetWarningsDefaultValue = 0;
+    if (t != NULL) {
+        fclose(t);
+	ret = compareFiles(temp, result);
+        if (temp != NULL) {
+            unlink(temp);
+            free(temp);
+        }
+	if (ret) {
+	    fprintf(stderr, "Result for %s failed\n", filename);
+	    return(-1);
+	}
+    }
+    if (err != NULL) {
+	ret = compareFileMem(err, testErrors, testErrorsSize);
+	if (ret != 0) {
+	    fprintf(stderr, "Error for %s failed\n", filename);
+	    printf("%s", testErrors);
+	    return(-1);
+	}
+    }
+
+    return(0);
+}
+
+/**
+ * streamParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file using the reader API and check for errors.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+streamParseTest(const char *filename, const char *result, const char *err,
+                int options) {
+    xmlTextReaderPtr reader;
+    int ret;
+
+    reader = xmlReaderForFile(filename, NULL, options);
+    ret = streamProcessTest(filename, result, err, reader, NULL);
+    xmlFreeTextReader(reader);
+    return(ret);
+}
+
+/**
+ * walkerParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file using the walker, i.e. a reader built from a atree.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+walkerParseTest(const char *filename, const char *result, const char *err,
+                int options) {
+    xmlDocPtr doc;
+    xmlTextReaderPtr reader;
+    int ret;
+
+    doc = xmlReadFile(filename, NULL, options);
+    if (doc == NULL) {
+        fprintf(stderr, "Failed to parse %s\n", filename);
+	return(-1);
+    }
+    reader = xmlReaderWalker(doc);
+    ret = streamProcessTest(filename, result, err, reader, NULL);
+    xmlFreeTextReader(reader);
+    xmlFreeDoc(doc);
+    return(ret);
+}
+
+/**
+ * streamMemParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file using the reader API from memory and check for errors.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+streamMemParseTest(const char *filename, const char *result, const char *err,
+                   int options) {
+    xmlTextReaderPtr reader;
+    int ret;
+    const char *base;
+    int size;
+
+    /*
+     * load and parse the memory
+     */
+    if (loadMem(filename, &base, &size) != 0) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+    reader = xmlReaderForMemory(base, size, filename, NULL, options);
+    ret = streamProcessTest(filename, result, err, reader, NULL);
+    free((char *)base);
+    xmlFreeTextReader(reader);
+    return(ret);
+}
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+/************************************************************************
+ *									*
+ *		XPath and XPointer based tests				*
+ *									*
+ ************************************************************************/
+
+static FILE *xpathOutput;
+static xmlDocPtr xpathDocument;
+
+static void
+testXPath(const char *str, int xptr, int expr) {
+    xmlXPathObjectPtr res;
+    xmlXPathContextPtr ctxt;
+
+    nb_tests++;
+#if defined(LIBXML_XPTR_ENABLED)
+    if (xptr) {
+	ctxt = xmlXPtrNewContext(xpathDocument, NULL, NULL);
+	res = xmlXPtrEval(BAD_CAST str, ctxt);
+    } else {
+#endif
+	ctxt = xmlXPathNewContext(xpathDocument);
+	ctxt->node = xmlDocGetRootElement(xpathDocument);
+	if (expr)
+	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
+	else {
+	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */
+	    xmlXPathCompExprPtr comp;
+
+	    comp = xmlXPathCompile(BAD_CAST str);
+	    if (comp != NULL) {
+		res = xmlXPathCompiledEval(comp, ctxt);
+		xmlXPathFreeCompExpr(comp);
+	    } else
+		res = NULL;
+	}
+#if defined(LIBXML_XPTR_ENABLED)
+    }
+#endif
+    xmlXPathDebugDumpObject(xpathOutput, res, 0);
+    xmlXPathFreeObject(res);
+    xmlXPathFreeContext(ctxt);
+}
+
+/**
+ * xpathExprTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing XPath standalone expressions and evaluate them
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+xpathCommonTest(const char *filename, const char *result,
+                int xptr, int expr) {
+    FILE *input;
+    char expression[5000];
+    int len, ret = 0;
+    char *temp;
+
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    xpathOutput = fopen(temp, "wb");
+    if (xpathOutput == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+        free(temp);
+	return(-1);
+    }
+
+    input = fopen(filename, "rb");
+    if (input == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot open %s for reading\n", filename);
+        free(temp);
+	return(-1);
+    }
+    while (fgets(expression, 4500, input) != NULL) {
+	len = strlen(expression);
+	len--;
+	while ((len >= 0) &&
+	       ((expression[len] == '\n') || (expression[len] == '\t') ||
+		(expression[len] == '\r') || (expression[len] == ' '))) len--;
+	expression[len + 1] = 0;
+	if (len >= 0) {
+	    fprintf(xpathOutput,
+	            "\n========================\nExpression: %s\n",
+		    expression) ;
+	    testXPath(expression, xptr, expr);
+	}
+    }
+
+    fclose(input);
+    fclose(xpathOutput);
+    if (result != NULL) {
+	ret = compareFiles(temp, result);
+	if (ret) {
+	    fprintf(stderr, "Result for %s failed\n", filename);
+	}
+    }
+
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    return(ret);
+}
+
+/**
+ * xpathExprTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing XPath standalone expressions and evaluate them
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+xpathExprTest(const char *filename, const char *result,
+              const char *err ATTRIBUTE_UNUSED,
+              int options ATTRIBUTE_UNUSED) {
+    return(xpathCommonTest(filename, result, 0, 1));
+}
+
+/**
+ * xpathDocTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing XPath expressions and evaluate them against
+ * a set of corresponding documents.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+xpathDocTest(const char *filename,
+             const char *resul ATTRIBUTE_UNUSED,
+             const char *err ATTRIBUTE_UNUSED,
+             int options) {
+
+    char pattern[500];
+    char result[500];
+    glob_t globbuf;
+    size_t i;
+    int ret = 0, res;
+
+    xpathDocument = xmlReadFile(filename, NULL,
+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (xpathDocument == NULL) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+
+    snprintf(pattern, 499, "./test/XPath/tests/%s*", baseFilename(filename));
+    pattern[499] = 0;
+    globbuf.gl_offs = 0;
+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
+    for (i = 0;i < globbuf.gl_pathc;i++) {
+        snprintf(result, 499, "result/XPath/tests/%s",
+	         baseFilename(globbuf.gl_pathv[i]));
+	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 0, 0);
+	if (res != 0)
+	    ret = res;
+    }
+    globfree(&globbuf);
+
+    xmlFreeDoc(xpathDocument);
+    return(ret);
+}
+
+#ifdef LIBXML_XPTR_ENABLED
+/**
+ * xptrDocTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing XPath expressions and evaluate them against
+ * a set of corresponding documents.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+xptrDocTest(const char *filename,
+            const char *resul ATTRIBUTE_UNUSED,
+            const char *err ATTRIBUTE_UNUSED,
+            int options) {
+
+    char pattern[500];
+    char result[500];
+    glob_t globbuf;
+    size_t i;
+    int ret = 0, res;
+
+    xpathDocument = xmlReadFile(filename, NULL,
+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (xpathDocument == NULL) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+
+    snprintf(pattern, 499, "./test/XPath/xptr/%s*", baseFilename(filename));
+    pattern[499] = 0;
+    globbuf.gl_offs = 0;
+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
+    for (i = 0;i < globbuf.gl_pathc;i++) {
+        snprintf(result, 499, "result/XPath/xptr/%s",
+	         baseFilename(globbuf.gl_pathv[i]));
+	res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 1, 0);
+	if (res != 0)
+	    ret = res;
+    }
+    globfree(&globbuf);
+
+    xmlFreeDoc(xpathDocument);
+    return(ret);
+}
+#endif /* LIBXML_XPTR_ENABLED */
+
+/**
+ * xmlidDocTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing xml:id and check for errors and verify
+ * that XPath queries will work on them as expected.
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+xmlidDocTest(const char *filename,
+             const char *result,
+             const char *err,
+             int options) {
+
+    int res = 0;
+    int ret = 0;
+    char *temp;
+
+    xpathDocument = xmlReadFile(filename, NULL,
+                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (xpathDocument == NULL) {
+        fprintf(stderr, "Failed to load %s\n", filename);
+	return(-1);
+    }
+
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    xpathOutput = fopen(temp, "wb");
+    if (xpathOutput == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+        xmlFreeDoc(xpathDocument);
+        free(temp);
+	return(-1);
+    }
+
+    testXPath("id('bar')", 0, 0);
+
+    fclose(xpathOutput);
+    if (result != NULL) {
+	ret = compareFiles(temp, result);
+	if (ret) {
+	    fprintf(stderr, "Result for %s failed\n", filename);
+	    res = 1;
+	}
+    }
+
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    xmlFreeDoc(xpathDocument);
+
+    if (err != NULL) {
+	ret = compareFileMem(err, testErrors, testErrorsSize);
+	if (ret != 0) {
+	    fprintf(stderr, "Error for %s failed\n", filename);
+	    res = 1;
+	}
+    }
+    return(res);
+}
+
+#endif /* LIBXML_DEBUG_ENABLED */
+#endif /* XPATH */
+/************************************************************************
+ *									*
+ *			URI based tests					*
+ *									*
+ ************************************************************************/
+
+static void
+handleURI(const char *str, const char *base, FILE *o) {
+    int ret;
+    xmlURIPtr uri;
+    xmlChar *res = NULL;
+
+    uri = xmlCreateURI();
+
+    if (base == NULL) {
+	ret = xmlParseURIReference(uri, str);
+	if (ret != 0)
+	    fprintf(o, "%s : error %d\n", str, ret);
+	else {
+	    xmlNormalizeURIPath(uri->path);
+	    xmlPrintURI(o, uri);
+	    fprintf(o, "\n");
+	}
+    } else {
+	res = xmlBuildURI((xmlChar *)str, (xmlChar *) base);
+	if (res != NULL) {
+	    fprintf(o, "%s\n", (char *) res);
+	}
+	else
+	    fprintf(o, "::ERROR::\n");
+    }
+    if (res != NULL)
+	xmlFree(res);
+    xmlFreeURI(uri);
+}
+
+/**
+ * uriCommonTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing URI and check for errors
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+uriCommonTest(const char *filename,
+             const char *result,
+             const char *err,
+             const char *base) {
+    char *temp;
+    FILE *o, *f;
+    char str[1024];
+    int res = 0, i, ret;
+
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    o = fopen(temp, "wb");
+    if (o == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+        free(temp);
+	return(-1);
+    }
+    f = fopen(filename, "rb");
+    if (f == NULL) {
+	fprintf(stderr, "failed to open input file %s\n", filename);
+	fclose(o);
+        if (temp != NULL) {
+            unlink(temp);
+            free(temp);
+        }
+	return(-1);
+    }
+
+    while (1) {
+	/*
+	 * read one line in string buffer.
+	 */
+	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)
+	   break;
+
+	/*
+	 * remove the ending spaces
+	 */
+	i = strlen(str);
+	while ((i > 0) &&
+	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||
+		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {
+	    i--;
+	    str[i] = 0;
+	}
+	nb_tests++;
+	handleURI(str, base, o);
+    }
+
+    fclose(f);
+    fclose(o);
+
+    if (result != NULL) {
+	ret = compareFiles(temp, result);
+	if (ret) {
+	    fprintf(stderr, "Result for %s failed\n", filename);
+	    res = 1;
+	}
+    }
+    if (err != NULL) {
+	ret = compareFileMem(err, testErrors, testErrorsSize);
+	if (ret != 0) {
+	    fprintf(stderr, "Error for %s failed\n", filename);
+	    res = 1;
+	}
+    }
+
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    return(res);
+}
+
+/**
+ * uriParseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing URI and check for errors
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+uriParseTest(const char *filename,
+             const char *result,
+             const char *err,
+             int options ATTRIBUTE_UNUSED) {
+    return(uriCommonTest(filename, result, err, NULL));
+}
+
+/**
+ * uriBaseTest:
+ * @filename: the file to parse
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing URI, compose them against a fixed base and
+ * check for errors
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+uriBaseTest(const char *filename,
+             const char *result,
+             const char *err,
+             int options ATTRIBUTE_UNUSED) {
+    return(uriCommonTest(filename, result, err,
+                         "http://foo.com/path/to/index.html?orig#help"));
+}
+
+static int urip_success = 1;
+static int urip_current = 0;
+static const char *urip_testURLs[] = {
+    "urip://example.com/a b.html",
+    "urip://example.com/a%20b.html",
+    "file:///path/to/a b.html",
+    "file:///path/to/a%20b.html",
+    "/path/to/a b.html",
+    "/path/to/a%20b.html",
+    "urip://example.com/résumé.html",
+    "urip://example.com/test?a=1&b=2%263&c=4#foo",
+    NULL
+};
+static const char *urip_rcvsURLs[] = {
+    /* it is an URI the strings must be escaped */
+    "urip://example.com/a%20b.html",
+    /* check that % escaping is not broken */
+    "urip://example.com/a%20b.html",
+    /* it's an URI path the strings must be escaped */
+    "file:///path/to/a%20b.html",
+    /* check that % escaping is not broken */
+    "file:///path/to/a%20b.html",
+    /* this is not an URI, this is a path, so this should not be escaped */
+    "/path/to/a b.html",
+    /* check that paths with % are not broken */
+    "/path/to/a%20b.html",
+    /* out of context the encoding can't be guessed byte by byte conversion */
+    "urip://example.com/r%E9sum%E9.html",
+    /* verify we don't destroy URIs especially the query part */
+    "urip://example.com/test?a=1&b=2%263&c=4#foo",
+    NULL
+};
+static const char *urip_res = "<list/>";
+static const char *urip_cur = NULL;
+static int urip_rlen;
+
+/**
+ * uripMatch:
+ * @URI: an URI to test
+ *
+ * Check for an urip: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+static int
+uripMatch(const char * URI) {
+    if ((URI == NULL) || (!strcmp(URI, "file:///etc/xml/catalog")))
+        return(0);
+    /* Verify we received the escaped URL */
+    if (strcmp(urip_rcvsURLs[urip_current], URI))
+	urip_success = 0;
+    return(1);
+}
+
+/**
+ * uripOpen:
+ * @URI: an URI to test
+ *
+ * Return a pointer to the urip: query handler, in this example simply
+ * the urip_current pointer...
+ *
+ * Returns an Input context or NULL in case or error
+ */
+static void *
+uripOpen(const char * URI) {
+    if ((URI == NULL) || (!strcmp(URI, "file:///etc/xml/catalog")))
+        return(NULL);
+    /* Verify we received the escaped URL */
+    if (strcmp(urip_rcvsURLs[urip_current], URI))
+	urip_success = 0;
+    urip_cur = urip_res;
+    urip_rlen = strlen(urip_res);
+    return((void *) urip_cur);
+}
+
+/**
+ * uripClose:
+ * @context: the read context
+ *
+ * Close the urip: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+static int
+uripClose(void * context) {
+    if (context == NULL) return(-1);
+    urip_cur = NULL;
+    urip_rlen = 0;
+    return(0);
+}
+
+/**
+ * uripRead:
+ * @context: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an urip: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+static int
+uripRead(void * context, char * buffer, int len) {
+   const char *ptr = (const char *) context;
+
+   if ((context == NULL) || (buffer == NULL) || (len < 0))
+       return(-1);
+
+   if (len > urip_rlen) len = urip_rlen;
+   memcpy(buffer, ptr, len);
+   urip_rlen -= len;
+   return(len);
+}
+
+static int
+urip_checkURL(const char *URL) {
+    xmlDocPtr doc;
+
+    doc = xmlReadFile(URL, NULL, 0);
+    if (doc == NULL)
+        return(-1);
+    xmlFreeDoc(doc);
+    return(1);
+}
+
+/**
+ * uriPathTest:
+ * @filename: ignored
+ * @result: ignored
+ * @err: ignored
+ *
+ * Run a set of tests to check how Path and URI are handled before
+ * being passed to the I/O layer
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+uriPathTest(const char *filename ATTRIBUTE_UNUSED,
+             const char *result ATTRIBUTE_UNUSED,
+             const char *err ATTRIBUTE_UNUSED,
+             int options ATTRIBUTE_UNUSED) {
+    int parsed;
+    int failures = 0;
+
+    /*
+     * register the new I/O handlers
+     */
+    if (xmlRegisterInputCallbacks(uripMatch, uripOpen, uripRead, uripClose) < 0)
+    {
+        fprintf(stderr, "failed to register HTTP handler\n");
+	return(-1);
+    }
+
+    for (urip_current = 0;urip_testURLs[urip_current] != NULL;urip_current++) {
+        urip_success = 1;
+        parsed = urip_checkURL(urip_testURLs[urip_current]);
+	if (urip_success != 1) {
+	    fprintf(stderr, "failed the URL passing test for %s",
+	            urip_testURLs[urip_current]);
+	    failures++;
+	} else if (parsed != 1) {
+	    fprintf(stderr, "failed the parsing test for %s",
+	            urip_testURLs[urip_current]);
+	    failures++;
+	}
+	nb_tests++;
+    }
+
+    xmlPopInputCallbacks();
+    return(failures);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+/************************************************************************
+ *									*
+ *			Schemas tests					*
+ *									*
+ ************************************************************************/
+static int
+schemasOneTest(const char *sch,
+               const char *filename,
+               const char *result,
+	       const char *err,
+	       int options,
+	       xmlSchemaPtr schemas) {
+    xmlDocPtr doc;
+    xmlSchemaValidCtxtPtr ctxt;
+    int ret = 0;
+    int validResult = 0;
+    char *temp;
+    FILE *schemasOutput;
+
+    doc = xmlReadFile(filename, NULL, options);
+    if (doc == NULL) {
+        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
+	return(-1);
+    }
+
+    temp = resultFilename(result, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    schemasOutput = fopen(temp, "wb");
+    if (schemasOutput == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+	xmlFreeDoc(doc);
+        free(temp);
+	return(-1);
+    }
+
+    ctxt = xmlSchemaNewValidCtxt(schemas);
+    xmlSchemaSetValidErrors(ctxt,
+         (xmlSchemaValidityErrorFunc) testErrorHandler,
+         (xmlSchemaValidityWarningFunc) testErrorHandler,
+	 ctxt);
+    validResult = xmlSchemaValidateDoc(ctxt, doc);
+    if (validResult == 0) {
+	fprintf(schemasOutput, "%s validates\n", filename);
+    } else if (validResult > 0) {
+	fprintf(schemasOutput, "%s fails to validate\n", filename);
+    } else {
+	fprintf(schemasOutput, "%s validation generated an internal error\n",
+	       filename);
+    }
+    fclose(schemasOutput);
+    if (result) {
+	if (compareFiles(temp, result)) {
+	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
+	    ret = 1;
+	}
+    }
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+
+    if ((validResult != 0) && (err != NULL)) {
+	if (compareFileMem(err, testErrors, testErrorsSize)) {
+	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
+	    ret = 1;
+	}
+    }
+
+    xmlSchemaFreeValidCtxt(ctxt);
+    xmlFreeDoc(doc);
+    return(ret);
+}
+/**
+ * schemasTest:
+ * @filename: the schemas file
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a file containing URI, compose them against a fixed base and
+ * check for errors
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+schemasTest(const char *filename,
+            const char *resul ATTRIBUTE_UNUSED,
+            const char *errr ATTRIBUTE_UNUSED,
+            int options) {
+    const char *base = baseFilename(filename);
+    const char *base2;
+    const char *instance;
+    xmlSchemaParserCtxtPtr ctxt;
+    xmlSchemaPtr schemas;
+    int res = 0, len, ret;
+    char pattern[500];
+    char prefix[500];
+    char result[500];
+    char err[500];
+    glob_t globbuf;
+    size_t i;
+    char count = 0;
+
+    /* first compile the schemas if possible */
+    ctxt = xmlSchemaNewParserCtxt(filename);
+    xmlSchemaSetParserErrors(ctxt,
+         (xmlSchemaValidityErrorFunc) testErrorHandler,
+         (xmlSchemaValidityWarningFunc) testErrorHandler,
+	 ctxt);
+    schemas = xmlSchemaParse(ctxt);
+    xmlSchemaFreeParserCtxt(ctxt);
+
+    /*
+     * most of the mess is about the output filenames generated by the Makefile
+     */
+    len = strlen(base);
+    if ((len > 499) || (len < 5)) {
+        xmlSchemaFree(schemas);
+	return(-1);
+    }
+    len -= 4; /* remove trailing .xsd */
+    if (base[len - 2] == '_') {
+        len -= 2; /* remove subtest number */
+    }
+    if (base[len - 2] == '_') {
+        len -= 2; /* remove subtest number */
+    }
+    memcpy(prefix, base, len);
+    prefix[len] = 0;
+
+    snprintf(pattern, 499, "./test/schemas/%s_?.xml", prefix);
+    pattern[499] = 0;
+
+    if (base[len] == '_') {
+        len += 2;
+	memcpy(prefix, base, len);
+	prefix[len] = 0;
+    }
+
+    globbuf.gl_offs = 0;
+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
+    for (i = 0;i < globbuf.gl_pathc;i++) {
+        testErrorsSize = 0;
+	testErrors[0] = 0;
+        instance = globbuf.gl_pathv[i];
+	base2 = baseFilename(instance);
+	len = strlen(base2);
+	if ((len > 6) && (base2[len - 6] == '_')) {
+	    count = base2[len - 5];
+	    snprintf(result, 499, "result/schemas/%s_%c",
+		     prefix, count);
+	    result[499] = 0;
+	    snprintf(err, 499, "result/schemas/%s_%c.err",
+		     prefix, count);
+	    err[499] = 0;
+	} else {
+	    fprintf(stderr, "don't know how to process %s\n", instance);
+	    continue;
+	}
+	if (schemas == NULL) {
+	} else {
+	    nb_tests++;
+	    ret = schemasOneTest(filename, instance, result, err,
+	                         options, schemas);
+	    if (ret != 0)
+		res = ret;
+	}
+    }
+    globfree(&globbuf);
+    xmlSchemaFree(schemas);
+
+    return(res);
+}
+
+/************************************************************************
+ *									*
+ *			Schemas tests					*
+ *									*
+ ************************************************************************/
+static int
+rngOneTest(const char *sch,
+               const char *filename,
+               const char *result,
+	       const char *err,
+	       int options,
+	       xmlRelaxNGPtr schemas) {
+    xmlDocPtr doc;
+    xmlRelaxNGValidCtxtPtr ctxt;
+    int ret = 0;
+    char *temp;
+    FILE *schemasOutput;
+
+    doc = xmlReadFile(filename, NULL, options);
+    if (doc == NULL) {
+        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
+	return(-1);
+    }
+
+    temp = resultFilename(result, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    schemasOutput = fopen(temp, "wb");
+    if (schemasOutput == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+	xmlFreeDoc(doc);
+        free(temp);
+	return(-1);
+    }
+
+    ctxt = xmlRelaxNGNewValidCtxt(schemas);
+    xmlRelaxNGSetValidErrors(ctxt,
+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+	 ctxt);
+    ret = xmlRelaxNGValidateDoc(ctxt, doc);
+    if (ret == 0) {
+	testErrorHandler(NULL, "%s validates\n", filename);
+    } else if (ret > 0) {
+	testErrorHandler(NULL, "%s fails to validate\n", filename);
+    } else {
+	testErrorHandler(NULL, "%s validation generated an internal error\n",
+	       filename);
+    }
+    fclose(schemasOutput);
+    ret = 0;
+    if (result) {
+	if (compareFiles(temp, result)) {
+	    fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
+	    ret = 1;
+	}
+    }
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+
+    if (err != NULL) {
+	if (compareFileMem(err, testErrors, testErrorsSize)) {
+	    fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
+	    ret = 1;
+	    printf("%s", testErrors);
+	}
+    }
+
+
+    xmlRelaxNGFreeValidCtxt(ctxt);
+    xmlFreeDoc(doc);
+    return(ret);
+}
+/**
+ * rngTest:
+ * @filename: the schemas file
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse an RNG schemas and then apply it to the related .xml
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+rngTest(const char *filename,
+            const char *resul ATTRIBUTE_UNUSED,
+            const char *errr ATTRIBUTE_UNUSED,
+            int options) {
+    const char *base = baseFilename(filename);
+    const char *base2;
+    const char *instance;
+    xmlRelaxNGParserCtxtPtr ctxt;
+    xmlRelaxNGPtr schemas;
+    int res = 0, len, ret = 0;
+    char pattern[500];
+    char prefix[500];
+    char result[500];
+    char err[500];
+    glob_t globbuf;
+    size_t i;
+    char count = 0;
+
+    /* first compile the schemas if possible */
+    ctxt = xmlRelaxNGNewParserCtxt(filename);
+    xmlRelaxNGSetParserErrors(ctxt,
+         (xmlRelaxNGValidityErrorFunc) testErrorHandler,
+         (xmlRelaxNGValidityWarningFunc) testErrorHandler,
+	 ctxt);
+    schemas = xmlRelaxNGParse(ctxt);
+    xmlRelaxNGFreeParserCtxt(ctxt);
+
+    /*
+     * most of the mess is about the output filenames generated by the Makefile
+     */
+    len = strlen(base);
+    if ((len > 499) || (len < 5)) {
+        xmlRelaxNGFree(schemas);
+	return(-1);
+    }
+    len -= 4; /* remove trailing .rng */
+    memcpy(prefix, base, len);
+    prefix[len] = 0;
+
+    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);
+    pattern[499] = 0;
+
+    globbuf.gl_offs = 0;
+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
+    for (i = 0;i < globbuf.gl_pathc;i++) {
+        testErrorsSize = 0;
+	testErrors[0] = 0;
+        instance = globbuf.gl_pathv[i];
+	base2 = baseFilename(instance);
+	len = strlen(base2);
+	if ((len > 6) && (base2[len - 6] == '_')) {
+	    count = base2[len - 5];
+	    snprintf(result, 499, "result/relaxng/%s_%c",
+		     prefix, count);
+	    result[499] = 0;
+	    snprintf(err, 499, "result/relaxng/%s_%c.err",
+		     prefix, count);
+	    err[499] = 0;
+	} else {
+	    fprintf(stderr, "don't know how to process %s\n", instance);
+	    continue;
+	}
+	if (schemas == NULL) {
+	} else {
+	    nb_tests++;
+	    ret = rngOneTest(filename, instance, result, err,
+	                         options, schemas);
+	    if (res != 0)
+		ret = res;
+	}
+    }
+    globfree(&globbuf);
+    xmlRelaxNGFree(schemas);
+
+    return(ret);
+}
+
+#ifdef LIBXML_READER_ENABLED
+/**
+ * rngStreamTest:
+ * @filename: the schemas file
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a set of files with streaming, applying an RNG schemas
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+rngStreamTest(const char *filename,
+            const char *resul ATTRIBUTE_UNUSED,
+            const char *errr ATTRIBUTE_UNUSED,
+            int options) {
+    const char *base = baseFilename(filename);
+    const char *base2;
+    const char *instance;
+    int res = 0, len, ret;
+    char pattern[500];
+    char prefix[500];
+    char result[500];
+    char err[500];
+    glob_t globbuf;
+    size_t i;
+    char count = 0;
+    xmlTextReaderPtr reader;
+    int disable_err = 0;
+
+    /*
+     * most of the mess is about the output filenames generated by the Makefile
+     */
+    len = strlen(base);
+    if ((len > 499) || (len < 5)) {
+	fprintf(stderr, "len(base) == %d !\n", len);
+	return(-1);
+    }
+    len -= 4; /* remove trailing .rng */
+    memcpy(prefix, base, len);
+    prefix[len] = 0;
+
+    /*
+     * strictly unifying the error messages is nearly impossible this
+     * hack is also done in the Makefile
+     */
+    if ((!strcmp(prefix, "tutor10_1")) || (!strcmp(prefix, "tutor10_2")) ||
+        (!strcmp(prefix, "tutor3_2")) || (!strcmp(prefix, "307377")) ||
+        (!strcmp(prefix, "tutor8_2")))
+	disable_err = 1;
+
+    snprintf(pattern, 499, "./test/relaxng/%s_?.xml", prefix);
+    pattern[499] = 0;
+
+    globbuf.gl_offs = 0;
+    glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
+    for (i = 0;i < globbuf.gl_pathc;i++) {
+        testErrorsSize = 0;
+	testErrors[0] = 0;
+        instance = globbuf.gl_pathv[i];
+	base2 = baseFilename(instance);
+	len = strlen(base2);
+	if ((len > 6) && (base2[len - 6] == '_')) {
+	    count = base2[len - 5];
+	    snprintf(result, 499, "result/relaxng/%s_%c",
+		     prefix, count);
+	    result[499] = 0;
+	    snprintf(err, 499, "result/relaxng/%s_%c.err",
+		     prefix, count);
+	    err[499] = 0;
+	} else {
+	    fprintf(stderr, "don't know how to process %s\n", instance);
+	    continue;
+	}
+	reader = xmlReaderForFile(instance, NULL, options);
+	if (reader == NULL) {
+	    fprintf(stderr, "Failed to build reder for %s\n", instance);
+	}
+	if (disable_err == 1)
+	    ret = streamProcessTest(instance, result, NULL, reader, filename);
+	else
+	    ret = streamProcessTest(instance, result, err, reader, filename);
+	xmlFreeTextReader(reader);
+	if (ret != 0) {
+	    fprintf(stderr, "instance %s failed\n", instance);
+	    res = ret;
+	}
+    }
+    globfree(&globbuf);
+
+    return(res);
+}
+#endif /* READER */
+
+#endif
+
+#ifdef LIBXML_PATTERN_ENABLED
+#ifdef LIBXML_READER_ENABLED
+/************************************************************************
+ *									*
+ *			Patterns tests					*
+ *									*
+ ************************************************************************/
+static void patternNode(FILE *out, xmlTextReaderPtr reader,
+                        const char *pattern, xmlPatternPtr patternc,
+			xmlStreamCtxtPtr patstream) {
+    xmlChar *path = NULL;
+    int match = -1;
+    int type, empty;
+
+    type = xmlTextReaderNodeType(reader);
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (type == XML_READER_TYPE_ELEMENT) {
+	/* do the check only on element start */
+	match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
+
+	if (match) {
+	    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
+	    fprintf(out, "Node %s matches pattern %s\n", path, pattern);
+	}
+    }
+    if (patstream != NULL) {
+	int ret;
+
+	if (type == XML_READER_TYPE_ELEMENT) {
+	    ret = xmlStreamPush(patstream,
+				xmlTextReaderConstLocalName(reader),
+				xmlTextReaderConstNamespaceUri(reader));
+	    if (ret < 0) {
+		fprintf(out, "xmlStreamPush() failure\n");
+		xmlFreeStreamCtxt(patstream);
+		patstream = NULL;
+	    } else if (ret != match) {
+		if (path == NULL) {
+		    path = xmlGetNodePath(
+				   xmlTextReaderCurrentNode(reader));
+		}
+		fprintf(out,
+			"xmlPatternMatch and xmlStreamPush disagree\n");
+		fprintf(out,
+			"  pattern %s node %s\n",
+			pattern, path);
+	    }
+
+
+	}
+	if ((type == XML_READER_TYPE_END_ELEMENT) ||
+	    ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
+	    ret = xmlStreamPop(patstream);
+	    if (ret < 0) {
+		fprintf(out, "xmlStreamPop() failure\n");
+		xmlFreeStreamCtxt(patstream);
+		patstream = NULL;
+	    }
+	}
+    }
+    if (path != NULL)
+	xmlFree(path);
+}
+
+/**
+ * patternTest:
+ * @filename: the schemas file
+ * @result: the file with expected result
+ * @err: the file with error messages
+ *
+ * Parse a set of files with streaming, applying an RNG schemas
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+patternTest(const char *filename,
+            const char *resul ATTRIBUTE_UNUSED,
+            const char *err ATTRIBUTE_UNUSED,
+            int options) {
+    xmlPatternPtr patternc = NULL;
+    xmlStreamCtxtPtr patstream = NULL;
+    FILE *o, *f;
+    char str[1024];
+    char xml[500];
+    char result[500];
+    int len, i;
+    int ret = 0, res;
+    char *temp;
+    xmlTextReaderPtr reader;
+    xmlDocPtr doc;
+
+    len = strlen(filename);
+    len -= 4;
+    memcpy(xml, filename, len);
+    xml[len] = 0;
+    snprintf(result, 499, "result/pattern/%s", baseFilename(xml));
+    result[499] = 0;
+    memcpy(xml + len, ".xml", 5);
+
+    if (!checkTestFile(xml)) {
+	fprintf(stderr, "Missing xml file %s\n", xml);
+	return(-1);
+    }
+    if (!checkTestFile(result)) {
+	fprintf(stderr, "Missing result file %s\n", result);
+	return(-1);
+    }
+    f = fopen(filename, "rb");
+    if (f == NULL) {
+        fprintf(stderr, "Failed to open %s\n", filename);
+	return(-1);
+    }
+    temp = resultFilename(filename, "", ".res");
+    if (temp == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        fatalError();
+    }
+    o = fopen(temp, "wb");
+    if (o == NULL) {
+	fprintf(stderr, "failed to open output file %s\n", temp);
+	fclose(f);
+        free(temp);
+	return(-1);
+    }
+    while (1) {
+	/*
+	 * read one line in string buffer.
+	 */
+	if (fgets (&str[0], sizeof (str) - 1, f) == NULL)
+	   break;
+
+	/*
+	 * remove the ending spaces
+	 */
+	i = strlen(str);
+	while ((i > 0) &&
+	       ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||
+		(str[i - 1] == ' ') || (str[i - 1] == '\t'))) {
+	    i--;
+	    str[i] = 0;
+	}
+	doc = xmlReadFile(xml, NULL, options);
+	if (doc == NULL) {
+	    fprintf(stderr, "Failed to parse %s\n", xml);
+	    ret = 1;
+	} else {
+	    xmlNodePtr root;
+	    const xmlChar *namespaces[22];
+	    int j;
+	    xmlNsPtr ns;
+
+	    root = xmlDocGetRootElement(doc);
+	    for (ns = root->nsDef, j = 0;ns != NULL && j < 20;ns=ns->next) {
+		namespaces[j++] = ns->href;
+		namespaces[j++] = ns->prefix;
+	    }
+	    namespaces[j++] = NULL;
+	    namespaces[j] = NULL;
+
+	    patternc = xmlPatterncompile((const xmlChar *) str, doc->dict,
+					 0, &namespaces[0]);
+	    if (patternc == NULL) {
+		testErrorHandler(NULL,
+			"Pattern %s failed to compile\n", str);
+		xmlFreeDoc(doc);
+		ret = 1;
+		continue;
+	    }
+	    patstream = xmlPatternGetStreamCtxt(patternc);
+	    if (patstream != NULL) {
+		ret = xmlStreamPush(patstream, NULL, NULL);
+		if (ret < 0) {
+		    fprintf(stderr, "xmlStreamPush() failure\n");
+		    xmlFreeStreamCtxt(patstream);
+		    patstream = NULL;
+		}
+	    }
+	    nb_tests++;
+
+	    reader = xmlReaderWalker(doc);
+	    res = xmlTextReaderRead(reader);
+	    while (res == 1) {
+		patternNode(o, reader, str, patternc, patstream);
+		res = xmlTextReaderRead(reader);
+	    }
+	    if (res != 0) {
+		fprintf(o, "%s : failed to parse\n", filename);
+	    }
+	    xmlFreeTextReader(reader);
+	    xmlFreeDoc(doc);
+	    xmlFreeStreamCtxt(patstream);
+	    patstream = NULL;
+	    xmlFreePattern(patternc);
+
+	}
+    }
+
+    fclose(f);
+    fclose(o);
+
+    ret = compareFiles(temp, result);
+    if (ret) {
+	fprintf(stderr, "Result for %s failed\n", filename);
+	ret = 1;
+    }
+    if (temp != NULL) {
+        unlink(temp);
+        free(temp);
+    }
+    return(ret);
+}
+#endif /* READER */
+#endif /* PATTERN */
+#ifdef LIBXML_C14N_ENABLED
+/************************************************************************
+ *									*
+ *			Canonicalization tests				*
+ *									*
+ ************************************************************************/
+static xmlXPathObjectPtr
+load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
+    xmlXPathObjectPtr xpath;
+    xmlDocPtr doc;
+    xmlChar *expr;
+    xmlXPathContextPtr ctx;
+    xmlNodePtr node;
+    xmlNsPtr ns;
+
+    /*
+     * load XPath expr as a file
+     */
+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+
+    doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (doc == NULL) {
+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
+	return(NULL);
+    }
+
+    /*
+     * Check the document is of the right kind
+     */
+    if(xmlDocGetRootElement(doc) == NULL) {
+        fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    node = doc->children;
+    while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {
+	node = node->next;
+    }
+
+    if(node == NULL) {
+        fprintf(stderr,"Error: XPath element expected in the file  \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    expr = xmlNodeGetContent(node);
+    if(expr == NULL) {
+        fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    ctx = xmlXPathNewContext(parent_doc);
+    if(ctx == NULL) {
+        fprintf(stderr,"Error: unable to create new context\n");
+        xmlFree(expr);
+        xmlFreeDoc(doc);
+        return(NULL);
+    }
+
+    /*
+     * Register namespaces
+     */
+    ns = node->nsDef;
+    while(ns != NULL) {
+	if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {
+	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);
+    xmlFree(expr);
+	    xmlXPathFreeContext(ctx);
+	    xmlFreeDoc(doc);
+	    return(NULL);
+	}
+	ns = ns->next;
+    }
+
+    /*
+     * Evaluate xpath
+     */
+    xpath = xmlXPathEvalExpression(expr, ctx);
+    if(xpath == NULL) {
+        fprintf(stderr,"Error: unable to evaluate xpath expression\n");
+xmlFree(expr);
+        xmlXPathFreeContext(ctx);
+        xmlFreeDoc(doc);
+        return(NULL);
+    }
+
+    /* print_xpath_nodes(xpath->nodesetval); */
+
+    xmlFree(expr);
+    xmlXPathFreeContext(ctx);
+    xmlFreeDoc(doc);
+    return(xpath);
+}
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define xxx_growBufferReentrant() {						\
+    buffer_size *= 2;							\
+    buffer = (xmlChar **)						\
+	xmlRealloc(buffer, buffer_size * sizeof(xmlChar*));	\
+    if (buffer == NULL) {						\
+	perror("realloc failed");					\
+	return(NULL);							\
+    }									\
+}
+
+static xmlChar **
+parse_list(xmlChar *str) {
+    xmlChar **buffer;
+    xmlChar **out = NULL;
+    int buffer_size = 0;
+    int len;
+
+    if(str == NULL) {
+	return(NULL);
+    }
+
+    len = xmlStrlen(str);
+    if((str[0] == '\'') && (str[len - 1] == '\'')) {
+	str[len - 1] = '\0';
+	str++;
+    }
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));
+    if (buffer == NULL) {
+	perror("malloc failed");
+	return(NULL);
+    }
+    out = buffer;
+
+    while(*str != '\0') {
+	if (out - buffer > buffer_size - 10) {
+	    int indx = out - buffer;
+
+	    xxx_growBufferReentrant();
+	    out = &buffer[indx];
+	}
+	(*out++) = str;
+	while(*str != ',' && *str != '\0') ++str;
+	if(*str == ',') *(str++) = '\0';
+    }
+    (*out) = NULL;
+    return buffer;
+}
+
+static int
+c14nRunTest(const char* xml_filename, int with_comments, int mode,
+	    const char* xpath_filename, const char *ns_filename,
+	    const char* result_file) {
+    xmlDocPtr doc;
+    xmlXPathObjectPtr xpath = NULL;
+    xmlChar *result = NULL;
+    int ret;
+    xmlChar **inclusive_namespaces = NULL;
+    const char *nslist = NULL;
+    int nssize;
+
+
+    /*
+     * build an XML tree from a the file; we need to add default
+     * attributes and resolve all character and entities references
+     */
+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+
+    doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (doc == NULL) {
+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
+	return(-1);
+    }
+
+    /*
+     * Check the document is of the right kind
+     */
+    if(xmlDocGetRootElement(doc) == NULL) {
+        fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);
+	xmlFreeDoc(doc);
+	return(-1);
+    }
+
+    /*
+     * load xpath file if specified
+     */
+    if(xpath_filename) {
+	xpath = load_xpath_expr(doc, xpath_filename);
+	if(xpath == NULL) {
+	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
+	    xmlFreeDoc(doc);
+	    return(-1);
+	}
+    }
+
+    if (ns_filename != NULL) {
+        if (loadMem(ns_filename, &nslist, &nssize)) {
+	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
+	    if(xpath != NULL) xmlXPathFreeObject(xpath);
+	    xmlFreeDoc(doc);
+	    return(-1);
+	}
+        inclusive_namespaces = parse_list((xmlChar *) nslist);
+    }
+
+    /*
+     * Canonical form
+     */
+    /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
+    ret = xmlC14NDocDumpMemory(doc,
+	    (xpath) ? xpath->nodesetval : NULL,
+	    mode, inclusive_namespaces,
+	    with_comments, &result);
+    if (ret >= 0) {
+	if(result != NULL) {
+	    if (compareFileMem(result_file, (const char *) result, ret)) {
+		fprintf(stderr, "Result mismatch for %s\n", xml_filename);
+		fprintf(stderr, "RESULT:\n%s\n", (const char*)result);
+	        ret = -1;
+	    }
+	}
+    } else {
+	fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);
+	ret = -1;
+    }
+
+    /*
+     * Cleanup
+     */
+    if (result != NULL) xmlFree(result);
+    if(xpath != NULL) xmlXPathFreeObject(xpath);
+    if (inclusive_namespaces != NULL) xmlFree(inclusive_namespaces);
+    if (nslist != NULL) free((char *) nslist);
+    xmlFreeDoc(doc);
+
+    return(ret);
+}
+
+static int
+c14nCommonTest(const char *filename, int with_comments, int mode,
+               const char *subdir) {
+    char buf[500];
+    char prefix[500];
+    const char *base;
+    int len;
+    char *result = NULL;
+    char *xpath = NULL;
+    char *ns = NULL;
+    int ret = 0;
+
+    base = baseFilename(filename);
+    len = strlen(base);
+    len -= 4;
+    memcpy(prefix, base, len);
+    prefix[len] = 0;
+
+    snprintf(buf, 499, "result/c14n/%s/%s", subdir,prefix);
+    if (!checkTestFile(buf)) {
+        fprintf(stderr, "Missing result file %s", buf);
+	return(-1);
+    }
+    result = strdup(buf);
+    snprintf(buf, 499, "test/c14n/%s/%s.xpath", subdir,prefix);
+    if (checkTestFile(buf)) {
+	xpath = strdup(buf);
+    }
+    snprintf(buf, 499, "test/c14n/%s/%s.ns", subdir,prefix);
+    if (checkTestFile(buf)) {
+	ns = strdup(buf);
+    }
+
+    nb_tests++;
+    if (c14nRunTest(filename, with_comments, mode,
+                    xpath, ns, result) < 0)
+        ret = 1;
+
+    if (result != NULL) free(result);
+    if (xpath != NULL) free(xpath);
+    if (ns != NULL) free(ns);
+    return(ret);
+}
+
+static int
+c14nWithCommentTest(const char *filename,
+                    const char *resul ATTRIBUTE_UNUSED,
+		    const char *err ATTRIBUTE_UNUSED,
+		    int options ATTRIBUTE_UNUSED) {
+    return(c14nCommonTest(filename, 1, XML_C14N_1_0, "with-comments"));
+}
+static int
+c14nWithoutCommentTest(const char *filename,
+                    const char *resul ATTRIBUTE_UNUSED,
+		    const char *err ATTRIBUTE_UNUSED,
+		    int options ATTRIBUTE_UNUSED) {
+    return(c14nCommonTest(filename, 0, XML_C14N_1_0, "without-comments"));
+}
+static int
+c14nExcWithoutCommentTest(const char *filename,
+                    const char *resul ATTRIBUTE_UNUSED,
+		    const char *err ATTRIBUTE_UNUSED,
+		    int options ATTRIBUTE_UNUSED) {
+    return(c14nCommonTest(filename, 0, XML_C14N_EXCLUSIVE_1_0, "exc-without-comments"));
+}
+static int
+c14n11WithoutCommentTest(const char *filename,
+                    const char *resul ATTRIBUTE_UNUSED,
+		    const char *err ATTRIBUTE_UNUSED,
+		    int options ATTRIBUTE_UNUSED) {
+    return(c14nCommonTest(filename, 0, XML_C14N_1_1, "1-1-without-comments"));
+}
+#endif
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined (LIBXML_SAX1_ENABLED)
+/************************************************************************
+ *									*
+ *			Catalog and threads test			*
+ *									*
+ ************************************************************************/
+
+/*
+ * mostly a cut and paste from testThreads.c
+ */
+#define	MAX_ARGC	20
+
+static const char *catalog = "test/threads/complex.xml";
+static const char *testfiles[] = {
+    "test/threads/abc.xml",
+    "test/threads/acb.xml",
+    "test/threads/bac.xml",
+    "test/threads/bca.xml",
+    "test/threads/cab.xml",
+    "test/threads/cba.xml",
+    "test/threads/invalid.xml",
+};
+
+static const char *Okay = "OK";
+static const char *Failed = "Failed";
+
+#ifndef xmlDoValidityCheckingDefaultValue
+#error xmlDoValidityCheckingDefaultValue is not a macro
+#endif
+#ifndef xmlGenericErrorContext
+#error xmlGenericErrorContext is not a macro
+#endif
+
+static void *
+thread_specific_data(void *private_data)
+{
+    xmlDocPtr myDoc;
+    const char *filename = (const char *) private_data;
+    int okay = 1;
+
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        xmlDoValidityCheckingDefaultValue = 0;
+        xmlGenericErrorContext = stdout;
+    } else {
+        xmlDoValidityCheckingDefaultValue = 1;
+        xmlGenericErrorContext = stderr;
+    }
+    myDoc = xmlParseFile(filename);
+    if (myDoc) {
+        xmlFreeDoc(myDoc);
+    } else {
+        printf("parse failed\n");
+        okay = 0;
+    }
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        if (xmlDoValidityCheckingDefaultValue != 0) {
+            printf("ValidityCheckingDefaultValue override failed\n");
+            okay = 0;
+        }
+        if (xmlGenericErrorContext != stdout) {
+            printf("xmlGenericErrorContext override failed\n");
+            okay = 0;
+        }
+    } else {
+        if (xmlDoValidityCheckingDefaultValue != 1) {
+            printf("ValidityCheckingDefaultValue override failed\n");
+            okay = 0;
+        }
+        if (xmlGenericErrorContext != stderr) {
+            printf("xmlGenericErrorContext override failed\n");
+            okay = 0;
+        }
+    }
+    if (okay == 0)
+        return ((void *) Failed);
+    return ((void *) Okay);
+}
+
+#if defined(linux) || defined(__sun) || defined(__APPLE_CC__)
+
+#include <pthread.h>
+
+static pthread_t tid[MAX_ARGC];
+
+static int
+testThread(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    int ret;
+    int res = 0;
+
+    xmlInitParser();
+
+    for (repeat = 0; repeat < 500; repeat++) {
+        xmlLoadCatalog(catalog);
+        nb_tests++;
+
+        for (i = 0; i < num_threads; i++) {
+            results[i] = NULL;
+            tid[i] = (pthread_t) - 1;
+        }
+
+        for (i = 0; i < num_threads; i++) {
+            ret = pthread_create(&tid[i], 0, thread_specific_data,
+                                 (void *) testfiles[i]);
+            if (ret != 0) {
+                fprintf(stderr, "pthread_create failed\n");
+                return (1);
+            }
+        }
+        for (i = 0; i < num_threads; i++) {
+            ret = pthread_join(tid[i], &results[i]);
+            if (ret != 0) {
+                fprintf(stderr, "pthread_join failed\n");
+                return (1);
+            }
+        }
+
+        xmlCatalogCleanup();
+        for (i = 0; i < num_threads; i++)
+            if (results[i] != (void *) Okay) {
+                fprintf(stderr, "Thread %d handling %s failed\n",
+                        i, testfiles[i]);
+                res = 1;
+            }
+    }
+    return (res);
+}
+
+#elif defined WIN32
+#include <windows.h>
+#include <string.h>
+
+#define TEST_REPEAT_COUNT 500
+
+static HANDLE tid[MAX_ARGC];
+
+static DWORD WINAPI
+win32_thread_specific_data(void *private_data)
+{
+    return((DWORD) thread_specific_data(private_data));
+}
+
+static int
+testThread(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    DWORD results[MAX_ARGC];
+    BOOL ret;
+    int res = 0;
+
+    xmlInitParser();
+    for (repeat = 0; repeat < TEST_REPEAT_COUNT; repeat++) {
+        xmlLoadCatalog(catalog);
+        nb_tests++;
+
+        for (i = 0; i < num_threads; i++) {
+            results[i] = 0;
+            tid[i] = (HANDLE) - 1;
+        }
+
+        for (i = 0; i < num_threads; i++) {
+            DWORD useless;
+
+            tid[i] = CreateThread(NULL, 0,
+                                  win32_thread_specific_data,
+				  (void *) testfiles[i], 0,
+                                  &useless);
+            if (tid[i] == NULL) {
+                fprintf(stderr, "CreateThread failed\n");
+                return(1);
+            }
+        }
+
+        if (WaitForMultipleObjects(num_threads, tid, TRUE, INFINITE) ==
+            WAIT_FAILED) {
+            fprintf(stderr, "WaitForMultipleObjects failed\n");
+	    return(1);
+	}
+
+        for (i = 0; i < num_threads; i++) {
+            ret = GetExitCodeThread(tid[i], &results[i]);
+            if (ret == 0) {
+                fprintf(stderr, "GetExitCodeThread failed\n");
+                return(1);
+            }
+            CloseHandle(tid[i]);
+        }
+
+        xmlCatalogCleanup();
+        for (i = 0; i < num_threads; i++) {
+            if (results[i] != (DWORD) Okay) {
+                fprintf(stderr, "Thread %d handling %s failed\n",
+		        i, testfiles[i]);
+	        res = 1;
+	    }
+        }
+    }
+
+    return (res);
+}
+
+#elif defined __BEOS__
+#include <OS.h>
+
+static thread_id tid[MAX_ARGC];
+
+static int
+testThread(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    status_t ret;
+    int res = 0;
+
+    xmlInitParser();
+    for (repeat = 0; repeat < 500; repeat++) {
+        xmlLoadCatalog(catalog);
+        for (i = 0; i < num_threads; i++) {
+            results[i] = NULL;
+            tid[i] = (thread_id) - 1;
+        }
+        for (i = 0; i < num_threads; i++) {
+            tid[i] =
+                spawn_thread(thread_specific_data, "xmlTestThread",
+                             B_NORMAL_PRIORITY, (void *) testfiles[i]);
+            if (tid[i] < B_OK) {
+                fprintf(stderr, "beos_thread_create failed\n");
+                return (1);
+            }
+            printf("beos_thread_create %d -> %d\n", i, tid[i]);
+        }
+        for (i = 0; i < num_threads; i++) {
+            ret = wait_for_thread(tid[i], &results[i]);
+            printf("beos_thread_wait %d -> %d\n", i, ret);
+            if (ret != B_OK) {
+                fprintf(stderr, "beos_thread_wait failed\n");
+                return (1);
+            }
+        }
+
+        xmlCatalogCleanup();
+        ret = B_OK;
+        for (i = 0; i < num_threads; i++)
+            if (results[i] != (void *) Okay) {
+                printf("Thread %d handling %s failed\n", i, testfiles[i]);
+                ret = B_ERROR;
+            }
+    }
+    if (ret != B_OK)
+        return(1);
+    return (0);
+}
+#else
+static int
+testThread(void)
+{
+    fprintf(stderr,
+            "Specific platform thread support not detected\n");
+    return (-1);
+}
+#endif
+static int
+threadsTest(const char *filename ATTRIBUTE_UNUSED,
+	    const char *resul ATTRIBUTE_UNUSED,
+	    const char *err ATTRIBUTE_UNUSED,
+	    int options ATTRIBUTE_UNUSED) {
+    return(testThread());
+}
+#endif
+/************************************************************************
+ *									*
+ *			Tests Descriptions				*
+ *									*
+ ************************************************************************/
+
+static
+testDesc testDescriptions[] = {
+    { "XML regression tests" ,
+      oldParseTest, "./test/*", "result/", "", NULL,
+      0 },
+    { "XML regression tests on memory" ,
+      memParseTest, "./test/*", "result/", "", NULL,
+      0 },
+    { "XML entity subst regression tests" ,
+      noentParseTest, "./test/*", "result/noent/", "", NULL,
+      XML_PARSE_NOENT },
+    { "XML Namespaces regression tests",
+      errParseTest, "./test/namespaces/*", "result/namespaces/", "", ".err",
+      0 },
+    { "Error cases regression tests",
+      errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
+      0 },
+#ifdef LIBXML_READER_ENABLED
+    { "Error cases stream regression tests",
+      streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",
+      0 },
+    { "Reader regression tests",
+      streamParseTest, "./test/*", "result/", ".rdr", NULL,
+      0 },
+    { "Reader entities substitution regression tests",
+      streamParseTest, "./test/*", "result/", ".rde", NULL,
+      XML_PARSE_NOENT },
+    { "Reader on memory regression tests",
+      streamMemParseTest, "./test/*", "result/", ".rdr", NULL,
+      0 },
+    { "Walker regression tests",
+      walkerParseTest, "./test/*", "result/", ".rdr", NULL,
+      0 },
+#endif
+#ifdef LIBXML_SAX1_ENABLED
+    { "SAX1 callbacks regression tests" ,
+      saxParseTest, "./test/*", "result/", ".sax", NULL,
+      XML_PARSE_SAX1 },
+    { "SAX2 callbacks regression tests" ,
+      saxParseTest, "./test/*", "result/", ".sax2", NULL,
+      0 },
+#endif
+#ifdef LIBXML_PUSH_ENABLED
+    { "XML push regression tests" ,
+      pushParseTest, "./test/*", "result/", "", NULL,
+      0 },
+#endif
+#ifdef LIBXML_HTML_ENABLED
+    { "HTML regression tests" ,
+      errParseTest, "./test/HTML/*", "result/HTML/", "", ".err",
+      XML_PARSE_HTML },
+#ifdef LIBXML_PUSH_ENABLED
+    { "Push HTML regression tests" ,
+      pushParseTest, "./test/HTML/*", "result/HTML/", "", ".err",
+      XML_PARSE_HTML },
+#endif
+#ifdef LIBXML_SAX1_ENABLED
+    { "HTML SAX regression tests" ,
+      saxParseTest, "./test/HTML/*", "result/HTML/", ".sax", NULL,
+      XML_PARSE_HTML },
+#endif
+#endif
+#ifdef LIBXML_VALID_ENABLED
+    { "Valid documents regression tests" ,
+      errParseTest, "./test/VCM/*", NULL, NULL, NULL,
+      XML_PARSE_DTDVALID },
+    { "Validity checking regression tests" ,
+      errParseTest, "./test/VC/*", "result/VC/", NULL, "",
+      XML_PARSE_DTDVALID },
+    { "General documents valid regression tests" ,
+      errParseTest, "./test/valid/*", "result/valid/", "", ".err",
+      XML_PARSE_DTDVALID },
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+    { "XInclude regression tests" ,
+      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,
+      /* Ignore errors at this point ".err", */
+      XML_PARSE_XINCLUDE },
+#ifdef LIBXML_READER_ENABLED
+    { "XInclude xmlReader regression tests",
+      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",
+      /* Ignore errors at this point ".err", */
+      NULL, XML_PARSE_XINCLUDE },
+#endif
+    { "XInclude regression tests stripping include nodes" ,
+      errParseTest, "./test/XInclude/docs/*", "result/XInclude/", "", NULL,
+      /* Ignore errors at this point ".err", */
+      XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },
+#ifdef LIBXML_READER_ENABLED
+    { "XInclude xmlReader regression tests stripping include nodes",
+      streamParseTest, "./test/XInclude/docs/*", "result/XInclude/", ".rdr",
+      /* Ignore errors at this point ".err", */
+      NULL, XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE },
+#endif
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+    { "XPath expressions regression tests" ,
+      xpathExprTest, "./test/XPath/expr/*", "result/XPath/expr/", "", NULL,
+      0 },
+    { "XPath document queries regression tests" ,
+      xpathDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
+      0 },
+#ifdef LIBXML_XPTR_ENABLED
+    { "XPointer document queries regression tests" ,
+      xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
+      0 },
+#endif
+    { "xml:id regression tests" ,
+      xmlidDocTest, "./test/xmlid/*", "result/xmlid/", "", ".err",
+      0 },
+#endif
+#endif
+    { "URI parsing tests" ,
+      uriParseTest, "./test/URI/*.uri", "result/URI/", "", NULL,
+      0 },
+    { "URI base composition tests" ,
+      uriBaseTest, "./test/URI/*.data", "result/URI/", "", NULL,
+      0 },
+    { "Path URI conversion tests" ,
+      uriPathTest, NULL, NULL, NULL, NULL,
+      0 },
+#ifdef LIBXML_SCHEMAS_ENABLED
+    { "Schemas regression tests" ,
+      schemasTest, "./test/schemas/*_*.xsd", NULL, NULL, NULL,
+      0 },
+    { "Relax-NG regression tests" ,
+      rngTest, "./test/relaxng/*.rng", NULL, NULL, NULL,
+      XML_PARSE_DTDATTR | XML_PARSE_NOENT },
+#ifdef LIBXML_READER_ENABLED
+    { "Relax-NG streaming regression tests" ,
+      rngStreamTest, "./test/relaxng/*.rng", NULL, NULL, NULL,
+      XML_PARSE_DTDATTR | XML_PARSE_NOENT },
+#endif
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+#ifdef LIBXML_READER_ENABLED
+    { "Pattern regression tests" ,
+      patternTest, "./test/pattern/*.pat", "result/pattern/", NULL, NULL,
+      0 },
+#endif
+#endif
+#ifdef LIBXML_C14N_ENABLED
+    { "C14N with comments regression tests" ,
+      c14nWithCommentTest, "./test/c14n/with-comments/*.xml", NULL, NULL, NULL,
+      0 },
+    { "C14N without comments regression tests" ,
+      c14nWithoutCommentTest, "./test/c14n/without-comments/*.xml", NULL, NULL, NULL,
+      0 },
+    { "C14N exclusive without comments regression tests" ,
+      c14nExcWithoutCommentTest, "./test/c14n/exc-without-comments/*.xml", NULL, NULL, NULL,
+      0 },
+    { "C14N 1.1 without comments regression tests" ,
+      c14n11WithoutCommentTest, "./test/c14n/1-1-without-comments/*.xml", NULL, NULL, NULL,
+      0 },
+#endif
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_ENABLED)
+    { "Catalog and Threads regression tests" ,
+      threadsTest, NULL, NULL, NULL, NULL,
+      0 },
+#endif
+    {NULL, NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/************************************************************************
+ *									*
+ *		The main code driving the tests				*
+ *									*
+ ************************************************************************/
+
+static int
+launchTests(testDescPtr tst) {
+    int res = 0, err = 0;
+    size_t i;
+    char *result;
+    char *error;
+    int mem;
+
+    if (tst == NULL) return(-1);
+    if (tst->in != NULL) {
+	glob_t globbuf;
+
+	globbuf.gl_offs = 0;
+	glob(tst->in, GLOB_DOOFFS, NULL, &globbuf);
+	for (i = 0;i < globbuf.gl_pathc;i++) {
+	    if (!checkTestFile(globbuf.gl_pathv[i]))
+	        continue;
+	    if (tst->suffix != NULL) {
+		result = resultFilename(globbuf.gl_pathv[i], tst->out,
+					tst->suffix);
+		if (result == NULL) {
+		    fprintf(stderr, "Out of memory !\n");
+		    fatalError();
+		}
+	    } else {
+	        result = NULL;
+	    }
+	    if (tst->err != NULL) {
+		error = resultFilename(globbuf.gl_pathv[i], tst->out,
+		                        tst->err);
+		if (error == NULL) {
+		    fprintf(stderr, "Out of memory !\n");
+		    fatalError();
+		}
+	    } else {
+	        error = NULL;
+	    }
+	    if ((result) &&(!checkTestFile(result))) {
+	        fprintf(stderr, "Missing result file %s\n", result);
+	    } else if ((error) &&(!checkTestFile(error))) {
+	        fprintf(stderr, "Missing error file %s\n", error);
+	    } else {
+		mem = xmlMemUsed();
+		extraMemoryFromResolver = 0;
+		testErrorsSize = 0;
+		testErrors[0] = 0;
+		res = tst->func(globbuf.gl_pathv[i], result, error,
+		                tst->options | XML_PARSE_COMPACT);
+		xmlResetLastError();
+		if (res != 0) {
+		    fprintf(stderr, "File %s generated an error\n",
+		            globbuf.gl_pathv[i]);
+		    nb_errors++;
+		    err++;
+		}
+		else if (xmlMemUsed() != mem) {
+		    if ((xmlMemUsed() != mem) &&
+		        (extraMemoryFromResolver == 0)) {
+			fprintf(stderr, "File %s leaked %d bytes\n",
+				globbuf.gl_pathv[i], xmlMemUsed() - mem);
+			nb_leaks++;
+			err++;
+		    }
+		}
+		testErrorsSize = 0;
+	    }
+	    if (result)
+		free(result);
+	    if (error)
+		free(error);
+	}
+	globfree(&globbuf);
+    } else {
+        testErrorsSize = 0;
+	testErrors[0] = 0;
+	extraMemoryFromResolver = 0;
+        res = tst->func(NULL, NULL, NULL, tst->options);
+	if (res != 0) {
+	    nb_errors++;
+	    err++;
+	}
+    }
+    return(err);
+}
+
+static int verbose = 0;
+static int tests_quiet = 0;
+
+static int
+runtest(int i) {
+    int ret = 0, res;
+    int old_errors, old_tests, old_leaks;
+
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    if ((tests_quiet == 0) && (testDescriptions[i].desc != NULL))
+	printf("## %s\n", testDescriptions[i].desc);
+    res = launchTests(&testDescriptions[i]);
+    if (res != 0)
+	ret++;
+    if (verbose) {
+	if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	    printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+	else
+	    printf("Ran %d tests, %d errors, %d leaks\n",
+		   nb_tests - old_tests,
+		   nb_errors - old_errors,
+		   nb_leaks - old_leaks);
+    }
+    return(ret);
+}
+
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    int i, a, ret = 0;
+    int subset = 0;
+
+    initializeLibxml2();
+
+    for (a = 1; a < argc;a++) {
+        if (!strcmp(argv[a], "-v"))
+	    verbose = 1;
+        else if (!strcmp(argv[a], "-quiet"))
+	    tests_quiet = 1;
+	else {
+	    for (i = 0; testDescriptions[i].func != NULL; i++) {
+	        if (strstr(testDescriptions[i].desc, argv[a])) {
+		    ret += runtest(i);
+		    subset++;
+		}
+	    }
+	}
+    }
+    if (subset == 0) {
+	for (i = 0; testDescriptions[i].func != NULL; i++) {
+	    ret += runtest(i);
+	}
+    }
+    if ((nb_errors == 0) && (nb_leaks == 0)) {
+        ret = 0;
+	printf("Total %d tests, no errors\n",
+	       nb_tests);
+    } else {
+        ret = 1;
+	printf("Total %d tests, %d errors, %d leaks\n",
+	       nb_tests, nb_errors, nb_leaks);
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(ret);
+}
+
+#else /* ! LIBXML_OUTPUT_ENABLED */
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    fprintf(stderr, "runtest requires output to be enabled in libxml2\n");
+    return(1);
+}
+#endif
diff --git a/src/schematron.c b/src/schematron.c
new file mode 100644
index 0000000..07709e2
--- /dev/null
+++ b/src/schematron.c
@@ -0,0 +1,1785 @@
+/*
+ * schematron.c : implementation of the Schematron schema validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+/*
+ * TODO:
+ * + double check the semantic, especially
+ *        - multiple rules applying in a single pattern/node
+ *        - the semantic of libxml2 patterns vs. XSLT production referenced
+ *          by the spec.
+ * + export of results in SVRL
+ * + full parsing and coverage of the spec, conformance of the input to the
+ *   spec
+ * + divergences between the draft and the ISO proposed standard :-(
+ * + hook and test include
+ * + try and compare with the XSLT version
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/pattern.h>
+#include <libxml/schematron.h>
+
+#define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT
+
+#define SCT_OLD_NS BAD_CAST "http://www.ascc.net/xml/schematron"
+
+#define XML_SCHEMATRON_NS BAD_CAST "http://purl.oclc.org/dsdl/schematron"
+
+
+static const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS;
+static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;
+
+#define IS_SCHEMATRON(node, elem)					\
+   ((node != NULL) && (node->type == XML_ELEMENT_NODE ) &&		\
+    (node->ns != NULL) &&						\
+    (xmlStrEqual(node->name, (const xmlChar *) elem)) &&		\
+    ((xmlStrEqual(node->ns->href, xmlSchematronNs)) ||			\
+     (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))
+
+#define NEXT_SCHEMATRON(node)						\
+   while (node != NULL) {						\
+       if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && 	\
+           ((xmlStrEqual(node->ns->href, xmlSchematronNs)) ||		\
+	    (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))		\
+	   break;							\
+       node = node->next;						\
+   }
+
+/**
+ * TODO:
+ *
+ * macro to flag unimplemented blocks
+ */
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+typedef enum {
+    XML_SCHEMATRON_ASSERT=1,
+    XML_SCHEMATRON_REPORT=2
+} xmlSchematronTestType;
+
+/**
+ * _xmlSchematronTest:
+ *
+ * A Schematrons test, either an assert or a report
+ */
+typedef struct _xmlSchematronTest xmlSchematronTest;
+typedef xmlSchematronTest *xmlSchematronTestPtr;
+struct _xmlSchematronTest {
+    xmlSchematronTestPtr next;	/* the next test in the list */
+    xmlSchematronTestType type;	/* the test type */
+    xmlNodePtr node;		/* the node in the tree */
+    xmlChar *test;		/* the expression to test */
+    xmlXPathCompExprPtr comp;	/* the compiled expression */
+    xmlChar *report;		/* the message to report */
+};
+
+/**
+ * _xmlSchematronRule:
+ *
+ * A Schematrons rule
+ */
+typedef struct _xmlSchematronRule xmlSchematronRule;
+typedef xmlSchematronRule *xmlSchematronRulePtr;
+struct _xmlSchematronRule {
+    xmlSchematronRulePtr next;	/* the next rule in the list */
+    xmlSchematronRulePtr patnext;/* the next rule in the pattern list */
+    xmlNodePtr node;		/* the node in the tree */
+    xmlChar *context;		/* the context evaluation rule */
+    xmlSchematronTestPtr tests;	/* the list of tests */
+    xmlPatternPtr pattern;	/* the compiled pattern associated */
+    xmlChar *report;		/* the message to report */
+};
+
+/**
+ * _xmlSchematronPattern:
+ *
+ * A Schematrons pattern
+ */
+typedef struct _xmlSchematronPattern xmlSchematronPattern;
+typedef xmlSchematronPattern *xmlSchematronPatternPtr;
+struct _xmlSchematronPattern {
+    xmlSchematronPatternPtr next;/* the next pattern in the list */
+    xmlSchematronRulePtr rules;	/* the list of rules */
+    xmlChar *name;		/* the name of the pattern */
+};
+
+/**
+ * _xmlSchematron:
+ *
+ * A Schematrons definition
+ */
+struct _xmlSchematron {
+    const xmlChar *name;	/* schema name */
+    int preserve;		/* was the document passed by the user */
+    xmlDocPtr doc;		/* pointer to the parsed document */
+    int flags;			/* specific to this schematron */
+
+    void *_private;		/* unused by the library */
+    xmlDictPtr dict;		/* the dictionnary used internally */
+
+    const xmlChar *title;	/* the title if any */
+
+    int nbNs;			/* the number of namespaces */
+
+    int nbPattern;		/* the number of patterns */
+    xmlSchematronPatternPtr patterns;/* the patterns found */
+    xmlSchematronRulePtr rules;	/* the rules gathered */
+    int nbNamespaces;		/* number of namespaces in the array */
+    int maxNamespaces;		/* size of the array */
+    const xmlChar **namespaces;	/* the array of namespaces */
+};
+
+/**
+ * xmlSchematronValidCtxt:
+ *
+ * A Schematrons validation context
+ */
+struct _xmlSchematronValidCtxt {
+    int type;
+    int flags;			/* an or of xmlSchematronValidOptions */
+
+    xmlDictPtr dict;
+    int nberrors;
+    int err;
+
+    xmlSchematronPtr schema;
+    xmlXPathContextPtr xctxt;
+
+    FILE *outputFile;		/* if using XML_SCHEMATRON_OUT_FILE */
+    xmlBufferPtr outputBuffer;	/* if using XML_SCHEMATRON_OUT_BUFFER */
+    xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
+    xmlOutputCloseCallback  ioclose;
+    void *ioctx;
+
+    /* error reporting data */
+    void *userData;                      /* user specific data block */
+    xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
+    xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
+    xmlStructuredErrorFunc serror;       /* the structured function */
+};
+
+struct _xmlSchematronParserCtxt {
+    int type;
+    const xmlChar *URL;
+    xmlDocPtr doc;
+    int preserve;               /* Whether the doc should be freed  */
+    const char *buffer;
+    int size;
+
+    xmlDictPtr dict;            /* dictionnary for interned string names */
+
+    int nberrors;
+    int err;
+    xmlXPathContextPtr xctxt;	/* the XPath context used for compilation */
+    xmlSchematronPtr schema;
+
+    int nbNamespaces;		/* number of namespaces in the array */
+    int maxNamespaces;		/* size of the array */
+    const xmlChar **namespaces;	/* the array of namespaces */
+
+    int nbIncludes;		/* number of includes in the array */
+    int maxIncludes;		/* size of the array */
+    xmlNodePtr *includes;	/* the array of includes */
+
+    /* error reporting data */
+    void *userData;                      /* user specific data block */
+    xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
+    xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
+    xmlStructuredErrorFunc serror;       /* the structured function */
+};
+
+#define XML_STRON_CTXT_PARSER 1
+#define XML_STRON_CTXT_VALIDATOR 2
+
+/************************************************************************
+ *									*
+ *			Error reporting					*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchematronPErrMemory:
+ * @node: a context node
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt,
+                        const char *extra, xmlNodePtr node)
+{
+    if (ctxt != NULL)
+        ctxt->nberrors++;
+    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
+                     extra);
+}
+
+/**
+ * xmlSchematronPErr:
+ * @ctxt: the parsing context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ * 
+ * Handle a parser error
+ */
+static void
+xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
+              const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    xmlGenericErrorFunc channel = NULL;
+    xmlStructuredErrorFunc schannel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        ctxt->nberrors++;
+        channel = ctxt->error;
+        data = ctxt->userData;
+	schannel = ctxt->serror;
+    }
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
+                    error, XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1, (const char *) str2, NULL, 0, 0,
+                    msg, str1, str2);
+}
+
+/**
+ * xmlSchematronVTypeErrMemory:
+ * @node: a context node
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
+                        const char *extra, xmlNodePtr node)
+{
+    if (ctxt != NULL) {
+        ctxt->nberrors++;
+        ctxt->err = XML_SCHEMAV_INTERNAL;
+    }
+    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
+                     extra);
+}
+
+/************************************************************************
+ *									*
+ *		Parsing and compilation of the Schematrontrons		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchematronAddTest:
+ * @ctxt: the schema parsing context
+ * @type:  the type of test
+ * @rule:  the parent rule
+ * @node:  the node hosting the test
+ * @test: the associated test
+ * @report: the associated report string
+ *
+ * Add a test to a schematron
+ *
+ * Returns the new pointer or NULL in case of error
+ */
+static xmlSchematronTestPtr
+xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt,
+                     xmlSchematronTestType type,
+                     xmlSchematronRulePtr rule,
+                     xmlNodePtr node, xmlChar *test, xmlChar *report)
+{
+    xmlSchematronTestPtr ret;
+    xmlXPathCompExprPtr comp;
+
+    if ((ctxt == NULL) || (rule == NULL) || (node == NULL) ||
+        (test == NULL))
+        return(NULL);
+
+    /*
+     * try first to compile the test expression
+     */
+    comp = xmlXPathCtxtCompile(ctxt->xctxt, test);
+    if (comp == NULL) {
+	xmlSchematronPErr(ctxt, node,
+	    XML_SCHEMAP_NOROOT,
+	    "Failed to compile test expression %s",
+	    test, NULL);
+	return(NULL);
+    }
+
+    ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(ctxt, "allocating schema test", node);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronTest));
+    ret->type = type;
+    ret->node = node;
+    ret->test = test;
+    ret->comp = comp;
+    ret->report = report;
+    ret->next = NULL;
+    if (rule->tests == NULL) {
+	rule->tests = ret;
+    } else {
+        xmlSchematronTestPtr prev = rule->tests;
+
+	while (prev->next != NULL)
+	     prev = prev->next;
+        prev->next = ret;
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchematronFreeTests:
+ * @tests:  a list of tests
+ *
+ * Free a list of tests.
+ */
+static void
+xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
+    xmlSchematronTestPtr next;
+
+    while (tests != NULL) {
+        next = tests->next;
+	if (tests->test != NULL)
+	    xmlFree(tests->test);
+	if (tests->comp != NULL)
+	    xmlXPathFreeCompExpr(tests->comp);
+	if (tests->report != NULL)
+	    xmlFree(tests->report);
+	xmlFree(tests);
+	tests = next;
+    }
+}
+
+/**
+ * xmlSchematronAddRule:
+ * @ctxt: the schema parsing context
+ * @schema:  a schema structure
+ * @node:  the node hosting the rule
+ * @context: the associated context string
+ * @report: the associated report string
+ *
+ * Add a rule to a schematron
+ *
+ * Returns the new pointer or NULL in case of error
+ */
+static xmlSchematronRulePtr
+xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
+                     xmlSchematronPatternPtr pat, xmlNodePtr node,
+		     xmlChar *context, xmlChar *report)
+{
+    xmlSchematronRulePtr ret;
+    xmlPatternPtr pattern;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
+        (context == NULL))
+        return(NULL);
+
+    /*
+     * Try first to compile the pattern
+     */
+    pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH,
+                                ctxt->namespaces);
+    if (pattern == NULL) {
+	xmlSchematronPErr(ctxt, node,
+	    XML_SCHEMAP_NOROOT,
+	    "Failed to compile context expression %s",
+	    context, NULL);
+    }
+
+    ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(ctxt, "allocating schema rule", node);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronRule));
+    ret->node = node;
+    ret->context = context;
+    ret->pattern = pattern;
+    ret->report = report;
+    ret->next = NULL;
+    if (schema->rules == NULL) {
+	schema->rules = ret;
+    } else {
+        xmlSchematronRulePtr prev = schema->rules;
+
+	while (prev->next != NULL)
+	     prev = prev->next;
+        prev->next = ret;
+    }
+    ret->patnext = NULL;
+    if (pat->rules == NULL) {
+	pat->rules = ret;
+    } else {
+        xmlSchematronRulePtr prev = pat->rules;
+
+	while (prev->patnext != NULL)
+	     prev = prev->patnext;
+        prev->patnext = ret;
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchematronFreeRules:
+ * @rules:  a list of rules
+ *
+ * Free a list of rules.
+ */
+static void
+xmlSchematronFreeRules(xmlSchematronRulePtr rules) {
+    xmlSchematronRulePtr next;
+
+    while (rules != NULL) {
+        next = rules->next;
+	if (rules->tests)
+	    xmlSchematronFreeTests(rules->tests);
+	if (rules->context != NULL)
+	    xmlFree(rules->context);
+	if (rules->pattern)
+	    xmlFreePattern(rules->pattern);
+	if (rules->report != NULL)
+	    xmlFree(rules->report);
+	xmlFree(rules);
+	rules = next;
+    }
+}
+
+/**
+ * xmlSchematronAddPattern:
+ * @ctxt: the schema parsing context
+ * @schema:  a schema structure
+ * @node:  the node hosting the pattern
+ * @id: the id or name of the pattern
+ *
+ * Add a pattern to a schematron
+ *
+ * Returns the new pointer or NULL in case of error
+ */
+static xmlSchematronPatternPtr
+xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt,
+                     xmlSchematronPtr schema, xmlNodePtr node, xmlChar *name)
+{
+    xmlSchematronPatternPtr ret;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || (name == NULL))
+        return(NULL);
+
+    ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronPattern));
+    ret->name = name;
+    ret->next = NULL;
+    if (schema->patterns == NULL) {
+	schema->patterns = ret;
+    } else {
+        xmlSchematronPatternPtr prev = schema->patterns;
+
+	while (prev->next != NULL)
+	     prev = prev->next;
+        prev->next = ret;
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchematronFreePatterns:
+ * @patterns:  a list of patterns
+ *
+ * Free a list of patterns.
+ */
+static void
+xmlSchematronFreePatterns(xmlSchematronPatternPtr patterns) {
+    xmlSchematronPatternPtr next;
+
+    while (patterns != NULL) {
+        next = patterns->next;
+	if (patterns->name != NULL)
+	    xmlFree(patterns->name);
+	xmlFree(patterns);
+	patterns = next;
+    }
+}
+
+/**
+ * xmlSchematronNewSchematron:
+ * @ctxt:  a schema validation context
+ *
+ * Allocate a new Schematron structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlSchematronPtr
+xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt)
+{
+    xmlSchematronPtr ret;
+
+    ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(ctxt, "allocating schema", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematron));
+    ret->dict = ctxt->dict;
+    xmlDictReference(ret->dict);
+
+    return (ret);
+}
+
+/**
+ * xmlSchematronFree:
+ * @schema:  a schema structure
+ *
+ * Deallocate a Schematron structure.
+ */
+void
+xmlSchematronFree(xmlSchematronPtr schema)
+{
+    if (schema == NULL)
+        return;
+
+    if ((schema->doc != NULL) && (!(schema->preserve)))
+        xmlFreeDoc(schema->doc);
+
+    if (schema->namespaces != NULL)
+        xmlFree((char **) schema->namespaces);
+    
+    xmlSchematronFreeRules(schema->rules);
+    xmlSchematronFreePatterns(schema->patterns);
+    xmlDictFree(schema->dict);
+    xmlFree(schema);
+}
+
+/**
+ * xmlSchematronNewParserCtxt:
+ * @URL:  the location of the schema
+ *
+ * Create an XML Schematrons parse context for that file/resource expected
+ * to contain an XML Schematrons file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchematronParserCtxtPtr
+xmlSchematronNewParserCtxt(const char *URL)
+{
+    xmlSchematronParserCtxtPtr ret;
+
+    if (URL == NULL)
+        return (NULL);
+
+    ret =
+        (xmlSchematronParserCtxtPtr)
+        xmlMalloc(sizeof(xmlSchematronParserCtxt));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
+                                NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
+    ret->type = XML_STRON_CTXT_PARSER;
+    ret->dict = xmlDictCreate();
+    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
+    ret->includes = NULL;
+    ret->xctxt = xmlXPathNewContext(NULL);
+    if (ret->xctxt == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
+                                NULL);
+	xmlSchematronFreeParserCtxt(ret);
+        return (NULL);
+    }
+    ret->xctxt->flags = XML_XPATH_CHECKNS;
+    return (ret);
+}
+
+/**
+ * xmlSchematronNewMemParserCtxt:
+ * @buffer:  a pointer to a char array containing the schemas
+ * @size:  the size of the array
+ *
+ * Create an XML Schematrons parse context for that memory buffer expected
+ * to contain an XML Schematrons file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchematronParserCtxtPtr
+xmlSchematronNewMemParserCtxt(const char *buffer, int size)
+{
+    xmlSchematronParserCtxtPtr ret;
+
+    if ((buffer == NULL) || (size <= 0))
+        return (NULL);
+
+    ret =
+        (xmlSchematronParserCtxtPtr)
+        xmlMalloc(sizeof(xmlSchematronParserCtxt));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
+                                NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
+    ret->buffer = buffer;
+    ret->size = size;
+    ret->dict = xmlDictCreate();
+    ret->xctxt = xmlXPathNewContext(NULL);
+    if (ret->xctxt == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
+                                NULL);
+	xmlSchematronFreeParserCtxt(ret);
+        return (NULL);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchematronNewDocParserCtxt:
+ * @doc:  a preparsed document tree
+ *
+ * Create an XML Schematrons parse context for that document.
+ * NB. The document may be modified during the parsing process.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchematronParserCtxtPtr
+xmlSchematronNewDocParserCtxt(xmlDocPtr doc)
+{
+    xmlSchematronParserCtxtPtr ret;
+
+    if (doc == NULL)
+        return (NULL);
+
+    ret =
+        (xmlSchematronParserCtxtPtr)
+        xmlMalloc(sizeof(xmlSchematronParserCtxt));
+    if (ret == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser context",
+                                NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronParserCtxt));
+    ret->doc = doc;
+    ret->dict = xmlDictCreate();
+    /* The application has responsibility for the document */
+    ret->preserve = 1;
+    ret->xctxt = xmlXPathNewContext(doc);
+    if (ret->xctxt == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
+                                NULL);
+	xmlSchematronFreeParserCtxt(ret);
+        return (NULL);
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlSchematronFreeParserCtxt:
+ * @ctxt:  the schema parser context
+ *
+ * Free the resources associated to the schema parser context
+ */
+void
+xmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->doc != NULL && !ctxt->preserve)
+        xmlFreeDoc(ctxt->doc);
+    if (ctxt->xctxt != NULL) {
+        xmlXPathFreeContext(ctxt->xctxt);
+    }
+    if (ctxt->namespaces != NULL)
+        xmlFree((char **) ctxt->namespaces);
+    xmlDictFree(ctxt->dict);
+    xmlFree(ctxt);
+}
+
+#if 0
+/**
+ * xmlSchematronPushInclude:
+ * @ctxt:  the schema parser context
+ * @doc:  the included document
+ * @cur:  the current include node
+ *
+ * Add an included document
+ */
+static void
+xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
+                        xmlDocPtr doc, xmlNodePtr cur)
+{
+    if (ctxt->includes == NULL) {
+        ctxt->maxIncludes = 10;
+        ctxt->includes = (xmlNodePtr *)
+	    xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
+	if (ctxt->includes == NULL) {
+	    xmlSchematronPErrMemory(NULL, "allocating parser includes",
+				    NULL);
+	    return;
+	}
+        ctxt->nbIncludes = 0;
+    } else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) {
+        xmlNodePtr *tmp;
+
+	tmp = (xmlNodePtr *)
+	    xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
+	               sizeof(xmlNodePtr));
+	if (tmp == NULL) {
+	    xmlSchematronPErrMemory(NULL, "allocating parser includes",
+				    NULL);
+	    return;
+	}
+        ctxt->includes = tmp;
+	ctxt->maxIncludes *= 2;
+    }
+    ctxt->includes[2 * ctxt->nbIncludes] = cur;
+    ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc;
+    ctxt->nbIncludes++;
+}
+
+/**
+ * xmlSchematronPopInclude:
+ * @ctxt:  the schema parser context
+ *
+ * Pop an include level. The included document is being freed
+ *
+ * Returns the node immediately following the include or NULL if the
+ *         include list was empty.
+ */
+static xmlNodePtr
+xmlSchematronPopInclude(xmlSchematronParserCtxtPtr ctxt)
+{
+    xmlDocPtr doc;
+    xmlNodePtr ret;
+
+    if (ctxt->nbIncludes <= 0)
+        return(NULL);
+    ctxt->nbIncludes--;
+    doc = (xmlDocPtr) ctxt->includes[2 * ctxt->nbIncludes + 1];
+    ret = ctxt->includes[2 * ctxt->nbIncludes];
+    xmlFreeDoc(doc);
+    if (ret != NULL)
+	ret = ret->next;
+    if (ret == NULL)
+        return(xmlSchematronPopInclude(ctxt));
+    return(ret);
+}
+#endif
+
+/**
+ * xmlSchematronAddNamespace:
+ * @ctxt:  the schema parser context
+ * @prefix:  the namespace prefix
+ * @ns:  the namespace name
+ *
+ * Add a namespace definition in the context
+ */
+static void
+xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
+                          const xmlChar *prefix, const xmlChar *ns)
+{
+    if (ctxt->namespaces == NULL) {
+        ctxt->maxNamespaces = 10;
+        ctxt->namespaces = (const xmlChar **)
+	    xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
+	if (ctxt->namespaces == NULL) {
+	    xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
+				    NULL);
+	    return;
+	}
+        ctxt->nbNamespaces = 0;
+    } else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) {
+        const xmlChar **tmp;
+
+	tmp = (const xmlChar **)
+	    xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
+	               sizeof(const xmlChar *));
+	if (tmp == NULL) {
+	    xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
+				    NULL);
+	    return;
+	}
+        ctxt->namespaces = tmp;
+	ctxt->maxNamespaces *= 2;
+    }
+    ctxt->namespaces[2 * ctxt->nbNamespaces] = 
+        xmlDictLookup(ctxt->dict, ns, -1);
+    ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = 
+        xmlDictLookup(ctxt->dict, prefix, -1);
+    ctxt->nbNamespaces++;
+    ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL;
+    ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = NULL;
+
+}
+
+/**
+ * xmlSchematronParseRule:
+ * @ctxt:  a schema validation context
+ * @rule:  the rule node
+ *
+ * parse a rule element
+ */
+static void
+xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
+                       xmlSchematronPatternPtr pattern,
+		       xmlNodePtr rule)
+{
+    xmlNodePtr cur;
+    int nbChecks = 0;
+    xmlChar *test;
+    xmlChar *context;
+    xmlChar *report;
+    xmlSchematronRulePtr ruleptr;
+    xmlSchematronTestPtr testptr;
+
+    if ((ctxt == NULL) || (rule == NULL)) return;
+
+    context = xmlGetNoNsProp(rule, BAD_CAST "context");
+    if (context == NULL) {
+	xmlSchematronPErr(ctxt, rule,
+	    XML_SCHEMAP_NOROOT,
+	    "rule has no context attribute",
+	    NULL, NULL);
+	return;
+    } else if (context[0] == 0) {
+	xmlSchematronPErr(ctxt, rule,
+	    XML_SCHEMAP_NOROOT,
+	    "rule has an empty context attribute",
+	    NULL, NULL);
+	xmlFree(context);
+	return;
+    } else {
+	ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
+	                               rule, context, NULL);
+	if (ruleptr == NULL) {
+	    xmlFree(context);
+	    return;
+	}
+    }
+
+    cur = rule->children;
+    NEXT_SCHEMATRON(cur);
+    while (cur != NULL) {
+	if (IS_SCHEMATRON(cur, "assert")) {
+	    nbChecks++;
+	    test = xmlGetNoNsProp(cur, BAD_CAST "test");
+	    if (test == NULL) {
+		xmlSchematronPErr(ctxt, cur,
+		    XML_SCHEMAP_NOROOT,
+		    "assert has no test attribute",
+		    NULL, NULL);
+	    } else if (test[0] == 0) {
+		xmlSchematronPErr(ctxt, cur,
+		    XML_SCHEMAP_NOROOT,
+		    "assert has an empty test attribute",
+		    NULL, NULL);
+		xmlFree(test);
+	    } else {
+		/* TODO will need dynamic processing instead */
+		report = xmlNodeGetContent(cur);
+
+		testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
+		                               ruleptr, cur, test, report);
+		if (testptr == NULL)
+		    xmlFree(test);
+	    }
+	} else if (IS_SCHEMATRON(cur, "report")) {
+	    nbChecks++;
+	    test = xmlGetNoNsProp(cur, BAD_CAST "test");
+	    if (test == NULL) {
+		xmlSchematronPErr(ctxt, cur,
+		    XML_SCHEMAP_NOROOT,
+		    "assert has no test attribute",
+		    NULL, NULL);
+	    } else if (test[0] == 0) {
+		xmlSchematronPErr(ctxt, cur,
+		    XML_SCHEMAP_NOROOT,
+		    "assert has an empty test attribute",
+		    NULL, NULL);
+		xmlFree(test);
+	    } else {
+		/* TODO will need dynamic processing instead */
+		report = xmlNodeGetContent(cur);
+
+		testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
+		                               ruleptr, cur, test, report);
+		if (testptr == NULL)
+		    xmlFree(test);
+	    }
+	} else {
+	    xmlSchematronPErr(ctxt, cur,
+		XML_SCHEMAP_NOROOT,
+		"Expecting an assert or a report element instead of %s",
+		cur->name, NULL);
+	}
+	cur = cur->next;
+	NEXT_SCHEMATRON(cur);
+    }
+    if (nbChecks == 0) {
+	xmlSchematronPErr(ctxt, rule,
+	    XML_SCHEMAP_NOROOT,
+	    "rule has no assert nor report element", NULL, NULL);
+    }
+}
+
+/**
+ * xmlSchematronParsePattern:
+ * @ctxt:  a schema validation context
+ * @pat:  the pattern node
+ *
+ * parse a pattern element
+ */
+static void
+xmlSchematronParsePattern(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr pat)
+{
+    xmlNodePtr cur;
+    xmlSchematronPatternPtr pattern;
+    int nbRules = 0;
+    xmlChar *id;
+
+    if ((ctxt == NULL) || (pat == NULL)) return;
+
+    id = xmlGetNoNsProp(pat, BAD_CAST "id");
+    if (id == NULL) {
+	id = xmlGetNoNsProp(pat, BAD_CAST "name");
+    }
+    pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id);
+    if (pattern == NULL) {
+	if (id != NULL)
+	    xmlFree(id);
+        return;
+    }
+    cur = pat->children;
+    NEXT_SCHEMATRON(cur);
+    while (cur != NULL) {
+	if (IS_SCHEMATRON(cur, "rule")) {
+	    xmlSchematronParseRule(ctxt, pattern, cur);
+	    nbRules++;
+	} else {
+	    xmlSchematronPErr(ctxt, cur,
+		XML_SCHEMAP_NOROOT,
+		"Expecting a rule element instead of %s", cur->name, NULL);
+	}
+	cur = cur->next;
+	NEXT_SCHEMATRON(cur);
+    }
+    if (nbRules == 0) {
+	xmlSchematronPErr(ctxt, pat,
+	    XML_SCHEMAP_NOROOT,
+	    "Pattern has no rule element", NULL, NULL);
+    }
+}
+
+#if 0
+/**
+ * xmlSchematronLoadInclude:
+ * @ctxt:  a schema validation context
+ * @cur:  the include element
+ *
+ * Load the include document, Push the current pointer
+ *
+ * Returns the updated node pointer
+ */
+static xmlNodePtr
+xmlSchematronLoadInclude(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr cur)
+{
+    xmlNodePtr ret = NULL;
+    xmlDocPtr doc = NULL;
+    xmlChar *href = NULL;
+    xmlChar *base = NULL;
+    xmlChar *URI = NULL;
+
+    if ((ctxt == NULL) || (cur == NULL))
+        return(NULL);
+
+    href = xmlGetNoNsProp(cur, BAD_CAST "href");
+    if (href == NULL) {
+	xmlSchematronPErr(ctxt, cur,
+	    XML_SCHEMAP_NOROOT,
+	    "Include has no href attribute", NULL, NULL);
+	return(cur->next);
+    }
+
+    /* do the URI base composition, load and find the root */
+    base = xmlNodeGetBase(cur->doc, cur);
+    URI = xmlBuildURI(href, base);
+    doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS);
+    if (doc == NULL) {
+	xmlSchematronPErr(ctxt, cur,
+		      XML_SCHEMAP_FAILED_LOAD,
+		      "could not load include '%s'.\n",
+		      URI, NULL);
+	goto done;
+    }
+    ret = xmlDocGetRootElement(doc);
+    if (ret == NULL) {
+	xmlSchematronPErr(ctxt, cur,
+		      XML_SCHEMAP_FAILED_LOAD,
+		      "could not find root from include '%s'.\n",
+		      URI, NULL);
+	goto done;
+    }
+
+    /* Success, push the include for rollback on exit */
+    xmlSchematronPushInclude(ctxt, doc, cur);
+
+done:
+    if (ret == NULL) {
+        if (doc != NULL)
+	    xmlFreeDoc(doc);
+    }
+    xmlFree(href);
+    if (base != NULL)
+        xmlFree(base);
+    if (URI != NULL)
+        xmlFree(URI);
+    return(ret);
+}
+#endif
+
+/**
+ * xmlSchematronParse:
+ * @ctxt:  a schema validation context
+ *
+ * parse a schema definition resource and build an internal
+ * XML Shema struture which can be used to validate instances.
+ *
+ * Returns the internal XML Schematron structure built from the resource or
+ *         NULL in case of error
+ */
+xmlSchematronPtr
+xmlSchematronParse(xmlSchematronParserCtxtPtr ctxt)
+{
+    xmlSchematronPtr ret = NULL;
+    xmlDocPtr doc;
+    xmlNodePtr root, cur;
+    int preserve = 0;
+
+    if (ctxt == NULL)
+        return (NULL);
+
+    ctxt->nberrors = 0;
+
+    /*
+     * First step is to parse the input document into an DOM/Infoset
+     */
+    if (ctxt->URL != NULL) {
+        doc = xmlReadFile((const char *) ctxt->URL, NULL,
+	                  SCHEMATRON_PARSE_OPTIONS);
+        if (doc == NULL) {
+	    xmlSchematronPErr(ctxt, NULL,
+			  XML_SCHEMAP_FAILED_LOAD,
+                          "xmlSchematronParse: could not load '%s'.\n",
+                          ctxt->URL, NULL);
+            return (NULL);
+        }
+	ctxt->preserve = 0;
+    } else if (ctxt->buffer != NULL) {
+        doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
+	                    SCHEMATRON_PARSE_OPTIONS);
+        if (doc == NULL) {
+	    xmlSchematronPErr(ctxt, NULL,
+			  XML_SCHEMAP_FAILED_PARSE,
+                          "xmlSchematronParse: could not parse.\n",
+                          NULL, NULL);
+            return (NULL);
+        }
+        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
+        ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
+	ctxt->preserve = 0;
+    } else if (ctxt->doc != NULL) {
+        doc = ctxt->doc;
+	preserve = 1;
+	ctxt->preserve = 1;
+    } else {
+	xmlSchematronPErr(ctxt, NULL,
+		      XML_SCHEMAP_NOTHING_TO_PARSE,
+		      "xmlSchematronParse: could not parse.\n",
+		      NULL, NULL);
+        return (NULL);
+    }
+
+    /*
+     * Then extract the root and Schematron parse it
+     */
+    root = xmlDocGetRootElement(doc);
+    if (root == NULL) {
+	xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
+		      XML_SCHEMAP_NOROOT,
+		      "The schema has no document element.\n", NULL, NULL);
+	if (!preserve) {
+	    xmlFreeDoc(doc);
+	}
+        return (NULL);
+    }
+
+    if (!IS_SCHEMATRON(root, "schema")) {
+	xmlSchematronPErr(ctxt, root,
+	    XML_SCHEMAP_NOROOT,
+	    "The XML document '%s' is not a XML schematron document",
+	    ctxt->URL, NULL);
+	goto exit;
+    }
+    ret = xmlSchematronNewSchematron(ctxt);
+    if (ret == NULL)
+        goto exit;
+    ctxt->schema = ret;
+
+    /*
+     * scan the schema elements
+     */
+    cur = root->children;
+    NEXT_SCHEMATRON(cur);
+    if (IS_SCHEMATRON(cur, "title")) {
+        xmlChar *title = xmlNodeGetContent(cur);
+	if (title != NULL) {
+	    ret->title = xmlDictLookup(ret->dict, title, -1);
+	    xmlFree(title);
+	}
+	cur = cur->next;
+	NEXT_SCHEMATRON(cur);
+    }
+    while (IS_SCHEMATRON(cur, "ns")) {
+        xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix");
+        xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri");
+	if ((uri == NULL) || (uri[0] == 0)) {
+	    xmlSchematronPErr(ctxt, cur,
+		XML_SCHEMAP_NOROOT,
+		"ns element has no uri", NULL, NULL);
+	}
+	if ((prefix == NULL) || (prefix[0] == 0)) {
+	    xmlSchematronPErr(ctxt, cur,
+		XML_SCHEMAP_NOROOT,
+		"ns element has no prefix", NULL, NULL);
+	}
+	if ((prefix) && (uri)) {
+	    xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
+	    xmlSchematronAddNamespace(ctxt, prefix, uri);
+	    ret->nbNs++;
+	}
+	if (uri)
+	    xmlFree(uri);
+	if (prefix)
+	    xmlFree(prefix);
+	cur = cur->next;
+	NEXT_SCHEMATRON(cur);
+    }
+    while (cur != NULL) {
+	if (IS_SCHEMATRON(cur, "pattern")) {
+	    xmlSchematronParsePattern(ctxt, cur);
+	    ret->nbPattern++;
+	} else {
+	    xmlSchematronPErr(ctxt, cur,
+		XML_SCHEMAP_NOROOT,
+		"Expecting a pattern element instead of %s", cur->name, NULL);
+	}
+	cur = cur->next;
+	NEXT_SCHEMATRON(cur);
+    }
+    if (ret->nbPattern == 0) {
+	xmlSchematronPErr(ctxt, root,
+	    XML_SCHEMAP_NOROOT,
+	    "The schematron document '%s' has no pattern",
+	    ctxt->URL, NULL);
+	goto exit;
+    }
+    /* the original document must be kept for reporting */
+    ret->doc = doc;
+    if (preserve) {
+	    ret->preserve = 1;
+    }
+    preserve = 1;
+
+exit:
+    if (!preserve) {
+	xmlFreeDoc(doc);
+    }
+    if (ret != NULL) {
+	if (ctxt->nberrors != 0) {
+	    xmlSchematronFree(ret);
+	    ret = NULL;
+	} else {
+	    ret->namespaces = ctxt->namespaces;
+	    ret->nbNamespaces = ctxt->nbNamespaces;
+	    ctxt->namespaces = NULL;
+	}
+    }
+    return (ret);
+}
+
+/************************************************************************
+ *									*
+ *		Schematrontron Reports handler				*
+ *									*
+ ************************************************************************/
+
+static xmlNodePtr
+xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
+                     xmlNodePtr cur, const xmlChar *xpath) {
+    xmlNodePtr node = NULL;
+    xmlXPathObjectPtr ret;
+
+    if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
+        return(NULL);
+
+    ctxt->xctxt->doc = cur->doc;
+    ctxt->xctxt->node = cur;
+    ret = xmlXPathEval(xpath, ctxt->xctxt);
+    if (ret == NULL)
+        return(NULL);
+
+    if ((ret->type == XPATH_NODESET) &&
+        (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
+	node = ret->nodesetval->nodeTab[0];
+
+    xmlXPathFreeObject(ret);
+    return(node);
+}
+
+/**
+ * xmlSchematronReportOutput:
+ * @ctxt: the validation context
+ * @cur: the current node tested
+ * @msg: the message output
+ *
+ * Output part of the report to whatever channel the user selected
+ */
+static void
+xmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                          xmlNodePtr cur ATTRIBUTE_UNUSED,
+                          const char *msg) {
+    /* TODO */
+    fprintf(stderr, "%s", msg);
+}
+
+/**
+ * xmlSchematronFormatReport:
+ * @ctxt:  the validation context
+ * @test: the test node
+ * @cur: the current node tested
+ *
+ * Build the string being reported to the user.
+ *
+ * Returns a report string or NULL in case of error. The string needs
+ *         to be deallocated by teh caller
+ */
+static xmlChar *
+xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, 
+			  xmlNodePtr test, xmlNodePtr cur) {
+    xmlChar *ret = NULL;
+    xmlNodePtr child, node;
+
+    if ((test == NULL) || (cur == NULL))
+        return(ret);
+
+    child = test->children;
+    while (child != NULL) {
+        if ((child->type == XML_TEXT_NODE) ||
+	    (child->type == XML_CDATA_SECTION_NODE))
+	    ret = xmlStrcat(ret, child->content);
+	else if (IS_SCHEMATRON(child, "name")) {
+	    xmlChar *path;
+
+	    path = xmlGetNoNsProp(child, BAD_CAST "path");
+
+            node = cur;
+	    if (path != NULL) {
+	        node = xmlSchematronGetNode(ctxt, cur, path);
+		if (node == NULL)
+		    node = cur;
+		xmlFree(path);
+	    }
+
+	    if ((node->ns == NULL) || (node->ns->prefix == NULL)) 
+	        ret = xmlStrcat(ret, node->name);
+	    else {
+	        ret = xmlStrcat(ret, node->ns->prefix);
+	        ret = xmlStrcat(ret, BAD_CAST ":");
+	        ret = xmlStrcat(ret, node->name);
+	    }
+	} else {
+	    child = child->next;
+	    continue;
+	}
+
+	/*
+	 * remove superfluous \n
+	 */
+	if (ret != NULL) {
+	    int len = xmlStrlen(ret);
+	    xmlChar c;
+
+	    if (len > 0) {
+		c = ret[len - 1];
+		if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
+		    while ((c == ' ') || (c == '\n') ||
+		           (c == '\r') || (c == '\t')) {
+			len--;
+			if (len == 0)
+			    break;
+			c = ret[len - 1];
+		    }
+		    ret[len] = ' ';
+		    ret[len + 1] = 0;
+		}
+	    }
+	}
+
+        child = child->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlSchematronReportSuccess:
+ * @ctxt:  the validation context
+ * @test: the compiled test
+ * @cur: the current node tested
+ * @success: boolean value for the result
+ *
+ * called from the validation engine when an assert or report test have
+ * been done.
+ */
+static void
+xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, 
+		   xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) {
+    if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
+        return;
+    /* if quiet and not SVRL report only failures */
+    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
+        ((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) &&
+	(test->type == XML_SCHEMATRON_REPORT))
+        return;
+    if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
+        TODO
+    } else {
+        xmlChar *path;
+	char msg[1000];
+	long line;
+	const xmlChar *report = NULL;
+
+        if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) ||
+	    ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
+	    return;
+	line = xmlGetLineNo(cur);
+	path = xmlGetNodePath(cur);
+	if (path == NULL)
+	    path = (xmlChar *) cur->name;
+#if 0
+	if ((test->report != NULL) && (test->report[0] != 0))
+	    report = test->report;
+#endif
+	if (test->node != NULL)
+            report = xmlSchematronFormatReport(ctxt, test->node, cur);
+	if (report == NULL) {
+	    if (test->type == XML_SCHEMATRON_ASSERT) {
+            report = xmlStrdup((const xmlChar *) "node failed assert");
+	    } else {
+            report = xmlStrdup((const xmlChar *) "node failed report");
+	    }
+	    }
+	    snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
+		     line, (const char *) report);
+
+    if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
+        xmlStructuredErrorFunc schannel = NULL;
+        xmlGenericErrorFunc channel = NULL;
+        void *data = NULL;
+
+        if (ctxt != NULL) {
+            if (ctxt->serror != NULL)
+                schannel = ctxt->serror;
+            else
+                channel = ctxt->error;
+            data = ctxt->userData;
+	}
+
+        __xmlRaiseError(schannel, channel, data,
+                        NULL, cur, XML_FROM_SCHEMATRONV,
+                        (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT,
+                        XML_ERR_ERROR, NULL, line,
+                        (pattern == NULL)?NULL:((const char *) pattern->name),
+                        (const char *) path,
+                        (const char *) report, 0, 0,
+                        "%s", msg);
+    } else {
+	xmlSchematronReportOutput(ctxt, cur, &msg[0]);
+    }
+
+    xmlFree((char *) report);
+
+	if ((path != NULL) && (path != (xmlChar *) cur->name))
+	    xmlFree(path);
+    }
+}
+
+/**
+ * xmlSchematronReportPattern:
+ * @ctxt:  the validation context
+ * @pattern: the current pattern
+ *
+ * called from the validation engine when starting to check a pattern
+ */
+static void
+xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt, 
+			   xmlSchematronPatternPtr pattern) {
+    if ((ctxt == NULL) || (pattern == NULL))
+        return;
+    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
+        return;
+    if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
+        TODO
+    } else {
+	char msg[1000];
+
+	if (pattern->name == NULL)
+	    return;
+	snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
+	xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
+    }
+}
+
+
+/************************************************************************
+ *									*
+ *		Validation against a Schematrontron				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchematronSetValidStructuredErrors:
+ * @ctxt:  a Schematron validation context
+ * @serror:  the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlSchematronSetValidStructuredErrors(xmlSchematronValidCtxtPtr ctxt,
+                                      xmlStructuredErrorFunc serror, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->serror = serror;
+    ctxt->error = NULL;
+    ctxt->warning = NULL;
+    ctxt->userData = ctx;
+}
+
+/**
+ * xmlSchematronNewValidCtxt:
+ * @schema:  a precompiled XML Schematrons
+ * @options: a set of xmlSchematronValidOptions
+ *
+ * Create an XML Schematrons validation context based on the given schema.
+ *
+ * Returns the validation context or NULL in case of error
+ */
+xmlSchematronValidCtxtPtr
+xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
+{
+    int i;
+    xmlSchematronValidCtxtPtr ret;
+
+    ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt));
+    if (ret == NULL) {
+        xmlSchematronVErrMemory(NULL, "allocating validation context",
+                                NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchematronValidCtxt));
+    ret->type = XML_STRON_CTXT_VALIDATOR;
+    ret->schema = schema;
+    ret->xctxt = xmlXPathNewContext(NULL);
+    ret->flags = options;
+    if (ret->xctxt == NULL) {
+        xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
+                                NULL);
+	xmlSchematronFreeValidCtxt(ret);
+        return (NULL);
+    }
+    for (i = 0;i < schema->nbNamespaces;i++) {
+        if ((schema->namespaces[2 * i] == NULL) ||
+            (schema->namespaces[2 * i + 1] == NULL))
+	    break;
+	xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
+	                   schema->namespaces[2 * i]);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchematronFreeValidCtxt:
+ * @ctxt:  the schema validation context
+ *
+ * Free the resources associated to the schema validation context
+ */
+void
+xmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->xctxt != NULL)
+        xmlXPathFreeContext(ctxt->xctxt);
+    if (ctxt->dict != NULL)
+        xmlDictFree(ctxt->dict);
+    xmlFree(ctxt);
+}
+
+static xmlNodePtr
+xmlSchematronNextNode(xmlNodePtr cur) {
+    if (cur->children != NULL) {
+	/*
+	 * Do not descend on entities declarations
+	 */
+	if (cur->children->type != XML_ENTITY_DECL) {
+	    cur = cur->children;
+	    /*
+	     * Skip DTDs
+	     */
+	    if (cur->type != XML_DTD_NODE)
+		return(cur);
+	}
+    }
+
+    while (cur->next != NULL) {
+	cur = cur->next;
+	if ((cur->type != XML_ENTITY_DECL) &&
+	    (cur->type != XML_DTD_NODE))
+	    return(cur);
+    }
+    
+    do {
+	cur = cur->parent;
+	if (cur == NULL) break;
+	if (cur->type == XML_DOCUMENT_NODE) return(NULL);
+	if (cur->next != NULL) {
+	    cur = cur->next;
+	    return(cur);
+	}
+    } while (cur != NULL);
+    return(cur);
+}
+
+/**
+ * xmlSchematronRunTest:
+ * @ctxt:  the schema validation context
+ * @test:  the current test
+ * @instance:  the document instace tree 
+ * @cur:  the current node in the instance
+ *
+ * Validate a rule against a tree instance at a given position
+ *
+ * Returns 1 in case of success, 0 if error and -1 in case of internal error
+ */
+static int
+xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
+     xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern)
+{
+    xmlXPathObjectPtr ret;
+    int failed;
+
+    failed = 0;
+    ctxt->xctxt->doc = instance;
+    ctxt->xctxt->node = cur;
+    ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt);
+    if (ret == NULL) {
+	failed = 1;
+    } else {
+        switch (ret->type) {
+	    case XPATH_XSLT_TREE:
+	    case XPATH_NODESET:
+		if ((ret->nodesetval == NULL) ||
+		    (ret->nodesetval->nodeNr == 0))
+		    failed = 1;
+		break;
+	    case XPATH_BOOLEAN:
+		failed = !ret->boolval;
+		break;
+	    case XPATH_NUMBER:
+		if ((xmlXPathIsNaN(ret->floatval)) ||
+		    (ret->floatval == 0.0))
+		    failed = 1;
+		break;
+	    case XPATH_STRING:
+		if ((ret->stringval == NULL) ||
+		    (ret->stringval[0] == 0))
+		    failed = 1;
+		break;
+	    case XPATH_UNDEFINED:
+	    case XPATH_POINT:
+	    case XPATH_RANGE:
+	    case XPATH_LOCATIONSET:
+	    case XPATH_USERS:
+		failed = 1;
+		break;
+	}
+	xmlXPathFreeObject(ret);
+    }
+    if ((failed) && (test->type == XML_SCHEMATRON_ASSERT))
+        ctxt->nberrors++;
+    else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT))
+        ctxt->nberrors++;
+
+    xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed);
+
+    return(!failed);
+}
+
+/**
+ * xmlSchematronValidateDoc:
+ * @ctxt:  the schema validation context
+ * @instance:  the document instace tree 
+ *
+ * Validate a tree instance against the schematron
+ *
+ * Returns 0 in case of success, -1 in case of internal error
+ *         and an error count otherwise.
+ */
+int
+xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
+{
+    xmlNodePtr cur, root;
+    xmlSchematronPatternPtr pattern;
+    xmlSchematronRulePtr rule;
+    xmlSchematronTestPtr test;
+
+    if ((ctxt == NULL) || (ctxt->schema == NULL) ||
+        (ctxt->schema->rules == NULL) || (instance == NULL))
+        return(-1);
+    ctxt->nberrors = 0;
+    root = xmlDocGetRootElement(instance);
+    if (root == NULL) {
+        TODO
+	ctxt->nberrors++;
+	return(1);
+    }
+    if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) ||
+        (ctxt->flags == 0)) {
+	/*
+	 * we are just trying to assert the validity of the document,
+	 * speed primes over the output, run in a single pass
+	 */
+	cur = root;
+	while (cur != NULL) {
+	    rule = ctxt->schema->rules;
+	    while (rule != NULL) {
+		if (xmlPatternMatch(rule->pattern, cur) == 1) {
+		    test = rule->tests;
+		    while (test != NULL) {
+			xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
+			test = test->next;
+		    }
+		}
+		rule = rule->next;
+	    }
+	    
+	    cur = xmlSchematronNextNode(cur);
+	}
+    } else {
+        /*
+	 * Process all contexts one at a time
+	 */
+	pattern = ctxt->schema->patterns;
+	
+	while (pattern != NULL) {
+	    xmlSchematronReportPattern(ctxt, pattern);
+
+	    /*
+	     * TODO convert the pattern rule to a direct XPath and
+	     * compute directly instead of using the pattern matching
+	     * over the full document... 
+	     * Check the exact semantic
+	     */
+	    cur = root;
+	    while (cur != NULL) {
+		rule = pattern->rules;
+		while (rule != NULL) {
+		    if (xmlPatternMatch(rule->pattern, cur) == 1) {
+			test = rule->tests;
+			while (test != NULL) {
+			    xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
+			    test = test->next;
+			}
+		    }
+		    rule = rule->patnext;
+		}
+		
+		cur = xmlSchematronNextNode(cur);
+	    }
+	    pattern = pattern->next;
+	}
+    }
+    return(ctxt->nberrors);
+}
+
+#ifdef STANDALONE
+int
+main(void)
+{
+    int ret;
+    xmlDocPtr instance;
+    xmlSchematronParserCtxtPtr pctxt;
+    xmlSchematronValidCtxtPtr vctxt;
+    xmlSchematronPtr schema = NULL;
+
+    pctxt = xmlSchematronNewParserCtxt("tst.sct");
+    if (pctxt == NULL) {
+        fprintf(stderr, "failed to build schematron parser\n");
+    } else {
+        schema = xmlSchematronParse(pctxt);
+	if (schema == NULL) {
+	    fprintf(stderr, "failed to compile schematron\n");
+	}
+	xmlSchematronFreeParserCtxt(pctxt);
+    }
+    instance = xmlReadFile("tst.sct", NULL,
+                           XML_PARSE_NOENT | XML_PARSE_NOCDATA);
+    if (instance == NULL) {
+	fprintf(stderr, "failed to parse instance\n");
+    }
+    if ((schema != NULL) && (instance != NULL)) {
+        vctxt = xmlSchematronNewValidCtxt(schema);
+	if (vctxt == NULL) {
+	    fprintf(stderr, "failed to build schematron validator\n");
+	} else {
+	    ret = xmlSchematronValidateDoc(vctxt, instance);
+	    xmlSchematronFreeValidCtxt(vctxt);
+	}
+    }
+    xmlSchematronFree(schema);
+    xmlFreeDoc(instance);
+
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return (0);
+}
+#endif
+#define bottom_schematron
+#include "elfgcchack.h"
+#endif /* LIBXML_SCHEMATRON_ENABLED */
diff --git a/src/testAutomata.c b/src/testAutomata.c
new file mode 100644
index 0000000..2f575ce
--- /dev/null
+++ b/src/testAutomata.c
@@ -0,0 +1,309 @@
+/*
+ * testRegexp.c: simple module for testing regular expressions
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#include "libxml.h"
+#ifdef LIBXML_AUTOMATA_ENABLED
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/xmlautomata.h>
+
+static int scanNumber(char **ptr) {
+    int ret = 0;
+    char *cur;
+
+    cur = *ptr;
+    while ((*cur >= '0') && (*cur <= '9')) {
+	ret = ret * 10 + (*cur - '0');
+	cur++;
+    }
+    *ptr = cur;
+    return(ret);
+}
+
+static void
+testRegexpFile(const char *filename) {
+    FILE *input;
+    char expr[5000];
+    int len;
+    int ret;
+    int i;
+    xmlAutomataPtr am;
+    xmlAutomataStatePtr states[1000];
+    xmlRegexpPtr regexp = NULL;
+    xmlRegExecCtxtPtr exec = NULL;
+
+    for (i = 0;i<1000;i++)
+	states[i] = NULL;
+
+    input = fopen(filename, "r");
+    if (input == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot open %s for reading\n", filename);
+	return;
+    }
+
+    am = xmlNewAutomata();
+    if (am == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot create automata\n");
+	fclose(input);
+	return;
+    }
+    states[0] = xmlAutomataGetInitState(am);
+    if (states[0] == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot get start state\n");
+	xmlFreeAutomata(am);
+	fclose(input);
+	return;
+    }
+    ret = 0;
+
+    while (fgets(expr, 4500, input) != NULL) {
+	if (expr[0] == '#')
+	    continue;
+	len = strlen(expr);
+	len--;
+	while ((len >= 0) && 
+	       ((expr[len] == '\n') || (expr[len] == '\t') ||
+		(expr[len] == '\r') || (expr[len] == ' '))) len--;
+	expr[len + 1] = 0;      
+	if (len >= 0) {
+	    if ((am != NULL) && (expr[0] == 't') && (expr[1] == ' ')) {
+		char *ptr = &expr[2];
+		int from, to;
+
+		from = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		if (states[from] == NULL)
+		    states[from] = xmlAutomataNewState(am);
+		ptr++;
+		to = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		if (states[to] == NULL)
+		    states[to] = xmlAutomataNewState(am);
+		ptr++;
+		xmlAutomataNewTransition(am, states[from], states[to],
+			                 BAD_CAST ptr, NULL);
+	    } else if ((am != NULL) && (expr[0] == 'e') && (expr[1] == ' ')) {
+		char *ptr = &expr[2];
+		int from, to;
+
+		from = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		if (states[from] == NULL)
+		    states[from] = xmlAutomataNewState(am);
+		ptr++;
+		to = scanNumber(&ptr);
+		if (states[to] == NULL)
+		    states[to] = xmlAutomataNewState(am);
+		xmlAutomataNewEpsilon(am, states[from], states[to]);
+	    } else if ((am != NULL) && (expr[0] == 'f') && (expr[1] == ' ')) {
+		char *ptr = &expr[2];
+		int state;
+
+		state = scanNumber(&ptr);
+		if (states[state] == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad state %d : %s\n", state, expr);
+		    break;
+		}
+		xmlAutomataSetFinalState(am, states[state]);
+	    } else if ((am != NULL) && (expr[0] == 'c') && (expr[1] == ' ')) {
+		char *ptr = &expr[2];
+		int from, to;
+		int min, max;
+
+		from = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		if (states[from] == NULL)
+		    states[from] = xmlAutomataNewState(am);
+		ptr++;
+		to = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		if (states[to] == NULL)
+		    states[to] = xmlAutomataNewState(am);
+		ptr++;
+		min = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		ptr++;
+		max = scanNumber(&ptr);
+		if (*ptr != ' ') {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Bad line %s\n", expr);
+		    break;
+		}
+		ptr++;
+		xmlAutomataNewCountTrans(am, states[from], states[to],
+			                 BAD_CAST ptr, min, max, NULL);
+	    } else if ((am != NULL) && (expr[0] == '-') && (expr[1] == '-')) {
+		/* end of the automata */
+		regexp = xmlAutomataCompile(am);
+		xmlFreeAutomata(am);
+		am = NULL;
+		if (regexp == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Failed to compile the automata");
+		    break;
+		}
+	    } else if ((expr[0] == '=') && (expr[1] == '>')) {
+		if (regexp == NULL) {
+		    printf("=> failed not compiled\n");
+		} else {
+		    if (exec == NULL)
+			exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
+		    if (ret == 0) {
+			ret = xmlRegExecPushString(exec, NULL, NULL);
+		    }
+		    if (ret == 1)
+			printf("=> Passed\n");
+		    else if ((ret == 0) || (ret == -1))
+			printf("=> Failed\n");
+		    else if (ret < 0)
+			printf("=> Error\n");
+		    xmlRegFreeExecCtxt(exec);
+		    exec = NULL;
+		}
+		ret = 0;
+	    } else if (regexp != NULL) {
+		if (exec == NULL)
+		    exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
+		ret = xmlRegExecPushString(exec, BAD_CAST expr, NULL);
+	    } else {
+		xmlGenericError(xmlGenericErrorContext,
+			"Unexpected line %s\n", expr);
+	    }
+	}
+    }
+    fclose(input);
+    if (regexp != NULL)
+	xmlRegFreeRegexp(regexp);
+    if (exec != NULL)
+	xmlRegFreeExecCtxt(exec);
+    if (am != NULL)
+	xmlFreeAutomata(am);
+}
+
+int main(int argc, char **argv) {
+
+    xmlInitMemory();
+
+    if (argc == 1) {
+	int ret;
+	xmlAutomataPtr am;
+	xmlAutomataStatePtr start, cur;
+	xmlRegexpPtr regexp;
+	xmlRegExecCtxtPtr exec;
+
+	am = xmlNewAutomata();
+	start = xmlAutomataGetInitState(am);
+
+	/* generate a[ba]*a */
+	cur = xmlAutomataNewTransition(am, start, NULL, BAD_CAST"a", NULL);
+	xmlAutomataNewTransition(am, cur, cur, BAD_CAST"b", NULL);
+	xmlAutomataNewTransition(am, cur, cur, BAD_CAST"a", NULL);
+	cur = xmlAutomataNewCountTrans(am, cur, NULL, BAD_CAST"a", 2, 3, NULL);
+	xmlAutomataSetFinalState(am, cur);
+
+	/* compile it in a regexp and free the automata */
+	regexp = xmlAutomataCompile(am);
+	xmlFreeAutomata(am);
+
+	/* test the regexp */
+	xmlRegexpPrint(stdout, regexp);
+	exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
+	ret = xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"b", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
+	if (ret == 1)
+	    printf("final\n");
+	else if (ret < 0)
+	    printf("error\n");
+	if (ret == 0) {
+	    ret = xmlRegExecPushString(exec, NULL, NULL);
+	    if (ret == 1)
+		printf("final\n");
+	    else if (ret < 0)
+		printf("error\n");
+	}
+	xmlRegFreeExecCtxt(exec);
+
+	/* free the regexp */
+	xmlRegFreeRegexp(regexp);
+    } else {
+	int i;
+
+	for (i = 1;i < argc;i++)
+	    testRegexpFile(argv[i]);
+    }
+
+    xmlCleanupParser();
+    xmlMemoryDump();
+    return(0);
+}
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : Automata support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_AUTOMATA_ENABLED */
diff --git a/src/testC14N.c b/src/testC14N.c
new file mode 100644
index 0000000..fbfa869
--- /dev/null
+++ b/src/testC14N.c
@@ -0,0 +1,364 @@
+/*
+ * Canonical XML implementation test program
+ * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
+ *
+ * See Copyright for the status of this software.
+ * 
+ * Author: Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "libxml.h"
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxml/c14n.h>
+
+
+static void usage(const char *name) {
+    fprintf(stderr,
+	"Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n",
+	    name);
+    fprintf(stderr, "where <mode> is one of following:\n");
+    fprintf(stderr,
+	"--with-comments       \t XML file canonicalization v1.0 w comments \n");
+    fprintf(stderr,
+	"--without-comments    \t XML file canonicalization v1.0 w/o comments\n");
+    fprintf(stderr,
+	"--1-1-with-comments       \t XML file canonicalization v1.1 w comments\n");
+    fprintf(stderr,
+	"--1-1-without-comments    \t XML file canonicalization v1.1 w/o comments\n");
+    fprintf(stderr,
+    "--exc-with-comments   \t Exclusive XML file canonicalization v1.0 w comments\n");
+    fprintf(stderr,
+    "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n");
+}
+
+static xmlXPathObjectPtr
+load_xpath_expr (xmlDocPtr parent_doc, const char* filename);
+
+static xmlChar **parse_list(xmlChar *str);
+
+/* static void print_xpath_nodes(xmlNodeSetPtr nodes); */
+
+static int 
+test_c14n(const char* xml_filename, int with_comments, int mode,
+	const char* xpath_filename, xmlChar **inclusive_namespaces) {
+    xmlDocPtr doc;
+    xmlXPathObjectPtr xpath = NULL; 
+    xmlChar *result = NULL;
+    int ret;
+
+    /*
+     * build an XML tree from a the file; we need to add default
+     * attributes and resolve all character and entities references
+     */
+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+
+    doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (doc == NULL) {
+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
+	return(-1);
+    }
+    
+    /*
+     * Check the document is of the right kind
+     */    
+    if(xmlDocGetRootElement(doc) == NULL) {
+        fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);
+	xmlFreeDoc(doc);
+	return(-1);
+    }
+
+    /* 
+     * load xpath file if specified 
+     */
+    if(xpath_filename) {
+	xpath = load_xpath_expr(doc, xpath_filename);
+	if(xpath == NULL) {
+	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
+	    xmlFreeDoc(doc); 
+	    return(-1);
+	}
+    }
+
+    /*
+     * Canonical form
+     */      
+    /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
+    ret = xmlC14NDocDumpMemory(doc, 
+	    (xpath) ? xpath->nodesetval : NULL, 
+	    mode, inclusive_namespaces,
+	    with_comments, &result);
+    if(ret >= 0) {
+	if(result != NULL) {
+	    write(1, result, ret);
+	    xmlFree(result);          
+	}
+    } else {
+	fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);
+	if(result != NULL) xmlFree(result);
+	xmlFreeDoc(doc); 
+	return(-1);
+    }
+        
+    /*
+     * Cleanup
+     */ 
+    if(xpath != NULL) xmlXPathFreeObject(xpath);
+    xmlFreeDoc(doc);    
+
+    return(ret);
+}
+
+int main(int argc, char **argv) {
+    int ret = -1;
+    
+    /*
+     * Init libxml
+     */     
+    xmlInitParser();
+    LIBXML_TEST_VERSION
+
+    /*
+     * Parse command line and process file
+     */
+    if( argc < 3 ) {
+	fprintf(stderr, "Error: wrong number of arguments.\n");
+	usage(argv[0]);
+    } else if(strcmp(argv[1], "--with-comments") == 0) {
+	ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
+    } else if(strcmp(argv[1], "--without-comments") == 0) {
+	ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
+    } else if(strcmp(argv[1], "--1-1-with-comments") == 0) {
+	ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
+    } else if(strcmp(argv[1], "--1-1-without-comments") == 0) {
+	ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
+    } else if(strcmp(argv[1], "--exc-with-comments") == 0) {
+	xmlChar **list;
+	
+	/* load exclusive namespace from command line */
+	list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
+	ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
+	if(list != NULL) xmlFree(list);
+    } else if(strcmp(argv[1], "--exc-without-comments") == 0) {
+	xmlChar **list;
+	
+	/* load exclusive namespace from command line */
+	list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
+	ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
+	if(list != NULL) xmlFree(list);
+    } else {
+	fprintf(stderr, "Error: bad option.\n");
+	usage(argv[0]);
+    }
+
+    /* 
+     * Shutdown libxml
+     */
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return((ret >= 0) ? 0 : 1);
+}
+
+/*
+ * Macro used to grow the current buffer.
+ */
+#define growBufferReentrant() {						\
+    buffer_size *= 2;							\
+    buffer = (xmlChar **)						\
+		xmlRealloc(buffer, buffer_size * sizeof(xmlChar*));	\
+    if (buffer == NULL) {						\
+	perror("realloc failed");					\
+	return(NULL);							\
+    }									\
+}
+
+static xmlChar **
+parse_list(xmlChar *str) {
+    xmlChar **buffer;
+    xmlChar **out = NULL;
+    int buffer_size = 0;
+    int len;
+
+    if(str == NULL) {
+	return(NULL);
+    }
+
+    len = xmlStrlen(str);
+    if((str[0] == '\'') && (str[len - 1] == '\'')) {
+	str[len - 1] = '\0';
+	str++;
+    }
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));
+    if (buffer == NULL) {
+	perror("malloc failed");
+	return(NULL);
+    }
+    out = buffer;
+
+    while(*str != '\0') {
+	if (out - buffer > buffer_size - 10) {
+	    int indx = out - buffer;
+
+	    growBufferReentrant();
+	    out = &buffer[indx];
+	}
+	(*out++) = str;
+	while(*str != ',' && *str != '\0') ++str;
+	if(*str == ',') *(str++) = '\0';
+    }
+    (*out) = NULL;
+    return buffer;
+}
+
+static xmlXPathObjectPtr
+load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
+    xmlXPathObjectPtr xpath; 
+    xmlDocPtr doc;
+    xmlChar *expr;
+    xmlXPathContextPtr ctx; 
+    xmlNodePtr node;
+    xmlNsPtr ns;
+    
+    /*
+     * load XPath expr as a file
+     */
+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+
+    doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+    if (doc == NULL) {
+	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
+	return(NULL);
+    }
+    
+    /*
+     * Check the document is of the right kind
+     */    
+    if(xmlDocGetRootElement(doc) == NULL) {
+        fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    node = doc->children;
+    while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {
+	node = node->next;
+    }
+    
+    if(node == NULL) {   
+        fprintf(stderr,"Error: XPath element expected in the file  \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    expr = xmlNodeGetContent(node);
+    if(expr == NULL) {
+        fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);
+	xmlFreeDoc(doc);
+	return(NULL);
+    }
+
+    ctx = xmlXPathNewContext(parent_doc);
+    if(ctx == NULL) {
+        fprintf(stderr,"Error: unable to create new context\n");
+        xmlFree(expr); 
+        xmlFreeDoc(doc); 
+        return(NULL);
+    }
+
+    /*
+     * Register namespaces
+     */
+    ns = node->nsDef;
+    while(ns != NULL) {
+	if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {
+	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);
+    	    xmlFree(expr); 
+	    xmlXPathFreeContext(ctx); 
+	    xmlFreeDoc(doc); 
+	    return(NULL);
+	}
+	ns = ns->next;
+    }
+
+    /*  
+     * Evaluate xpath
+     */
+    xpath = xmlXPathEvalExpression(expr, ctx);
+    if(xpath == NULL) {
+        fprintf(stderr,"Error: unable to evaluate xpath expression\n");
+    	xmlFree(expr); 
+        xmlXPathFreeContext(ctx); 
+        xmlFreeDoc(doc); 
+        return(NULL);
+    }
+
+    /* print_xpath_nodes(xpath->nodesetval); */
+
+    xmlFree(expr); 
+    xmlXPathFreeContext(ctx); 
+    xmlFreeDoc(doc); 
+    return(xpath);
+}
+
+/*
+static void
+print_xpath_nodes(xmlNodeSetPtr nodes) {
+    xmlNodePtr cur;
+    int i;
+    
+    if(nodes == NULL ){ 
+	fprintf(stderr, "Error: no nodes set defined\n");
+	return;
+    }
+    
+    fprintf(stderr, "Nodes Set:\n-----\n");
+    for(i = 0; i < nodes->nodeNr; ++i) {
+	if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+	    xmlNsPtr ns;
+	    
+	    ns = (xmlNsPtr)nodes->nodeTab[i];
+	    cur = (xmlNodePtr)ns->next;
+	    fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n", 
+		    ns->prefix, ns->href,
+		    (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
+	} else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
+	    cur = nodes->nodeTab[i];    
+	    fprintf(stderr, "element node \"%s:%s\"\n", 
+		    (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
+	} else {
+	    cur = nodes->nodeTab[i];    
+	    fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type);
+	}
+    }
+}
+*/
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_C14N_ENABLED */
+
+
diff --git a/src/testHTML.c b/src/testHTML.c
new file mode 100644
index 0000000..f350342
--- /dev/null
+++ b/src/testHTML.c
@@ -0,0 +1,880 @@
+/*
+ * testHTML.c : a small tester program for HTML input.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#ifdef LIBXML_HTML_ENABLED
+
+#include <string.h>
+#include <stdarg.h>
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+
+#ifdef LIBXML_DEBUG_ENABLED
+static int debug = 0;
+#endif
+static int copy = 0;
+static int sax = 0;
+static int repeat = 0;
+static int noout = 0;
+#ifdef LIBXML_PUSH_ENABLED
+static int push = 0;
+#endif /* LIBXML_PUSH_ENABLED */
+static char *encoding = NULL;
+static int options = 0;
+
+static xmlSAXHandler emptySAXHandlerStruct = {
+    NULL, /* internalSubset */
+    NULL, /* isStandalone */
+    NULL, /* hasInternalSubset */
+    NULL, /* hasExternalSubset */
+    NULL, /* resolveEntity */
+    NULL, /* getEntity */
+    NULL, /* entityDecl */
+    NULL, /* notationDecl */
+    NULL, /* attributeDecl */
+    NULL, /* elementDecl */
+    NULL, /* unparsedEntityDecl */
+    NULL, /* setDocumentLocator */
+    NULL, /* startDocument */
+    NULL, /* endDocument */
+    NULL, /* startElement */
+    NULL, /* endElement */
+    NULL, /* reference */
+    NULL, /* characters */
+    NULL, /* ignorableWhitespace */
+    NULL, /* processingInstruction */
+    NULL, /* comment */
+    NULL, /* xmlParserWarning */
+    NULL, /* xmlParserError */
+    NULL, /* xmlParserError */
+    NULL, /* getParameterEntity */
+    NULL, /* cdataBlock */
+    NULL, /* externalSubset */
+    1,    /* initialized */
+    NULL, /* private */
+    NULL, /* startElementNsSAX2Func */
+    NULL, /* endElementNsSAX2Func */
+    NULL  /* xmlStructuredErrorFunc */
+};
+
+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
+extern xmlSAXHandlerPtr debugSAXHandler;
+
+/************************************************************************
+ *									*
+ *				Debug Handlers				*
+ *									*
+ ************************************************************************/
+
+/**
+ * isStandaloneDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.isStandalone()\n");
+    return(0);
+}
+
+/**
+ * hasInternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.hasInternalSubset()\n");
+    return(0);
+}
+
+/**
+ * hasExternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.hasExternalSubset()\n");
+    return(0);
+}
+
+/**
+ * hasInternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    fprintf(stdout, "SAX.internalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(stdout, " ,");
+    else
+	fprintf(stdout, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(stdout, " )\n");
+    else
+	fprintf(stdout, " %s)\n", SystemID);
+}
+
+/**
+ * resolveEntityDebug:
+ * @ctxt:  An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
+{
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+
+    
+    fprintf(stdout, "SAX.resolveEntity(");
+    if (publicId != NULL)
+	fprintf(stdout, "%s", (char *)publicId);
+    else
+	fprintf(stdout, " ");
+    if (systemId != NULL)
+	fprintf(stdout, ", %s)\n", (char *)systemId);
+    else
+	fprintf(stdout, ", )\n");
+/*********
+    if (systemId != NULL) {
+        return(xmlNewInputFromFile(ctxt, (char *) systemId));
+    }
+ *********/
+    return(NULL);
+}
+
+/**
+ * getEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    fprintf(stdout, "SAX.getEntity(%s)\n", name);
+    return(NULL);
+}
+
+/**
+ * getParameterEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
+    return(NULL);
+}
+
+
+/**
+ * entityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @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).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+    fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
+            name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the attribute name 
+ * @type:  the attribute type 
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
+              int type, int def, const xmlChar *defaultValue,
+	      xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
+            elem, name, type, def, defaultValue);
+}
+
+/**
+ * elementDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the element name 
+ * @type:  the element type 
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
+            name, type);
+}
+
+/**
+ * notationDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId);
+}
+
+/**
+ * unparsedEntityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+    fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId,
+	    (char *) notationName);
+}
+
+/**
+ * setDocumentLocatorDebug:
+ * @ctxt:  An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.setDocumentLocator()\n");
+}
+
+/**
+ * startDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.startDocument()\n");
+}
+
+/**
+ * endDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    fprintf(stdout, "SAX.endDocument()\n");
+}
+
+/**
+ * startElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    fprintf(stdout, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+	    fprintf(stdout, ", %s", atts[i++]);
+	    if (atts[i] != NULL) {
+		unsigned char output[40];
+		const unsigned char *att = atts[i];
+		int outlen, attlen;
+	        fprintf(stdout, "='");
+		while ((attlen = strlen((char*)att)) > 0) {
+		    outlen = sizeof output - 1;
+		    htmlEncodeEntities(output, &outlen, att, &attlen, '\'');
+		    output[outlen] = 0;
+		    fprintf(stdout, "%s", (char *) output);
+		    att += attlen;
+		}
+		fprintf(stdout, "'");
+	    }
+	}
+    }
+    fprintf(stdout, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
+}
+
+/**
+ * charactersDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    unsigned char output[40];
+    int inlen = len, outlen = 30;
+
+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
+    output[outlen] = 0;
+
+    fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
+}
+
+/**
+ * cdataDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some cdata chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+cdataDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    unsigned char output[40];
+    int inlen = len, outlen = 30;
+
+    htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
+    output[outlen] = 0;
+
+    fprintf(stdout, "SAX.cdata(%s, %d)\n", output, len);
+}
+
+/**
+ * referenceDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected. 
+ */
+static void
+referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    fprintf(stdout, "SAX.reference(%s)\n", name);
+}
+
+/**
+ * ignorableWhitespaceDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char output[40];
+    int i;
+
+    for (i = 0;(i<len) && (i < 30);i++)
+	output[i] = ch[i];
+    output[i] = 0;
+
+    fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
+}
+
+/**
+ * processingInstructionDebug:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+                      const xmlChar *data)
+{
+    fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
+            (char *) target, (char *) data);
+}
+
+/**
+ * commentDebug:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+    fprintf(stdout, "SAX.comment(%s)\n", value);
+}
+
+/**
+ * warningDebug:
+ * @ctxt:  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.
+ */
+static void XMLCDECL
+warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    va_start(args, msg);
+    fprintf(stdout, "SAX.warning: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * errorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    va_start(args, msg);
+    fprintf(stdout, "SAX.error: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * fatalErrorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    va_start(args, msg);
+    fprintf(stdout, "SAX.fatalError: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+static xmlSAXHandler debugSAXHandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    startElementDebug,
+    endElementDebug,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataDebug,
+    NULL,
+    1,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
+/************************************************************************
+ *									*
+ *				Debug					*
+ *									*
+ ************************************************************************/
+
+static void
+parseSAXFile(char *filename) {
+    htmlDocPtr doc = NULL;
+
+    /*
+     * Empty callbacks for checking
+     */
+#ifdef LIBXML_PUSH_ENABLED
+    if (push) {
+	FILE *f;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+	f = fopen(filename, "rb");
+#else
+	f = fopen(filename, "r");
+#endif
+	if (f != NULL) {
+	    int res, size = 3;
+	    char chars[4096];
+	    htmlParserCtxtPtr ctxt;
+
+	    /* if (repeat) */
+		size = 4096;
+	    res = fread(chars, 1, 4, f);
+	    if (res > 0) {
+		ctxt = htmlCreatePushParserCtxt(emptySAXHandler, NULL,
+			    chars, res, filename, XML_CHAR_ENCODING_NONE);
+		while ((res = fread(chars, 1, size, f)) > 0) {
+		    htmlParseChunk(ctxt, chars, res, 0);
+		}
+		htmlParseChunk(ctxt, chars, 0, 1);
+		doc = ctxt->myDoc;
+		htmlFreeParserCtxt(ctxt);
+	    }
+	    if (doc != NULL) {
+		fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
+		xmlFreeDoc(doc);
+	    }
+	    fclose(f);
+	}
+	if (!noout) {
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+		f = fopen(filename, "rb");
+#else
+		f = fopen(filename, "r");
+#endif
+	    if (f != NULL) {
+		int res, size = 3;
+		char chars[4096];
+		htmlParserCtxtPtr ctxt;
+
+		/* if (repeat) */
+		    size = 4096;
+		res = fread(chars, 1, 4, f);
+		if (res > 0) {
+		    ctxt = htmlCreatePushParserCtxt(debugSAXHandler, NULL,
+				chars, res, filename, XML_CHAR_ENCODING_NONE);
+		    while ((res = fread(chars, 1, size, f)) > 0) {
+			htmlParseChunk(ctxt, chars, res, 0);
+		    }
+		    htmlParseChunk(ctxt, chars, 0, 1);
+		    doc = ctxt->myDoc;
+		    htmlFreeParserCtxt(ctxt);
+		}
+		if (doc != NULL) {
+		    fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
+		    xmlFreeDoc(doc);
+		}
+		fclose(f);
+	    }
+	}
+    } else {	
+#endif /* LIBXML_PUSH_ENABLED */
+	doc = htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
+	if (doc != NULL) {
+	    fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
+	    xmlFreeDoc(doc);
+	}
+
+	if (!noout) {
+	    /*
+	     * Debug callback
+	     */
+	    doc = htmlSAXParseFile(filename, NULL, debugSAXHandler, NULL);
+	    if (doc != NULL) {
+		fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
+		xmlFreeDoc(doc);
+	    }
+	}
+#ifdef LIBXML_PUSH_ENABLED
+    }
+#endif /* LIBXML_PUSH_ENABLED */
+}
+
+static void
+parseAndPrintFile(char *filename) {
+    htmlDocPtr doc = NULL;
+
+    /*
+     * build an HTML tree from a string;
+     */
+#ifdef LIBXML_PUSH_ENABLED
+    if (push) {
+	FILE *f;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+	f = fopen(filename, "rb");
+#else
+	f = fopen(filename, "r");
+#endif
+	if (f != NULL) {
+	    int res, size = 3;
+	    char chars[4096];
+	    htmlParserCtxtPtr ctxt;
+
+	    /* if (repeat) */
+		size = 4096;
+	    res = fread(chars, 1, 4, f);
+	    if (res > 0) {
+		ctxt = htmlCreatePushParserCtxt(NULL, NULL,
+			    chars, res, filename, XML_CHAR_ENCODING_NONE);
+		while ((res = fread(chars, 1, size, f)) > 0) {
+		    htmlParseChunk(ctxt, chars, res, 0);
+		}
+		htmlParseChunk(ctxt, chars, 0, 1);
+		doc = ctxt->myDoc;
+		htmlFreeParserCtxt(ctxt);
+	    }
+	    fclose(f);
+	}
+    } else {	
+	doc = htmlReadFile(filename, NULL, options);
+    }
+#else
+	doc = htmlReadFile(filename,NULL,options);
+#endif
+    if (doc == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Could not parse %s\n", filename);
+    }
+
+#ifdef LIBXML_TREE_ENABLED
+    /*
+     * test intermediate copy if needed.
+     */
+    if (copy) {
+        htmlDocPtr tmp;
+
+        tmp = doc;
+	doc = xmlCopyDoc(doc, 1);
+	xmlFreeDoc(tmp);
+    }
+#endif
+
+#ifdef LIBXML_OUTPUT_ENABLED
+    /*
+     * print it.
+     */
+    if (!noout) { 
+#ifdef LIBXML_DEBUG_ENABLED
+	if (!debug) {
+	    if (encoding)
+		htmlSaveFileEnc("-", doc, encoding);
+	    else
+		htmlDocDump(stdout, doc);
+	} else
+	    xmlDebugDumpDocument(stdout, doc);
+#else
+	if (encoding)
+	    htmlSaveFileEnc("-", doc, encoding);
+	else
+	    htmlDocDump(stdout, doc);
+#endif
+    }	
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+    /*
+     * free it.
+     */
+    xmlFreeDoc(doc);
+}
+
+int main(int argc, char **argv) {
+    int i, count;
+    int files = 0;
+
+    for (i = 1; i < argc ; i++) {
+#ifdef LIBXML_DEBUG_ENABLED
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else
+#endif
+	    if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
+	    copy++;
+#ifdef LIBXML_PUSH_ENABLED
+	else if ((!strcmp(argv[i], "-push")) || (!strcmp(argv[i], "--push")))
+	    push++;
+#endif /* LIBXML_PUSH_ENABLED */
+	else if ((!strcmp(argv[i], "-sax")) || (!strcmp(argv[i], "--sax")))
+	    sax++;
+	else if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout")))
+	    noout++;
+	else if ((!strcmp(argv[i], "-repeat")) ||
+	         (!strcmp(argv[i], "--repeat")))
+	    repeat++;
+	else if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    encoding = argv[i];
+        }
+    }
+    for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    continue;
+        }
+	if (argv[i][0] != '-') {
+	    if (repeat) {
+		for (count = 0;count < 100 * repeat;count++) {
+		    if (sax)
+			parseSAXFile(argv[i]);
+		    else   
+			parseAndPrintFile(argv[i]);
+		}    
+	    } else {
+		if (sax)
+		    parseSAXFile(argv[i]);
+		else   
+		    parseAndPrintFile(argv[i]);
+	    }
+	    files ++;
+	}
+    }
+    if (files == 0) {
+	printf("Usage : %s [--debug] [--copy] [--copy] HTMLfiles ...\n",
+	       argv[0]);
+	printf("\tParse the HTML files and output the result of the parsing\n");
+#ifdef LIBXML_DEBUG_ENABLED
+	printf("\t--debug : dump a debug tree of the in-memory document\n");
+#endif
+	printf("\t--copy : used to test the internal copy implementation\n");
+	printf("\t--sax : debug the sequence of SAX callbacks\n");
+	printf("\t--repeat : parse the file 100 times, for timing\n");
+	printf("\t--noout : do not print the result\n");
+#ifdef LIBXML_PUSH_ENABLED
+	printf("\t--push : use the push mode parser\n");
+#endif /* LIBXML_PUSH_ENABLED */
+	printf("\t--encode encoding : output in the given encoding\n");
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+#else /* !LIBXML_HTML_ENABLED */
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : HTML support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif
diff --git a/src/testModule.c b/src/testModule.c
new file mode 100644
index 0000000..8293c45
--- /dev/null
+++ b/src/testModule.c
@@ -0,0 +1,82 @@
+/*
+ * testModule.c : a small tester program for xmlModule
+ *
+ * See Copyright for the status of this software.
+ *
+ * joelwreed@comcast.net
+ */
+
+#include "libxml.h"
+#ifdef LIBXML_MODULES_ENABLED
+#include <libxml/xmlversion.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmodule.h>
+
+#ifdef _WIN32
+#define MODULE_PATH "."
+#include <stdlib.h> /* for _MAX_PATH */
+#ifndef __MINGW32__
+#define PATH_MAX _MAX_PATH
+#endif
+#else
+#define MODULE_PATH ".libs"
+#endif
+
+/* Used for SCO Openserver*/
+#ifndef PATH_MAX
+#ifdef _POSIX_PATH_MAX
+#define PATH_MAX _POSIX_PATH_MAX
+#else
+#define PATH_MAX 4096
+#endif
+#endif
+
+typedef int (*hello_world_t)(void);
+ 
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    xmlChar filename[PATH_MAX];
+    xmlModulePtr module = NULL;
+    hello_world_t hello_world = NULL;
+
+    /* build the module filename, and confirm the module exists */
+    xmlStrPrintf(filename, sizeof(filename),
+                 (const xmlChar*) "%s/testdso%s",
+                 (const xmlChar*)MODULE_PATH,
+		 (const xmlChar*)LIBXML_MODULE_EXTENSION);
+
+    module = xmlModuleOpen((const char*)filename, 0);
+    if (module)
+      {
+        if (xmlModuleSymbol(module, "hello_world", (void **) &hello_world)) {
+	    fprintf(stderr, "Failure to lookup\n");
+	    return(1);
+	}
+	if (hello_world == NULL) {
+	    fprintf(stderr, "Lookup returned NULL\n");
+	    return(1);
+	}
+	
+        (*hello_world)();
+
+        xmlModuleClose(module);
+      }
+
+    xmlMemoryDump();
+
+    return(0);
+}
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : Module support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/testReader.c b/src/testReader.c
new file mode 100644
index 0000000..8f8e26d
--- /dev/null
+++ b/src/testReader.c
@@ -0,0 +1,145 @@
+/*
+ * testSAX.c : a small tester program for parsing using the SAX API.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#ifdef LIBXML_READER_ENABLED
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+
+#include <libxml/xmlreader.h>
+
+static int debug = 0;
+static int dump = 0;
+static int noent = 0;
+static int count = 0;
+static int valid = 0;
+static int consumed = 0;
+
+static void usage(const char *progname) {
+    printf("Usage : %s [options] XMLfiles ...\n", progname);
+    printf("\tParse the XML files using the xmlTextReader API\n");
+    printf("\t --count: count the number of attribute and elements\n");
+    printf("\t --valid: validate the document\n");
+    printf("\t --consumed: count the number of bytes consumed\n");
+    exit(1);
+}
+static int elem, attrs;
+
+static void processNode(xmlTextReaderPtr reader) {
+    int type;
+
+    type = xmlTextReaderNodeType(reader);
+    if (count) {
+	if (type == 1) {
+	    elem++;
+	    attrs += xmlTextReaderAttributeCount(reader);
+	}
+    }
+}
+
+static void handleFile(const char *filename) {
+    xmlTextReaderPtr reader;
+    int ret;
+
+    if (count) {
+	elem = 0;
+	attrs = 0;
+    }
+
+    reader = xmlNewTextReaderFilename(filename);
+    if (reader != NULL) {
+	if (valid)
+	    xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
+
+	/*
+	 * Process all nodes in sequence
+	 */
+	ret = xmlTextReaderRead(reader);
+	while (ret == 1) {
+	    processNode(reader);
+	    ret = xmlTextReaderRead(reader);
+	}
+
+	/*
+	 * Done, cleanup and status
+	 */
+	if (consumed)
+		printf("%ld bytes consumed by parser\n", xmlTextReaderByteConsumed(reader));
+	xmlFreeTextReader(reader);
+	if (ret != 0) {
+	    printf("%s : failed to parse\n", filename);
+	} else if (count)
+	    printf("%s : %d elements, %d attributes\n", filename, elem, attrs);
+    } else {
+	fprintf(stderr, "Unable to open %s\n", filename);
+    }
+}
+
+int main(int argc, char **argv) {
+    int i;
+    int files = 0;
+
+    if (argc <= 1) {
+	usage(argv[0]);
+	return(1);
+    }
+    LIBXML_TEST_VERSION
+    for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else if ((!strcmp(argv[i], "-dump")) || (!strcmp(argv[i], "--dump")))
+	    dump++;
+	else if ((!strcmp(argv[i], "-count")) || (!strcmp(argv[i], "--count")))
+	    count++;
+	else if ((!strcmp(argv[i], "-consumed")) || (!strcmp(argv[i], "--consumed")))
+	    consumed++;
+	else if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
+	    valid++;
+	else if ((!strcmp(argv[i], "-noent")) ||
+	         (!strcmp(argv[i], "--noent")))
+	    noent++;
+    }
+    if (noent != 0) xmlSubstituteEntitiesDefault(1);
+    for (i = 1; i < argc ; i++) {
+	if (argv[i][0] != '-') {
+	    handleFile(argv[i]);
+	    files ++;
+	}
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+#else
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : xmlReader parser support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_READER_ENABLED */
diff --git a/src/testRegexp.c b/src/testRegexp.c
new file mode 100644
index 0000000..626536e
--- /dev/null
+++ b/src/testRegexp.c
@@ -0,0 +1,402 @@
+/*
+ * testRegexp.c: simple module for testing regular expressions
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#include "libxml.h"
+#ifdef LIBXML_REGEXP_ENABLED
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/xmlregexp.h>
+
+static int repeat = 0;
+static int debug = 0;
+
+static void testRegexp(xmlRegexpPtr comp, const char *value) {
+    int ret;
+
+    ret = xmlRegexpExec(comp, (const xmlChar *) value);
+    if (ret == 1)
+	printf("%s: Ok\n", value);
+    else if (ret == 0)
+	printf("%s: Fail\n", value);
+    else
+	printf("%s: Error: %d\n", value, ret);
+    if (repeat) {
+	int j;
+	for (j = 0;j < 999999;j++)
+	    xmlRegexpExec(comp, (const xmlChar *) value);
+    }
+}
+
+static void
+testRegexpFile(const char *filename) {
+    xmlRegexpPtr comp = NULL;
+    FILE *input;
+    char expression[5000];
+    int len;
+
+    input = fopen(filename, "r");
+    if (input == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot open %s for reading\n", filename);
+	return;
+    }
+    while (fgets(expression, 4500, input) != NULL) {
+	len = strlen(expression);
+	len--;
+	while ((len >= 0) && 
+	       ((expression[len] == '\n') || (expression[len] == '\t') ||
+		(expression[len] == '\r') || (expression[len] == ' '))) len--;
+	expression[len + 1] = 0;      
+	if (len >= 0) {
+	    if (expression[0] == '#')
+		continue;
+	    if ((expression[0] == '=') && (expression[1] == '>')) {
+		char *pattern = &expression[2];
+
+		if (comp != NULL) {
+		    xmlRegFreeRegexp(comp);
+		    comp = NULL;
+		}
+		printf("Regexp: %s\n", pattern) ;
+		comp = xmlRegexpCompile((const xmlChar *) pattern);
+		if (comp == NULL) {
+		    printf("   failed to compile\n");
+		    break;
+		}
+	    } else if (comp == NULL) {
+		printf("Regexp: %s\n", expression) ;
+		comp = xmlRegexpCompile((const xmlChar *) expression);
+		if (comp == NULL) {
+		    printf("   failed to compile\n");
+		    break;
+		}
+	    } else if (comp != NULL) {
+		testRegexp(comp, expression);
+	    }
+	}
+    }
+    fclose(input);
+    if (comp != NULL)
+	xmlRegFreeRegexp(comp);
+}
+
+#ifdef LIBXML_EXPR_ENABLED
+static void
+runFileTest(xmlExpCtxtPtr ctxt, const char *filename) {
+    xmlExpNodePtr expr = NULL, sub;
+    FILE *input;
+    char expression[5000];
+    int len;
+
+    input = fopen(filename, "r");
+    if (input == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot open %s for reading\n", filename);
+	return;
+    }
+    while (fgets(expression, 4500, input) != NULL) {
+	len = strlen(expression);
+	len--;
+	while ((len >= 0) && 
+	       ((expression[len] == '\n') || (expression[len] == '\t') ||
+		(expression[len] == '\r') || (expression[len] == ' '))) len--;
+	expression[len + 1] = 0;      
+	if (len >= 0) {
+	    if (expression[0] == '#')
+		continue;
+	    if ((expression[0] == '=') && (expression[1] == '>')) {
+		char *str = &expression[2];
+
+		if (expr != NULL) {
+		    xmlExpFree(ctxt, expr);
+		    if (xmlExpCtxtNbNodes(ctxt) != 0) 
+		        printf(" Parse/free of Expression leaked %d\n",
+			       xmlExpCtxtNbNodes(ctxt));
+		    expr = NULL;
+		}
+		printf("Expression: %s\n", str) ;
+		expr = xmlExpParse(ctxt, str);
+		if (expr == NULL) {
+		    printf("   parsing Failed\n");
+		    break;
+		}
+	    } else if (expr != NULL) {
+	        int expect = -1;
+		int nodes1, nodes2;
+
+		if (expression[0] == '0')
+		    expect = 0;
+		if (expression[0] == '1')
+		    expect = 1;
+		printf("Subexp: %s", expression + 2) ;
+		nodes1 = xmlExpCtxtNbNodes(ctxt);
+		sub = xmlExpParse(ctxt, expression + 2);
+		if (sub == NULL) {
+		    printf("   parsing Failed\n");
+		    break;
+		} else {
+		    int ret;
+		    
+		    nodes2 = xmlExpCtxtNbNodes(ctxt);
+		    ret = xmlExpSubsume(ctxt, expr, sub);
+
+		    if ((expect == 1) && (ret == 1)) {
+			printf(" => accept, Ok\n");
+		    } else if ((expect == 0) && (ret == 0)) {
+		        printf(" => reject, Ok\n");
+		    } else if ((expect == 1) && (ret == 0)) {
+			printf(" => reject, Failed\n");
+		    } else if ((expect == 0) && (ret == 1)) {
+			printf(" => accept, Failed\n");
+		    } else {
+		        printf(" => fail internally\n");
+		    }
+		    if (xmlExpCtxtNbNodes(ctxt) > nodes2) {
+		        printf(" Subsume leaked %d\n",
+			       xmlExpCtxtNbNodes(ctxt) - nodes2);
+			nodes1 += xmlExpCtxtNbNodes(ctxt) - nodes2;
+		    }
+		    xmlExpFree(ctxt, sub);
+		    if (xmlExpCtxtNbNodes(ctxt) > nodes1) {
+		        printf(" Parse/free leaked %d\n",
+			       xmlExpCtxtNbNodes(ctxt) - nodes1);
+		    }
+		}
+
+	    }
+	}
+    }
+    if (expr != NULL) {
+	xmlExpFree(ctxt, expr);
+	if (xmlExpCtxtNbNodes(ctxt) != 0) 
+	    printf(" Parse/free of Expression leaked %d\n",
+		   xmlExpCtxtNbNodes(ctxt));
+    }
+    fclose(input);
+}
+
+static void 
+testReduce(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr, const char *tst) {
+    xmlBufferPtr xmlExpBuf;
+    xmlExpNodePtr sub, deriv;
+    xmlExpBuf = xmlBufferCreate();
+
+    sub = xmlExpParse(ctxt, tst);
+    if (sub == NULL) {
+        printf("Subset %s failed to parse\n", tst);
+	return;
+    }
+    xmlExpDump(xmlExpBuf, sub);
+    printf("Subset parsed as: %s\n",
+           (const char *) xmlBufferContent(xmlExpBuf));
+    deriv = xmlExpExpDerive(ctxt, expr, sub);
+    if (deriv == NULL) {
+        printf("Derivation led to an internal error, report this !\n");
+	return;
+    } else {
+        xmlBufferEmpty(xmlExpBuf);
+	xmlExpDump(xmlExpBuf, deriv);
+	if (xmlExpIsNillable(deriv))
+	    printf("Resulting nillable derivation: %s\n",
+	           (const char *) xmlBufferContent(xmlExpBuf));
+	else
+	    printf("Resulting derivation: %s\n",
+	           (const char *) xmlBufferContent(xmlExpBuf));
+	xmlExpFree(ctxt, deriv);
+    }
+    xmlExpFree(ctxt, sub);
+}
+
+static void 
+exprDebug(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr) {
+    xmlBufferPtr xmlExpBuf;
+    xmlExpNodePtr deriv;
+    const char *list[40];
+    int ret;
+
+    xmlExpBuf = xmlBufferCreate();
+
+    if (expr == NULL) {
+        printf("Failed to parse\n");
+	return;
+    }
+    xmlExpDump(xmlExpBuf, expr);
+    printf("Parsed as: %s\n", (const char *) xmlBufferContent(xmlExpBuf));
+    printf("Max token input = %d\n", xmlExpMaxToken(expr));
+    if (xmlExpIsNillable(expr) == 1)
+	printf("Is nillable\n");
+    ret = xmlExpGetLanguage(ctxt, expr, (const xmlChar **) &list[0], 40);
+    if (ret < 0)
+	printf("Failed to get list: %d\n", ret);
+    else {
+	int i;
+
+	printf("Language has %d strings, testing string derivations\n", ret);
+	for (i = 0;i < ret;i++) {
+	    deriv = xmlExpStringDerive(ctxt, expr, BAD_CAST list[i], -1);
+	    if (deriv == NULL) {
+		printf("  %s -> derivation failed\n", list[i]);
+	    } else {
+		xmlBufferEmpty(xmlExpBuf);
+		xmlExpDump(xmlExpBuf, deriv);
+		printf("  %s -> %s\n", list[i],
+		       (const char *) xmlBufferContent(xmlExpBuf));
+	    }
+	    xmlExpFree(ctxt, deriv);
+	}
+    }
+    xmlBufferFree(xmlExpBuf);
+}
+#endif
+
+static void usage(const char *name) {
+    fprintf(stderr, "Usage: %s [flags]\n", name);
+    fprintf(stderr, "Testing tool for libxml2 string and pattern regexps\n");
+    fprintf(stderr, "   --debug: switch on debugging\n");
+    fprintf(stderr, "   --repeat: loop on the operation\n");
+#ifdef LIBXML_EXPR_ENABLED
+    fprintf(stderr, "   --expr: test xmlExp and not xmlRegexp\n");
+#endif
+    fprintf(stderr, "   --input filename: use the given filename for regexp\n");
+    fprintf(stderr, "   --input filename: use the given filename for exp\n");
+}
+
+int main(int argc, char **argv) {
+    xmlRegexpPtr comp = NULL;
+#ifdef LIBXML_EXPR_ENABLED
+    xmlExpNodePtr expr = NULL;
+    int use_exp = 0;
+    xmlExpCtxtPtr ctxt = NULL;
+#endif
+    const char *pattern = NULL;
+    char *filename = NULL;
+    int i;
+
+    xmlInitMemory();
+
+    if (argc <= 1) {
+	usage(argv[0]);
+	return(1);
+    }
+    for (i = 1; i < argc ; i++) {
+	if (!strcmp(argv[i], "-"))
+	    break;
+
+	if (argv[i][0] != '-')
+	    continue;
+	if (!strcmp(argv[i], "--"))
+	    break;
+
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
+	    debug++;
+	} else if ((!strcmp(argv[i], "-repeat")) ||
+	         (!strcmp(argv[i], "--repeat"))) {
+	    repeat++;
+#ifdef LIBXML_EXPR_ENABLED
+	} else if ((!strcmp(argv[i], "-expr")) ||
+	         (!strcmp(argv[i], "--expr"))) {
+	    use_exp++;
+#endif
+	} else if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "-f")) ||
+		   (!strcmp(argv[i], "--input")))
+	    filename = argv[++i];
+        else {
+	    fprintf(stderr, "Unknown option %s\n", argv[i]);
+	    usage(argv[0]);
+	}
+    }
+
+#ifdef LIBXML_EXPR_ENABLED
+    if (use_exp)
+	ctxt = xmlExpNewCtxt(0, NULL);
+#endif
+
+    if (filename != NULL) {
+#ifdef LIBXML_EXPR_ENABLED
+        if (use_exp)
+	    runFileTest(ctxt, filename);
+	else
+#endif
+	    testRegexpFile(filename);
+    } else {
+        int  data = 0;
+#ifdef LIBXML_EXPR_ENABLED
+
+        if (use_exp) {
+	    for (i = 1; i < argc ; i++) {
+	        if (strcmp(argv[i], "--") == 0)
+		    data = 1;
+		else if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0) ||
+		    (data == 1)) {
+		    if (pattern == NULL) {
+			pattern = argv[i];
+			printf("Testing expr %s:\n", pattern);
+			expr = xmlExpParse(ctxt, pattern);
+			if (expr == NULL) {
+			    printf("   failed to compile\n");
+			    break;
+			}
+			if (debug) {
+			    exprDebug(ctxt, expr);
+			}
+		    } else {
+			testReduce(ctxt, expr, argv[i]);
+		    }
+		}
+	    }
+	    if (expr != NULL) {
+		xmlExpFree(ctxt, expr);
+		expr = NULL;
+	    }
+	} else
+#endif
+        {
+	    for (i = 1; i < argc ; i++) {
+	        if (strcmp(argv[i], "--") == 0)
+		    data = 1;
+		else if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0) ||
+		         (data == 1)) {
+		    if (pattern == NULL) {
+			pattern = argv[i];
+			printf("Testing %s:\n", pattern);
+			comp = xmlRegexpCompile((const xmlChar *) pattern);
+			if (comp == NULL) {
+			    printf("   failed to compile\n");
+			    break;
+			}
+			if (debug)
+			    xmlRegexpPrint(stdout, comp);
+		    } else {
+			testRegexp(comp, argv[i]);
+		    }
+		}
+	    }
+	    if (comp != NULL)
+		xmlRegFreeRegexp(comp);
+        }
+    }
+#ifdef LIBXML_EXPR_ENABLED
+    if (ctxt != NULL) {
+	printf("Ops: %d nodes, %d cons\n",
+	       xmlExpCtxtNbNodes(ctxt), xmlExpCtxtNbCons(ctxt));
+	xmlExpFreeCtxt(ctxt);
+    }
+#endif
+    xmlCleanupParser();
+    xmlMemoryDump();
+    return(0);
+}
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : Regexp support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_REGEXP_ENABLED */
diff --git a/src/testRelax.c b/src/testRelax.c
new file mode 100644
index 0000000..e18b3c2
--- /dev/null
+++ b/src/testRelax.c
@@ -0,0 +1,194 @@
+/*
+ * testRelax.c : a small tester program for RelaxNG validation
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+#include "libxml.h"
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+/* seems needed for Solaris */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/relaxng.h>
+
+#ifdef LIBXML_DEBUG_ENABLED
+static int debug = 0;
+#endif
+static int noout = 0;
+static int tree = 0;
+#ifdef HAVE_SYS_MMAN_H
+static int memory = 0;
+#endif
+
+
+int main(int argc, char **argv) {
+    int i;
+    int files = 0;
+    xmlRelaxNGPtr schema = NULL;
+
+    for (i = 1; i < argc ; i++) {
+#ifdef LIBXML_DEBUG_ENABLED
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else
+#endif
+#ifdef HAVE_SYS_MMAN_H
+	if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) {
+	    memory++;
+        } else
+#endif
+	if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) {
+	    noout++;
+        } else
+	if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree"))) {
+	    tree++;
+        }
+    }
+    xmlLineNumbersDefault(1);
+    xmlSubstituteEntitiesDefault(1);
+    for (i = 1; i < argc ; i++) {
+	if (argv[i][0] != '-') {
+	    if (schema == NULL) {
+		xmlRelaxNGParserCtxtPtr ctxt;
+
+#ifdef HAVE_SYS_MMAN_H
+		if (memory) {
+		    int fd;
+		    struct stat info;
+		    const char *base;
+		    if (stat(argv[i], &info) < 0) 
+			break;
+		    if ((fd = open(argv[i], O_RDONLY)) < 0)
+			break;
+		    base = mmap(NULL, info.st_size, PROT_READ,
+			        MAP_SHARED, fd, 0) ;
+		    if (base == (void *) MAP_FAILED)
+			break;
+
+		    ctxt = xmlRelaxNGNewMemParserCtxt((char *)base,info.st_size);
+
+		    xmlRelaxNGSetParserErrors(ctxt,
+			    (xmlRelaxNGValidityErrorFunc) fprintf,
+			    (xmlRelaxNGValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlRelaxNGParse(ctxt);
+		    xmlRelaxNGFreeParserCtxt(ctxt);
+		    munmap((char *) base, info.st_size);
+		} else
+#endif
+		{
+		    ctxt = xmlRelaxNGNewParserCtxt(argv[i]);
+		    xmlRelaxNGSetParserErrors(ctxt,
+			    (xmlRelaxNGValidityErrorFunc) fprintf,
+			    (xmlRelaxNGValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlRelaxNGParse(ctxt);
+		    xmlRelaxNGFreeParserCtxt(ctxt);
+		}
+		if (schema == NULL) {
+		    printf("Relax-NG schema %s failed to compile\n", argv[i]);
+		    files = -1;
+		    break;
+		}
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+		if (debug)
+		    xmlRelaxNGDump(stdout, schema);
+#endif
+		if (tree)
+		    xmlRelaxNGDumpTree(stdout, schema);
+#endif /* LIBXML_OUTPUT_ENABLED */
+	    } else {
+		xmlDocPtr doc;
+
+		doc = xmlReadFile(argv[i],NULL,0);
+
+		if (doc == NULL) {
+		    fprintf(stderr, "Could not parse %s\n", argv[i]);
+		} else {
+		    xmlRelaxNGValidCtxtPtr ctxt;
+		    int ret;
+
+		    ctxt = xmlRelaxNGNewValidCtxt(schema);
+		    xmlRelaxNGSetValidErrors(ctxt,
+			    (xmlRelaxNGValidityErrorFunc) fprintf,
+			    (xmlRelaxNGValidityWarningFunc) fprintf,
+			    stderr);
+		    ret = xmlRelaxNGValidateDoc(ctxt, doc);
+		    if (ret == 0) {
+			printf("%s validates\n", argv[i]);
+		    } else if (ret > 0) {
+			printf("%s fails to validate\n", argv[i]);
+		    } else {
+			printf("%s validation generated an internal error\n",
+			       argv[i]);
+		    }
+		    xmlRelaxNGFreeValidCtxt(ctxt);
+		    xmlFreeDoc(doc);
+		}
+	    }
+	    files ++;
+	}
+    }
+    if (schema != NULL)
+	xmlRelaxNGFree(schema);
+    if (files == 0) {
+	printf("Usage : %s [--debug] [--noout] schemas XMLfiles ...\n",
+	       argv[0]);
+	printf("\tParse the HTML files and output the result of the parsing\n");
+#ifdef LIBXML_DEBUG_ENABLED
+	printf("\t--debug : dump a debug tree of the in-memory document\n");
+#endif
+	printf("\t--noout : do not print the result\n");
+	printf("\t--tree : print the intermediate Relax-NG document tree\n");
+#ifdef HAVE_SYS_MMAN_H
+	printf("\t--memory : test the schemas in memory parsing\n");
+#endif
+    }
+    xmlRelaxNGCleanupTypes();
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : RelaxNG support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/testSAX.c b/src/testSAX.c
new file mode 100644
index 0000000..cd16268
--- /dev/null
+++ b/src/testSAX.c
@@ -0,0 +1,1198 @@
+/*
+ * testSAX.c : a small tester program for parsing using the SAX API.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef LIBXML_SAX1_ENABLED
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+
+static int debug = 0;
+static int copy = 0;
+static int recovery = 0;
+static int push = 0;
+static int speed = 0;
+static int noent = 0;
+static int quiet = 0;
+static int nonull = 0;
+static int sax2 = 0;
+static int repeat = 0;
+static int callbacks = 0;
+static int timing = 0;
+
+/*
+ * Timing routines.
+ */
+/*
+ * Internal timing routines to remove the necessity to have unix-specific
+ * function calls
+ */
+
+#ifndef HAVE_GETTIMEOFDAY 
+#ifdef HAVE_SYS_TIMEB_H
+#ifdef HAVE_SYS_TIME_H
+#ifdef HAVE_FTIME
+
+static int
+my_gettimeofday(struct timeval *tvp, void *tzp)
+{
+	struct timeb timebuffer;
+
+	ftime(&timebuffer);
+	if (tvp) {
+		tvp->tv_sec = timebuffer.time;
+		tvp->tv_usec = timebuffer.millitm * 1000L;
+	}
+	return (0);
+}
+#define HAVE_GETTIMEOFDAY 1
+#define gettimeofday my_gettimeofday
+
+#endif /* HAVE_FTIME */
+#endif /* HAVE_SYS_TIME_H */
+#endif /* HAVE_SYS_TIMEB_H */
+#endif /* !HAVE_GETTIMEOFDAY */
+
+#if defined(HAVE_GETTIMEOFDAY)
+static struct timeval begin, end;
+
+/*
+ * startTimer: call where you want to start timing
+ */
+static void
+startTimer(void)
+{
+    gettimeofday(&begin, NULL);
+}
+
+/*
+ * endTimer: call where you want to stop timing and to print out a
+ *           message about the timing performed; format is a printf
+ *           type argument
+ */
+static void XMLCDECL
+endTimer(const char *fmt, ...)
+{
+    long msec;
+    va_list ap;
+
+    gettimeofday(&end, NULL);
+    msec = end.tv_sec - begin.tv_sec;
+    msec *= 1000;
+    msec += (end.tv_usec - begin.tv_usec) / 1000;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+
+    fprintf(stderr, " took %ld ms\n", msec);
+}
+#elif defined(HAVE_TIME_H)
+/*
+ * No gettimeofday function, so we have to make do with calling clock.
+ * This is obviously less accurate, but there's little we can do about
+ * that.
+ */
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 100
+#endif
+
+static clock_t begin, end;
+static void
+startTimer(void)
+{
+    begin = clock();
+}
+static void XMLCDECL
+endTimer(const char *fmt, ...)
+{
+    long msec;
+    va_list ap;
+
+    end = clock();
+    msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, " took %ld ms\n", msec);
+}
+#else
+
+/*
+ * We don't have a gettimeofday or time.h, so we just don't do timing
+ */
+static void
+startTimer(void)
+{
+    /*
+     * Do nothing
+     */
+}
+static void XMLCDECL
+endTimer(char *format, ...)
+{
+    /*
+     * We cannot do anything because we don't have a timing function
+     */
+#ifdef HAVE_STDARG_H
+    va_start(ap, format);
+    vfprintf(stderr, format, ap);
+    va_end(ap);
+    fprintf(stderr, " was not timed\n", msec);
+#else
+    /* We don't have gettimeofday, time or stdarg.h, what crazy world is
+     * this ?!
+     */
+#endif
+}
+#endif
+
+/*
+ * empty SAX block
+ */
+static xmlSAXHandler emptySAXHandlerStruct = {
+    NULL, /* internalSubset */
+    NULL, /* isStandalone */
+    NULL, /* hasInternalSubset */
+    NULL, /* hasExternalSubset */
+    NULL, /* resolveEntity */
+    NULL, /* getEntity */
+    NULL, /* entityDecl */
+    NULL, /* notationDecl */
+    NULL, /* attributeDecl */
+    NULL, /* elementDecl */
+    NULL, /* unparsedEntityDecl */
+    NULL, /* setDocumentLocator */
+    NULL, /* startDocument */
+    NULL, /* endDocument */
+    NULL, /* startElement */
+    NULL, /* endElement */
+    NULL, /* reference */
+    NULL, /* characters */
+    NULL, /* ignorableWhitespace */
+    NULL, /* processingInstruction */
+    NULL, /* comment */
+    NULL, /* xmlParserWarning */
+    NULL, /* xmlParserError */
+    NULL, /* xmlParserError */
+    NULL, /* getParameterEntity */
+    NULL, /* cdataBlock; */
+    NULL, /* externalSubset; */
+    1,
+    NULL,
+    NULL, /* startElementNs */
+    NULL, /* endElementNs */
+    NULL  /* xmlStructuredErrorFunc */
+};
+
+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
+extern xmlSAXHandlerPtr debugSAXHandler;
+
+/************************************************************************
+ *									*
+ *				Debug Handlers				*
+ *									*
+ ************************************************************************/
+
+/**
+ * isStandaloneDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(stdout, "SAX.isStandalone()\n");
+    return(0);
+}
+
+/**
+ * hasInternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(stdout, "SAX.hasInternalSubset()\n");
+    return(0);
+}
+
+/**
+ * hasExternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return(0);
+    fprintf(stdout, "SAX.hasExternalSubset()\n");
+    return(0);
+}
+
+/**
+ * internalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.internalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(stdout, " ,");
+    else
+	fprintf(stdout, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(stdout, " )\n");
+    else
+	fprintf(stdout, " %s)\n", SystemID);
+}
+
+/**
+ * externalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.externalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(stdout, " ,");
+    else
+	fprintf(stdout, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(stdout, " )\n");
+    else
+	fprintf(stdout, " %s)\n", SystemID);
+}
+
+/**
+ * resolveEntityDebug:
+ * @ctxt:  An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+
+    
+    fprintf(stdout, "SAX.resolveEntity(");
+    if (publicId != NULL)
+	fprintf(stdout, "%s", (char *)publicId);
+    else
+	fprintf(stdout, " ");
+    if (systemId != NULL)
+	fprintf(stdout, ", %s)\n", (char *)systemId);
+    else
+	fprintf(stdout, ", )\n");
+/*********
+    if (systemId != NULL) {
+        return(xmlNewInputFromFile(ctxt, (char *) systemId));
+    }
+ *********/
+    return(NULL);
+}
+
+/**
+ * getEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    fprintf(stdout, "SAX.getEntity(%s)\n", name);
+    return(NULL);
+}
+
+/**
+ * getParameterEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return(NULL);
+    fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
+    return(NULL);
+}
+
+
+/**
+ * entityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @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).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+    /* not all libraries handle printing null pointers nicely */
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (content == NULL)
+        content = (xmlChar *)nullstr;
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
+            name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the attribute name 
+ * @type:  the attribute type 
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
+                   const xmlChar * name, int type, int def,
+                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
+{
+    callbacks++;
+    if (quiet)
+        return;
+    if (defaultValue == NULL)
+        fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
+                elem, name, type, def);
+    else
+        fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
+                elem, name, type, def, defaultValue);
+    xmlFreeEnumeration(tree);
+}
+
+/**
+ * elementDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the element name 
+ * @type:  the element type 
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
+            name, type);
+}
+
+/**
+ * notationDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId);
+}
+
+/**
+ * unparsedEntityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (notationName == NULL)
+        notationName = nullstr;
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId,
+	    (char *) notationName);
+}
+
+/**
+ * setDocumentLocatorDebug:
+ * @ctxt:  An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.setDocumentLocator()\n");
+}
+
+/**
+ * startDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.startDocument()\n");
+}
+
+/**
+ * endDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.endDocument()\n");
+}
+
+/**
+ * startElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+	    fprintf(stdout, ", %s='", atts[i++]);
+	    if (atts[i] != NULL)
+	        fprintf(stdout, "%s'", atts[i]);
+	}
+    }
+    fprintf(stdout, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
+}
+
+/**
+ * charactersDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char output[40];
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	output[i] = ch[i];
+    output[i] = 0;
+
+    fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
+}
+
+/**
+ * referenceDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected. 
+ */
+static void
+referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.reference(%s)\n", name);
+}
+
+/**
+ * ignorableWhitespaceDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char output[40];
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	output[i] = ch[i];
+    output[i] = 0;
+    fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
+}
+
+/**
+ * processingInstructionDebug:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+                      const xmlChar *data)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    if (data != NULL)
+	fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
+		(char *) target, (char *) data);
+    else
+	fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
+		(char *) target);
+}
+
+/**
+ * cdataBlockDebug:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
+	    (char *) value, len);
+}
+
+/**
+ * commentDebug:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.comment(%s)\n", value);
+}
+
+/**
+ * warningDebug:
+ * @ctxt:  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.
+ */
+static void XMLCDECL
+warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.warning: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * errorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.error: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * fatalErrorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (quiet)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.fatalError: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+static xmlSAXHandler debugSAXHandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    startElementDebug,
+    endElementDebug,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    1,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
+
+/*
+ * SAX2 specific callbacks
+ */
+/**
+ * startElementNsDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                    const xmlChar *localname,
+                    const xmlChar *prefix,
+                    const xmlChar *URI,
+		    int nb_namespaces,
+		    const xmlChar **namespaces,
+		    int nb_attributes,
+		    int nb_defaulted,
+		    const xmlChar **attributes)
+{
+    int i;
+
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(stdout, ", NULL");
+    else
+	fprintf(stdout, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(stdout, ", NULL");
+    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");
+	    if (namespaces[i] != NULL)
+	        fprintf(stdout, ":%s", namespaces[i]);
+	    i++;
+	    fprintf(stdout, "='%s'", namespaces[i]);
+	}
+    }
+    fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
+    if (attributes != NULL) {
+        for (i = 0;i < nb_attributes * 5;i += 5) {
+	    if (attributes[i + 1] != NULL)
+		fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
+	    else
+		fprintf(stdout, ", %s='", attributes[i]);
+	    fprintf(stdout, "%.4s...', %d", attributes[i + 3],
+		    (int)(attributes[i + 4] - attributes[i + 3]));
+	}
+    }
+    fprintf(stdout, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                  const xmlChar *localname,
+                  const xmlChar *prefix,
+                  const xmlChar *URI)
+{
+    callbacks++;
+    if (quiet)
+	return;
+    fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(stdout, ", NULL");
+    else
+	fprintf(stdout, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(stdout, ", NULL)\n");
+    else
+	fprintf(stdout, ", '%s')\n", (char *) URI);
+}
+
+static xmlSAXHandler debugSAX2HandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    NULL,
+    NULL,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    XML_SAX2_MAGIC,
+    NULL,
+    startElementNsDebug,
+    endElementNsDebug,
+    NULL
+};
+
+static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
+
+/************************************************************************
+ *									*
+ *				Debug					*
+ *									*
+ ************************************************************************/
+
+static void
+parseAndPrintFile(char *filename) {
+    int res;
+
+#ifdef LIBXML_PUSH_ENABLED
+    if (push) {
+	FILE *f;
+
+        if ((!quiet) && (!nonull)) {
+	    /*
+	     * Empty callbacks for checking
+	     */
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+	    f = fopen(filename, "rb");
+#else
+	    f = fopen(filename, "r");
+#endif
+	    if (f != NULL) {
+		int ret;
+		char chars[10];
+		xmlParserCtxtPtr ctxt;
+
+		ret = fread(chars, 1, 4, f);
+		if (ret > 0) {
+		    ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
+				chars, ret, filename);
+		    while ((ret = fread(chars, 1, 3, f)) > 0) {
+			xmlParseChunk(ctxt, chars, ret, 0);
+		    }
+		    xmlParseChunk(ctxt, chars, 0, 1);
+		    xmlFreeParserCtxt(ctxt);
+		}
+		fclose(f);
+	    } else {
+		xmlGenericError(xmlGenericErrorContext,
+			"Cannot read file %s\n", filename);
+	    }
+	}
+	/*
+	 * Debug callback
+	 */
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+	f = fopen(filename, "rb");
+#else
+	f = fopen(filename, "r");
+#endif
+	if (f != NULL) {
+	    int ret;
+	    char chars[10];
+	    xmlParserCtxtPtr ctxt;
+
+	    ret = fread(chars, 1, 4, f);
+	    if (ret > 0) {
+	        if (sax2)
+		    ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
+				chars, ret, filename);
+		else
+		    ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
+				chars, ret, filename);
+		while ((ret = fread(chars, 1, 3, f)) > 0) {
+		    xmlParseChunk(ctxt, chars, ret, 0);
+		}
+		ret = xmlParseChunk(ctxt, chars, 0, 1);
+		xmlFreeParserCtxt(ctxt);
+		if (ret != 0) {
+		    fprintf(stdout,
+		            "xmlSAXUserParseFile returned error %d\n", ret);
+		}
+	    }
+	    fclose(f);
+	}
+    } else {
+#endif /* LIBXML_PUSH_ENABLED */
+	if (!speed) {
+	    /*
+	     * Empty callbacks for checking
+	     */
+	    if ((!quiet) && (!nonull)) {
+		res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
+		if (res != 0) {
+		    fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
+		}
+	    }
+
+	    /*
+	     * Debug callback
+	     */
+	    callbacks = 0;
+	    if (repeat) {
+	        int i;
+		for (i = 0;i < 99;i++) {
+		    if (sax2)
+			res = xmlSAXUserParseFile(debugSAX2Handler, NULL,
+			                          filename);
+		    else
+			res = xmlSAXUserParseFile(debugSAXHandler, NULL,
+			                          filename);
+		}
+	    }
+	    if (sax2)
+	        res = xmlSAXUserParseFile(debugSAX2Handler, NULL, filename);
+	    else
+		res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
+	    if (res != 0) {
+		fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
+	    }
+	    if (quiet)
+		fprintf(stdout, "%d callbacks generated\n", callbacks);
+	} else {
+	    /*
+	     * test 100x the SAX parse
+	     */
+	    int i;
+
+	    for (i = 0; i<100;i++)
+		res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
+	    if (res != 0) {
+		fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
+	    }
+	}
+#ifdef LIBXML_PUSH_ENABLED
+    }
+#endif
+}
+
+
+int main(int argc, char **argv) {
+    int i;
+    int files = 0;
+
+    LIBXML_TEST_VERSION	/* be safe, plus calls xmlInitParser */
+    
+    for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
+	    copy++;
+	else if ((!strcmp(argv[i], "-recover")) ||
+	         (!strcmp(argv[i], "--recover")))
+	    recovery++;
+	else if ((!strcmp(argv[i], "-push")) ||
+	         (!strcmp(argv[i], "--push")))
+#ifdef LIBXML_PUSH_ENABLED
+	    push++;
+#else
+	    fprintf(stderr,"'push' not enabled in library - ignoring\n");
+#endif /* LIBXML_PUSH_ENABLED */
+	else if ((!strcmp(argv[i], "-speed")) ||
+	         (!strcmp(argv[i], "--speed")))
+	    speed++;
+	else if ((!strcmp(argv[i], "-timing")) ||
+	         (!strcmp(argv[i], "--timing"))) {
+	    nonull++;
+	    timing++;
+	    quiet++;
+	} else if ((!strcmp(argv[i], "-repeat")) ||
+	         (!strcmp(argv[i], "--repeat"))) {
+	    repeat++;
+	    quiet++;
+	} else if ((!strcmp(argv[i], "-noent")) ||
+	         (!strcmp(argv[i], "--noent")))
+	    noent++;
+	else if ((!strcmp(argv[i], "-quiet")) ||
+	         (!strcmp(argv[i], "--quiet")))
+	    quiet++;
+	else if ((!strcmp(argv[i], "-sax2")) ||
+	         (!strcmp(argv[i], "--sax2")))
+	    sax2++;
+	else if ((!strcmp(argv[i], "-nonull")) ||
+	         (!strcmp(argv[i], "--nonull")))
+	    nonull++;
+    }
+    if (noent != 0) xmlSubstituteEntitiesDefault(1);
+    for (i = 1; i < argc ; i++) {
+	if (argv[i][0] != '-') {
+	    if (timing) {
+		startTimer();
+	    }
+	    parseAndPrintFile(argv[i]);
+	    if (timing) {
+		endTimer("Parsing");
+	    }
+	    files ++;
+	}
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+#else
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : SAX1 parsing support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_SAX1_ENABLED */
diff --git a/src/testSchemas.c b/src/testSchemas.c
new file mode 100644
index 0000000..47f8b39
--- /dev/null
+++ b/src/testSchemas.c
@@ -0,0 +1,185 @@
+/*
+ * testSchemas.c : a small tester program for Schema validation
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+#include "libxml.h"
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+/* seems needed for Solaris */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+
+#ifdef LIBXML_DEBUG_ENABLED
+static int debug = 0;
+#endif
+static int noout = 0;
+#ifdef HAVE_SYS_MMAN_H
+static int memory = 0;
+#endif
+
+
+int main(int argc, char **argv) {
+    int i;
+    int files = 0;
+    xmlSchemaPtr schema = NULL;
+
+    for (i = 1; i < argc ; i++) {
+#ifdef LIBXML_DEBUG_ENABLED
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else
+#endif
+#ifdef HAVE_SYS_MMAN_H
+	if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) {
+	    memory++;
+        } else
+#endif
+	if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) {
+	    noout++;
+        }
+    }
+    xmlLineNumbersDefault(1);
+    for (i = 1; i < argc ; i++) {
+	if (argv[i][0] != '-') {
+	    if (schema == NULL) {
+		xmlSchemaParserCtxtPtr ctxt;
+
+#ifdef HAVE_SYS_MMAN_H
+		if (memory) {
+		    int fd;
+		    struct stat info;
+		    const char *base;
+		    if (stat(argv[i], &info) < 0) 
+			break;
+		    if ((fd = open(argv[i], O_RDONLY)) < 0)
+			break;
+		    base = mmap(NULL, info.st_size, PROT_READ,
+			        MAP_SHARED, fd, 0) ;
+		    if (base == (void *) MAP_FAILED)
+			break;
+
+		    ctxt = xmlSchemaNewMemParserCtxt((char *)base,info.st_size);
+
+		    xmlSchemaSetParserErrors(ctxt,
+			    (xmlSchemaValidityErrorFunc) fprintf,
+			    (xmlSchemaValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlSchemaParse(ctxt);
+		    xmlSchemaFreeParserCtxt(ctxt);
+		    munmap((char *) base, info.st_size);
+		} else
+#endif
+		{
+		    ctxt = xmlSchemaNewParserCtxt(argv[i]);
+		    xmlSchemaSetParserErrors(ctxt,
+			    (xmlSchemaValidityErrorFunc) fprintf,
+			    (xmlSchemaValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlSchemaParse(ctxt);
+		    xmlSchemaFreeParserCtxt(ctxt);
+		}
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+		if (debug)
+		    xmlSchemaDump(stdout, schema);
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
+		if (schema == NULL)
+		    goto failed_schemas;
+	    } else {
+		xmlDocPtr doc;
+
+		doc = xmlReadFile(argv[i],NULL,0);
+
+		if (doc == NULL) {
+		    fprintf(stderr, "Could not parse %s\n", argv[i]);
+		} else {
+		    xmlSchemaValidCtxtPtr ctxt;
+		    int ret;
+
+		    ctxt = xmlSchemaNewValidCtxt(schema);
+		    xmlSchemaSetValidErrors(ctxt,
+			    (xmlSchemaValidityErrorFunc) fprintf,
+			    (xmlSchemaValidityWarningFunc) fprintf,
+			    stderr);
+		    ret = xmlSchemaValidateDoc(ctxt, doc);
+		    if (ret == 0) {
+			printf("%s validates\n", argv[i]);
+		    } else if (ret > 0) {
+			printf("%s fails to validate\n", argv[i]);
+		    } else {
+			printf("%s validation generated an internal error\n",
+			       argv[i]);
+		    }
+		    xmlSchemaFreeValidCtxt(ctxt);
+		    xmlFreeDoc(doc);
+		}
+	    }
+	    files ++;
+	}
+    }
+    if (schema != NULL)
+	xmlSchemaFree(schema);
+    if (files == 0) {
+	printf("Usage : %s [--debug] [--noout] schemas XMLfiles ...\n",
+	       argv[0]);
+	printf("\tParse the HTML files and output the result of the parsing\n");
+#ifdef LIBXML_DEBUG_ENABLED
+	printf("\t--debug : dump a debug tree of the in-memory document\n");
+#endif
+	printf("\t--noout : do not print the result\n");
+#ifdef HAVE_SYS_MMAN_H
+	printf("\t--memory : test the schemas in memory parsing\n");
+#endif
+    }
+failed_schemas:
+    xmlSchemaCleanupTypes();
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : Schemas support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/testThreads.c b/src/testThreads.c
new file mode 100644
index 0000000..b43cbd0
--- /dev/null
+++ b/src/testThreads.c
@@ -0,0 +1,202 @@
+#include "libxml.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_ENABLED)
+#include <libxml/globals.h>
+#include <libxml/threads.h>
+#include <libxml/parser.h>
+#include <libxml/catalog.h>
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#elif defined HAVE_BEOS_THREADS
+#include <OS.h>
+#endif
+#include <string.h>
+#if !defined(_MSC_VER)
+#include <unistd.h>
+#endif
+#include <assert.h>
+
+#define	MAX_ARGC	20
+#ifdef HAVE_PTHREAD_H
+static pthread_t tid[MAX_ARGC];
+#elif defined HAVE_BEOS_THREADS
+static thread_id tid[MAX_ARGC];
+#endif
+
+static const char *catalog = "test/threads/complex.xml";
+static const char *testfiles[] = {
+    "test/threads/abc.xml",
+    "test/threads/acb.xml",
+    "test/threads/bac.xml",
+    "test/threads/bca.xml",
+    "test/threads/cab.xml",
+    "test/threads/cba.xml",
+    "test/threads/invalid.xml",
+};
+
+static const char *Okay = "OK";
+static const char *Failed = "Failed";
+
+#ifndef xmlDoValidityCheckingDefaultValue
+#error xmlDoValidityCheckingDefaultValue is not a macro
+#endif
+#ifndef xmlGenericErrorContext
+#error xmlGenericErrorContext is not a macro
+#endif
+
+static void *
+thread_specific_data(void *private_data)
+{
+    xmlDocPtr myDoc;
+    const char *filename = (const char *) private_data;
+    int okay = 1;
+
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        xmlDoValidityCheckingDefaultValue = 0;
+        xmlGenericErrorContext = stdout;
+    } else {
+        xmlDoValidityCheckingDefaultValue = 1;
+        xmlGenericErrorContext = stderr;
+    }
+    myDoc = xmlParseFile(filename);
+    if (myDoc) {
+        xmlFreeDoc(myDoc);
+    } else {
+        printf("parse failed\n");
+	okay = 0;
+    }
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        if (xmlDoValidityCheckingDefaultValue != 0) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stdout) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    } else {
+        if (xmlDoValidityCheckingDefaultValue != 1) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stderr) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    }
+    if (okay == 0)
+	return((void *) Failed);
+    return ((void *) Okay);
+}
+
+#ifdef HAVE_PTHREAD_H
+int
+main(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    int ret;
+
+    xmlInitParser();
+    for (repeat = 0;repeat < 500;repeat++) {
+	xmlLoadCatalog(catalog);
+
+	for (i = 0; i < num_threads; i++) {
+	    results[i] = NULL;
+	    tid[i] = (pthread_t) -1;
+	}
+
+	for (i = 0; i < num_threads; i++) {
+	    ret = pthread_create(&tid[i], NULL, thread_specific_data,
+				 (void *) testfiles[i]);
+	    if (ret != 0) {
+		perror("pthread_create");
+		exit(1);
+	    }
+	}
+	for (i = 0; i < num_threads; i++) {
+	    ret = pthread_join(tid[i], &results[i]);
+	    if (ret != 0) {
+		perror("pthread_join");
+		exit(1);
+	    }
+	}
+
+	xmlCatalogCleanup();
+	for (i = 0; i < num_threads; i++)
+	    if (results[i] != (void *) Okay)
+		printf("Thread %d handling %s failed\n", i, testfiles[i]);
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+    return (0);
+}
+#elif defined HAVE_BEOS_THREADS
+int
+main(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    status_t ret;
+
+    xmlInitParser();
+    printf("Parser initialized\n");
+    for (repeat = 0;repeat < 500;repeat++) {
+    printf("repeat: %d\n",repeat);
+	xmlLoadCatalog(catalog);
+	printf("loaded catalog: %s\n", catalog);
+	for (i = 0; i < num_threads; i++) {
+	    results[i] = NULL;
+	    tid[i] = (thread_id) -1;
+	}
+	printf("cleaned threads\n");
+	for (i = 0; i < num_threads; i++) {
+		tid[i] = spawn_thread(thread_specific_data, "xmlTestThread", B_NORMAL_PRIORITY, (void *) testfiles[i]);
+		if (tid[i] < B_OK) {
+			perror("beos_thread_create");
+			exit(1);
+		}
+		printf("beos_thread_create %d -> %d\n", i, tid[i]);
+	}
+	for (i = 0; i < num_threads; i++) {
+	    ret = wait_for_thread(tid[i], &results[i]);
+	    printf("beos_thread_wait %d -> %d\n", i, ret);
+	    if (ret != B_OK) {
+			perror("beos_thread_wait");
+			exit(1);
+	    }
+	}
+
+	xmlCatalogCleanup();
+	ret = B_OK;
+	for (i = 0; i < num_threads; i++)
+	    if (results[i] != (void *) Okay) {
+			printf("Thread %d handling %s failed\n", i, testfiles[i]);
+			ret = B_ERROR;
+		}
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+	if (ret == B_OK)
+		printf("testThread : BeOS : SUCCESS!\n");
+	else
+		printf("testThread : BeOS : FAILED!\n");
+
+    return (0);
+}
+#endif /* pthreads or BeOS threads */
+
+#else /* !LIBXML_THREADS_ENABLED */
+int
+main(void)
+{
+    fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
+    return (0);
+}
+#endif
diff --git a/src/testThreadsWin32.c b/src/testThreadsWin32.c
new file mode 100644
index 0000000..6ed702e
--- /dev/null
+++ b/src/testThreadsWin32.c
@@ -0,0 +1,150 @@
+#include "libxml.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
+#include <libxml/globals.h>
+#include <libxml/threads.h>
+#include <libxml/parser.h>
+#include <libxml/catalog.h>
+#include <windows.h>
+#include <string.h>
+#include <assert.h>
+
+#define	MAX_ARGC	20
+#define TEST_REPEAT_COUNT 500
+
+static HANDLE tid[MAX_ARGC];
+
+static const char *catalog = "test/threads/complex.xml";
+static char *testfiles[] = {
+    "test/threads/abc.xml",
+    "test/threads/acb.xml",
+    "test/threads/bac.xml",
+    "test/threads/bca.xml",
+    "test/threads/cab.xml",
+    "test/threads/cba.xml",
+    "test/threads/invalid.xml",
+};
+
+const char *Okay = "OK";
+const char *Failed = "Failed";
+
+#ifndef xmlDoValidityCheckingDefaultValue
+#error xmlDoValidityCheckingDefaultValue is not a macro
+#endif
+#ifndef xmlGenericErrorContext
+#error xmlGenericErrorContext is not a macro
+#endif
+
+static DWORD WINAPI
+thread_specific_data(void *private_data)
+{
+    xmlDocPtr myDoc;
+    const char *filename = (const char *) private_data;
+    int okay = 1;
+
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        xmlDoValidityCheckingDefaultValue = 0;
+        xmlGenericErrorContext = stdout;
+    } else {
+        xmlDoValidityCheckingDefaultValue = 1;
+        xmlGenericErrorContext = stderr;
+    }
+    myDoc = xmlParseFile(filename);
+    if (myDoc) {
+        xmlFreeDoc(myDoc);
+    } else {
+        printf("parse failed\n");
+	okay = 0;
+    }
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        if (xmlDoValidityCheckingDefaultValue != 0) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stdout) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    } else {
+        if (xmlDoValidityCheckingDefaultValue != 1) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stderr) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    }
+    if (okay == 0)
+	return ((DWORD) Failed);
+    return ((DWORD) Okay);
+}
+
+int
+main()
+{
+	unsigned int i, repeat;
+	unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+	DWORD results[MAX_ARGC];
+	BOOL ret;
+
+	xmlInitParser();
+	for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++)
+	{
+		xmlLoadCatalog(catalog);
+
+		for (i = 0; i < num_threads; i++)
+		{
+			results[i] = 0;
+			tid[i] = (HANDLE) -1;
+		}
+
+		for (i = 0; i < num_threads; i++)
+		{
+			DWORD useless;
+			tid[i] = CreateThread(NULL, 0, 
+				thread_specific_data, testfiles[i], 0, &useless);
+			if (tid[i] == NULL)
+			{
+				perror("CreateThread");
+				exit(1);
+			}
+		}
+
+		if (WaitForMultipleObjects (num_threads, tid, TRUE, INFINITE) == WAIT_FAILED) 
+			perror ("WaitForMultipleObjects failed");
+
+		for (i = 0; i < num_threads; i++)
+		{
+			ret = GetExitCodeThread (tid[i], &results[i]);
+			if (ret == 0)
+			{
+				perror("GetExitCodeThread");
+				exit(1);
+			}
+			CloseHandle (tid[i]);
+		}
+
+		xmlCatalogCleanup();
+		for (i = 0; i < num_threads; i++) {
+		    if (results[i] != (DWORD) Okay) 
+			printf("Thread %d handling %s failed\n", i, testfiles[i]);
+		}
+	}
+
+	xmlCleanupParser();
+	xmlMemoryDump();
+
+	return (0);
+}
+
+#else /* !LIBXML_THREADS_ENABLED */
+int
+main()
+{
+    fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
+    return (0);
+}
+#endif
diff --git a/src/testURI.c b/src/testURI.c
new file mode 100644
index 0000000..d20989d
--- /dev/null
+++ b/src/testURI.c
@@ -0,0 +1,124 @@
+/*
+ * testURI.c : a small tester program for XML input.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/uri.h>
+#include <libxml/globals.h>
+
+static const char *base = NULL;
+static int escape = 0;
+static int debug = 0;
+
+static void handleURI(const char *str) {
+    int ret;
+    xmlURIPtr uri;
+    xmlChar *res = NULL, *parsed = NULL;
+
+    uri = xmlCreateURI();
+
+    if (base == NULL) {
+	ret = xmlParseURIReference(uri, str);
+	if (ret != 0)
+	    printf("%s : error %d\n", str, ret);
+	else {
+	    if (debug) {
+	        if (uri->scheme) printf("scheme: %s\n", uri->scheme);
+	        if (uri->opaque) printf("opaque: %s\n", uri->opaque);
+	        if (uri->authority) printf("authority: %s\n", uri->authority);
+	        if (uri->server) printf("server: %s\n", uri->server);
+	        if (uri->user) printf("user: %s\n", uri->user);
+	        if (uri->port != 0) printf("port: %d\n", uri->port);
+	        if (uri->path) printf("path: %s\n", uri->path);
+	        if (uri->query) printf("query: %s\n", uri->query);
+	        if (uri->fragment) printf("fragment: %s\n", uri->fragment);
+	        if (uri->query_raw) printf("query_raw: %s\n", uri->query_raw);
+	        if (uri->cleanup != 0) printf("cleanup\n");
+	    }
+	    xmlNormalizeURIPath(uri->path);
+	    if (escape != 0) {
+		parsed = xmlSaveUri(uri);
+		res = xmlURIEscape(parsed);
+		printf("%s\n", (char *) res);
+
+	    } else {
+		xmlPrintURI(stdout, uri);
+		printf("\n");
+	    }
+	}
+    } else {
+	res = xmlBuildURI((xmlChar *)str, (xmlChar *) base);
+	if (res != NULL) {
+	    printf("%s\n", (char *) res);
+	}
+	else
+	    printf("::ERROR::\n");
+    }
+    if (res != NULL)
+	xmlFree(res);
+    if (parsed != NULL)
+	xmlFree(parsed);
+    xmlFreeURI(uri);
+}
+
+int main(int argc, char **argv) {
+    int i, arg = 1;
+
+    if ((argc > arg) && (argv[arg] != NULL) &&
+	((!strcmp(argv[arg], "-base")) || (!strcmp(argv[arg], "--base")))) {
+	arg++;
+	base = argv[arg];
+	if (base != NULL)
+	    arg++;
+    }
+    if ((argc > arg) && (argv[arg] != NULL) &&
+	((!strcmp(argv[arg], "-escape")) || (!strcmp(argv[arg], "--escape")))) {
+	arg++;
+	escape++;
+    }
+    if ((argc > arg) && (argv[arg] != NULL) &&
+	((!strcmp(argv[arg], "-debug")) || (!strcmp(argv[arg], "--debug")))) {
+	arg++;
+	debug++;
+    }
+    if (argv[arg] == NULL) {
+	char str[1024];
+
+        while (1) {
+	    /*
+	     * read one line in string buffer.
+	     */
+	    if (fgets (&str[0], sizeof (str) - 1, stdin) == NULL)
+	       break;
+
+	    /*
+	     * remove the ending spaces
+	     */
+	    i = strlen(str);
+	    while ((i > 0) &&
+		   ((str[i - 1] == '\n') || (str[i - 1] == '\r') ||
+		    (str[i - 1] == ' ') || (str[i - 1] == '\t'))) {
+		i--;
+		str[i] = 0;
+	    }
+	    handleURI(str);
+        }
+    } else {
+	while (argv[arg] != NULL) {
+	    handleURI(argv[arg]);
+	    arg++;
+	}
+    }
+    xmlMemoryDump();
+    return(0);
+}
diff --git a/src/testXPath.c b/src/testXPath.c
new file mode 100644
index 0000000..677419a
--- /dev/null
+++ b/src/testXPath.c
@@ -0,0 +1,227 @@
+/*
+ * testXPath.c : a small tester program for XPath.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+
+#include <libxml/xpath.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+#if defined(LIBXML_XPTR_ENABLED)
+#include <libxml/xpointer.h>
+static int xptr = 0;
+#endif
+static int debug = 0;
+static int valid = 0;
+static int expr = 0;
+static int tree = 0;
+static int nocdata = 0;
+static xmlDocPtr document = NULL;
+
+/*
+ * Default document
+ */
+static xmlChar buffer[] = 
+"<?xml version=\"1.0\"?>\n\
+<EXAMPLE prop1=\"gnome is great\" prop2=\"&amp; linux too\">\n\
+  <head>\n\
+   <title>Welcome to Gnome</title>\n\
+  </head>\n\
+  <chapter>\n\
+   <title>The Linux adventure</title>\n\
+   <p>bla bla bla ...</p>\n\
+   <image href=\"linus.gif\"/>\n\
+   <p>...</p>\n\
+  </chapter>\n\
+  <chapter>\n\
+   <title>Chapter 2</title>\n\
+   <p>this is chapter 2 ...</p>\n\
+  </chapter>\n\
+  <chapter>\n\
+   <title>Chapter 3</title>\n\
+   <p>this is chapter 3 ...</p>\n\
+  </chapter>\n\
+</EXAMPLE>\n\
+";
+
+
+static void
+testXPath(const char *str) {
+    xmlXPathObjectPtr res;
+    xmlXPathContextPtr ctxt;
+    
+#if defined(LIBXML_XPTR_ENABLED)
+    if (xptr) {
+	ctxt = xmlXPtrNewContext(document, NULL, NULL);
+	res = xmlXPtrEval(BAD_CAST str, ctxt);
+    } else {
+#endif
+	ctxt = xmlXPathNewContext(document);
+	ctxt->node = xmlDocGetRootElement(document);
+	if (expr)
+	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
+	else {
+	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */
+	    xmlXPathCompExprPtr comp;
+
+	    comp = xmlXPathCompile(BAD_CAST str);
+	    if (comp != NULL) {
+		if (tree) 
+		    xmlXPathDebugDumpCompExpr(stdout, comp, 0);
+
+		res = xmlXPathCompiledEval(comp, ctxt);
+		xmlXPathFreeCompExpr(comp);
+	    } else
+		res = NULL;
+	}
+#if defined(LIBXML_XPTR_ENABLED)
+    }
+#endif
+    xmlXPathDebugDumpObject(stdout, res, 0);
+    xmlXPathFreeObject(res);
+    xmlXPathFreeContext(ctxt);
+}
+
+static void
+testXPathFile(const char *filename) {
+    FILE *input;
+    char expression[5000];
+    int len;
+
+    input = fopen(filename, "r");
+    if (input == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"Cannot open %s for reading\n", filename);
+	return;
+    }
+    while (fgets(expression, 4500, input) != NULL) {
+	len = strlen(expression);
+	len--;
+	while ((len >= 0) && 
+	       ((expression[len] == '\n') || (expression[len] == '\t') ||
+		(expression[len] == '\r') || (expression[len] == ' '))) len--;
+	expression[len + 1] = 0;      
+	if (len >= 0) {
+	    printf("\n========================\nExpression: %s\n", expression) ;
+	    testXPath(expression);
+	}
+    }
+
+    fclose(input);
+}
+
+int main(int argc, char **argv) {
+    int i;
+    int strings = 0;
+    int usefile = 0;
+    char *filename = NULL;
+
+    for (i = 1; i < argc ; i++) {
+#if defined(LIBXML_XPTR_ENABLED)
+	if ((!strcmp(argv[i], "-xptr")) || (!strcmp(argv[i], "--xptr")))
+	    xptr++;
+	else 
+#endif
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
+	    valid++;
+	else if ((!strcmp(argv[i], "-expr")) || (!strcmp(argv[i], "--expr")))
+	    expr++;
+	else if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree")))
+	    tree++;
+	else if ((!strcmp(argv[i], "-nocdata")) ||
+		 (!strcmp(argv[i], "--nocdata")))
+	    nocdata++;
+	else if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input")))
+	    filename = argv[++i];
+	else if ((!strcmp(argv[i], "-f")) || (!strcmp(argv[i], "--file")))
+	    usefile++;
+    }
+    if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
+    xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
+    xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefaultValue = 1;
+    if (nocdata != 0) {
+	xmlDefaultSAXHandlerInit();
+	xmlDefaultSAXHandler.cdataBlock = NULL;
+    }
+    if (document == NULL) {
+        if (filename == NULL)
+	    document = xmlReadDoc(buffer,NULL,NULL,XML_PARSE_COMPACT);
+	else
+	    document = xmlReadFile(filename,NULL,XML_PARSE_COMPACT);
+    }
+    for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input"))) {
+	    i++; continue;
+	}
+	if (argv[i][0] != '-') {
+	    if (usefile)
+	        testXPathFile(argv[i]);
+	    else
+		testXPath(argv[i]);
+	    strings ++;
+	}
+    }
+    if (strings == 0) {
+	printf("Usage : %s [--debug] [--copy] stringsorfiles ...\n",
+	       argv[0]);
+	printf("\tParse the XPath strings and output the result of the parsing\n");
+	printf("\t--debug : dump a debug version of the result\n");
+	printf("\t--valid : switch on DTD support in the parser\n");
+#if defined(LIBXML_XPTR_ENABLED)
+	printf("\t--xptr : expressions are XPointer expressions\n");
+#endif
+	printf("\t--expr : debug XPath expressions only\n");
+	printf("\t--tree : show the compiled XPath tree\n");
+	printf("\t--nocdata : do not generate CDATA nodes\n");
+	printf("\t--input filename : or\n");
+	printf("\t-i filename      : read the document from filename\n");
+	printf("\t--file : or\n");
+	printf("\t-f     : read queries from files, args\n");
+    }
+    if (document != NULL) 
+	xmlFreeDoc(document);
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(0);
+}
+#else
+#include <stdio.h>
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    printf("%s : XPath/Debug support not compiled in\n", argv[0]);
+    return(0);
+}
+#endif /* LIBXML_XPATH_ENABLED */
diff --git a/src/testapi.c b/src/testapi.c
new file mode 100644
index 0000000..d046cbc
--- /dev/null
+++ b/src/testapi.c
@@ -0,0 +1,51691 @@
+/*
+ * testapi.c: libxml2 API tester program.
+ *
+ * Automatically generated by gentest.py from libxml2-api.xml
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "libxml.h"
+#else
+#include <stdio.h>
+#endif
+
+#include <stdlib.h> /* for putenv() */
+#include <string.h>
+#include <libxml/xmlerror.h>
+#include <libxml/relaxng.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define snprintf _snprintf
+#endif
+
+static int testlibxml2(void);
+static int test_module(const char *module);
+
+static int generic_errors = 0;
+static int call_tests = 0;
+static int function_tests = 0;
+
+static xmlChar chartab[1024];
+static int inttab[1024];
+static unsigned long longtab[1024];
+
+static xmlDocPtr api_doc = NULL;
+static xmlDtdPtr api_dtd = NULL;
+static xmlNodePtr api_root = NULL;
+static xmlAttrPtr api_attr = NULL;
+static xmlNsPtr api_ns = NULL;
+
+static void
+structured_errors(void *userData ATTRIBUTE_UNUSED,
+                  xmlErrorPtr error ATTRIBUTE_UNUSED) {
+    generic_errors++;
+}
+
+static void
+free_api_doc(void) {
+    xmlFreeDoc(api_doc);
+    api_doc = NULL;
+    api_dtd = NULL;
+    api_root = NULL;
+    api_attr = NULL;
+    api_ns = NULL;
+}
+
+static xmlDocPtr
+get_api_doc(void) {
+    if (api_doc == NULL) {
+        api_doc = xmlReadMemory("<!DOCTYPE root [<!ELEMENT root EMPTY>]><root xmlns:h='http://example.com/' h:foo='bar'/>", 88, "root_test", NULL, 0);
+	api_root = NULL;
+	api_attr = NULL;
+    }
+    return(api_doc);
+}
+
+static xmlDtdPtr
+get_api_dtd(void) {
+    if ((api_dtd == NULL) || (api_dtd->type != XML_DTD_NODE)) {
+        get_api_doc();
+	if ((api_doc != NULL) && (api_doc->children != NULL) &&
+	    (api_doc->children->type == XML_DTD_NODE))
+	    api_dtd = (xmlDtdPtr) api_doc->children;
+    }
+    return(api_dtd);
+}
+
+static xmlNodePtr
+get_api_root(void) {
+    if ((api_root == NULL) || (api_root->type != XML_ELEMENT_NODE)) {
+        get_api_doc();
+	if ((api_doc != NULL) && (api_doc->children != NULL) &&
+	    (api_doc->children->next != NULL) &&
+	    (api_doc->children->next->type == XML_ELEMENT_NODE))
+	    api_root = api_doc->children->next;
+    }
+    return(api_root);
+}
+
+static xmlNsPtr
+get_api_ns(void) {
+    get_api_root();
+    if (api_root != NULL)
+        api_ns = api_root->nsDef;
+    return(api_ns);
+}
+
+static xmlAttrPtr
+get_api_attr(void) {
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+    static int nr = 0;
+    xmlChar name[20];
+#endif
+
+    if ((api_root == NULL) || (api_root->type != XML_ELEMENT_NODE)) {
+        get_api_root();
+    }
+    if (api_root == NULL) 
+        return(NULL);
+    if (api_root->properties != NULL) {
+        api_attr = api_root->properties;
+        return(api_root->properties);
+    }
+    api_attr = NULL;
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+    snprintf((char *) name, 20, "foo%d", nr++);
+    api_attr = xmlSetProp(api_root, name, (const xmlChar *) "bar");
+#endif
+    return(api_attr);
+}
+
+static int quiet = 0;
+
+int main(int argc, char **argv) {
+    int ret;
+    int blocks, mem;
+
+    /* access to the proxy can slow up regression tests a lot */
+    putenv((char *) "http_proxy=");
+
+    memset(chartab, 0, sizeof(chartab));
+    strncpy((char *) chartab, "  chartab\n", 20);
+    memset(inttab, 0, sizeof(inttab));
+    memset(longtab, 0, sizeof(longtab));
+
+    xmlInitParser();
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlRelaxNGInitTypes();
+#endif
+
+    LIBXML_TEST_VERSION
+
+    xmlSetStructuredErrorFunc(NULL, structured_errors);
+
+    if (argc >= 2) {
+        if (!strcmp(argv[1], "-q")) {
+	    quiet = 1;
+	    if (argc >= 3)
+	        ret = test_module(argv[2]);
+	    else
+		ret = testlibxml2();
+        } else {
+	   ret = test_module(argv[1]);
+	}
+    } else
+	ret = testlibxml2();
+
+    xmlCleanupParser();
+    blocks = xmlMemBlocks();
+    mem = xmlMemUsed();
+    if ((blocks != 0) || (mem != 0)) {
+        printf("testapi leaked %d bytes in %d blocks\n", mem, blocks);
+    }
+    xmlMemoryDump();
+
+    return (ret != 0);
+}
+
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/catalog.h>
+#include <libxml/chvalid.h>
+#include <libxml/dict.h>
+#include <libxml/encoding.h>
+#include <libxml/entities.h>
+#include <libxml/hash.h>
+#include <libxml/list.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/pattern.h>
+#include <libxml/relaxng.h>
+#include <libxml/schemasInternals.h>
+#include <libxml/schematron.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#include <libxml/valid.h>
+#include <libxml/xinclude.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlsave.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xpath.h>
+#include <libxml/xpointer.h>
+#include <libxml/debugXML.h>
+
+/* 
+  We manually define xmlErrMemory because it's normal declaration
+  is "hidden" by #ifdef IN_LIBXML
+*/
+void xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra);
+
+/*
+ We need some "remote" addresses, but want to avoid getting into
+ name resolution delays, so we use these
+*/
+#define	REMOTE1GOOD	"http://localhost/"
+#define	REMOTE1BAD	"http:http://http"
+#define	REMOTE2GOOD	"ftp://localhost/foo"
+
+#define gen_nb_void_ptr 2
+
+static void *gen_void_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_void_ptr(int no ATTRIBUTE_UNUSED, void *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#if 0
+#define gen_nb_const_void_ptr 2
+
+static const void *gen_const_void_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return((const void *) "immutable string");
+    return(NULL);
+}
+static void des_const_void_ptr(int no ATTRIBUTE_UNUSED, const void *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#define gen_nb_userdata 3
+
+static void *gen_userdata(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return((void *) &call_tests);
+    if (no == 1) return((void *) -1);
+    return(NULL);
+}
+static void des_userdata(int no ATTRIBUTE_UNUSED, void *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+
+#define gen_nb_int 4
+
+static int gen_int(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(0);
+    if (no == 1) return(1);
+    if (no == 2) return(-1);
+    if (no == 3) return(122);
+    return(-1);
+}
+
+static void des_int(int no ATTRIBUTE_UNUSED, int val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_parseroptions 5
+
+static int gen_parseroptions(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(XML_PARSE_NOBLANKS | XML_PARSE_RECOVER);
+    if (no == 1) return(XML_PARSE_NOENT | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_DTDVALID | XML_PARSE_NOCDATA);
+    if (no == 2) return(XML_PARSE_XINCLUDE | XML_PARSE_NOXINCNODE | XML_PARSE_NSCLEAN);
+    if (no == 3) return(XML_PARSE_XINCLUDE | XML_PARSE_NODICT);
+    return(XML_PARSE_SAX1);
+}
+
+static void des_parseroptions(int no ATTRIBUTE_UNUSED, int val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#if 0
+#define gen_nb_long 5
+
+static long gen_long(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(0);
+    if (no == 1) return(1);
+    if (no == 2) return(-1);
+    if (no == 3) return(122);
+    return(-1);
+}
+
+static void des_long(int no ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#define gen_nb_xmlChar 4
+
+static xmlChar gen_xmlChar(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return('a');
+    if (no == 1) return(' ');
+    if (no == 2) return((xmlChar) 'ø');
+    return(0);
+}
+
+static void des_xmlChar(int no ATTRIBUTE_UNUSED, xmlChar val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_unsigned_int 3
+
+static unsigned int gen_unsigned_int(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(0);
+    if (no == 1) return(1);
+    if (no == 2) return(122);
+    return((unsigned int) -1);
+}
+
+static void des_unsigned_int(int no ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_unsigned_long 4
+
+static unsigned long gen_unsigned_long(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(0);
+    if (no == 1) return(1);
+    if (no == 2) return(122);
+    return((unsigned long) -1);
+}
+
+static void des_unsigned_long(int no ATTRIBUTE_UNUSED, unsigned long val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_double 4
+
+static double gen_double(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(0);
+    if (no == 1) return(-1.1);
+#if defined(LIBXML_XPATH_ENABLED)
+    if (no == 2) return(xmlXPathNAN);
+#endif
+    return(-1);
+}
+
+static void des_double(int no ATTRIBUTE_UNUSED, double val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_unsigned_long_ptr 2
+
+static unsigned long *gen_unsigned_long_ptr(int no, int nr) {
+    if (no == 0) return(&longtab[nr]);
+    return(NULL);
+}
+
+static void des_unsigned_long_ptr(int no ATTRIBUTE_UNUSED, unsigned long *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_int_ptr 2
+
+static int *gen_int_ptr(int no, int nr) {
+    if (no == 0) return(&inttab[nr]);
+    return(NULL);
+}
+
+static void des_int_ptr(int no ATTRIBUTE_UNUSED, int *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_const_char_ptr 4
+
+static char *gen_const_char_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return((char *) "foo");
+    if (no == 1) return((char *) "<foo/>");
+    if (no == 2) return((char *) "test/ent2");
+    return(NULL);
+}
+static void des_const_char_ptr(int no ATTRIBUTE_UNUSED, const char *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlChar_ptr 2
+
+static xmlChar *gen_xmlChar_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(&chartab[0]);
+    return(NULL);
+}
+static void des_xmlChar_ptr(int no ATTRIBUTE_UNUSED, xmlChar *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_FILE_ptr 2
+
+static FILE *gen_FILE_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(fopen("test.out", "a+"));
+    return(NULL);
+}
+static void des_FILE_ptr(int no ATTRIBUTE_UNUSED, FILE *val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) fclose(val);
+}
+
+#define gen_nb_debug_FILE_ptr 2
+static FILE *gen_debug_FILE_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(fopen("test.out", "a+"));
+}
+static void des_debug_FILE_ptr(int no ATTRIBUTE_UNUSED, FILE *val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) fclose(val);
+}
+
+#define gen_nb_const_xmlChar_ptr 5
+
+static xmlChar *gen_const_xmlChar_ptr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return((xmlChar *) "foo");
+    if (no == 1) return((xmlChar *) "<foo/>");
+    if (no == 2) return((xmlChar *) "nøne");
+    if (no == 3) return((xmlChar *) " 2ab ");
+    return(NULL);
+}
+static void des_const_xmlChar_ptr(int no ATTRIBUTE_UNUSED, const xmlChar *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_filepath 8
+
+static const char *gen_filepath(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return("missing.xml");
+    if (no == 1) return("<foo/>");
+    if (no == 2) return("test/ent2");
+    if (no == 3) return("test/valid/REC-xml-19980210.xml");
+    if (no == 4) return("test/valid/dtds/xhtml1-strict.dtd");
+    if (no == 5) return(REMOTE1GOOD);
+    if (no == 6) return(REMOTE1BAD);
+    return(NULL);
+}
+static void des_filepath(int no ATTRIBUTE_UNUSED, const char *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_eaten_name 2
+
+static xmlChar *gen_eaten_name(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlStrdup(BAD_CAST "eaten"));
+    return(NULL);
+}
+static void des_eaten_name(int no ATTRIBUTE_UNUSED, xmlChar *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_fileoutput 6
+
+static const char *gen_fileoutput(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return("/missing.xml");
+    if (no == 1) return("<foo/>");
+    if (no == 2) return(REMOTE2GOOD);
+    if (no == 3) return(REMOTE1GOOD);
+    if (no == 4) return(REMOTE1BAD);
+    return(NULL);
+}
+static void des_fileoutput(int no ATTRIBUTE_UNUSED, const char *val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlParserCtxtPtr 3
+static xmlParserCtxtPtr gen_xmlParserCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewParserCtxt());
+    if (no == 1) return(xmlCreateMemoryParserCtxt("<doc/>", 6));
+    return(NULL);
+}
+static void des_xmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, xmlParserCtxtPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL)
+        xmlFreeParserCtxt(val);
+}
+
+#define gen_nb_xmlSAXHandlerPtr 2
+static xmlSAXHandlerPtr gen_xmlSAXHandlerPtr(int no, int nr ATTRIBUTE_UNUSED) {
+#ifdef LIBXML_SAX1_ENABLED
+    if (no == 0) return((xmlSAXHandlerPtr) &xmlDefaultSAXHandler);
+#endif
+    return(NULL);
+}
+static void des_xmlSAXHandlerPtr(int no ATTRIBUTE_UNUSED, xmlSAXHandlerPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlValidCtxtPtr 2
+static xmlValidCtxtPtr gen_xmlValidCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) {
+#ifdef LIBXML_VALID_ENABLED
+    if (no == 0) return(xmlNewValidCtxt());
+#endif
+    return(NULL);
+}
+static void des_xmlValidCtxtPtr(int no ATTRIBUTE_UNUSED, xmlValidCtxtPtr val, int nr ATTRIBUTE_UNUSED) {
+#ifdef LIBXML_VALID_ENABLED
+    if (val != NULL)
+        xmlFreeValidCtxt(val);
+#endif
+}
+
+#define gen_nb_xmlParserInputBufferPtr 8
+
+static xmlParserInputBufferPtr gen_xmlParserInputBufferPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlParserInputBufferCreateFilename("missing.xml", XML_CHAR_ENCODING_NONE));
+    if (no == 1) return(xmlParserInputBufferCreateFilename("<foo/>", XML_CHAR_ENCODING_NONE));
+    if (no == 2) return(xmlParserInputBufferCreateFilename("test/ent2", XML_CHAR_ENCODING_NONE));
+    if (no == 3) return(xmlParserInputBufferCreateFilename("test/valid/REC-xml-19980210.xml", XML_CHAR_ENCODING_NONE));
+    if (no == 4) return(xmlParserInputBufferCreateFilename("test/valid/dtds/xhtml1-strict.dtd", XML_CHAR_ENCODING_NONE));
+    if (no == 5) return(xmlParserInputBufferCreateFilename(REMOTE1GOOD, XML_CHAR_ENCODING_NONE));
+    if (no == 6) return(xmlParserInputBufferCreateFilename(REMOTE1BAD, XML_CHAR_ENCODING_NONE));
+    return(NULL);
+}
+static void des_xmlParserInputBufferPtr(int no ATTRIBUTE_UNUSED, xmlParserInputBufferPtr val, int nr ATTRIBUTE_UNUSED) {
+    xmlFreeParserInputBuffer(val);
+}
+
+#define gen_nb_xmlDocPtr 4
+static xmlDocPtr gen_xmlDocPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewDoc(BAD_CAST "1.0"));
+    if (no == 1) return(xmlReadMemory("<foo/>", 6, "test", NULL, 0));
+    if (no == 2) return(xmlReadMemory("<!DOCTYPE foo []> <foo/>", 24, "test", NULL, 0));
+    return(NULL);
+}
+static void des_xmlDocPtr(int no ATTRIBUTE_UNUSED, xmlDocPtr val, int nr ATTRIBUTE_UNUSED) {
+    if ((val != NULL) && (val != api_doc) && (val->doc != api_doc))
+        xmlFreeDoc(val);
+}
+
+#define gen_nb_xmlAttrPtr 2
+static xmlAttrPtr gen_xmlAttrPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(get_api_attr());
+    return(NULL);
+}
+static void des_xmlAttrPtr(int no, xmlAttrPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) free_api_doc();
+}
+
+#define gen_nb_xmlDictPtr 2
+static xmlDictPtr gen_xmlDictPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlDictCreate());
+    return(NULL);
+}
+static void des_xmlDictPtr(int no ATTRIBUTE_UNUSED, xmlDictPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL)
+        xmlDictFree(val);
+}
+
+#define gen_nb_xmlNodePtr 3
+static xmlNodePtr gen_xmlNodePtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewPI(BAD_CAST "test", NULL));
+    if (no == 1) return(get_api_root());
+    return(NULL);
+/*     if (no == 2) return((xmlNodePtr) get_api_doc()); */
+}
+static void des_xmlNodePtr(int no, xmlNodePtr val, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) {
+        free_api_doc();
+    } else if (val != NULL) {
+        xmlUnlinkNode(val);
+        xmlFreeNode(val);
+    }
+}
+
+#define gen_nb_xmlDtdPtr 3
+static xmlDtdPtr gen_xmlDtdPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) 
+        return(xmlNewDtd(NULL, BAD_CAST "dtd", BAD_CAST"foo", BAD_CAST"bar"));
+    if (no == 1) return(get_api_dtd());
+    return(NULL);
+}
+static void des_xmlDtdPtr(int no, xmlDtdPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) free_api_doc();
+    else if (val != NULL) {
+        xmlUnlinkNode((xmlNodePtr) val);
+        xmlFreeNode((xmlNodePtr) val);
+    }
+}
+
+#define gen_nb_xmlNsPtr 2
+static xmlNsPtr gen_xmlNsPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(get_api_ns());
+    return(NULL);
+}
+static void des_xmlNsPtr(int no, xmlNsPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) free_api_doc();
+}
+
+#define gen_nb_xmlNodePtr_in 3
+static xmlNodePtr gen_xmlNodePtr_in(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewPI(BAD_CAST "test", NULL));
+    if (no == 0) return(xmlNewText(BAD_CAST "text"));
+    return(NULL);
+}
+static void des_xmlNodePtr_in(int no ATTRIBUTE_UNUSED, xmlNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#ifdef LIBXML_WRITER_ENABLED
+#define gen_nb_xmlTextWriterPtr 2
+static xmlTextWriterPtr gen_xmlTextWriterPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewTextWriterFilename("test.out", 0));
+    return(NULL);
+}
+static void des_xmlTextWriterPtr(int no ATTRIBUTE_UNUSED, xmlTextWriterPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) xmlFreeTextWriter(val);
+}
+#endif
+
+#ifdef LIBXML_READER_ENABLED
+#define gen_nb_xmlTextReaderPtr 4
+static xmlTextReaderPtr gen_xmlTextReaderPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewTextReaderFilename("test/ent2"));
+    if (no == 1) return(xmlNewTextReaderFilename("test/valid/REC-xml-19980210.xml"));
+    if (no == 2) return(xmlNewTextReaderFilename("test/valid/dtds/xhtml1-strict.dtd"));
+    return(NULL);
+}
+static void des_xmlTextReaderPtr(int no ATTRIBUTE_UNUSED, xmlTextReaderPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) xmlFreeTextReader(val);
+}
+#endif
+
+#define gen_nb_xmlBufferPtr 3
+static const char *static_buf_content = "a static buffer";
+static xmlBufferPtr gen_xmlBufferPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlBufferCreate());
+    if (no == 1) return(xmlBufferCreateStatic((void *)static_buf_content, 13));
+    return(NULL);
+}
+static void des_xmlBufferPtr(int no ATTRIBUTE_UNUSED, xmlBufferPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlBufferFree(val);
+    }
+}
+
+#define gen_nb_xmlListPtr 2
+static xmlListPtr gen_xmlListPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlListCreate(NULL, NULL));
+    return(NULL);
+}
+static void des_xmlListPtr(int no ATTRIBUTE_UNUSED, xmlListPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlListDelete(val);
+    }
+}
+
+#define gen_nb_xmlHashTablePtr 2
+static xmlHashTablePtr gen_xmlHashTablePtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlHashCreate(10));
+    return(NULL);
+}
+static void des_xmlHashTablePtr(int no ATTRIBUTE_UNUSED, xmlHashTablePtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlHashFree(val, NULL);
+    }
+}
+
+#include <libxml/xpathInternals.h>
+
+#ifdef LIBXML_XPATH_ENABLED
+#define gen_nb_xmlXPathObjectPtr 5
+static xmlXPathObjectPtr gen_xmlXPathObjectPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlXPathNewString(BAD_CAST "string object"));
+    if (no == 1) return(xmlXPathNewFloat(1.1));
+    if (no == 2) return(xmlXPathNewBoolean(1));
+    if (no == 3) return(xmlXPathNewNodeSet(NULL));
+    return(NULL);
+}
+static void des_xmlXPathObjectPtr(int no ATTRIBUTE_UNUSED, xmlXPathObjectPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlXPathFreeObject(val);
+    }
+}
+#endif
+
+#ifdef LIBXML_OUTPUT_ENABLED
+#define gen_nb_xmlOutputBufferPtr 2
+static xmlOutputBufferPtr gen_xmlOutputBufferPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlOutputBufferCreateFilename("test.out", NULL, 0));
+    return(NULL);
+}
+static void des_xmlOutputBufferPtr(int no ATTRIBUTE_UNUSED, xmlOutputBufferPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlOutputBufferClose(val);
+    }
+}
+#endif
+
+#ifdef LIBXML_FTP_ENABLED
+#define gen_nb_xmlNanoFTPCtxtPtr 4
+static void *gen_xmlNanoFTPCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNanoFTPNewCtxt(REMOTE2GOOD));
+    if (no == 1) return(xmlNanoFTPNewCtxt(REMOTE1GOOD));
+    if (no == 2) return(xmlNanoFTPNewCtxt("foo"));
+    return(NULL);
+}
+static void des_xmlNanoFTPCtxtPtr(int no ATTRIBUTE_UNUSED, void *val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+        xmlNanoFTPFreeCtxt(val);
+    }
+}
+#endif
+
+#ifdef LIBXML_HTTP_ENABLED
+#define gen_nb_xmlNanoHTTPCtxtPtr 1
+static void *gen_xmlNanoHTTPCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNanoHTTPOpen(REMOTE1GOOD, NULL));
+    if (no == 1) return(xmlNanoHTTPOpen(REMOTE2GOOD, NULL));
+    if (no == 2) return(xmlNanoHTTPOpen(REMOTE1BAD, NULL));
+    return(NULL);
+}
+static void des_xmlNanoHTTPCtxtPtr(int no ATTRIBUTE_UNUSED, void *val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL) {
+	xmlNanoHTTPClose(val);
+    }
+}
+#endif
+
+#define gen_nb_xmlCharEncoding 4
+static xmlCharEncoding gen_xmlCharEncoding(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(XML_CHAR_ENCODING_UTF8);
+    if (no == 1) return(XML_CHAR_ENCODING_NONE);
+    if (no == 2) return(XML_CHAR_ENCODING_8859_1);
+    return(XML_CHAR_ENCODING_ERROR);
+}
+static void des_xmlCharEncoding(int no ATTRIBUTE_UNUSED, xmlCharEncoding val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+
+#define gen_nb_xmlExpCtxtPtr 1
+static xmlExpCtxtPtr gen_xmlExpCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlExpCtxtPtr(int no ATTRIBUTE_UNUSED, xmlExpCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlExpNodePtr 1
+static xmlExpNodePtr gen_xmlExpNodePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlExpNodePtr(int no ATTRIBUTE_UNUSED, xmlExpNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+#define gen_nb_xmlSchemaPtr 1
+static xmlSchemaPtr gen_xmlSchemaPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaPtr(int no ATTRIBUTE_UNUSED, xmlSchemaPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlSchemaValidCtxtPtr 1
+static xmlSchemaValidCtxtPtr gen_xmlSchemaValidCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaValidCtxtPtr(int no ATTRIBUTE_UNUSED, xmlSchemaValidCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+
+#define gen_nb_xmlHashDeallocator 2
+static void 
+test_xmlHashDeallocator(void *payload ATTRIBUTE_UNUSED, xmlChar *name ATTRIBUTE_UNUSED) {
+}
+
+static xmlHashDeallocator gen_xmlHashDeallocator(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(test_xmlHashDeallocator);
+    return(NULL);
+}
+static void des_xmlHashDeallocator(int no ATTRIBUTE_UNUSED, xmlHashDeallocator val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+
+static void desret_int(int val ATTRIBUTE_UNUSED) {
+}
+static void desret_xmlChar(xmlChar val ATTRIBUTE_UNUSED) {
+}
+static void desret_long(long val ATTRIBUTE_UNUSED) {
+}
+static void desret_unsigned_long(unsigned long val ATTRIBUTE_UNUSED) {
+}
+static void desret_double(double val ATTRIBUTE_UNUSED) {
+}
+static void desret_xmlCharEncoding(xmlCharEncoding val ATTRIBUTE_UNUSED) {
+}
+#if 0
+static void desret_const_void_ptr(void *val ATTRIBUTE_UNUSED) {
+}
+#endif
+static void desret_void_ptr(void *val ATTRIBUTE_UNUSED) {
+}
+static void desret_const_char_ptr(const char *val ATTRIBUTE_UNUSED) {
+}
+static void desret_const_xmlChar_ptr(const xmlChar *val ATTRIBUTE_UNUSED) {
+}
+static void desret_xmlChar_ptr(xmlChar *val) {
+    if (val != NULL)
+	xmlFree(val);
+}
+static void desret_xmlDocPtr(xmlDocPtr val) {
+    if (val != api_doc)
+	xmlFreeDoc(val);
+}
+static void desret_xmlDictPtr(xmlDictPtr val) {
+    xmlDictFree(val);
+}
+#ifdef LIBXML_OUTPUT_ENABLED
+static void desret_xmlOutputBufferPtr(xmlOutputBufferPtr val) {
+    xmlOutputBufferClose(val);
+}
+#endif
+#ifdef LIBXML_READER_ENABLED
+static void desret_xmlTextReaderPtr(xmlTextReaderPtr val) {
+    xmlFreeTextReader(val);
+}
+#endif
+static void desret_xmlNodePtr(xmlNodePtr val) {
+    if ((val != NULL) && (val != api_root) && (val != (xmlNodePtr) api_doc)) {
+	xmlUnlinkNode(val);
+	xmlFreeNode(val);
+    }
+}
+static void desret_xmlAttrPtr(xmlAttrPtr val) {
+    if (val != NULL) {
+	xmlUnlinkNode((xmlNodePtr) val);
+	xmlFreeNode((xmlNodePtr) val);
+    }
+}
+static void desret_xmlEntityPtr(xmlEntityPtr val) {
+    if (val != NULL) {
+	xmlUnlinkNode((xmlNodePtr) val);
+	xmlFreeNode((xmlNodePtr) val);
+    }
+}
+static void desret_xmlElementPtr(xmlElementPtr val) {
+    if (val != NULL) {
+	xmlUnlinkNode((xmlNodePtr) val);
+    }
+}
+static void desret_xmlAttributePtr(xmlAttributePtr val) {
+    if (val != NULL) {
+	xmlUnlinkNode((xmlNodePtr) val);
+    }
+}
+static void desret_xmlNsPtr(xmlNsPtr val ATTRIBUTE_UNUSED) {
+}
+static void desret_xmlDtdPtr(xmlDtdPtr val) {
+    desret_xmlNodePtr((xmlNodePtr)val);
+}
+#ifdef LIBXML_XPATH_ENABLED
+static void desret_xmlXPathObjectPtr(xmlXPathObjectPtr val) {
+    xmlXPathFreeObject(val);
+}
+static void desret_xmlNodeSetPtr(xmlNodeSetPtr val) {
+    xmlXPathFreeNodeSet(val);
+}
+#endif
+static void desret_xmlParserCtxtPtr(xmlParserCtxtPtr val) {
+    xmlFreeParserCtxt(val);
+}
+static void desret_xmlParserInputBufferPtr(xmlParserInputBufferPtr val) {
+    xmlFreeParserInputBuffer(val);
+}
+static void desret_xmlParserInputPtr(xmlParserInputPtr val) {
+    xmlFreeInputStream(val);
+}
+#ifdef LIBXML_WRITER_ENABLED
+static void desret_xmlTextWriterPtr(xmlTextWriterPtr val) {
+    xmlFreeTextWriter(val);
+}
+#endif
+static void desret_xmlBufferPtr(xmlBufferPtr val) {
+    xmlBufferFree(val);
+}
+#ifdef LIBXML_SCHEMAS_ENABLED
+static void desret_xmlSchemaParserCtxtPtr(xmlSchemaParserCtxtPtr val) {
+    xmlSchemaFreeParserCtxt(val);
+}
+static void desret_xmlSchemaTypePtr(xmlSchemaTypePtr val ATTRIBUTE_UNUSED) {
+}
+static void desret_xmlRelaxNGParserCtxtPtr(xmlRelaxNGParserCtxtPtr val) {
+    xmlRelaxNGFreeParserCtxt(val);
+}
+#endif
+#ifdef LIBXML_HTML_ENABLED
+static void desret_const_htmlEntityDesc_ptr(const htmlEntityDesc * val ATTRIBUTE_UNUSED) {
+}
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+static void desret_xmlNanoHTTPCtxtPtr(void *val) {
+    xmlNanoHTTPClose(val);
+}
+#endif
+#ifdef LIBXML_FTP_ENABLED
+static void desret_xmlNanoFTPCtxtPtr(void *val) {
+    xmlNanoFTPClose(val);
+}
+#endif
+/* cut and pasted from autogenerated to avoid troubles */
+#define gen_nb_const_xmlChar_ptr_ptr 1
+static xmlChar ** gen_const_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, const xmlChar ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_unsigned_char_ptr 1
+static unsigned char * gen_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, unsigned char * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_const_unsigned_char_ptr 1
+static unsigned char * gen_const_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_unsigned_char_ptr(int no ATTRIBUTE_UNUSED, const unsigned char * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#ifdef LIBXML_HTML_ENABLED
+#define gen_nb_const_htmlNodePtr 1
+static htmlNodePtr gen_const_htmlNodePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_htmlNodePtr(int no ATTRIBUTE_UNUSED, const htmlNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_HTML_ENABLED
+#define gen_nb_htmlDocPtr 3
+static htmlDocPtr gen_htmlDocPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(htmlNewDoc(NULL, NULL));
+    if (no == 1) return(htmlReadMemory("<html/>", 7, "test", NULL, 0));
+    return(NULL);
+}
+static void des_htmlDocPtr(int no ATTRIBUTE_UNUSED, htmlDocPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if ((val != NULL) && (val != api_doc) && (val->doc != api_doc))
+        xmlFreeDoc(val);
+}
+static void desret_htmlDocPtr(htmlDocPtr val) {
+    if ((val != NULL) && (val != api_doc) && (val->doc != api_doc))
+        xmlFreeDoc(val);
+}
+#define gen_nb_htmlParserCtxtPtr 3
+static htmlParserCtxtPtr gen_htmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if (no == 0) return(xmlNewParserCtxt());
+    if (no == 1) return(htmlCreateMemoryParserCtxt("<html/>", 7));
+    return(NULL);
+}
+static void des_htmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, htmlParserCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL)
+        htmlFreeParserCtxt(val);
+}
+static void desret_htmlParserCtxtPtr(htmlParserCtxtPtr val) {
+    if (val != NULL)
+        htmlFreeParserCtxt(val);
+}
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+#define gen_nb_xmlNodeSetPtr 1
+static xmlNodeSetPtr gen_xmlNodeSetPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlNodeSetPtr(int no ATTRIBUTE_UNUSED, xmlNodeSetPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_DEBUG_ENABLED
+#ifdef LIBXML_XPATH_ENABLED
+#define gen_nb_xmlShellCtxtPtr 1
+static xmlShellCtxtPtr gen_xmlShellCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlShellCtxtPtr(int no ATTRIBUTE_UNUSED, xmlShellCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+#endif
+
+#ifdef LIBXML_PATTERN_ENABLED
+#define gen_nb_xmlPatternPtr 1
+static xmlPatternPtr gen_xmlPatternPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlPatternPtr(int no ATTRIBUTE_UNUSED, xmlPatternPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#define gen_nb_xmlElementContentPtr 1
+static xmlElementContentPtr gen_xmlElementContentPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlElementContentPtr(int no ATTRIBUTE_UNUSED, xmlElementContentPtr val, int nr ATTRIBUTE_UNUSED) {
+    if (val != NULL)
+        xmlFreeElementContent(val);
+}
+static void desret_xmlElementContentPtr(xmlElementContentPtr val) {
+    if (val != NULL)
+        xmlFreeElementContent(val);
+}
+
+#define gen_nb_xmlParserNodeInfoSeqPtr 1
+static xmlParserNodeInfoSeqPtr gen_xmlParserNodeInfoSeqPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlParserNodeInfoSeqPtr(int no ATTRIBUTE_UNUSED, xmlParserNodeInfoSeqPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_const_xmlParserNodeInfo_ptr(const xmlParserNodeInfo *val ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_void_ptr_ptr 1
+static void ** gen_void_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_void_ptr_ptr(int no ATTRIBUTE_UNUSED, void ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+/************************************************************************
+ *									*
+ *   WARNING: end of the manually maintained part of the test code	*
+ *            do not remove or alter the CUT HERE line			*
+ *									*
+ ************************************************************************/
+
+/* CUT HERE: everything below that line is generated */
+#ifdef LIBXML_HTML_ENABLED
+static void desret_htmlStatus(htmlStatus val ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#define gen_nb_xmlAttributeDefault 4
+static xmlAttributeDefault gen_xmlAttributeDefault(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_ATTRIBUTE_FIXED);
+    if (no == 2) return(XML_ATTRIBUTE_IMPLIED);
+    if (no == 3) return(XML_ATTRIBUTE_NONE);
+    if (no == 4) return(XML_ATTRIBUTE_REQUIRED);
+    return(0);
+}
+
+static void des_xmlAttributeDefault(int no ATTRIBUTE_UNUSED, xmlAttributeDefault val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlAttributeType 4
+static xmlAttributeType gen_xmlAttributeType(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_ATTRIBUTE_CDATA);
+    if (no == 2) return(XML_ATTRIBUTE_ENTITIES);
+    if (no == 3) return(XML_ATTRIBUTE_ENTITY);
+    if (no == 4) return(XML_ATTRIBUTE_ENUMERATION);
+    return(0);
+}
+
+static void des_xmlAttributeType(int no ATTRIBUTE_UNUSED, xmlAttributeType val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlBufferAllocationScheme 4
+static xmlBufferAllocationScheme gen_xmlBufferAllocationScheme(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_BUFFER_ALLOC_DOUBLEIT);
+    if (no == 2) return(XML_BUFFER_ALLOC_EXACT);
+    if (no == 3) return(XML_BUFFER_ALLOC_IMMUTABLE);
+    if (no == 4) return(XML_BUFFER_ALLOC_IO);
+    return(0);
+}
+
+static void des_xmlBufferAllocationScheme(int no ATTRIBUTE_UNUSED, xmlBufferAllocationScheme val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_xmlBufferAllocationScheme(xmlBufferAllocationScheme val ATTRIBUTE_UNUSED) {
+}
+
+#ifdef LIBXML_CATALOG_ENABLED
+#define gen_nb_xmlCatalogAllow 4
+static xmlCatalogAllow gen_xmlCatalogAllow(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_CATA_ALLOW_ALL);
+    if (no == 2) return(XML_CATA_ALLOW_DOCUMENT);
+    if (no == 3) return(XML_CATA_ALLOW_GLOBAL);
+    if (no == 4) return(XML_CATA_ALLOW_NONE);
+    return(0);
+}
+
+static void des_xmlCatalogAllow(int no ATTRIBUTE_UNUSED, xmlCatalogAllow val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_xmlCatalogAllow(xmlCatalogAllow val ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#ifdef LIBXML_CATALOG_ENABLED
+#define gen_nb_xmlCatalogPrefer 3
+static xmlCatalogPrefer gen_xmlCatalogPrefer(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_CATA_PREFER_NONE);
+    if (no == 2) return(XML_CATA_PREFER_PUBLIC);
+    if (no == 3) return(XML_CATA_PREFER_SYSTEM);
+    return(0);
+}
+
+static void des_xmlCatalogPrefer(int no ATTRIBUTE_UNUSED, xmlCatalogPrefer val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_xmlCatalogPrefer(xmlCatalogPrefer val ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#define gen_nb_xmlElementContentType 4
+static xmlElementContentType gen_xmlElementContentType(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_ELEMENT_CONTENT_ELEMENT);
+    if (no == 2) return(XML_ELEMENT_CONTENT_OR);
+    if (no == 3) return(XML_ELEMENT_CONTENT_PCDATA);
+    if (no == 4) return(XML_ELEMENT_CONTENT_SEQ);
+    return(0);
+}
+
+static void des_xmlElementContentType(int no ATTRIBUTE_UNUSED, xmlElementContentType val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlElementTypeVal 4
+static xmlElementTypeVal gen_xmlElementTypeVal(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_ELEMENT_TYPE_ANY);
+    if (no == 2) return(XML_ELEMENT_TYPE_ELEMENT);
+    if (no == 3) return(XML_ELEMENT_TYPE_EMPTY);
+    if (no == 4) return(XML_ELEMENT_TYPE_MIXED);
+    return(0);
+}
+
+static void des_xmlElementTypeVal(int no ATTRIBUTE_UNUSED, xmlElementTypeVal val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_xmlFeature 4
+static xmlFeature gen_xmlFeature(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_WITH_AUTOMATA);
+    if (no == 2) return(XML_WITH_C14N);
+    if (no == 3) return(XML_WITH_CATALOG);
+    if (no == 4) return(XML_WITH_DEBUG);
+    return(0);
+}
+
+static void des_xmlFeature(int no ATTRIBUTE_UNUSED, xmlFeature val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_xmlParserErrors(xmlParserErrors val ATTRIBUTE_UNUSED) {
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+#define gen_nb_xmlSchemaValType 4
+static xmlSchemaValType gen_xmlSchemaValType(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_SCHEMAS_ANYSIMPLETYPE);
+    if (no == 2) return(XML_SCHEMAS_ANYTYPE);
+    if (no == 3) return(XML_SCHEMAS_ANYURI);
+    if (no == 4) return(XML_SCHEMAS_BASE64BINARY);
+    return(0);
+}
+
+static void des_xmlSchemaValType(int no ATTRIBUTE_UNUSED, xmlSchemaValType val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static void desret_xmlSchemaValType(xmlSchemaValType val ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+#define gen_nb_xmlSchemaWhitespaceValueType 4
+static xmlSchemaWhitespaceValueType gen_xmlSchemaWhitespaceValueType(int no, int nr ATTRIBUTE_UNUSED) {
+    if (no == 1) return(XML_SCHEMA_WHITESPACE_COLLAPSE);
+    if (no == 2) return(XML_SCHEMA_WHITESPACE_PRESERVE);
+    if (no == 3) return(XML_SCHEMA_WHITESPACE_REPLACE);
+    if (no == 4) return(XML_SCHEMA_WHITESPACE_UNKNOWN);
+    return(0);
+}
+
+static void des_xmlSchemaWhitespaceValueType(int no ATTRIBUTE_UNUSED, xmlSchemaWhitespaceValueType val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#endif
+
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/SAX2.h>
+#include <libxml/c14n.h>
+#include <libxml/catalog.h>
+#include <libxml/chvalid.h>
+#include <libxml/debugXML.h>
+#include <libxml/dict.h>
+#include <libxml/encoding.h>
+#include <libxml/entities.h>
+#include <libxml/hash.h>
+#include <libxml/list.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/pattern.h>
+#include <libxml/relaxng.h>
+#include <libxml/schemasInternals.h>
+#include <libxml/schematron.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#include <libxml/valid.h>
+#include <libxml/xinclude.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlmodule.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlsave.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xpointer.h>
+static int test_HTMLparser(void);
+static int test_HTMLtree(void);
+static int test_SAX2(void);
+static int test_c14n(void);
+static int test_catalog(void);
+static int test_chvalid(void);
+static int test_debugXML(void);
+static int test_dict(void);
+static int test_encoding(void);
+static int test_entities(void);
+static int test_hash(void);
+static int test_list(void);
+static int test_nanoftp(void);
+static int test_nanohttp(void);
+static int test_parser(void);
+static int test_parserInternals(void);
+static int test_pattern(void);
+static int test_relaxng(void);
+static int test_schemasInternals(void);
+static int test_schematron(void);
+static int test_tree(void);
+static int test_uri(void);
+static int test_valid(void);
+static int test_xinclude(void);
+static int test_xmlIO(void);
+static int test_xmlautomata(void);
+static int test_xmlerror(void);
+static int test_xmlmodule(void);
+static int test_xmlreader(void);
+static int test_xmlregexp(void);
+static int test_xmlsave(void);
+static int test_xmlschemas(void);
+static int test_xmlschemastypes(void);
+static int test_xmlstring(void);
+static int test_xmlunicode(void);
+static int test_xmlwriter(void);
+static int test_xpath(void);
+static int test_xpathInternals(void);
+static int test_xpointer(void);
+
+/**
+ * testlibxml2:
+ *
+ * Main entry point of the tester for the full libxml2 module,
+ * it calls all the tester entry point for each module.
+ *
+ * Returns the number of error found
+ */
+static int
+testlibxml2(void)
+{
+    int test_ret = 0;
+
+    test_ret += test_HTMLparser();
+    test_ret += test_HTMLtree();
+    test_ret += test_SAX2();
+    test_ret += test_c14n();
+    test_ret += test_catalog();
+    test_ret += test_chvalid();
+    test_ret += test_debugXML();
+    test_ret += test_dict();
+    test_ret += test_encoding();
+    test_ret += test_entities();
+    test_ret += test_hash();
+    test_ret += test_list();
+    test_ret += test_nanoftp();
+    test_ret += test_nanohttp();
+    test_ret += test_parser();
+    test_ret += test_parserInternals();
+    test_ret += test_pattern();
+    test_ret += test_relaxng();
+    test_ret += test_schemasInternals();
+    test_ret += test_schematron();
+    test_ret += test_tree();
+    test_ret += test_uri();
+    test_ret += test_valid();
+    test_ret += test_xinclude();
+    test_ret += test_xmlIO();
+    test_ret += test_xmlautomata();
+    test_ret += test_xmlerror();
+    test_ret += test_xmlmodule();
+    test_ret += test_xmlreader();
+    test_ret += test_xmlregexp();
+    test_ret += test_xmlsave();
+    test_ret += test_xmlschemas();
+    test_ret += test_xmlschemastypes();
+    test_ret += test_xmlstring();
+    test_ret += test_xmlunicode();
+    test_ret += test_xmlwriter();
+    test_ret += test_xpath();
+    test_ret += test_xpathInternals();
+    test_ret += test_xpointer();
+
+    printf("Total: %d functions, %d tests, %d errors\n",
+           function_tests, call_tests, test_ret);
+    return(test_ret);
+}
+
+
+static int
+test_UTF8ToHtml(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    unsigned char * out; /* a pointer to an array of bytes to store the result */
+    int n_out;
+    int * outlen; /* the length of @out */
+    int n_outlen;
+    unsigned char * in; /* a pointer to an array of UTF-8 chars */
+    int n_in;
+    int * inlen; /* the length of @in */
+    int n_inlen;
+
+    for (n_out = 0;n_out < gen_nb_unsigned_char_ptr;n_out++) {
+    for (n_outlen = 0;n_outlen < gen_nb_int_ptr;n_outlen++) {
+    for (n_in = 0;n_in < gen_nb_const_unsigned_char_ptr;n_in++) {
+    for (n_inlen = 0;n_inlen < gen_nb_int_ptr;n_inlen++) {
+        mem_base = xmlMemBlocks();
+        out = gen_unsigned_char_ptr(n_out, 0);
+        outlen = gen_int_ptr(n_outlen, 1);
+        in = gen_const_unsigned_char_ptr(n_in, 2);
+        inlen = gen_int_ptr(n_inlen, 3);
+
+        ret_val = UTF8ToHtml(out, outlen, (const unsigned char *)in, inlen);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_char_ptr(n_out, out, 0);
+        des_int_ptr(n_outlen, outlen, 1);
+        des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+        des_int_ptr(n_inlen, inlen, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in UTF8ToHtml",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_outlen);
+            printf(" %d", n_in);
+            printf(" %d", n_inlen);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_HTML_ENABLED
+
+#define gen_nb_const_htmlElemDesc_ptr 1
+static htmlElemDesc * gen_const_htmlElemDesc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_htmlElemDesc_ptr(int no ATTRIBUTE_UNUSED, const htmlElemDesc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_htmlAttrAllowed(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlStatus ret_val;
+    htmlElemDesc * elt; /* HTML element */
+    int n_elt;
+    xmlChar * attr; /* HTML attribute */
+    int n_attr;
+    int legacy; /* whether to allow deprecated attributes */
+    int n_legacy;
+
+    for (n_elt = 0;n_elt < gen_nb_const_htmlElemDesc_ptr;n_elt++) {
+    for (n_attr = 0;n_attr < gen_nb_const_xmlChar_ptr;n_attr++) {
+    for (n_legacy = 0;n_legacy < gen_nb_int;n_legacy++) {
+        mem_base = xmlMemBlocks();
+        elt = gen_const_htmlElemDesc_ptr(n_elt, 0);
+        attr = gen_const_xmlChar_ptr(n_attr, 1);
+        legacy = gen_int(n_legacy, 2);
+
+        ret_val = htmlAttrAllowed((const htmlElemDesc *)elt, (const xmlChar *)attr, legacy);
+        desret_htmlStatus(ret_val);
+        call_tests++;
+        des_const_htmlElemDesc_ptr(n_elt, (const htmlElemDesc *)elt, 0);
+        des_const_xmlChar_ptr(n_attr, (const xmlChar *)attr, 1);
+        des_int(n_legacy, legacy, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlAttrAllowed",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_elt);
+            printf(" %d", n_attr);
+            printf(" %d", n_legacy);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_HTML_ENABLED
+
+#define gen_nb_htmlNodePtr 1
+static htmlNodePtr gen_htmlNodePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_htmlNodePtr(int no ATTRIBUTE_UNUSED, htmlNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_htmlAutoCloseTag(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlDocPtr doc; /* the HTML document */
+    int n_doc;
+    xmlChar * name; /* The tag name */
+    int n_name;
+    htmlNodePtr elem; /* the HTML element */
+    int n_elem;
+
+    for (n_doc = 0;n_doc < gen_nb_htmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_elem = 0;n_elem < gen_nb_htmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_htmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        elem = gen_htmlNodePtr(n_elem, 2);
+
+        ret_val = htmlAutoCloseTag(doc, (const xmlChar *)name, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_htmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlAutoCloseTag",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCreateMemoryParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ret_val;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = htmlCreateMemoryParserCtxt((const char *)buffer, size);
+        desret_htmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCreateMemoryParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_HTML_ENABLED
+
+#define gen_nb_htmlSAXHandlerPtr 1
+static htmlSAXHandlerPtr gen_htmlSAXHandlerPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_htmlSAXHandlerPtr(int no ATTRIBUTE_UNUSED, htmlSAXHandlerPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_htmlCreatePushParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ret_val;
+    htmlSAXHandlerPtr sax; /* a SAX handler */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks */
+    int n_user_data;
+    char * chunk; /* a pointer to an array of chars */
+    int n_chunk;
+    int size; /* number of chars in the array */
+    int n_size;
+    const char * filename; /* an optional file name or URI */
+    int n_filename;
+    xmlCharEncoding enc; /* an optional encoding */
+    int n_enc;
+
+    for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_chunk = 0;n_chunk < gen_nb_const_char_ptr;n_chunk++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_htmlSAXHandlerPtr(n_sax, 0);
+        user_data = gen_userdata(n_user_data, 1);
+        chunk = gen_const_char_ptr(n_chunk, 2);
+        size = gen_int(n_size, 3);
+        filename = gen_fileoutput(n_filename, 4);
+        enc = gen_xmlCharEncoding(n_enc, 5);
+
+        ret_val = htmlCreatePushParserCtxt(sax, user_data, (const char *)chunk, size, filename, enc);
+        desret_htmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_htmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_user_data, user_data, 1);
+        des_const_char_ptr(n_chunk, (const char *)chunk, 2);
+        des_int(n_size, size, 3);
+        des_fileoutput(n_filename, filename, 4);
+        des_xmlCharEncoding(n_enc, enc, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCreatePushParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_chunk);
+            printf(" %d", n_size);
+            printf(" %d", n_filename);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCtxtReadDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_int(n_options, 4);
+
+        ret_val = htmlCtxtReadDoc(ctxt, (const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_int(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCtxtReadDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCtxtReadFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    htmlDocPtr ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        filename = gen_filepath(n_filename, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_int(n_options, 3);
+
+        ret_val = htmlCtxtReadFile(ctxt, filename, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_filepath(n_filename, filename, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_options, options, 3);
+        xmlResetLastError();
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCtxtReadMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        buffer = gen_const_char_ptr(n_buffer, 1);
+        size = gen_int(n_size, 2);
+        URL = gen_filepath(n_URL, 3);
+        encoding = gen_const_char_ptr(n_encoding, 4);
+        options = gen_int(n_options, 5);
+
+        ret_val = htmlCtxtReadMemory(ctxt, (const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+        des_int(n_size, size, 2);
+        des_filepath(n_URL, URL, 3);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+        des_int(n_options, options, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCtxtReadMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCtxtReset(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+
+        htmlCtxtReset(ctxt);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCtxtReset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlCtxtUseOptions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        options = gen_int(n_options, 1);
+
+        ret_val = htmlCtxtUseOptions(ctxt, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_int(n_options, options, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCtxtUseOptions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlElementAllowedHere(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlElemDesc * parent; /* HTML parent element */
+    int n_parent;
+    xmlChar * elt; /* HTML element */
+    int n_elt;
+
+    for (n_parent = 0;n_parent < gen_nb_const_htmlElemDesc_ptr;n_parent++) {
+    for (n_elt = 0;n_elt < gen_nb_const_xmlChar_ptr;n_elt++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_const_htmlElemDesc_ptr(n_parent, 0);
+        elt = gen_const_xmlChar_ptr(n_elt, 1);
+
+        ret_val = htmlElementAllowedHere((const htmlElemDesc *)parent, (const xmlChar *)elt);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_htmlElemDesc_ptr(n_parent, (const htmlElemDesc *)parent, 0);
+        des_const_xmlChar_ptr(n_elt, (const xmlChar *)elt, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlElementAllowedHere",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_elt);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlElementStatusHere(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlStatus ret_val;
+    htmlElemDesc * parent; /* HTML parent element */
+    int n_parent;
+    htmlElemDesc * elt; /* HTML element */
+    int n_elt;
+
+    for (n_parent = 0;n_parent < gen_nb_const_htmlElemDesc_ptr;n_parent++) {
+    for (n_elt = 0;n_elt < gen_nb_const_htmlElemDesc_ptr;n_elt++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_const_htmlElemDesc_ptr(n_parent, 0);
+        elt = gen_const_htmlElemDesc_ptr(n_elt, 1);
+
+        ret_val = htmlElementStatusHere((const htmlElemDesc *)parent, (const htmlElemDesc *)elt);
+        desret_htmlStatus(ret_val);
+        call_tests++;
+        des_const_htmlElemDesc_ptr(n_parent, (const htmlElemDesc *)parent, 0);
+        des_const_htmlElemDesc_ptr(n_elt, (const htmlElemDesc *)elt, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlElementStatusHere",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_elt);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlEncodeEntities(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    unsigned char * out; /* a pointer to an array of bytes to store the result */
+    int n_out;
+    int * outlen; /* the length of @out */
+    int n_outlen;
+    unsigned char * in; /* a pointer to an array of UTF-8 chars */
+    int n_in;
+    int * inlen; /* the length of @in */
+    int n_inlen;
+    int quoteChar; /* the quote character to escape (' or ") or zero. */
+    int n_quoteChar;
+
+    for (n_out = 0;n_out < gen_nb_unsigned_char_ptr;n_out++) {
+    for (n_outlen = 0;n_outlen < gen_nb_int_ptr;n_outlen++) {
+    for (n_in = 0;n_in < gen_nb_const_unsigned_char_ptr;n_in++) {
+    for (n_inlen = 0;n_inlen < gen_nb_int_ptr;n_inlen++) {
+    for (n_quoteChar = 0;n_quoteChar < gen_nb_int;n_quoteChar++) {
+        mem_base = xmlMemBlocks();
+        out = gen_unsigned_char_ptr(n_out, 0);
+        outlen = gen_int_ptr(n_outlen, 1);
+        in = gen_const_unsigned_char_ptr(n_in, 2);
+        inlen = gen_int_ptr(n_inlen, 3);
+        quoteChar = gen_int(n_quoteChar, 4);
+
+        ret_val = htmlEncodeEntities(out, outlen, (const unsigned char *)in, inlen, quoteChar);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_char_ptr(n_out, out, 0);
+        des_int_ptr(n_outlen, outlen, 1);
+        des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+        des_int_ptr(n_inlen, inlen, 3);
+        des_int(n_quoteChar, quoteChar, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlEncodeEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_outlen);
+            printf(" %d", n_in);
+            printf(" %d", n_inlen);
+            printf(" %d", n_quoteChar);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlEntityLookup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    const htmlEntityDesc * ret_val;
+    xmlChar * name; /* the entity name */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+
+        ret_val = htmlEntityLookup((const xmlChar *)name);
+        desret_const_htmlEntityDesc_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlEntityLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlEntityValueLookup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    const htmlEntityDesc * ret_val;
+    unsigned int value; /* the entity's unicode value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_unsigned_int;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_unsigned_int(n_value, 0);
+
+        ret_val = htmlEntityValueLookup(value);
+        desret_const_htmlEntityDesc_ptr(ret_val);
+        call_tests++;
+        des_unsigned_int(n_value, value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlEntityValueLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlHandleOmittedElem(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    int val; /* int 0 or 1 */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = htmlHandleOmittedElem(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlHandleOmittedElem",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlIsAutoClosed(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlDocPtr doc; /* the HTML document */
+    int n_doc;
+    htmlNodePtr elem; /* the HTML element */
+    int n_elem;
+
+    for (n_doc = 0;n_doc < gen_nb_htmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_htmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_htmlDocPtr(n_doc, 0);
+        elem = gen_htmlNodePtr(n_elem, 1);
+
+        ret_val = htmlIsAutoClosed(doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlDocPtr(n_doc, doc, 0);
+        des_htmlNodePtr(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlIsAutoClosed",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlIsScriptAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * name; /* an attribute name */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+
+        ret_val = htmlIsScriptAttribute((const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlIsScriptAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNewParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = htmlNewParserCtxt();
+        desret_htmlParserCtxtPtr(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNewParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeStatus(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlStatus ret_val;
+    htmlNodePtr node; /* an htmlNodePtr in a tree */
+    int n_node;
+    int legacy; /* whether to allow deprecated elements (YES is faster here for Element nodes) */
+    int n_legacy;
+
+    for (n_node = 0;n_node < gen_nb_const_htmlNodePtr;n_node++) {
+    for (n_legacy = 0;n_legacy < gen_nb_int;n_legacy++) {
+        mem_base = xmlMemBlocks();
+        node = gen_const_htmlNodePtr(n_node, 0);
+        legacy = gen_int(n_legacy, 1);
+
+        ret_val = htmlNodeStatus((const htmlNodePtr)node, legacy);
+        desret_htmlStatus(ret_val);
+        call_tests++;
+        des_const_htmlNodePtr(n_node, (const htmlNodePtr)node, 0);
+        des_int(n_legacy, legacy, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeStatus",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_legacy);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseCharRef(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = htmlParseCharRef(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseCharRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseChunk(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_PUSH_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    char * chunk; /* an char array */
+    int n_chunk;
+    int size; /* the size in byte of the chunk */
+    int n_size;
+    int terminate; /* last chunk indicator */
+    int n_terminate;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_chunk = 0;n_chunk < gen_nb_const_char_ptr;n_chunk++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_terminate = 0;n_terminate < gen_nb_int;n_terminate++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        chunk = gen_const_char_ptr(n_chunk, 1);
+        size = gen_int(n_size, 2);
+        terminate = gen_int(n_terminate, 3);
+
+        ret_val = htmlParseChunk(ctxt, (const char *)chunk, size, terminate);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+        des_int(n_size, size, 2);
+        des_int(n_terminate, terminate, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseChunk",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_chunk);
+            printf(" %d", n_size);
+            printf(" %d", n_terminate);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+    char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+    int n_encoding;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlChar_ptr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlChar_ptr(n_cur, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+
+        ret_val = htmlParseDoc(cur, (const char *)encoding);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlChar_ptr(n_cur, cur, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = htmlParseDocument(ctxt);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+
+        htmlParseElement(ctxt);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseEntityRef(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    const htmlEntityDesc * ret_val;
+    htmlParserCtxtPtr ctxt; /* an HTML parser context */
+    int n_ctxt;
+    xmlChar ** str; /* location to store the entity name */
+    int n_str;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
+        str = gen_const_xmlChar_ptr_ptr(n_str, 1);
+
+        ret_val = htmlParseEntityRef(ctxt, (const xmlChar **)str);
+        desret_const_htmlEntityDesc_ptr(ret_val);
+        call_tests++;
+        des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr_ptr(n_str, (const xmlChar **)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlParseEntityRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlParseFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    htmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+    char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+    int n_encoding;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        filename = gen_filepath(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+
+        ret_val = htmlParseFile(filename, (const char *)encoding);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        xmlResetLastError();
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlReadDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+        URL = gen_filepath(n_URL, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_int(n_options, 3);
+
+        ret_val = htmlReadDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        des_filepath(n_URL, URL, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlReadDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlReadFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+        options = gen_int(n_options, 2);
+
+        ret_val = htmlReadFile(filename, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        des_int(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlReadFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlReadMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of htmlParserOption(s) */
+    int n_options;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_int(n_options, 4);
+
+        ret_val = htmlReadMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_int(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlReadMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSAXParseDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+    char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+    int n_encoding;
+    htmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    void * userData; /* if using SAX, this pointer will be provided on callbacks. */
+    int n_userData;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlChar_ptr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) {
+    for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlChar_ptr(n_cur, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+        sax = gen_htmlSAXHandlerPtr(n_sax, 2);
+        userData = gen_userdata(n_userData, 3);
+
+        ret_val = htmlSAXParseDoc(cur, (const char *)encoding, sax, userData);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlChar_ptr(n_cur, cur, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        des_htmlSAXHandlerPtr(n_sax, sax, 2);
+        des_userdata(n_userData, userData, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSAXParseDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_sax);
+            printf(" %d", n_userData);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSAXParseFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+    char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+    int n_encoding;
+    htmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    void * userData; /* if using SAX, this pointer will be provided on callbacks. */
+    int n_userData;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) {
+    for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+        sax = gen_htmlSAXHandlerPtr(n_sax, 2);
+        userData = gen_userdata(n_userData, 3);
+
+        ret_val = htmlSAXParseFile(filename, (const char *)encoding, sax, userData);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        des_htmlSAXHandlerPtr(n_sax, sax, 2);
+        des_userdata(n_userData, userData, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSAXParseFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_sax);
+            printf(" %d", n_userData);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlTagLookup(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_HTMLparser(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing HTMLparser : 32 of 38 functions ...\n");
+    test_ret += test_UTF8ToHtml();
+    test_ret += test_htmlAttrAllowed();
+    test_ret += test_htmlAutoCloseTag();
+    test_ret += test_htmlCreateMemoryParserCtxt();
+    test_ret += test_htmlCreatePushParserCtxt();
+    test_ret += test_htmlCtxtReadDoc();
+    test_ret += test_htmlCtxtReadFile();
+    test_ret += test_htmlCtxtReadMemory();
+    test_ret += test_htmlCtxtReset();
+    test_ret += test_htmlCtxtUseOptions();
+    test_ret += test_htmlElementAllowedHere();
+    test_ret += test_htmlElementStatusHere();
+    test_ret += test_htmlEncodeEntities();
+    test_ret += test_htmlEntityLookup();
+    test_ret += test_htmlEntityValueLookup();
+    test_ret += test_htmlHandleOmittedElem();
+    test_ret += test_htmlIsAutoClosed();
+    test_ret += test_htmlIsScriptAttribute();
+    test_ret += test_htmlNewParserCtxt();
+    test_ret += test_htmlNodeStatus();
+    test_ret += test_htmlParseCharRef();
+    test_ret += test_htmlParseChunk();
+    test_ret += test_htmlParseDoc();
+    test_ret += test_htmlParseDocument();
+    test_ret += test_htmlParseElement();
+    test_ret += test_htmlParseEntityRef();
+    test_ret += test_htmlParseFile();
+    test_ret += test_htmlReadDoc();
+    test_ret += test_htmlReadFile();
+    test_ret += test_htmlReadMemory();
+    test_ret += test_htmlSAXParseDoc();
+    test_ret += test_htmlSAXParseFile();
+    test_ret += test_htmlTagLookup();
+
+    if (test_ret != 0)
+	printf("Module HTMLparser: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_htmlDocContentDumpFormatOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr buf; /* the HTML buffer output */
+    int n_buf;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the encoding string */
+    int n_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        format = gen_int(n_format, 3);
+
+        htmlDocContentDumpFormatOutput(buf, cur, (const char *)encoding, format);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDocContentDumpFormatOutput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlDocContentDumpOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr buf; /* the HTML buffer output */
+    int n_buf;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the encoding string */
+    int n_encoding;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+
+        htmlDocContentDumpOutput(buf, cur, (const char *)encoding);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDocContentDumpOutput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlDocDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    FILE * f; /* the FILE* */
+    int n_f;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+
+    for (n_f = 0;n_f < gen_nb_FILE_ptr;n_f++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        f = gen_FILE_ptr(n_f, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+
+        ret_val = htmlDocDump(f, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_f, f, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDocDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_f);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlChar_ptr_ptr 1
+static xmlChar ** gen_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlChar_ptr_ptr(int no ATTRIBUTE_UNUSED, xmlChar ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_htmlDocDumpMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    xmlChar ** mem; /* OUT: the memory pointer */
+    int n_mem;
+    int * size; /* OUT: the memory length */
+    int n_size;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_mem = 0;n_mem < gen_nb_xmlChar_ptr_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int_ptr;n_size++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlDocPtr(n_cur, 0);
+        mem = gen_xmlChar_ptr_ptr(n_mem, 1);
+        size = gen_int_ptr(n_size, 2);
+
+        htmlDocDumpMemory(cur, mem, size);
+        call_tests++;
+        des_xmlDocPtr(n_cur, cur, 0);
+        des_xmlChar_ptr_ptr(n_mem, mem, 1);
+        des_int_ptr(n_size, size, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDocDumpMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlDocDumpMemoryFormat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    xmlChar ** mem; /* OUT: the memory pointer */
+    int n_mem;
+    int * size; /* OUT: the memory length */
+    int n_size;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_mem = 0;n_mem < gen_nb_xmlChar_ptr_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int_ptr;n_size++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlDocPtr(n_cur, 0);
+        mem = gen_xmlChar_ptr_ptr(n_mem, 1);
+        size = gen_int_ptr(n_size, 2);
+        format = gen_int(n_format, 3);
+
+        htmlDocDumpMemoryFormat(cur, mem, size, format);
+        call_tests++;
+        des_xmlDocPtr(n_cur, cur, 0);
+        des_xmlChar_ptr_ptr(n_mem, mem, 1);
+        des_int_ptr(n_size, size, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDocDumpMemoryFormat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlGetMetaEncoding(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    htmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_htmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_htmlDocPtr(n_doc, 0);
+
+        ret_val = htmlGetMetaEncoding(doc);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_htmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlGetMetaEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlIsBooleanAttr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * name; /* the name of the attribute to check */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+
+        ret_val = htmlIsBooleanAttr((const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlIsBooleanAttr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNewDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    xmlChar * URI; /* URI for the dtd, or NULL */
+    int n_URI;
+    xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
+    int n_ExternalID;
+
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_const_xmlChar_ptr(n_URI, 0);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
+
+        ret_val = htmlNewDoc((const xmlChar *)URI, (const xmlChar *)ExternalID);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNewDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_ExternalID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNewDocNoDtD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlDocPtr ret_val;
+    xmlChar * URI; /* URI for the dtd, or NULL */
+    int n_URI;
+    xmlChar * ExternalID; /* the external ID of the DTD, or NULL */
+    int n_ExternalID;
+
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_const_xmlChar_ptr(n_URI, 0);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
+
+        ret_val = htmlNewDocNoDtD((const xmlChar *)URI, (const xmlChar *)ExternalID);
+        desret_htmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNewDocNoDtD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_ExternalID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the HTML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+
+        ret_val = htmlNodeDump(buf, doc, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeDumpFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * out; /* the FILE pointer */
+    int n_out;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+
+    for (n_out = 0;n_out < gen_nb_FILE_ptr;n_out++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        out = gen_FILE_ptr(n_out, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+
+        htmlNodeDumpFile(out, doc, cur);
+        call_tests++;
+        des_FILE_ptr(n_out, out, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeDumpFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeDumpFileFormat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    FILE * out; /* the FILE pointer */
+    int n_out;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+    char * encoding; /* the document encoding */
+    int n_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_out = 0;n_out < gen_nb_FILE_ptr;n_out++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        out = gen_FILE_ptr(n_out, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        format = gen_int(n_format, 4);
+
+        ret_val = htmlNodeDumpFileFormat(out, doc, cur, (const char *)encoding, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_out, out, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_int(n_format, format, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeDumpFileFormat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeDumpFormatOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr buf; /* the HTML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+    char * encoding; /* the encoding string */
+    int n_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        format = gen_int(n_format, 4);
+
+        htmlNodeDumpFormatOutput(buf, doc, cur, (const char *)encoding, format);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_int(n_format, format, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeDumpFormatOutput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlNodeDumpOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr buf; /* the HTML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+    char * encoding; /* the encoding string */
+    int n_encoding;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+
+        htmlNodeDumpOutput(buf, doc, cur, (const char *)encoding);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNodeDumpOutput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSaveFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename (or URL) */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+
+        ret_val = htmlSaveFile(filename, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSaveFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSaveFileEnc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the document encoding */
+    int n_encoding;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+
+        ret_val = htmlSaveFileEnc(filename, cur, (const char *)encoding);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSaveFileEnc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSaveFileFormat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the document encoding */
+    int n_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        format = gen_int(n_format, 3);
+
+        ret_val = htmlSaveFileFormat(filename, cur, (const char *)encoding, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSaveFileFormat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlSetMetaEncoding(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    int ret_val;
+    htmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * encoding; /* the encoding string */
+    int n_encoding;
+
+    for (n_doc = 0;n_doc < gen_nb_htmlDocPtr;n_doc++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_xmlChar_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_htmlDocPtr(n_doc, 0);
+        encoding = gen_const_xmlChar_ptr(n_encoding, 1);
+
+        ret_val = htmlSetMetaEncoding(doc, (const xmlChar *)encoding);
+        desret_int(ret_val);
+        call_tests++;
+        des_htmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_encoding, (const xmlChar *)encoding, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlSetMetaEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_HTMLtree(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing HTMLtree : 18 of 18 functions ...\n");
+    test_ret += test_htmlDocContentDumpFormatOutput();
+    test_ret += test_htmlDocContentDumpOutput();
+    test_ret += test_htmlDocDump();
+    test_ret += test_htmlDocDumpMemory();
+    test_ret += test_htmlDocDumpMemoryFormat();
+    test_ret += test_htmlGetMetaEncoding();
+    test_ret += test_htmlIsBooleanAttr();
+    test_ret += test_htmlNewDoc();
+    test_ret += test_htmlNewDocNoDtD();
+    test_ret += test_htmlNodeDump();
+    test_ret += test_htmlNodeDumpFile();
+    test_ret += test_htmlNodeDumpFileFormat();
+    test_ret += test_htmlNodeDumpFormatOutput();
+    test_ret += test_htmlNodeDumpOutput();
+    test_ret += test_htmlSaveFile();
+    test_ret += test_htmlSaveFileEnc();
+    test_ret += test_htmlSaveFileFormat();
+    test_ret += test_htmlSetMetaEncoding();
+
+    if (test_ret != 0)
+	printf("Module HTMLtree: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_docbDefaultSAXHandlerInit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DOCB_ENABLED)
+#ifdef LIBXML_DOCB_ENABLED
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        docbDefaultSAXHandlerInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in docbDefaultSAXHandlerInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlDefaultSAXHandlerInit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+#ifdef LIBXML_HTML_ENABLED
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        htmlDefaultSAXHandlerInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlDefaultSAXHandlerInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDefaultSAXHandlerInit(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlDefaultSAXHandlerInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDefaultSAXHandlerInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlEnumerationPtr 1
+static xmlEnumerationPtr gen_xmlEnumerationPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlEnumerationPtr(int no ATTRIBUTE_UNUSED, xmlEnumerationPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlSAX2AttributeDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * elem; /* the name of the element */
+    int n_elem;
+    xmlChar * fullname; /* the attribute name */
+    int n_fullname;
+    int type; /* the attribute type */
+    int n_type;
+    int def; /* the type of default value */
+    int n_def;
+    xmlChar * defaultValue; /* the attribute default value */
+    int n_defaultValue;
+    xmlEnumerationPtr tree; /* the tree of enumerated value set */
+    int n_tree;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_elem = 0;n_elem < gen_nb_const_xmlChar_ptr;n_elem++) {
+    for (n_fullname = 0;n_fullname < gen_nb_const_xmlChar_ptr;n_fullname++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_def = 0;n_def < gen_nb_int;n_def++) {
+    for (n_defaultValue = 0;n_defaultValue < gen_nb_const_xmlChar_ptr;n_defaultValue++) {
+    for (n_tree = 0;n_tree < gen_nb_xmlEnumerationPtr;n_tree++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        elem = gen_const_xmlChar_ptr(n_elem, 1);
+        fullname = gen_const_xmlChar_ptr(n_fullname, 2);
+        type = gen_int(n_type, 3);
+        def = gen_int(n_def, 4);
+        defaultValue = gen_const_xmlChar_ptr(n_defaultValue, 5);
+        tree = gen_xmlEnumerationPtr(n_tree, 6);
+
+        xmlSAX2AttributeDecl(ctx, (const xmlChar *)elem, (const xmlChar *)fullname, type, def, (const xmlChar *)defaultValue, tree);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
+        des_const_xmlChar_ptr(n_fullname, (const xmlChar *)fullname, 2);
+        des_int(n_type, type, 3);
+        des_int(n_def, def, 4);
+        des_const_xmlChar_ptr(n_defaultValue, (const xmlChar *)defaultValue, 5);
+        des_xmlEnumerationPtr(n_tree, tree, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2AttributeDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_elem);
+            printf(" %d", n_fullname);
+            printf(" %d", n_type);
+            printf(" %d", n_def);
+            printf(" %d", n_defaultValue);
+            printf(" %d", n_tree);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2CDataBlock(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * value; /* The pcdata content */
+    int n_value;
+    int len; /* the block length */
+    int n_len;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        len = gen_int(n_len, 2);
+
+        xmlSAX2CDataBlock(ctx, (const xmlChar *)value, len);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2CDataBlock",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_value);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2Characters(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * ch; /* a xmlChar string */
+    int n_ch;
+    int len; /* the number of xmlChar */
+    int n_len;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_ch = 0;n_ch < gen_nb_const_xmlChar_ptr;n_ch++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        ch = gen_const_xmlChar_ptr(n_ch, 1);
+        len = gen_int(n_len, 2);
+
+        xmlSAX2Characters(ctx, (const xmlChar *)ch, len);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_ch, (const xmlChar *)ch, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2Characters",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_ch);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2Comment(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * value; /* the xmlSAX2Comment content */
+    int n_value;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+
+        xmlSAX2Comment(ctx, (const xmlChar *)value);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2Comment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2ElementDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* the element name */
+    int n_name;
+    int type; /* the element type */
+    int n_type;
+    xmlElementContentPtr content; /* the element value tree */
+    int n_content;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_content = 0;n_content < gen_nb_xmlElementContentPtr;n_content++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_int(n_type, 2);
+        content = gen_xmlElementContentPtr(n_content, 3);
+
+        xmlSAX2ElementDecl(ctx, (const xmlChar *)name, type, content);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_type, type, 2);
+        des_xmlElementContentPtr(n_content, content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2ElementDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2EndDocument(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        xmlSAX2EndDocument(ctx);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2EndDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2EndElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The element name */
+    int n_name;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        xmlSAX2EndElement(ctx, (const xmlChar *)name);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2EndElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2EndElementNs(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * localname; /* the local name of the element */
+    int n_localname;
+    xmlChar * prefix; /* the element namespace prefix if available */
+    int n_prefix;
+    xmlChar * URI; /* the element namespace name if available */
+    int n_URI;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_localname = 0;n_localname < gen_nb_const_xmlChar_ptr;n_localname++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        localname = gen_const_xmlChar_ptr(n_localname, 1);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 2);
+        URI = gen_const_xmlChar_ptr(n_URI, 3);
+
+        xmlSAX2EndElementNs(ctx, (const xmlChar *)localname, (const xmlChar *)prefix, (const xmlChar *)URI);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_localname, (const xmlChar *)localname, 1);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2EndElementNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_localname);
+            printf(" %d", n_prefix);
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2EntityDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* the entity name */
+    int n_name;
+    int type; /* the entity type */
+    int n_type;
+    xmlChar * publicId; /* The public ID of the entity */
+    int n_publicId;
+    xmlChar * systemId; /* The system ID of the entity */
+    int n_systemId;
+    xmlChar * content; /* the entity value (without processing). */
+    int n_content;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_publicId = 0;n_publicId < gen_nb_const_xmlChar_ptr;n_publicId++) {
+    for (n_systemId = 0;n_systemId < gen_nb_const_xmlChar_ptr;n_systemId++) {
+    for (n_content = 0;n_content < gen_nb_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_int(n_type, 2);
+        publicId = gen_const_xmlChar_ptr(n_publicId, 3);
+        systemId = gen_const_xmlChar_ptr(n_systemId, 4);
+        content = gen_xmlChar_ptr(n_content, 5);
+
+        xmlSAX2EntityDecl(ctx, (const xmlChar *)name, type, (const xmlChar *)publicId, (const xmlChar *)systemId, content);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_type, type, 2);
+        des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 3);
+        des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 4);
+        des_xmlChar_ptr(n_content, content, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2EntityDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_publicId);
+            printf(" %d", n_systemId);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2ExternalSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* the root element name */
+    int n_name;
+    xmlChar * ExternalID; /* the external ID */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
+    int n_SystemID;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
+
+        xmlSAX2ExternalSubset(ctx, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2ExternalSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetColumnNumber(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2GetColumnNumber(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetColumnNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The entity name */
+    int n_name;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlSAX2GetEntity(ctx, (const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetLineNumber(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2GetLineNumber(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetLineNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetParameterEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The entity name */
+    int n_name;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlSAX2GetParameterEntity(ctx, (const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetParameterEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetPublicId(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2GetPublicId(ctx);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetPublicId",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2GetSystemId(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2GetSystemId(ctx);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2GetSystemId",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2HasExternalSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2HasExternalSubset(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2HasExternalSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2HasInternalSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2HasInternalSubset(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2HasInternalSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2IgnorableWhitespace(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * ch; /* a xmlChar string */
+    int n_ch;
+    int len; /* the number of xmlChar */
+    int n_len;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_ch = 0;n_ch < gen_nb_const_xmlChar_ptr;n_ch++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        ch = gen_const_xmlChar_ptr(n_ch, 1);
+        len = gen_int(n_len, 2);
+
+        xmlSAX2IgnorableWhitespace(ctx, (const xmlChar *)ch, len);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_ch, (const xmlChar *)ch, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2IgnorableWhitespace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_ch);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlSAXHandler_ptr 1
+static xmlSAXHandler * gen_xmlSAXHandler_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSAXHandler_ptr(int no ATTRIBUTE_UNUSED, xmlSAXHandler * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlSAX2InitDefaultSAXHandler(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlSAXHandler * hdlr; /* the SAX handler */
+    int n_hdlr;
+    int warning; /* flag if non-zero sets the handler warning procedure */
+    int n_warning;
+
+    for (n_hdlr = 0;n_hdlr < gen_nb_xmlSAXHandler_ptr;n_hdlr++) {
+    for (n_warning = 0;n_warning < gen_nb_int;n_warning++) {
+        mem_base = xmlMemBlocks();
+        hdlr = gen_xmlSAXHandler_ptr(n_hdlr, 0);
+        warning = gen_int(n_warning, 1);
+
+        xmlSAX2InitDefaultSAXHandler(hdlr, warning);
+        call_tests++;
+        des_xmlSAXHandler_ptr(n_hdlr, hdlr, 0);
+        des_int(n_warning, warning, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2InitDefaultSAXHandler",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_hdlr);
+            printf(" %d", n_warning);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2InitDocbDefaultSAXHandler(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DOCB_ENABLED)
+    int mem_base;
+    xmlSAXHandler * hdlr; /* the SAX handler */
+    int n_hdlr;
+
+    for (n_hdlr = 0;n_hdlr < gen_nb_xmlSAXHandler_ptr;n_hdlr++) {
+        mem_base = xmlMemBlocks();
+        hdlr = gen_xmlSAXHandler_ptr(n_hdlr, 0);
+
+        xmlSAX2InitDocbDefaultSAXHandler(hdlr);
+        call_tests++;
+        des_xmlSAXHandler_ptr(n_hdlr, hdlr, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2InitDocbDefaultSAXHandler",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_hdlr);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2InitHtmlDefaultSAXHandler(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    xmlSAXHandler * hdlr; /* the SAX handler */
+    int n_hdlr;
+
+    for (n_hdlr = 0;n_hdlr < gen_nb_xmlSAXHandler_ptr;n_hdlr++) {
+        mem_base = xmlMemBlocks();
+        hdlr = gen_xmlSAXHandler_ptr(n_hdlr, 0);
+
+        xmlSAX2InitHtmlDefaultSAXHandler(hdlr);
+        call_tests++;
+        des_xmlSAXHandler_ptr(n_hdlr, hdlr, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2InitHtmlDefaultSAXHandler",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_hdlr);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2InternalSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* the root element name */
+    int n_name;
+    xmlChar * ExternalID; /* the external ID */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the SYSTEM ID (e.g. filename or URL) */
+    int n_SystemID;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
+
+        xmlSAX2InternalSubset(ctx, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2InternalSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2IsStandalone(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        ret_val = xmlSAX2IsStandalone(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2IsStandalone",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2NotationDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The name of the notation */
+    int n_name;
+    xmlChar * publicId; /* The public ID of the entity */
+    int n_publicId;
+    xmlChar * systemId; /* The system ID of the entity */
+    int n_systemId;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_publicId = 0;n_publicId < gen_nb_const_xmlChar_ptr;n_publicId++) {
+    for (n_systemId = 0;n_systemId < gen_nb_const_xmlChar_ptr;n_systemId++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        publicId = gen_const_xmlChar_ptr(n_publicId, 2);
+        systemId = gen_const_xmlChar_ptr(n_systemId, 3);
+
+        xmlSAX2NotationDecl(ctx, (const xmlChar *)name, (const xmlChar *)publicId, (const xmlChar *)systemId);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 2);
+        des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2NotationDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_publicId);
+            printf(" %d", n_systemId);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2ProcessingInstruction(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * target; /* the target name */
+    int n_target;
+    xmlChar * data; /* the PI data's */
+    int n_data;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_target = 0;n_target < gen_nb_const_xmlChar_ptr;n_target++) {
+    for (n_data = 0;n_data < gen_nb_const_xmlChar_ptr;n_data++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        target = gen_const_xmlChar_ptr(n_target, 1);
+        data = gen_const_xmlChar_ptr(n_data, 2);
+
+        xmlSAX2ProcessingInstruction(ctx, (const xmlChar *)target, (const xmlChar *)data);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
+        des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2ProcessingInstruction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_target);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2Reference(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The entity name */
+    int n_name;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        xmlSAX2Reference(ctx, (const xmlChar *)name);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2Reference",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2ResolveEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * publicId; /* The public ID of the entity */
+    int n_publicId;
+    xmlChar * systemId; /* The system ID of the entity */
+    int n_systemId;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_publicId = 0;n_publicId < gen_nb_const_xmlChar_ptr;n_publicId++) {
+    for (n_systemId = 0;n_systemId < gen_nb_const_xmlChar_ptr;n_systemId++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        publicId = gen_const_xmlChar_ptr(n_publicId, 1);
+        systemId = gen_const_xmlChar_ptr(n_systemId, 2);
+
+        ret_val = xmlSAX2ResolveEntity(ctx, (const xmlChar *)publicId, (const xmlChar *)systemId);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 1);
+        des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2ResolveEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_publicId);
+            printf(" %d", n_systemId);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlSAXLocatorPtr 1
+static xmlSAXLocatorPtr gen_xmlSAXLocatorPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSAXLocatorPtr(int no ATTRIBUTE_UNUSED, xmlSAXLocatorPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlSAX2SetDocumentLocator(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlSAXLocatorPtr loc; /* A SAX Locator */
+    int n_loc;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_loc = 0;n_loc < gen_nb_xmlSAXLocatorPtr;n_loc++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        loc = gen_xmlSAXLocatorPtr(n_loc, 1);
+
+        xmlSAX2SetDocumentLocator(ctx, loc);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_xmlSAXLocatorPtr(n_loc, loc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2SetDocumentLocator",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_loc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2StartDocument(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        xmlSAX2StartDocument(ctx);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2StartDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2StartElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * fullname; /* The element name, including namespace prefix */
+    int n_fullname;
+    xmlChar ** atts; /* An array of name/value attributes pairs, NULL terminated */
+    int n_atts;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_fullname = 0;n_fullname < gen_nb_const_xmlChar_ptr;n_fullname++) {
+    for (n_atts = 0;n_atts < gen_nb_const_xmlChar_ptr_ptr;n_atts++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        fullname = gen_const_xmlChar_ptr(n_fullname, 1);
+        atts = gen_const_xmlChar_ptr_ptr(n_atts, 2);
+
+        xmlSAX2StartElement(ctx, (const xmlChar *)fullname, (const xmlChar **)atts);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_fullname, (const xmlChar *)fullname, 1);
+        des_const_xmlChar_ptr_ptr(n_atts, (const xmlChar **)atts, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2StartElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_fullname);
+            printf(" %d", n_atts);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2StartElementNs(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * localname; /* the local name of the element */
+    int n_localname;
+    xmlChar * prefix; /* the element namespace prefix if available */
+    int n_prefix;
+    xmlChar * URI; /* the element namespace name if available */
+    int n_URI;
+    int nb_namespaces; /* number of namespace definitions on that node */
+    int n_nb_namespaces;
+    xmlChar ** namespaces; /* pointer to the array of prefix/URI pairs namespace definitions */
+    int n_namespaces;
+    int nb_attributes; /* the number of attributes on that node */
+    int n_nb_attributes;
+    int nb_defaulted; /* the number of defaulted attributes. */
+    int n_nb_defaulted;
+    xmlChar ** attributes; /* pointer to the array of (localname/prefix/URI/value/end) attribute values. */
+    int n_attributes;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_localname = 0;n_localname < gen_nb_const_xmlChar_ptr;n_localname++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+    for (n_nb_namespaces = 0;n_nb_namespaces < gen_nb_int;n_nb_namespaces++) {
+    for (n_namespaces = 0;n_namespaces < gen_nb_const_xmlChar_ptr_ptr;n_namespaces++) {
+    for (n_nb_attributes = 0;n_nb_attributes < gen_nb_int;n_nb_attributes++) {
+    for (n_nb_defaulted = 0;n_nb_defaulted < gen_nb_int;n_nb_defaulted++) {
+    for (n_attributes = 0;n_attributes < gen_nb_const_xmlChar_ptr_ptr;n_attributes++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        localname = gen_const_xmlChar_ptr(n_localname, 1);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 2);
+        URI = gen_const_xmlChar_ptr(n_URI, 3);
+        nb_namespaces = gen_int(n_nb_namespaces, 4);
+        namespaces = gen_const_xmlChar_ptr_ptr(n_namespaces, 5);
+        nb_attributes = gen_int(n_nb_attributes, 6);
+        nb_defaulted = gen_int(n_nb_defaulted, 7);
+        attributes = gen_const_xmlChar_ptr_ptr(n_attributes, 8);
+
+        xmlSAX2StartElementNs(ctx, (const xmlChar *)localname, (const xmlChar *)prefix, (const xmlChar *)URI, nb_namespaces, (const xmlChar **)namespaces, nb_attributes, nb_defaulted, (const xmlChar **)attributes);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_localname, (const xmlChar *)localname, 1);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 3);
+        des_int(n_nb_namespaces, nb_namespaces, 4);
+        des_const_xmlChar_ptr_ptr(n_namespaces, (const xmlChar **)namespaces, 5);
+        des_int(n_nb_attributes, nb_attributes, 6);
+        des_int(n_nb_defaulted, nb_defaulted, 7);
+        des_const_xmlChar_ptr_ptr(n_attributes, (const xmlChar **)attributes, 8);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2StartElementNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_localname);
+            printf(" %d", n_prefix);
+            printf(" %d", n_URI);
+            printf(" %d", n_nb_namespaces);
+            printf(" %d", n_namespaces);
+            printf(" %d", n_nb_attributes);
+            printf(" %d", n_nb_defaulted);
+            printf(" %d", n_attributes);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAX2UnparsedEntityDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* the user data (XML parser context) */
+    int n_ctx;
+    xmlChar * name; /* The name of the entity */
+    int n_name;
+    xmlChar * publicId; /* The public ID of the entity */
+    int n_publicId;
+    xmlChar * systemId; /* The system ID of the entity */
+    int n_systemId;
+    xmlChar * notationName; /* the name of the notation */
+    int n_notationName;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_publicId = 0;n_publicId < gen_nb_const_xmlChar_ptr;n_publicId++) {
+    for (n_systemId = 0;n_systemId < gen_nb_const_xmlChar_ptr;n_systemId++) {
+    for (n_notationName = 0;n_notationName < gen_nb_const_xmlChar_ptr;n_notationName++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        publicId = gen_const_xmlChar_ptr(n_publicId, 2);
+        systemId = gen_const_xmlChar_ptr(n_systemId, 3);
+        notationName = gen_const_xmlChar_ptr(n_notationName, 4);
+
+        xmlSAX2UnparsedEntityDecl(ctx, (const xmlChar *)name, (const xmlChar *)publicId, (const xmlChar *)systemId, (const xmlChar *)notationName);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_publicId, (const xmlChar *)publicId, 2);
+        des_const_xmlChar_ptr(n_systemId, (const xmlChar *)systemId, 3);
+        des_const_xmlChar_ptr(n_notationName, (const xmlChar *)notationName, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAX2UnparsedEntityDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_name);
+            printf(" %d", n_publicId);
+            printf(" %d", n_systemId);
+            printf(" %d", n_notationName);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXDefaultVersion(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    int version; /* the version, 1 or 2 */
+    int n_version;
+
+    for (n_version = 0;n_version < gen_nb_int;n_version++) {
+        mem_base = xmlMemBlocks();
+        version = gen_int(n_version, 0);
+
+        ret_val = xmlSAXDefaultVersion(version);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_version, version, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXDefaultVersion",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_version);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXVersion(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlSAXHandler * hdlr; /* the SAX handler */
+    int n_hdlr;
+    int version; /* the version, 1 or 2 */
+    int n_version;
+
+    for (n_hdlr = 0;n_hdlr < gen_nb_xmlSAXHandler_ptr;n_hdlr++) {
+    for (n_version = 0;n_version < gen_nb_int;n_version++) {
+        mem_base = xmlMemBlocks();
+        hdlr = gen_xmlSAXHandler_ptr(n_hdlr, 0);
+        version = gen_int(n_version, 1);
+
+        ret_val = xmlSAXVersion(hdlr, version);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSAXHandler_ptr(n_hdlr, hdlr, 0);
+        des_int(n_version, version, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXVersion",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_hdlr);
+            printf(" %d", n_version);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_SAX2(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing SAX2 : 38 of 38 functions ...\n");
+    test_ret += test_docbDefaultSAXHandlerInit();
+    test_ret += test_htmlDefaultSAXHandlerInit();
+    test_ret += test_xmlDefaultSAXHandlerInit();
+    test_ret += test_xmlSAX2AttributeDecl();
+    test_ret += test_xmlSAX2CDataBlock();
+    test_ret += test_xmlSAX2Characters();
+    test_ret += test_xmlSAX2Comment();
+    test_ret += test_xmlSAX2ElementDecl();
+    test_ret += test_xmlSAX2EndDocument();
+    test_ret += test_xmlSAX2EndElement();
+    test_ret += test_xmlSAX2EndElementNs();
+    test_ret += test_xmlSAX2EntityDecl();
+    test_ret += test_xmlSAX2ExternalSubset();
+    test_ret += test_xmlSAX2GetColumnNumber();
+    test_ret += test_xmlSAX2GetEntity();
+    test_ret += test_xmlSAX2GetLineNumber();
+    test_ret += test_xmlSAX2GetParameterEntity();
+    test_ret += test_xmlSAX2GetPublicId();
+    test_ret += test_xmlSAX2GetSystemId();
+    test_ret += test_xmlSAX2HasExternalSubset();
+    test_ret += test_xmlSAX2HasInternalSubset();
+    test_ret += test_xmlSAX2IgnorableWhitespace();
+    test_ret += test_xmlSAX2InitDefaultSAXHandler();
+    test_ret += test_xmlSAX2InitDocbDefaultSAXHandler();
+    test_ret += test_xmlSAX2InitHtmlDefaultSAXHandler();
+    test_ret += test_xmlSAX2InternalSubset();
+    test_ret += test_xmlSAX2IsStandalone();
+    test_ret += test_xmlSAX2NotationDecl();
+    test_ret += test_xmlSAX2ProcessingInstruction();
+    test_ret += test_xmlSAX2Reference();
+    test_ret += test_xmlSAX2ResolveEntity();
+    test_ret += test_xmlSAX2SetDocumentLocator();
+    test_ret += test_xmlSAX2StartDocument();
+    test_ret += test_xmlSAX2StartElement();
+    test_ret += test_xmlSAX2StartElementNs();
+    test_ret += test_xmlSAX2UnparsedEntityDecl();
+    test_ret += test_xmlSAXDefaultVersion();
+    test_ret += test_xmlSAXVersion();
+
+    if (test_ret != 0)
+	printf("Module SAX2: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlC14NDocDumpMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the XML document for canonization */
+    int n_doc;
+    xmlNodeSetPtr nodes; /* the nodes set to be included in the canonized image or NULL if all document nodes should be included */
+    int n_nodes;
+    int mode; /* the c14n mode (see @xmlC14NMode) */
+    int n_mode;
+    xmlChar ** inclusive_ns_prefixes; /* the list of inclusive namespace prefixes ended with a NULL or NULL if there is no inclusive namespaces (only for exclusive canonicalization, ignored otherwise) */
+    int n_inclusive_ns_prefixes;
+    int with_comments; /* include comments in the result (!=0) or not (==0) */
+    int n_with_comments;
+    xmlChar ** doc_txt_ptr; /* the memory pointer for allocated canonical XML text; the caller of this functions is responsible for calling xmlFree() to free allocated memory */
+    int n_doc_txt_ptr;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_mode = 0;n_mode < gen_nb_int;n_mode++) {
+    for (n_inclusive_ns_prefixes = 0;n_inclusive_ns_prefixes < gen_nb_xmlChar_ptr_ptr;n_inclusive_ns_prefixes++) {
+    for (n_with_comments = 0;n_with_comments < gen_nb_int;n_with_comments++) {
+    for (n_doc_txt_ptr = 0;n_doc_txt_ptr < gen_nb_xmlChar_ptr_ptr;n_doc_txt_ptr++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        nodes = gen_xmlNodeSetPtr(n_nodes, 1);
+        mode = gen_int(n_mode, 2);
+        inclusive_ns_prefixes = gen_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, 3);
+        with_comments = gen_int(n_with_comments, 4);
+        doc_txt_ptr = gen_xmlChar_ptr_ptr(n_doc_txt_ptr, 5);
+
+        ret_val = xmlC14NDocDumpMemory(doc, nodes, mode, inclusive_ns_prefixes, with_comments, doc_txt_ptr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodeSetPtr(n_nodes, nodes, 1);
+        des_int(n_mode, mode, 2);
+        des_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, inclusive_ns_prefixes, 3);
+        des_int(n_with_comments, with_comments, 4);
+        des_xmlChar_ptr_ptr(n_doc_txt_ptr, doc_txt_ptr, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlC14NDocDumpMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_nodes);
+            printf(" %d", n_mode);
+            printf(" %d", n_inclusive_ns_prefixes);
+            printf(" %d", n_with_comments);
+            printf(" %d", n_doc_txt_ptr);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlC14NDocSave(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the XML document for canonization */
+    int n_doc;
+    xmlNodeSetPtr nodes; /* the nodes set to be included in the canonized image or NULL if all document nodes should be included */
+    int n_nodes;
+    int mode; /* the c14n mode (see @xmlC14NMode) */
+    int n_mode;
+    xmlChar ** inclusive_ns_prefixes; /* the list of inclusive namespace prefixes ended with a NULL or NULL if there is no inclusive namespaces (only for exclusive canonicalization, ignored otherwise) */
+    int n_inclusive_ns_prefixes;
+    int with_comments; /* include comments in the result (!=0) or not (==0) */
+    int n_with_comments;
+    const char * filename; /* the filename to store canonical XML image */
+    int n_filename;
+    int compression; /* the compression level (zlib requred): -1 - libxml default, 0 - uncompressed, >0 - compression level */
+    int n_compression;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_mode = 0;n_mode < gen_nb_int;n_mode++) {
+    for (n_inclusive_ns_prefixes = 0;n_inclusive_ns_prefixes < gen_nb_xmlChar_ptr_ptr;n_inclusive_ns_prefixes++) {
+    for (n_with_comments = 0;n_with_comments < gen_nb_int;n_with_comments++) {
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        nodes = gen_xmlNodeSetPtr(n_nodes, 1);
+        mode = gen_int(n_mode, 2);
+        inclusive_ns_prefixes = gen_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, 3);
+        with_comments = gen_int(n_with_comments, 4);
+        filename = gen_fileoutput(n_filename, 5);
+        compression = gen_int(n_compression, 6);
+
+        ret_val = xmlC14NDocSave(doc, nodes, mode, inclusive_ns_prefixes, with_comments, filename, compression);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodeSetPtr(n_nodes, nodes, 1);
+        des_int(n_mode, mode, 2);
+        des_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, inclusive_ns_prefixes, 3);
+        des_int(n_with_comments, with_comments, 4);
+        des_fileoutput(n_filename, filename, 5);
+        des_int(n_compression, compression, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlC14NDocSave",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_nodes);
+            printf(" %d", n_mode);
+            printf(" %d", n_inclusive_ns_prefixes);
+            printf(" %d", n_with_comments);
+            printf(" %d", n_filename);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlC14NDocSaveTo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the XML document for canonization */
+    int n_doc;
+    xmlNodeSetPtr nodes; /* the nodes set to be included in the canonized image or NULL if all document nodes should be included */
+    int n_nodes;
+    int mode; /* the c14n mode (see @xmlC14NMode) */
+    int n_mode;
+    xmlChar ** inclusive_ns_prefixes; /* the list of inclusive namespace prefixes ended with a NULL or NULL if there is no inclusive namespaces (only for exclusive canonicalization, ignored otherwise) */
+    int n_inclusive_ns_prefixes;
+    int with_comments; /* include comments in the result (!=0) or not (==0) */
+    int n_with_comments;
+    xmlOutputBufferPtr buf; /* the output buffer to store canonical XML; this buffer MUST have encoder==NULL because C14N requires UTF-8 output */
+    int n_buf;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_mode = 0;n_mode < gen_nb_int;n_mode++) {
+    for (n_inclusive_ns_prefixes = 0;n_inclusive_ns_prefixes < gen_nb_xmlChar_ptr_ptr;n_inclusive_ns_prefixes++) {
+    for (n_with_comments = 0;n_with_comments < gen_nb_int;n_with_comments++) {
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        nodes = gen_xmlNodeSetPtr(n_nodes, 1);
+        mode = gen_int(n_mode, 2);
+        inclusive_ns_prefixes = gen_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, 3);
+        with_comments = gen_int(n_with_comments, 4);
+        buf = gen_xmlOutputBufferPtr(n_buf, 5);
+
+        ret_val = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes, with_comments, buf);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodeSetPtr(n_nodes, nodes, 1);
+        des_int(n_mode, mode, 2);
+        des_xmlChar_ptr_ptr(n_inclusive_ns_prefixes, inclusive_ns_prefixes, 3);
+        des_int(n_with_comments, with_comments, 4);
+        des_xmlOutputBufferPtr(n_buf, buf, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlC14NDocSaveTo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_nodes);
+            printf(" %d", n_mode);
+            printf(" %d", n_inclusive_ns_prefixes);
+            printf(" %d", n_with_comments);
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlC14NExecute(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_c14n(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing c14n : 3 of 4 functions ...\n");
+    test_ret += test_xmlC14NDocDumpMemory();
+    test_ret += test_xmlC14NDocSave();
+    test_ret += test_xmlC14NDocSaveTo();
+    test_ret += test_xmlC14NExecute();
+
+    if (test_ret != 0)
+	printf("Module c14n: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_CATALOG_ENABLED
+
+#define gen_nb_xmlCatalogPtr 1
+static xmlCatalogPtr gen_xmlCatalogPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlCatalogPtr(int no ATTRIBUTE_UNUSED, xmlCatalogPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlACatalogAdd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * type; /* the type of record to add to the catalog */
+    int n_type;
+    xmlChar * orig; /* the system, public or prefix to match */
+    int n_orig;
+    xmlChar * replace; /* the replacement value for the match */
+    int n_replace;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_type = 0;n_type < gen_nb_const_xmlChar_ptr;n_type++) {
+    for (n_orig = 0;n_orig < gen_nb_const_xmlChar_ptr;n_orig++) {
+    for (n_replace = 0;n_replace < gen_nb_const_xmlChar_ptr;n_replace++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        type = gen_const_xmlChar_ptr(n_type, 1);
+        orig = gen_const_xmlChar_ptr(n_orig, 2);
+        replace = gen_const_xmlChar_ptr(n_replace, 3);
+
+        ret_val = xmlACatalogAdd(catal, (const xmlChar *)type, (const xmlChar *)orig, (const xmlChar *)replace);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_type, (const xmlChar *)type, 1);
+        des_const_xmlChar_ptr(n_orig, (const xmlChar *)orig, 2);
+        des_const_xmlChar_ptr(n_replace, (const xmlChar *)replace, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogAdd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_type);
+            printf(" %d", n_orig);
+            printf(" %d", n_replace);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    FILE * out; /* the file. */
+    int n_out;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_out = 0;n_out < gen_nb_FILE_ptr;n_out++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        out = gen_FILE_ptr(n_out, 1);
+
+        xmlACatalogDump(catal, out);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_FILE_ptr(n_out, out, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_out);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogRemove(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * value; /* the value to remove */
+    int n_value;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+
+        ret_val = xmlACatalogRemove(catal, (const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogRemove",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogResolve(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * pubID; /* the public ID string */
+    int n_pubID;
+    xmlChar * sysID; /* the system ID string */
+    int n_sysID;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
+    for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        pubID = gen_const_xmlChar_ptr(n_pubID, 1);
+        sysID = gen_const_xmlChar_ptr(n_sysID, 2);
+
+        ret_val = xmlACatalogResolve(catal, (const xmlChar *)pubID, (const xmlChar *)sysID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
+        des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogResolve",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_pubID);
+            printf(" %d", n_sysID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogResolvePublic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * pubID; /* the public ID string */
+    int n_pubID;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        pubID = gen_const_xmlChar_ptr(n_pubID, 1);
+
+        ret_val = xmlACatalogResolvePublic(catal, (const xmlChar *)pubID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogResolvePublic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_pubID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogResolveSystem(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * sysID; /* the system ID string */
+    int n_sysID;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        sysID = gen_const_xmlChar_ptr(n_sysID, 1);
+
+        ret_val = xmlACatalogResolveSystem(catal, (const xmlChar *)sysID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogResolveSystem",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_sysID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlACatalogResolveURI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlCatalogPtr catal; /* a Catalog */
+    int n_catal;
+    xmlChar * URI; /* the URI */
+    int n_URI;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+        URI = gen_const_xmlChar_ptr(n_URI, 1);
+
+        ret_val = xmlACatalogResolveURI(catal, (const xmlChar *)URI);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlACatalogResolveURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogAdd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * type; /* the type of record to add to the catalog */
+    int n_type;
+    xmlChar * orig; /* the system, public or prefix to match */
+    int n_orig;
+    xmlChar * replace; /* the replacement value for the match */
+    int n_replace;
+
+    for (n_type = 0;n_type < gen_nb_const_xmlChar_ptr;n_type++) {
+    for (n_orig = 0;n_orig < gen_nb_const_xmlChar_ptr;n_orig++) {
+    for (n_replace = 0;n_replace < gen_nb_const_xmlChar_ptr;n_replace++) {
+        mem_base = xmlMemBlocks();
+        type = gen_const_xmlChar_ptr(n_type, 0);
+        orig = gen_const_xmlChar_ptr(n_orig, 1);
+        replace = gen_const_xmlChar_ptr(n_replace, 2);
+
+        ret_val = xmlCatalogAdd((const xmlChar *)type, (const xmlChar *)orig, (const xmlChar *)replace);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_type, (const xmlChar *)type, 0);
+        des_const_xmlChar_ptr(n_orig, (const xmlChar *)orig, 1);
+        des_const_xmlChar_ptr(n_replace, (const xmlChar *)replace, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogAdd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_orig);
+            printf(" %d", n_replace);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+
+
+        xmlCatalogCleanup();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogConvert(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int ret_val;
+
+
+        ret_val = xmlCatalogConvert();
+        desret_int(ret_val);
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * out; /* the file. */
+    int n_out;
+
+    for (n_out = 0;n_out < gen_nb_FILE_ptr;n_out++) {
+        mem_base = xmlMemBlocks();
+        out = gen_FILE_ptr(n_out, 0);
+
+        xmlCatalogDump(out);
+        call_tests++;
+        des_FILE_ptr(n_out, out, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogGetDefaults(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlCatalogAllow ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlCatalogGetDefaults();
+        desret_xmlCatalogAllow(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogGetDefaults",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogIsEmpty(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlCatalogPtr catal; /* should this create an SGML catalog */
+    int n_catal;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+
+        ret_val = xmlCatalogIsEmpty(catal);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogIsEmpty",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogLocalResolve(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    void * catalogs; /* a document's list of catalogs */
+    int n_catalogs;
+    xmlChar * pubID; /* the public ID string */
+    int n_pubID;
+    xmlChar * sysID; /* the system ID string */
+    int n_sysID;
+
+    for (n_catalogs = 0;n_catalogs < gen_nb_void_ptr;n_catalogs++) {
+    for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
+    for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
+        mem_base = xmlMemBlocks();
+        catalogs = gen_void_ptr(n_catalogs, 0);
+        pubID = gen_const_xmlChar_ptr(n_pubID, 1);
+        sysID = gen_const_xmlChar_ptr(n_sysID, 2);
+
+        ret_val = xmlCatalogLocalResolve(catalogs, (const xmlChar *)pubID, (const xmlChar *)sysID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_void_ptr(n_catalogs, catalogs, 0);
+        des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 1);
+        des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogLocalResolve",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catalogs);
+            printf(" %d", n_pubID);
+            printf(" %d", n_sysID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogLocalResolveURI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    void * catalogs; /* a document's list of catalogs */
+    int n_catalogs;
+    xmlChar * URI; /* the URI */
+    int n_URI;
+
+    for (n_catalogs = 0;n_catalogs < gen_nb_void_ptr;n_catalogs++) {
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+        mem_base = xmlMemBlocks();
+        catalogs = gen_void_ptr(n_catalogs, 0);
+        URI = gen_const_xmlChar_ptr(n_URI, 1);
+
+        ret_val = xmlCatalogLocalResolveURI(catalogs, (const xmlChar *)URI);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_void_ptr(n_catalogs, catalogs, 0);
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogLocalResolveURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catalogs);
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogRemove(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int ret_val;
+    xmlChar * value; /* the value to remove */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlCatalogRemove((const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogResolve(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    xmlChar * ret_val;
+    xmlChar * pubID; /* the public ID string */
+    int n_pubID;
+    xmlChar * sysID; /* the system ID string */
+    int n_sysID;
+
+    for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
+    for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
+        pubID = gen_const_xmlChar_ptr(n_pubID, 0);
+        sysID = gen_const_xmlChar_ptr(n_sysID, 1);
+
+        ret_val = xmlCatalogResolve((const xmlChar *)pubID, (const xmlChar *)sysID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 0);
+        des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 1);
+        xmlResetLastError();
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogResolvePublic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * pubID; /* the public ID string */
+    int n_pubID;
+
+    for (n_pubID = 0;n_pubID < gen_nb_const_xmlChar_ptr;n_pubID++) {
+        mem_base = xmlMemBlocks();
+        pubID = gen_const_xmlChar_ptr(n_pubID, 0);
+
+        ret_val = xmlCatalogResolvePublic((const xmlChar *)pubID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_pubID, (const xmlChar *)pubID, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogResolvePublic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_pubID);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogResolveSystem(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * sysID; /* the system ID string */
+    int n_sysID;
+
+    for (n_sysID = 0;n_sysID < gen_nb_const_xmlChar_ptr;n_sysID++) {
+        mem_base = xmlMemBlocks();
+        sysID = gen_const_xmlChar_ptr(n_sysID, 0);
+
+        ret_val = xmlCatalogResolveSystem((const xmlChar *)sysID);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_sysID, (const xmlChar *)sysID, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogResolveSystem",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sysID);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogResolveURI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * URI; /* the URI */
+    int n_URI;
+
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_const_xmlChar_ptr(n_URI, 0);
+
+        ret_val = xmlCatalogResolveURI((const xmlChar *)URI);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogResolveURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogSetDefaultPrefer(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlCatalogPrefer ret_val;
+    xmlCatalogPrefer prefer; /* the default preference for delegation */
+    int n_prefer;
+
+    for (n_prefer = 0;n_prefer < gen_nb_xmlCatalogPrefer;n_prefer++) {
+        mem_base = xmlMemBlocks();
+        prefer = gen_xmlCatalogPrefer(n_prefer, 0);
+
+        ret_val = xmlCatalogSetDefaultPrefer(prefer);
+        desret_xmlCatalogPrefer(ret_val);
+        call_tests++;
+        des_xmlCatalogPrefer(n_prefer, prefer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogSetDefaultPrefer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_prefer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCatalogSetDefaults(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlCatalogAllow allow; /* what catalogs should be accepted */
+    int n_allow;
+
+    for (n_allow = 0;n_allow < gen_nb_xmlCatalogAllow;n_allow++) {
+        mem_base = xmlMemBlocks();
+        allow = gen_xmlCatalogAllow(n_allow, 0);
+
+        xmlCatalogSetDefaults(allow);
+        call_tests++;
+        des_xmlCatalogAllow(n_allow, allow, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCatalogSetDefaults",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_allow);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlConvertSGMLCatalog(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlCatalogPtr catal; /* the catalog */
+    int n_catal;
+
+    for (n_catal = 0;n_catal < gen_nb_xmlCatalogPtr;n_catal++) {
+        mem_base = xmlMemBlocks();
+        catal = gen_xmlCatalogPtr(n_catal, 0);
+
+        ret_val = xmlConvertSGMLCatalog(catal);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCatalogPtr(n_catal, catal, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlConvertSGMLCatalog",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_catal);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitializeCatalog(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlInitializeCatalog();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlInitializeCatalog",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLoadACatalog(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlLoadCatalog(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int ret_val;
+    const char * filename; /* a file path */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlLoadCatalog(filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLoadCatalogs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    char * pathss; /* a list of directories separated by a colon or a space. */
+    int n_pathss;
+
+    for (n_pathss = 0;n_pathss < gen_nb_const_char_ptr;n_pathss++) {
+        pathss = gen_const_char_ptr(n_pathss, 0);
+
+        xmlLoadCatalogs((const char *)pathss);
+        call_tests++;
+        des_const_char_ptr(n_pathss, (const char *)pathss, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLoadSGMLSuperCatalog(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewCatalog(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseCatalogFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_CATALOG_ENABLED)
+    int mem_base;
+    xmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlParseCatalogFile(filename);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseCatalogFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_catalog(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing catalog : 27 of 36 functions ...\n");
+    test_ret += test_xmlACatalogAdd();
+    test_ret += test_xmlACatalogDump();
+    test_ret += test_xmlACatalogRemove();
+    test_ret += test_xmlACatalogResolve();
+    test_ret += test_xmlACatalogResolvePublic();
+    test_ret += test_xmlACatalogResolveSystem();
+    test_ret += test_xmlACatalogResolveURI();
+    test_ret += test_xmlCatalogAdd();
+    test_ret += test_xmlCatalogCleanup();
+    test_ret += test_xmlCatalogConvert();
+    test_ret += test_xmlCatalogDump();
+    test_ret += test_xmlCatalogGetDefaults();
+    test_ret += test_xmlCatalogIsEmpty();
+    test_ret += test_xmlCatalogLocalResolve();
+    test_ret += test_xmlCatalogLocalResolveURI();
+    test_ret += test_xmlCatalogRemove();
+    test_ret += test_xmlCatalogResolve();
+    test_ret += test_xmlCatalogResolvePublic();
+    test_ret += test_xmlCatalogResolveSystem();
+    test_ret += test_xmlCatalogResolveURI();
+    test_ret += test_xmlCatalogSetDefaultPrefer();
+    test_ret += test_xmlCatalogSetDefaults();
+    test_ret += test_xmlConvertSGMLCatalog();
+    test_ret += test_xmlInitializeCatalog();
+    test_ret += test_xmlLoadACatalog();
+    test_ret += test_xmlLoadCatalog();
+    test_ret += test_xmlLoadCatalogs();
+    test_ret += test_xmlLoadSGMLSuperCatalog();
+    test_ret += test_xmlNewCatalog();
+    test_ret += test_xmlParseCatalogFile();
+
+    if (test_ret != 0)
+	printf("Module catalog: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+#define gen_nb_const_xmlChRangeGroup_ptr 1
+static xmlChRangeGroup * gen_const_xmlChRangeGroup_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlChRangeGroup_ptr(int no ATTRIBUTE_UNUSED, const xmlChRangeGroup * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCharInRange(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int val; /* character to be validated */
+    int n_val;
+    xmlChRangeGroup * rptr; /* pointer to range to be used to validate */
+    int n_rptr;
+
+    for (n_val = 0;n_val < gen_nb_unsigned_int;n_val++) {
+    for (n_rptr = 0;n_rptr < gen_nb_const_xmlChRangeGroup_ptr;n_rptr++) {
+        mem_base = xmlMemBlocks();
+        val = gen_unsigned_int(n_val, 0);
+        rptr = gen_const_xmlChRangeGroup_ptr(n_rptr, 1);
+
+        ret_val = xmlCharInRange(val, (const xmlChRangeGroup *)rptr);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_val, val, 0);
+        des_const_xmlChRangeGroup_ptr(n_rptr, (const xmlChRangeGroup *)rptr, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharInRange",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf(" %d", n_rptr);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsBaseChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsBaseChar(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsBaseChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsBlank(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsBlank(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsBlank",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsChar(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsCombining(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsCombining(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsCombining",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsDigit(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsDigit(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsDigit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsExtender(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsExtender(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsExtender",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsIdeographic(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsIdeographic(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsIdeographic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsPubidChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned int ch; /* character to validate */
+    int n_ch;
+
+    for (n_ch = 0;n_ch < gen_nb_unsigned_int;n_ch++) {
+        mem_base = xmlMemBlocks();
+        ch = gen_unsigned_int(n_ch, 0);
+
+        ret_val = xmlIsPubidChar(ch);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_int(n_ch, ch, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsPubidChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ch);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_chvalid(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing chvalid : 9 of 9 functions ...\n");
+    test_ret += test_xmlCharInRange();
+    test_ret += test_xmlIsBaseChar();
+    test_ret += test_xmlIsBlank();
+    test_ret += test_xmlIsChar();
+    test_ret += test_xmlIsCombining();
+    test_ret += test_xmlIsDigit();
+    test_ret += test_xmlIsExtender();
+    test_ret += test_xmlIsIdeographic();
+    test_ret += test_xmlIsPubidChar();
+
+    if (test_ret != 0)
+	printf("Module chvalid: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlBoolToText(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    const char * ret_val;
+    int boolval; /* a bool to turn into text */
+    int n_boolval;
+
+    for (n_boolval = 0;n_boolval < gen_nb_int;n_boolval++) {
+        mem_base = xmlMemBlocks();
+        boolval = gen_int(n_boolval, 0);
+
+        ret_val = xmlBoolToText(boolval);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_int(n_boolval, boolval, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBoolToText",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_boolval);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugCheckDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    int ret_val;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlDebugCheckDocument(output, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugCheckDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpAttr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlAttrPtr attr; /* the attribute */
+    int n_attr;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        attr = gen_xmlAttrPtr(n_attr, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlDebugDumpAttr(output, attr, depth);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlAttrPtr(n_attr, attr, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpAttr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_attr);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpAttrList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlAttrPtr attr; /* the attribute list */
+    int n_attr;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        attr = gen_xmlAttrPtr(n_attr, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlDebugDumpAttrList(output, attr, depth);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlAttrPtr(n_attr, attr, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpAttrList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_attr);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlDtdPtr dtd; /* the DTD */
+    int n_dtd;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        dtd = gen_xmlDtdPtr(n_dtd, 1);
+
+        xmlDebugDumpDTD(output, dtd);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlDtdPtr(n_dtd, dtd, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_dtd);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        xmlDebugDumpDocument(output, doc);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpDocumentHead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        xmlDebugDumpDocumentHead(output, doc);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpDocumentHead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpEntities(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        xmlDebugDumpEntities(output, doc);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlDebugDumpNode(output, node, depth);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_node);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpNodeList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlNodePtr node; /* the node list */
+    int n_node;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlDebugDumpNodeList(output, node, depth);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_node);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpOneNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlDebugDumpOneNode(output, node, depth);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpOneNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_node);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDebugDumpString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlChar * str; /* the string */
+    int n_str;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+
+        xmlDebugDumpString(output, (const xmlChar *)str);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDebugDumpString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLsCountNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node to count */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlLsCountNode(node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLsCountNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLsOneNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlNodePtr node; /* the node to dump */
+    int n_node;
+
+    for (n_output = 0;n_output < gen_nb_debug_FILE_ptr;n_output++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        output = gen_debug_FILE_ptr(n_output, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        xmlLsOneNode(output, node);
+        call_tests++;
+        des_debug_FILE_ptr(n_output, output, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLsOneNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_char_ptr 1
+static char * gen_char_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_char_ptr(int no ATTRIBUTE_UNUSED, char * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlShell(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellBase(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * arg; /* unused */
+    int n_arg;
+    xmlNodePtr node; /* a node */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_arg = 0;n_arg < gen_nb_char_ptr;n_arg++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        arg = gen_char_ptr(n_arg, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellBase(ctxt, arg, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_arg, arg, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellBase",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_arg);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellCat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * arg; /* unused */
+    int n_arg;
+    xmlNodePtr node; /* a node */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_arg = 0;n_arg < gen_nb_char_ptr;n_arg++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        arg = gen_char_ptr(n_arg, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellCat(ctxt, arg, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_arg, arg, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellCat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_arg);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellDir(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * arg; /* unused */
+    int n_arg;
+    xmlNodePtr node; /* a node */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_arg = 0;n_arg < gen_nb_char_ptr;n_arg++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        arg = gen_char_ptr(n_arg, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellDir(ctxt, arg, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_arg, arg, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellDir",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_arg);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellDu(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * arg; /* unused */
+    int n_arg;
+    xmlNodePtr tree; /* a node defining a subtree */
+    int n_tree;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_arg = 0;n_arg < gen_nb_char_ptr;n_arg++) {
+    for (n_tree = 0;n_tree < gen_nb_xmlNodePtr;n_tree++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        arg = gen_char_ptr(n_arg, 1);
+        tree = gen_xmlNodePtr(n_tree, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellDu(ctxt, arg, tree, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_arg, arg, 1);
+        des_xmlNodePtr(n_tree, tree, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellDu",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_arg);
+            printf(" %d", n_tree);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * arg; /* unused */
+    int n_arg;
+    xmlNodePtr node; /* a node */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_arg = 0;n_arg < gen_nb_char_ptr;n_arg++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        arg = gen_char_ptr(n_arg, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellList(ctxt, arg, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_arg, arg, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_arg);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellLoad(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * filename; /* the file name */
+    int n_filename;
+    xmlNodePtr node; /* unused */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_char_ptr;n_filename++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        filename = gen_char_ptr(n_filename, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellLoad(ctxt, filename, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_filename, filename, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellLoad",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellPrintXPathResult(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr list; /* a valid result generated by an xpath evaluation */
+    int n_list;
+
+    for (n_list = 0;n_list < gen_nb_xmlXPathObjectPtr;n_list++) {
+        mem_base = xmlMemBlocks();
+        list = gen_xmlXPathObjectPtr(n_list, 0);
+
+        xmlShellPrintXPathResult(list);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_list, list, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellPrintXPathResult",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_list);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellPwd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * buffer; /* the output buffer */
+    int n_buffer;
+    xmlNodePtr node; /* a node */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_buffer = 0;n_buffer < gen_nb_char_ptr;n_buffer++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        buffer = gen_char_ptr(n_buffer, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellPwd(ctxt, buffer, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_buffer, buffer, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellPwd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_buffer);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellSave(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * filename; /* the file name (optional) */
+    int n_filename;
+    xmlNodePtr node; /* unused */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_char_ptr;n_filename++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        filename = gen_char_ptr(n_filename, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellSave(ctxt, filename, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_filename, filename, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellSave",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellValidate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * dtd; /* the DTD URI (optional) */
+    int n_dtd;
+    xmlNodePtr node; /* unused */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_dtd = 0;n_dtd < gen_nb_char_ptr;n_dtd++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        dtd = gen_char_ptr(n_dtd, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellValidate(ctxt, dtd, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_dtd, dtd, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellValidate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_dtd);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlShellWrite(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_DEBUG_ENABLED) && defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlShellCtxtPtr ctxt; /* the shell context */
+    int n_ctxt;
+    char * filename; /* the file name */
+    int n_filename;
+    xmlNodePtr node; /* a node in the tree */
+    int n_node;
+    xmlNodePtr node2; /* unused */
+    int n_node2;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlShellCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_char_ptr;n_filename++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlShellCtxtPtr(n_ctxt, 0);
+        filename = gen_char_ptr(n_filename, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        node2 = gen_xmlNodePtr(n_node2, 3);
+
+        ret_val = xmlShellWrite(ctxt, filename, node, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlShellCtxtPtr(n_ctxt, ctxt, 0);
+        des_char_ptr(n_filename, filename, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr(n_node2, node2, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlShellWrite",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf(" %d", n_node);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_debugXML(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing debugXML : 25 of 28 functions ...\n");
+    test_ret += test_xmlBoolToText();
+    test_ret += test_xmlDebugCheckDocument();
+    test_ret += test_xmlDebugDumpAttr();
+    test_ret += test_xmlDebugDumpAttrList();
+    test_ret += test_xmlDebugDumpDTD();
+    test_ret += test_xmlDebugDumpDocument();
+    test_ret += test_xmlDebugDumpDocumentHead();
+    test_ret += test_xmlDebugDumpEntities();
+    test_ret += test_xmlDebugDumpNode();
+    test_ret += test_xmlDebugDumpNodeList();
+    test_ret += test_xmlDebugDumpOneNode();
+    test_ret += test_xmlDebugDumpString();
+    test_ret += test_xmlLsCountNode();
+    test_ret += test_xmlLsOneNode();
+    test_ret += test_xmlShell();
+    test_ret += test_xmlShellBase();
+    test_ret += test_xmlShellCat();
+    test_ret += test_xmlShellDir();
+    test_ret += test_xmlShellDu();
+    test_ret += test_xmlShellList();
+    test_ret += test_xmlShellLoad();
+    test_ret += test_xmlShellPrintXPathResult();
+    test_ret += test_xmlShellPwd();
+    test_ret += test_xmlShellSave();
+    test_ret += test_xmlShellValidate();
+    test_ret += test_xmlShellWrite();
+
+    if (test_ret != 0)
+	printf("Module debugXML: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlDictCleanup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlDictCleanup();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictCreate(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDictPtr ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlDictCreate();
+        desret_xmlDictPtr(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictCreate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictCreateSub(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDictPtr ret_val;
+    xmlDictPtr sub; /* an existing dictionnary */
+    int n_sub;
+
+    for (n_sub = 0;n_sub < gen_nb_xmlDictPtr;n_sub++) {
+        mem_base = xmlMemBlocks();
+        sub = gen_xmlDictPtr(n_sub, 0);
+
+        ret_val = xmlDictCreateSub(sub);
+        desret_xmlDictPtr(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_sub, sub, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictCreateSub",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sub);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictExists(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    int len; /* the length of the name, if -1 it is recomputed */
+    int n_len;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlDictExists(dict, (const xmlChar *)name, len);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictExists",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf(" %d", n_name);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictLookup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    int len; /* the length of the name, if -1 it is recomputed */
+    int n_len;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlDictLookup(dict, (const xmlChar *)name, len);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf(" %d", n_name);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictOwns(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+    xmlChar * str; /* the string */
+    int n_str;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+
+        ret_val = xmlDictOwns(dict, (const xmlChar *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictOwns",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictQLookup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+    xmlChar * prefix; /* the prefix */
+    int n_prefix;
+    xmlChar * name; /* the name */
+    int n_name;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+
+        ret_val = xmlDictQLookup(dict, (const xmlChar *)prefix, (const xmlChar *)name);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictQLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictReference(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+
+        ret_val = xmlDictReference(dict);
+        xmlDictFree(dict);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictReference",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDictSize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDictPtr dict; /* the dictionnary */
+    int n_dict;
+
+    for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
+        mem_base = xmlMemBlocks();
+        dict = gen_xmlDictPtr(n_dict, 0);
+
+        ret_val = xmlDictSize(dict);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDictPtr(n_dict, dict, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDictSize",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dict);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_dict(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing dict : 9 of 10 functions ...\n");
+    test_ret += test_xmlDictCleanup();
+    test_ret += test_xmlDictCreate();
+    test_ret += test_xmlDictCreateSub();
+    test_ret += test_xmlDictExists();
+    test_ret += test_xmlDictLookup();
+    test_ret += test_xmlDictOwns();
+    test_ret += test_xmlDictQLookup();
+    test_ret += test_xmlDictReference();
+    test_ret += test_xmlDictSize();
+
+    if (test_ret != 0)
+	printf("Module dict: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_UTF8Toisolat1(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef LIBXML_OUTPUT_ENABLED
+    int mem_base;
+    int ret_val;
+    unsigned char * out; /* a pointer to an array of bytes to store the result */
+    int n_out;
+    int * outlen; /* the length of @out */
+    int n_outlen;
+    unsigned char * in; /* a pointer to an array of UTF-8 chars */
+    int n_in;
+    int * inlen; /* the length of @in */
+    int n_inlen;
+
+    for (n_out = 0;n_out < gen_nb_unsigned_char_ptr;n_out++) {
+    for (n_outlen = 0;n_outlen < gen_nb_int_ptr;n_outlen++) {
+    for (n_in = 0;n_in < gen_nb_const_unsigned_char_ptr;n_in++) {
+    for (n_inlen = 0;n_inlen < gen_nb_int_ptr;n_inlen++) {
+        mem_base = xmlMemBlocks();
+        out = gen_unsigned_char_ptr(n_out, 0);
+        outlen = gen_int_ptr(n_outlen, 1);
+        in = gen_const_unsigned_char_ptr(n_in, 2);
+        inlen = gen_int_ptr(n_inlen, 3);
+
+        ret_val = UTF8Toisolat1(out, outlen, (const unsigned char *)in, inlen);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_char_ptr(n_out, out, 0);
+        des_int_ptr(n_outlen, outlen, 1);
+        des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+        des_int_ptr(n_inlen, inlen, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in UTF8Toisolat1",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_outlen);
+            printf(" %d", n_in);
+            printf(" %d", n_inlen);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_isolat1ToUTF8(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned char * out; /* a pointer to an array of bytes to store the result */
+    int n_out;
+    int * outlen; /* the length of @out */
+    int n_outlen;
+    unsigned char * in; /* a pointer to an array of ISO Latin 1 chars */
+    int n_in;
+    int * inlen; /* the length of @in */
+    int n_inlen;
+
+    for (n_out = 0;n_out < gen_nb_unsigned_char_ptr;n_out++) {
+    for (n_outlen = 0;n_outlen < gen_nb_int_ptr;n_outlen++) {
+    for (n_in = 0;n_in < gen_nb_const_unsigned_char_ptr;n_in++) {
+    for (n_inlen = 0;n_inlen < gen_nb_int_ptr;n_inlen++) {
+        mem_base = xmlMemBlocks();
+        out = gen_unsigned_char_ptr(n_out, 0);
+        outlen = gen_int_ptr(n_outlen, 1);
+        in = gen_const_unsigned_char_ptr(n_in, 2);
+        inlen = gen_int_ptr(n_inlen, 3);
+
+        ret_val = isolat1ToUTF8(out, outlen, (const unsigned char *)in, inlen);
+        desret_int(ret_val);
+        call_tests++;
+        des_unsigned_char_ptr(n_out, out, 0);
+        des_int_ptr(n_outlen, outlen, 1);
+        des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 2);
+        des_int_ptr(n_inlen, inlen, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in isolat1ToUTF8",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_outlen);
+            printf(" %d", n_in);
+            printf(" %d", n_inlen);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddEncodingAlias(void) {
+    int test_ret = 0;
+
+    int ret_val;
+    char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
+    int n_name;
+    char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+    int n_alias;
+
+    for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
+    for (n_alias = 0;n_alias < gen_nb_const_char_ptr;n_alias++) {
+        name = gen_const_char_ptr(n_name, 0);
+        alias = gen_const_char_ptr(n_alias, 1);
+
+        ret_val = xmlAddEncodingAlias((const char *)name, (const char *)alias);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_name, (const char *)name, 0);
+        des_const_char_ptr(n_alias, (const char *)alias, 1);
+        xmlResetLastError();
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlCharEncodingHandler_ptr 1
+static xmlCharEncodingHandler * gen_xmlCharEncodingHandler_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlCharEncodingHandler_ptr(int no ATTRIBUTE_UNUSED, xmlCharEncodingHandler * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCharEncCloseFunc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    int n_handler;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandler_ptr;n_handler++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlCharEncodingHandler_ptr(n_handler, 0);
+
+        ret_val = xmlCharEncCloseFunc(handler);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCharEncodingHandler_ptr(n_handler, handler, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharEncCloseFunc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCharEncFirstLine(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    int n_handler;
+    xmlBufferPtr out; /* an xmlBuffer for the output. */
+    int n_out;
+    xmlBufferPtr in; /* an xmlBuffer for the input */
+    int n_in;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandler_ptr;n_handler++) {
+    for (n_out = 0;n_out < gen_nb_xmlBufferPtr;n_out++) {
+    for (n_in = 0;n_in < gen_nb_xmlBufferPtr;n_in++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlCharEncodingHandler_ptr(n_handler, 0);
+        out = gen_xmlBufferPtr(n_out, 1);
+        in = gen_xmlBufferPtr(n_in, 2);
+
+        ret_val = xmlCharEncFirstLine(handler, out, in);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCharEncodingHandler_ptr(n_handler, handler, 0);
+        des_xmlBufferPtr(n_out, out, 1);
+        des_xmlBufferPtr(n_in, in, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharEncFirstLine",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf(" %d", n_out);
+            printf(" %d", n_in);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCharEncInFunc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlCharEncodingHandler * handler; /* char encoding transformation data structure */
+    int n_handler;
+    xmlBufferPtr out; /* an xmlBuffer for the output. */
+    int n_out;
+    xmlBufferPtr in; /* an xmlBuffer for the input */
+    int n_in;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandler_ptr;n_handler++) {
+    for (n_out = 0;n_out < gen_nb_xmlBufferPtr;n_out++) {
+    for (n_in = 0;n_in < gen_nb_xmlBufferPtr;n_in++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlCharEncodingHandler_ptr(n_handler, 0);
+        out = gen_xmlBufferPtr(n_out, 1);
+        in = gen_xmlBufferPtr(n_in, 2);
+
+        ret_val = xmlCharEncInFunc(handler, out, in);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCharEncodingHandler_ptr(n_handler, handler, 0);
+        des_xmlBufferPtr(n_out, out, 1);
+        des_xmlBufferPtr(n_in, in, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharEncInFunc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf(" %d", n_out);
+            printf(" %d", n_in);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCharEncOutFunc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    int n_handler;
+    xmlBufferPtr out; /* an xmlBuffer for the output. */
+    int n_out;
+    xmlBufferPtr in; /* an xmlBuffer for the input */
+    int n_in;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandler_ptr;n_handler++) {
+    for (n_out = 0;n_out < gen_nb_xmlBufferPtr;n_out++) {
+    for (n_in = 0;n_in < gen_nb_xmlBufferPtr;n_in++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlCharEncodingHandler_ptr(n_handler, 0);
+        out = gen_xmlBufferPtr(n_out, 1);
+        in = gen_xmlBufferPtr(n_in, 2);
+
+        ret_val = xmlCharEncOutFunc(handler, out, in);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlCharEncodingHandler_ptr(n_handler, handler, 0);
+        des_xmlBufferPtr(n_out, out, 1);
+        des_xmlBufferPtr(n_in, in, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharEncOutFunc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf(" %d", n_out);
+            printf(" %d", n_in);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCleanupCharEncodingHandlers(void) {
+    int test_ret = 0;
+
+
+
+        xmlCleanupCharEncodingHandlers();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCleanupEncodingAliases(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlCleanupEncodingAliases();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCleanupEncodingAliases",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDelEncodingAlias(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+    int n_alias;
+
+    for (n_alias = 0;n_alias < gen_nb_const_char_ptr;n_alias++) {
+        mem_base = xmlMemBlocks();
+        alias = gen_const_char_ptr(n_alias, 0);
+
+        ret_val = xmlDelEncodingAlias((const char *)alias);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_alias, (const char *)alias, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDelEncodingAlias",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_alias);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDetectCharEncoding(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlCharEncoding ret_val;
+    unsigned char * in; /* a pointer to the first bytes of the XML entity, must be at least 2 bytes long (at least 4 if encoding is UTF4 variant). */
+    int n_in;
+    int len; /* pointer to the length of the buffer */
+    int n_len;
+
+    for (n_in = 0;n_in < gen_nb_const_unsigned_char_ptr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        in = gen_const_unsigned_char_ptr(n_in, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlDetectCharEncoding((const unsigned char *)in, len);
+        desret_xmlCharEncoding(ret_val);
+        call_tests++;
+        des_const_unsigned_char_ptr(n_in, (const unsigned char *)in, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDetectCharEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFindCharEncodingHandler(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetCharEncodingHandler(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetCharEncodingName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const char * ret_val;
+    xmlCharEncoding enc; /* the encoding */
+    int n_enc;
+
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        enc = gen_xmlCharEncoding(n_enc, 0);
+
+        ret_val = xmlGetCharEncodingName(enc);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_xmlCharEncoding(n_enc, enc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetCharEncodingName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetEncodingAlias(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const char * ret_val;
+    char * alias; /* the alias name as parsed, in UTF-8 format (ASCII actually) */
+    int n_alias;
+
+    for (n_alias = 0;n_alias < gen_nb_const_char_ptr;n_alias++) {
+        mem_base = xmlMemBlocks();
+        alias = gen_const_char_ptr(n_alias, 0);
+
+        ret_val = xmlGetEncodingAlias((const char *)alias);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_alias, (const char *)alias, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetEncodingAlias",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_alias);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitCharEncodingHandlers(void) {
+    int test_ret = 0;
+
+
+
+        xmlInitCharEncodingHandlers();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewCharEncodingHandler(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseCharEncoding(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlCharEncoding ret_val;
+    char * name; /* the encoding name as parsed, in UTF-8 format (ASCII actually) */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_char_ptr(n_name, 0);
+
+        ret_val = xmlParseCharEncoding((const char *)name);
+        desret_xmlCharEncoding(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_name, (const char *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseCharEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlCharEncodingHandlerPtr 1
+static xmlCharEncodingHandlerPtr gen_xmlCharEncodingHandlerPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlCharEncodingHandlerPtr(int no ATTRIBUTE_UNUSED, xmlCharEncodingHandlerPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlRegisterCharEncodingHandler(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlCharEncodingHandlerPtr handler; /* the xmlCharEncodingHandlerPtr handler block */
+    int n_handler;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandlerPtr;n_handler++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlCharEncodingHandlerPtr(n_handler, 0);
+
+        xmlRegisterCharEncodingHandler(handler);
+        call_tests++;
+        des_xmlCharEncodingHandlerPtr(n_handler, handler, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegisterCharEncodingHandler",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_encoding(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing encoding : 16 of 19 functions ...\n");
+    test_ret += test_UTF8Toisolat1();
+    test_ret += test_isolat1ToUTF8();
+    test_ret += test_xmlAddEncodingAlias();
+    test_ret += test_xmlCharEncCloseFunc();
+    test_ret += test_xmlCharEncFirstLine();
+    test_ret += test_xmlCharEncInFunc();
+    test_ret += test_xmlCharEncOutFunc();
+    test_ret += test_xmlCleanupCharEncodingHandlers();
+    test_ret += test_xmlCleanupEncodingAliases();
+    test_ret += test_xmlDelEncodingAlias();
+    test_ret += test_xmlDetectCharEncoding();
+    test_ret += test_xmlFindCharEncodingHandler();
+    test_ret += test_xmlGetCharEncodingHandler();
+    test_ret += test_xmlGetCharEncodingName();
+    test_ret += test_xmlGetEncodingAlias();
+    test_ret += test_xmlInitCharEncodingHandlers();
+    test_ret += test_xmlNewCharEncodingHandler();
+    test_ret += test_xmlParseCharEncoding();
+    test_ret += test_xmlRegisterCharEncodingHandler();
+
+    if (test_ret != 0)
+	printf("Module encoding: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlAddDocEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+    int type; /* the entity type XML_xxx_yyy_ENTITY */
+    int n_type;
+    xmlChar * ExternalID; /* the entity external ID if available */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the entity system ID if available */
+    int n_SystemID;
+    xmlChar * content; /* the entity content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_int(n_type, 2);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 3);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
+        content = gen_const_xmlChar_ptr(n_content, 5);
+
+        ret_val = xmlAddDocEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_type, type, 2);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddDocEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddDtdEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+    int type; /* the entity type XML_xxx_yyy_ENTITY */
+    int n_type;
+    xmlChar * ExternalID; /* the entity external ID if available */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the entity system ID if available */
+    int n_SystemID;
+    xmlChar * content; /* the entity content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_int(n_type, 2);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 3);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
+        content = gen_const_xmlChar_ptr(n_content, 5);
+
+        ret_val = xmlAddDtdEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_type, type, 2);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddDtdEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCleanupPredefinedEntities(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef LIBXML_LEGACY_ENABLED
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlCleanupPredefinedEntities();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCleanupPredefinedEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlEntitiesTablePtr 1
+static xmlEntitiesTablePtr gen_xmlEntitiesTablePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlEntitiesTablePtr(int no ATTRIBUTE_UNUSED, xmlEntitiesTablePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCopyEntitiesTable(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateEntitiesTable(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlDumpEntitiesTable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* An XML buffer. */
+    int n_buf;
+    xmlEntitiesTablePtr table; /* An entity table */
+    int n_table;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_table = 0;n_table < gen_nb_xmlEntitiesTablePtr;n_table++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        table = gen_xmlEntitiesTablePtr(n_table, 1);
+
+        xmlDumpEntitiesTable(buf, table);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlEntitiesTablePtr(n_table, table, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpEntitiesTable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_table);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlEntityPtr 1
+static xmlEntityPtr gen_xmlEntityPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlEntityPtr(int no ATTRIBUTE_UNUSED, xmlEntityPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlDumpEntityDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* An XML buffer. */
+    int n_buf;
+    xmlEntityPtr ent; /* An entity table */
+    int n_ent;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_ent = 0;n_ent < gen_nb_xmlEntityPtr;n_ent++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        ent = gen_xmlEntityPtr(n_ent, 1);
+
+        xmlDumpEntityDecl(buf, ent);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlEntityPtr(n_ent, ent, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpEntityDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_ent);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlEncodeEntitiesReentrant(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document containing the string */
+    int n_doc;
+    xmlChar * input; /* A string to convert to XML. */
+    int n_input;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_input = 0;n_input < gen_nb_const_xmlChar_ptr;n_input++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        input = gen_const_xmlChar_ptr(n_input, 1);
+
+        ret_val = xmlEncodeEntitiesReentrant(doc, (const xmlChar *)input);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_input, (const xmlChar *)input, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlEncodeEntitiesReentrant",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_input);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlEncodeSpecialChars(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document containing the string */
+    int n_doc;
+    xmlChar * input; /* A string to convert to XML. */
+    int n_input;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_input = 0;n_input < gen_nb_const_xmlChar_ptr;n_input++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        input = gen_const_xmlChar_ptr(n_input, 1);
+
+        ret_val = xmlEncodeSpecialChars(doc, (const xmlChar *)input);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_input, (const xmlChar *)input, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlEncodeSpecialChars",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_input);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDocEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document referencing the entity */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetDocEntity(doc, (const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDocEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document referencing the entity */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetDtdEntity(doc, (const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDtdEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetParameterEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document referencing the entity */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetParameterEntity(doc, (const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetParameterEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetPredefinedEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlChar * name; /* the entity name */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+
+        ret_val = xmlGetPredefinedEntity((const xmlChar *)name);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetPredefinedEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitializePredefinedEntities(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef LIBXML_LEGACY_ENABLED
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlInitializePredefinedEntities();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlInitializePredefinedEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlEntityPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the entity name */
+    int n_name;
+    int type; /* the entity type XML_xxx_yyy_ENTITY */
+    int n_type;
+    xmlChar * ExternalID; /* the entity external ID if available */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the entity system ID if available */
+    int n_SystemID;
+    xmlChar * content; /* the entity content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_int(n_type, 2);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 3);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 4);
+        content = gen_const_xmlChar_ptr(n_content, 5);
+
+        ret_val = xmlNewEntity(doc, (const xmlChar *)name, type, (const xmlChar *)ExternalID, (const xmlChar *)SystemID, (const xmlChar *)content);
+        desret_xmlEntityPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_int(n_type, type, 2);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 3);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 4);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_entities(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing entities : 13 of 17 functions ...\n");
+    test_ret += test_xmlAddDocEntity();
+    test_ret += test_xmlAddDtdEntity();
+    test_ret += test_xmlCleanupPredefinedEntities();
+    test_ret += test_xmlCopyEntitiesTable();
+    test_ret += test_xmlCreateEntitiesTable();
+    test_ret += test_xmlDumpEntitiesTable();
+    test_ret += test_xmlDumpEntityDecl();
+    test_ret += test_xmlEncodeEntitiesReentrant();
+    test_ret += test_xmlEncodeSpecialChars();
+    test_ret += test_xmlGetDocEntity();
+    test_ret += test_xmlGetDtdEntity();
+    test_ret += test_xmlGetParameterEntity();
+    test_ret += test_xmlGetPredefinedEntity();
+    test_ret += test_xmlInitializePredefinedEntities();
+    test_ret += test_xmlNewEntity();
+
+    if (test_ret != 0)
+	printf("Module entities: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlHashAddEntry(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        userdata = gen_userdata(n_userdata, 2);
+
+        ret_val = xmlHashAddEntry(table, (const xmlChar *)name, userdata);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_userdata(n_userdata, userdata, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashAddEntry",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_userdata);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashAddEntry2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        userdata = gen_userdata(n_userdata, 3);
+
+        ret_val = xmlHashAddEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, userdata);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_userdata(n_userdata, userdata, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashAddEntry2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_userdata);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashAddEntry3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlChar * name3; /* a third name of the userdata */
+    int n_name3;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        name3 = gen_const_xmlChar_ptr(n_name3, 3);
+        userdata = gen_userdata(n_userdata, 4);
+
+        ret_val = xmlHashAddEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, userdata);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
+        des_userdata(n_userdata, userdata, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashAddEntry3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_name3);
+            printf(" %d", n_userdata);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashCopy(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashCreate(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashCreateDict(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashLookup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlHashLookup(table, (const xmlChar *)name);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashLookup2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+
+        ret_val = xmlHashLookup2(table, (const xmlChar *)name, (const xmlChar *)name2);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashLookup2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashLookup3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlChar * name3; /* a third name of the userdata */
+    int n_name3;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        name3 = gen_const_xmlChar_ptr(n_name3, 3);
+
+        ret_val = xmlHashLookup3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashLookup3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_name3);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashQLookup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * prefix; /* the prefix of the userdata */
+    int n_prefix;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+
+        ret_val = xmlHashQLookup(table, (const xmlChar *)prefix, (const xmlChar *)name);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashQLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashQLookup2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * prefix; /* the prefix of the userdata */
+    int n_prefix;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * prefix2; /* the second prefix of the userdata */
+    int n_prefix2;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix2 = 0;n_prefix2 < gen_nb_const_xmlChar_ptr;n_prefix2++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        prefix2 = gen_const_xmlChar_ptr(n_prefix2, 3);
+        name2 = gen_const_xmlChar_ptr(n_name2, 4);
+
+        ret_val = xmlHashQLookup2(table, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashQLookup2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_prefix2);
+            printf(" %d", n_name2);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashQLookup3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * prefix; /* the prefix of the userdata */
+    int n_prefix;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * prefix2; /* the second prefix of the userdata */
+    int n_prefix2;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlChar * prefix3; /* the third prefix of the userdata */
+    int n_prefix3;
+    xmlChar * name3; /* a third name of the userdata */
+    int n_name3;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix2 = 0;n_prefix2 < gen_nb_const_xmlChar_ptr;n_prefix2++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_prefix3 = 0;n_prefix3 < gen_nb_const_xmlChar_ptr;n_prefix3++) {
+    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        prefix2 = gen_const_xmlChar_ptr(n_prefix2, 3);
+        name2 = gen_const_xmlChar_ptr(n_name2, 4);
+        prefix3 = gen_const_xmlChar_ptr(n_prefix3, 5);
+        name3 = gen_const_xmlChar_ptr(n_name3, 6);
+
+        ret_val = xmlHashQLookup3(table, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2, (const xmlChar *)prefix3, (const xmlChar *)name3);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 4);
+        des_const_xmlChar_ptr(n_prefix3, (const xmlChar *)prefix3, 5);
+        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashQLookup3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_prefix2);
+            printf(" %d", n_name2);
+            printf(" %d", n_prefix3);
+            printf(" %d", n_name3);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashRemoveEntry(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        f = gen_xmlHashDeallocator(n_f, 2);
+
+        ret_val = xmlHashRemoveEntry(table, (const xmlChar *)name, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_xmlHashDeallocator(n_f, f, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashRemoveEntry",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashRemoveEntry2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        f = gen_xmlHashDeallocator(n_f, 3);
+
+        ret_val = xmlHashRemoveEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_xmlHashDeallocator(n_f, f, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashRemoveEntry2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashRemoveEntry3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlChar * name3; /* a third name of the userdata */
+    int n_name3;
+    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        name3 = gen_const_xmlChar_ptr(n_name3, 3);
+        f = gen_xmlHashDeallocator(n_f, 4);
+
+        ret_val = xmlHashRemoveEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
+        des_xmlHashDeallocator(n_f, f, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashRemoveEntry3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_name3);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashScan(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashScan3(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashScanFull(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashScanFull3(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashSize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+
+        ret_val = xmlHashSize(table);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashSize",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashUpdateEntry(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        userdata = gen_userdata(n_userdata, 2);
+        f = gen_xmlHashDeallocator(n_f, 3);
+
+        ret_val = xmlHashUpdateEntry(table, (const xmlChar *)name, userdata, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_userdata(n_userdata, userdata, 2);
+        des_xmlHashDeallocator(n_f, f, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashUpdateEntry",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_userdata);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashUpdateEntry2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        userdata = gen_userdata(n_userdata, 3);
+        f = gen_xmlHashDeallocator(n_f, 4);
+
+        ret_val = xmlHashUpdateEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, userdata, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_userdata(n_userdata, userdata, 3);
+        des_xmlHashDeallocator(n_f, f, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashUpdateEntry2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_userdata);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHashUpdateEntry3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlHashTablePtr table; /* the hash table */
+    int n_table;
+    xmlChar * name; /* the name of the userdata */
+    int n_name;
+    xmlChar * name2; /* a second name of the userdata */
+    int n_name2;
+    xmlChar * name3; /* a third name of the userdata */
+    int n_name3;
+    void * userdata; /* a pointer to the userdata */
+    int n_userdata;
+    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
+    int n_f;
+
+    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
+    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
+    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+        mem_base = xmlMemBlocks();
+        table = gen_xmlHashTablePtr(n_table, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        name2 = gen_const_xmlChar_ptr(n_name2, 2);
+        name3 = gen_const_xmlChar_ptr(n_name3, 3);
+        userdata = gen_userdata(n_userdata, 4);
+        f = gen_xmlHashDeallocator(n_f, 5);
+
+        ret_val = xmlHashUpdateEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, userdata, f);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlHashTablePtr(n_table, table, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
+        des_userdata(n_userdata, userdata, 4);
+        des_xmlHashDeallocator(n_f, f, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHashUpdateEntry3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_table);
+            printf(" %d", n_name);
+            printf(" %d", n_name2);
+            printf(" %d", n_name3);
+            printf(" %d", n_userdata);
+            printf(" %d", n_f);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_hash(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing hash : 16 of 24 functions ...\n");
+    test_ret += test_xmlHashAddEntry();
+    test_ret += test_xmlHashAddEntry2();
+    test_ret += test_xmlHashAddEntry3();
+    test_ret += test_xmlHashCopy();
+    test_ret += test_xmlHashCreate();
+    test_ret += test_xmlHashCreateDict();
+    test_ret += test_xmlHashLookup();
+    test_ret += test_xmlHashLookup2();
+    test_ret += test_xmlHashLookup3();
+    test_ret += test_xmlHashQLookup();
+    test_ret += test_xmlHashQLookup2();
+    test_ret += test_xmlHashQLookup3();
+    test_ret += test_xmlHashRemoveEntry();
+    test_ret += test_xmlHashRemoveEntry2();
+    test_ret += test_xmlHashRemoveEntry3();
+    test_ret += test_xmlHashScan();
+    test_ret += test_xmlHashScan3();
+    test_ret += test_xmlHashScanFull();
+    test_ret += test_xmlHashScanFull3();
+    test_ret += test_xmlHashSize();
+    test_ret += test_xmlHashUpdateEntry();
+    test_ret += test_xmlHashUpdateEntry2();
+    test_ret += test_xmlHashUpdateEntry3();
+
+    if (test_ret != 0)
+	printf("Module hash: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+#define gen_nb_xmlLinkPtr 1
+static xmlLinkPtr gen_xmlLinkPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlLinkPtr(int no ATTRIBUTE_UNUSED, xmlLinkPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlLinkGetData(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlLinkPtr lk; /* a link */
+    int n_lk;
+
+    for (n_lk = 0;n_lk < gen_nb_xmlLinkPtr;n_lk++) {
+        mem_base = xmlMemBlocks();
+        lk = gen_xmlLinkPtr(n_lk, 0);
+
+        ret_val = xmlLinkGetData(lk);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlLinkPtr(n_lk, lk, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLinkGetData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_lk);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListAppend(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* the data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListAppend(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListAppend",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListClear(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        xmlListClear(l);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListClear",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_xmlListPtr 1
+static xmlListPtr gen_const_xmlListPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlListPtr(int no ATTRIBUTE_UNUSED, const xmlListPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlListCopy(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr cur; /* the new list */
+    int n_cur;
+    xmlListPtr old; /* the old list */
+    int n_old;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlListPtr;n_cur++) {
+    for (n_old = 0;n_old < gen_nb_const_xmlListPtr;n_old++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlListPtr(n_cur, 0);
+        old = gen_const_xmlListPtr(n_old, 1);
+
+        ret_val = xmlListCopy(cur, (const xmlListPtr)old);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_cur, cur, 0);
+        des_const_xmlListPtr(n_old, (const xmlListPtr)old, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListCopy",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_old);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListCreate(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlListDup(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlListEmpty(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        ret_val = xmlListEmpty(l);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListEmpty",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListEnd(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlListFront(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlListInsert(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* the data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListInsert(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListInsert",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListMerge(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l1; /* the original list */
+    int n_l1;
+    xmlListPtr l2; /* the new list */
+    int n_l2;
+
+    for (n_l1 = 0;n_l1 < gen_nb_xmlListPtr;n_l1++) {
+    for (n_l2 = 0;n_l2 < gen_nb_xmlListPtr;n_l2++) {
+        mem_base = xmlMemBlocks();
+        l1 = gen_xmlListPtr(n_l1, 0);
+        l2 = gen_xmlListPtr(n_l2, 1);
+
+        xmlListMerge(l1, l2);
+        call_tests++;
+        des_xmlListPtr(n_l1, l1, 0);
+        des_xmlListPtr(n_l2, l2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListMerge",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l1);
+            printf(" %d", n_l2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListPopBack(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        xmlListPopBack(l);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListPopBack",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListPopFront(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        xmlListPopFront(l);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListPopFront",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListPushBack(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* new data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListPushBack(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListPushBack",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListPushFront(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* new data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListPushFront(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListPushFront",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListRemoveAll(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* list data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListRemoveAll(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListRemoveAll",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListRemoveFirst(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* list data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListRemoveFirst(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListRemoveFirst",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListRemoveLast(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* list data */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListRemoveLast(l, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListRemoveLast",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListReverse(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        xmlListReverse(l);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListReverse",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListReverseSearch(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* a search value */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListReverseSearch(l, data);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListReverseSearch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListReverseWalk(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlListSearch(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+    void * data; /* a search value */
+    int n_data;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+        data = gen_userdata(n_data, 1);
+
+        ret_val = xmlListSearch(l, data);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        des_userdata(n_data, data, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListSearch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListSize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        ret_val = xmlListSize(l);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListSize",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListSort(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlListPtr l; /* a list */
+    int n_l;
+
+    for (n_l = 0;n_l < gen_nb_xmlListPtr;n_l++) {
+        mem_base = xmlMemBlocks();
+        l = gen_xmlListPtr(n_l, 0);
+
+        xmlListSort(l);
+        call_tests++;
+        des_xmlListPtr(n_l, l, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlListSort",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_l);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlListWalk(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_list(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing list : 19 of 26 functions ...\n");
+    test_ret += test_xmlLinkGetData();
+    test_ret += test_xmlListAppend();
+    test_ret += test_xmlListClear();
+    test_ret += test_xmlListCopy();
+    test_ret += test_xmlListCreate();
+    test_ret += test_xmlListDup();
+    test_ret += test_xmlListEmpty();
+    test_ret += test_xmlListEnd();
+    test_ret += test_xmlListFront();
+    test_ret += test_xmlListInsert();
+    test_ret += test_xmlListMerge();
+    test_ret += test_xmlListPopBack();
+    test_ret += test_xmlListPopFront();
+    test_ret += test_xmlListPushBack();
+    test_ret += test_xmlListPushFront();
+    test_ret += test_xmlListRemoveAll();
+    test_ret += test_xmlListRemoveFirst();
+    test_ret += test_xmlListRemoveLast();
+    test_ret += test_xmlListReverse();
+    test_ret += test_xmlListReverseSearch();
+    test_ret += test_xmlListReverseWalk();
+    test_ret += test_xmlListSearch();
+    test_ret += test_xmlListSize();
+    test_ret += test_xmlListSort();
+    test_ret += test_xmlListWalk();
+
+    if (test_ret != 0)
+	printf("Module list: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlNanoFTPCheckResponse(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoFTPCheckResponse(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPCheckResponse",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlNanoFTPCleanup();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPCloseConnection(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoFTPCloseConnection(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPCloseConnection",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPCwd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+    char * directory; /* a directory on the server */
+    int n_directory;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+    for (n_directory = 0;n_directory < gen_nb_const_char_ptr;n_directory++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+        directory = gen_const_char_ptr(n_directory, 1);
+
+        ret_val = xmlNanoFTPCwd(ctx, (const char *)directory);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        des_const_char_ptr(n_directory, (const char *)directory, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPCwd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_directory);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPDele(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+    const char * file; /* a file or directory on the server */
+    int n_file;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+    for (n_file = 0;n_file < gen_nb_filepath;n_file++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+        file = gen_filepath(n_file, 1);
+
+        ret_val = xmlNanoFTPDele(ctx, file);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        des_filepath(n_file, file, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPDele",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_file);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPGet(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPGetConnection(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoFTPGetConnection(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPGetConnection",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPGetResponse(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoFTPGetResponse(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPGetResponse",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPGetSocket(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+    const char * filename; /* the file to retrieve (or NULL if path is in context). */
+    int n_filename;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+        filename = gen_filepath(n_filename, 1);
+
+        ret_val = xmlNanoFTPGetSocket(ctx, filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        des_filepath(n_filename, filename, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPGetSocket",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPInit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlNanoFTPInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPList(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPNewCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * URL; /* The URL used to initialize the context */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+
+        ret_val = xmlNanoFTPNewCtxt(URL);
+        desret_xmlNanoFTPCtxtPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPNewCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPOpen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * URL; /* the URL to the resource */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+
+        ret_val = xmlNanoFTPOpen(URL);
+        desret_xmlNanoFTPCtxtPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPOpen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPProxy(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    char * host; /* the proxy host name */
+    int n_host;
+    int port; /* the proxy port */
+    int n_port;
+    char * user; /* the proxy user name */
+    int n_user;
+    char * passwd; /* the proxy password */
+    int n_passwd;
+    int type; /* the type of proxy 1 for using SITE, 2 for USER a@b */
+    int n_type;
+
+    for (n_host = 0;n_host < gen_nb_const_char_ptr;n_host++) {
+    for (n_port = 0;n_port < gen_nb_int;n_port++) {
+    for (n_user = 0;n_user < gen_nb_const_char_ptr;n_user++) {
+    for (n_passwd = 0;n_passwd < gen_nb_const_char_ptr;n_passwd++) {
+    for (n_type = 0;n_type < gen_nb_int;n_type++) {
+        host = gen_const_char_ptr(n_host, 0);
+        port = gen_int(n_port, 1);
+        user = gen_const_char_ptr(n_user, 2);
+        passwd = gen_const_char_ptr(n_passwd, 3);
+        type = gen_int(n_type, 4);
+
+        xmlNanoFTPProxy((const char *)host, port, (const char *)user, (const char *)passwd, type);
+        call_tests++;
+        des_const_char_ptr(n_host, (const char *)host, 0);
+        des_int(n_port, port, 1);
+        des_const_char_ptr(n_user, (const char *)user, 2);
+        des_const_char_ptr(n_passwd, (const char *)passwd, 3);
+        des_int(n_type, type, 4);
+        xmlResetLastError();
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPQuit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoFTPQuit(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPQuit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPRead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the FTP context */
+    int n_ctx;
+    void * dest; /* a buffer */
+    int n_dest;
+    int len; /* the buffer length */
+    int n_len;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+    for (n_dest = 0;n_dest < gen_nb_void_ptr;n_dest++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+        dest = gen_void_ptr(n_dest, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlNanoFTPRead(ctx, dest, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        des_void_ptr(n_dest, dest, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_dest);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPScanProxy(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    const char * URL; /* The proxy URL used to initialize the proxy context */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+        URL = gen_filepath(n_URL, 0);
+
+        xmlNanoFTPScanProxy(URL);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoFTPUpdateURL(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* an FTP context */
+    int n_ctx;
+    const char * URL; /* The URL used to update the context */
+    int n_URL;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoFTPCtxtPtr;n_ctx++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoFTPCtxtPtr(n_ctx, 0);
+        URL = gen_filepath(n_URL, 1);
+
+        ret_val = xmlNanoFTPUpdateURL(ctx, URL);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoFTPCtxtPtr(n_ctx, ctx, 0);
+        des_filepath(n_URL, URL, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoFTPUpdateURL",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_URL);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_nanoftp(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing nanoftp : 16 of 22 functions ...\n");
+    test_ret += test_xmlNanoFTPCheckResponse();
+    test_ret += test_xmlNanoFTPCleanup();
+    test_ret += test_xmlNanoFTPCloseConnection();
+    test_ret += test_xmlNanoFTPCwd();
+    test_ret += test_xmlNanoFTPDele();
+    test_ret += test_xmlNanoFTPGet();
+    test_ret += test_xmlNanoFTPGetConnection();
+    test_ret += test_xmlNanoFTPGetResponse();
+    test_ret += test_xmlNanoFTPGetSocket();
+    test_ret += test_xmlNanoFTPInit();
+    test_ret += test_xmlNanoFTPList();
+    test_ret += test_xmlNanoFTPNewCtxt();
+    test_ret += test_xmlNanoFTPOpen();
+    test_ret += test_xmlNanoFTPProxy();
+    test_ret += test_xmlNanoFTPQuit();
+    test_ret += test_xmlNanoFTPRead();
+    test_ret += test_xmlNanoFTPScanProxy();
+    test_ret += test_xmlNanoFTPUpdateURL();
+
+    if (test_ret != 0)
+	printf("Module nanoftp: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlNanoHTTPAuthHeader(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    const char * ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoHTTPAuthHeader(ctx);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPAuthHeader",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlNanoHTTPCleanup();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPContentLength(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoHTTPContentLength(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPContentLength",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPEncoding(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    const char * ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoHTTPEncoding(ctx);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_char_ptr_ptr 1
+static char ** gen_char_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_char_ptr_ptr(int no ATTRIBUTE_UNUSED, char ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlNanoHTTPFetch(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * URL; /* The URL to load */
+    int n_URL;
+    const char * filename; /* the filename where the content should be saved */
+    int n_filename;
+    char ** contentType; /* if available the Content-Type information will be returned at that location */
+    int n_contentType;
+
+    for (n_URL = 0;n_URL < gen_nb_fileoutput;n_URL++) {
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_contentType = 0;n_contentType < gen_nb_char_ptr_ptr;n_contentType++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_fileoutput(n_URL, 0);
+        filename = gen_fileoutput(n_filename, 1);
+        contentType = gen_char_ptr_ptr(n_contentType, 2);
+
+        ret_val = xmlNanoHTTPFetch(URL, filename, contentType);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_URL, URL, 0);
+        des_fileoutput(n_filename, filename, 1);
+        des_char_ptr_ptr(n_contentType, contentType, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPFetch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_filename);
+            printf(" %d", n_contentType);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPInit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlNanoHTTPInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPMimeType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    const char * ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoHTTPMimeType(ctx);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPMimeType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPOpen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * URL; /* The URL to load */
+    int n_URL;
+    char ** contentType; /* if available the Content-Type information will be returned at that location */
+    int n_contentType;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_contentType = 0;n_contentType < gen_nb_char_ptr_ptr;n_contentType++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+        contentType = gen_char_ptr_ptr(n_contentType, 1);
+
+        ret_val = xmlNanoHTTPOpen(URL, contentType);
+        desret_xmlNanoHTTPCtxtPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        des_char_ptr_ptr(n_contentType, contentType, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPOpen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_contentType);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPOpenRedir(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * URL; /* The URL to load */
+    int n_URL;
+    char ** contentType; /* if available the Content-Type information will be returned at that location */
+    int n_contentType;
+    char ** redir; /* if available the redirected URL will be returned */
+    int n_redir;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_contentType = 0;n_contentType < gen_nb_char_ptr_ptr;n_contentType++) {
+    for (n_redir = 0;n_redir < gen_nb_char_ptr_ptr;n_redir++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+        contentType = gen_char_ptr_ptr(n_contentType, 1);
+        redir = gen_char_ptr_ptr(n_redir, 2);
+
+        ret_val = xmlNanoHTTPOpenRedir(URL, contentType, redir);
+        desret_xmlNanoHTTPCtxtPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        des_char_ptr_ptr(n_contentType, contentType, 1);
+        des_char_ptr_ptr(n_redir, redir, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPOpenRedir",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_contentType);
+            printf(" %d", n_redir);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPRead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+    void * dest; /* a buffer */
+    int n_dest;
+    int len; /* the buffer length */
+    int n_len;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+    for (n_dest = 0;n_dest < gen_nb_void_ptr;n_dest++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+        dest = gen_void_ptr(n_dest, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlNanoHTTPRead(ctx, dest, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        des_void_ptr(n_dest, dest, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_dest);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPRedir(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPReturnCode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctx; /* the HTTP context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlNanoHTTPCtxtPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlNanoHTTPCtxtPtr(n_ctx, 0);
+
+        ret_val = xmlNanoHTTPReturnCode(ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNanoHTTPCtxtPtr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPReturnCode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPSave(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * ctxt; /* the HTTP context */
+    int n_ctxt;
+    const char * filename; /* the filename where the content should be saved */
+    int n_filename;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_void_ptr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_void_ptr(n_ctxt, 0);
+        filename = gen_fileoutput(n_filename, 1);
+
+        ret_val = xmlNanoHTTPSave(ctxt, filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_ctxt, ctxt, 0);
+        des_fileoutput(n_filename, filename, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNanoHTTPSave",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNanoHTTPScanProxy(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    const char * URL; /* The proxy URL used to initialize the proxy context */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+        URL = gen_filepath(n_URL, 0);
+
+        xmlNanoHTTPScanProxy(URL);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_nanohttp(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing nanohttp : 13 of 17 functions ...\n");
+    test_ret += test_xmlNanoHTTPAuthHeader();
+    test_ret += test_xmlNanoHTTPCleanup();
+    test_ret += test_xmlNanoHTTPContentLength();
+    test_ret += test_xmlNanoHTTPEncoding();
+    test_ret += test_xmlNanoHTTPFetch();
+    test_ret += test_xmlNanoHTTPInit();
+    test_ret += test_xmlNanoHTTPMimeType();
+    test_ret += test_xmlNanoHTTPOpen();
+    test_ret += test_xmlNanoHTTPOpenRedir();
+    test_ret += test_xmlNanoHTTPRead();
+    test_ret += test_xmlNanoHTTPRedir();
+    test_ret += test_xmlNanoHTTPReturnCode();
+    test_ret += test_xmlNanoHTTPSave();
+    test_ret += test_xmlNanoHTTPScanProxy();
+
+    if (test_ret != 0)
+	printf("Module nanohttp: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlByteConsumed(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    long ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlByteConsumed(ctxt);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlByteConsumed",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlClearNodeInfoSeq(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserNodeInfoSeqPtr seq; /* a node info sequence pointer */
+    int n_seq;
+
+    for (n_seq = 0;n_seq < gen_nb_xmlParserNodeInfoSeqPtr;n_seq++) {
+        mem_base = xmlMemBlocks();
+        seq = gen_xmlParserNodeInfoSeqPtr(n_seq, 0);
+
+        xmlClearNodeInfoSeq(seq);
+        call_tests++;
+        des_xmlParserNodeInfoSeqPtr(n_seq, seq, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlClearNodeInfoSeq",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_seq);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlClearParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        xmlClearParserCtxt(ctxt);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlClearParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateDocParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+
+        ret_val = xmlCreateDocParserCtxt((const xmlChar *)cur);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateDocParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreatePushParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PUSH_ENABLED)
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    xmlSAXHandlerPtr sax; /* a SAX handler */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks */
+    int n_user_data;
+    char * chunk; /* a pointer to an array of chars */
+    int n_chunk;
+    int size; /* number of chars in the array */
+    int n_size;
+    const char * filename; /* an optional file name or URI */
+    int n_filename;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_chunk = 0;n_chunk < gen_nb_const_char_ptr;n_chunk++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        user_data = gen_userdata(n_user_data, 1);
+        chunk = gen_const_char_ptr(n_chunk, 2);
+        size = gen_int(n_size, 3);
+        filename = gen_fileoutput(n_filename, 4);
+
+        ret_val = xmlCreatePushParserCtxt(sax, user_data, (const char *)chunk, size, filename);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_user_data, user_data, 1);
+        des_const_char_ptr(n_chunk, (const char *)chunk, 2);
+        des_int(n_size, size, 3);
+        des_fileoutput(n_filename, filename, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreatePushParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_chunk);
+            printf(" %d", n_size);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtReadDoc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_parseroptions(n_options, 4);
+
+        ret_val = xmlCtxtReadDoc(ctxt, (const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_parseroptions(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtReadDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtReadFile(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        filename = gen_filepath(n_filename, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_parseroptions(n_options, 3);
+
+        ret_val = xmlCtxtReadFile(ctxt, filename, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_filepath(n_filename, filename, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_parseroptions(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtReadFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtReadMemory(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        buffer = gen_const_char_ptr(n_buffer, 1);
+        size = gen_int(n_size, 2);
+        URL = gen_filepath(n_URL, 3);
+        encoding = gen_const_char_ptr(n_encoding, 4);
+        options = gen_parseroptions(n_options, 5);
+
+        ret_val = xmlCtxtReadMemory(ctxt, (const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+        des_int(n_size, size, 2);
+        des_filepath(n_URL, URL, 3);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+        des_parseroptions(n_options, options, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtReadMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtReset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        xmlCtxtReset(ctxt);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtReset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtResetPush(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    char * chunk; /* a pointer to an array of chars */
+    int n_chunk;
+    int size; /* number of chars in the array */
+    int n_size;
+    const char * filename; /* an optional file name or URI */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_chunk = 0;n_chunk < gen_nb_const_char_ptr;n_chunk++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        chunk = gen_const_char_ptr(n_chunk, 1);
+        size = gen_int(n_size, 2);
+        filename = gen_filepath(n_filename, 3);
+        encoding = gen_const_char_ptr(n_encoding, 4);
+
+        ret_val = xmlCtxtResetPush(ctxt, (const char *)chunk, size, filename, (const char *)encoding);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+        des_int(n_size, size, 2);
+        des_filepath(n_filename, filename, 3);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtResetPush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_chunk);
+            printf(" %d", n_size);
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtUseOptions(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        options = gen_parseroptions(n_options, 1);
+
+        ret_val = xmlCtxtUseOptions(ctxt, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_parseroptions(n_options, options, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtUseOptions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetExternalEntityLoader(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetFeature(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef LIBXML_LEGACY_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML/HTML parser context */
+    int n_ctxt;
+    char * name; /* the feature name */
+    int n_name;
+    void * result; /* location to store the result */
+    int n_result;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
+    for (n_result = 0;n_result < gen_nb_void_ptr;n_result++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        name = gen_const_char_ptr(n_name, 1);
+        result = gen_void_ptr(n_result, 2);
+
+        ret_val = xmlGetFeature(ctxt, (const char *)name, result);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_name, (const char *)name, 1);
+        des_void_ptr(n_result, result, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetFeature",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_result);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_char_ptr_ptr 1
+static char ** gen_const_char_ptr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_char_ptr_ptr(int no ATTRIBUTE_UNUSED, const char ** val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlGetFeaturesList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef LIBXML_LEGACY_ENABLED
+    int mem_base;
+    int ret_val;
+    int * len; /* the length of the features name array (input/output) */
+    int n_len;
+    char ** result; /* an array of string to be filled with the features name. */
+    int n_result;
+
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+    for (n_result = 0;n_result < gen_nb_const_char_ptr_ptr;n_result++) {
+        mem_base = xmlMemBlocks();
+        len = gen_int_ptr(n_len, 0);
+        result = gen_const_char_ptr_ptr(n_result, 1);
+
+        ret_val = xmlGetFeaturesList(len, (const char **)result);
+        desret_int(ret_val);
+        call_tests++;
+        des_int_ptr(n_len, len, 0);
+        des_const_char_ptr_ptr(n_result, (const char **)result, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetFeaturesList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_len);
+            printf(" %d", n_result);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHasFeature(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlFeature feature; /* the feature to be examined */
+    int n_feature;
+
+    for (n_feature = 0;n_feature < gen_nb_xmlFeature;n_feature++) {
+        mem_base = xmlMemBlocks();
+        feature = gen_xmlFeature(n_feature, 0);
+
+        ret_val = xmlHasFeature(feature);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlFeature(n_feature, feature, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHasFeature",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_feature);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOParseDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef LIBXML_VALID_ENABLED
+    xmlDtdPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block or NULL */
+    int n_sax;
+    xmlParserInputBufferPtr input; /* an Input Buffer */
+    int n_input;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        input = gen_xmlParserInputBufferPtr(n_input, 1);
+        enc = gen_xmlCharEncoding(n_enc, 2);
+
+        ret_val = xmlIOParseDTD(sax, input, enc);
+        input = NULL;
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_xmlParserInputBufferPtr(n_input, input, 1);
+        des_xmlCharEncoding(n_enc, enc, 2);
+        xmlResetLastError();
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitNodeInfoSeq(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserNodeInfoSeqPtr seq; /* a node info sequence pointer */
+    int n_seq;
+
+    for (n_seq = 0;n_seq < gen_nb_xmlParserNodeInfoSeqPtr;n_seq++) {
+        mem_base = xmlMemBlocks();
+        seq = gen_xmlParserNodeInfoSeqPtr(n_seq, 0);
+
+        xmlInitNodeInfoSeq(seq);
+        call_tests++;
+        des_xmlParserNodeInfoSeqPtr(n_seq, seq, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlInitNodeInfoSeq",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_seq);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitParser(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlInitParser();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlInitParser",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlInitParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlInitParserCtxt(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlInitParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlKeepBlanksDefault(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int val; /* int 0 or 1 */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlKeepBlanksDefault(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlKeepBlanksDefault",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLineNumbersDefault(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int val; /* int 0 or 1 */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlLineNumbersDefault(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLineNumbersDefault",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLoadExternalEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    const char * URL; /* the URL for the entity to load */
+    int n_URL;
+    char * ID; /* the Public ID for the entity to load */
+    int n_ID;
+    xmlParserCtxtPtr ctxt; /* the context in which the entity is called or NULL */
+    int n_ctxt;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_ID = 0;n_ID < gen_nb_const_char_ptr;n_ID++) {
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+        ID = gen_const_char_ptr(n_ID, 1);
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 2);
+
+        ret_val = xmlLoadExternalEntity(URL, (const char *)ID, ctxt);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        des_const_char_ptr(n_ID, (const char *)ID, 1);
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLoadExternalEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_ID);
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewIOInputStream(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlParserInputBufferPtr input; /* an I/O Input */
+    int n_input;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        input = gen_xmlParserInputBufferPtr(n_input, 1);
+        enc = gen_xmlCharEncoding(n_enc, 2);
+
+        ret_val = xmlNewIOInputStream(ctxt, input, enc);
+        if (ret_val != NULL) input = NULL;
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputBufferPtr(n_input, input, 1);
+        des_xmlCharEncoding(n_enc, enc, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewIOInputStream",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_input);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlNewParserCtxt();
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlNodePtr_ptr 1
+static xmlNodePtr * gen_xmlNodePtr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlNodePtr_ptr(int no ATTRIBUTE_UNUSED, xmlNodePtr * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParseBalancedChunkMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document the chunk pertains to */
+    int n_doc;
+    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
+    int n_user_data;
+    int depth; /* Used for loop detection, use 0 */
+    int n_depth;
+    xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
+    int n_string;
+    xmlNodePtr * lst; /* the return value for the set of parsed nodes */
+    int n_lst;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
+    for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        sax = gen_xmlSAXHandlerPtr(n_sax, 1);
+        user_data = gen_userdata(n_user_data, 2);
+        depth = gen_int(n_depth, 3);
+        string = gen_const_xmlChar_ptr(n_string, 4);
+        lst = gen_xmlNodePtr_ptr(n_lst, 5);
+        
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+
+
+        ret_val = xmlParseBalancedChunkMemory(doc, sax, user_data, depth, (const xmlChar *)string, lst);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlSAXHandlerPtr(n_sax, sax, 1);
+        des_userdata(n_user_data, user_data, 2);
+        des_int(n_depth, depth, 3);
+        des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 4);
+        des_xmlNodePtr_ptr(n_lst, lst, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseBalancedChunkMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_depth);
+            printf(" %d", n_string);
+            printf(" %d", n_lst);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseBalancedChunkMemoryRecover(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document the chunk pertains to */
+    int n_doc;
+    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
+    int n_user_data;
+    int depth; /* Used for loop detection, use 0 */
+    int n_depth;
+    xmlChar * string; /* the input string in UTF8 or ISO-Latin (zero terminated) */
+    int n_string;
+    xmlNodePtr * lst; /* the return value for the set of parsed nodes */
+    int n_lst;
+    int recover; /* return nodes even if the data is broken (use 0) */
+    int n_recover;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
+    for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+    for (n_recover = 0;n_recover < gen_nb_int;n_recover++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        sax = gen_xmlSAXHandlerPtr(n_sax, 1);
+        user_data = gen_userdata(n_user_data, 2);
+        depth = gen_int(n_depth, 3);
+        string = gen_const_xmlChar_ptr(n_string, 4);
+        lst = gen_xmlNodePtr_ptr(n_lst, 5);
+        recover = gen_int(n_recover, 6);
+        
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+
+
+        ret_val = xmlParseBalancedChunkMemoryRecover(doc, sax, user_data, depth, (const xmlChar *)string, lst, recover);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlSAXHandlerPtr(n_sax, sax, 1);
+        des_userdata(n_user_data, user_data, 2);
+        des_int(n_depth, depth, 3);
+        des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 4);
+        des_xmlNodePtr_ptr(n_lst, lst, 5);
+        des_int(n_recover, recover, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseBalancedChunkMemoryRecover",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_depth);
+            printf(" %d", n_string);
+            printf(" %d", n_lst);
+            printf(" %d", n_recover);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseChunk(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PUSH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    char * chunk; /* an char array */
+    int n_chunk;
+    int size; /* the size in byte of the chunk */
+    int n_size;
+    int terminate; /* last chunk indicator */
+    int n_terminate;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_chunk = 0;n_chunk < gen_nb_const_char_ptr;n_chunk++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_terminate = 0;n_terminate < gen_nb_int;n_terminate++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        chunk = gen_const_char_ptr(n_chunk, 1);
+        size = gen_int(n_size, 2);
+        terminate = gen_int(n_terminate, 3);
+
+        ret_val = xmlParseChunk(ctxt, (const char *)chunk, size, terminate);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_chunk, (const char *)chunk, 1);
+        des_int(n_size, size, 2);
+        des_int(n_terminate, terminate, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseChunk",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_chunk);
+            printf(" %d", n_size);
+            printf(" %d", n_terminate);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseCtxtExternalEntity(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctx; /* the existing parsing context */
+    int n_ctx;
+    xmlChar * URL; /* the URL for the entity to load */
+    int n_URL;
+    xmlChar * ID; /* the System ID for the entity to load */
+    int n_ID;
+    xmlNodePtr * lst; /* the return value for the set of parsed nodes */
+    int n_lst;
+
+    for (n_ctx = 0;n_ctx < gen_nb_xmlParserCtxtPtr;n_ctx++) {
+    for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
+    for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
+    for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_xmlParserCtxtPtr(n_ctx, 0);
+        URL = gen_const_xmlChar_ptr(n_URL, 1);
+        ID = gen_const_xmlChar_ptr(n_ID, 2);
+        lst = gen_xmlNodePtr_ptr(n_lst, 3);
+
+        ret_val = xmlParseCtxtExternalEntity(ctx, (const xmlChar *)URL, (const xmlChar *)ID, lst);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctx, ctx, 0);
+        des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 1);
+        des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 2);
+        des_xmlNodePtr_ptr(n_lst, lst, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseCtxtExternalEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_URL);
+            printf(" %d", n_ID);
+            printf(" %d", n_lst);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef LIBXML_VALID_ENABLED
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
+    int n_ExternalID;
+    xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
+    int n_SystemID;
+
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 0);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 1);
+
+        ret_val = xmlParseDTD((const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 0);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+
+        ret_val = xmlParseDoc((const xmlChar *)cur);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseDocument(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlParseDocument(ctxt);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlParseEntity(filename);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseExtParsedEnt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlParseExtParsedEnt(ctxt);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseExtParsedEnt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseExternalEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document the chunk pertains to */
+    int n_doc;
+    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
+    int n_user_data;
+    int depth; /* Used for loop detection, use 0 */
+    int n_depth;
+    xmlChar * URL; /* the URL for the entity to load */
+    int n_URL;
+    xmlChar * ID; /* the System ID for the entity to load */
+    int n_ID;
+    xmlNodePtr * lst; /* the return value for the set of parsed nodes */
+    int n_lst;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+    for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
+    for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
+    for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        sax = gen_xmlSAXHandlerPtr(n_sax, 1);
+        user_data = gen_userdata(n_user_data, 2);
+        depth = gen_int(n_depth, 3);
+        URL = gen_const_xmlChar_ptr(n_URL, 4);
+        ID = gen_const_xmlChar_ptr(n_ID, 5);
+        lst = gen_xmlNodePtr_ptr(n_lst, 6);
+
+        ret_val = xmlParseExternalEntity(doc, sax, user_data, depth, (const xmlChar *)URL, (const xmlChar *)ID, lst);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlSAXHandlerPtr(n_sax, sax, 1);
+        des_userdata(n_user_data, user_data, 2);
+        des_int(n_depth, depth, 3);
+        des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 4);
+        des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 5);
+        des_xmlNodePtr_ptr(n_lst, lst, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseExternalEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_depth);
+            printf(" %d", n_URL);
+            printf(" %d", n_ID);
+            printf(" %d", n_lst);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlParseFile(filename);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseInNodeContext(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserErrors ret_val;
+    xmlNodePtr node; /* the context node */
+    int n_node;
+    char * data; /* the input string */
+    int n_data;
+    int datalen; /* the input string length in bytes */
+    int n_datalen;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+    xmlNodePtr * lst; /* the return value for the set of parsed nodes */
+    int n_lst;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_data = 0;n_data < gen_nb_const_char_ptr;n_data++) {
+    for (n_datalen = 0;n_datalen < gen_nb_int;n_datalen++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+    for (n_lst = 0;n_lst < gen_nb_xmlNodePtr_ptr;n_lst++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        data = gen_const_char_ptr(n_data, 1);
+        datalen = gen_int(n_datalen, 2);
+        options = gen_parseroptions(n_options, 3);
+        lst = gen_xmlNodePtr_ptr(n_lst, 4);
+
+        ret_val = xmlParseInNodeContext(node, (const char *)data, datalen, options, lst);
+        desret_xmlParserErrors(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_char_ptr(n_data, (const char *)data, 1);
+        des_int(n_datalen, datalen, 2);
+        des_parseroptions(n_options, options, 3);
+        des_xmlNodePtr_ptr(n_lst, lst, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseInNodeContext",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_data);
+            printf(" %d", n_datalen);
+            printf(" %d", n_options);
+            printf(" %d", n_lst);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    char * buffer; /* an pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = xmlParseMemory((const char *)buffer, size);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_xmlParserNodeInfoPtr 1
+static xmlParserNodeInfoPtr gen_const_xmlParserNodeInfoPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlParserNodeInfoPtr(int no ATTRIBUTE_UNUSED, const xmlParserNodeInfoPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParserAddNodeInfo(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlParserNodeInfoPtr info; /* a node info sequence pointer */
+    int n_info;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_info = 0;n_info < gen_nb_const_xmlParserNodeInfoPtr;n_info++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        info = gen_const_xmlParserNodeInfoPtr(n_info, 1);
+
+        xmlParserAddNodeInfo(ctxt, (const xmlParserNodeInfoPtr)info);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlParserNodeInfoPtr(n_info, (const xmlParserNodeInfoPtr)info, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserAddNodeInfo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_info);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_xmlParserCtxtPtr 1
+static xmlParserCtxtPtr gen_const_xmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, const xmlParserCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+#define gen_nb_const_xmlNodePtr 1
+static xmlNodePtr gen_const_xmlNodePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlNodePtr(int no ATTRIBUTE_UNUSED, const xmlNodePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParserFindNodeInfo(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlParserNodeInfo * ret_val;
+    xmlParserCtxtPtr ctx; /* an XML parser context */
+    int n_ctx;
+    xmlNodePtr node; /* an XML node within the tree */
+    int n_node;
+
+    for (n_ctx = 0;n_ctx < gen_nb_const_xmlParserCtxtPtr;n_ctx++) {
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_const_xmlParserCtxtPtr(n_ctx, 0);
+        node = gen_const_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlParserFindNodeInfo((const xmlParserCtxtPtr)ctx, (const xmlNodePtr)node);
+        desret_const_xmlParserNodeInfo_ptr(ret_val);
+        call_tests++;
+        des_const_xmlParserCtxtPtr(n_ctx, (const xmlParserCtxtPtr)ctx, 0);
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserFindNodeInfo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_xmlParserNodeInfoSeqPtr 1
+static xmlParserNodeInfoSeqPtr gen_const_xmlParserNodeInfoSeqPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlParserNodeInfoSeqPtr(int no ATTRIBUTE_UNUSED, const xmlParserNodeInfoSeqPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParserFindNodeInfoIndex(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    unsigned long ret_val;
+    xmlParserNodeInfoSeqPtr seq; /* a node info sequence pointer */
+    int n_seq;
+    xmlNodePtr node; /* an XML node pointer */
+    int n_node;
+
+    for (n_seq = 0;n_seq < gen_nb_const_xmlParserNodeInfoSeqPtr;n_seq++) {
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        seq = gen_const_xmlParserNodeInfoSeqPtr(n_seq, 0);
+        node = gen_const_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlParserFindNodeInfoIndex((const xmlParserNodeInfoSeqPtr)seq, (const xmlNodePtr)node);
+        desret_unsigned_long(ret_val);
+        call_tests++;
+        des_const_xmlParserNodeInfoSeqPtr(n_seq, (const xmlParserNodeInfoSeqPtr)seq, 0);
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserFindNodeInfoIndex",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_seq);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlParserInputPtr 1
+static xmlParserInputPtr gen_xmlParserInputPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlParserInputPtr(int no ATTRIBUTE_UNUSED, xmlParserInputPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParserInputGrow(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserInputPtr in; /* an XML parser input */
+    int n_in;
+    int len; /* an indicative size for the lookahead */
+    int n_len;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputPtr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputPtr(n_in, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlParserInputGrow(in, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserInputPtr(n_in, in, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputGrow",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputRead(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserInputPtr in; /* an XML parser input */
+    int n_in;
+    int len; /* an indicative size for the lookahead */
+    int n_len;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputPtr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputPtr(n_in, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlParserInputRead(in, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserInputPtr(n_in, in, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPedanticParserDefault(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int val; /* int 0 or 1 */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlPedanticParserDefault(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPedanticParserDefault",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReadDoc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+        URL = gen_filepath(n_URL, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_parseroptions(n_options, 3);
+
+        ret_val = xmlReadDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        des_filepath(n_URL, URL, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_parseroptions(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReadDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReadFile(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+        options = gen_parseroptions(n_options, 2);
+
+        ret_val = xmlReadFile(filename, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        des_parseroptions(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReadFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReadMemory(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_parseroptions(n_options, 4);
+
+        ret_val = xmlReadMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_parseroptions(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReadMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRecoverDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+
+        ret_val = xmlRecoverDoc((const xmlChar *)cur);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRecoverDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRecoverFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlRecoverFile(filename);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRecoverFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRecoverMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    char * buffer; /* an pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = xmlRecoverMemory((const char *)buffer, size);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRecoverMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    xmlChar * ExternalID; /* a NAME* containing the External ID of the DTD */
+    int n_ExternalID;
+    xmlChar * SystemID; /* a NAME* containing the URL to the DTD */
+    int n_SystemID;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 1);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 2);
+
+        ret_val = xmlSAXParseDTD(sax, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 1);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    xmlChar * cur; /* a pointer to an array of xmlChar */
+    int n_cur;
+    int recovery; /* work in recovery mode, i.e. tries to read no Well Formed documents */
+    int n_recovery;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_recovery = 0;n_recovery < gen_nb_int;n_recovery++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        recovery = gen_int(n_recovery, 2);
+
+        ret_val = xmlSAXParseDoc(sax, (const xmlChar *)cur, recovery);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_int(n_recovery, recovery, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_cur);
+            printf(" %d", n_recovery);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        filename = gen_filepath(n_filename, 1);
+
+        ret_val = xmlSAXParseEntity(sax, filename);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_filepath(n_filename, filename, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    const char * filename; /* the filename */
+    int n_filename;
+    int recovery; /* work in recovery mode, i.e. tries to read no Well Formed documents */
+    int n_recovery;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_recovery = 0;n_recovery < gen_nb_int;n_recovery++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        filename = gen_filepath(n_filename, 1);
+        recovery = gen_int(n_recovery, 2);
+
+        ret_val = xmlSAXParseFile(sax, filename, recovery);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_filepath(n_filename, filename, 1);
+        des_int(n_recovery, recovery, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_filename);
+            printf(" %d", n_recovery);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseFileWithData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    const char * filename; /* the filename */
+    int n_filename;
+    int recovery; /* work in recovery mode, i.e. tries to read no Well Formed documents */
+    int n_recovery;
+    void * data; /* the userdata */
+    int n_data;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_recovery = 0;n_recovery < gen_nb_int;n_recovery++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        filename = gen_filepath(n_filename, 1);
+        recovery = gen_int(n_recovery, 2);
+        data = gen_userdata(n_data, 3);
+
+        ret_val = xmlSAXParseFileWithData(sax, filename, recovery, data);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_filepath(n_filename, filename, 1);
+        des_int(n_recovery, recovery, 2);
+        des_userdata(n_data, data, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseFileWithData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_filename);
+            printf(" %d", n_recovery);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    char * buffer; /* an pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    int recovery; /* work in recovery mode, i.e. tries to read not Well Formed documents */
+    int n_recovery;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_recovery = 0;n_recovery < gen_nb_int;n_recovery++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        buffer = gen_const_char_ptr(n_buffer, 1);
+        size = gen_int(n_size, 2);
+        recovery = gen_int(n_recovery, 3);
+
+        ret_val = xmlSAXParseMemory(sax, (const char *)buffer, size, recovery);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+        des_int(n_size, size, 2);
+        des_int(n_recovery, recovery, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_recovery);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXParseMemoryWithData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlSAXHandlerPtr sax; /* the SAX handler block */
+    int n_sax;
+    char * buffer; /* an pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    int recovery; /* work in recovery mode, i.e. tries to read no Well Formed documents */
+    int n_recovery;
+    void * data; /* the userdata */
+    int n_data;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_recovery = 0;n_recovery < gen_nb_int;n_recovery++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        buffer = gen_const_char_ptr(n_buffer, 1);
+        size = gen_int(n_size, 2);
+        recovery = gen_int(n_recovery, 3);
+        data = gen_userdata(n_data, 4);
+
+        ret_val = xmlSAXParseMemoryWithData(sax, (const char *)buffer, size, recovery, data);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+        des_int(n_size, size, 2);
+        des_int(n_recovery, recovery, 3);
+        des_userdata(n_data, data, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXParseMemoryWithData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_recovery);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXUserParseFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlSAXHandlerPtr sax; /* a SAX handler */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks */
+    int n_user_data;
+    const char * filename; /* a file name */
+    int n_filename;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        user_data = gen_userdata(n_user_data, 1);
+        filename = gen_filepath(n_filename, 2);
+        
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+
+
+        ret_val = xmlSAXUserParseFile(sax, user_data, filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_user_data, user_data, 1);
+        des_filepath(n_filename, filename, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXUserParseFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSAXUserParseMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlSAXHandlerPtr sax; /* a SAX handler */
+    int n_sax;
+    void * user_data; /* The user data returned on SAX callbacks */
+    int n_user_data;
+    char * buffer; /* an in-memory XML document input */
+    int n_buffer;
+    int size; /* the length of the XML document in bytes */
+    int n_size;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        user_data = gen_userdata(n_user_data, 1);
+        buffer = gen_const_char_ptr(n_buffer, 2);
+        size = gen_int(n_size, 3);
+        
+#ifdef LIBXML_SAX1_ENABLED
+        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
+#endif
+
+
+        ret_val = xmlSAXUserParseMemory(sax, user_data, (const char *)buffer, size);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_user_data, user_data, 1);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 2);
+        des_int(n_size, size, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSAXUserParseMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetExternalEntityLoader(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetFeature(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_LEGACY_ENABLED)
+#ifdef LIBXML_LEGACY_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML/HTML parser context */
+    int n_ctxt;
+    char * name; /* the feature name */
+    int n_name;
+    void * value; /* pointer to the location of the new value */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_void_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        name = gen_const_char_ptr(n_name, 1);
+        value = gen_void_ptr(n_value, 2);
+
+        ret_val = xmlSetFeature(ctxt, (const char *)name, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_name, (const char *)name, 1);
+        des_void_ptr(n_value, value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetFeature",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetupParserForBuffer(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SAX1_ENABLED)
+#ifdef LIBXML_SAX1_ENABLED
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlChar * buffer; /* a xmlChar * buffer */
+    int n_buffer;
+    const char * filename; /* a file name */
+    int n_filename;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_xmlChar_ptr;n_buffer++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        buffer = gen_const_xmlChar_ptr(n_buffer, 1);
+        filename = gen_filepath(n_filename, 2);
+
+        xmlSetupParserForBuffer(ctxt, (const xmlChar *)buffer, filename);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_buffer, (const xmlChar *)buffer, 1);
+        des_filepath(n_filename, filename, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetupParserForBuffer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_buffer);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStopParser(void) {
+    int test_ret = 0;
+
+#ifdef LIBXML_PUSH_ENABLED
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        xmlStopParser(ctxt);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStopParser",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSubstituteEntitiesDefault(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int val; /* int 0 or 1 */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlSubstituteEntitiesDefault(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSubstituteEntitiesDefault",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_parser(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing parser : 61 of 70 functions ...\n");
+    test_ret += test_xmlByteConsumed();
+    test_ret += test_xmlClearNodeInfoSeq();
+    test_ret += test_xmlClearParserCtxt();
+    test_ret += test_xmlCreateDocParserCtxt();
+    test_ret += test_xmlCreatePushParserCtxt();
+    test_ret += test_xmlCtxtReadDoc();
+    test_ret += test_xmlCtxtReadFile();
+    test_ret += test_xmlCtxtReadMemory();
+    test_ret += test_xmlCtxtReset();
+    test_ret += test_xmlCtxtResetPush();
+    test_ret += test_xmlCtxtUseOptions();
+    test_ret += test_xmlGetExternalEntityLoader();
+    test_ret += test_xmlGetFeature();
+    test_ret += test_xmlGetFeaturesList();
+    test_ret += test_xmlHasFeature();
+    test_ret += test_xmlIOParseDTD();
+    test_ret += test_xmlInitNodeInfoSeq();
+    test_ret += test_xmlInitParser();
+    test_ret += test_xmlInitParserCtxt();
+    test_ret += test_xmlKeepBlanksDefault();
+    test_ret += test_xmlLineNumbersDefault();
+    test_ret += test_xmlLoadExternalEntity();
+    test_ret += test_xmlNewIOInputStream();
+    test_ret += test_xmlNewParserCtxt();
+    test_ret += test_xmlParseBalancedChunkMemory();
+    test_ret += test_xmlParseBalancedChunkMemoryRecover();
+    test_ret += test_xmlParseChunk();
+    test_ret += test_xmlParseCtxtExternalEntity();
+    test_ret += test_xmlParseDTD();
+    test_ret += test_xmlParseDoc();
+    test_ret += test_xmlParseDocument();
+    test_ret += test_xmlParseEntity();
+    test_ret += test_xmlParseExtParsedEnt();
+    test_ret += test_xmlParseExternalEntity();
+    test_ret += test_xmlParseFile();
+    test_ret += test_xmlParseInNodeContext();
+    test_ret += test_xmlParseMemory();
+    test_ret += test_xmlParserAddNodeInfo();
+    test_ret += test_xmlParserFindNodeInfo();
+    test_ret += test_xmlParserFindNodeInfoIndex();
+    test_ret += test_xmlParserInputGrow();
+    test_ret += test_xmlParserInputRead();
+    test_ret += test_xmlPedanticParserDefault();
+    test_ret += test_xmlReadDoc();
+    test_ret += test_xmlReadFile();
+    test_ret += test_xmlReadMemory();
+    test_ret += test_xmlRecoverDoc();
+    test_ret += test_xmlRecoverFile();
+    test_ret += test_xmlRecoverMemory();
+    test_ret += test_xmlSAXParseDTD();
+    test_ret += test_xmlSAXParseDoc();
+    test_ret += test_xmlSAXParseEntity();
+    test_ret += test_xmlSAXParseFile();
+    test_ret += test_xmlSAXParseFileWithData();
+    test_ret += test_xmlSAXParseMemory();
+    test_ret += test_xmlSAXParseMemoryWithData();
+    test_ret += test_xmlSAXUserParseFile();
+    test_ret += test_xmlSAXUserParseMemory();
+    test_ret += test_xmlSetExternalEntityLoader();
+    test_ret += test_xmlSetFeature();
+    test_ret += test_xmlSetupParserForBuffer();
+    test_ret += test_xmlStopParser();
+    test_ret += test_xmlSubstituteEntitiesDefault();
+
+    if (test_ret != 0)
+	printf("Module parser: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_htmlCreateFileParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+    char * encoding; /* a free form C string describing the HTML document encoding, or NULL */
+    int n_encoding;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+
+        ret_val = htmlCreateFileParserCtxt(filename, (const char *)encoding);
+        desret_htmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlCreateFileParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_htmlInitAutoClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        htmlInitAutoClose();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlInitAutoClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_inputPop(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = inputPop(ctxt);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in inputPop",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_inputPush(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlParserInputPtr value; /* the parser input */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_value = 0;n_value < gen_nb_xmlParserInputPtr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        value = gen_xmlParserInputPtr(n_value, 1);
+
+        ret_val = inputPush(ctxt, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputPtr(n_value, value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in inputPush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_namePop(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = namePop(ctxt);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in namePop",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_namePush(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlChar * value; /* the element name */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+
+        ret_val = namePush(ctxt, (const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in namePush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_nodePop(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = nodePop(ctxt);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in nodePop",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_nodePush(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlNodePtr value; /* the element node */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_value = 0;n_value < gen_nb_xmlNodePtr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        value = gen_xmlNodePtr(n_value, 1);
+
+        ret_val = nodePush(ctxt, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_value, value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in nodePush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCheckLanguageID(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * lang; /* pointer to the string value */
+    int n_lang;
+
+    for (n_lang = 0;n_lang < gen_nb_const_xmlChar_ptr;n_lang++) {
+        mem_base = xmlMemBlocks();
+        lang = gen_const_xmlChar_ptr(n_lang, 0);
+
+        ret_val = xmlCheckLanguageID((const xmlChar *)lang);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_lang, (const xmlChar *)lang, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCheckLanguageID",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_lang);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int len; /* Ignored, compatibility */
+    int n_len;
+    xmlChar * out; /* pointer to an array of xmlChar */
+    int n_out;
+    int val; /* the char value */
+    int n_val;
+
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+    for (n_out = 0;n_out < gen_nb_xmlChar_ptr;n_out++) {
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        len = gen_int(n_len, 0);
+        out = gen_xmlChar_ptr(n_out, 1);
+        val = gen_int(n_val, 2);
+
+        ret_val = xmlCopyChar(len, out, val);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_len, len, 0);
+        des_xmlChar_ptr(n_out, out, 1);
+        des_int(n_val, val, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_len);
+            printf(" %d", n_out);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyCharMultiByte(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * out; /* pointer to an array of xmlChar */
+    int n_out;
+    int val; /* the char value */
+    int n_val;
+
+    for (n_out = 0;n_out < gen_nb_xmlChar_ptr;n_out++) {
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        out = gen_xmlChar_ptr(n_out, 0);
+        val = gen_int(n_val, 1);
+
+        ret_val = xmlCopyCharMultiByte(out, val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlChar_ptr(n_out, out, 0);
+        des_int(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyCharMultiByte",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateEntityParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    xmlChar * URL; /* the entity URL */
+    int n_URL;
+    xmlChar * ID; /* the entity PUBLIC ID */
+    int n_ID;
+    xmlChar * base; /* a possible base for the target URI */
+    int n_base;
+
+    for (n_URL = 0;n_URL < gen_nb_const_xmlChar_ptr;n_URL++) {
+    for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
+    for (n_base = 0;n_base < gen_nb_const_xmlChar_ptr;n_base++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_const_xmlChar_ptr(n_URL, 0);
+        ID = gen_const_xmlChar_ptr(n_ID, 1);
+        base = gen_const_xmlChar_ptr(n_base, 2);
+
+        ret_val = xmlCreateEntityParserCtxt((const xmlChar *)URL, (const xmlChar *)ID, (const xmlChar *)base);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URL, (const xmlChar *)URL, 0);
+        des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 1);
+        des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateEntityParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_ID);
+            printf(" %d", n_base);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateFileParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    const char * filename; /* the filename */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+
+        ret_val = xmlCreateFileParserCtxt(filename);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateFileParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateMemoryParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = xmlCreateMemoryParserCtxt((const char *)buffer, size);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateMemoryParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateURLParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    const char * filename; /* the filename or URL */
+    int n_filename;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        options = gen_int(n_options, 1);
+
+        ret_val = xmlCreateURLParserCtxt(filename, options);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_int(n_options, options, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateURLParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCurrentChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* the XML parser context */
+    int n_ctxt;
+    int * len; /* pointer to the length of the char read */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        len = gen_int_ptr(n_len, 1);
+
+        ret_val = xmlCurrentChar(ctxt, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_int_ptr(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCurrentChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlErrMemory(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    char * extra; /* extra informations */
+    int n_extra;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_extra = 0;n_extra < gen_nb_const_char_ptr;n_extra++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        extra = gen_const_char_ptr(n_extra, 1);
+
+        xmlErrMemory(ctxt, (const char *)extra);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_char_ptr(n_extra, (const char *)extra, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlErrMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_extra);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsLetter(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int c; /* an unicode character (int) */
+    int n_c;
+
+    for (n_c = 0;n_c < gen_nb_int;n_c++) {
+        mem_base = xmlMemBlocks();
+        c = gen_int(n_c, 0);
+
+        ret_val = xmlIsLetter(c);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_c, c, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsLetter",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_c);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewEntityInputStream(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlEntityPtr entity; /* an Entity pointer */
+    int n_entity;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_entity = 0;n_entity < gen_nb_xmlEntityPtr;n_entity++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        entity = gen_xmlEntityPtr(n_entity, 1);
+
+        ret_val = xmlNewEntityInputStream(ctxt, entity);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlEntityPtr(n_entity, entity, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewEntityInputStream",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_entity);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewInputFromFile(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    const char * filename; /* the filename to use as entity */
+    int n_filename;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        filename = gen_filepath(n_filename, 1);
+
+        ret_val = xmlNewInputFromFile(ctxt, filename);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_filepath(n_filename, filename, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewInputFromFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewInputStream(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlNewInputStream(ctxt);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewInputStream",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewStringInputStream(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlChar * buffer; /* an memory buffer */
+    int n_buffer;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_xmlChar_ptr;n_buffer++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        buffer = gen_const_xmlChar_ptr(n_buffer, 1);
+
+        ret_val = xmlNewStringInputStream(ctxt, (const xmlChar *)buffer);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_buffer, (const xmlChar *)buffer, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewStringInputStream",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_buffer);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNextChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ctxt; /* the XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        xmlNextChar(ctxt);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNextChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputShrink(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr in; /* an XML parser input */
+    int n_in;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputPtr;n_in++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputPtr(n_in, 0);
+
+        xmlParserInputShrink(in);
+        call_tests++;
+        des_xmlParserInputPtr(n_in, in, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputShrink",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPopInput(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlPopInput(ctxt);
+        desret_xmlChar(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPopInput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPushInput(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlParserInputPtr input; /* an XML parser input fragment (entity, XML fragment ...). */
+    int n_input;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        input = gen_xmlParserInputPtr(n_input, 1);
+
+        ret_val = xmlPushInput(ctxt, input);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputPtr(n_input, input, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPushInput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_input);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetEntityReferenceFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSplitQName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlChar * name; /* an XML parser context */
+    int n_name;
+    xmlChar ** prefix; /* a xmlChar ** */
+    int n_prefix;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix = 0;n_prefix < gen_nb_xmlChar_ptr_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        prefix = gen_xmlChar_ptr_ptr(n_prefix, 2);
+
+        ret_val = xmlSplitQName(ctxt, (const xmlChar *)name, prefix);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_xmlChar_ptr_ptr(n_prefix, prefix, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSplitQName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStringCurrentChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* the XML parser context */
+    int n_ctxt;
+    xmlChar * cur; /* pointer to the beginning of the char */
+    int n_cur;
+    int * len; /* pointer to the length of the char read */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        len = gen_int_ptr(n_len, 2);
+
+        ret_val = xmlStringCurrentChar(ctxt, (const xmlChar *)cur, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_int_ptr(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStringCurrentChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStringDecodeEntities(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlParserCtxtPtr ctxt; /* the parser context */
+    int n_ctxt;
+    xmlChar * str; /* the input string */
+    int n_str;
+    int what; /* combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF */
+    int n_what;
+    xmlChar end; /* an end marker xmlChar, 0 if none */
+    int n_end;
+    xmlChar end2; /* an end marker xmlChar, 0 if none */
+    int n_end2;
+    xmlChar end3; /* an end marker xmlChar, 0 if none */
+    int n_end3;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_what = 0;n_what < gen_nb_int;n_what++) {
+    for (n_end = 0;n_end < gen_nb_xmlChar;n_end++) {
+    for (n_end2 = 0;n_end2 < gen_nb_xmlChar;n_end2++) {
+    for (n_end3 = 0;n_end3 < gen_nb_xmlChar;n_end3++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+        what = gen_int(n_what, 2);
+        end = gen_xmlChar(n_end, 3);
+        end2 = gen_xmlChar(n_end2, 4);
+        end3 = gen_xmlChar(n_end3, 5);
+
+        ret_val = xmlStringDecodeEntities(ctxt, (const xmlChar *)str, what, end, end2, end3);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        des_int(n_what, what, 2);
+        des_xmlChar(n_end, end, 3);
+        des_xmlChar(n_end2, end2, 4);
+        des_xmlChar(n_end3, end3, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStringDecodeEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_str);
+            printf(" %d", n_what);
+            printf(" %d", n_end);
+            printf(" %d", n_end2);
+            printf(" %d", n_end3);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStringLenDecodeEntities(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlParserCtxtPtr ctxt; /* the parser context */
+    int n_ctxt;
+    xmlChar * str; /* the input string */
+    int n_str;
+    int len; /* the string length */
+    int n_len;
+    int what; /* combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF */
+    int n_what;
+    xmlChar end; /* an end marker xmlChar, 0 if none */
+    int n_end;
+    xmlChar end2; /* an end marker xmlChar, 0 if none */
+    int n_end2;
+    xmlChar end3; /* an end marker xmlChar, 0 if none */
+    int n_end3;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+    for (n_what = 0;n_what < gen_nb_int;n_what++) {
+    for (n_end = 0;n_end < gen_nb_xmlChar;n_end++) {
+    for (n_end2 = 0;n_end2 < gen_nb_xmlChar;n_end2++) {
+    for (n_end3 = 0;n_end3 < gen_nb_xmlChar;n_end3++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+        len = gen_int(n_len, 2);
+        what = gen_int(n_what, 3);
+        end = gen_xmlChar(n_end, 4);
+        end2 = gen_xmlChar(n_end2, 5);
+        end3 = gen_xmlChar(n_end3, 6);
+
+        ret_val = xmlStringLenDecodeEntities(ctxt, (const xmlChar *)str, len, what, end, end2, end3);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        des_int(n_len, len, 2);
+        des_int(n_what, what, 3);
+        des_xmlChar(n_end, end, 4);
+        des_xmlChar(n_end2, end2, 5);
+        des_xmlChar(n_end3, end3, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStringLenDecodeEntities",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_str);
+            printf(" %d", n_len);
+            printf(" %d", n_what);
+            printf(" %d", n_end);
+            printf(" %d", n_end2);
+            printf(" %d", n_end3);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSwitchEncoding(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* the parser context */
+    int n_ctxt;
+    xmlCharEncoding enc; /* the encoding value (number) */
+    int n_enc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        enc = gen_xmlCharEncoding(n_enc, 1);
+
+        ret_val = xmlSwitchEncoding(ctxt, enc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlCharEncoding(n_enc, enc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSwitchEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSwitchInputEncoding(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* the parser context */
+    int n_ctxt;
+    xmlParserInputPtr input; /* the input stream */
+    int n_input;
+    xmlCharEncodingHandlerPtr handler; /* the encoding handler */
+    int n_handler;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandlerPtr;n_handler++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        input = gen_xmlParserInputPtr(n_input, 1);
+        handler = gen_xmlCharEncodingHandlerPtr(n_handler, 2);
+
+        ret_val = xmlSwitchInputEncoding(ctxt, input, handler);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputPtr(n_input, input, 1);
+        des_xmlCharEncodingHandlerPtr(n_handler, handler, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSwitchInputEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_input);
+            printf(" %d", n_handler);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSwitchToEncoding(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserCtxtPtr ctxt; /* the parser context */
+    int n_ctxt;
+    xmlCharEncodingHandlerPtr handler; /* the encoding handler */
+    int n_handler;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandlerPtr;n_handler++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        handler = gen_xmlCharEncodingHandlerPtr(n_handler, 1);
+
+        ret_val = xmlSwitchToEncoding(ctxt, handler);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlCharEncodingHandlerPtr(n_handler, handler, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSwitchToEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_handler);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_parserInternals(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing parserInternals : 33 of 90 functions ...\n");
+    test_ret += test_htmlCreateFileParserCtxt();
+    test_ret += test_htmlInitAutoClose();
+    test_ret += test_inputPop();
+    test_ret += test_inputPush();
+    test_ret += test_namePop();
+    test_ret += test_namePush();
+    test_ret += test_nodePop();
+    test_ret += test_nodePush();
+    test_ret += test_xmlCheckLanguageID();
+    test_ret += test_xmlCopyChar();
+    test_ret += test_xmlCopyCharMultiByte();
+    test_ret += test_xmlCreateEntityParserCtxt();
+    test_ret += test_xmlCreateFileParserCtxt();
+    test_ret += test_xmlCreateMemoryParserCtxt();
+    test_ret += test_xmlCreateURLParserCtxt();
+    test_ret += test_xmlCurrentChar();
+    test_ret += test_xmlErrMemory();
+    test_ret += test_xmlIsLetter();
+    test_ret += test_xmlNewEntityInputStream();
+    test_ret += test_xmlNewInputFromFile();
+    test_ret += test_xmlNewInputStream();
+    test_ret += test_xmlNewStringInputStream();
+    test_ret += test_xmlNextChar();
+    test_ret += test_xmlParserInputShrink();
+    test_ret += test_xmlPopInput();
+    test_ret += test_xmlPushInput();
+    test_ret += test_xmlSetEntityReferenceFunc();
+    test_ret += test_xmlSplitQName();
+    test_ret += test_xmlStringCurrentChar();
+    test_ret += test_xmlStringDecodeEntities();
+    test_ret += test_xmlStringLenDecodeEntities();
+    test_ret += test_xmlSwitchEncoding();
+    test_ret += test_xmlSwitchInputEncoding();
+    test_ret += test_xmlSwitchToEncoding();
+
+    if (test_ret != 0)
+	printf("Module parserInternals: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlPatternFromRoot(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlPatternPtr comp; /* the precompiled pattern */
+    int n_comp;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlPatternPtr;n_comp++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlPatternPtr(n_comp, 0);
+
+        ret_val = xmlPatternFromRoot(comp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlPatternPtr(n_comp, comp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPatternFromRoot",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatternGetStreamCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatternMatch(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlPatternPtr comp; /* the precompiled pattern */
+    int n_comp;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlPatternPtr;n_comp++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlPatternPtr(n_comp, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlPatternMatch(comp, node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlPatternPtr(n_comp, comp, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPatternMatch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatternMaxDepth(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlPatternPtr comp; /* the precompiled pattern */
+    int n_comp;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlPatternPtr;n_comp++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlPatternPtr(n_comp, 0);
+
+        ret_val = xmlPatternMaxDepth(comp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlPatternPtr(n_comp, comp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPatternMaxDepth",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatternMinDepth(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlPatternPtr comp; /* the precompiled pattern */
+    int n_comp;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlPatternPtr;n_comp++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlPatternPtr(n_comp, 0);
+
+        ret_val = xmlPatternMinDepth(comp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlPatternPtr(n_comp, comp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPatternMinDepth",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatternStreamable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlPatternPtr comp; /* the precompiled pattern */
+    int n_comp;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlPatternPtr;n_comp++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlPatternPtr(n_comp, 0);
+
+        ret_val = xmlPatternStreamable(comp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlPatternPtr(n_comp, comp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPatternStreamable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPatterncompile(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_PATTERN_ENABLED
+
+#define gen_nb_xmlStreamCtxtPtr 1
+static xmlStreamCtxtPtr gen_xmlStreamCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlStreamCtxtPtr(int no ATTRIBUTE_UNUSED, xmlStreamCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlStreamPop(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlStreamCtxtPtr stream; /* the stream context */
+    int n_stream;
+
+    for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
+        mem_base = xmlMemBlocks();
+        stream = gen_xmlStreamCtxtPtr(n_stream, 0);
+
+        ret_val = xmlStreamPop(stream);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlStreamCtxtPtr(n_stream, stream, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStreamPop",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_stream);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStreamPush(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlStreamCtxtPtr stream; /* the stream context */
+    int n_stream;
+    xmlChar * name; /* the current name */
+    int n_name;
+    xmlChar * ns; /* the namespace name */
+    int n_ns;
+
+    for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns = 0;n_ns < gen_nb_const_xmlChar_ptr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        stream = gen_xmlStreamCtxtPtr(n_stream, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ns = gen_const_xmlChar_ptr(n_ns, 2);
+
+        ret_val = xmlStreamPush(stream, (const xmlChar *)name, (const xmlChar *)ns);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlStreamCtxtPtr(n_stream, stream, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStreamPush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_stream);
+            printf(" %d", n_name);
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStreamPushAttr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlStreamCtxtPtr stream; /* the stream context */
+    int n_stream;
+    xmlChar * name; /* the current name */
+    int n_name;
+    xmlChar * ns; /* the namespace name */
+    int n_ns;
+
+    for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns = 0;n_ns < gen_nb_const_xmlChar_ptr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        stream = gen_xmlStreamCtxtPtr(n_stream, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ns = gen_const_xmlChar_ptr(n_ns, 2);
+
+        ret_val = xmlStreamPushAttr(stream, (const xmlChar *)name, (const xmlChar *)ns);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlStreamCtxtPtr(n_stream, stream, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStreamPushAttr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_stream);
+            printf(" %d", n_name);
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStreamPushNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlStreamCtxtPtr stream; /* the stream context */
+    int n_stream;
+    xmlChar * name; /* the current name */
+    int n_name;
+    xmlChar * ns; /* the namespace name */
+    int n_ns;
+    int nodeType; /* the type of the node being pushed */
+    int n_nodeType;
+
+    for (n_stream = 0;n_stream < gen_nb_xmlStreamCtxtPtr;n_stream++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns = 0;n_ns < gen_nb_const_xmlChar_ptr;n_ns++) {
+    for (n_nodeType = 0;n_nodeType < gen_nb_int;n_nodeType++) {
+        mem_base = xmlMemBlocks();
+        stream = gen_xmlStreamCtxtPtr(n_stream, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ns = gen_const_xmlChar_ptr(n_ns, 2);
+        nodeType = gen_int(n_nodeType, 3);
+
+        ret_val = xmlStreamPushNode(stream, (const xmlChar *)name, (const xmlChar *)ns, nodeType);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlStreamCtxtPtr(n_stream, stream, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 2);
+        des_int(n_nodeType, nodeType, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStreamPushNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_stream);
+            printf(" %d", n_name);
+            printf(" %d", n_ns);
+            printf(" %d", n_nodeType);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStreamWantsAnyNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_PATTERN_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlStreamCtxtPtr streamCtxt; /* the stream context */
+    int n_streamCtxt;
+
+    for (n_streamCtxt = 0;n_streamCtxt < gen_nb_xmlStreamCtxtPtr;n_streamCtxt++) {
+        mem_base = xmlMemBlocks();
+        streamCtxt = gen_xmlStreamCtxtPtr(n_streamCtxt, 0);
+
+        ret_val = xmlStreamWantsAnyNode(streamCtxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlStreamCtxtPtr(n_streamCtxt, streamCtxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStreamWantsAnyNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_streamCtxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_pattern(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing pattern : 10 of 15 functions ...\n");
+    test_ret += test_xmlPatternFromRoot();
+    test_ret += test_xmlPatternGetStreamCtxt();
+    test_ret += test_xmlPatternMatch();
+    test_ret += test_xmlPatternMaxDepth();
+    test_ret += test_xmlPatternMinDepth();
+    test_ret += test_xmlPatternStreamable();
+    test_ret += test_xmlPatterncompile();
+    test_ret += test_xmlStreamPop();
+    test_ret += test_xmlStreamPush();
+    test_ret += test_xmlStreamPushAttr();
+    test_ret += test_xmlStreamPushNode();
+    test_ret += test_xmlStreamWantsAnyNode();
+
+    if (test_ret != 0)
+	printf("Module pattern: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlRelaxNGPtr 1
+static xmlRelaxNGPtr gen_xmlRelaxNGPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRelaxNGPtr(int no ATTRIBUTE_UNUSED, xmlRelaxNGPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlRelaxNGDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * output; /* the file output */
+    int n_output;
+    xmlRelaxNGPtr schema; /* a schema structure */
+    int n_schema;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_schema = 0;n_schema < gen_nb_xmlRelaxNGPtr;n_schema++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        schema = gen_xmlRelaxNGPtr(n_schema, 1);
+
+        xmlRelaxNGDump(output, schema);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlRelaxNGPtr(n_schema, schema, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_schema);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGDumpTree(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * output; /* the file output */
+    int n_output;
+    xmlRelaxNGPtr schema; /* a schema structure */
+    int n_schema;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_schema = 0;n_schema < gen_nb_xmlRelaxNGPtr;n_schema++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        schema = gen_xmlRelaxNGPtr(n_schema, 1);
+
+        xmlRelaxNGDumpTree(output, schema);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlRelaxNGPtr(n_schema, schema, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGDumpTree",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_schema);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlRelaxNGParserCtxtPtr 1
+static xmlRelaxNGParserCtxtPtr gen_xmlRelaxNGParserCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRelaxNGParserCtxtPtr(int no ATTRIBUTE_UNUSED, xmlRelaxNGParserCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlRelaxNGValidityErrorFunc_ptr 1
+static xmlRelaxNGValidityErrorFunc * gen_xmlRelaxNGValidityErrorFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRelaxNGValidityErrorFunc_ptr(int no ATTRIBUTE_UNUSED, xmlRelaxNGValidityErrorFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlRelaxNGValidityWarningFunc_ptr 1
+static xmlRelaxNGValidityWarningFunc * gen_xmlRelaxNGValidityWarningFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRelaxNGValidityWarningFunc_ptr(int no ATTRIBUTE_UNUSED, xmlRelaxNGValidityWarningFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlRelaxNGGetParserErrors(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGParserCtxtPtr ctxt; /* a Relax-NG validation context */
+    int n_ctxt;
+    xmlRelaxNGValidityErrorFunc * err; /* the error callback result */
+    int n_err;
+    xmlRelaxNGValidityWarningFunc * warn; /* the warning callback result */
+    int n_warn;
+    void ** ctx; /* contextual data for the callbacks result */
+    int n_ctx;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGParserCtxtPtr;n_ctxt++) {
+    for (n_err = 0;n_err < gen_nb_xmlRelaxNGValidityErrorFunc_ptr;n_err++) {
+    for (n_warn = 0;n_warn < gen_nb_xmlRelaxNGValidityWarningFunc_ptr;n_warn++) {
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGParserCtxtPtr(n_ctxt, 0);
+        err = gen_xmlRelaxNGValidityErrorFunc_ptr(n_err, 1);
+        warn = gen_xmlRelaxNGValidityWarningFunc_ptr(n_warn, 2);
+        ctx = gen_void_ptr_ptr(n_ctx, 3);
+
+        ret_val = xmlRelaxNGGetParserErrors(ctxt, err, warn, ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlRelaxNGValidityErrorFunc_ptr(n_err, err, 1);
+        des_xmlRelaxNGValidityWarningFunc_ptr(n_warn, warn, 2);
+        des_void_ptr_ptr(n_ctx, ctx, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGGetParserErrors",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_err);
+            printf(" %d", n_warn);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlRelaxNGValidCtxtPtr 1
+static xmlRelaxNGValidCtxtPtr gen_xmlRelaxNGValidCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRelaxNGValidCtxtPtr(int no ATTRIBUTE_UNUSED, xmlRelaxNGValidCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlRelaxNGGetValidErrors(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* a Relax-NG validation context */
+    int n_ctxt;
+    xmlRelaxNGValidityErrorFunc * err; /* the error function result */
+    int n_err;
+    xmlRelaxNGValidityWarningFunc * warn; /* the warning function result */
+    int n_warn;
+    void ** ctx; /* the functions context result */
+    int n_ctx;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_err = 0;n_err < gen_nb_xmlRelaxNGValidityErrorFunc_ptr;n_err++) {
+    for (n_warn = 0;n_warn < gen_nb_xmlRelaxNGValidityWarningFunc_ptr;n_warn++) {
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        err = gen_xmlRelaxNGValidityErrorFunc_ptr(n_err, 1);
+        warn = gen_xmlRelaxNGValidityWarningFunc_ptr(n_warn, 2);
+        ctx = gen_void_ptr_ptr(n_ctx, 3);
+
+        ret_val = xmlRelaxNGGetValidErrors(ctxt, err, warn, ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlRelaxNGValidityErrorFunc_ptr(n_err, err, 1);
+        des_xmlRelaxNGValidityWarningFunc_ptr(n_warn, warn, 2);
+        des_void_ptr_ptr(n_ctx, ctx, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGGetValidErrors",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_err);
+            printf(" %d", n_warn);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGInitTypes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlRelaxNGInitTypes();
+        desret_int(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGInitTypes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGNewDocParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlRelaxNGParserCtxtPtr ret_val;
+    xmlDocPtr doc; /* a preparsed document tree */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlRelaxNGNewDocParserCtxt(doc);
+        desret_xmlRelaxNGParserCtxtPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGNewDocParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGNewMemParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlRelaxNGParserCtxtPtr ret_val;
+    char * buffer; /* a pointer to a char array containing the schemas */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = xmlRelaxNGNewMemParserCtxt((const char *)buffer, size);
+        desret_xmlRelaxNGParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGNewMemParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGNewParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlRelaxNGParserCtxtPtr ret_val;
+    char * URL; /* the location of the schema */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_const_char_ptr(n_URL, 0);
+
+        ret_val = xmlRelaxNGNewParserCtxt((const char *)URL);
+        desret_xmlRelaxNGParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_URL, (const char *)URL, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGNewParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGNewValidCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGParse(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGSetParserErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGSetParserStructuredErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGSetValidErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGSetValidStructuredErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGValidateDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* a Relax-NG validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a parsed document tree */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlRelaxNGValidateDoc(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGValidateDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGValidateFullElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+
+        ret_val = xmlRelaxNGValidateFullElement(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGValidateFullElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGValidatePopElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* the RelaxNG validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+
+        ret_val = xmlRelaxNGValidatePopElement(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGValidatePopElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGValidatePushCData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* the RelaxNG validation context */
+    int n_ctxt;
+    xmlChar * data; /* some character data read */
+    int n_data;
+    int len; /* the lenght of the data */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_data = 0;n_data < gen_nb_const_xmlChar_ptr;n_data++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        data = gen_const_xmlChar_ptr(n_data, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlRelaxNGValidatePushCData(ctxt, (const xmlChar *)data, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGValidatePushCData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_data);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxNGValidatePushElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+
+        ret_val = xmlRelaxNGValidatePushElement(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxNGValidatePushElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRelaxParserSetFlag(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRelaxNGParserCtxtPtr ctxt; /* a RelaxNG parser context */
+    int n_ctxt;
+    int flags; /* a set of flags values */
+    int n_flags;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlRelaxNGParserCtxtPtr;n_ctxt++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlRelaxNGParserCtxtPtr(n_ctxt, 0);
+        flags = gen_int(n_flags, 1);
+
+        ret_val = xmlRelaxParserSetFlag(ctxt, flags);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRelaxNGParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_int(n_flags, flags, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRelaxParserSetFlag",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_flags);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_relaxng(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing relaxng : 14 of 24 functions ...\n");
+    test_ret += test_xmlRelaxNGDump();
+    test_ret += test_xmlRelaxNGDumpTree();
+    test_ret += test_xmlRelaxNGGetParserErrors();
+    test_ret += test_xmlRelaxNGGetValidErrors();
+    test_ret += test_xmlRelaxNGInitTypes();
+    test_ret += test_xmlRelaxNGNewDocParserCtxt();
+    test_ret += test_xmlRelaxNGNewMemParserCtxt();
+    test_ret += test_xmlRelaxNGNewParserCtxt();
+    test_ret += test_xmlRelaxNGNewValidCtxt();
+    test_ret += test_xmlRelaxNGParse();
+    test_ret += test_xmlRelaxNGSetParserErrors();
+    test_ret += test_xmlRelaxNGSetParserStructuredErrors();
+    test_ret += test_xmlRelaxNGSetValidErrors();
+    test_ret += test_xmlRelaxNGSetValidStructuredErrors();
+    test_ret += test_xmlRelaxNGValidateDoc();
+    test_ret += test_xmlRelaxNGValidateFullElement();
+    test_ret += test_xmlRelaxNGValidatePopElement();
+    test_ret += test_xmlRelaxNGValidatePushCData();
+    test_ret += test_xmlRelaxNGValidatePushElement();
+    test_ret += test_xmlRelaxParserSetFlag();
+
+    if (test_ret != 0)
+	printf("Module relaxng: %d errors\n", test_ret);
+    return(test_ret);
+}
+static int
+test_schemasInternals(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing schemasInternals : 0 of 2 functions ...\n");
+
+    if (test_ret != 0)
+	printf("Module schemasInternals: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlSchematronNewDocParserCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchematronNewMemParserCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchematronNewParserCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#define gen_nb_xmlSchematronPtr 1
+static xmlSchematronPtr gen_xmlSchematronPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchematronPtr(int no ATTRIBUTE_UNUSED, xmlSchematronPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchematronNewValidCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#define gen_nb_xmlSchematronParserCtxtPtr 1
+static xmlSchematronParserCtxtPtr gen_xmlSchematronParserCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchematronParserCtxtPtr(int no ATTRIBUTE_UNUSED, xmlSchematronParserCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchematronParse(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#define gen_nb_xmlSchematronValidCtxtPtr 1
+static xmlSchematronValidCtxtPtr gen_xmlSchematronValidCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchematronValidCtxtPtr(int no ATTRIBUTE_UNUSED, xmlSchematronValidCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchematronSetValidStructuredErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchematronValidateDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMATRON_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchematronValidCtxtPtr ctxt; /* the schema validation context */
+    int n_ctxt;
+    xmlDocPtr instance; /* the document instace tree */
+    int n_instance;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchematronValidCtxtPtr;n_ctxt++) {
+    for (n_instance = 0;n_instance < gen_nb_xmlDocPtr;n_instance++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchematronValidCtxtPtr(n_ctxt, 0);
+        instance = gen_xmlDocPtr(n_instance, 1);
+
+        ret_val = xmlSchematronValidateDoc(ctxt, instance);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchematronValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_instance, instance, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchematronValidateDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_instance);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_schematron(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing schematron : 1 of 10 functions ...\n");
+    test_ret += test_xmlSchematronNewDocParserCtxt();
+    test_ret += test_xmlSchematronNewMemParserCtxt();
+    test_ret += test_xmlSchematronNewParserCtxt();
+    test_ret += test_xmlSchematronNewValidCtxt();
+    test_ret += test_xmlSchematronParse();
+    test_ret += test_xmlSchematronSetValidStructuredErrors();
+    test_ret += test_xmlSchematronValidateDoc();
+
+    if (test_ret != 0)
+	printf("Module schematron: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlAddChild(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+    xmlNodePtr cur; /* the child node */
+    int n_cur;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+        cur = gen_xmlNodePtr_in(n_cur, 1);
+
+        ret_val = xmlAddChild(parent, cur);
+        if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        des_xmlNodePtr_in(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddChildList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+    xmlNodePtr cur; /* the first node in the list */
+    int n_cur;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+        cur = gen_xmlNodePtr_in(n_cur, 1);
+
+        ret_val = xmlAddChildList(parent, cur);
+        if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        des_xmlNodePtr_in(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddChildList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddNextSibling(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr cur; /* the child node */
+    int n_cur;
+    xmlNodePtr elem; /* the new node */
+    int n_elem;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        elem = gen_xmlNodePtr_in(n_elem, 1);
+
+        ret_val = xmlAddNextSibling(cur, elem);
+        if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_xmlNodePtr_in(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddNextSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddPrevSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr cur; /* the child node */
+    int n_cur;
+    xmlNodePtr elem; /* the new node */
+    int n_elem;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        elem = gen_xmlNodePtr_in(n_elem, 1);
+
+        ret_val = xmlAddPrevSibling(cur, elem);
+        if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_xmlNodePtr_in(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddPrevSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddSibling(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr cur; /* the child node */
+    int n_cur;
+    xmlNodePtr elem; /* the new node */
+    int n_elem;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr_in;n_elem++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        elem = gen_xmlNodePtr_in(n_elem, 1);
+
+        ret_val = xmlAddSibling(cur, elem);
+        if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_xmlNodePtr_in(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAttrSerializeTxtContent(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef LIBXML_OUTPUT_ENABLED
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlAttrPtr attr; /* the attribute node */
+    int n_attr;
+    xmlChar * string; /* the text content */
+    int n_string;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        attr = gen_xmlAttrPtr(n_attr, 2);
+        string = gen_const_xmlChar_ptr(n_string, 3);
+
+        xmlAttrSerializeTxtContent(buf, doc, attr, (const xmlChar *)string);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlAttrPtr(n_attr, attr, 2);
+        des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAttrSerializeTxtContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_attr);
+            printf(" %d", n_string);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferAdd(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer to dump */
+    int n_buf;
+    xmlChar * str; /* the #xmlChar string */
+    int n_str;
+    int len; /* the number of #xmlChar to add */
+    int n_len;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlBufferAdd(buf, (const xmlChar *)str, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferAdd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_str);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferAddHead(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer */
+    int n_buf;
+    xmlChar * str; /* the #xmlChar string */
+    int n_str;
+    int len; /* the number of #xmlChar to add */
+    int n_len;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlBufferAddHead(buf, (const xmlChar *)str, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferAddHead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_str);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferCCat(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer to dump */
+    int n_buf;
+    char * str; /* the C char string */
+    int n_str;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_str = 0;n_str < gen_nb_const_char_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        str = gen_const_char_ptr(n_str, 1);
+
+        ret_val = xmlBufferCCat(buf, (const char *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_char_ptr(n_str, (const char *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferCCat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferCat(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer to add to */
+    int n_buf;
+    xmlChar * str; /* the #xmlChar string */
+    int n_str;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+
+        ret_val = xmlBufferCat(buf, (const xmlChar *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferCat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_const_xmlBufferPtr 1
+static xmlBufferPtr gen_const_xmlBufferPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_const_xmlBufferPtr(int no ATTRIBUTE_UNUSED, const xmlBufferPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlBufferContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlBufferPtr buf; /* the buffer */
+    int n_buf;
+
+    for (n_buf = 0;n_buf < gen_nb_const_xmlBufferPtr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_const_xmlBufferPtr(n_buf, 0);
+
+        ret_val = xmlBufferContent((const xmlBufferPtr)buf);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlBufferPtr(n_buf, (const xmlBufferPtr)buf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferCreate(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlBufferCreate();
+        desret_xmlBufferPtr(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferCreate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferCreateSize(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferCreateStatic(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferEmpty(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr buf; /* the buffer */
+    int n_buf;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+
+        xmlBufferEmpty(buf);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferEmpty",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferGrow(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer */
+    int n_buf;
+    unsigned int len; /* the minimum free size to allocate */
+    int n_len;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_len = 0;n_len < gen_nb_unsigned_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        len = gen_unsigned_int(n_len, 1);
+
+        ret_val = xmlBufferGrow(buf, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_unsigned_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferGrow",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferLength(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer */
+    int n_buf;
+
+    for (n_buf = 0;n_buf < gen_nb_const_xmlBufferPtr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_const_xmlBufferPtr(n_buf, 0);
+
+        ret_val = xmlBufferLength((const xmlBufferPtr)buf);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlBufferPtr(n_buf, (const xmlBufferPtr)buf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferLength",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferResize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer to resize */
+    int n_buf;
+    unsigned int size; /* the desired size */
+    int n_size;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_size = 0;n_size < gen_nb_unsigned_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        size = gen_unsigned_int(n_size, 1);
+
+        ret_val = xmlBufferResize(buf, size);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_unsigned_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferResize",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferSetAllocationScheme(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr buf; /* the buffer to tune */
+    int n_buf;
+    xmlBufferAllocationScheme scheme; /* allocation scheme to use */
+    int n_scheme;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_scheme = 0;n_scheme < gen_nb_xmlBufferAllocationScheme;n_scheme++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        scheme = gen_xmlBufferAllocationScheme(n_scheme, 1);
+
+        xmlBufferSetAllocationScheme(buf, scheme);
+        if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlBufferAllocationScheme(n_scheme, scheme, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferSetAllocationScheme",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_scheme);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferShrink(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the buffer to dump */
+    int n_buf;
+    unsigned int len; /* the number of xmlChar to remove */
+    int n_len;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_len = 0;n_len < gen_nb_unsigned_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        len = gen_unsigned_int(n_len, 1);
+
+        ret_val = xmlBufferShrink(buf, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_unsigned_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferShrink",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferWriteCHAR(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer */
+    int n_buf;
+    xmlChar * string; /* the string to add */
+    int n_string;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        string = gen_const_xmlChar_ptr(n_string, 1);
+
+        xmlBufferWriteCHAR(buf, (const xmlChar *)string);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferWriteCHAR",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_string);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferWriteChar(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    char * string; /* the string to add */
+    int n_string;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_string = 0;n_string < gen_nb_const_char_ptr;n_string++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        string = gen_const_char_ptr(n_string, 1);
+
+        xmlBufferWriteChar(buf, (const char *)string);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_char_ptr(n_string, (const char *)string, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferWriteChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_string);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBufferWriteQuotedString(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlChar * string; /* the string to add */
+    int n_string;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr;n_string++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        string = gen_const_xmlChar_ptr(n_string, 1);
+
+        xmlBufferWriteQuotedString(buf, (const xmlChar *)string);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_const_xmlChar_ptr(n_string, (const xmlChar *)string, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBufferWriteQuotedString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_string);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBuildQName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * ncname; /* the Name */
+    int n_ncname;
+    xmlChar * prefix; /* the prefix */
+    int n_prefix;
+    xmlChar * memory; /* preallocated memory */
+    int n_memory;
+    int len; /* preallocated memory length */
+    int n_len;
+
+    for (n_ncname = 0;n_ncname < gen_nb_const_xmlChar_ptr;n_ncname++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_memory = 0;n_memory < gen_nb_xmlChar_ptr;n_memory++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ncname = gen_const_xmlChar_ptr(n_ncname, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        memory = gen_xmlChar_ptr(n_memory, 2);
+        len = gen_int(n_len, 3);
+
+        ret_val = xmlBuildQName((const xmlChar *)ncname, (const xmlChar *)prefix, memory, len);
+        if ((ret_val != NULL) && (ret_val != ncname) &&
+              (ret_val != prefix) && (ret_val != memory))
+              xmlFree(ret_val);
+	  ret_val = NULL;
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_ncname, (const xmlChar *)ncname, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_xmlChar_ptr(n_memory, memory, 2);
+        des_int(n_len, len, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBuildQName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ncname);
+            printf(" %d", n_prefix);
+            printf(" %d", n_memory);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlChildElementCount(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    unsigned long ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+
+        ret_val = xmlChildElementCount(parent);
+        desret_unsigned_long(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlChildElementCount",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    int recursive; /* if not zero do a recursive copy. */
+    int n_recursive;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_recursive = 0;n_recursive < gen_nb_int;n_recursive++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        recursive = gen_int(n_recursive, 1);
+
+        ret_val = xmlCopyDoc(doc, recursive);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_int(n_recursive, recursive, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_recursive);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyDtd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlDtdPtr dtd; /* the dtd */
+    int n_dtd;
+
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+        mem_base = xmlMemBlocks();
+        dtd = gen_xmlDtdPtr(n_dtd, 0);
+
+        ret_val = xmlCopyDtd(dtd);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlDtdPtr(n_dtd, dtd, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyDtd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dtd);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyNamespace(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNsPtr ret_val;
+    xmlNsPtr cur; /* the namespace */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNsPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNsPtr(n_cur, 0);
+
+        ret_val = xmlCopyNamespace(cur);
+        if (ret_val != NULL) xmlFreeNs(ret_val);
+        desret_xmlNsPtr(ret_val);
+        call_tests++;
+        des_xmlNsPtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyNamespace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyNamespaceList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNsPtr ret_val;
+    xmlNsPtr cur; /* the first namespace */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNsPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNsPtr(n_cur, 0);
+
+        ret_val = xmlCopyNamespaceList(cur);
+        if (ret_val != NULL) xmlFreeNsList(ret_val);
+        desret_xmlNsPtr(ret_val);
+        call_tests++;
+        des_xmlNsPtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyNamespaceList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    int extended; /* if 1 do a recursive copy (properties, namespaces and children when applicable) if 2 copy properties and namespaces (when applicable) */
+    int n_extended;
+
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+    for (n_extended = 0;n_extended < gen_nb_int;n_extended++) {
+        mem_base = xmlMemBlocks();
+        node = gen_const_xmlNodePtr(n_node, 0);
+        extended = gen_int(n_extended, 1);
+
+        ret_val = xmlCopyNode((const xmlNodePtr)node, extended);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 0);
+        des_int(n_extended, extended, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_extended);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyNodeList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr node; /* the first node in the list. */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_const_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlCopyNodeList((const xmlNodePtr)node);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr target; /* the element where the attribute will be grafted */
+    int n_target;
+    xmlAttrPtr cur; /* the attribute */
+    int n_cur;
+
+    for (n_target = 0;n_target < gen_nb_xmlNodePtr;n_target++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlAttrPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        target = gen_xmlNodePtr(n_target, 0);
+        cur = gen_xmlAttrPtr(n_cur, 1);
+
+        ret_val = xmlCopyProp(target, cur);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_target, target, 0);
+        des_xmlAttrPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_target);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyPropList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr target; /* the element where the attributes will be grafted */
+    int n_target;
+    xmlAttrPtr cur; /* the first attribute */
+    int n_cur;
+
+    for (n_target = 0;n_target < gen_nb_xmlNodePtr;n_target++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlAttrPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        target = gen_xmlNodePtr(n_target, 0);
+        cur = gen_xmlAttrPtr(n_cur, 1);
+
+        ret_val = xmlCopyPropList(target, cur);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_target, target, 0);
+        des_xmlAttrPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyPropList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_target);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateIntSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlDocPtr doc; /* the document pointer */
+    int n_doc;
+    xmlChar * name; /* the DTD name */
+    int n_name;
+    xmlChar * ExternalID; /* the external (PUBLIC) ID */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the system ID */
+    int n_SystemID;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
+
+        ret_val = xmlCreateIntSubset(doc, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCreateIntSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlDOMWrapCtxtPtr 1
+static xmlDOMWrapCtxtPtr gen_xmlDOMWrapCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlDOMWrapCtxtPtr(int no ATTRIBUTE_UNUSED, xmlDOMWrapCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlDOMWrapAdoptNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDOMWrapCtxtPtr ctxt; /* the optional context for custom processing */
+    int n_ctxt;
+    xmlDocPtr sourceDoc; /* the optional sourceDoc */
+    int n_sourceDoc;
+    xmlNodePtr node; /* the node to start with */
+    int n_node;
+    xmlDocPtr destDoc; /* the destination doc */
+    int n_destDoc;
+    xmlNodePtr destParent; /* the optional new parent of @node in @destDoc */
+    int n_destParent;
+    int options; /* option flags */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlDOMWrapCtxtPtr;n_ctxt++) {
+    for (n_sourceDoc = 0;n_sourceDoc < gen_nb_xmlDocPtr;n_sourceDoc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_destDoc = 0;n_destDoc < gen_nb_xmlDocPtr;n_destDoc++) {
+    for (n_destParent = 0;n_destParent < gen_nb_xmlNodePtr;n_destParent++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlDOMWrapCtxtPtr(n_ctxt, 0);
+        sourceDoc = gen_xmlDocPtr(n_sourceDoc, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        destDoc = gen_xmlDocPtr(n_destDoc, 3);
+        destParent = gen_xmlNodePtr(n_destParent, 4);
+        options = gen_int(n_options, 5);
+
+        ret_val = xmlDOMWrapAdoptNode(ctxt, sourceDoc, node, destDoc, destParent, options);
+        if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDOMWrapCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_sourceDoc, sourceDoc, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlDocPtr(n_destDoc, destDoc, 3);
+        des_xmlNodePtr(n_destParent, destParent, 4);
+        des_int(n_options, options, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDOMWrapAdoptNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_sourceDoc);
+            printf(" %d", n_node);
+            printf(" %d", n_destDoc);
+            printf(" %d", n_destParent);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDOMWrapCloneNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDOMWrapCtxtPtr ctxt; /* the optional context for custom processing */
+    int n_ctxt;
+    xmlDocPtr sourceDoc; /* the optional sourceDoc */
+    int n_sourceDoc;
+    xmlNodePtr node; /* the node to start with */
+    int n_node;
+    xmlNodePtr * resNode; /* the clone of the given @node */
+    int n_resNode;
+    xmlDocPtr destDoc; /* the destination doc */
+    int n_destDoc;
+    xmlNodePtr destParent; /* the optional new parent of @node in @destDoc */
+    int n_destParent;
+    int deep; /* descend into child if set */
+    int n_deep;
+    int options; /* option flags */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlDOMWrapCtxtPtr;n_ctxt++) {
+    for (n_sourceDoc = 0;n_sourceDoc < gen_nb_xmlDocPtr;n_sourceDoc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_resNode = 0;n_resNode < gen_nb_xmlNodePtr_ptr;n_resNode++) {
+    for (n_destDoc = 0;n_destDoc < gen_nb_xmlDocPtr;n_destDoc++) {
+    for (n_destParent = 0;n_destParent < gen_nb_xmlNodePtr;n_destParent++) {
+    for (n_deep = 0;n_deep < gen_nb_int;n_deep++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlDOMWrapCtxtPtr(n_ctxt, 0);
+        sourceDoc = gen_xmlDocPtr(n_sourceDoc, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        resNode = gen_xmlNodePtr_ptr(n_resNode, 3);
+        destDoc = gen_xmlDocPtr(n_destDoc, 4);
+        destParent = gen_xmlNodePtr(n_destParent, 5);
+        deep = gen_int(n_deep, 6);
+        options = gen_int(n_options, 7);
+
+        ret_val = xmlDOMWrapCloneNode(ctxt, sourceDoc, node, resNode, destDoc, destParent, deep, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDOMWrapCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_sourceDoc, sourceDoc, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_xmlNodePtr_ptr(n_resNode, resNode, 3);
+        des_xmlDocPtr(n_destDoc, destDoc, 4);
+        des_xmlNodePtr(n_destParent, destParent, 5);
+        des_int(n_deep, deep, 6);
+        des_int(n_options, options, 7);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDOMWrapCloneNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_sourceDoc);
+            printf(" %d", n_node);
+            printf(" %d", n_resNode);
+            printf(" %d", n_destDoc);
+            printf(" %d", n_destParent);
+            printf(" %d", n_deep);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDOMWrapNewCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlDOMWrapReconcileNamespaces(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDOMWrapCtxtPtr ctxt; /* DOM wrapper context, unused at the moment */
+    int n_ctxt;
+    xmlNodePtr elem; /* the element-node */
+    int n_elem;
+    int options; /* option flags */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlDOMWrapCtxtPtr;n_ctxt++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlDOMWrapCtxtPtr(n_ctxt, 0);
+        elem = gen_xmlNodePtr(n_elem, 1);
+        options = gen_int(n_options, 2);
+
+        ret_val = xmlDOMWrapReconcileNamespaces(ctxt, elem, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDOMWrapCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_elem, elem, 1);
+        des_int(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDOMWrapReconcileNamespaces",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_elem);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDOMWrapRemoveNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDOMWrapCtxtPtr ctxt; /* a DOM wrapper context */
+    int n_ctxt;
+    xmlDocPtr doc; /* the doc */
+    int n_doc;
+    xmlNodePtr node; /* the node to be removed. */
+    int n_node;
+    int options; /* set of options, unused at the moment */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlDOMWrapCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlDOMWrapCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        node = gen_xmlNodePtr(n_node, 2);
+        options = gen_int(n_options, 3);
+
+        ret_val = xmlDOMWrapRemoveNode(ctxt, doc, node, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDOMWrapCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_node, node, 2);
+        des_int(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDOMWrapRemoveNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_node);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocCopyNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    int extended; /* if 1 do a recursive copy (properties, namespaces and children when applicable) if 2 copy properties and namespaces (when applicable) */
+    int n_extended;
+
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_extended = 0;n_extended < gen_nb_int;n_extended++) {
+        mem_base = xmlMemBlocks();
+        node = gen_const_xmlNodePtr(n_node, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        extended = gen_int(n_extended, 2);
+
+        ret_val = xmlDocCopyNode((const xmlNodePtr)node, doc, extended);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_int(n_extended, extended, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocCopyNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_doc);
+            printf(" %d", n_extended);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocCopyNodeList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the target document */
+    int n_doc;
+    xmlNodePtr node; /* the first node in the list. */
+    int n_node;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_node = 0;n_node < gen_nb_const_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        node = gen_const_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlDocCopyNodeList(doc, (const xmlNodePtr)node);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlNodePtr(n_node, (const xmlNodePtr)node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocCopyNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    FILE * f; /* the FILE* */
+    int n_f;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+
+    for (n_f = 0;n_f < gen_nb_FILE_ptr;n_f++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        f = gen_FILE_ptr(n_f, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+
+        ret_val = xmlDocDump(f, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_f, f, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_f);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocDumpFormatMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    xmlChar ** mem; /* OUT: the memory pointer */
+    int n_mem;
+    int * size; /* OUT: the memory length */
+    int n_size;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_mem = 0;n_mem < gen_nb_xmlChar_ptr_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int_ptr;n_size++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlDocPtr(n_cur, 0);
+        mem = gen_xmlChar_ptr_ptr(n_mem, 1);
+        size = gen_int_ptr(n_size, 2);
+        format = gen_int(n_format, 3);
+
+        xmlDocDumpFormatMemory(cur, mem, size, format);
+        call_tests++;
+        des_xmlDocPtr(n_cur, cur, 0);
+        des_xmlChar_ptr_ptr(n_mem, mem, 1);
+        des_int_ptr(n_size, size, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocDumpFormatMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocDumpFormatMemoryEnc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr out_doc; /* Document to generate XML text from */
+    int n_out_doc;
+    xmlChar ** doc_txt_ptr; /* Memory pointer for allocated XML text */
+    int n_doc_txt_ptr;
+    int * doc_txt_len; /* Length of the generated XML text */
+    int n_doc_txt_len;
+    char * txt_encoding; /* Character encoding to use when generating XML text */
+    int n_txt_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_out_doc = 0;n_out_doc < gen_nb_xmlDocPtr;n_out_doc++) {
+    for (n_doc_txt_ptr = 0;n_doc_txt_ptr < gen_nb_xmlChar_ptr_ptr;n_doc_txt_ptr++) {
+    for (n_doc_txt_len = 0;n_doc_txt_len < gen_nb_int_ptr;n_doc_txt_len++) {
+    for (n_txt_encoding = 0;n_txt_encoding < gen_nb_const_char_ptr;n_txt_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        out_doc = gen_xmlDocPtr(n_out_doc, 0);
+        doc_txt_ptr = gen_xmlChar_ptr_ptr(n_doc_txt_ptr, 1);
+        doc_txt_len = gen_int_ptr(n_doc_txt_len, 2);
+        txt_encoding = gen_const_char_ptr(n_txt_encoding, 3);
+        format = gen_int(n_format, 4);
+
+        xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, (const char *)txt_encoding, format);
+        call_tests++;
+        des_xmlDocPtr(n_out_doc, out_doc, 0);
+        des_xmlChar_ptr_ptr(n_doc_txt_ptr, doc_txt_ptr, 1);
+        des_int_ptr(n_doc_txt_len, doc_txt_len, 2);
+        des_const_char_ptr(n_txt_encoding, (const char *)txt_encoding, 3);
+        des_int(n_format, format, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocDumpFormatMemoryEnc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out_doc);
+            printf(" %d", n_doc_txt_ptr);
+            printf(" %d", n_doc_txt_len);
+            printf(" %d", n_txt_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocDumpMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    xmlChar ** mem; /* OUT: the memory pointer */
+    int n_mem;
+    int * size; /* OUT: the memory length */
+    int n_size;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_mem = 0;n_mem < gen_nb_xmlChar_ptr_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int_ptr;n_size++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlDocPtr(n_cur, 0);
+        mem = gen_xmlChar_ptr_ptr(n_mem, 1);
+        size = gen_int_ptr(n_size, 2);
+
+        xmlDocDumpMemory(cur, mem, size);
+        call_tests++;
+        des_xmlDocPtr(n_cur, cur, 0);
+        des_xmlChar_ptr_ptr(n_mem, mem, 1);
+        des_int_ptr(n_size, size, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocDumpMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocDumpMemoryEnc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlDocPtr out_doc; /* Document to generate XML text from */
+    int n_out_doc;
+    xmlChar ** doc_txt_ptr; /* Memory pointer for allocated XML text */
+    int n_doc_txt_ptr;
+    int * doc_txt_len; /* Length of the generated XML text */
+    int n_doc_txt_len;
+    char * txt_encoding; /* Character encoding to use when generating XML text */
+    int n_txt_encoding;
+
+    for (n_out_doc = 0;n_out_doc < gen_nb_xmlDocPtr;n_out_doc++) {
+    for (n_doc_txt_ptr = 0;n_doc_txt_ptr < gen_nb_xmlChar_ptr_ptr;n_doc_txt_ptr++) {
+    for (n_doc_txt_len = 0;n_doc_txt_len < gen_nb_int_ptr;n_doc_txt_len++) {
+    for (n_txt_encoding = 0;n_txt_encoding < gen_nb_const_char_ptr;n_txt_encoding++) {
+        mem_base = xmlMemBlocks();
+        out_doc = gen_xmlDocPtr(n_out_doc, 0);
+        doc_txt_ptr = gen_xmlChar_ptr_ptr(n_doc_txt_ptr, 1);
+        doc_txt_len = gen_int_ptr(n_doc_txt_len, 2);
+        txt_encoding = gen_const_char_ptr(n_txt_encoding, 3);
+
+        xmlDocDumpMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, (const char *)txt_encoding);
+        call_tests++;
+        des_xmlDocPtr(n_out_doc, out_doc, 0);
+        des_xmlChar_ptr_ptr(n_doc_txt_ptr, doc_txt_ptr, 1);
+        des_int_ptr(n_doc_txt_len, doc_txt_len, 2);
+        des_const_char_ptr(n_txt_encoding, (const char *)txt_encoding, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocDumpMemoryEnc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out_doc);
+            printf(" %d", n_doc_txt_ptr);
+            printf(" %d", n_doc_txt_len);
+            printf(" %d", n_txt_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocFormatDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    FILE * f; /* the FILE* */
+    int n_f;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_f = 0;n_f < gen_nb_FILE_ptr;n_f++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        f = gen_FILE_ptr(n_f, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        format = gen_int(n_format, 2);
+
+        ret_val = xmlDocFormatDump(f, cur, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_f, f, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_int(n_format, format, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocFormatDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_f);
+            printf(" %d", n_cur);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocGetRootElement(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlDocGetRootElement(doc);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocGetRootElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDocSetRootElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr root; /* the new document root element, if root is NULL no action is taken, to remove a node from a document use xmlUnlinkNode(root) instead. */
+    int n_root;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_root = 0;n_root < gen_nb_xmlNodePtr_in;n_root++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        root = gen_xmlNodePtr_in(n_root, 1);
+
+        ret_val = xmlDocSetRootElement(doc, root);
+        if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr_in(n_root, root, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDocSetRootElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_root);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlElemDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * f; /* the FILE * for the output */
+    int n_f;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+
+    for (n_f = 0;n_f < gen_nb_FILE_ptr;n_f++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        f = gen_FILE_ptr(n_f, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+
+        xmlElemDump(f, doc, cur);
+        call_tests++;
+        des_FILE_ptr(n_f, f, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlElemDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_f);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFirstElementChild(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+
+        ret_val = xmlFirstElementChild(parent);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlFirstElementChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetBufferAllocationScheme(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferAllocationScheme ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlGetBufferAllocationScheme();
+        desret_xmlBufferAllocationScheme(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetBufferAllocationScheme",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetCompressMode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlGetCompressMode();
+        desret_int(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetCompressMode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDocCompressMode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlGetDocCompressMode(doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDocCompressMode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetIntSubset(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlDocPtr doc; /* the document pointer */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlGetIntSubset(doc);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetIntSubset",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetLastChild(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+
+        ret_val = xmlGetLastChild(parent);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetLastChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetLineNo(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    long ret_val;
+    xmlNodePtr node; /* valid node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlGetLineNo(node);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetLineNo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetNoNsProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetNoNsProp(node, (const xmlChar *)name);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetNoNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetNodePath(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlGetNodePath(node);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetNodePath",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetNsList(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetNsProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * nameSpace; /* the URI of the namespace */
+    int n_nameSpace;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_nameSpace = 0;n_nameSpace < gen_nb_const_xmlChar_ptr;n_nameSpace++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
+
+        ret_val = xmlGetNsProp(node, (const xmlChar *)name, (const xmlChar *)nameSpace);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf(" %d", n_nameSpace);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetProp(node, (const xmlChar *)name);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHasNsProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * nameSpace; /* the URI of the namespace */
+    int n_nameSpace;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_nameSpace = 0;n_nameSpace < gen_nb_const_xmlChar_ptr;n_nameSpace++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
+
+        ret_val = xmlHasNsProp(node, (const xmlChar *)name, (const xmlChar *)nameSpace);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHasNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf(" %d", n_nameSpace);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlHasProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlHasProp(node, (const xmlChar *)name);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlHasProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsBlankNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlIsBlankNode(node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsBlankNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsXHTML(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * systemID; /* the system identifier */
+    int n_systemID;
+    xmlChar * publicID; /* the public identifier */
+    int n_publicID;
+
+    for (n_systemID = 0;n_systemID < gen_nb_const_xmlChar_ptr;n_systemID++) {
+    for (n_publicID = 0;n_publicID < gen_nb_const_xmlChar_ptr;n_publicID++) {
+        mem_base = xmlMemBlocks();
+        systemID = gen_const_xmlChar_ptr(n_systemID, 0);
+        publicID = gen_const_xmlChar_ptr(n_publicID, 1);
+
+        ret_val = xmlIsXHTML((const xmlChar *)systemID, (const xmlChar *)publicID);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_systemID, (const xmlChar *)systemID, 0);
+        des_const_xmlChar_ptr(n_publicID, (const xmlChar *)publicID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsXHTML",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_systemID);
+            printf(" %d", n_publicID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlLastElementChild(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+
+        ret_val = xmlLastElementChild(parent);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlLastElementChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewCDataBlock(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * content; /* the CDATA block content content */
+    int n_content;
+    int len; /* the length of the block */
+    int n_len;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlNewCDataBlock(doc, (const xmlChar *)content, len);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewCDataBlock",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewCharRef(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the char ref string, starting with # or "&# ... ;" */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlNewCharRef(doc, (const xmlChar *)name);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewCharRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewChild(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+    xmlNsPtr ns; /* a namespace if any */
+    int n_ns;
+    xmlChar * name; /* the name of the child */
+    int n_name;
+    xmlChar * content; /* the XML content of the child if any. */
+    int n_content;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlNewChild(parent, ns, (const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewComment(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlChar * content; /* the comment content */
+    int n_content;
+
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        content = gen_const_xmlChar_ptr(n_content, 0);
+
+        ret_val = xmlNewComment((const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewComment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDoc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlChar * version; /* xmlChar string giving the version of XML "1.0" */
+    int n_version;
+
+    for (n_version = 0;n_version < gen_nb_const_xmlChar_ptr;n_version++) {
+        mem_base = xmlMemBlocks();
+        version = gen_const_xmlChar_ptr(n_version, 0);
+
+        ret_val = xmlNewDoc((const xmlChar *)version);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_version, (const xmlChar *)version, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_version);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocComment(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * content; /* the comment content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlNewDocComment(doc, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocComment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocFragment(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document owning the fragment */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlNewDocFragment(doc);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocFragment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNsPtr ns; /* namespace if any */
+    int n_ns;
+    xmlChar * name; /* the node name */
+    int n_name;
+    xmlChar * content; /* the XML text content if any */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlNewDocNode(doc, ns, (const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocNodeEatName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNsPtr ns; /* namespace if any */
+    int n_ns;
+    xmlChar * name; /* the node name */
+    int n_name;
+    xmlChar * content; /* the XML text content if any */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_eaten_name;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_eaten_name(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlNewDocNodeEatName(doc, ns, name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_eaten_name(n_name, name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocNodeEatName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocPI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the target document */
+    int n_doc;
+    xmlChar * name; /* the processing instruction name */
+    int n_name;
+    xmlChar * content; /* the PI content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlNewDocPI(doc, (const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocPI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the name of the attribute */
+    int n_name;
+    xmlChar * value; /* the value of the attribute */
+    int n_value;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+
+        ret_val = xmlNewDocProp(doc, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocRawNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNsPtr ns; /* namespace if any */
+    int n_ns;
+    xmlChar * name; /* the node name */
+    int n_name;
+    xmlChar * content; /* the text content if any */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlNewDocRawNode(doc, ns, (const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocRawNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocText(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * content; /* the text content */
+    int n_content;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlNewDocText(doc, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocText",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocTextLen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * content; /* the text content */
+    int n_content;
+    int len; /* the text len. */
+    int n_len;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlNewDocTextLen(doc, (const xmlChar *)content, len);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocTextLen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDtd(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDtdPtr ret_val;
+    xmlDocPtr doc; /* the document pointer */
+    int n_doc;
+    xmlChar * name; /* the DTD name */
+    int n_name;
+    xmlChar * ExternalID; /* the external ID */
+    int n_ExternalID;
+    xmlChar * SystemID; /* the system ID */
+    int n_SystemID;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ExternalID = 0;n_ExternalID < gen_nb_const_xmlChar_ptr;n_ExternalID++) {
+    for (n_SystemID = 0;n_SystemID < gen_nb_const_xmlChar_ptr;n_SystemID++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ExternalID = gen_const_xmlChar_ptr(n_ExternalID, 2);
+        SystemID = gen_const_xmlChar_ptr(n_SystemID, 3);
+
+        ret_val = xmlNewDtd(doc, (const xmlChar *)name, (const xmlChar *)ExternalID, (const xmlChar *)SystemID);
+        desret_xmlDtdPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ExternalID, (const xmlChar *)ExternalID, 2);
+        des_const_xmlChar_ptr(n_SystemID, (const xmlChar *)SystemID, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDtd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_ExternalID);
+            printf(" %d", n_SystemID);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewNode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNsPtr ns; /* namespace if any */
+    int n_ns;
+    xmlChar * name; /* the node name */
+    int n_name;
+
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ns = gen_xmlNsPtr(n_ns, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlNewNode(ns, (const xmlChar *)name);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNsPtr(n_ns, ns, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewNodeEatName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNsPtr ns; /* namespace if any */
+    int n_ns;
+    xmlChar * name; /* the node name */
+    int n_name;
+
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_eaten_name;n_name++) {
+        mem_base = xmlMemBlocks();
+        ns = gen_xmlNsPtr(n_ns, 0);
+        name = gen_eaten_name(n_name, 1);
+
+        ret_val = xmlNewNodeEatName(ns, name);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNsPtr(n_ns, ns, 0);
+        des_eaten_name(n_name, name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewNodeEatName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewNs(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNsPtr ret_val;
+    xmlNodePtr node; /* the element carrying the namespace */
+    int n_node;
+    xmlChar * href; /* the URI associated */
+    int n_href;
+    xmlChar * prefix; /* the prefix for the namespace */
+    int n_prefix;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_href = 0;n_href < gen_nb_const_xmlChar_ptr;n_href++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        href = gen_const_xmlChar_ptr(n_href, 1);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 2);
+
+        ret_val = xmlNewNs(node, (const xmlChar *)href, (const xmlChar *)prefix);
+        if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);
+        desret_xmlNsPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_href, (const xmlChar *)href, 1);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_href);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewNsProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the holding node */
+    int n_node;
+    xmlNsPtr ns; /* the namespace */
+    int n_ns;
+    xmlChar * name; /* the name of the attribute */
+    int n_name;
+    xmlChar * value; /* the value of the attribute */
+    int n_value;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        value = gen_const_xmlChar_ptr(n_value, 3);
+
+        ret_val = xmlNewNsProp(node, ns, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewNsPropEatName(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the holding node */
+    int n_node;
+    xmlNsPtr ns; /* the namespace */
+    int n_ns;
+    xmlChar * name; /* the name of the attribute */
+    int n_name;
+    xmlChar * value; /* the value of the attribute */
+    int n_value;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_eaten_name;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_eaten_name(n_name, 2);
+        value = gen_const_xmlChar_ptr(n_value, 3);
+
+        ret_val = xmlNewNsPropEatName(node, ns, name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_eaten_name(n_name, name, 2);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewNsPropEatName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewPI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlChar * name; /* the processing instruction name */
+    int n_name;
+    xmlChar * content; /* the PI content */
+    int n_content;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlNewPI((const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewPI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the holding node */
+    int n_node;
+    xmlChar * name; /* the name of the attribute */
+    int n_name;
+    xmlChar * value; /* the value of the attribute */
+    int n_value;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+
+        ret_val = xmlNewProp(node, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewReference(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the reference name, or the reference string with & and ; */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlNewReference(doc, (const xmlChar *)name);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewReference",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewText(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlChar * content; /* the text content */
+    int n_content;
+
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        content = gen_const_xmlChar_ptr(n_content, 0);
+
+        ret_val = xmlNewText((const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewText",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextChild(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr parent; /* the parent node */
+    int n_parent;
+    xmlNsPtr ns; /* a namespace if any */
+    int n_ns;
+    xmlChar * name; /* the name of the child */
+    int n_name;
+    xmlChar * content; /* the text content of the child if any. */
+    int n_content;
+
+    for (n_parent = 0;n_parent < gen_nb_xmlNodePtr;n_parent++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        parent = gen_xmlNodePtr(n_parent, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlNewTextChild(parent, ns, (const xmlChar *)name, (const xmlChar *)content);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_parent, parent, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_parent);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextLen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlChar * content; /* the text content */
+    int n_content;
+    int len; /* the text len. */
+    int n_len;
+
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        content = gen_const_xmlChar_ptr(n_content, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlNewTextLen((const xmlChar *)content, len);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextLen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNextElementSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr node; /* the current node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlNextElementSibling(node);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNextElementSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeAddContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr cur; /* the node being modified */
+    int n_cur;
+    xmlChar * content; /* extra content */
+    int n_content;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        xmlNodeAddContent(cur, (const xmlChar *)content);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeAddContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeAddContentLen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr cur; /* the node being modified */
+    int n_cur;
+    xmlChar * content; /* extra content */
+    int n_content;
+    int len; /* the size of @content */
+    int n_len;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        xmlNodeAddContentLen(cur, (const xmlChar *)content, len);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeAddContentLen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeBufGetContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buffer; /* a buffer */
+    int n_buffer;
+    xmlNodePtr cur; /* the node being read */
+    int n_cur;
+
+    for (n_buffer = 0;n_buffer < gen_nb_xmlBufferPtr;n_buffer++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_xmlBufferPtr(n_buffer, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlNodeBufGetContent(buffer, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buffer, buffer, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeBufGetContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+    int level; /* the imbrication level for indenting */
+    int n_level;
+    int format; /* is formatting allowed */
+    int n_format;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_level = 0;n_level < gen_nb_int;n_level++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+        level = gen_int(n_level, 3);
+        format = gen_int(n_format, 4);
+
+        ret_val = xmlNodeDump(buf, doc, cur, level, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        des_int(n_level, level, 3);
+        des_int(n_format, format, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf(" %d", n_level);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeDumpOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr cur; /* the current node */
+    int n_cur;
+    int level; /* the imbrication level for indenting */
+    int n_level;
+    int format; /* is formatting allowed */
+    int n_format;
+    char * encoding; /* an optional encoding string */
+    int n_encoding;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_level = 0;n_level < gen_nb_int;n_level++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        cur = gen_xmlNodePtr(n_cur, 2);
+        level = gen_int(n_level, 3);
+        format = gen_int(n_format, 4);
+        encoding = gen_const_char_ptr(n_encoding, 5);
+
+        xmlNodeDumpOutput(buf, doc, cur, level, format, (const char *)encoding);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_cur, cur, 2);
+        des_int(n_level, level, 3);
+        des_int(n_format, format, 4);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeDumpOutput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf(" %d", n_level);
+            printf(" %d", n_format);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeGetBase(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document the node pertains to */
+    int n_doc;
+    xmlNodePtr cur; /* the node being checked */
+    int n_cur;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlNodeGetBase(doc, cur);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeGetBase",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeGetContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr cur; /* the node being read */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+
+        ret_val = xmlNodeGetContent(cur);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeGetContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeGetLang(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr cur; /* the node being checked */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+
+        ret_val = xmlNodeGetLang(cur);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeGetLang",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeGetSpacePreserve(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlNodePtr cur; /* the node being checked */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+
+        ret_val = xmlNodeGetSpacePreserve(cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeGetSpacePreserve",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeIsText(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlNodeIsText(node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeIsText",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeListGetRawString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr list; /* a Node list */
+    int n_list;
+    int inLine; /* should we replace entity contents or show their external form */
+    int n_inLine;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_list = 0;n_list < gen_nb_xmlNodePtr;n_list++) {
+    for (n_inLine = 0;n_inLine < gen_nb_int;n_inLine++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        list = gen_xmlNodePtr(n_list, 1);
+        inLine = gen_int(n_inLine, 2);
+
+        ret_val = xmlNodeListGetRawString(doc, list, inLine);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_list, list, 1);
+        des_int(n_inLine, inLine, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeListGetRawString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_list);
+            printf(" %d", n_inLine);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeListGetString(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr list; /* a Node list */
+    int n_list;
+    int inLine; /* should we replace entity contents or show their external form */
+    int n_inLine;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_list = 0;n_list < gen_nb_xmlNodePtr;n_list++) {
+    for (n_inLine = 0;n_inLine < gen_nb_int;n_inLine++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        list = gen_xmlNodePtr(n_list, 1);
+        inLine = gen_int(n_inLine, 2);
+
+        ret_val = xmlNodeListGetString(doc, list, inLine);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_list, list, 1);
+        des_int(n_inLine, inLine, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeListGetString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_list);
+            printf(" %d", n_inLine);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetBase(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    xmlNodePtr cur; /* the node being changed */
+    int n_cur;
+    xmlChar * uri; /* the new base URI */
+    int n_uri;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_uri = 0;n_uri < gen_nb_const_xmlChar_ptr;n_uri++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        uri = gen_const_xmlChar_ptr(n_uri, 1);
+
+        xmlNodeSetBase(cur, (const xmlChar *)uri);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_uri, (const xmlChar *)uri, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetBase",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_uri);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr cur; /* the node being modified */
+    int n_cur;
+    xmlChar * content; /* the new value of the content */
+    int n_content;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        xmlNodeSetContent(cur, (const xmlChar *)content);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetContentLen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr cur; /* the node being modified */
+    int n_cur;
+    xmlChar * content; /* the new value of the content */
+    int n_content;
+    int len; /* the size of @content */
+    int n_len;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        xmlNodeSetContentLen(cur, (const xmlChar *)content, len);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetContentLen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetLang(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr cur; /* the node being changed */
+    int n_cur;
+    xmlChar * lang; /* the language description */
+    int n_lang;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_lang = 0;n_lang < gen_nb_const_xmlChar_ptr;n_lang++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        lang = gen_const_xmlChar_ptr(n_lang, 1);
+
+        xmlNodeSetLang(cur, (const xmlChar *)lang);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_lang, (const xmlChar *)lang, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetLang",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_lang);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr cur; /* the node being changed */
+    int n_cur;
+    xmlChar * name; /* the new tag name */
+    int n_name;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        xmlNodeSetName(cur, (const xmlChar *)name);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNodeSetSpacePreserve(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr cur; /* the node being changed */
+    int n_cur;
+    int val; /* the xml:space value ("0": default, 1: "preserve") */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodePtr(n_cur, 0);
+        val = gen_int(n_val, 1);
+
+        xmlNodeSetSpacePreserve(cur, val);
+        call_tests++;
+        des_xmlNodePtr(n_cur, cur, 0);
+        des_int(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNodeSetSpacePreserve",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPreviousElementSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr node; /* the current node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlPreviousElementSibling(node);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPreviousElementSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReconciliateNs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr tree; /* a node defining the subtree to reconciliate */
+    int n_tree;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_tree = 0;n_tree < gen_nb_xmlNodePtr;n_tree++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        tree = gen_xmlNodePtr(n_tree, 1);
+
+        ret_val = xmlReconciliateNs(doc, tree);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_tree, tree, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReconciliateNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_tree);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRemoveProp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlAttrPtr cur; /* an attribute */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlAttrPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlAttrPtr(n_cur, 0);
+
+        ret_val = xmlRemoveProp(cur);
+        cur = NULL;
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlAttrPtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRemoveProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReplaceNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr old; /* the old node */
+    int n_old;
+    xmlNodePtr cur; /* the node */
+    int n_cur;
+
+    for (n_old = 0;n_old < gen_nb_xmlNodePtr;n_old++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr_in;n_cur++) {
+        mem_base = xmlMemBlocks();
+        old = gen_xmlNodePtr(n_old, 0);
+        cur = gen_xmlNodePtr_in(n_cur, 1);
+
+        ret_val = xmlReplaceNode(old, cur);
+        if (cur != NULL) {
+              xmlUnlinkNode(cur);
+              xmlFreeNode(cur) ; cur = NULL ; }
+          if (old != NULL) {
+              xmlUnlinkNode(old);
+              xmlFreeNode(old) ; old = NULL ; }
+	  ret_val = NULL;
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_old, old, 0);
+        des_xmlNodePtr_in(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReplaceNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_old);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename (or URL) */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+
+        ret_val = xmlSaveFile(filename, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFileEnc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename (or URL) */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the name of an encoding (or NULL) */
+    int n_encoding;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+
+        ret_val = xmlSaveFileEnc(filename, cur, (const char *)encoding);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFileEnc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFileTo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlOutputBufferPtr buf; /* an output I/O buffer */
+    int n_buf;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the encoding if any assuming the I/O layer handles the trancoding */
+    int n_encoding;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+
+        ret_val = xmlSaveFileTo(buf, cur, (const char *)encoding);
+        buf = NULL;
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFileTo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFormatFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename (or URL) */
+    int n_filename;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        format = gen_int(n_format, 2);
+
+        ret_val = xmlSaveFormatFile(filename, cur, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_int(n_format, format, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFormatFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFormatFileEnc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the filename or URL to output */
+    int n_filename;
+    xmlDocPtr cur; /* the document being saved */
+    int n_cur;
+    char * encoding; /* the name of the encoding to use or NULL. */
+    int n_encoding;
+    int format; /* should formatting spaces be added. */
+    int n_format;
+
+    for (n_filename = 0;n_filename < gen_nb_fileoutput;n_filename++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_fileoutput(n_filename, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        format = gen_int(n_format, 3);
+
+        ret_val = xmlSaveFormatFileEnc(filename, cur, (const char *)encoding, format);
+        desret_int(ret_val);
+        call_tests++;
+        des_fileoutput(n_filename, filename, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFormatFileEnc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFormatFileTo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlOutputBufferPtr buf; /* an output I/O buffer */
+    int n_buf;
+    xmlDocPtr cur; /* the document */
+    int n_cur;
+    char * encoding; /* the encoding if any assuming the I/O layer handles the trancoding */
+    int n_encoding;
+    int format; /* should formatting spaces been added */
+    int n_format;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlDocPtr;n_cur++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_format = 0;n_format < gen_nb_int;n_format++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlOutputBufferPtr(n_buf, 0);
+        cur = gen_xmlDocPtr(n_cur, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        format = gen_int(n_format, 3);
+
+        ret_val = xmlSaveFormatFileTo(buf, cur, (const char *)encoding, format);
+        buf = NULL;
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_buf, buf, 0);
+        des_xmlDocPtr(n_cur, cur, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_int(n_format, format, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFormatFileTo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_cur);
+            printf(" %d", n_encoding);
+            printf(" %d", n_format);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSearchNs(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNsPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr node; /* the current node */
+    int n_node;
+    xmlChar * nameSpace; /* the namespace prefix */
+    int n_nameSpace;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_nameSpace = 0;n_nameSpace < gen_nb_const_xmlChar_ptr;n_nameSpace++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        nameSpace = gen_const_xmlChar_ptr(n_nameSpace, 2);
+
+        ret_val = xmlSearchNs(doc, node, (const xmlChar *)nameSpace);
+        desret_xmlNsPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_const_xmlChar_ptr(n_nameSpace, (const xmlChar *)nameSpace, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSearchNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_node);
+            printf(" %d", n_nameSpace);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSearchNsByHref(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNsPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr node; /* the current node */
+    int n_node;
+    xmlChar * href; /* the namespace value */
+    int n_href;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_href = 0;n_href < gen_nb_const_xmlChar_ptr;n_href++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        href = gen_const_xmlChar_ptr(n_href, 2);
+
+        ret_val = xmlSearchNsByHref(doc, node, (const xmlChar *)href);
+        desret_xmlNsPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_const_xmlChar_ptr(n_href, (const xmlChar *)href, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSearchNsByHref",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_node);
+            printf(" %d", n_href);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetBufferAllocationScheme(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferAllocationScheme scheme; /* allocation method to use */
+    int n_scheme;
+
+    for (n_scheme = 0;n_scheme < gen_nb_xmlBufferAllocationScheme;n_scheme++) {
+        mem_base = xmlMemBlocks();
+        scheme = gen_xmlBufferAllocationScheme(n_scheme, 0);
+
+        xmlSetBufferAllocationScheme(scheme);
+        call_tests++;
+        des_xmlBufferAllocationScheme(n_scheme, scheme, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetBufferAllocationScheme",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_scheme);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetCompressMode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int mode; /* the compression ratio */
+    int n_mode;
+
+    for (n_mode = 0;n_mode < gen_nb_int;n_mode++) {
+        mem_base = xmlMemBlocks();
+        mode = gen_int(n_mode, 0);
+
+        xmlSetCompressMode(mode);
+        call_tests++;
+        des_int(n_mode, mode, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetCompressMode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_mode);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetDocCompressMode(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    int mode; /* the compression ratio */
+    int n_mode;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_mode = 0;n_mode < gen_nb_int;n_mode++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        mode = gen_int(n_mode, 1);
+
+        xmlSetDocCompressMode(doc, mode);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_int(n_mode, mode, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetDocCompressMode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_mode);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetNs(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr node; /* a node in the document */
+    int n_node;
+    xmlNsPtr ns; /* a namespace pointer */
+    int n_ns;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+
+        xmlSetNs(node, ns);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetNsProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlNsPtr ns; /* the namespace definition */
+    int n_ns;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * value; /* the attribute value */
+    int n_value;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        value = gen_const_xmlChar_ptr(n_value, 3);
+
+        ret_val = xmlSetNsProp(node, ns, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name (a QName) */
+    int n_name;
+    xmlChar * value; /* the attribute value */
+    int n_value;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+
+        ret_val = xmlSetProp(node, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSetProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSplitQName2(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * name; /* the full QName */
+    int n_name;
+    xmlChar ** prefix; /* a xmlChar ** */
+    int n_prefix;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix = 0;n_prefix < gen_nb_xmlChar_ptr_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+        prefix = gen_xmlChar_ptr_ptr(n_prefix, 1);
+
+        ret_val = xmlSplitQName2((const xmlChar *)name, prefix);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        des_xmlChar_ptr_ptr(n_prefix, prefix, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSplitQName2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSplitQName3(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlChar * name; /* the full QName */
+    int n_name;
+    int * len; /* an int * */
+    int n_len;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+        len = gen_int_ptr(n_len, 1);
+
+        ret_val = xmlSplitQName3((const xmlChar *)name, len);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        des_int_ptr(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSplitQName3",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStringGetNodeList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * value; /* the value of the attribute */
+    int n_value;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+
+        ret_val = xmlStringGetNodeList(doc, (const xmlChar *)value);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStringGetNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStringLenGetNodeList(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * value; /* the value of the text */
+    int n_value;
+    int len; /* the length of the string value */
+    int n_len;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlStringLenGetNodeList(doc, (const xmlChar *)value, len);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStringLenGetNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_value);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextConcat(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * content; /* the content */
+    int n_content;
+    int len; /* @content length */
+    int n_len;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlTextConcat(node, (const xmlChar *)content, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextConcat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextMerge(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlNodePtr first; /* the first text node */
+    int n_first;
+    xmlNodePtr second; /* the second text node being merged */
+    int n_second;
+
+    for (n_first = 0;n_first < gen_nb_xmlNodePtr_in;n_first++) {
+    for (n_second = 0;n_second < gen_nb_xmlNodePtr_in;n_second++) {
+        mem_base = xmlMemBlocks();
+        first = gen_xmlNodePtr_in(n_first, 0);
+        second = gen_xmlNodePtr_in(n_second, 1);
+
+        ret_val = xmlTextMerge(first, second);
+        if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
+              xmlUnlinkNode(second);
+              xmlFreeNode(second) ; second = NULL ; }
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr_in(n_first, first, 0);
+        des_xmlNodePtr_in(n_second, second, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextMerge",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_first);
+            printf(" %d", n_second);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUnsetNsProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlNsPtr ns; /* the namespace definition */
+    int n_ns;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        ns = gen_xmlNsPtr(n_ns, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+
+        ret_val = xmlUnsetNsProp(node, ns, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_xmlNsPtr(n_ns, ns, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUnsetNsProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUnsetProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node; /* the node */
+    int n_node;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlUnsetProp(node, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUnsetProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNCName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    int space; /* allow spaces in front and end of the string */
+    int n_space;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_space = 0;n_space < gen_nb_int;n_space++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+        space = gen_int(n_space, 1);
+
+        ret_val = xmlValidateNCName((const xmlChar *)value, space);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        des_int(n_space, space, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNCName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf(" %d", n_space);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNMToken(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    int space; /* allow spaces in front and end of the string */
+    int n_space;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_space = 0;n_space < gen_nb_int;n_space++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+        space = gen_int(n_space, 1);
+
+        ret_val = xmlValidateNMToken((const xmlChar *)value, space);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        des_int(n_space, space, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNMToken",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf(" %d", n_space);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    int space; /* allow spaces in front and end of the string */
+    int n_space;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_space = 0;n_space < gen_nb_int;n_space++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+        space = gen_int(n_space, 1);
+
+        ret_val = xmlValidateName((const xmlChar *)value, space);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        des_int(n_space, space, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf(" %d", n_space);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateQName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#ifdef LIBXML_TREE_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    int space; /* allow spaces in front and end of the string */
+    int n_space;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_space = 0;n_space < gen_nb_int;n_space++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+        space = gen_int(n_space, 1);
+
+        ret_val = xmlValidateQName((const xmlChar *)value, space);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        des_int(n_space, space, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateQName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf(" %d", n_space);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_tree(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing tree : 138 of 157 functions ...\n");
+    test_ret += test_xmlAddChild();
+    test_ret += test_xmlAddChildList();
+    test_ret += test_xmlAddNextSibling();
+    test_ret += test_xmlAddPrevSibling();
+    test_ret += test_xmlAddSibling();
+    test_ret += test_xmlAttrSerializeTxtContent();
+    test_ret += test_xmlBufferAdd();
+    test_ret += test_xmlBufferAddHead();
+    test_ret += test_xmlBufferCCat();
+    test_ret += test_xmlBufferCat();
+    test_ret += test_xmlBufferContent();
+    test_ret += test_xmlBufferCreate();
+    test_ret += test_xmlBufferCreateSize();
+    test_ret += test_xmlBufferCreateStatic();
+    test_ret += test_xmlBufferEmpty();
+    test_ret += test_xmlBufferGrow();
+    test_ret += test_xmlBufferLength();
+    test_ret += test_xmlBufferResize();
+    test_ret += test_xmlBufferSetAllocationScheme();
+    test_ret += test_xmlBufferShrink();
+    test_ret += test_xmlBufferWriteCHAR();
+    test_ret += test_xmlBufferWriteChar();
+    test_ret += test_xmlBufferWriteQuotedString();
+    test_ret += test_xmlBuildQName();
+    test_ret += test_xmlChildElementCount();
+    test_ret += test_xmlCopyDoc();
+    test_ret += test_xmlCopyDtd();
+    test_ret += test_xmlCopyNamespace();
+    test_ret += test_xmlCopyNamespaceList();
+    test_ret += test_xmlCopyNode();
+    test_ret += test_xmlCopyNodeList();
+    test_ret += test_xmlCopyProp();
+    test_ret += test_xmlCopyPropList();
+    test_ret += test_xmlCreateIntSubset();
+    test_ret += test_xmlDOMWrapAdoptNode();
+    test_ret += test_xmlDOMWrapCloneNode();
+    test_ret += test_xmlDOMWrapNewCtxt();
+    test_ret += test_xmlDOMWrapReconcileNamespaces();
+    test_ret += test_xmlDOMWrapRemoveNode();
+    test_ret += test_xmlDocCopyNode();
+    test_ret += test_xmlDocCopyNodeList();
+    test_ret += test_xmlDocDump();
+    test_ret += test_xmlDocDumpFormatMemory();
+    test_ret += test_xmlDocDumpFormatMemoryEnc();
+    test_ret += test_xmlDocDumpMemory();
+    test_ret += test_xmlDocDumpMemoryEnc();
+    test_ret += test_xmlDocFormatDump();
+    test_ret += test_xmlDocGetRootElement();
+    test_ret += test_xmlDocSetRootElement();
+    test_ret += test_xmlElemDump();
+    test_ret += test_xmlFirstElementChild();
+    test_ret += test_xmlGetBufferAllocationScheme();
+    test_ret += test_xmlGetCompressMode();
+    test_ret += test_xmlGetDocCompressMode();
+    test_ret += test_xmlGetIntSubset();
+    test_ret += test_xmlGetLastChild();
+    test_ret += test_xmlGetLineNo();
+    test_ret += test_xmlGetNoNsProp();
+    test_ret += test_xmlGetNodePath();
+    test_ret += test_xmlGetNsList();
+    test_ret += test_xmlGetNsProp();
+    test_ret += test_xmlGetProp();
+    test_ret += test_xmlHasNsProp();
+    test_ret += test_xmlHasProp();
+    test_ret += test_xmlIsBlankNode();
+    test_ret += test_xmlIsXHTML();
+    test_ret += test_xmlLastElementChild();
+    test_ret += test_xmlNewCDataBlock();
+    test_ret += test_xmlNewCharRef();
+    test_ret += test_xmlNewChild();
+    test_ret += test_xmlNewComment();
+    test_ret += test_xmlNewDoc();
+    test_ret += test_xmlNewDocComment();
+    test_ret += test_xmlNewDocFragment();
+    test_ret += test_xmlNewDocNode();
+    test_ret += test_xmlNewDocNodeEatName();
+    test_ret += test_xmlNewDocPI();
+    test_ret += test_xmlNewDocProp();
+    test_ret += test_xmlNewDocRawNode();
+    test_ret += test_xmlNewDocText();
+    test_ret += test_xmlNewDocTextLen();
+    test_ret += test_xmlNewDtd();
+    test_ret += test_xmlNewNode();
+    test_ret += test_xmlNewNodeEatName();
+    test_ret += test_xmlNewNs();
+    test_ret += test_xmlNewNsProp();
+    test_ret += test_xmlNewNsPropEatName();
+    test_ret += test_xmlNewPI();
+    test_ret += test_xmlNewProp();
+    test_ret += test_xmlNewReference();
+    test_ret += test_xmlNewText();
+    test_ret += test_xmlNewTextChild();
+    test_ret += test_xmlNewTextLen();
+    test_ret += test_xmlNextElementSibling();
+    test_ret += test_xmlNodeAddContent();
+    test_ret += test_xmlNodeAddContentLen();
+    test_ret += test_xmlNodeBufGetContent();
+    test_ret += test_xmlNodeDump();
+    test_ret += test_xmlNodeDumpOutput();
+    test_ret += test_xmlNodeGetBase();
+    test_ret += test_xmlNodeGetContent();
+    test_ret += test_xmlNodeGetLang();
+    test_ret += test_xmlNodeGetSpacePreserve();
+    test_ret += test_xmlNodeIsText();
+    test_ret += test_xmlNodeListGetRawString();
+    test_ret += test_xmlNodeListGetString();
+    test_ret += test_xmlNodeSetBase();
+    test_ret += test_xmlNodeSetContent();
+    test_ret += test_xmlNodeSetContentLen();
+    test_ret += test_xmlNodeSetLang();
+    test_ret += test_xmlNodeSetName();
+    test_ret += test_xmlNodeSetSpacePreserve();
+    test_ret += test_xmlPreviousElementSibling();
+    test_ret += test_xmlReconciliateNs();
+    test_ret += test_xmlRemoveProp();
+    test_ret += test_xmlReplaceNode();
+    test_ret += test_xmlSaveFile();
+    test_ret += test_xmlSaveFileEnc();
+    test_ret += test_xmlSaveFileTo();
+    test_ret += test_xmlSaveFormatFile();
+    test_ret += test_xmlSaveFormatFileEnc();
+    test_ret += test_xmlSaveFormatFileTo();
+    test_ret += test_xmlSearchNs();
+    test_ret += test_xmlSearchNsByHref();
+    test_ret += test_xmlSetBufferAllocationScheme();
+    test_ret += test_xmlSetCompressMode();
+    test_ret += test_xmlSetDocCompressMode();
+    test_ret += test_xmlSetNs();
+    test_ret += test_xmlSetNsProp();
+    test_ret += test_xmlSetProp();
+    test_ret += test_xmlSplitQName2();
+    test_ret += test_xmlSplitQName3();
+    test_ret += test_xmlStringGetNodeList();
+    test_ret += test_xmlStringLenGetNodeList();
+    test_ret += test_xmlTextConcat();
+    test_ret += test_xmlTextMerge();
+    test_ret += test_xmlUnsetNsProp();
+    test_ret += test_xmlUnsetProp();
+    test_ret += test_xmlValidateNCName();
+    test_ret += test_xmlValidateNMToken();
+    test_ret += test_xmlValidateName();
+    test_ret += test_xmlValidateQName();
+
+    if (test_ret != 0)
+	printf("Module tree: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlBuildRelativeURI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * URI; /* the URI reference under consideration */
+    int n_URI;
+    xmlChar * base; /* the base value */
+    int n_base;
+
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+    for (n_base = 0;n_base < gen_nb_const_xmlChar_ptr;n_base++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_const_xmlChar_ptr(n_URI, 0);
+        base = gen_const_xmlChar_ptr(n_base, 1);
+
+        ret_val = xmlBuildRelativeURI((const xmlChar *)URI, (const xmlChar *)base);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+        des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBuildRelativeURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_base);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlBuildURI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * URI; /* the URI instance found in the document */
+    int n_URI;
+    xmlChar * base; /* the base value */
+    int n_base;
+
+    for (n_URI = 0;n_URI < gen_nb_const_xmlChar_ptr;n_URI++) {
+    for (n_base = 0;n_base < gen_nb_const_xmlChar_ptr;n_base++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_const_xmlChar_ptr(n_URI, 0);
+        base = gen_const_xmlChar_ptr(n_base, 1);
+
+        ret_val = xmlBuildURI((const xmlChar *)URI, (const xmlChar *)base);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_URI, (const xmlChar *)URI, 0);
+        des_const_xmlChar_ptr(n_base, (const xmlChar *)base, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlBuildURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_base);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCanonicPath(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * path; /* the resource locator in a filesystem notation */
+    int n_path;
+
+    for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
+        mem_base = xmlMemBlocks();
+        path = gen_const_xmlChar_ptr(n_path, 0);
+
+        ret_val = xmlCanonicPath((const xmlChar *)path);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCanonicPath",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_path);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateURI(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlNormalizeURIPath(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    char * path; /* pointer to the path string */
+    int n_path;
+
+    for (n_path = 0;n_path < gen_nb_char_ptr;n_path++) {
+        mem_base = xmlMemBlocks();
+        path = gen_char_ptr(n_path, 0);
+
+        ret_val = xmlNormalizeURIPath(path);
+        desret_int(ret_val);
+        call_tests++;
+        des_char_ptr(n_path, path, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNormalizeURIPath",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_path);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseURI(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParseURIRaw(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlURIPtr 1
+static xmlURIPtr gen_xmlURIPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlURIPtr(int no ATTRIBUTE_UNUSED, xmlURIPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlParseURIReference(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlURIPtr uri; /* pointer to an URI structure */
+    int n_uri;
+    char * str; /* the string to analyze */
+    int n_str;
+
+    for (n_uri = 0;n_uri < gen_nb_xmlURIPtr;n_uri++) {
+    for (n_str = 0;n_str < gen_nb_const_char_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        uri = gen_xmlURIPtr(n_uri, 0);
+        str = gen_const_char_ptr(n_str, 1);
+
+        ret_val = xmlParseURIReference(uri, (const char *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlURIPtr(n_uri, uri, 0);
+        des_const_char_ptr(n_str, (const char *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParseURIReference",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_uri);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPathToURI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * path; /* the resource locator in a filesystem notation */
+    int n_path;
+
+    for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
+        mem_base = xmlMemBlocks();
+        path = gen_const_xmlChar_ptr(n_path, 0);
+
+        ret_val = xmlPathToURI((const xmlChar *)path);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPathToURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_path);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPrintURI(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    FILE * stream; /* a FILE* for the output */
+    int n_stream;
+    xmlURIPtr uri; /* pointer to an xmlURI */
+    int n_uri;
+
+    for (n_stream = 0;n_stream < gen_nb_FILE_ptr;n_stream++) {
+    for (n_uri = 0;n_uri < gen_nb_xmlURIPtr;n_uri++) {
+        mem_base = xmlMemBlocks();
+        stream = gen_FILE_ptr(n_stream, 0);
+        uri = gen_xmlURIPtr(n_uri, 1);
+
+        xmlPrintURI(stream, uri);
+        call_tests++;
+        des_FILE_ptr(n_stream, stream, 0);
+        des_xmlURIPtr(n_uri, uri, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPrintURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_stream);
+            printf(" %d", n_uri);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveUri(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlURIPtr uri; /* pointer to an xmlURI */
+    int n_uri;
+
+    for (n_uri = 0;n_uri < gen_nb_xmlURIPtr;n_uri++) {
+        mem_base = xmlMemBlocks();
+        uri = gen_xmlURIPtr(n_uri, 0);
+
+        ret_val = xmlSaveUri(uri);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlURIPtr(n_uri, uri, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveUri",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_uri);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlURIEscape(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * str; /* the string of the URI to escape */
+    int n_str;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+
+        ret_val = xmlURIEscape((const xmlChar *)str);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlURIEscape",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlURIEscapeStr(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * str; /* string to escape */
+    int n_str;
+    xmlChar * list; /* exception list string of chars not to escape */
+    int n_list;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_list = 0;n_list < gen_nb_const_xmlChar_ptr;n_list++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        list = gen_const_xmlChar_ptr(n_list, 1);
+
+        ret_val = xmlURIEscapeStr((const xmlChar *)str, (const xmlChar *)list);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_const_xmlChar_ptr(n_list, (const xmlChar *)list, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlURIEscapeStr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_list);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlURIUnescapeString(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_uri(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing uri : 10 of 15 functions ...\n");
+    test_ret += test_xmlBuildRelativeURI();
+    test_ret += test_xmlBuildURI();
+    test_ret += test_xmlCanonicPath();
+    test_ret += test_xmlCreateURI();
+    test_ret += test_xmlNormalizeURIPath();
+    test_ret += test_xmlParseURI();
+    test_ret += test_xmlParseURIRaw();
+    test_ret += test_xmlParseURIReference();
+    test_ret += test_xmlPathToURI();
+    test_ret += test_xmlPrintURI();
+    test_ret += test_xmlSaveUri();
+    test_ret += test_xmlURIEscape();
+    test_ret += test_xmlURIEscapeStr();
+    test_ret += test_xmlURIUnescapeString();
+
+    if (test_ret != 0)
+	printf("Module uri: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlAddAttributeDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttributePtr ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDtdPtr dtd; /* pointer to the DTD */
+    int n_dtd;
+    xmlChar * elem; /* the element name */
+    int n_elem;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * ns; /* the attribute namespace prefix */
+    int n_ns;
+    xmlAttributeType type; /* the attribute type */
+    int n_type;
+    xmlAttributeDefault def; /* the attribute default type */
+    int n_def;
+    xmlChar * defaultValue; /* the attribute default value */
+    int n_defaultValue;
+    xmlEnumerationPtr tree; /* if it's an enumeration, the associated list */
+    int n_tree;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_elem = 0;n_elem < gen_nb_const_xmlChar_ptr;n_elem++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns = 0;n_ns < gen_nb_const_xmlChar_ptr;n_ns++) {
+    for (n_type = 0;n_type < gen_nb_xmlAttributeType;n_type++) {
+    for (n_def = 0;n_def < gen_nb_xmlAttributeDefault;n_def++) {
+    for (n_defaultValue = 0;n_defaultValue < gen_nb_const_xmlChar_ptr;n_defaultValue++) {
+    for (n_tree = 0;n_tree < gen_nb_xmlEnumerationPtr;n_tree++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        dtd = gen_xmlDtdPtr(n_dtd, 1);
+        elem = gen_const_xmlChar_ptr(n_elem, 2);
+        name = gen_const_xmlChar_ptr(n_name, 3);
+        ns = gen_const_xmlChar_ptr(n_ns, 4);
+        type = gen_xmlAttributeType(n_type, 5);
+        def = gen_xmlAttributeDefault(n_def, 6);
+        defaultValue = gen_const_xmlChar_ptr(n_defaultValue, 7);
+        tree = gen_xmlEnumerationPtr(n_tree, 8);
+
+        ret_val = xmlAddAttributeDecl(ctxt, dtd, (const xmlChar *)elem, (const xmlChar *)name, (const xmlChar *)ns, type, def, (const xmlChar *)defaultValue, tree);
+        desret_xmlAttributePtr(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDtdPtr(n_dtd, dtd, 1);
+        des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 2);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
+        des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 4);
+        des_xmlAttributeType(n_type, type, 5);
+        des_xmlAttributeDefault(n_def, def, 6);
+        des_const_xmlChar_ptr(n_defaultValue, (const xmlChar *)defaultValue, 7);
+        des_xmlEnumerationPtr(n_tree, tree, 8);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddAttributeDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_dtd);
+            printf(" %d", n_elem);
+            printf(" %d", n_name);
+            printf(" %d", n_ns);
+            printf(" %d", n_type);
+            printf(" %d", n_def);
+            printf(" %d", n_defaultValue);
+            printf(" %d", n_tree);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddElementDecl(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementPtr ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDtdPtr dtd; /* pointer to the DTD */
+    int n_dtd;
+    xmlChar * name; /* the entity name */
+    int n_name;
+    xmlElementTypeVal type; /* the element type */
+    int n_type;
+    xmlElementContentPtr content; /* the element content tree or NULL */
+    int n_content;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_xmlElementTypeVal;n_type++) {
+    for (n_content = 0;n_content < gen_nb_xmlElementContentPtr;n_content++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        dtd = gen_xmlDtdPtr(n_dtd, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        type = gen_xmlElementTypeVal(n_type, 3);
+        content = gen_xmlElementContentPtr(n_content, 4);
+
+        ret_val = xmlAddElementDecl(ctxt, dtd, (const xmlChar *)name, type, content);
+        desret_xmlElementPtr(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDtdPtr(n_dtd, dtd, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_xmlElementTypeVal(n_type, type, 3);
+        des_xmlElementContentPtr(n_content, content, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAddElementDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_dtd);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddID(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddNotationDecl(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAddRef(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlAttributeTablePtr 1
+static xmlAttributeTablePtr gen_xmlAttributeTablePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlAttributeTablePtr(int no ATTRIBUTE_UNUSED, xmlAttributeTablePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCopyAttributeTable(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyDocElementContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementContentPtr ret_val;
+    xmlDocPtr doc; /* the document owning the element declaration */
+    int n_doc;
+    xmlElementContentPtr cur; /* An element content pointer. */
+    int n_cur;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlElementContentPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        cur = gen_xmlElementContentPtr(n_cur, 1);
+
+        ret_val = xmlCopyDocElementContent(doc, cur);
+        desret_xmlElementContentPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlElementContentPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyDocElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyElementContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementContentPtr ret_val;
+    xmlElementContentPtr cur; /* An element content pointer. */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlElementContentPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlElementContentPtr(n_cur, 0);
+
+        ret_val = xmlCopyElementContent(cur);
+        desret_xmlElementContentPtr(ret_val);
+        call_tests++;
+        des_xmlElementContentPtr(n_cur, cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlElementTablePtr 1
+static xmlElementTablePtr gen_xmlElementTablePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlElementTablePtr(int no ATTRIBUTE_UNUSED, xmlElementTablePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCopyElementTable(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlCopyEnumeration(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlNotationTablePtr 1
+static xmlNotationTablePtr gen_xmlNotationTablePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlNotationTablePtr(int no ATTRIBUTE_UNUSED, xmlNotationTablePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCopyNotationTable(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlCreateEnumeration(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlAttributePtr 1
+static xmlAttributePtr gen_xmlAttributePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlAttributePtr(int no ATTRIBUTE_UNUSED, xmlAttributePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlDumpAttributeDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlAttributePtr attr; /* An attribute declaration */
+    int n_attr;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttributePtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        attr = gen_xmlAttributePtr(n_attr, 1);
+
+        xmlDumpAttributeDecl(buf, attr);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlAttributePtr(n_attr, attr, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpAttributeDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDumpAttributeTable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlAttributeTablePtr table; /* An attribute table */
+    int n_table;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_table = 0;n_table < gen_nb_xmlAttributeTablePtr;n_table++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        table = gen_xmlAttributeTablePtr(n_table, 1);
+
+        xmlDumpAttributeTable(buf, table);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlAttributeTablePtr(n_table, table, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpAttributeTable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_table);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlElementPtr 1
+static xmlElementPtr gen_xmlElementPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlElementPtr(int no ATTRIBUTE_UNUSED, xmlElementPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlDumpElementDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlElementPtr elem; /* An element table */
+    int n_elem;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlElementPtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        elem = gen_xmlElementPtr(n_elem, 1);
+
+        xmlDumpElementDecl(buf, elem);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlElementPtr(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpElementDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDumpElementTable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlElementTablePtr table; /* An element table */
+    int n_table;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_table = 0;n_table < gen_nb_xmlElementTablePtr;n_table++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        table = gen_xmlElementTablePtr(n_table, 1);
+
+        xmlDumpElementTable(buf, table);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlElementTablePtr(n_table, table, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpElementTable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_table);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlNotationPtr 1
+static xmlNotationPtr gen_xmlNotationPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlNotationPtr(int no ATTRIBUTE_UNUSED, xmlNotationPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlDumpNotationDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlNotationPtr nota; /* A notation declaration */
+    int n_nota;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_nota = 0;n_nota < gen_nb_xmlNotationPtr;n_nota++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        nota = gen_xmlNotationPtr(n_nota, 1);
+
+        xmlDumpNotationDecl(buf, nota);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlNotationPtr(n_nota, nota, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpNotationDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_nota);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlDumpNotationTable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* the XML buffer output */
+    int n_buf;
+    xmlNotationTablePtr table; /* A notation table */
+    int n_table;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_table = 0;n_table < gen_nb_xmlNotationTablePtr;n_table++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        table = gen_xmlNotationTablePtr(n_table, 1);
+
+        xmlDumpNotationTable(buf, table);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlNotationTablePtr(n_table, table, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlDumpNotationTable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_table);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdAttrDesc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttributePtr ret_val;
+    xmlDtdPtr dtd; /* a pointer to the DtD to search */
+    int n_dtd;
+    xmlChar * elem; /* the element name */
+    int n_elem;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_elem = 0;n_elem < gen_nb_const_xmlChar_ptr;n_elem++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        dtd = gen_xmlDtdPtr(n_dtd, 0);
+        elem = gen_const_xmlChar_ptr(n_elem, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+
+        ret_val = xmlGetDtdAttrDesc(dtd, (const xmlChar *)elem, (const xmlChar *)name);
+        desret_xmlAttributePtr(ret_val);
+        call_tests++;
+        des_xmlDtdPtr(n_dtd, dtd, 0);
+        des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDtdAttrDesc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dtd);
+            printf(" %d", n_elem);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdElementDesc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementPtr ret_val;
+    xmlDtdPtr dtd; /* a pointer to the DtD to search */
+    int n_dtd;
+    xmlChar * name; /* the element name */
+    int n_name;
+
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        dtd = gen_xmlDtdPtr(n_dtd, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlGetDtdElementDesc(dtd, (const xmlChar *)name);
+        desret_xmlElementPtr(ret_val);
+        call_tests++;
+        des_xmlDtdPtr(n_dtd, dtd, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDtdElementDesc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dtd);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdNotationDesc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdQAttrDesc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttributePtr ret_val;
+    xmlDtdPtr dtd; /* a pointer to the DtD to search */
+    int n_dtd;
+    xmlChar * elem; /* the element name */
+    int n_elem;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * prefix; /* the attribute namespace prefix */
+    int n_prefix;
+
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_elem = 0;n_elem < gen_nb_const_xmlChar_ptr;n_elem++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        dtd = gen_xmlDtdPtr(n_dtd, 0);
+        elem = gen_const_xmlChar_ptr(n_elem, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 3);
+
+        ret_val = xmlGetDtdQAttrDesc(dtd, (const xmlChar *)elem, (const xmlChar *)name, (const xmlChar *)prefix);
+        desret_xmlAttributePtr(ret_val);
+        call_tests++;
+        des_xmlDtdPtr(n_dtd, dtd, 0);
+        des_const_xmlChar_ptr(n_elem, (const xmlChar *)elem, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDtdQAttrDesc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dtd);
+            printf(" %d", n_elem);
+            printf(" %d", n_name);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetDtdQElementDesc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementPtr ret_val;
+    xmlDtdPtr dtd; /* a pointer to the DtD to search */
+    int n_dtd;
+    xmlChar * name; /* the element name */
+    int n_name;
+    xmlChar * prefix; /* the element namespace prefix */
+    int n_prefix;
+
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        dtd = gen_xmlDtdPtr(n_dtd, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 2);
+
+        ret_val = xmlGetDtdQElementDesc(dtd, (const xmlChar *)name, (const xmlChar *)prefix);
+        desret_xmlElementPtr(ret_val);
+        call_tests++;
+        des_xmlDtdPtr(n_dtd, dtd, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetDtdQElementDesc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_dtd);
+            printf(" %d", n_name);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetID(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlAttrPtr ret_val;
+    xmlDocPtr doc; /* pointer to the document */
+    int n_doc;
+    xmlChar * ID; /* the ID value */
+    int n_ID;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_ID = 0;n_ID < gen_nb_const_xmlChar_ptr;n_ID++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        ID = gen_const_xmlChar_ptr(n_ID, 1);
+
+        ret_val = xmlGetID(doc, (const xmlChar *)ID);
+        desret_xmlAttrPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_ID, (const xmlChar *)ID, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetID",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_ID);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetRefs(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsID(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr elem; /* the element carrying the attribute */
+    int n_elem;
+    xmlAttrPtr attr; /* the attribute */
+    int n_attr;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        elem = gen_xmlNodePtr(n_elem, 1);
+        attr = gen_xmlAttrPtr(n_attr, 2);
+
+        ret_val = xmlIsID(doc, elem, attr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_elem, elem, 1);
+        des_xmlAttrPtr(n_attr, attr, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsID",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsMixedElement(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the element name */
+    int n_name;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlIsMixedElement(doc, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsMixedElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIsRef(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr elem; /* the element carrying the attribute */
+    int n_elem;
+    xmlAttrPtr attr; /* the attribute */
+    int n_attr;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        elem = gen_xmlNodePtr(n_elem, 1);
+        attr = gen_xmlAttrPtr(n_attr, 2);
+
+        ret_val = xmlIsRef(doc, elem, attr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_elem, elem, 1);
+        des_xmlAttrPtr(n_attr, attr, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIsRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewDocElementContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementContentPtr ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * name; /* the subelement name or NULL */
+    int n_name;
+    xmlElementContentType type; /* the type of element content decl */
+    int n_type;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_xmlElementContentType;n_type++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        type = gen_xmlElementContentType(n_type, 2);
+
+        ret_val = xmlNewDocElementContent(doc, (const xmlChar *)name, type);
+        xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;
+        desret_xmlElementContentPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_xmlElementContentType(n_type, type, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewDocElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewElementContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlElementContentPtr ret_val;
+    xmlChar * name; /* the subelement name or NULL */
+    int n_name;
+    xmlElementContentType type; /* the type of element content decl */
+    int n_type;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_type = 0;n_type < gen_nb_xmlElementContentType;n_type++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+        type = gen_xmlElementContentType(n_type, 1);
+
+        ret_val = xmlNewElementContent((const xmlChar *)name, type);
+        desret_xmlElementContentPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        des_xmlElementContentType(n_type, type, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf(" %d", n_type);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewValidCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRemoveID(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlAttrPtr attr; /* the attribute */
+    int n_attr;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        attr = gen_xmlAttrPtr(n_attr, 1);
+
+        ret_val = xmlRemoveID(doc, attr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlAttrPtr(n_attr, attr, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRemoveID",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRemoveRef(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlAttrPtr attr; /* the attribute */
+    int n_attr;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        attr = gen_xmlAttrPtr(n_attr, 1);
+
+        ret_val = xmlRemoveRef(doc, attr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlAttrPtr(n_attr, attr, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRemoveRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSnprintfElementContent(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    char * buf; /* an output buffer */
+    int n_buf;
+    int size; /* the buffer size */
+    int n_size;
+    xmlElementContentPtr content; /* An element table */
+    int n_content;
+    int englob; /* 1 if one must print the englobing parenthesis, 0 otherwise */
+    int n_englob;
+
+    for (n_buf = 0;n_buf < gen_nb_char_ptr;n_buf++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_content = 0;n_content < gen_nb_xmlElementContentPtr;n_content++) {
+    for (n_englob = 0;n_englob < gen_nb_int;n_englob++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_char_ptr(n_buf, 0);
+        size = gen_int(n_size, 1);
+        content = gen_xmlElementContentPtr(n_content, 2);
+        englob = gen_int(n_englob, 3);
+
+        xmlSnprintfElementContent(buf, size, content, englob);
+        call_tests++;
+        des_char_ptr(n_buf, buf, 0);
+        des_int(n_size, size, 1);
+        des_xmlElementContentPtr(n_content, content, 2);
+        des_int(n_englob, englob, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSnprintfElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_size);
+            printf(" %d", n_content);
+            printf(" %d", n_englob);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSprintfElementContent(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+#ifdef LIBXML_OUTPUT_ENABLED
+    int mem_base;
+    char * buf; /* an output buffer */
+    int n_buf;
+    xmlElementContentPtr content; /* An element table */
+    int n_content;
+    int englob; /* 1 if one must print the englobing parenthesis, 0 otherwise */
+    int n_englob;
+
+    for (n_buf = 0;n_buf < gen_nb_char_ptr;n_buf++) {
+    for (n_content = 0;n_content < gen_nb_xmlElementContentPtr;n_content++) {
+    for (n_englob = 0;n_englob < gen_nb_int;n_englob++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_char_ptr(n_buf, 0);
+        content = gen_xmlElementContentPtr(n_content, 1);
+        englob = gen_int(n_englob, 2);
+
+        xmlSprintfElementContent(buf, content, englob);
+        call_tests++;
+        des_char_ptr(n_buf, buf, 0);
+        des_xmlElementContentPtr(n_content, content, 1);
+        des_int(n_englob, englob, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSprintfElementContent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_content);
+            printf(" %d", n_englob);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidBuildContentModel(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* a validation context */
+    int n_ctxt;
+    xmlElementPtr elem; /* an element declaration node */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlElementPtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        elem = gen_xmlElementPtr(n_elem, 1);
+
+        ret_val = xmlValidBuildContentModel(ctxt, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlElementPtr(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidBuildContentModel",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidCtxtNormalizeAttributeValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context or NULL */
+    int n_ctxt;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr elem; /* the parent */
+    int n_elem;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * value; /* the attribute value */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+        name = gen_const_xmlChar_ptr(n_name, 3);
+        value = gen_const_xmlChar_ptr(n_value, 4);
+
+        ret_val = xmlValidCtxtNormalizeAttributeValue(ctxt, doc, elem, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidCtxtNormalizeAttributeValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlElementContent_ptr 1
+static xmlElementContent * gen_xmlElementContent_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlElementContent_ptr(int no ATTRIBUTE_UNUSED, xmlElementContent * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlValidGetPotentialChildren(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef LIBXML_VALID_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlElementContent * ctree; /* an element content tree */
+    int n_ctree;
+    xmlChar ** names; /* an array to store the list of child names */
+    int n_names;
+    int * len; /* a pointer to the number of element in the list */
+    int n_len;
+    int max; /* the size of the array */
+    int n_max;
+
+    for (n_ctree = 0;n_ctree < gen_nb_xmlElementContent_ptr;n_ctree++) {
+    for (n_names = 0;n_names < gen_nb_const_xmlChar_ptr_ptr;n_names++) {
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+    for (n_max = 0;n_max < gen_nb_int;n_max++) {
+        mem_base = xmlMemBlocks();
+        ctree = gen_xmlElementContent_ptr(n_ctree, 0);
+        names = gen_const_xmlChar_ptr_ptr(n_names, 1);
+        len = gen_int_ptr(n_len, 2);
+        max = gen_int(n_max, 3);
+
+        ret_val = xmlValidGetPotentialChildren(ctree, (const xmlChar **)names, len, max);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlElementContent_ptr(n_ctree, ctree, 0);
+        des_const_xmlChar_ptr_ptr(n_names, (const xmlChar **)names, 1);
+        des_int_ptr(n_len, len, 2);
+        des_int(n_max, max, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidGetPotentialChildren",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctree);
+            printf(" %d", n_names);
+            printf(" %d", n_len);
+            printf(" %d", n_max);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidGetValidElements(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+#ifdef LIBXML_VALID_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlNode * prev; /* an element to insert after */
+    int n_prev;
+    xmlNode * next; /* an element to insert next */
+    int n_next;
+    xmlChar ** names; /* an array to store the list of child names */
+    int n_names;
+    int max; /* the size of the array */
+    int n_max;
+
+    for (n_prev = 0;n_prev < gen_nb_xmlNodePtr;n_prev++) {
+    for (n_next = 0;n_next < gen_nb_xmlNodePtr;n_next++) {
+    for (n_names = 0;n_names < gen_nb_const_xmlChar_ptr_ptr;n_names++) {
+    for (n_max = 0;n_max < gen_nb_int;n_max++) {
+        mem_base = xmlMemBlocks();
+        prev = gen_xmlNodePtr(n_prev, 0);
+        next = gen_xmlNodePtr(n_next, 1);
+        names = gen_const_xmlChar_ptr_ptr(n_names, 2);
+        max = gen_int(n_max, 3);
+
+        ret_val = xmlValidGetValidElements(prev, next, (const xmlChar **)names, max);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_prev, prev, 0);
+        des_xmlNodePtr(n_next, next, 1);
+        des_const_xmlChar_ptr_ptr(n_names, (const xmlChar **)names, 2);
+        des_int(n_max, max, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidGetValidElements",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_prev);
+            printf(" %d", n_next);
+            printf(" %d", n_names);
+            printf(" %d", n_max);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidNormalizeAttributeValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlNodePtr elem; /* the parent */
+    int n_elem;
+    xmlChar * name; /* the attribute name */
+    int n_name;
+    xmlChar * value; /* the attribute value */
+    int n_value;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        elem = gen_xmlNodePtr(n_elem, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        value = gen_const_xmlChar_ptr(n_value, 3);
+
+        ret_val = xmlValidNormalizeAttributeValue(doc, elem, (const xmlChar *)name, (const xmlChar *)value);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_elem, elem, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidNormalizeAttributeValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateAttributeDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlAttributePtr attr; /* an attribute definition */
+    int n_attr;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttributePtr;n_attr++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        attr = gen_xmlAttributePtr(n_attr, 2);
+
+        ret_val = xmlValidateAttributeDecl(ctxt, doc, attr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlAttributePtr(n_attr, attr, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateAttributeDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_attr);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateAttributeValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlAttributeType type; /* an attribute type */
+    int n_type;
+    xmlChar * value; /* an attribute value */
+    int n_value;
+
+    for (n_type = 0;n_type < gen_nb_xmlAttributeType;n_type++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlAttributeType(n_type, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+
+        ret_val = xmlValidateAttributeValue(type, (const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlAttributeType(n_type, type, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateAttributeValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlValidateDocument(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateDocumentFinal(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlValidateDocumentFinal(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateDocumentFinal",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateDtd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlDtdPtr dtd; /* a dtd instance */
+    int n_dtd;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_dtd = 0;n_dtd < gen_nb_xmlDtdPtr;n_dtd++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        dtd = gen_xmlDtdPtr(n_dtd, 2);
+
+        ret_val = xmlValidateDtd(ctxt, doc, dtd);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlDtdPtr(n_dtd, dtd, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateDtd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_dtd);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateDtdFinal(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlValidateDtdFinal(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateDtdFinal",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+
+        ret_val = xmlValidateElement(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateElementDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlElementPtr elem; /* an element definition */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlElementPtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlElementPtr(n_elem, 2);
+
+        ret_val = xmlValidateElementDecl(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlElementPtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateElementDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNameValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* an Name value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlValidateNameValue((const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNameValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNamesValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* an Names value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlValidateNamesValue((const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNamesValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNmtokenValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* an Nmtoken value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlValidateNmtokenValue((const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNmtokenValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNmtokensValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * value; /* an Nmtokens value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlValidateNmtokensValue((const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNmtokensValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNotationDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNotationPtr nota; /* a notation definition */
+    int n_nota;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_nota = 0;n_nota < gen_nb_xmlNotationPtr;n_nota++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        nota = gen_xmlNotationPtr(n_nota, 2);
+
+        ret_val = xmlValidateNotationDecl(ctxt, doc, nota);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNotationPtr(n_nota, nota, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNotationDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_nota);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateNotationUse(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* the document */
+    int n_doc;
+    xmlChar * notationName; /* the notation name to check */
+    int n_notationName;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_notationName = 0;n_notationName < gen_nb_const_xmlChar_ptr;n_notationName++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        notationName = gen_const_xmlChar_ptr(n_notationName, 2);
+
+        ret_val = xmlValidateNotationUse(ctxt, doc, (const xmlChar *)notationName);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_const_xmlChar_ptr(n_notationName, (const xmlChar *)notationName, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateNotationUse",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_notationName);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateOneAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+    xmlAttrPtr attr; /* an attribute instance */
+    int n_attr;
+    xmlChar * value; /* the attribute value (without entities processing) */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_attr = 0;n_attr < gen_nb_xmlAttrPtr;n_attr++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+        attr = gen_xmlAttrPtr(n_attr, 3);
+        value = gen_const_xmlChar_ptr(n_value, 4);
+
+        ret_val = xmlValidateOneAttribute(ctxt, doc, elem, attr, (const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        des_xmlAttrPtr(n_attr, attr, 3);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateOneAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_attr);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateOneElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+
+        ret_val = xmlValidateOneElement(ctxt, doc, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateOneElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateOneNamespace(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+    xmlChar * prefix; /* the namespace prefix */
+    int n_prefix;
+    xmlNsPtr ns; /* an namespace declaration instance */
+    int n_ns;
+    xmlChar * value; /* the attribute value (without entities processing) */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 3);
+        ns = gen_xmlNsPtr(n_ns, 4);
+        value = gen_const_xmlChar_ptr(n_value, 5);
+
+        ret_val = xmlValidateOneNamespace(ctxt, doc, elem, (const xmlChar *)prefix, ns, (const xmlChar *)value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 3);
+        des_xmlNsPtr(n_ns, ns, 4);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateOneNamespace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_prefix);
+            printf(" %d", n_ns);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidatePopElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+    xmlChar * qname; /* the qualified name as appearing in the serialization */
+    int n_qname;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_qname = 0;n_qname < gen_nb_const_xmlChar_ptr;n_qname++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+        qname = gen_const_xmlChar_ptr(n_qname, 3);
+
+        ret_val = xmlValidatePopElement(ctxt, doc, elem, (const xmlChar *)qname);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        des_const_xmlChar_ptr(n_qname, (const xmlChar *)qname, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidatePopElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_qname);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidatePushCData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlChar * data; /* some character data read */
+    int n_data;
+    int len; /* the lenght of the data */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_data = 0;n_data < gen_nb_const_xmlChar_ptr;n_data++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        data = gen_const_xmlChar_ptr(n_data, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlValidatePushCData(ctxt, (const xmlChar *)data, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_data, (const xmlChar *)data, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidatePushCData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_data);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidatePushElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED) && defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+    xmlNodePtr elem; /* an element instance */
+    int n_elem;
+    xmlChar * qname; /* the qualified name as appearing in the serialization */
+    int n_qname;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+    for (n_qname = 0;n_qname < gen_nb_const_xmlChar_ptr;n_qname++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+        elem = gen_xmlNodePtr(n_elem, 2);
+        qname = gen_const_xmlChar_ptr(n_qname, 3);
+
+        ret_val = xmlValidatePushElement(ctxt, doc, elem, (const xmlChar *)qname);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        des_xmlNodePtr(n_elem, elem, 2);
+        des_const_xmlChar_ptr(n_qname, (const xmlChar *)qname, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidatePushElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf(" %d", n_elem);
+            printf(" %d", n_qname);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlValidateRoot(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_VALID_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlValidCtxtPtr ctxt; /* the validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document instance */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlValidateRoot(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlValidateRoot",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_valid(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing valid : 50 of 70 functions ...\n");
+    test_ret += test_xmlAddAttributeDecl();
+    test_ret += test_xmlAddElementDecl();
+    test_ret += test_xmlAddID();
+    test_ret += test_xmlAddNotationDecl();
+    test_ret += test_xmlAddRef();
+    test_ret += test_xmlCopyAttributeTable();
+    test_ret += test_xmlCopyDocElementContent();
+    test_ret += test_xmlCopyElementContent();
+    test_ret += test_xmlCopyElementTable();
+    test_ret += test_xmlCopyEnumeration();
+    test_ret += test_xmlCopyNotationTable();
+    test_ret += test_xmlCreateEnumeration();
+    test_ret += test_xmlDumpAttributeDecl();
+    test_ret += test_xmlDumpAttributeTable();
+    test_ret += test_xmlDumpElementDecl();
+    test_ret += test_xmlDumpElementTable();
+    test_ret += test_xmlDumpNotationDecl();
+    test_ret += test_xmlDumpNotationTable();
+    test_ret += test_xmlGetDtdAttrDesc();
+    test_ret += test_xmlGetDtdElementDesc();
+    test_ret += test_xmlGetDtdNotationDesc();
+    test_ret += test_xmlGetDtdQAttrDesc();
+    test_ret += test_xmlGetDtdQElementDesc();
+    test_ret += test_xmlGetID();
+    test_ret += test_xmlGetRefs();
+    test_ret += test_xmlIsID();
+    test_ret += test_xmlIsMixedElement();
+    test_ret += test_xmlIsRef();
+    test_ret += test_xmlNewDocElementContent();
+    test_ret += test_xmlNewElementContent();
+    test_ret += test_xmlNewValidCtxt();
+    test_ret += test_xmlRemoveID();
+    test_ret += test_xmlRemoveRef();
+    test_ret += test_xmlSnprintfElementContent();
+    test_ret += test_xmlSprintfElementContent();
+    test_ret += test_xmlValidBuildContentModel();
+    test_ret += test_xmlValidCtxtNormalizeAttributeValue();
+    test_ret += test_xmlValidGetPotentialChildren();
+    test_ret += test_xmlValidGetValidElements();
+    test_ret += test_xmlValidNormalizeAttributeValue();
+    test_ret += test_xmlValidateAttributeDecl();
+    test_ret += test_xmlValidateAttributeValue();
+    test_ret += test_xmlValidateDocument();
+    test_ret += test_xmlValidateDocumentFinal();
+    test_ret += test_xmlValidateDtd();
+    test_ret += test_xmlValidateDtdFinal();
+    test_ret += test_xmlValidateElement();
+    test_ret += test_xmlValidateElementDecl();
+    test_ret += test_xmlValidateNameValue();
+    test_ret += test_xmlValidateNamesValue();
+    test_ret += test_xmlValidateNmtokenValue();
+    test_ret += test_xmlValidateNmtokensValue();
+    test_ret += test_xmlValidateNotationDecl();
+    test_ret += test_xmlValidateNotationUse();
+    test_ret += test_xmlValidateOneAttribute();
+    test_ret += test_xmlValidateOneElement();
+    test_ret += test_xmlValidateOneNamespace();
+    test_ret += test_xmlValidatePopElement();
+    test_ret += test_xmlValidatePushCData();
+    test_ret += test_xmlValidatePushElement();
+    test_ret += test_xmlValidateRoot();
+
+    if (test_ret != 0)
+	printf("Module valid: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlXIncludeNewContext(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcess(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* an XML document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlXIncludeProcess(doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcess",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcessFlags(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* an XML document */
+    int n_doc;
+    int flags; /* a set of xmlParserOption used for parsing XML includes */
+    int n_flags;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        flags = gen_int(n_flags, 1);
+
+        ret_val = xmlXIncludeProcessFlags(doc, flags);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_int(n_flags, flags, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessFlags",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_flags);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcessFlagsData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlDocPtr doc; /* an XML document */
+    int n_doc;
+    int flags; /* a set of xmlParserOption used for parsing XML includes */
+    int n_flags;
+    void * data; /* application data that will be passed to the parser context in the _private field of the parser context(s) */
+    int n_data;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        flags = gen_int(n_flags, 1);
+        data = gen_userdata(n_data, 2);
+
+        ret_val = xmlXIncludeProcessFlagsData(doc, flags, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_int(n_flags, flags, 1);
+        des_userdata(n_data, data, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessFlagsData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_flags);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+
+#define gen_nb_xmlXIncludeCtxtPtr 1
+static xmlXIncludeCtxtPtr gen_xmlXIncludeCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlXIncludeCtxtPtr(int no ATTRIBUTE_UNUSED, xmlXIncludeCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlXIncludeProcessNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXIncludeCtxtPtr ctxt; /* an existing XInclude context */
+    int n_ctxt;
+    xmlNodePtr node; /* a node in an XML document */
+    int n_node;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXIncludeCtxtPtr;n_ctxt++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXIncludeCtxtPtr(n_ctxt, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlXIncludeProcessNode(ctxt, node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXIncludeCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcessTree(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr tree; /* a node in an XML document */
+    int n_tree;
+
+    for (n_tree = 0;n_tree < gen_nb_xmlNodePtr;n_tree++) {
+        mem_base = xmlMemBlocks();
+        tree = gen_xmlNodePtr(n_tree, 0);
+
+        ret_val = xmlXIncludeProcessTree(tree);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_tree, tree, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessTree",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_tree);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcessTreeFlags(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr tree; /* a node in an XML document */
+    int n_tree;
+    int flags; /* a set of xmlParserOption used for parsing XML includes */
+    int n_flags;
+
+    for (n_tree = 0;n_tree < gen_nb_xmlNodePtr;n_tree++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+        mem_base = xmlMemBlocks();
+        tree = gen_xmlNodePtr(n_tree, 0);
+        flags = gen_int(n_flags, 1);
+
+        ret_val = xmlXIncludeProcessTreeFlags(tree, flags);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_tree, tree, 0);
+        des_int(n_flags, flags, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessTreeFlags",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_tree);
+            printf(" %d", n_flags);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeProcessTreeFlagsData(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr tree; /* an XML node */
+    int n_tree;
+    int flags; /* a set of xmlParserOption used for parsing XML includes */
+    int n_flags;
+    void * data; /* application data that will be passed to the parser context in the _private field of the parser context(s) */
+    int n_data;
+
+    for (n_tree = 0;n_tree < gen_nb_xmlNodePtr;n_tree++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        tree = gen_xmlNodePtr(n_tree, 0);
+        flags = gen_int(n_flags, 1);
+        data = gen_userdata(n_data, 2);
+
+        ret_val = xmlXIncludeProcessTreeFlagsData(tree, flags, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_tree, tree, 0);
+        des_int(n_flags, flags, 1);
+        des_userdata(n_data, data, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeProcessTreeFlagsData",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_tree);
+            printf(" %d", n_flags);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXIncludeSetFlags(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXIncludeCtxtPtr ctxt; /* an XInclude processing context */
+    int n_ctxt;
+    int flags; /* a set of xmlParserOption used for parsing XML includes */
+    int n_flags;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXIncludeCtxtPtr;n_ctxt++) {
+    for (n_flags = 0;n_flags < gen_nb_int;n_flags++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXIncludeCtxtPtr(n_ctxt, 0);
+        flags = gen_int(n_flags, 1);
+
+        ret_val = xmlXIncludeSetFlags(ctxt, flags);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXIncludeCtxtPtr(n_ctxt, ctxt, 0);
+        des_int(n_flags, flags, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXIncludeSetFlags",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_flags);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xinclude(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xinclude : 8 of 10 functions ...\n");
+    test_ret += test_xmlXIncludeNewContext();
+    test_ret += test_xmlXIncludeProcess();
+    test_ret += test_xmlXIncludeProcessFlags();
+    test_ret += test_xmlXIncludeProcessFlagsData();
+    test_ret += test_xmlXIncludeProcessNode();
+    test_ret += test_xmlXIncludeProcessTree();
+    test_ret += test_xmlXIncludeProcessTreeFlags();
+    test_ret += test_xmlXIncludeProcessTreeFlagsData();
+    test_ret += test_xmlXIncludeSetFlags();
+
+    if (test_ret != 0)
+	printf("Module xinclude: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlAllocOutputBuffer(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr ret_val;
+    xmlCharEncodingHandlerPtr encoder; /* the encoding converter or NULL */
+    int n_encoder;
+
+    for (n_encoder = 0;n_encoder < gen_nb_xmlCharEncodingHandlerPtr;n_encoder++) {
+        mem_base = xmlMemBlocks();
+        encoder = gen_xmlCharEncodingHandlerPtr(n_encoder, 0);
+
+        ret_val = xmlAllocOutputBuffer(encoder);
+        desret_xmlOutputBufferPtr(ret_val);
+        call_tests++;
+        des_xmlCharEncodingHandlerPtr(n_encoder, encoder, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAllocOutputBuffer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_encoder);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAllocParserInputBuffer(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        enc = gen_xmlCharEncoding(n_enc, 0);
+
+        ret_val = xmlAllocParserInputBuffer(enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_xmlCharEncoding(n_enc, enc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAllocParserInputBuffer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCheckFilename(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    char * path; /* the path to check */
+    int n_path;
+
+    for (n_path = 0;n_path < gen_nb_const_char_ptr;n_path++) {
+        mem_base = xmlMemBlocks();
+        path = gen_const_char_ptr(n_path, 0);
+
+        ret_val = xmlCheckFilename((const char *)path);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_path, (const char *)path, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCheckFilename",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_path);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCheckHTTPInput(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* an XML parser context */
+    int n_ctxt;
+    xmlParserInputPtr ret; /* an XML parser input */
+    int n_ret;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_ret = 0;n_ret < gen_nb_xmlParserInputPtr;n_ret++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        ret = gen_xmlParserInputPtr(n_ret, 1);
+
+        ret_val = xmlCheckHTTPInput(ctxt, ret);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputPtr(n_ret, ret, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCheckHTTPInput",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_ret);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCleanupInputCallbacks(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlCleanupInputCallbacks();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCleanupInputCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCleanupOutputCallbacks(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlCleanupOutputCallbacks();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCleanupOutputCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFileClose(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+
+        ret_val = xmlFileClose(context);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlFileClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFileMatch(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlFileMatch(filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlFileMatch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFileOpen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlFileOpen(filename);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlFileOpen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlFileRead(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+    char * buffer; /* where to drop data */
+    int n_buffer;
+    int len; /* number of bytes to write */
+    int n_len;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+    for (n_buffer = 0;n_buffer < gen_nb_char_ptr;n_buffer++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+        buffer = gen_char_ptr(n_buffer, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlFileRead(context, buffer, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        des_char_ptr(n_buffer, buffer, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlFileRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf(" %d", n_buffer);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOFTPClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+
+        ret_val = xmlIOFTPClose(context);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOFTPClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOFTPMatch(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlIOFTPMatch(filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOFTPMatch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOFTPOpen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlIOFTPOpen(filename);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOFTPOpen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOFTPRead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_FTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+    char * buffer; /* where to drop data */
+    int n_buffer;
+    int len; /* number of bytes to write */
+    int n_len;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+    for (n_buffer = 0;n_buffer < gen_nb_char_ptr;n_buffer++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+        buffer = gen_char_ptr(n_buffer, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlIOFTPRead(context, buffer, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        des_char_ptr(n_buffer, buffer, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOFTPRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf(" %d", n_buffer);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOHTTPClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+
+        ret_val = xmlIOHTTPClose(context);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOHTTPClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOHTTPMatch(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlIOHTTPMatch(filename);
+        desret_int(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOHTTPMatch",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOHTTPOpen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    void * ret_val;
+    const char * filename; /* the URI for matching */
+    int n_filename;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+
+        ret_val = xmlIOHTTPOpen(filename);
+        desret_xmlNanoHTTPCtxtPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOHTTPOpen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlIOHTTPRead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+    int ret_val;
+    void * context; /* the I/O context */
+    int n_context;
+    char * buffer; /* where to drop data */
+    int n_buffer;
+    int len; /* number of bytes to write */
+    int n_len;
+
+    for (n_context = 0;n_context < gen_nb_void_ptr;n_context++) {
+    for (n_buffer = 0;n_buffer < gen_nb_char_ptr;n_buffer++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        context = gen_void_ptr(n_context, 0);
+        buffer = gen_char_ptr(n_buffer, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlIOHTTPRead(context, buffer, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_void_ptr(n_context, context, 0);
+        des_char_ptr(n_buffer, buffer, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlIOHTTPRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_context);
+            printf(" %d", n_buffer);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNoNetExternalEntityLoader(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr ret_val;
+    const char * URL; /* the URL for the entity to load */
+    int n_URL;
+    char * ID; /* the System ID for the entity to load */
+    int n_ID;
+    xmlParserCtxtPtr ctxt; /* the context in which the entity is called or NULL */
+    int n_ctxt;
+
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_ID = 0;n_ID < gen_nb_const_char_ptr;n_ID++) {
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_filepath(n_URL, 0);
+        ID = gen_const_char_ptr(n_ID, 1);
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 2);
+
+        ret_val = xmlNoNetExternalEntityLoader(URL, (const char *)ID, ctxt);
+        desret_xmlParserInputPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URL, URL, 0);
+        des_const_char_ptr(n_ID, (const char *)ID, 1);
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNoNetExternalEntityLoader",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf(" %d", n_ID);
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNormalizeWindowsPath(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * path; /* the input file path */
+    int n_path;
+
+    for (n_path = 0;n_path < gen_nb_const_xmlChar_ptr;n_path++) {
+        mem_base = xmlMemBlocks();
+        path = gen_const_xmlChar_ptr(n_path, 0);
+
+        ret_val = xmlNormalizeWindowsPath((const xmlChar *)path);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_path, (const xmlChar *)path, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNormalizeWindowsPath",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_path);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferCreateBuffer(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr ret_val;
+    xmlBufferPtr buffer; /* a xmlBufferPtr */
+    int n_buffer;
+    xmlCharEncodingHandlerPtr encoder; /* the encoding converter or NULL */
+    int n_encoder;
+
+    for (n_buffer = 0;n_buffer < gen_nb_xmlBufferPtr;n_buffer++) {
+    for (n_encoder = 0;n_encoder < gen_nb_xmlCharEncodingHandlerPtr;n_encoder++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_xmlBufferPtr(n_buffer, 0);
+        encoder = gen_xmlCharEncodingHandlerPtr(n_encoder, 1);
+
+        ret_val = xmlOutputBufferCreateBuffer(buffer, encoder);
+        desret_xmlOutputBufferPtr(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buffer, buffer, 0);
+        des_xmlCharEncodingHandlerPtr(n_encoder, encoder, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferCreateBuffer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_encoder);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferCreateFd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr ret_val;
+    int fd; /* a file descriptor number */
+    int n_fd;
+    xmlCharEncodingHandlerPtr encoder; /* the encoding converter or NULL */
+    int n_encoder;
+
+    for (n_fd = 0;n_fd < gen_nb_int;n_fd++) {
+    for (n_encoder = 0;n_encoder < gen_nb_xmlCharEncodingHandlerPtr;n_encoder++) {
+        mem_base = xmlMemBlocks();
+        fd = gen_int(n_fd, 0);
+        encoder = gen_xmlCharEncodingHandlerPtr(n_encoder, 1);
+
+        ret_val = xmlOutputBufferCreateFd(fd, encoder);
+        desret_xmlOutputBufferPtr(ret_val);
+        call_tests++;
+        des_int(n_fd, fd, 0);
+        des_xmlCharEncodingHandlerPtr(n_encoder, encoder, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferCreateFd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_fd);
+            printf(" %d", n_encoder);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferCreateFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr ret_val;
+    FILE * file; /* a FILE* */
+    int n_file;
+    xmlCharEncodingHandlerPtr encoder; /* the encoding converter or NULL */
+    int n_encoder;
+
+    for (n_file = 0;n_file < gen_nb_FILE_ptr;n_file++) {
+    for (n_encoder = 0;n_encoder < gen_nb_xmlCharEncodingHandlerPtr;n_encoder++) {
+        mem_base = xmlMemBlocks();
+        file = gen_FILE_ptr(n_file, 0);
+        encoder = gen_xmlCharEncodingHandlerPtr(n_encoder, 1);
+
+        ret_val = xmlOutputBufferCreateFile(file, encoder);
+        desret_xmlOutputBufferPtr(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_file, file, 0);
+        des_xmlCharEncodingHandlerPtr(n_encoder, encoder, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferCreateFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_file);
+            printf(" %d", n_encoder);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferCreateFilename(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    xmlOutputBufferPtr ret_val;
+    const char * URI; /* a C string containing the URI or filename */
+    int n_URI;
+    xmlCharEncodingHandlerPtr encoder; /* the encoding converter or NULL */
+    int n_encoder;
+    int compression; /* the compression ration (0 none, 9 max). */
+    int n_compression;
+
+    for (n_URI = 0;n_URI < gen_nb_fileoutput;n_URI++) {
+    for (n_encoder = 0;n_encoder < gen_nb_xmlCharEncodingHandlerPtr;n_encoder++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_fileoutput(n_URI, 0);
+        encoder = gen_xmlCharEncodingHandlerPtr(n_encoder, 1);
+        compression = gen_int(n_compression, 2);
+
+        ret_val = xmlOutputBufferCreateFilename(URI, encoder, compression);
+        desret_xmlOutputBufferPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_URI, URI, 0);
+        des_xmlCharEncodingHandlerPtr(n_encoder, encoder, 1);
+        des_int(n_compression, compression, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferCreateFilename",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_encoder);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferFlush(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlOutputBufferPtr out; /* a buffered output */
+    int n_out;
+
+    for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
+        mem_base = xmlMemBlocks();
+        out = gen_xmlOutputBufferPtr(n_out, 0);
+
+        ret_val = xmlOutputBufferFlush(out);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_out, out, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferFlush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferWrite(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlOutputBufferPtr out; /* a buffered parser output */
+    int n_out;
+    int len; /* the size in bytes of the array. */
+    int n_len;
+    char * buf; /* an char array */
+    int n_buf;
+
+    for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+    for (n_buf = 0;n_buf < gen_nb_const_char_ptr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        out = gen_xmlOutputBufferPtr(n_out, 0);
+        len = gen_int(n_len, 1);
+        buf = gen_const_char_ptr(n_buf, 2);
+
+        ret_val = xmlOutputBufferWrite(out, len, (const char *)buf);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_out, out, 0);
+        des_int(n_len, len, 1);
+        des_const_char_ptr(n_buf, (const char *)buf, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferWrite",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_len);
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferWriteEscape(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlOutputBufferWriteString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlOutputBufferPtr out; /* a buffered parser output */
+    int n_out;
+    char * str; /* a zero terminated C string */
+    int n_str;
+
+    for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
+    for (n_str = 0;n_str < gen_nb_const_char_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        out = gen_xmlOutputBufferPtr(n_out, 0);
+        str = gen_const_char_ptr(n_str, 1);
+
+        ret_val = xmlOutputBufferWriteString(out, (const char *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_out, out, 0);
+        des_const_char_ptr(n_str, (const char *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlOutputBufferWriteString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserGetDirectory(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferCreateFd(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    int fd; /* a file descriptor number */
+    int n_fd;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_fd = 0;n_fd < gen_nb_int;n_fd++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        fd = gen_int(n_fd, 0);
+        enc = gen_xmlCharEncoding(n_enc, 1);
+        if (fd >= 0) fd = -1;
+
+        ret_val = xmlParserInputBufferCreateFd(fd, enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_int(n_fd, fd, 0);
+        des_xmlCharEncoding(n_enc, enc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferCreateFd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_fd);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferCreateFile(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    FILE * file; /* a FILE* */
+    int n_file;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_file = 0;n_file < gen_nb_FILE_ptr;n_file++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        file = gen_FILE_ptr(n_file, 0);
+        enc = gen_xmlCharEncoding(n_enc, 1);
+
+        ret_val = xmlParserInputBufferCreateFile(file, enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_FILE_ptr(n_file, file, 0);
+        des_xmlCharEncoding(n_enc, enc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferCreateFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_file);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferCreateFilename(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    const char * URI; /* a C string containing the URI or filename */
+    int n_URI;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_URI = 0;n_URI < gen_nb_fileoutput;n_URI++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_fileoutput(n_URI, 0);
+        enc = gen_xmlCharEncoding(n_enc, 1);
+
+        ret_val = xmlParserInputBufferCreateFilename(URI, enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_URI, URI, 0);
+        des_xmlCharEncoding(n_enc, enc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferCreateFilename",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferCreateMem(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    char * mem; /* the memory input */
+    int n_mem;
+    int size; /* the length of the memory block */
+    int n_size;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_mem = 0;n_mem < gen_nb_const_char_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        mem = gen_const_char_ptr(n_mem, 0);
+        size = gen_int(n_size, 1);
+        enc = gen_xmlCharEncoding(n_enc, 2);
+
+        ret_val = xmlParserInputBufferCreateMem((const char *)mem, size, enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_mem, (const char *)mem, 0);
+        des_int(n_size, size, 1);
+        des_xmlCharEncoding(n_enc, enc, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferCreateMem",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferCreateStatic(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    char * mem; /* the memory input */
+    int n_mem;
+    int size; /* the length of the memory block */
+    int n_size;
+    xmlCharEncoding enc; /* the charset encoding if known */
+    int n_enc;
+
+    for (n_mem = 0;n_mem < gen_nb_const_char_ptr;n_mem++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+        mem_base = xmlMemBlocks();
+        mem = gen_const_char_ptr(n_mem, 0);
+        size = gen_int(n_size, 1);
+        enc = gen_xmlCharEncoding(n_enc, 2);
+
+        ret_val = xmlParserInputBufferCreateStatic((const char *)mem, size, enc);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_mem, (const char *)mem, 0);
+        des_int(n_size, size, 1);
+        des_xmlCharEncoding(n_enc, enc, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferCreateStatic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_mem);
+            printf(" %d", n_size);
+            printf(" %d", n_enc);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferGrow(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserInputBufferPtr in; /* a buffered parser input */
+    int n_in;
+    int len; /* indicative value of the amount of chars to read */
+    int n_len;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputBufferPtr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputBufferPtr(n_in, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlParserInputBufferGrow(in, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserInputBufferPtr(n_in, in, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferGrow",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferPush(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserInputBufferPtr in; /* a buffered parser input */
+    int n_in;
+    int len; /* the size in bytes of the array. */
+    int n_len;
+    char * buf; /* an char array */
+    int n_buf;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputBufferPtr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+    for (n_buf = 0;n_buf < gen_nb_const_char_ptr;n_buf++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputBufferPtr(n_in, 0);
+        len = gen_int(n_len, 1);
+        buf = gen_const_char_ptr(n_buf, 2);
+
+        ret_val = xmlParserInputBufferPush(in, len, (const char *)buf);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserInputBufferPtr(n_in, in, 0);
+        des_int(n_len, len, 1);
+        des_const_char_ptr(n_buf, (const char *)buf, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferPush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf(" %d", n_buf);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserInputBufferRead(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlParserInputBufferPtr in; /* a buffered parser input */
+    int n_in;
+    int len; /* indicative value of the amount of chars to read */
+    int n_len;
+
+    for (n_in = 0;n_in < gen_nb_xmlParserInputBufferPtr;n_in++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        in = gen_xmlParserInputBufferPtr(n_in, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlParserInputBufferRead(in, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlParserInputBufferPtr(n_in, in, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserInputBufferRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_in);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlPopInputCallbacks(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+
+        mem_base = xmlMemBlocks();
+
+        ret_val = xmlPopInputCallbacks();
+        desret_int(ret_val);
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlPopInputCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegisterDefaultInputCallbacks(void) {
+    int test_ret = 0;
+
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlRegisterDefaultInputCallbacks();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegisterDefaultInputCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegisterDefaultOutputCallbacks(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlRegisterDefaultOutputCallbacks();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegisterDefaultOutputCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegisterHTTPPostCallbacks(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED) && defined(LIBXML_HTTP_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlRegisterHTTPPostCallbacks();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegisterHTTPPostCallbacks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlIO(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlIO : 39 of 48 functions ...\n");
+    test_ret += test_xmlAllocOutputBuffer();
+    test_ret += test_xmlAllocParserInputBuffer();
+    test_ret += test_xmlCheckFilename();
+    test_ret += test_xmlCheckHTTPInput();
+    test_ret += test_xmlCleanupInputCallbacks();
+    test_ret += test_xmlCleanupOutputCallbacks();
+    test_ret += test_xmlFileClose();
+    test_ret += test_xmlFileMatch();
+    test_ret += test_xmlFileOpen();
+    test_ret += test_xmlFileRead();
+    test_ret += test_xmlIOFTPClose();
+    test_ret += test_xmlIOFTPMatch();
+    test_ret += test_xmlIOFTPOpen();
+    test_ret += test_xmlIOFTPRead();
+    test_ret += test_xmlIOHTTPClose();
+    test_ret += test_xmlIOHTTPMatch();
+    test_ret += test_xmlIOHTTPOpen();
+    test_ret += test_xmlIOHTTPRead();
+    test_ret += test_xmlNoNetExternalEntityLoader();
+    test_ret += test_xmlNormalizeWindowsPath();
+    test_ret += test_xmlOutputBufferCreateBuffer();
+    test_ret += test_xmlOutputBufferCreateFd();
+    test_ret += test_xmlOutputBufferCreateFile();
+    test_ret += test_xmlOutputBufferCreateFilename();
+    test_ret += test_xmlOutputBufferFlush();
+    test_ret += test_xmlOutputBufferWrite();
+    test_ret += test_xmlOutputBufferWriteEscape();
+    test_ret += test_xmlOutputBufferWriteString();
+    test_ret += test_xmlParserGetDirectory();
+    test_ret += test_xmlParserInputBufferCreateFd();
+    test_ret += test_xmlParserInputBufferCreateFile();
+    test_ret += test_xmlParserInputBufferCreateFilename();
+    test_ret += test_xmlParserInputBufferCreateMem();
+    test_ret += test_xmlParserInputBufferCreateStatic();
+    test_ret += test_xmlParserInputBufferGrow();
+    test_ret += test_xmlParserInputBufferPush();
+    test_ret += test_xmlParserInputBufferRead();
+    test_ret += test_xmlPopInputCallbacks();
+    test_ret += test_xmlRegisterDefaultInputCallbacks();
+    test_ret += test_xmlRegisterDefaultOutputCallbacks();
+    test_ret += test_xmlRegisterHTTPPostCallbacks();
+
+    if (test_ret != 0)
+	printf("Module xmlIO: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_AUTOMATA_ENABLED
+
+#define gen_nb_xmlAutomataPtr 1
+static xmlAutomataPtr gen_xmlAutomataPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlAutomataPtr(int no ATTRIBUTE_UNUSED, xmlAutomataPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlAutomataCompile(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataGetInitState(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataIsDeterminist(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlAutomataPtr am; /* an automata */
+    int n_am;
+
+    for (n_am = 0;n_am < gen_nb_xmlAutomataPtr;n_am++) {
+        mem_base = xmlMemBlocks();
+        am = gen_xmlAutomataPtr(n_am, 0);
+
+        ret_val = xmlAutomataIsDeterminist(am);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlAutomataPtr(n_am, am, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAutomataIsDeterminist",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_am);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_AUTOMATA_ENABLED
+
+#define gen_nb_xmlAutomataStatePtr 1
+static xmlAutomataStatePtr gen_xmlAutomataStatePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlAutomataStatePtr(int no ATTRIBUTE_UNUSED, xmlAutomataStatePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlAutomataNewAllTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewCountTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewCountTrans2(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewCountedTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewCounter(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlAutomataPtr am; /* an automata */
+    int n_am;
+    int min; /* the minimal value on the counter */
+    int n_min;
+    int max; /* the maximal value on the counter */
+    int n_max;
+
+    for (n_am = 0;n_am < gen_nb_xmlAutomataPtr;n_am++) {
+    for (n_min = 0;n_min < gen_nb_int;n_min++) {
+    for (n_max = 0;n_max < gen_nb_int;n_max++) {
+        mem_base = xmlMemBlocks();
+        am = gen_xmlAutomataPtr(n_am, 0);
+        min = gen_int(n_min, 1);
+        max = gen_int(n_max, 2);
+
+        ret_val = xmlAutomataNewCounter(am, min, max);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlAutomataPtr(n_am, am, 0);
+        des_int(n_min, min, 1);
+        des_int(n_max, max, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAutomataNewCounter",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_am);
+            printf(" %d", n_min);
+            printf(" %d", n_max);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewCounterTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewEpsilon(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewNegTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewOnceTrans(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewOnceTrans2(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewState(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewTransition(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataNewTransition2(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlAutomataSetFinalState(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_AUTOMATA_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlAutomataPtr am; /* an automata */
+    int n_am;
+    xmlAutomataStatePtr state; /* a state in this automata */
+    int n_state;
+
+    for (n_am = 0;n_am < gen_nb_xmlAutomataPtr;n_am++) {
+    for (n_state = 0;n_state < gen_nb_xmlAutomataStatePtr;n_state++) {
+        mem_base = xmlMemBlocks();
+        am = gen_xmlAutomataPtr(n_am, 0);
+        state = gen_xmlAutomataStatePtr(n_state, 1);
+
+        ret_val = xmlAutomataSetFinalState(am, state);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlAutomataPtr(n_am, am, 0);
+        des_xmlAutomataStatePtr(n_state, state, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlAutomataSetFinalState",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_am);
+            printf(" %d", n_state);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewAutomata(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_xmlautomata(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlautomata : 3 of 19 functions ...\n");
+    test_ret += test_xmlAutomataCompile();
+    test_ret += test_xmlAutomataGetInitState();
+    test_ret += test_xmlAutomataIsDeterminist();
+    test_ret += test_xmlAutomataNewAllTrans();
+    test_ret += test_xmlAutomataNewCountTrans();
+    test_ret += test_xmlAutomataNewCountTrans2();
+    test_ret += test_xmlAutomataNewCountedTrans();
+    test_ret += test_xmlAutomataNewCounter();
+    test_ret += test_xmlAutomataNewCounterTrans();
+    test_ret += test_xmlAutomataNewEpsilon();
+    test_ret += test_xmlAutomataNewNegTrans();
+    test_ret += test_xmlAutomataNewOnceTrans();
+    test_ret += test_xmlAutomataNewOnceTrans2();
+    test_ret += test_xmlAutomataNewState();
+    test_ret += test_xmlAutomataNewTransition();
+    test_ret += test_xmlAutomataNewTransition2();
+    test_ret += test_xmlAutomataSetFinalState();
+    test_ret += test_xmlNewAutomata();
+
+    if (test_ret != 0)
+	printf("Module xmlautomata: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+#define gen_nb_xmlGenericErrorFunc_ptr 1
+static xmlGenericErrorFunc * gen_xmlGenericErrorFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlGenericErrorFunc_ptr(int no ATTRIBUTE_UNUSED, xmlGenericErrorFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_initGenericErrorDefaultFunc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlGenericErrorFunc * handler; /* the handler */
+    int n_handler;
+
+    for (n_handler = 0;n_handler < gen_nb_xmlGenericErrorFunc_ptr;n_handler++) {
+        mem_base = xmlMemBlocks();
+        handler = gen_xmlGenericErrorFunc_ptr(n_handler, 0);
+
+        initGenericErrorDefaultFunc(handler);
+        call_tests++;
+        des_xmlGenericErrorFunc_ptr(n_handler, handler, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in initGenericErrorDefaultFunc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_handler);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+#define gen_nb_xmlErrorPtr 1
+static xmlErrorPtr gen_xmlErrorPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlErrorPtr(int no ATTRIBUTE_UNUSED, xmlErrorPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+
+static int
+test_xmlCopyError(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlErrorPtr from; /* a source error */
+    int n_from;
+    xmlErrorPtr to; /* a target error */
+    int n_to;
+
+    for (n_from = 0;n_from < gen_nb_xmlErrorPtr;n_from++) {
+    for (n_to = 0;n_to < gen_nb_xmlErrorPtr;n_to++) {
+        mem_base = xmlMemBlocks();
+        from = gen_xmlErrorPtr(n_from, 0);
+        to = gen_xmlErrorPtr(n_to, 1);
+
+        ret_val = xmlCopyError(from, to);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlErrorPtr(n_from, from, 0);
+        des_xmlErrorPtr(n_to, to, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCopyError",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_from);
+            printf(" %d", n_to);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtGetLastError(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlCtxtResetLastError(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    void * ctx; /* an XML parser context */
+    int n_ctx;
+
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctx = gen_void_ptr(n_ctx, 0);
+
+        xmlCtxtResetLastError(ctx);
+        call_tests++;
+        des_void_ptr(n_ctx, ctx, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCtxtResetLastError",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetLastError(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserError(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserPrintFileContext(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr input; /* an xmlParserInputPtr input */
+    int n_input;
+
+    for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+        mem_base = xmlMemBlocks();
+        input = gen_xmlParserInputPtr(n_input, 0);
+
+        xmlParserPrintFileContext(input);
+        call_tests++;
+        des_xmlParserInputPtr(n_input, input, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserPrintFileContext",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_input);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserPrintFileInfo(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserInputPtr input; /* an xmlParserInputPtr input */
+    int n_input;
+
+    for (n_input = 0;n_input < gen_nb_xmlParserInputPtr;n_input++) {
+        mem_base = xmlMemBlocks();
+        input = gen_xmlParserInputPtr(n_input, 0);
+
+        xmlParserPrintFileInfo(input);
+        call_tests++;
+        des_xmlParserInputPtr(n_input, input, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlParserPrintFileInfo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_input);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserValidityError(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserValidityWarning(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlParserWarning(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlResetError(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlErrorPtr err; /* pointer to the error. */
+    int n_err;
+
+    for (n_err = 0;n_err < gen_nb_xmlErrorPtr;n_err++) {
+        mem_base = xmlMemBlocks();
+        err = gen_xmlErrorPtr(n_err, 0);
+
+        xmlResetError(err);
+        call_tests++;
+        des_xmlErrorPtr(n_err, err, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlResetError",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_err);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlResetLastError(void) {
+    int test_ret = 0;
+
+
+
+        xmlResetLastError();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetGenericErrorFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSetStructuredErrorFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_xmlerror(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlerror : 7 of 15 functions ...\n");
+    test_ret += test_initGenericErrorDefaultFunc();
+    test_ret += test_xmlCopyError();
+    test_ret += test_xmlCtxtGetLastError();
+    test_ret += test_xmlCtxtResetLastError();
+    test_ret += test_xmlGetLastError();
+    test_ret += test_xmlParserError();
+    test_ret += test_xmlParserPrintFileContext();
+    test_ret += test_xmlParserPrintFileInfo();
+    test_ret += test_xmlParserValidityError();
+    test_ret += test_xmlParserValidityWarning();
+    test_ret += test_xmlParserWarning();
+    test_ret += test_xmlResetError();
+    test_ret += test_xmlResetLastError();
+    test_ret += test_xmlSetGenericErrorFunc();
+    test_ret += test_xmlSetStructuredErrorFunc();
+
+    if (test_ret != 0)
+	printf("Module xmlerror: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_MODULES_ENABLED
+
+#define gen_nb_xmlModulePtr 1
+static xmlModulePtr gen_xmlModulePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlModulePtr(int no ATTRIBUTE_UNUSED, xmlModulePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlModuleClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_MODULES_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlModulePtr module; /* the module handle */
+    int n_module;
+
+    for (n_module = 0;n_module < gen_nb_xmlModulePtr;n_module++) {
+        mem_base = xmlMemBlocks();
+        module = gen_xmlModulePtr(n_module, 0);
+
+        ret_val = xmlModuleClose(module);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlModulePtr(n_module, module, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlModuleClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_module);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlModuleOpen(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlModuleSymbol(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_MODULES_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlModulePtr module; /* the module */
+    int n_module;
+    char * name; /* the name of the symbol */
+    int n_name;
+    void ** symbol; /* the resulting symbol address */
+    int n_symbol;
+
+    for (n_module = 0;n_module < gen_nb_xmlModulePtr;n_module++) {
+    for (n_name = 0;n_name < gen_nb_const_char_ptr;n_name++) {
+    for (n_symbol = 0;n_symbol < gen_nb_void_ptr_ptr;n_symbol++) {
+        mem_base = xmlMemBlocks();
+        module = gen_xmlModulePtr(n_module, 0);
+        name = gen_const_char_ptr(n_name, 1);
+        symbol = gen_void_ptr_ptr(n_symbol, 2);
+
+        ret_val = xmlModuleSymbol(module, (const char *)name, symbol);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlModulePtr(n_module, module, 0);
+        des_const_char_ptr(n_name, (const char *)name, 1);
+        des_void_ptr_ptr(n_symbol, symbol, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlModuleSymbol",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_module);
+            printf(" %d", n_name);
+            printf(" %d", n_symbol);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlmodule(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlmodule : 2 of 4 functions ...\n");
+    test_ret += test_xmlModuleClose();
+    test_ret += test_xmlModuleOpen();
+    test_ret += test_xmlModuleSymbol();
+
+    if (test_ret != 0)
+	printf("Module xmlmodule: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlNewTextReader(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    xmlParserInputBufferPtr input; /* the xmlParserInputBufferPtr used to read data */
+    int n_input;
+    const char * URI; /* the URI information for the source if available */
+    int n_URI;
+
+    for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+    for (n_URI = 0;n_URI < gen_nb_filepath;n_URI++) {
+        mem_base = xmlMemBlocks();
+        input = gen_xmlParserInputBufferPtr(n_input, 0);
+        URI = gen_filepath(n_URI, 1);
+
+        ret_val = xmlNewTextReader(input, URI);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_xmlParserInputBufferPtr(n_input, input, 0);
+        des_filepath(n_URI, URI, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextReader",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_input);
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextReaderFilename(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    const char * URI; /* the URI of the resource to process */
+    int n_URI;
+
+    for (n_URI = 0;n_URI < gen_nb_filepath;n_URI++) {
+        mem_base = xmlMemBlocks();
+        URI = gen_filepath(n_URI, 0);
+
+        ret_val = xmlNewTextReaderFilename(URI);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_filepath(n_URI, URI, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextReaderFilename",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URI);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderForDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+        URL = gen_filepath(n_URL, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_parseroptions(n_options, 3);
+
+        ret_val = xmlReaderForDoc((const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        des_filepath(n_URL, URL, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_parseroptions(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderForDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderForFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        filename = gen_filepath(n_filename, 0);
+        encoding = gen_const_char_ptr(n_encoding, 1);
+        options = gen_parseroptions(n_options, 2);
+
+        ret_val = xmlReaderForFile(filename, (const char *)encoding, options);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_filepath(n_filename, filename, 0);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 1);
+        des_parseroptions(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderForFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderForMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_parseroptions(n_options, 4);
+
+        ret_val = xmlReaderForMemory((const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_parseroptions(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderForMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderNewDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+    xmlChar * cur; /* a pointer to a zero terminated string */
+    int n_cur;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_parseroptions(n_options, 4);
+
+        ret_val = xmlReaderNewDoc(reader, (const xmlChar *)cur, URL, (const char *)encoding, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_parseroptions(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderNewDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_cur);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderNewFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+    const char * filename; /* a file or URL */
+    int n_filename;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        filename = gen_filepath(n_filename, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        options = gen_parseroptions(n_options, 3);
+
+        ret_val = xmlReaderNewFile(reader, filename, (const char *)encoding, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_filepath(n_filename, filename, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_parseroptions(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderNewFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_filename);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderNewMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+    char * buffer; /* a pointer to a char array */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        buffer = gen_const_char_ptr(n_buffer, 1);
+        size = gen_int(n_size, 2);
+        URL = gen_filepath(n_URL, 3);
+        encoding = gen_const_char_ptr(n_encoding, 4);
+        options = gen_parseroptions(n_options, 5);
+
+        ret_val = xmlReaderNewMemory(reader, (const char *)buffer, size, URL, (const char *)encoding, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_char_ptr(n_buffer, (const char *)buffer, 1);
+        des_int(n_size, size, 2);
+        des_filepath(n_URL, URL, 3);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 4);
+        des_parseroptions(n_options, options, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderNewMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderNewWalker(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+    xmlDocPtr doc; /* a preparsed document */
+    int n_doc;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlReaderNewWalker(reader, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderNewWalker",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlReaderWalker(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr ret_val;
+    xmlDocPtr doc; /* a preparsed document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlReaderWalker(doc);
+        desret_xmlTextReaderPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlReaderWalker",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderAttributeCount(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderAttributeCount(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderAttributeCount",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderBaseUri(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderBaseUri(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderBaseUri",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderByteConsumed(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    long ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderByteConsumed(reader);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderByteConsumed",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderClose(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstBaseUri(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstBaseUri(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstBaseUri",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstEncoding(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstEncoding(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstEncoding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstLocalName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstLocalName(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstLocalName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstName(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstNamespaceUri(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstNamespaceUri(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstNamespaceUri",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstPrefix(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstPrefix(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstPrefix",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * str; /* the string to intern. */
+    int n_str;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+
+        ret_val = xmlTextReaderConstString(reader, (const xmlChar *)str);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstValue(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstXmlLang(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstXmlLang(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstXmlLang",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderConstXmlVersion(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderConstXmlVersion(reader);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderConstXmlVersion",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderCurrentDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlDocPtr ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderCurrentDoc(reader);
+        desret_xmlDocPtr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderCurrentDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderCurrentNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderCurrentNode(reader);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderCurrentNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderDepth(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderDepth(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderDepth",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderExpand(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderExpand(reader);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderExpand",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * name; /* the qualified name of the attribute. */
+    int n_name;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextReaderGetAttribute(reader, (const xmlChar *)name);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetAttributeNo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    int no; /* the zero-based index of the attribute relative to the containing element */
+    int n_no;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_no = 0;n_no < gen_nb_int;n_no++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        no = gen_int(n_no, 1);
+
+        ret_val = xmlTextReaderGetAttributeNo(reader, no);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_int(n_no, no, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetAttributeNo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_no);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetAttributeNs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * localName; /* the local name of the attribute. */
+    int n_localName;
+    xmlChar * namespaceURI; /* the namespace URI of the attribute. */
+    int n_namespaceURI;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_localName = 0;n_localName < gen_nb_const_xmlChar_ptr;n_localName++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        localName = gen_const_xmlChar_ptr(n_localName, 1);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 2);
+
+        ret_val = xmlTextReaderGetAttributeNs(reader, (const xmlChar *)localName, (const xmlChar *)namespaceURI);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_localName, (const xmlChar *)localName, 1);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetAttributeNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_localName);
+            printf(" %d", n_namespaceURI);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_READER_ENABLED
+
+#define gen_nb_xmlTextReaderErrorFunc_ptr 1
+static xmlTextReaderErrorFunc * gen_xmlTextReaderErrorFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlTextReaderErrorFunc_ptr(int no ATTRIBUTE_UNUSED, xmlTextReaderErrorFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlTextReaderGetErrorHandler(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlTextReaderErrorFunc * f; /* the callback function or NULL is no callback has been registered */
+    int n_f;
+    void ** arg; /* a user argument */
+    int n_arg;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_f = 0;n_f < gen_nb_xmlTextReaderErrorFunc_ptr;n_f++) {
+    for (n_arg = 0;n_arg < gen_nb_void_ptr_ptr;n_arg++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        f = gen_xmlTextReaderErrorFunc_ptr(n_f, 1);
+        arg = gen_void_ptr_ptr(n_arg, 2);
+
+        xmlTextReaderGetErrorHandler(reader, f, arg);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_xmlTextReaderErrorFunc_ptr(n_f, f, 1);
+        des_void_ptr_ptr(n_arg, arg, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetErrorHandler",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_f);
+            printf(" %d", n_arg);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetParserColumnNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the user data (XML reader context) */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderGetParserColumnNumber(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetParserColumnNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetParserLineNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the user data (XML reader context) */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderGetParserLineNumber(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetParserLineNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetParserProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    int prop; /* the xmlParserProperties to get */
+    int n_prop;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_prop = 0;n_prop < gen_nb_int;n_prop++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        prop = gen_int(n_prop, 1);
+
+        ret_val = xmlTextReaderGetParserProp(reader, prop);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_int(n_prop, prop, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetParserProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_prop);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderGetRemainder(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlParserInputBufferPtr ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderGetRemainder(reader);
+        desret_xmlParserInputBufferPtr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderGetRemainder",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderHasAttributes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderHasAttributes(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderHasAttributes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderHasValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderHasValue(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderHasValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderIsDefault(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderIsDefault(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderIsDefault",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderIsEmptyElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderIsEmptyElement(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderIsEmptyElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderIsNamespaceDecl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderIsNamespaceDecl(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderIsNamespaceDecl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderIsValid(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderIsValid(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderIsValid",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderLocalName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderLocalName(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderLocalName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_READER_ENABLED
+
+#define gen_nb_xmlTextReaderLocatorPtr 1
+static xmlTextReaderLocatorPtr gen_xmlTextReaderLocatorPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlTextReaderLocatorPtr(int no ATTRIBUTE_UNUSED, xmlTextReaderLocatorPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlTextReaderLocatorBaseURI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderLocatorPtr locator; /* the xmlTextReaderLocatorPtr used */
+    int n_locator;
+
+    for (n_locator = 0;n_locator < gen_nb_xmlTextReaderLocatorPtr;n_locator++) {
+        mem_base = xmlMemBlocks();
+        locator = gen_xmlTextReaderLocatorPtr(n_locator, 0);
+
+        ret_val = xmlTextReaderLocatorBaseURI(locator);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderLocatorPtr(n_locator, locator, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderLocatorBaseURI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_locator);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderLocatorLineNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderLocatorPtr locator; /* the xmlTextReaderLocatorPtr used */
+    int n_locator;
+
+    for (n_locator = 0;n_locator < gen_nb_xmlTextReaderLocatorPtr;n_locator++) {
+        mem_base = xmlMemBlocks();
+        locator = gen_xmlTextReaderLocatorPtr(n_locator, 0);
+
+        ret_val = xmlTextReaderLocatorLineNumber(locator);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderLocatorPtr(n_locator, locator, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderLocatorLineNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_locator);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderLookupNamespace(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * prefix; /* the prefix whose namespace URI is to be resolved. To return the default namespace, specify NULL */
+    int n_prefix;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+
+        ret_val = xmlTextReaderLookupNamespace(reader, (const xmlChar *)prefix);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderLookupNamespace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * name; /* the qualified name of the attribute. */
+    int n_name;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToAttributeNo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    int no; /* the zero-based index of the attribute relative to the containing element. */
+    int n_no;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_no = 0;n_no < gen_nb_int;n_no++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        no = gen_int(n_no, 1);
+
+        ret_val = xmlTextReaderMoveToAttributeNo(reader, no);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_int(n_no, no, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToAttributeNo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_no);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToAttributeNs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * localName; /* the local name of the attribute. */
+    int n_localName;
+    xmlChar * namespaceURI; /* the namespace URI of the attribute. */
+    int n_namespaceURI;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_localName = 0;n_localName < gen_nb_const_xmlChar_ptr;n_localName++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        localName = gen_const_xmlChar_ptr(n_localName, 1);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 2);
+
+        ret_val = xmlTextReaderMoveToAttributeNs(reader, (const xmlChar *)localName, (const xmlChar *)namespaceURI);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_localName, (const xmlChar *)localName, 1);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToAttributeNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_localName);
+            printf(" %d", n_namespaceURI);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderMoveToElement(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToFirstAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderMoveToFirstAttribute(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToFirstAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderMoveToNextAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderMoveToNextAttribute(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderMoveToNextAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderName(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderNamespaceUri(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderNamespaceUri(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderNamespaceUri",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderNext(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderNext(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderNext",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderNextSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderNextSibling(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderNextSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderNodeType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderNodeType(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderNodeType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderNormalization(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderNormalization(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderNormalization",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderPrefix(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderPrefix(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderPrefix",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderPreserve(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderPreserve(reader);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderPreserve",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderPreservePattern(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
+#ifdef LIBXML_PATTERN_ENABLED
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlChar * pattern; /* an XPath subset pattern */
+    int n_pattern;
+    xmlChar ** namespaces; /* the prefix definitions, array of [URI, prefix] or NULL */
+    int n_namespaces;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_pattern = 0;n_pattern < gen_nb_const_xmlChar_ptr;n_pattern++) {
+    for (n_namespaces = 0;n_namespaces < gen_nb_const_xmlChar_ptr_ptr;n_namespaces++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        pattern = gen_const_xmlChar_ptr(n_pattern, 1);
+        namespaces = gen_const_xmlChar_ptr_ptr(n_namespaces, 2);
+
+        ret_val = xmlTextReaderPreservePattern(reader, (const xmlChar *)pattern, (const xmlChar **)namespaces);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_xmlChar_ptr(n_pattern, (const xmlChar *)pattern, 1);
+        des_const_xmlChar_ptr_ptr(n_namespaces, (const xmlChar **)namespaces, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderPreservePattern",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_pattern);
+            printf(" %d", n_namespaces);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderQuoteChar(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderQuoteChar(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderQuoteChar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderRead(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderRead(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderRead",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderReadAttributeValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderReadAttributeValue(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderReadAttributeValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderReadState(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderReadState(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderReadState",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderRelaxNGSetSchema(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlRelaxNGPtr schema; /* a precompiled RelaxNG schema */
+    int n_schema;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_schema = 0;n_schema < gen_nb_xmlRelaxNGPtr;n_schema++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        schema = gen_xmlRelaxNGPtr(n_schema, 1);
+
+        ret_val = xmlTextReaderRelaxNGSetSchema(reader, schema);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_xmlRelaxNGPtr(n_schema, schema, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderRelaxNGSetSchema",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_schema);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderRelaxNGValidate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    char * rng; /* the path to a RelaxNG schema or NULL */
+    int n_rng;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_rng = 0;n_rng < gen_nb_const_char_ptr;n_rng++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        rng = gen_const_char_ptr(n_rng, 1);
+
+        ret_val = xmlTextReaderRelaxNGValidate(reader, (const char *)rng);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_char_ptr(n_rng, (const char *)rng, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderRelaxNGValidate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_rng);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSchemaValidate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    char * xsd; /* the path to a W3C XSD schema or NULL */
+    int n_xsd;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_xsd = 0;n_xsd < gen_nb_const_char_ptr;n_xsd++) {
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        xsd = gen_const_char_ptr(n_xsd, 1);
+
+        ret_val = xmlTextReaderSchemaValidate(reader, (const char *)xsd);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_const_char_ptr(n_xsd, (const char *)xsd, 1);
+        xmlResetLastError();
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSchemaValidateCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlSchemaValidCtxtPtr ctxt; /* the XML Schema validation context or NULL */
+    int n_ctxt;
+    int options; /* options (not used yet) */
+    int n_options;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 1);
+        options = gen_parseroptions(n_options, 2);
+
+        ret_val = xmlTextReaderSchemaValidateCtxt(reader, ctxt, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 1);
+        des_parseroptions(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderSchemaValidateCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_ctxt);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSetErrorHandler(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSetParserProp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    int prop; /* the xmlParserProperties to set */
+    int n_prop;
+    int value; /* usually 0 or 1 to (de)activate it */
+    int n_value;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_prop = 0;n_prop < gen_nb_int;n_prop++) {
+    for (n_value = 0;n_value < gen_nb_int;n_value++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        prop = gen_int(n_prop, 1);
+        value = gen_int(n_value, 2);
+
+        ret_val = xmlTextReaderSetParserProp(reader, prop, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_int(n_prop, prop, 1);
+        des_int(n_value, value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderSetParserProp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_prop);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSetSchema(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+    xmlSchemaPtr schema; /* a precompiled Schema schema */
+    int n_schema;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_schema = 0;n_schema < gen_nb_xmlSchemaPtr;n_schema++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        schema = gen_xmlSchemaPtr(n_schema, 1);
+
+        ret_val = xmlTextReaderSetSchema(reader, schema);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_xmlSchemaPtr(n_schema, schema, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderSetSchema",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_schema);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSetStructuredErrorHandler(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderSetup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* an XML reader */
+    int n_reader;
+    xmlParserInputBufferPtr input; /* xmlParserInputBufferPtr used to feed the reader, will be destroyed with it. */
+    int n_input;
+    const char * URL; /* the base URL to use for the document */
+    int n_URL;
+    char * encoding; /* the document encoding, or NULL */
+    int n_encoding;
+    int options; /* a combination of xmlParserOption */
+    int n_options;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+    for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+        input = gen_xmlParserInputBufferPtr(n_input, 1);
+        URL = gen_filepath(n_URL, 2);
+        encoding = gen_const_char_ptr(n_encoding, 3);
+        options = gen_parseroptions(n_options, 4);
+
+        ret_val = xmlTextReaderSetup(reader, input, URL, (const char *)encoding, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        des_filepath(n_URL, URL, 2);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 3);
+        des_parseroptions(n_options, options, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderSetup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf(" %d", n_input);
+            printf(" %d", n_URL);
+            printf(" %d", n_encoding);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderStandalone(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderStandalone(reader);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderStandalone",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderValue(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextReaderXmlLang(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_READER_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlTextReaderPtr reader; /* the xmlTextReaderPtr used */
+    int n_reader;
+
+    for (n_reader = 0;n_reader < gen_nb_xmlTextReaderPtr;n_reader++) {
+        mem_base = xmlMemBlocks();
+        reader = gen_xmlTextReaderPtr(n_reader, 0);
+
+        ret_val = xmlTextReaderXmlLang(reader);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlTextReaderPtr(n_reader, reader, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextReaderXmlLang",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_reader);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlreader(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlreader : 75 of 85 functions ...\n");
+    test_ret += test_xmlNewTextReader();
+    test_ret += test_xmlNewTextReaderFilename();
+    test_ret += test_xmlReaderForDoc();
+    test_ret += test_xmlReaderForFile();
+    test_ret += test_xmlReaderForMemory();
+    test_ret += test_xmlReaderNewDoc();
+    test_ret += test_xmlReaderNewFile();
+    test_ret += test_xmlReaderNewMemory();
+    test_ret += test_xmlReaderNewWalker();
+    test_ret += test_xmlReaderWalker();
+    test_ret += test_xmlTextReaderAttributeCount();
+    test_ret += test_xmlTextReaderBaseUri();
+    test_ret += test_xmlTextReaderByteConsumed();
+    test_ret += test_xmlTextReaderClose();
+    test_ret += test_xmlTextReaderConstBaseUri();
+    test_ret += test_xmlTextReaderConstEncoding();
+    test_ret += test_xmlTextReaderConstLocalName();
+    test_ret += test_xmlTextReaderConstName();
+    test_ret += test_xmlTextReaderConstNamespaceUri();
+    test_ret += test_xmlTextReaderConstPrefix();
+    test_ret += test_xmlTextReaderConstString();
+    test_ret += test_xmlTextReaderConstValue();
+    test_ret += test_xmlTextReaderConstXmlLang();
+    test_ret += test_xmlTextReaderConstXmlVersion();
+    test_ret += test_xmlTextReaderCurrentDoc();
+    test_ret += test_xmlTextReaderCurrentNode();
+    test_ret += test_xmlTextReaderDepth();
+    test_ret += test_xmlTextReaderExpand();
+    test_ret += test_xmlTextReaderGetAttribute();
+    test_ret += test_xmlTextReaderGetAttributeNo();
+    test_ret += test_xmlTextReaderGetAttributeNs();
+    test_ret += test_xmlTextReaderGetErrorHandler();
+    test_ret += test_xmlTextReaderGetParserColumnNumber();
+    test_ret += test_xmlTextReaderGetParserLineNumber();
+    test_ret += test_xmlTextReaderGetParserProp();
+    test_ret += test_xmlTextReaderGetRemainder();
+    test_ret += test_xmlTextReaderHasAttributes();
+    test_ret += test_xmlTextReaderHasValue();
+    test_ret += test_xmlTextReaderIsDefault();
+    test_ret += test_xmlTextReaderIsEmptyElement();
+    test_ret += test_xmlTextReaderIsNamespaceDecl();
+    test_ret += test_xmlTextReaderIsValid();
+    test_ret += test_xmlTextReaderLocalName();
+    test_ret += test_xmlTextReaderLocatorBaseURI();
+    test_ret += test_xmlTextReaderLocatorLineNumber();
+    test_ret += test_xmlTextReaderLookupNamespace();
+    test_ret += test_xmlTextReaderMoveToAttribute();
+    test_ret += test_xmlTextReaderMoveToAttributeNo();
+    test_ret += test_xmlTextReaderMoveToAttributeNs();
+    test_ret += test_xmlTextReaderMoveToElement();
+    test_ret += test_xmlTextReaderMoveToFirstAttribute();
+    test_ret += test_xmlTextReaderMoveToNextAttribute();
+    test_ret += test_xmlTextReaderName();
+    test_ret += test_xmlTextReaderNamespaceUri();
+    test_ret += test_xmlTextReaderNext();
+    test_ret += test_xmlTextReaderNextSibling();
+    test_ret += test_xmlTextReaderNodeType();
+    test_ret += test_xmlTextReaderNormalization();
+    test_ret += test_xmlTextReaderPrefix();
+    test_ret += test_xmlTextReaderPreserve();
+    test_ret += test_xmlTextReaderPreservePattern();
+    test_ret += test_xmlTextReaderQuoteChar();
+    test_ret += test_xmlTextReaderRead();
+    test_ret += test_xmlTextReaderReadAttributeValue();
+    test_ret += test_xmlTextReaderReadState();
+    test_ret += test_xmlTextReaderRelaxNGSetSchema();
+    test_ret += test_xmlTextReaderRelaxNGValidate();
+    test_ret += test_xmlTextReaderSchemaValidate();
+    test_ret += test_xmlTextReaderSchemaValidateCtxt();
+    test_ret += test_xmlTextReaderSetErrorHandler();
+    test_ret += test_xmlTextReaderSetParserProp();
+    test_ret += test_xmlTextReaderSetSchema();
+    test_ret += test_xmlTextReaderSetStructuredErrorHandler();
+    test_ret += test_xmlTextReaderSetup();
+    test_ret += test_xmlTextReaderStandalone();
+    test_ret += test_xmlTextReaderValue();
+    test_ret += test_xmlTextReaderXmlLang();
+
+    if (test_ret != 0)
+	printf("Module xmlreader: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlExpCtxtNbCons(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpCtxtPtr ctxt; /* an expression context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlExpCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlExpCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlExpCtxtNbCons(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpCtxtNbCons",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpCtxtNbNodes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpCtxtPtr ctxt; /* an expression context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlExpCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlExpCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlExpCtxtNbNodes(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpCtxtNbNodes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    xmlBufferPtr buf; /* a buffer to receive the output */
+    int n_buf;
+    xmlExpNodePtr expr; /* the compiled expression */
+    int n_expr;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_expr = 0;n_expr < gen_nb_xmlExpNodePtr;n_expr++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        expr = gen_xmlExpNodePtr(n_expr, 1);
+
+        xmlExpDump(buf, expr);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_xmlExpNodePtr(n_expr, expr, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_expr);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpExpDerive(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpGetLanguage(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpCtxtPtr ctxt; /* the expression context */
+    int n_ctxt;
+    xmlExpNodePtr exp; /* the expression */
+    int n_exp;
+    xmlChar ** langList; /* where to store the tokens */
+    int n_langList;
+    int len; /* the allocated lenght of @list */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlExpCtxtPtr;n_ctxt++) {
+    for (n_exp = 0;n_exp < gen_nb_xmlExpNodePtr;n_exp++) {
+    for (n_langList = 0;n_langList < gen_nb_const_xmlChar_ptr_ptr;n_langList++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlExpCtxtPtr(n_ctxt, 0);
+        exp = gen_xmlExpNodePtr(n_exp, 1);
+        langList = gen_const_xmlChar_ptr_ptr(n_langList, 2);
+        len = gen_int(n_len, 3);
+
+        ret_val = xmlExpGetLanguage(ctxt, exp, (const xmlChar **)langList, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlExpNodePtr(n_exp, exp, 1);
+        des_const_xmlChar_ptr_ptr(n_langList, (const xmlChar **)langList, 2);
+        des_int(n_len, len, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpGetLanguage",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_exp);
+            printf(" %d", n_langList);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpGetStart(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpCtxtPtr ctxt; /* the expression context */
+    int n_ctxt;
+    xmlExpNodePtr exp; /* the expression */
+    int n_exp;
+    xmlChar ** tokList; /* where to store the tokens */
+    int n_tokList;
+    int len; /* the allocated lenght of @list */
+    int n_len;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlExpCtxtPtr;n_ctxt++) {
+    for (n_exp = 0;n_exp < gen_nb_xmlExpNodePtr;n_exp++) {
+    for (n_tokList = 0;n_tokList < gen_nb_const_xmlChar_ptr_ptr;n_tokList++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlExpCtxtPtr(n_ctxt, 0);
+        exp = gen_xmlExpNodePtr(n_exp, 1);
+        tokList = gen_const_xmlChar_ptr_ptr(n_tokList, 2);
+        len = gen_int(n_len, 3);
+
+        ret_val = xmlExpGetStart(ctxt, exp, (const xmlChar **)tokList, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlExpNodePtr(n_exp, exp, 1);
+        des_const_xmlChar_ptr_ptr(n_tokList, (const xmlChar **)tokList, 2);
+        des_int(n_len, len, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpGetStart",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_exp);
+            printf(" %d", n_tokList);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpIsNillable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpNodePtr exp; /* the expression */
+    int n_exp;
+
+    for (n_exp = 0;n_exp < gen_nb_xmlExpNodePtr;n_exp++) {
+        mem_base = xmlMemBlocks();
+        exp = gen_xmlExpNodePtr(n_exp, 0);
+
+        ret_val = xmlExpIsNillable(exp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpNodePtr(n_exp, exp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpIsNillable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpMaxToken(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpNodePtr expr; /* a compiled expression */
+    int n_expr;
+
+    for (n_expr = 0;n_expr < gen_nb_xmlExpNodePtr;n_expr++) {
+        mem_base = xmlMemBlocks();
+        expr = gen_xmlExpNodePtr(n_expr, 0);
+
+        ret_val = xmlExpMaxToken(expr);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpNodePtr(n_expr, expr, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpMaxToken",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_expr);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpNewAtom(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpNewCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpNewOr(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpNewRange(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpNewSeq(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpParse(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpRef(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    xmlExpNodePtr exp; /* the expression */
+    int n_exp;
+
+    for (n_exp = 0;n_exp < gen_nb_xmlExpNodePtr;n_exp++) {
+        mem_base = xmlMemBlocks();
+        exp = gen_xmlExpNodePtr(n_exp, 0);
+
+        xmlExpRef(exp);
+        call_tests++;
+        des_xmlExpNodePtr(n_exp, exp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpRef",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpStringDerive(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlExpSubsume(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED) && defined(LIBXML_EXPR_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlExpCtxtPtr ctxt; /* the expressions context */
+    int n_ctxt;
+    xmlExpNodePtr exp; /* the englobing expression */
+    int n_exp;
+    xmlExpNodePtr sub; /* the subexpression */
+    int n_sub;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlExpCtxtPtr;n_ctxt++) {
+    for (n_exp = 0;n_exp < gen_nb_xmlExpNodePtr;n_exp++) {
+    for (n_sub = 0;n_sub < gen_nb_xmlExpNodePtr;n_sub++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlExpCtxtPtr(n_ctxt, 0);
+        exp = gen_xmlExpNodePtr(n_exp, 1);
+        sub = gen_xmlExpNodePtr(n_sub, 2);
+
+        ret_val = xmlExpSubsume(ctxt, exp, sub);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlExpCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlExpNodePtr(n_exp, exp, 1);
+        des_xmlExpNodePtr(n_sub, sub, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlExpSubsume",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_exp);
+            printf(" %d", n_sub);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#define gen_nb_xmlRegExecCtxtPtr 1
+static xmlRegExecCtxtPtr gen_xmlRegExecCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRegExecCtxtPtr(int no ATTRIBUTE_UNUSED, xmlRegExecCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlRegExecErrInfo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegExecCtxtPtr exec; /* a regexp execution context generating an error */
+    int n_exec;
+    xmlChar ** string; /* return value for the error string */
+    int n_string;
+    int * nbval; /* pointer to the number of accepted values IN/OUT */
+    int n_nbval;
+    int * nbneg; /* return number of negative transitions */
+    int n_nbneg;
+    xmlChar ** values; /* pointer to the array of acceptable values */
+    int n_values;
+    int * terminal; /* return value if this was a terminal state */
+    int n_terminal;
+
+    for (n_exec = 0;n_exec < gen_nb_xmlRegExecCtxtPtr;n_exec++) {
+    for (n_string = 0;n_string < gen_nb_const_xmlChar_ptr_ptr;n_string++) {
+    for (n_nbval = 0;n_nbval < gen_nb_int_ptr;n_nbval++) {
+    for (n_nbneg = 0;n_nbneg < gen_nb_int_ptr;n_nbneg++) {
+    for (n_values = 0;n_values < gen_nb_xmlChar_ptr_ptr;n_values++) {
+    for (n_terminal = 0;n_terminal < gen_nb_int_ptr;n_terminal++) {
+        mem_base = xmlMemBlocks();
+        exec = gen_xmlRegExecCtxtPtr(n_exec, 0);
+        string = gen_const_xmlChar_ptr_ptr(n_string, 1);
+        nbval = gen_int_ptr(n_nbval, 2);
+        nbneg = gen_int_ptr(n_nbneg, 3);
+        values = gen_xmlChar_ptr_ptr(n_values, 4);
+        terminal = gen_int_ptr(n_terminal, 5);
+
+        ret_val = xmlRegExecErrInfo(exec, (const xmlChar **)string, nbval, nbneg, values, terminal);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegExecCtxtPtr(n_exec, exec, 0);
+        des_const_xmlChar_ptr_ptr(n_string, (const xmlChar **)string, 1);
+        des_int_ptr(n_nbval, nbval, 2);
+        des_int_ptr(n_nbneg, nbneg, 3);
+        des_xmlChar_ptr_ptr(n_values, values, 4);
+        des_int_ptr(n_terminal, terminal, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegExecErrInfo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exec);
+            printf(" %d", n_string);
+            printf(" %d", n_nbval);
+            printf(" %d", n_nbneg);
+            printf(" %d", n_values);
+            printf(" %d", n_terminal);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegExecNextValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegExecCtxtPtr exec; /* a regexp execution context */
+    int n_exec;
+    int * nbval; /* pointer to the number of accepted values IN/OUT */
+    int n_nbval;
+    int * nbneg; /* return number of negative transitions */
+    int n_nbneg;
+    xmlChar ** values; /* pointer to the array of acceptable values */
+    int n_values;
+    int * terminal; /* return value if this was a terminal state */
+    int n_terminal;
+
+    for (n_exec = 0;n_exec < gen_nb_xmlRegExecCtxtPtr;n_exec++) {
+    for (n_nbval = 0;n_nbval < gen_nb_int_ptr;n_nbval++) {
+    for (n_nbneg = 0;n_nbneg < gen_nb_int_ptr;n_nbneg++) {
+    for (n_values = 0;n_values < gen_nb_xmlChar_ptr_ptr;n_values++) {
+    for (n_terminal = 0;n_terminal < gen_nb_int_ptr;n_terminal++) {
+        mem_base = xmlMemBlocks();
+        exec = gen_xmlRegExecCtxtPtr(n_exec, 0);
+        nbval = gen_int_ptr(n_nbval, 1);
+        nbneg = gen_int_ptr(n_nbneg, 2);
+        values = gen_xmlChar_ptr_ptr(n_values, 3);
+        terminal = gen_int_ptr(n_terminal, 4);
+
+        ret_val = xmlRegExecNextValues(exec, nbval, nbneg, values, terminal);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegExecCtxtPtr(n_exec, exec, 0);
+        des_int_ptr(n_nbval, nbval, 1);
+        des_int_ptr(n_nbneg, nbneg, 2);
+        des_xmlChar_ptr_ptr(n_values, values, 3);
+        des_int_ptr(n_terminal, terminal, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegExecNextValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exec);
+            printf(" %d", n_nbval);
+            printf(" %d", n_nbneg);
+            printf(" %d", n_values);
+            printf(" %d", n_terminal);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegExecPushString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegExecCtxtPtr exec; /* a regexp execution context or NULL to indicate the end */
+    int n_exec;
+    xmlChar * value; /* a string token input */
+    int n_value;
+    void * data; /* data associated to the token to reuse in callbacks */
+    int n_data;
+
+    for (n_exec = 0;n_exec < gen_nb_xmlRegExecCtxtPtr;n_exec++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        exec = gen_xmlRegExecCtxtPtr(n_exec, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        data = gen_userdata(n_data, 2);
+
+        ret_val = xmlRegExecPushString(exec, (const xmlChar *)value, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegExecCtxtPtr(n_exec, exec, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_userdata(n_data, data, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegExecPushString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exec);
+            printf(" %d", n_value);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegExecPushString2(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegExecCtxtPtr exec; /* a regexp execution context or NULL to indicate the end */
+    int n_exec;
+    xmlChar * value; /* the first string token input */
+    int n_value;
+    xmlChar * value2; /* the second string token input */
+    int n_value2;
+    void * data; /* data associated to the token to reuse in callbacks */
+    int n_data;
+
+    for (n_exec = 0;n_exec < gen_nb_xmlRegExecCtxtPtr;n_exec++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_value2 = 0;n_value2 < gen_nb_const_xmlChar_ptr;n_value2++) {
+    for (n_data = 0;n_data < gen_nb_userdata;n_data++) {
+        mem_base = xmlMemBlocks();
+        exec = gen_xmlRegExecCtxtPtr(n_exec, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        value2 = gen_const_xmlChar_ptr(n_value2, 2);
+        data = gen_userdata(n_data, 3);
+
+        ret_val = xmlRegExecPushString2(exec, (const xmlChar *)value, (const xmlChar *)value2, data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegExecCtxtPtr(n_exec, exec, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_const_xmlChar_ptr(n_value2, (const xmlChar *)value2, 2);
+        des_userdata(n_data, data, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegExecPushString2",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_exec);
+            printf(" %d", n_value);
+            printf(" %d", n_value2);
+            printf(" %d", n_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#define gen_nb_xmlRegexpPtr 1
+static xmlRegexpPtr gen_xmlRegexpPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlRegexpPtr(int no ATTRIBUTE_UNUSED, xmlRegexpPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlRegNewExecCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegexpCompile(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegexpExec(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegexpPtr comp; /* the compiled regular expression */
+    int n_comp;
+    xmlChar * content; /* the value to check against the regular expression */
+    int n_content;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlRegexpPtr;n_comp++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlRegexpPtr(n_comp, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlRegexpExec(comp, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegexpPtr(n_comp, comp, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegexpExec",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegexpIsDeterminist(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlRegexpPtr comp; /* the compiled regular expression */
+    int n_comp;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlRegexpPtr;n_comp++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlRegexpPtr(n_comp, 0);
+
+        ret_val = xmlRegexpIsDeterminist(comp);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlRegexpPtr(n_comp, comp, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegexpIsDeterminist",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlRegexpPrint(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_REGEXP_ENABLED)
+    int mem_base;
+    FILE * output; /* the file for the output debug */
+    int n_output;
+    xmlRegexpPtr regexp; /* the compiled regexp */
+    int n_regexp;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_regexp = 0;n_regexp < gen_nb_xmlRegexpPtr;n_regexp++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        regexp = gen_xmlRegexpPtr(n_regexp, 1);
+
+        xmlRegexpPrint(output, regexp);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlRegexpPtr(n_regexp, regexp, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlRegexpPrint",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_regexp);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlregexp(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlregexp : 16 of 30 functions ...\n");
+    test_ret += test_xmlExpCtxtNbCons();
+    test_ret += test_xmlExpCtxtNbNodes();
+    test_ret += test_xmlExpDump();
+    test_ret += test_xmlExpExpDerive();
+    test_ret += test_xmlExpGetLanguage();
+    test_ret += test_xmlExpGetStart();
+    test_ret += test_xmlExpIsNillable();
+    test_ret += test_xmlExpMaxToken();
+    test_ret += test_xmlExpNewAtom();
+    test_ret += test_xmlExpNewCtxt();
+    test_ret += test_xmlExpNewOr();
+    test_ret += test_xmlExpNewRange();
+    test_ret += test_xmlExpNewSeq();
+    test_ret += test_xmlExpParse();
+    test_ret += test_xmlExpRef();
+    test_ret += test_xmlExpStringDerive();
+    test_ret += test_xmlExpSubsume();
+    test_ret += test_xmlRegExecErrInfo();
+    test_ret += test_xmlRegExecNextValues();
+    test_ret += test_xmlRegExecPushString();
+    test_ret += test_xmlRegExecPushString2();
+    test_ret += test_xmlRegNewExecCtxt();
+    test_ret += test_xmlRegexpCompile();
+    test_ret += test_xmlRegexpExec();
+    test_ret += test_xmlRegexpIsDeterminist();
+    test_ret += test_xmlRegexpPrint();
+
+    if (test_ret != 0)
+	printf("Module xmlregexp: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_OUTPUT_ENABLED
+
+#define gen_nb_xmlSaveCtxtPtr 1
+static xmlSaveCtxtPtr gen_xmlSaveCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSaveCtxtPtr(int no ATTRIBUTE_UNUSED, xmlSaveCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSaveClose(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSaveCtxtPtr ctxt; /* a document saving context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSaveCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlSaveClose(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSaveCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveClose",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    long ret_val;
+    xmlSaveCtxtPtr ctxt; /* a document saving context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a document */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSaveCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlSaveDoc(ctxt, doc);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlSaveCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveFlush(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSaveCtxtPtr ctxt; /* a document saving context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSaveCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlSaveFlush(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSaveCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveFlush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveSetAttrEscape(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveSetEscape(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveToBuffer(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveToFd(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveToFilename(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSaveTree(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    long ret_val;
+    xmlSaveCtxtPtr ctxt; /* a document saving context */
+    int n_ctxt;
+    xmlNodePtr node; /* the top node of the subtree to save */
+    int n_node;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSaveCtxtPtr(n_ctxt, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlSaveTree(ctxt, node);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlSaveCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSaveTree",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlsave(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlsave : 4 of 10 functions ...\n");
+    test_ret += test_xmlSaveClose();
+    test_ret += test_xmlSaveDoc();
+    test_ret += test_xmlSaveFlush();
+    test_ret += test_xmlSaveSetAttrEscape();
+    test_ret += test_xmlSaveSetEscape();
+    test_ret += test_xmlSaveToBuffer();
+    test_ret += test_xmlSaveToFd();
+    test_ret += test_xmlSaveToFilename();
+    test_ret += test_xmlSaveTree();
+
+    if (test_ret != 0)
+	printf("Module xmlsave: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlSchemaDump(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    FILE * output; /* the file output */
+    int n_output;
+    xmlSchemaPtr schema; /* a schema structure */
+    int n_schema;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_schema = 0;n_schema < gen_nb_xmlSchemaPtr;n_schema++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        schema = gen_xmlSchemaPtr(n_schema, 1);
+
+        xmlSchemaDump(output, schema);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlSchemaPtr(n_schema, schema, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaDump",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_schema);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaParserCtxtPtr 1
+static xmlSchemaParserCtxtPtr gen_xmlSchemaParserCtxtPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaParserCtxtPtr(int no ATTRIBUTE_UNUSED, xmlSchemaParserCtxtPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaValidityErrorFunc_ptr 1
+static xmlSchemaValidityErrorFunc * gen_xmlSchemaValidityErrorFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaValidityErrorFunc_ptr(int no ATTRIBUTE_UNUSED, xmlSchemaValidityErrorFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaValidityWarningFunc_ptr 1
+static xmlSchemaValidityWarningFunc * gen_xmlSchemaValidityWarningFunc_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaValidityWarningFunc_ptr(int no ATTRIBUTE_UNUSED, xmlSchemaValidityWarningFunc * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaGetParserErrors(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaParserCtxtPtr ctxt; /* a XMl-Schema parser context */
+    int n_ctxt;
+    xmlSchemaValidityErrorFunc * err; /* the error callback result */
+    int n_err;
+    xmlSchemaValidityWarningFunc * warn; /* the warning callback result */
+    int n_warn;
+    void ** ctx; /* contextual data for the callbacks result */
+    int n_ctx;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaParserCtxtPtr;n_ctxt++) {
+    for (n_err = 0;n_err < gen_nb_xmlSchemaValidityErrorFunc_ptr;n_err++) {
+    for (n_warn = 0;n_warn < gen_nb_xmlSchemaValidityWarningFunc_ptr;n_warn++) {
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaParserCtxtPtr(n_ctxt, 0);
+        err = gen_xmlSchemaValidityErrorFunc_ptr(n_err, 1);
+        warn = gen_xmlSchemaValidityWarningFunc_ptr(n_warn, 2);
+        ctx = gen_void_ptr_ptr(n_ctx, 3);
+
+        ret_val = xmlSchemaGetParserErrors(ctxt, err, warn, ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlSchemaValidityErrorFunc_ptr(n_err, err, 1);
+        des_xmlSchemaValidityWarningFunc_ptr(n_warn, warn, 2);
+        des_void_ptr_ptr(n_ctx, ctx, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetParserErrors",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_err);
+            printf(" %d", n_warn);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetValidErrors(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a XML-Schema validation context */
+    int n_ctxt;
+    xmlSchemaValidityErrorFunc * err; /* the error function result */
+    int n_err;
+    xmlSchemaValidityWarningFunc * warn; /* the warning function result */
+    int n_warn;
+    void ** ctx; /* the functions context result */
+    int n_ctx;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_err = 0;n_err < gen_nb_xmlSchemaValidityErrorFunc_ptr;n_err++) {
+    for (n_warn = 0;n_warn < gen_nb_xmlSchemaValidityWarningFunc_ptr;n_warn++) {
+    for (n_ctx = 0;n_ctx < gen_nb_void_ptr_ptr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        err = gen_xmlSchemaValidityErrorFunc_ptr(n_err, 1);
+        warn = gen_xmlSchemaValidityWarningFunc_ptr(n_warn, 2);
+        ctx = gen_void_ptr_ptr(n_ctx, 3);
+
+        ret_val = xmlSchemaGetValidErrors(ctxt, err, warn, ctx);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlSchemaValidityErrorFunc_ptr(n_err, err, 1);
+        des_xmlSchemaValidityWarningFunc_ptr(n_warn, warn, 2);
+        des_void_ptr_ptr(n_ctx, ctx, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetValidErrors",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_err);
+            printf(" %d", n_warn);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaIsValid(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* the schema validation context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlSchemaIsValid(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaIsValid",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewDocParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaParserCtxtPtr ret_val;
+    xmlDocPtr doc; /* a preparsed document tree */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlSchemaNewDocParserCtxt(doc);
+        desret_xmlSchemaParserCtxtPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaNewDocParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewMemParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaParserCtxtPtr ret_val;
+    char * buffer; /* a pointer to a char array containing the schemas */
+    int n_buffer;
+    int size; /* the size of the array */
+    int n_size;
+
+    for (n_buffer = 0;n_buffer < gen_nb_const_char_ptr;n_buffer++) {
+    for (n_size = 0;n_size < gen_nb_int;n_size++) {
+        mem_base = xmlMemBlocks();
+        buffer = gen_const_char_ptr(n_buffer, 0);
+        size = gen_int(n_size, 1);
+
+        ret_val = xmlSchemaNewMemParserCtxt((const char *)buffer, size);
+        desret_xmlSchemaParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_buffer, (const char *)buffer, 0);
+        des_int(n_size, size, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaNewMemParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buffer);
+            printf(" %d", n_size);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaParserCtxtPtr ret_val;
+    char * URL; /* the location of the schema */
+    int n_URL;
+
+    for (n_URL = 0;n_URL < gen_nb_const_char_ptr;n_URL++) {
+        mem_base = xmlMemBlocks();
+        URL = gen_const_char_ptr(n_URL, 0);
+
+        ret_val = xmlSchemaNewParserCtxt((const char *)URL);
+        desret_xmlSchemaParserCtxtPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_URL, (const char *)URL, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaNewParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_URL);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewValidCtxt(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaParse(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSAXHandlerPtr_ptr 1
+static xmlSAXHandlerPtr * gen_xmlSAXHandlerPtr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSAXHandlerPtr_ptr(int no ATTRIBUTE_UNUSED, xmlSAXHandlerPtr * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaSAXPlug(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaSAXPlugPtr 1
+static xmlSchemaSAXPlugPtr gen_xmlSchemaSAXPlugPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaSAXPlugPtr(int no ATTRIBUTE_UNUSED, xmlSchemaSAXPlugPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaSAXUnplug(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaSAXPlugPtr plug; /* a data structure returned by xmlSchemaSAXPlug */
+    int n_plug;
+
+    for (n_plug = 0;n_plug < gen_nb_xmlSchemaSAXPlugPtr;n_plug++) {
+        mem_base = xmlMemBlocks();
+        plug = gen_xmlSchemaSAXPlugPtr(n_plug, 0);
+
+        ret_val = xmlSchemaSAXUnplug(plug);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaSAXPlugPtr(n_plug, plug, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaSAXUnplug",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_plug);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaSetParserErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaSetParserStructuredErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaSetValidErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaSetValidOptions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+    int options; /* a combination of xmlSchemaValidOption */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        options = gen_int(n_options, 1);
+
+        ret_val = xmlSchemaSetValidOptions(ctxt, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_int(n_options, options, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaSetValidOptions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaSetValidStructuredErrors(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidCtxtGetOptions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlSchemaValidCtxtGetOptions(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidCtxtGetOptions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidCtxtGetParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+
+        ret_val = xmlSchemaValidCtxtGetParserCtxt(ctxt);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidCtxtGetParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateDoc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+    xmlDocPtr doc; /* a parsed document tree */
+    int n_doc;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        doc = gen_xmlDocPtr(n_doc, 1);
+
+        ret_val = xmlSchemaValidateDoc(ctxt, doc);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlDocPtr(n_doc, doc, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateDoc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateFile(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+    const char * filename; /* the URI of the instance */
+    int n_filename;
+    int options; /* a future set of options, currently unused */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_filename = 0;n_filename < gen_nb_filepath;n_filename++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        filename = gen_filepath(n_filename, 1);
+        options = gen_int(n_options, 2);
+
+        ret_val = xmlSchemaValidateFile(ctxt, filename, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_filepath(n_filename, filename, 1);
+        des_int(n_options, options, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateFile",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_filename);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateOneElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+    xmlNodePtr elem; /* an element node */
+    int n_elem;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_elem = 0;n_elem < gen_nb_xmlNodePtr;n_elem++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        elem = gen_xmlNodePtr(n_elem, 1);
+
+        ret_val = xmlSchemaValidateOneElement(ctxt, elem);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_elem, elem, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateOneElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_elem);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateStream(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValidCtxtPtr ctxt; /* a schema validation context */
+    int n_ctxt;
+    xmlParserInputBufferPtr input; /* the input to use for reading the data */
+    int n_input;
+    xmlCharEncoding enc; /* an optional encoding information */
+    int n_enc;
+    xmlSAXHandlerPtr sax; /* a SAX handler for the resulting events */
+    int n_sax;
+    void * user_data; /* the context to provide to the SAX handler. */
+    int n_user_data;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchemaValidCtxtPtr;n_ctxt++) {
+    for (n_input = 0;n_input < gen_nb_xmlParserInputBufferPtr;n_input++) {
+    for (n_enc = 0;n_enc < gen_nb_xmlCharEncoding;n_enc++) {
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_user_data = 0;n_user_data < gen_nb_userdata;n_user_data++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlSchemaValidCtxtPtr(n_ctxt, 0);
+        input = gen_xmlParserInputBufferPtr(n_input, 1);
+        enc = gen_xmlCharEncoding(n_enc, 2);
+        sax = gen_xmlSAXHandlerPtr(n_sax, 3);
+        user_data = gen_userdata(n_user_data, 4);
+
+        ret_val = xmlSchemaValidateStream(ctxt, input, enc, sax, user_data);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValidCtxtPtr(n_ctxt, ctxt, 0);
+        des_xmlParserInputBufferPtr(n_input, input, 1);
+        des_xmlCharEncoding(n_enc, enc, 2);
+        des_xmlSAXHandlerPtr(n_sax, sax, 3);
+        des_userdata(n_user_data, user_data, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateStream",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_input);
+            printf(" %d", n_enc);
+            printf(" %d", n_sax);
+            printf(" %d", n_user_data);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlschemas(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlschemas : 15 of 25 functions ...\n");
+    test_ret += test_xmlSchemaDump();
+    test_ret += test_xmlSchemaGetParserErrors();
+    test_ret += test_xmlSchemaGetValidErrors();
+    test_ret += test_xmlSchemaIsValid();
+    test_ret += test_xmlSchemaNewDocParserCtxt();
+    test_ret += test_xmlSchemaNewMemParserCtxt();
+    test_ret += test_xmlSchemaNewParserCtxt();
+    test_ret += test_xmlSchemaNewValidCtxt();
+    test_ret += test_xmlSchemaParse();
+    test_ret += test_xmlSchemaSAXPlug();
+    test_ret += test_xmlSchemaSAXUnplug();
+    test_ret += test_xmlSchemaSetParserErrors();
+    test_ret += test_xmlSchemaSetParserStructuredErrors();
+    test_ret += test_xmlSchemaSetValidErrors();
+    test_ret += test_xmlSchemaSetValidOptions();
+    test_ret += test_xmlSchemaSetValidStructuredErrors();
+    test_ret += test_xmlSchemaValidCtxtGetOptions();
+    test_ret += test_xmlSchemaValidCtxtGetParserCtxt();
+    test_ret += test_xmlSchemaValidateDoc();
+    test_ret += test_xmlSchemaValidateFile();
+    test_ret += test_xmlSchemaValidateOneElement();
+    test_ret += test_xmlSchemaValidateStream();
+
+    if (test_ret != 0)
+	printf("Module xmlschemas: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaFacetPtr 1
+static xmlSchemaFacetPtr gen_xmlSchemaFacetPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaFacetPtr(int no ATTRIBUTE_UNUSED, xmlSchemaFacetPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaTypePtr 1
+static xmlSchemaTypePtr gen_xmlSchemaTypePtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaTypePtr(int no ATTRIBUTE_UNUSED, xmlSchemaTypePtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaCheckFacet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaFacetPtr facet; /* the facet */
+    int n_facet;
+    xmlSchemaTypePtr typeDecl; /* the schema type definition */
+    int n_typeDecl;
+    xmlSchemaParserCtxtPtr pctxt; /* the schema parser context or NULL */
+    int n_pctxt;
+    xmlChar * name; /* the optional name of the type */
+    int n_name;
+
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_typeDecl = 0;n_typeDecl < gen_nb_xmlSchemaTypePtr;n_typeDecl++) {
+    for (n_pctxt = 0;n_pctxt < gen_nb_xmlSchemaParserCtxtPtr;n_pctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        facet = gen_xmlSchemaFacetPtr(n_facet, 0);
+        typeDecl = gen_xmlSchemaTypePtr(n_typeDecl, 1);
+        pctxt = gen_xmlSchemaParserCtxtPtr(n_pctxt, 2);
+        name = gen_const_xmlChar_ptr(n_name, 3);
+
+        ret_val = xmlSchemaCheckFacet(facet, typeDecl, pctxt, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaFacetPtr(n_facet, facet, 0);
+        des_xmlSchemaTypePtr(n_typeDecl, typeDecl, 1);
+        des_xmlSchemaParserCtxtPtr(n_pctxt, pctxt, 2);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaCheckFacet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_facet);
+            printf(" %d", n_typeDecl);
+            printf(" %d", n_pctxt);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaCleanupTypes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+
+
+        xmlSchemaCleanupTypes();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaCollapseString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * value; /* a value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlSchemaCollapseString((const xmlChar *)value);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaCollapseString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaValPtr 1
+static xmlSchemaValPtr gen_xmlSchemaValPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaValPtr(int no ATTRIBUTE_UNUSED, xmlSchemaValPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaCompareValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr x; /* a first value */
+    int n_x;
+    xmlSchemaValPtr y; /* a second value */
+    int n_y;
+
+    for (n_x = 0;n_x < gen_nb_xmlSchemaValPtr;n_x++) {
+    for (n_y = 0;n_y < gen_nb_xmlSchemaValPtr;n_y++) {
+        mem_base = xmlMemBlocks();
+        x = gen_xmlSchemaValPtr(n_x, 0);
+        y = gen_xmlSchemaValPtr(n_y, 1);
+
+        ret_val = xmlSchemaCompareValues(x, y);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_x, x, 0);
+        des_xmlSchemaValPtr(n_y, y, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaCompareValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_x);
+            printf(" %d", n_y);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaCompareValuesWhtsp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr x; /* a first value */
+    int n_x;
+    xmlSchemaWhitespaceValueType xws; /* the whitespace value of x */
+    int n_xws;
+    xmlSchemaValPtr y; /* a second value */
+    int n_y;
+    xmlSchemaWhitespaceValueType yws; /* the whitespace value of y */
+    int n_yws;
+
+    for (n_x = 0;n_x < gen_nb_xmlSchemaValPtr;n_x++) {
+    for (n_xws = 0;n_xws < gen_nb_xmlSchemaWhitespaceValueType;n_xws++) {
+    for (n_y = 0;n_y < gen_nb_xmlSchemaValPtr;n_y++) {
+    for (n_yws = 0;n_yws < gen_nb_xmlSchemaWhitespaceValueType;n_yws++) {
+        mem_base = xmlMemBlocks();
+        x = gen_xmlSchemaValPtr(n_x, 0);
+        xws = gen_xmlSchemaWhitespaceValueType(n_xws, 1);
+        y = gen_xmlSchemaValPtr(n_y, 2);
+        yws = gen_xmlSchemaWhitespaceValueType(n_yws, 3);
+
+        ret_val = xmlSchemaCompareValuesWhtsp(x, xws, y, yws);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_x, x, 0);
+        des_xmlSchemaWhitespaceValueType(n_xws, xws, 1);
+        des_xmlSchemaValPtr(n_y, y, 2);
+        des_xmlSchemaWhitespaceValueType(n_yws, yws, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaCompareValuesWhtsp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_x);
+            printf(" %d", n_xws);
+            printf(" %d", n_y);
+            printf(" %d", n_yws);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaCopyValue(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetBuiltInListSimpleTypeItemType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaTypePtr ret_val;
+    xmlSchemaTypePtr type; /* the built-in simple type. */
+    int n_type;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+
+        ret_val = xmlSchemaGetBuiltInListSimpleTypeItemType(type);
+        desret_xmlSchemaTypePtr(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetBuiltInListSimpleTypeItemType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetBuiltInType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    xmlSchemaTypePtr ret_val;
+    xmlSchemaValType type; /* the type of the built in type */
+    int n_type;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaValType;n_type++) {
+        type = gen_xmlSchemaValType(n_type, 0);
+
+        ret_val = xmlSchemaGetBuiltInType(type);
+        desret_xmlSchemaTypePtr(ret_val);
+        call_tests++;
+        des_xmlSchemaValType(n_type, type, 0);
+        xmlResetLastError();
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetCanonValue(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+    xmlChar ** retValue; /* the returned value */
+    int n_retValue;
+
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+    for (n_retValue = 0;n_retValue < gen_nb_const_xmlChar_ptr_ptr;n_retValue++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlSchemaValPtr(n_val, 0);
+        retValue = gen_const_xmlChar_ptr_ptr(n_retValue, 1);
+
+        ret_val = xmlSchemaGetCanonValue(val, (const xmlChar **)retValue);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_val, val, 0);
+        des_const_xmlChar_ptr_ptr(n_retValue, (const xmlChar **)retValue, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetCanonValue",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf(" %d", n_retValue);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetCanonValueWhtsp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+    xmlChar ** retValue; /* the returned value */
+    int n_retValue;
+    xmlSchemaWhitespaceValueType ws; /* the whitespace type of the value */
+    int n_ws;
+
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+    for (n_retValue = 0;n_retValue < gen_nb_const_xmlChar_ptr_ptr;n_retValue++) {
+    for (n_ws = 0;n_ws < gen_nb_xmlSchemaWhitespaceValueType;n_ws++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlSchemaValPtr(n_val, 0);
+        retValue = gen_const_xmlChar_ptr_ptr(n_retValue, 1);
+        ws = gen_xmlSchemaWhitespaceValueType(n_ws, 2);
+
+        ret_val = xmlSchemaGetCanonValueWhtsp(val, (const xmlChar **)retValue, ws);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_val, val, 0);
+        des_const_xmlChar_ptr_ptr(n_retValue, (const xmlChar **)retValue, 1);
+        des_xmlSchemaWhitespaceValueType(n_ws, ws, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetCanonValueWhtsp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf(" %d", n_retValue);
+            printf(" %d", n_ws);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetFacetValueAsULong(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    unsigned long ret_val;
+    xmlSchemaFacetPtr facet; /* an schemas type facet */
+    int n_facet;
+
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+        mem_base = xmlMemBlocks();
+        facet = gen_xmlSchemaFacetPtr(n_facet, 0);
+
+        ret_val = xmlSchemaGetFacetValueAsULong(facet);
+        desret_unsigned_long(ret_val);
+        call_tests++;
+        des_xmlSchemaFacetPtr(n_facet, facet, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetFacetValueAsULong",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_facet);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetPredefinedType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaTypePtr ret_val;
+    xmlChar * name; /* the type name */
+    int n_name;
+    xmlChar * ns; /* the URI of the namespace usually "http://www.w3.org/2001/XMLSchema" */
+    int n_ns;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns = 0;n_ns < gen_nb_const_xmlChar_ptr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+        ns = gen_const_xmlChar_ptr(n_ns, 1);
+
+        ret_val = xmlSchemaGetPredefinedType((const xmlChar *)name, (const xmlChar *)ns);
+        desret_xmlSchemaTypePtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        des_const_xmlChar_ptr(n_ns, (const xmlChar *)ns, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetPredefinedType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaGetValType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlSchemaValType ret_val;
+    xmlSchemaValPtr val; /* a schemas value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlSchemaValPtr(n_val, 0);
+
+        ret_val = xmlSchemaGetValType(val);
+        desret_xmlSchemaValType(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaGetValType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaInitTypes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+
+
+        xmlSchemaInitTypes();
+        call_tests++;
+        xmlResetLastError();
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaIsBuiltInTypeFacet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr type; /* the built-in type */
+    int n_type;
+    int facetType; /* the facet type */
+    int n_facetType;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+    for (n_facetType = 0;n_facetType < gen_nb_int;n_facetType++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+        facetType = gen_int(n_facetType, 1);
+
+        ret_val = xmlSchemaIsBuiltInTypeFacet(type, facetType);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        des_int(n_facetType, facetType, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaIsBuiltInTypeFacet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_facetType);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewFacet(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewNOTATIONValue(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewQNameValue(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaNewStringValue(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#define gen_nb_xmlSchemaValPtr_ptr 1
+static xmlSchemaValPtr * gen_xmlSchemaValPtr_ptr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlSchemaValPtr_ptr(int no ATTRIBUTE_UNUSED, xmlSchemaValPtr * val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlSchemaValPredefTypeNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr type; /* the predefined type */
+    int n_type;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    xmlSchemaValPtr * val; /* the return computed value */
+    int n_val;
+    xmlNodePtr node; /* the node containing the value */
+    int n_node;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr_ptr;n_val++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        val = gen_xmlSchemaValPtr_ptr(n_val, 2);
+        node = gen_xmlNodePtr(n_node, 3);
+
+        ret_val = xmlSchemaValPredefTypeNode(type, (const xmlChar *)value, val, node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_xmlSchemaValPtr_ptr(n_val, val, 2);
+        des_xmlNodePtr(n_node, node, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValPredefTypeNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValPredefTypeNodeNoNorm(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr type; /* the predefined type */
+    int n_type;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    xmlSchemaValPtr * val; /* the return computed value */
+    int n_val;
+    xmlNodePtr node; /* the node containing the value */
+    int n_node;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr_ptr;n_val++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        val = gen_xmlSchemaValPtr_ptr(n_val, 2);
+        node = gen_xmlNodePtr(n_node, 3);
+
+        ret_val = xmlSchemaValPredefTypeNodeNoNorm(type, (const xmlChar *)value, val, node);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_xmlSchemaValPtr_ptr(n_val, val, 2);
+        des_xmlNodePtr(n_node, node, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValPredefTypeNodeNoNorm",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateFacet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr base; /* the base type */
+    int n_base;
+    xmlSchemaFacetPtr facet; /* the facet to check */
+    int n_facet;
+    xmlChar * value; /* the lexical repr of the value to validate */
+    int n_value;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+
+    for (n_base = 0;n_base < gen_nb_xmlSchemaTypePtr;n_base++) {
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        base = gen_xmlSchemaTypePtr(n_base, 0);
+        facet = gen_xmlSchemaFacetPtr(n_facet, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+        val = gen_xmlSchemaValPtr(n_val, 3);
+
+        ret_val = xmlSchemaValidateFacet(base, facet, (const xmlChar *)value, val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_base, base, 0);
+        des_xmlSchemaFacetPtr(n_facet, facet, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        des_xmlSchemaValPtr(n_val, val, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateFacet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_base);
+            printf(" %d", n_facet);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateFacetWhtsp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaFacetPtr facet; /* the facet to check */
+    int n_facet;
+    xmlSchemaWhitespaceValueType fws; /* the whitespace type of the facet's value */
+    int n_fws;
+    xmlSchemaValType valType; /* the built-in type of the value */
+    int n_valType;
+    xmlChar * value; /* the lexical (or normalized for pattern) repr of the value to validate */
+    int n_value;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+    xmlSchemaWhitespaceValueType ws; /* the whitespace type of the value */
+    int n_ws;
+
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_fws = 0;n_fws < gen_nb_xmlSchemaWhitespaceValueType;n_fws++) {
+    for (n_valType = 0;n_valType < gen_nb_xmlSchemaValType;n_valType++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+    for (n_ws = 0;n_ws < gen_nb_xmlSchemaWhitespaceValueType;n_ws++) {
+        mem_base = xmlMemBlocks();
+        facet = gen_xmlSchemaFacetPtr(n_facet, 0);
+        fws = gen_xmlSchemaWhitespaceValueType(n_fws, 1);
+        valType = gen_xmlSchemaValType(n_valType, 2);
+        value = gen_const_xmlChar_ptr(n_value, 3);
+        val = gen_xmlSchemaValPtr(n_val, 4);
+        ws = gen_xmlSchemaWhitespaceValueType(n_ws, 5);
+
+        ret_val = xmlSchemaValidateFacetWhtsp(facet, fws, valType, (const xmlChar *)value, val, ws);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaFacetPtr(n_facet, facet, 0);
+        des_xmlSchemaWhitespaceValueType(n_fws, fws, 1);
+        des_xmlSchemaValType(n_valType, valType, 2);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 3);
+        des_xmlSchemaValPtr(n_val, val, 4);
+        des_xmlSchemaWhitespaceValueType(n_ws, ws, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateFacetWhtsp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_facet);
+            printf(" %d", n_fws);
+            printf(" %d", n_valType);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf(" %d", n_ws);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateLengthFacet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr type; /* the built-in type */
+    int n_type;
+    xmlSchemaFacetPtr facet; /* the facet to check */
+    int n_facet;
+    xmlChar * value; /* the lexical repr. of the value to be validated */
+    int n_value;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+    unsigned long * length; /* the actual length of the value */
+    int n_length;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+    for (n_length = 0;n_length < gen_nb_unsigned_long_ptr;n_length++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+        facet = gen_xmlSchemaFacetPtr(n_facet, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+        val = gen_xmlSchemaValPtr(n_val, 3);
+        length = gen_unsigned_long_ptr(n_length, 4);
+
+        ret_val = xmlSchemaValidateLengthFacet(type, facet, (const xmlChar *)value, val, length);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        des_xmlSchemaFacetPtr(n_facet, facet, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        des_xmlSchemaValPtr(n_val, val, 3);
+        des_unsigned_long_ptr(n_length, length, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateLengthFacet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_facet);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf(" %d", n_length);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateLengthFacetWhtsp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaFacetPtr facet; /* the facet to check */
+    int n_facet;
+    xmlSchemaValType valType; /* the built-in type */
+    int n_valType;
+    xmlChar * value; /* the lexical repr. of the value to be validated */
+    int n_value;
+    xmlSchemaValPtr val; /* the precomputed value */
+    int n_val;
+    unsigned long * length; /* the actual length of the value */
+    int n_length;
+    xmlSchemaWhitespaceValueType ws; /* the whitespace type of the value */
+    int n_ws;
+
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_valType = 0;n_valType < gen_nb_xmlSchemaValType;n_valType++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+    for (n_length = 0;n_length < gen_nb_unsigned_long_ptr;n_length++) {
+    for (n_ws = 0;n_ws < gen_nb_xmlSchemaWhitespaceValueType;n_ws++) {
+        mem_base = xmlMemBlocks();
+        facet = gen_xmlSchemaFacetPtr(n_facet, 0);
+        valType = gen_xmlSchemaValType(n_valType, 1);
+        value = gen_const_xmlChar_ptr(n_value, 2);
+        val = gen_xmlSchemaValPtr(n_val, 3);
+        length = gen_unsigned_long_ptr(n_length, 4);
+        ws = gen_xmlSchemaWhitespaceValueType(n_ws, 5);
+
+        ret_val = xmlSchemaValidateLengthFacetWhtsp(facet, valType, (const xmlChar *)value, val, length, ws);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaFacetPtr(n_facet, facet, 0);
+        des_xmlSchemaValType(n_valType, valType, 1);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 2);
+        des_xmlSchemaValPtr(n_val, val, 3);
+        des_unsigned_long_ptr(n_length, length, 4);
+        des_xmlSchemaWhitespaceValueType(n_ws, ws, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateLengthFacetWhtsp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_facet);
+            printf(" %d", n_valType);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf(" %d", n_length);
+            printf(" %d", n_ws);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidateListSimpleTypeFacet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaFacetPtr facet; /* the facet to check */
+    int n_facet;
+    xmlChar * value; /* the lexical repr of the value to validate */
+    int n_value;
+    unsigned long actualLen; /* the number of list items */
+    int n_actualLen;
+    unsigned long * expectedLen; /* the resulting expected number of list items */
+    int n_expectedLen;
+
+    for (n_facet = 0;n_facet < gen_nb_xmlSchemaFacetPtr;n_facet++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_actualLen = 0;n_actualLen < gen_nb_unsigned_long;n_actualLen++) {
+    for (n_expectedLen = 0;n_expectedLen < gen_nb_unsigned_long_ptr;n_expectedLen++) {
+        mem_base = xmlMemBlocks();
+        facet = gen_xmlSchemaFacetPtr(n_facet, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        actualLen = gen_unsigned_long(n_actualLen, 2);
+        expectedLen = gen_unsigned_long_ptr(n_expectedLen, 3);
+
+        ret_val = xmlSchemaValidateListSimpleTypeFacet(facet, (const xmlChar *)value, actualLen, expectedLen);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaFacetPtr(n_facet, facet, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_unsigned_long(n_actualLen, actualLen, 2);
+        des_unsigned_long_ptr(n_expectedLen, expectedLen, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidateListSimpleTypeFacet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_facet);
+            printf(" %d", n_value);
+            printf(" %d", n_actualLen);
+            printf(" %d", n_expectedLen);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValidatePredefinedType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaTypePtr type; /* the predefined type */
+    int n_type;
+    xmlChar * value; /* the value to check */
+    int n_value;
+    xmlSchemaValPtr * val; /* the return computed value */
+    int n_val;
+
+    for (n_type = 0;n_type < gen_nb_xmlSchemaTypePtr;n_type++) {
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        type = gen_xmlSchemaTypePtr(n_type, 0);
+        value = gen_const_xmlChar_ptr(n_value, 1);
+        val = gen_xmlSchemaValPtr_ptr(n_val, 2);
+
+        ret_val = xmlSchemaValidatePredefinedType(type, (const xmlChar *)value, val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaTypePtr(n_type, type, 0);
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 1);
+        des_xmlSchemaValPtr_ptr(n_val, val, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValidatePredefinedType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_type);
+            printf(" %d", n_value);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValueAppend(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr prev; /* the value */
+    int n_prev;
+    xmlSchemaValPtr cur; /* the value to be appended */
+    int n_cur;
+
+    for (n_prev = 0;n_prev < gen_nb_xmlSchemaValPtr;n_prev++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlSchemaValPtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        prev = gen_xmlSchemaValPtr(n_prev, 0);
+        cur = gen_xmlSchemaValPtr(n_cur, 1);
+
+        ret_val = xmlSchemaValueAppend(prev, cur);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_prev, prev, 0);
+        des_xmlSchemaValPtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValueAppend",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_prev);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValueGetAsBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlSchemaValPtr val; /* the value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlSchemaValPtr(n_val, 0);
+
+        ret_val = xmlSchemaValueGetAsBoolean(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValueGetAsBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValueGetAsString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlSchemaValPtr val; /* the value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlSchemaValPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlSchemaValPtr(n_val, 0);
+
+        ret_val = xmlSchemaValueGetAsString(val);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlSchemaValPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaValueGetAsString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaValueGetNext(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlSchemaWhiteSpaceReplace(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * value; /* a value */
+    int n_value;
+
+    for (n_value = 0;n_value < gen_nb_const_xmlChar_ptr;n_value++) {
+        mem_base = xmlMemBlocks();
+        value = gen_const_xmlChar_ptr(n_value, 0);
+
+        ret_val = xmlSchemaWhiteSpaceReplace((const xmlChar *)value);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_value, (const xmlChar *)value, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlSchemaWhiteSpaceReplace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlschemastypes(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlschemastypes : 26 of 34 functions ...\n");
+    test_ret += test_xmlSchemaCheckFacet();
+    test_ret += test_xmlSchemaCleanupTypes();
+    test_ret += test_xmlSchemaCollapseString();
+    test_ret += test_xmlSchemaCompareValues();
+    test_ret += test_xmlSchemaCompareValuesWhtsp();
+    test_ret += test_xmlSchemaCopyValue();
+    test_ret += test_xmlSchemaGetBuiltInListSimpleTypeItemType();
+    test_ret += test_xmlSchemaGetBuiltInType();
+    test_ret += test_xmlSchemaGetCanonValue();
+    test_ret += test_xmlSchemaGetCanonValueWhtsp();
+    test_ret += test_xmlSchemaGetFacetValueAsULong();
+    test_ret += test_xmlSchemaGetPredefinedType();
+    test_ret += test_xmlSchemaGetValType();
+    test_ret += test_xmlSchemaInitTypes();
+    test_ret += test_xmlSchemaIsBuiltInTypeFacet();
+    test_ret += test_xmlSchemaNewFacet();
+    test_ret += test_xmlSchemaNewNOTATIONValue();
+    test_ret += test_xmlSchemaNewQNameValue();
+    test_ret += test_xmlSchemaNewStringValue();
+    test_ret += test_xmlSchemaValPredefTypeNode();
+    test_ret += test_xmlSchemaValPredefTypeNodeNoNorm();
+    test_ret += test_xmlSchemaValidateFacet();
+    test_ret += test_xmlSchemaValidateFacetWhtsp();
+    test_ret += test_xmlSchemaValidateLengthFacet();
+    test_ret += test_xmlSchemaValidateLengthFacetWhtsp();
+    test_ret += test_xmlSchemaValidateListSimpleTypeFacet();
+    test_ret += test_xmlSchemaValidatePredefinedType();
+    test_ret += test_xmlSchemaValueAppend();
+    test_ret += test_xmlSchemaValueGetAsBoolean();
+    test_ret += test_xmlSchemaValueGetAsString();
+    test_ret += test_xmlSchemaValueGetNext();
+    test_ret += test_xmlSchemaWhiteSpaceReplace();
+
+    if (test_ret != 0)
+	printf("Module xmlschemastypes: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlCharStrdup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    char * cur; /* the input char * */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_const_char_ptr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_char_ptr(n_cur, 0);
+
+        ret_val = xmlCharStrdup((const char *)cur);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_cur, (const char *)cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharStrdup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCharStrndup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    char * cur; /* the input char * */
+    int n_cur;
+    int len; /* the len of @cur */
+    int n_len;
+
+    for (n_cur = 0;n_cur < gen_nb_const_char_ptr;n_cur++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_char_ptr(n_cur, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlCharStrndup((const char *)cur, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_cur, (const char *)cur, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCharStrndup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlCheckUTF8(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned char * utf; /* Pointer to putative UTF-8 encoded string. */
+    int n_utf;
+
+    for (n_utf = 0;n_utf < gen_nb_const_unsigned_char_ptr;n_utf++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_unsigned_char_ptr(n_utf, 0);
+
+        ret_val = xmlCheckUTF8((const unsigned char *)utf);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_unsigned_char_ptr(n_utf, (const unsigned char *)utf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlCheckUTF8",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlGetUTF8Char(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    unsigned char * utf; /* a sequence of UTF-8 encoded bytes */
+    int n_utf;
+    int * len; /* a pointer to the minimum number of bytes present in the sequence.  This is used to assure the next character is completely contained within the sequence. */
+    int n_len;
+
+    for (n_utf = 0;n_utf < gen_nb_const_unsigned_char_ptr;n_utf++) {
+    for (n_len = 0;n_len < gen_nb_int_ptr;n_len++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_unsigned_char_ptr(n_utf, 0);
+        len = gen_int_ptr(n_len, 1);
+
+        ret_val = xmlGetUTF8Char((const unsigned char *)utf, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_unsigned_char_ptr(n_utf, (const unsigned char *)utf, 0);
+        des_int_ptr(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlGetUTF8Char",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrEqual(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str1; /* the first xmlChar * */
+    int n_str1;
+    xmlChar * str2; /* the second xmlChar * */
+    int n_str2;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+
+        ret_val = xmlStrEqual((const xmlChar *)str1, (const xmlChar *)str2);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrEqual",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrPrintf(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrQEqual(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * pref; /* the prefix of the QName */
+    int n_pref;
+    xmlChar * name; /* the localname of the QName */
+    int n_name;
+    xmlChar * str; /* the second xmlChar * */
+    int n_str;
+
+    for (n_pref = 0;n_pref < gen_nb_const_xmlChar_ptr;n_pref++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        pref = gen_const_xmlChar_ptr(n_pref, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        str = gen_const_xmlChar_ptr(n_str, 2);
+
+        ret_val = xmlStrQEqual((const xmlChar *)pref, (const xmlChar *)name, (const xmlChar *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_pref, (const xmlChar *)pref, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrQEqual",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_pref);
+            printf(" %d", n_name);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrVPrintf(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrcasecmp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str1; /* the first xmlChar * */
+    int n_str1;
+    xmlChar * str2; /* the second xmlChar * */
+    int n_str2;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+
+        ret_val = xmlStrcasecmp((const xmlChar *)str1, (const xmlChar *)str2);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrcasecmp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrcasestr(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlChar * str; /* the xmlChar * array (haystack) */
+    int n_str;
+    xmlChar * val; /* the xmlChar to search (needle) */
+    int n_val;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        val = gen_const_xmlChar_ptr(n_val, 1);
+
+        ret_val = xmlStrcasestr((const xmlChar *)str, (const xmlChar *)val);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrcasestr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrchr(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlChar * str; /* the xmlChar * array */
+    int n_str;
+    xmlChar val; /* the xmlChar to search */
+    int n_val;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_val = 0;n_val < gen_nb_xmlChar;n_val++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        val = gen_xmlChar(n_val, 1);
+
+        ret_val = xmlStrchr((const xmlChar *)str, val);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_xmlChar(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrchr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrcmp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str1; /* the first xmlChar * */
+    int n_str1;
+    xmlChar * str2; /* the second xmlChar * */
+    int n_str2;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+
+        ret_val = xmlStrcmp((const xmlChar *)str1, (const xmlChar *)str2);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrcmp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrdup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * cur; /* the input xmlChar * */
+    int n_cur;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+
+        ret_val = xmlStrdup((const xmlChar *)cur);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrdup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrlen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str; /* the xmlChar * array */
+    int n_str;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+
+        ret_val = xmlStrlen((const xmlChar *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrlen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrncasecmp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str1; /* the first xmlChar * */
+    int n_str1;
+    xmlChar * str2; /* the second xmlChar * */
+    int n_str2;
+    int len; /* the max comparison length */
+    int n_len;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlStrncasecmp((const xmlChar *)str1, (const xmlChar *)str2, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrncasecmp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrncatNew(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * str1; /* first xmlChar string */
+    int n_str1;
+    xmlChar * str2; /* second xmlChar string */
+    int n_str2;
+    int len; /* the len of @str2 or < 0 */
+    int n_len;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlStrncatNew((const xmlChar *)str1, (const xmlChar *)str2, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrncatNew",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrncmp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * str1; /* the first xmlChar * */
+    int n_str1;
+    xmlChar * str2; /* the second xmlChar * */
+    int n_str2;
+    int len; /* the max comparison length */
+    int n_len;
+
+    for (n_str1 = 0;n_str1 < gen_nb_const_xmlChar_ptr;n_str1++) {
+    for (n_str2 = 0;n_str2 < gen_nb_const_xmlChar_ptr;n_str2++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        str1 = gen_const_xmlChar_ptr(n_str1, 0);
+        str2 = gen_const_xmlChar_ptr(n_str2, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlStrncmp((const xmlChar *)str1, (const xmlChar *)str2, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str1, (const xmlChar *)str1, 0);
+        des_const_xmlChar_ptr(n_str2, (const xmlChar *)str2, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrncmp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str1);
+            printf(" %d", n_str2);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrndup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * cur; /* the input xmlChar * */
+    int n_cur;
+    int len; /* the len of @cur */
+    int n_len;
+
+    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_const_xmlChar_ptr(n_cur, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlStrndup((const xmlChar *)cur, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrndup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrstr(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlChar * str; /* the xmlChar * array (haystack) */
+    int n_str;
+    xmlChar * val; /* the xmlChar to search (needle) */
+    int n_val;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        val = gen_const_xmlChar_ptr(n_val, 1);
+
+        ret_val = xmlStrstr((const xmlChar *)str, (const xmlChar *)val);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrstr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlStrsub(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * str; /* the xmlChar * array (haystack) */
+    int n_str;
+    int start; /* the index of the first char (zero based) */
+    int n_start;
+    int len; /* the length of the substring */
+    int n_len;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_start = 0;n_start < gen_nb_int;n_start++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        start = gen_int(n_start, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlStrsub((const xmlChar *)str, start, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_int(n_start, start, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlStrsub",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_start);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Charcmp(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * utf1; /* pointer to first UTF8 char */
+    int n_utf1;
+    xmlChar * utf2; /* pointer to second UTF8 char */
+    int n_utf2;
+
+    for (n_utf1 = 0;n_utf1 < gen_nb_const_xmlChar_ptr;n_utf1++) {
+    for (n_utf2 = 0;n_utf2 < gen_nb_const_xmlChar_ptr;n_utf2++) {
+        mem_base = xmlMemBlocks();
+        utf1 = gen_const_xmlChar_ptr(n_utf1, 0);
+        utf2 = gen_const_xmlChar_ptr(n_utf2, 1);
+
+        ret_val = xmlUTF8Charcmp((const xmlChar *)utf1, (const xmlChar *)utf2);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf1, (const xmlChar *)utf1, 0);
+        des_const_xmlChar_ptr(n_utf2, (const xmlChar *)utf2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Charcmp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf1);
+            printf(" %d", n_utf2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Size(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * utf; /* pointer to the UTF8 character */
+    int n_utf;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+
+        ret_val = xmlUTF8Size((const xmlChar *)utf);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Size",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strlen(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+    int n_utf;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+
+        ret_val = xmlUTF8Strlen((const xmlChar *)utf);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strlen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strloc(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * utf; /* the input UTF8 * */
+    int n_utf;
+    xmlChar * utfchar; /* the UTF8 character to be found */
+    int n_utfchar;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+    for (n_utfchar = 0;n_utfchar < gen_nb_const_xmlChar_ptr;n_utfchar++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+        utfchar = gen_const_xmlChar_ptr(n_utfchar, 1);
+
+        ret_val = xmlUTF8Strloc((const xmlChar *)utf, (const xmlChar *)utfchar);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        des_const_xmlChar_ptr(n_utfchar, (const xmlChar *)utfchar, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strloc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_utfchar);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strndup(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * utf; /* the input UTF8 * */
+    int n_utf;
+    int len; /* the len of @utf (in chars) */
+    int n_len;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlUTF8Strndup((const xmlChar *)utf, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strndup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strpos(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlChar * utf; /* the input UTF8 * */
+    int n_utf;
+    int pos; /* the position of the desired UTF8 char (in chars) */
+    int n_pos;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+    for (n_pos = 0;n_pos < gen_nb_int;n_pos++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+        pos = gen_int(n_pos, 1);
+
+        ret_val = xmlUTF8Strpos((const xmlChar *)utf, pos);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        des_int(n_pos, pos, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strpos",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_pos);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strsize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+    int n_utf;
+    int len; /* the number of characters in the array */
+    int n_len;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+        len = gen_int(n_len, 1);
+
+        ret_val = xmlUTF8Strsize((const xmlChar *)utf, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        des_int(n_len, len, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strsize",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUTF8Strsub(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlChar * ret_val;
+    xmlChar * utf; /* a sequence of UTF-8 encoded bytes */
+    int n_utf;
+    int start; /* relative pos of first char */
+    int n_start;
+    int len; /* total number to copy */
+    int n_len;
+
+    for (n_utf = 0;n_utf < gen_nb_const_xmlChar_ptr;n_utf++) {
+    for (n_start = 0;n_start < gen_nb_int;n_start++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        utf = gen_const_xmlChar_ptr(n_utf, 0);
+        start = gen_int(n_start, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlUTF8Strsub((const xmlChar *)utf, start, len);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_utf, (const xmlChar *)utf, 0);
+        des_int(n_start, start, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUTF8Strsub",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_utf);
+            printf(" %d", n_start);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+static int
+test_xmlstring(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlstring : 26 of 30 functions ...\n");
+    test_ret += test_xmlCharStrdup();
+    test_ret += test_xmlCharStrndup();
+    test_ret += test_xmlCheckUTF8();
+    test_ret += test_xmlGetUTF8Char();
+    test_ret += test_xmlStrEqual();
+    test_ret += test_xmlStrPrintf();
+    test_ret += test_xmlStrQEqual();
+    test_ret += test_xmlStrVPrintf();
+    test_ret += test_xmlStrcasecmp();
+    test_ret += test_xmlStrcasestr();
+    test_ret += test_xmlStrchr();
+    test_ret += test_xmlStrcmp();
+    test_ret += test_xmlStrdup();
+    test_ret += test_xmlStrlen();
+    test_ret += test_xmlStrncasecmp();
+    test_ret += test_xmlStrncatNew();
+    test_ret += test_xmlStrncmp();
+    test_ret += test_xmlStrndup();
+    test_ret += test_xmlStrstr();
+    test_ret += test_xmlStrsub();
+    test_ret += test_xmlUTF8Charcmp();
+    test_ret += test_xmlUTF8Size();
+    test_ret += test_xmlUTF8Strlen();
+    test_ret += test_xmlUTF8Strloc();
+    test_ret += test_xmlUTF8Strndup();
+    test_ret += test_xmlUTF8Strpos();
+    test_ret += test_xmlUTF8Strsize();
+    test_ret += test_xmlUTF8Strsub();
+
+    if (test_ret != 0)
+	printf("Module xmlstring: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlUCSIsAegeanNumbers(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsAegeanNumbers(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsAegeanNumbers",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsAlphabeticPresentationForms(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsAlphabeticPresentationForms(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsAlphabeticPresentationForms",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsArabic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsArabic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsArabic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsArabicPresentationFormsA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsArabicPresentationFormsA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsArabicPresentationFormsA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsArabicPresentationFormsB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsArabicPresentationFormsB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsArabicPresentationFormsB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsArmenian(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsArmenian(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsArmenian",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsArrows(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsArrows(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsArrows",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBasicLatin(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBasicLatin(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBasicLatin",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBengali(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBengali(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBengali",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBlock(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+    char * block; /* UCS block name */
+    int n_block;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+    for (n_block = 0;n_block < gen_nb_const_char_ptr;n_block++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+        block = gen_const_char_ptr(n_block, 1);
+
+        ret_val = xmlUCSIsBlock(code, (const char *)block);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        des_const_char_ptr(n_block, (const char *)block, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBlock",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf(" %d", n_block);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBlockElements(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBlockElements(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBlockElements",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBopomofo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBopomofo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBopomofo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBopomofoExtended(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBopomofoExtended(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBopomofoExtended",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBoxDrawing(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBoxDrawing(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBoxDrawing",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBraillePatterns(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBraillePatterns(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBraillePatterns",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsBuhid(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsBuhid(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsBuhid",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsByzantineMusicalSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsByzantineMusicalSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsByzantineMusicalSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKCompatibility(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKCompatibility(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKCompatibility",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKCompatibilityForms(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKCompatibilityForms(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKCompatibilityForms",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKCompatibilityIdeographs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKCompatibilityIdeographs(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKCompatibilityIdeographs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKCompatibilityIdeographsSupplement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKCompatibilityIdeographsSupplement(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKCompatibilityIdeographsSupplement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKRadicalsSupplement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKRadicalsSupplement(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKRadicalsSupplement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKSymbolsandPunctuation(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKSymbolsandPunctuation(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKSymbolsandPunctuation",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKUnifiedIdeographs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKUnifiedIdeographs(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKUnifiedIdeographs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKUnifiedIdeographsExtensionA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKUnifiedIdeographsExtensionA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKUnifiedIdeographsExtensionA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCJKUnifiedIdeographsExtensionB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCJKUnifiedIdeographsExtensionB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCJKUnifiedIdeographsExtensionB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+    char * cat; /* UCS Category name */
+    int n_cat;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+    for (n_cat = 0;n_cat < gen_nb_const_char_ptr;n_cat++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+        cat = gen_const_char_ptr(n_cat, 1);
+
+        ret_val = xmlUCSIsCat(code, (const char *)cat);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        des_const_char_ptr(n_cat, (const char *)cat, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf(" %d", n_cat);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatC(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatC(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatC",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatCc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatCc(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatCc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatCf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatCf(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatCf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatCo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatCo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatCo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatCs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatCs(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatCs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatL(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatL(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatL",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatLl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatLl(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatLl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatLm(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatLm(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatLm",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatLo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatLo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatLo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatLt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatLt(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatLt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatLu(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatLu(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatLu",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatM(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatM(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatM",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatMc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatMc(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatMc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatMe(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatMe(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatMe",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatMn(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatMn(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatMn",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatN(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatN(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatN",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatNd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatNd(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatNd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatNl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatNl(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatNl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatNo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatNo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatNo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatP(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatP(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatP",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPc(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPd(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPe(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPe(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPe",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPf(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPi(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPi(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPi",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatPs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatPs(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatPs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatS(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatSc(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatSc(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatSc",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatSk(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatSk(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatSk",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatSm(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatSm(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatSm",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatSo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatSo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatSo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatZ(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatZ(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatZ",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatZl(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatZl(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatZl",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatZp(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatZp(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatZp",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCatZs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCatZs(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCatZs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCherokee(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCherokee(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCherokee",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCombiningDiacriticalMarks(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCombiningDiacriticalMarks(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCombiningDiacriticalMarks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCombiningDiacriticalMarksforSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCombiningDiacriticalMarksforSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCombiningDiacriticalMarksforSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCombiningHalfMarks(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCombiningHalfMarks(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCombiningHalfMarks",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCombiningMarksforSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCombiningMarksforSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCombiningMarksforSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsControlPictures(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsControlPictures(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsControlPictures",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCurrencySymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCurrencySymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCurrencySymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCypriotSyllabary(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCypriotSyllabary(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCypriotSyllabary",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCyrillic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCyrillic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCyrillic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsCyrillicSupplement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsCyrillicSupplement(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsCyrillicSupplement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsDeseret(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsDeseret(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsDeseret",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsDevanagari(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsDevanagari(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsDevanagari",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsDingbats(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsDingbats(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsDingbats",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsEnclosedAlphanumerics(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsEnclosedAlphanumerics(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsEnclosedAlphanumerics",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsEnclosedCJKLettersandMonths(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsEnclosedCJKLettersandMonths(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsEnclosedCJKLettersandMonths",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsEthiopic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsEthiopic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsEthiopic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGeneralPunctuation(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGeneralPunctuation(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGeneralPunctuation",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGeometricShapes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGeometricShapes(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGeometricShapes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGeorgian(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGeorgian(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGeorgian",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGothic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGothic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGothic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGreek(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGreek(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGreek",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGreekExtended(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGreekExtended(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGreekExtended",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGreekandCoptic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGreekandCoptic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGreekandCoptic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGujarati(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGujarati(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGujarati",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsGurmukhi(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsGurmukhi(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsGurmukhi",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHalfwidthandFullwidthForms(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHalfwidthandFullwidthForms(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHalfwidthandFullwidthForms",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHangulCompatibilityJamo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHangulCompatibilityJamo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHangulCompatibilityJamo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHangulJamo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHangulJamo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHangulJamo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHangulSyllables(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHangulSyllables(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHangulSyllables",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHanunoo(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHanunoo(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHanunoo",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHebrew(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHebrew(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHebrew",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHighPrivateUseSurrogates(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHighPrivateUseSurrogates(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHighPrivateUseSurrogates",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHighSurrogates(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHighSurrogates(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHighSurrogates",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsHiragana(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsHiragana(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsHiragana",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsIPAExtensions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsIPAExtensions(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsIPAExtensions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsIdeographicDescriptionCharacters(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsIdeographicDescriptionCharacters(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsIdeographicDescriptionCharacters",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKanbun(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKanbun(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKanbun",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKangxiRadicals(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKangxiRadicals(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKangxiRadicals",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKannada(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKannada(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKannada",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKatakana(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKatakana(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKatakana",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKatakanaPhoneticExtensions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKatakanaPhoneticExtensions(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKatakanaPhoneticExtensions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKhmer(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKhmer(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKhmer",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsKhmerSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsKhmerSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsKhmerSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLao(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLao(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLao",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLatin1Supplement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLatin1Supplement(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLatin1Supplement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLatinExtendedA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLatinExtendedA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLatinExtendedA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLatinExtendedAdditional(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLatinExtendedAdditional(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLatinExtendedAdditional",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLatinExtendedB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLatinExtendedB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLatinExtendedB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLetterlikeSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLetterlikeSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLetterlikeSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLimbu(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLimbu(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLimbu",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLinearBIdeograms(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLinearBIdeograms(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLinearBIdeograms",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLinearBSyllabary(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLinearBSyllabary(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLinearBSyllabary",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsLowSurrogates(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsLowSurrogates(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsLowSurrogates",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMalayalam(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMalayalam(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMalayalam",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMathematicalAlphanumericSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMathematicalAlphanumericSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMathematicalAlphanumericSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMathematicalOperators(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMathematicalOperators(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMathematicalOperators",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMiscellaneousMathematicalSymbolsA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMiscellaneousMathematicalSymbolsA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMiscellaneousMathematicalSymbolsA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMiscellaneousMathematicalSymbolsB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMiscellaneousMathematicalSymbolsB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMiscellaneousMathematicalSymbolsB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMiscellaneousSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMiscellaneousSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMiscellaneousSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMiscellaneousSymbolsandArrows(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMiscellaneousSymbolsandArrows(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMiscellaneousSymbolsandArrows",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMiscellaneousTechnical(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMiscellaneousTechnical(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMiscellaneousTechnical",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMongolian(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMongolian(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMongolian",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMusicalSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMusicalSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMusicalSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsMyanmar(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsMyanmar(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsMyanmar",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsNumberForms(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsNumberForms(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsNumberForms",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsOgham(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsOgham(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsOgham",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsOldItalic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsOldItalic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsOldItalic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsOpticalCharacterRecognition(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsOpticalCharacterRecognition(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsOpticalCharacterRecognition",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsOriya(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsOriya(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsOriya",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsOsmanya(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsOsmanya(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsOsmanya",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsPhoneticExtensions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsPhoneticExtensions(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsPhoneticExtensions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsPrivateUse(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsPrivateUse(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsPrivateUse",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsPrivateUseArea(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsPrivateUseArea(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsPrivateUseArea",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsRunic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsRunic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsRunic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsShavian(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsShavian(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsShavian",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSinhala(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSinhala(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSinhala",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSmallFormVariants(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSmallFormVariants(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSmallFormVariants",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSpacingModifierLetters(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSpacingModifierLetters(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSpacingModifierLetters",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSpecials(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSpecials(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSpecials",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSuperscriptsandSubscripts(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSuperscriptsandSubscripts(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSuperscriptsandSubscripts",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSupplementalArrowsA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSupplementalArrowsA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSupplementalArrowsA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSupplementalArrowsB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSupplementalArrowsB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSupplementalArrowsB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSupplementalMathematicalOperators(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSupplementalMathematicalOperators(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSupplementalMathematicalOperators",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSupplementaryPrivateUseAreaA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSupplementaryPrivateUseAreaA(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSupplementaryPrivateUseAreaA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSupplementaryPrivateUseAreaB(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSupplementaryPrivateUseAreaB(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSupplementaryPrivateUseAreaB",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsSyriac(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsSyriac(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsSyriac",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTagalog(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTagalog(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTagalog",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTagbanwa(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTagbanwa(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTagbanwa",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTags(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTags(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTags",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTaiLe(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTaiLe(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTaiLe",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTaiXuanJingSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTaiXuanJingSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTaiXuanJingSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTamil(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTamil(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTamil",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTelugu(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTelugu(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTelugu",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsThaana(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsThaana(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsThaana",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsThai(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsThai(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsThai",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsTibetan(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsTibetan(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsTibetan",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsUgaritic(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsUgaritic(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsUgaritic",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsUnifiedCanadianAboriginalSyllabics(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsUnifiedCanadianAboriginalSyllabics(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsUnifiedCanadianAboriginalSyllabics",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsVariationSelectors(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsVariationSelectors(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsVariationSelectors",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsVariationSelectorsSupplement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsVariationSelectorsSupplement(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsVariationSelectorsSupplement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsYiRadicals(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsYiRadicals(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsYiRadicals",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsYiSyllables(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsYiSyllables(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsYiSyllables",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlUCSIsYijingHexagramSymbols(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_UNICODE_ENABLED)
+    int mem_base;
+    int ret_val;
+    int code; /* UCS code point */
+    int n_code;
+
+    for (n_code = 0;n_code < gen_nb_int;n_code++) {
+        mem_base = xmlMemBlocks();
+        code = gen_int(n_code, 0);
+
+        ret_val = xmlUCSIsYijingHexagramSymbols(code);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_code, code, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlUCSIsYijingHexagramSymbols",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_code);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xmlunicode(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlunicode : 166 of 166 functions ...\n");
+    test_ret += test_xmlUCSIsAegeanNumbers();
+    test_ret += test_xmlUCSIsAlphabeticPresentationForms();
+    test_ret += test_xmlUCSIsArabic();
+    test_ret += test_xmlUCSIsArabicPresentationFormsA();
+    test_ret += test_xmlUCSIsArabicPresentationFormsB();
+    test_ret += test_xmlUCSIsArmenian();
+    test_ret += test_xmlUCSIsArrows();
+    test_ret += test_xmlUCSIsBasicLatin();
+    test_ret += test_xmlUCSIsBengali();
+    test_ret += test_xmlUCSIsBlock();
+    test_ret += test_xmlUCSIsBlockElements();
+    test_ret += test_xmlUCSIsBopomofo();
+    test_ret += test_xmlUCSIsBopomofoExtended();
+    test_ret += test_xmlUCSIsBoxDrawing();
+    test_ret += test_xmlUCSIsBraillePatterns();
+    test_ret += test_xmlUCSIsBuhid();
+    test_ret += test_xmlUCSIsByzantineMusicalSymbols();
+    test_ret += test_xmlUCSIsCJKCompatibility();
+    test_ret += test_xmlUCSIsCJKCompatibilityForms();
+    test_ret += test_xmlUCSIsCJKCompatibilityIdeographs();
+    test_ret += test_xmlUCSIsCJKCompatibilityIdeographsSupplement();
+    test_ret += test_xmlUCSIsCJKRadicalsSupplement();
+    test_ret += test_xmlUCSIsCJKSymbolsandPunctuation();
+    test_ret += test_xmlUCSIsCJKUnifiedIdeographs();
+    test_ret += test_xmlUCSIsCJKUnifiedIdeographsExtensionA();
+    test_ret += test_xmlUCSIsCJKUnifiedIdeographsExtensionB();
+    test_ret += test_xmlUCSIsCat();
+    test_ret += test_xmlUCSIsCatC();
+    test_ret += test_xmlUCSIsCatCc();
+    test_ret += test_xmlUCSIsCatCf();
+    test_ret += test_xmlUCSIsCatCo();
+    test_ret += test_xmlUCSIsCatCs();
+    test_ret += test_xmlUCSIsCatL();
+    test_ret += test_xmlUCSIsCatLl();
+    test_ret += test_xmlUCSIsCatLm();
+    test_ret += test_xmlUCSIsCatLo();
+    test_ret += test_xmlUCSIsCatLt();
+    test_ret += test_xmlUCSIsCatLu();
+    test_ret += test_xmlUCSIsCatM();
+    test_ret += test_xmlUCSIsCatMc();
+    test_ret += test_xmlUCSIsCatMe();
+    test_ret += test_xmlUCSIsCatMn();
+    test_ret += test_xmlUCSIsCatN();
+    test_ret += test_xmlUCSIsCatNd();
+    test_ret += test_xmlUCSIsCatNl();
+    test_ret += test_xmlUCSIsCatNo();
+    test_ret += test_xmlUCSIsCatP();
+    test_ret += test_xmlUCSIsCatPc();
+    test_ret += test_xmlUCSIsCatPd();
+    test_ret += test_xmlUCSIsCatPe();
+    test_ret += test_xmlUCSIsCatPf();
+    test_ret += test_xmlUCSIsCatPi();
+    test_ret += test_xmlUCSIsCatPo();
+    test_ret += test_xmlUCSIsCatPs();
+    test_ret += test_xmlUCSIsCatS();
+    test_ret += test_xmlUCSIsCatSc();
+    test_ret += test_xmlUCSIsCatSk();
+    test_ret += test_xmlUCSIsCatSm();
+    test_ret += test_xmlUCSIsCatSo();
+    test_ret += test_xmlUCSIsCatZ();
+    test_ret += test_xmlUCSIsCatZl();
+    test_ret += test_xmlUCSIsCatZp();
+    test_ret += test_xmlUCSIsCatZs();
+    test_ret += test_xmlUCSIsCherokee();
+    test_ret += test_xmlUCSIsCombiningDiacriticalMarks();
+    test_ret += test_xmlUCSIsCombiningDiacriticalMarksforSymbols();
+    test_ret += test_xmlUCSIsCombiningHalfMarks();
+    test_ret += test_xmlUCSIsCombiningMarksforSymbols();
+    test_ret += test_xmlUCSIsControlPictures();
+    test_ret += test_xmlUCSIsCurrencySymbols();
+    test_ret += test_xmlUCSIsCypriotSyllabary();
+    test_ret += test_xmlUCSIsCyrillic();
+    test_ret += test_xmlUCSIsCyrillicSupplement();
+    test_ret += test_xmlUCSIsDeseret();
+    test_ret += test_xmlUCSIsDevanagari();
+    test_ret += test_xmlUCSIsDingbats();
+    test_ret += test_xmlUCSIsEnclosedAlphanumerics();
+    test_ret += test_xmlUCSIsEnclosedCJKLettersandMonths();
+    test_ret += test_xmlUCSIsEthiopic();
+    test_ret += test_xmlUCSIsGeneralPunctuation();
+    test_ret += test_xmlUCSIsGeometricShapes();
+    test_ret += test_xmlUCSIsGeorgian();
+    test_ret += test_xmlUCSIsGothic();
+    test_ret += test_xmlUCSIsGreek();
+    test_ret += test_xmlUCSIsGreekExtended();
+    test_ret += test_xmlUCSIsGreekandCoptic();
+    test_ret += test_xmlUCSIsGujarati();
+    test_ret += test_xmlUCSIsGurmukhi();
+    test_ret += test_xmlUCSIsHalfwidthandFullwidthForms();
+    test_ret += test_xmlUCSIsHangulCompatibilityJamo();
+    test_ret += test_xmlUCSIsHangulJamo();
+    test_ret += test_xmlUCSIsHangulSyllables();
+    test_ret += test_xmlUCSIsHanunoo();
+    test_ret += test_xmlUCSIsHebrew();
+    test_ret += test_xmlUCSIsHighPrivateUseSurrogates();
+    test_ret += test_xmlUCSIsHighSurrogates();
+    test_ret += test_xmlUCSIsHiragana();
+    test_ret += test_xmlUCSIsIPAExtensions();
+    test_ret += test_xmlUCSIsIdeographicDescriptionCharacters();
+    test_ret += test_xmlUCSIsKanbun();
+    test_ret += test_xmlUCSIsKangxiRadicals();
+    test_ret += test_xmlUCSIsKannada();
+    test_ret += test_xmlUCSIsKatakana();
+    test_ret += test_xmlUCSIsKatakanaPhoneticExtensions();
+    test_ret += test_xmlUCSIsKhmer();
+    test_ret += test_xmlUCSIsKhmerSymbols();
+    test_ret += test_xmlUCSIsLao();
+    test_ret += test_xmlUCSIsLatin1Supplement();
+    test_ret += test_xmlUCSIsLatinExtendedA();
+    test_ret += test_xmlUCSIsLatinExtendedAdditional();
+    test_ret += test_xmlUCSIsLatinExtendedB();
+    test_ret += test_xmlUCSIsLetterlikeSymbols();
+    test_ret += test_xmlUCSIsLimbu();
+    test_ret += test_xmlUCSIsLinearBIdeograms();
+    test_ret += test_xmlUCSIsLinearBSyllabary();
+    test_ret += test_xmlUCSIsLowSurrogates();
+    test_ret += test_xmlUCSIsMalayalam();
+    test_ret += test_xmlUCSIsMathematicalAlphanumericSymbols();
+    test_ret += test_xmlUCSIsMathematicalOperators();
+    test_ret += test_xmlUCSIsMiscellaneousMathematicalSymbolsA();
+    test_ret += test_xmlUCSIsMiscellaneousMathematicalSymbolsB();
+    test_ret += test_xmlUCSIsMiscellaneousSymbols();
+    test_ret += test_xmlUCSIsMiscellaneousSymbolsandArrows();
+    test_ret += test_xmlUCSIsMiscellaneousTechnical();
+    test_ret += test_xmlUCSIsMongolian();
+    test_ret += test_xmlUCSIsMusicalSymbols();
+    test_ret += test_xmlUCSIsMyanmar();
+    test_ret += test_xmlUCSIsNumberForms();
+    test_ret += test_xmlUCSIsOgham();
+    test_ret += test_xmlUCSIsOldItalic();
+    test_ret += test_xmlUCSIsOpticalCharacterRecognition();
+    test_ret += test_xmlUCSIsOriya();
+    test_ret += test_xmlUCSIsOsmanya();
+    test_ret += test_xmlUCSIsPhoneticExtensions();
+    test_ret += test_xmlUCSIsPrivateUse();
+    test_ret += test_xmlUCSIsPrivateUseArea();
+    test_ret += test_xmlUCSIsRunic();
+    test_ret += test_xmlUCSIsShavian();
+    test_ret += test_xmlUCSIsSinhala();
+    test_ret += test_xmlUCSIsSmallFormVariants();
+    test_ret += test_xmlUCSIsSpacingModifierLetters();
+    test_ret += test_xmlUCSIsSpecials();
+    test_ret += test_xmlUCSIsSuperscriptsandSubscripts();
+    test_ret += test_xmlUCSIsSupplementalArrowsA();
+    test_ret += test_xmlUCSIsSupplementalArrowsB();
+    test_ret += test_xmlUCSIsSupplementalMathematicalOperators();
+    test_ret += test_xmlUCSIsSupplementaryPrivateUseAreaA();
+    test_ret += test_xmlUCSIsSupplementaryPrivateUseAreaB();
+    test_ret += test_xmlUCSIsSyriac();
+    test_ret += test_xmlUCSIsTagalog();
+    test_ret += test_xmlUCSIsTagbanwa();
+    test_ret += test_xmlUCSIsTags();
+    test_ret += test_xmlUCSIsTaiLe();
+    test_ret += test_xmlUCSIsTaiXuanJingSymbols();
+    test_ret += test_xmlUCSIsTamil();
+    test_ret += test_xmlUCSIsTelugu();
+    test_ret += test_xmlUCSIsThaana();
+    test_ret += test_xmlUCSIsThai();
+    test_ret += test_xmlUCSIsTibetan();
+    test_ret += test_xmlUCSIsUgaritic();
+    test_ret += test_xmlUCSIsUnifiedCanadianAboriginalSyllabics();
+    test_ret += test_xmlUCSIsVariationSelectors();
+    test_ret += test_xmlUCSIsVariationSelectorsSupplement();
+    test_ret += test_xmlUCSIsYiRadicals();
+    test_ret += test_xmlUCSIsYiSyllables();
+    test_ret += test_xmlUCSIsYijingHexagramSymbols();
+
+    if (test_ret != 0)
+	printf("Module xmlunicode: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlNewTextWriter(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlTextWriterPtr ret_val;
+    xmlOutputBufferPtr out; /* an xmlOutputBufferPtr */
+    int n_out;
+
+    for (n_out = 0;n_out < gen_nb_xmlOutputBufferPtr;n_out++) {
+        mem_base = xmlMemBlocks();
+        out = gen_xmlOutputBufferPtr(n_out, 0);
+
+        ret_val = xmlNewTextWriter(out);
+        if (ret_val != NULL) out = NULL;
+        desret_xmlTextWriterPtr(ret_val);
+        call_tests++;
+        des_xmlOutputBufferPtr(n_out, out, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextWriter",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_out);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextWriterFilename(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlTextWriterPtr ret_val;
+    const char * uri; /* the URI of the resource for the output */
+    int n_uri;
+    int compression; /* compress the output? */
+    int n_compression;
+
+    for (n_uri = 0;n_uri < gen_nb_fileoutput;n_uri++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        uri = gen_fileoutput(n_uri, 0);
+        compression = gen_int(n_compression, 1);
+
+        ret_val = xmlNewTextWriterFilename(uri, compression);
+        desret_xmlTextWriterPtr(ret_val);
+        call_tests++;
+        des_fileoutput(n_uri, uri, 0);
+        des_int(n_compression, compression, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextWriterFilename",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_uri);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextWriterMemory(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlTextWriterPtr ret_val;
+    xmlBufferPtr buf; /* xmlBufferPtr */
+    int n_buf;
+    int compression; /* compress the output? */
+    int n_compression;
+
+    for (n_buf = 0;n_buf < gen_nb_xmlBufferPtr;n_buf++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        buf = gen_xmlBufferPtr(n_buf, 0);
+        compression = gen_int(n_compression, 1);
+
+        ret_val = xmlNewTextWriterMemory(buf, compression);
+        desret_xmlTextWriterPtr(ret_val);
+        call_tests++;
+        des_xmlBufferPtr(n_buf, buf, 0);
+        des_int(n_compression, compression, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextWriterMemory",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_buf);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextWriterPushParser(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlTextWriterPtr ret_val;
+    xmlParserCtxtPtr ctxt; /* xmlParserCtxtPtr to hold the new XML document tree */
+    int n_ctxt;
+    int compression; /* compress the output? */
+    int n_compression;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
+        compression = gen_int(n_compression, 1);
+
+        ret_val = xmlNewTextWriterPushParser(ctxt, compression);
+        if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;
+        desret_xmlTextWriterPtr(ret_val);
+        call_tests++;
+        des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
+        des_int(n_compression, compression, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextWriterPushParser",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlNewTextWriterTree(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    xmlTextWriterPtr ret_val;
+    xmlDocPtr doc; /* xmlDocPtr */
+    int n_doc;
+    xmlNodePtr node; /* xmlNodePtr or NULL for doc->children */
+    int n_node;
+    int compression; /* compress the output? */
+    int n_compression;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_compression = 0;n_compression < gen_nb_int;n_compression++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        compression = gen_int(n_compression, 2);
+
+        ret_val = xmlNewTextWriterTree(doc, node, compression);
+        desret_xmlTextWriterPtr(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_int(n_compression, compression, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewTextWriterTree",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf(" %d", n_node);
+            printf(" %d", n_compression);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndAttribute(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndCDATA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndCDATA(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndCDATA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndComment(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndComment(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndComment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndDTD(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndDTDAttlist(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndDTDAttlist(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndDTDAttlist",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndDTDElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndDTDElement(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndDTDElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndDTDEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndDTDEntity(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndDTDEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndDocument(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndElement(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterEndPI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterEndPI(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterEndPI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterFlush(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterFlush(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterFlush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterFullEndElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterFullEndElement(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterFullEndElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterSetIndent(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    int indent; /* do indentation? */
+    int n_indent;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_indent = 0;n_indent < gen_nb_int;n_indent++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        indent = gen_int(n_indent, 1);
+
+        ret_val = xmlTextWriterSetIndent(writer, indent);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_int(n_indent, indent, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterSetIndent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_indent);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterSetIndentString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * str; /* the xmlChar string */
+    int n_str;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        str = gen_const_xmlChar_ptr(n_str, 1);
+
+        ret_val = xmlTextWriterSetIndentString(writer, (const xmlChar *)str);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterSetIndentString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* element name */
+    int n_name;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextWriterStartAttribute(writer, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartAttributeNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * prefix; /* namespace prefix or NULL */
+    int n_prefix;
+    xmlChar * name; /* element local name */
+    int n_name;
+    xmlChar * namespaceURI; /* namespace URI or NULL */
+    int n_namespaceURI;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
+
+        ret_val = xmlTextWriterStartAttributeNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartAttributeNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_namespaceURI);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartCDATA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterStartCDATA(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartCDATA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartComment(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+
+        ret_val = xmlTextWriterStartComment(writer);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartComment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD */
+    int n_name;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 2);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 3);
+
+        ret_val = xmlTextWriterStartDTD(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartDTDAttlist(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD ATTLIST */
+    int n_name;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextWriterStartDTDAttlist(writer, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartDTDAttlist",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartDTDElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD element */
+    int n_name;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextWriterStartDTDElement(writer, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartDTDElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartDTDEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    int pe; /* TRUE if this is a parameter entity, FALSE if not */
+    int n_pe;
+    xmlChar * name; /* the name of the DTD ATTLIST */
+    int n_name;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_pe = 0;n_pe < gen_nb_int;n_pe++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        pe = gen_int(n_pe, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+
+        ret_val = xmlTextWriterStartDTDEntity(writer, pe, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_int(n_pe, pe, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartDTDEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_pe);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartDocument(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    char * version; /* the xml version ("1.0") or NULL for default ("1.0") */
+    int n_version;
+    char * encoding; /* the encoding or NULL for default */
+    int n_encoding;
+    char * standalone; /* "yes" or "no" or NULL for default */
+    int n_standalone;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_version = 0;n_version < gen_nb_const_char_ptr;n_version++) {
+    for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
+    for (n_standalone = 0;n_standalone < gen_nb_const_char_ptr;n_standalone++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        version = gen_const_char_ptr(n_version, 1);
+        encoding = gen_const_char_ptr(n_encoding, 2);
+        standalone = gen_const_char_ptr(n_standalone, 3);
+
+        ret_val = xmlTextWriterStartDocument(writer, (const char *)version, (const char *)encoding, (const char *)standalone);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_char_ptr(n_version, (const char *)version, 1);
+        des_const_char_ptr(n_encoding, (const char *)encoding, 2);
+        des_const_char_ptr(n_standalone, (const char *)standalone, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartDocument",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_version);
+            printf(" %d", n_encoding);
+            printf(" %d", n_standalone);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* element name */
+    int n_name;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlTextWriterStartElement(writer, (const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartElementNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * prefix; /* namespace prefix or NULL */
+    int n_prefix;
+    xmlChar * name; /* element local name */
+    int n_name;
+    xmlChar * namespaceURI; /* namespace URI or NULL */
+    int n_namespaceURI;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
+
+        ret_val = xmlTextWriterStartElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartElementNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_namespaceURI);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterStartPI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * target; /* PI target */
+    int n_target;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_target = 0;n_target < gen_nb_const_xmlChar_ptr;n_target++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        target = gen_const_xmlChar_ptr(n_target, 1);
+
+        ret_val = xmlTextWriterStartPI(writer, (const xmlChar *)target);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterStartPI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_target);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* attribute name */
+    int n_name;
+    xmlChar * content; /* attribute content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlTextWriterWriteAttribute(writer, (const xmlChar *)name, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteAttributeNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * prefix; /* namespace prefix */
+    int n_prefix;
+    xmlChar * name; /* attribute local name */
+    int n_name;
+    xmlChar * namespaceURI; /* namespace URI */
+    int n_namespaceURI;
+    xmlChar * content; /* attribute content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
+        content = gen_const_xmlChar_ptr(n_content, 4);
+
+        ret_val = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteAttributeNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_namespaceURI);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteBase64(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    char * data; /* binary data */
+    int n_data;
+    int start; /* the position within the data of the first byte to encode */
+    int n_start;
+    int len; /* the number of bytes to encode */
+    int n_len;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_data = 0;n_data < gen_nb_const_char_ptr;n_data++) {
+    for (n_start = 0;n_start < gen_nb_int;n_start++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        data = gen_const_char_ptr(n_data, 1);
+        start = gen_int(n_start, 2);
+        len = gen_int(n_len, 3);
+
+        ret_val = xmlTextWriterWriteBase64(writer, (const char *)data, start, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_char_ptr(n_data, (const char *)data, 1);
+        des_int(n_start, start, 2);
+        des_int(n_len, len, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteBase64",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_data);
+            printf(" %d", n_start);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteBinHex(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    char * data; /* binary data */
+    int n_data;
+    int start; /* the position within the data of the first byte to encode */
+    int n_start;
+    int len; /* the number of bytes to encode */
+    int n_len;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_data = 0;n_data < gen_nb_const_char_ptr;n_data++) {
+    for (n_start = 0;n_start < gen_nb_int;n_start++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        data = gen_const_char_ptr(n_data, 1);
+        start = gen_int(n_start, 2);
+        len = gen_int(n_len, 3);
+
+        ret_val = xmlTextWriterWriteBinHex(writer, (const char *)data, start, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_char_ptr(n_data, (const char *)data, 1);
+        des_int(n_start, start, 2);
+        des_int(n_len, len, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteBinHex",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_data);
+            printf(" %d", n_start);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteCDATA(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * content; /* CDATA content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlTextWriterWriteCDATA(writer, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteCDATA",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteComment(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * content; /* comment string */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlTextWriterWriteComment(writer, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteComment",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTD(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD */
+    int n_name;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+    xmlChar * subset; /* string content of the DTD */
+    int n_subset;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+    for (n_subset = 0;n_subset < gen_nb_const_xmlChar_ptr;n_subset++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 2);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 3);
+        subset = gen_const_xmlChar_ptr(n_subset, 4);
+
+        ret_val = xmlTextWriterWriteDTD(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)subset);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
+        des_const_xmlChar_ptr(n_subset, (const xmlChar *)subset, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTD",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf(" %d", n_subset);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDAttlist(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD ATTLIST */
+    int n_name;
+    xmlChar * content; /* content of the ATTLIST */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlTextWriterWriteDTDAttlist(writer, (const xmlChar *)name, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDAttlist",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the DTD element */
+    int n_name;
+    xmlChar * content; /* content of the element */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlTextWriterWriteDTDElement(writer, (const xmlChar *)name, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    int pe; /* TRUE if this is a parameter entity, FALSE if not */
+    int n_pe;
+    xmlChar * name; /* the name of the DTD entity */
+    int n_name;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+    xmlChar * ndataid; /* the xml notation name. */
+    int n_ndataid;
+    xmlChar * content; /* content of the entity */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_pe = 0;n_pe < gen_nb_int;n_pe++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+    for (n_ndataid = 0;n_ndataid < gen_nb_const_xmlChar_ptr;n_ndataid++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        pe = gen_int(n_pe, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 3);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 4);
+        ndataid = gen_const_xmlChar_ptr(n_ndataid, 5);
+        content = gen_const_xmlChar_ptr(n_content, 6);
+
+        ret_val = xmlTextWriterWriteDTDEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_int(n_pe, pe, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 3);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 4);
+        des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 5);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 6);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_pe);
+            printf(" %d", n_name);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf(" %d", n_ndataid);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDExternalEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    int pe; /* TRUE if this is a parameter entity, FALSE if not */
+    int n_pe;
+    xmlChar * name; /* the name of the DTD entity */
+    int n_name;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+    xmlChar * ndataid; /* the xml notation name. */
+    int n_ndataid;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_pe = 0;n_pe < gen_nb_int;n_pe++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+    for (n_ndataid = 0;n_ndataid < gen_nb_const_xmlChar_ptr;n_ndataid++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        pe = gen_int(n_pe, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 3);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 4);
+        ndataid = gen_const_xmlChar_ptr(n_ndataid, 5);
+
+        ret_val = xmlTextWriterWriteDTDExternalEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_int(n_pe, pe, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 3);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 4);
+        des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 5);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDExternalEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_pe);
+            printf(" %d", n_name);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf(" %d", n_ndataid);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDExternalEntityContents(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+    xmlChar * ndataid; /* the xml notation name. */
+    int n_ndataid;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+    for (n_ndataid = 0;n_ndataid < gen_nb_const_xmlChar_ptr;n_ndataid++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 1);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 2);
+        ndataid = gen_const_xmlChar_ptr(n_ndataid, 3);
+
+        ret_val = xmlTextWriterWriteDTDExternalEntityContents(writer, (const xmlChar *)pubid, (const xmlChar *)sysid, (const xmlChar *)ndataid);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 1);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 2);
+        des_const_xmlChar_ptr(n_ndataid, (const xmlChar *)ndataid, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDExternalEntityContents",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf(" %d", n_ndataid);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDInternalEntity(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    int pe; /* TRUE if this is a parameter entity, FALSE if not */
+    int n_pe;
+    xmlChar * name; /* the name of the DTD entity */
+    int n_name;
+    xmlChar * content; /* content of the entity */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_pe = 0;n_pe < gen_nb_int;n_pe++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        pe = gen_int(n_pe, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        content = gen_const_xmlChar_ptr(n_content, 3);
+
+        ret_val = xmlTextWriterWriteDTDInternalEntity(writer, pe, (const xmlChar *)name, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_int(n_pe, pe, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDInternalEntity",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_pe);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteDTDNotation(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* the name of the xml notation */
+    int n_name;
+    xmlChar * pubid; /* the public identifier, which is an alternative to the system identifier */
+    int n_pubid;
+    xmlChar * sysid; /* the system identifier, which is the URI of the DTD */
+    int n_sysid;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_pubid = 0;n_pubid < gen_nb_const_xmlChar_ptr;n_pubid++) {
+    for (n_sysid = 0;n_sysid < gen_nb_const_xmlChar_ptr;n_sysid++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        pubid = gen_const_xmlChar_ptr(n_pubid, 2);
+        sysid = gen_const_xmlChar_ptr(n_sysid, 3);
+
+        ret_val = xmlTextWriterWriteDTDNotation(writer, (const xmlChar *)name, (const xmlChar *)pubid, (const xmlChar *)sysid);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_pubid, (const xmlChar *)pubid, 2);
+        des_const_xmlChar_ptr(n_sysid, (const xmlChar *)sysid, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteDTDNotation",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_pubid);
+            printf(" %d", n_sysid);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteElement(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * name; /* element name */
+    int n_name;
+    xmlChar * content; /* element content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlTextWriterWriteElement(writer, (const xmlChar *)name, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteElement",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_name);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteElementNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * prefix; /* namespace prefix */
+    int n_prefix;
+    xmlChar * name; /* element local name */
+    int n_name;
+    xmlChar * namespaceURI; /* namespace URI */
+    int n_namespaceURI;
+    xmlChar * content; /* element content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_namespaceURI = 0;n_namespaceURI < gen_nb_const_xmlChar_ptr;n_namespaceURI++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        name = gen_const_xmlChar_ptr(n_name, 2);
+        namespaceURI = gen_const_xmlChar_ptr(n_namespaceURI, 3);
+        content = gen_const_xmlChar_ptr(n_content, 4);
+
+        ret_val = xmlTextWriterWriteElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)namespaceURI, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
+        des_const_xmlChar_ptr(n_namespaceURI, (const xmlChar *)namespaceURI, 3);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 4);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteElementNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_prefix);
+            printf(" %d", n_name);
+            printf(" %d", n_namespaceURI);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatAttribute(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatAttributeNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatCDATA(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatComment(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatDTD(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatDTDAttlist(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatDTDElement(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatDTDInternalEntity(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatElement(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatElementNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatPI(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatRaw(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteFormatString(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWritePI(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * target; /* PI target */
+    int n_target;
+    xmlChar * content; /* PI content */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_target = 0;n_target < gen_nb_const_xmlChar_ptr;n_target++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        target = gen_const_xmlChar_ptr(n_target, 1);
+        content = gen_const_xmlChar_ptr(n_content, 2);
+
+        ret_val = xmlTextWriterWritePI(writer, (const xmlChar *)target, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_target, (const xmlChar *)target, 1);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWritePI",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_target);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteRaw(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * content; /* text string */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlTextWriterWriteRaw(writer, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteRaw",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteRawLen(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * content; /* text string */
+    int n_content;
+    int len; /* length of the text string */
+    int n_len;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+    for (n_len = 0;n_len < gen_nb_int;n_len++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+        len = gen_int(n_len, 2);
+
+        ret_val = xmlTextWriterWriteRawLen(writer, (const xmlChar *)content, len);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        des_int(n_len, len, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteRawLen",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_content);
+            printf(" %d", n_len);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_WRITER_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlTextWriterPtr writer; /* the xmlTextWriterPtr */
+    int n_writer;
+    xmlChar * content; /* text string */
+    int n_content;
+
+    for (n_writer = 0;n_writer < gen_nb_xmlTextWriterPtr;n_writer++) {
+    for (n_content = 0;n_content < gen_nb_const_xmlChar_ptr;n_content++) {
+        mem_base = xmlMemBlocks();
+        writer = gen_xmlTextWriterPtr(n_writer, 0);
+        content = gen_const_xmlChar_ptr(n_content, 1);
+
+        ret_val = xmlTextWriterWriteString(writer, (const xmlChar *)content);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlTextWriterPtr(n_writer, writer, 0);
+        des_const_xmlChar_ptr(n_content, (const xmlChar *)content, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlTextWriterWriteString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_writer);
+            printf(" %d", n_content);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatAttribute(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatAttributeNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatCDATA(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatComment(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatDTD(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatDTDAttlist(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatDTDElement(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatDTDInternalEntity(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatElement(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatElementNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatPI(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatRaw(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlTextWriterWriteVFormatString(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+static int
+test_xmlwriter(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xmlwriter : 51 of 79 functions ...\n");
+    test_ret += test_xmlNewTextWriter();
+    test_ret += test_xmlNewTextWriterFilename();
+    test_ret += test_xmlNewTextWriterMemory();
+    test_ret += test_xmlNewTextWriterPushParser();
+    test_ret += test_xmlNewTextWriterTree();
+    test_ret += test_xmlTextWriterEndAttribute();
+    test_ret += test_xmlTextWriterEndCDATA();
+    test_ret += test_xmlTextWriterEndComment();
+    test_ret += test_xmlTextWriterEndDTD();
+    test_ret += test_xmlTextWriterEndDTDAttlist();
+    test_ret += test_xmlTextWriterEndDTDElement();
+    test_ret += test_xmlTextWriterEndDTDEntity();
+    test_ret += test_xmlTextWriterEndDocument();
+    test_ret += test_xmlTextWriterEndElement();
+    test_ret += test_xmlTextWriterEndPI();
+    test_ret += test_xmlTextWriterFlush();
+    test_ret += test_xmlTextWriterFullEndElement();
+    test_ret += test_xmlTextWriterSetIndent();
+    test_ret += test_xmlTextWriterSetIndentString();
+    test_ret += test_xmlTextWriterStartAttribute();
+    test_ret += test_xmlTextWriterStartAttributeNS();
+    test_ret += test_xmlTextWriterStartCDATA();
+    test_ret += test_xmlTextWriterStartComment();
+    test_ret += test_xmlTextWriterStartDTD();
+    test_ret += test_xmlTextWriterStartDTDAttlist();
+    test_ret += test_xmlTextWriterStartDTDElement();
+    test_ret += test_xmlTextWriterStartDTDEntity();
+    test_ret += test_xmlTextWriterStartDocument();
+    test_ret += test_xmlTextWriterStartElement();
+    test_ret += test_xmlTextWriterStartElementNS();
+    test_ret += test_xmlTextWriterStartPI();
+    test_ret += test_xmlTextWriterWriteAttribute();
+    test_ret += test_xmlTextWriterWriteAttributeNS();
+    test_ret += test_xmlTextWriterWriteBase64();
+    test_ret += test_xmlTextWriterWriteBinHex();
+    test_ret += test_xmlTextWriterWriteCDATA();
+    test_ret += test_xmlTextWriterWriteComment();
+    test_ret += test_xmlTextWriterWriteDTD();
+    test_ret += test_xmlTextWriterWriteDTDAttlist();
+    test_ret += test_xmlTextWriterWriteDTDElement();
+    test_ret += test_xmlTextWriterWriteDTDEntity();
+    test_ret += test_xmlTextWriterWriteDTDExternalEntity();
+    test_ret += test_xmlTextWriterWriteDTDExternalEntityContents();
+    test_ret += test_xmlTextWriterWriteDTDInternalEntity();
+    test_ret += test_xmlTextWriterWriteDTDNotation();
+    test_ret += test_xmlTextWriterWriteElement();
+    test_ret += test_xmlTextWriterWriteElementNS();
+    test_ret += test_xmlTextWriterWriteFormatAttribute();
+    test_ret += test_xmlTextWriterWriteFormatAttributeNS();
+    test_ret += test_xmlTextWriterWriteFormatCDATA();
+    test_ret += test_xmlTextWriterWriteFormatComment();
+    test_ret += test_xmlTextWriterWriteFormatDTD();
+    test_ret += test_xmlTextWriterWriteFormatDTDAttlist();
+    test_ret += test_xmlTextWriterWriteFormatDTDElement();
+    test_ret += test_xmlTextWriterWriteFormatDTDInternalEntity();
+    test_ret += test_xmlTextWriterWriteFormatElement();
+    test_ret += test_xmlTextWriterWriteFormatElementNS();
+    test_ret += test_xmlTextWriterWriteFormatPI();
+    test_ret += test_xmlTextWriterWriteFormatRaw();
+    test_ret += test_xmlTextWriterWriteFormatString();
+    test_ret += test_xmlTextWriterWritePI();
+    test_ret += test_xmlTextWriterWriteRaw();
+    test_ret += test_xmlTextWriterWriteRawLen();
+    test_ret += test_xmlTextWriterWriteString();
+    test_ret += test_xmlTextWriterWriteVFormatAttribute();
+    test_ret += test_xmlTextWriterWriteVFormatAttributeNS();
+    test_ret += test_xmlTextWriterWriteVFormatCDATA();
+    test_ret += test_xmlTextWriterWriteVFormatComment();
+    test_ret += test_xmlTextWriterWriteVFormatDTD();
+    test_ret += test_xmlTextWriterWriteVFormatDTDAttlist();
+    test_ret += test_xmlTextWriterWriteVFormatDTDElement();
+    test_ret += test_xmlTextWriterWriteVFormatDTDInternalEntity();
+    test_ret += test_xmlTextWriterWriteVFormatElement();
+    test_ret += test_xmlTextWriterWriteVFormatElementNS();
+    test_ret += test_xmlTextWriterWriteVFormatPI();
+    test_ret += test_xmlTextWriterWriteVFormatRaw();
+    test_ret += test_xmlTextWriterWriteVFormatString();
+
+    if (test_ret != 0)
+	printf("Module xmlwriter: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlXPathCastBooleanToNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    int val; /* a boolean */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlXPathCastBooleanToNumber(val);
+        desret_double(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastBooleanToNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastBooleanToString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    int val; /* a boolean */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlXPathCastBooleanToString(val);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastBooleanToString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNodeSetToBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodeSetPtr ns; /* a node-set */
+    int n_ns;
+
+    for (n_ns = 0;n_ns < gen_nb_xmlNodeSetPtr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        ns = gen_xmlNodeSetPtr(n_ns, 0);
+
+        ret_val = xmlXPathCastNodeSetToBoolean(ns);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_ns, ns, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNodeSetToBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNodeSetToNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlNodeSetPtr ns; /* a node-set */
+    int n_ns;
+
+    for (n_ns = 0;n_ns < gen_nb_xmlNodeSetPtr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        ns = gen_xmlNodeSetPtr(n_ns, 0);
+
+        ret_val = xmlXPathCastNodeSetToNumber(ns);
+        desret_double(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_ns, ns, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNodeSetToNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNodeSetToString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodeSetPtr ns; /* a node-set */
+    int n_ns;
+
+    for (n_ns = 0;n_ns < gen_nb_xmlNodeSetPtr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        ns = gen_xmlNodeSetPtr(n_ns, 0);
+
+        ret_val = xmlXPathCastNodeSetToString(ns);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_ns, ns, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNodeSetToString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNodeToNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlXPathCastNodeToNumber(node);
+        desret_double(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNodeToNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNodeToString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        node = gen_xmlNodePtr(n_node, 0);
+
+        ret_val = xmlXPathCastNodeToString(node);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node, node, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNodeToString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNumberToBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    double val; /* a number */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_double;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_double(n_val, 0);
+
+        ret_val = xmlXPathCastNumberToBoolean(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_double(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNumberToBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastNumberToString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    double val; /* a number */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_double;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_double(n_val, 0);
+
+        ret_val = xmlXPathCastNumberToString(val);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_double(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastNumberToString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastStringToBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * val; /* a string */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_const_xmlChar_ptr(n_val, 0);
+
+        ret_val = xmlXPathCastStringToBoolean((const xmlChar *)val);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastStringToBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastStringToNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlChar * val; /* a string */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_const_xmlChar_ptr(n_val, 0);
+
+        ret_val = xmlXPathCastStringToNumber((const xmlChar *)val);
+        desret_double(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastStringToNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastToBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathCastToBoolean(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastToBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastToNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathCastToNumber(val);
+        desret_double(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastToNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCastToString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathCastToString(val);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCastToString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCmpNodes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodePtr node1; /* the first node */
+    int n_node1;
+    xmlNodePtr node2; /* the second node */
+    int n_node2;
+
+    for (n_node1 = 0;n_node1 < gen_nb_xmlNodePtr;n_node1++) {
+    for (n_node2 = 0;n_node2 < gen_nb_xmlNodePtr;n_node2++) {
+        mem_base = xmlMemBlocks();
+        node1 = gen_xmlNodePtr(n_node1, 0);
+        node2 = gen_xmlNodePtr(n_node2, 1);
+
+        ret_val = xmlXPathCmpNodes(node1, node2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_node1, node1, 0);
+        des_xmlNodePtr(n_node2, node2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCmpNodes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_node1);
+            printf(" %d", n_node2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCompile(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#define gen_nb_xmlXPathCompExprPtr 1
+static xmlXPathCompExprPtr gen_xmlXPathCompExprPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlXPathCompExprPtr(int no ATTRIBUTE_UNUSED, xmlXPathCompExprPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#define gen_nb_xmlXPathContextPtr 1
+static xmlXPathContextPtr gen_xmlXPathContextPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlXPathContextPtr(int no ATTRIBUTE_UNUSED, xmlXPathContextPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlXPathCompiledEval(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathCompExprPtr comp; /* the compiled XPath expression */
+    int n_comp;
+    xmlXPathContextPtr ctx; /* the XPath context */
+    int n_ctx;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlXPathCompExprPtr;n_comp++) {
+    for (n_ctx = 0;n_ctx < gen_nb_xmlXPathContextPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlXPathCompExprPtr(n_comp, 0);
+        ctx = gen_xmlXPathContextPtr(n_ctx, 1);
+
+        ret_val = xmlXPathCompiledEval(comp, ctx);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathCompExprPtr(n_comp, comp, 0);
+        des_xmlXPathContextPtr(n_ctx, ctx, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCompiledEval",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCompiledEvalToBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathCompExprPtr comp; /* the compiled XPath expression */
+    int n_comp;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_comp = 0;n_comp < gen_nb_xmlXPathCompExprPtr;n_comp++) {
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        comp = gen_xmlXPathCompExprPtr(n_comp, 0);
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 1);
+
+        ret_val = xmlXPathCompiledEvalToBoolean(comp, ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathCompExprPtr(n_comp, comp, 0);
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCompiledEvalToBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_comp);
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathContextSetCache(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    int active; /* enables/disables (creates/frees) the cache */
+    int n_active;
+    int value; /* a value with semantics dependant on @options */
+    int n_value;
+    int options; /* options (currently only the value 0 is used) */
+    int n_options;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_active = 0;n_active < gen_nb_int;n_active++) {
+    for (n_value = 0;n_value < gen_nb_int;n_value++) {
+    for (n_options = 0;n_options < gen_nb_int;n_options++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        active = gen_int(n_active, 1);
+        value = gen_int(n_value, 2);
+        options = gen_int(n_options, 3);
+
+        ret_val = xmlXPathContextSetCache(ctxt, active, value, options);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_active, active, 1);
+        des_int(n_value, value, 2);
+        des_int(n_options, options, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathContextSetCache",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_active);
+            printf(" %d", n_value);
+            printf(" %d", n_options);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathConvertBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathConvertBoolean(val);
+        val = NULL;
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathConvertBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathConvertNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathConvertNumber(val);
+        val = NULL;
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathConvertNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathConvertString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr val; /* an XPath object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathConvertString(val);
+        val = NULL;
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathConvertString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCtxtCompile(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEval(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlChar * str; /* the XPath expression */
+    int n_str;
+    xmlXPathContextPtr ctx; /* the XPath context */
+    int n_ctx;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_ctx = 0;n_ctx < gen_nb_xmlXPathContextPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        ctx = gen_xmlXPathContextPtr(n_ctx, 1);
+
+        ret_val = xmlXPathEval((const xmlChar *)str, ctx);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_xmlXPathContextPtr(n_ctx, ctx, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEval",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEvalExpression(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlChar * str; /* the XPath expression */
+    int n_str;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 1);
+
+        ret_val = xmlXPathEvalExpression((const xmlChar *)str, ctxt);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEvalExpression",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEvalPredicate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlXPathObjectPtr res; /* the Predicate Expression evaluation result */
+    int n_res;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_res = 0;n_res < gen_nb_xmlXPathObjectPtr;n_res++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        res = gen_xmlXPathObjectPtr(n_res, 1);
+
+        ret_val = xmlXPathEvalPredicate(ctxt, res);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_xmlXPathObjectPtr(n_res, res, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEvalPredicate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_res);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathInit(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+
+        mem_base = xmlMemBlocks();
+
+        xmlXPathInit();
+        call_tests++;
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathInit",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf("\n");
+        }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathIsInf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    double val; /* a double value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_double;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_double(n_val, 0);
+
+        ret_val = xmlXPathIsInf(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_double(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathIsInf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathIsNaN(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+    int mem_base;
+    int ret_val;
+    double val; /* a double value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_double;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_double(n_val, 0);
+
+        ret_val = xmlXPathIsNaN(val);
+        desret_int(ret_val);
+        call_tests++;
+        des_double(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathIsNaN",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewContext(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetCreate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodePtr val; /* an initial xmlNodePtr, or NULL */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlNodePtr(n_val, 0);
+
+        ret_val = xmlXPathNodeSetCreate(val);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetCreate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathObjectCopy(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr val; /* the original object */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlXPathObjectPtr(n_val, 0);
+
+        ret_val = xmlXPathObjectCopy(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathObjectCopy",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathOrderDocElems(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    long ret_val;
+    xmlDocPtr doc; /* an input document */
+    int n_doc;
+
+    for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
+        mem_base = xmlMemBlocks();
+        doc = gen_xmlDocPtr(n_doc, 0);
+
+        ret_val = xmlXPathOrderDocElems(doc);
+        desret_long(ret_val);
+        call_tests++;
+        des_xmlDocPtr(n_doc, doc, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathOrderDocElems",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_doc);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xpath(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xpath : 30 of 38 functions ...\n");
+    test_ret += test_xmlXPathCastBooleanToNumber();
+    test_ret += test_xmlXPathCastBooleanToString();
+    test_ret += test_xmlXPathCastNodeSetToBoolean();
+    test_ret += test_xmlXPathCastNodeSetToNumber();
+    test_ret += test_xmlXPathCastNodeSetToString();
+    test_ret += test_xmlXPathCastNodeToNumber();
+    test_ret += test_xmlXPathCastNodeToString();
+    test_ret += test_xmlXPathCastNumberToBoolean();
+    test_ret += test_xmlXPathCastNumberToString();
+    test_ret += test_xmlXPathCastStringToBoolean();
+    test_ret += test_xmlXPathCastStringToNumber();
+    test_ret += test_xmlXPathCastToBoolean();
+    test_ret += test_xmlXPathCastToNumber();
+    test_ret += test_xmlXPathCastToString();
+    test_ret += test_xmlXPathCmpNodes();
+    test_ret += test_xmlXPathCompile();
+    test_ret += test_xmlXPathCompiledEval();
+    test_ret += test_xmlXPathCompiledEvalToBoolean();
+    test_ret += test_xmlXPathContextSetCache();
+    test_ret += test_xmlXPathConvertBoolean();
+    test_ret += test_xmlXPathConvertNumber();
+    test_ret += test_xmlXPathConvertString();
+    test_ret += test_xmlXPathCtxtCompile();
+    test_ret += test_xmlXPathEval();
+    test_ret += test_xmlXPathEvalExpression();
+    test_ret += test_xmlXPathEvalPredicate();
+    test_ret += test_xmlXPathInit();
+    test_ret += test_xmlXPathIsInf();
+    test_ret += test_xmlXPathIsNaN();
+    test_ret += test_xmlXPathNewContext();
+    test_ret += test_xmlXPathNodeSetCreate();
+    test_ret += test_xmlXPathObjectCopy();
+    test_ret += test_xmlXPathOrderDocElems();
+
+    if (test_ret != 0)
+	printf("Module xpath: %d errors\n", test_ret);
+    return(test_ret);
+}
+#ifdef LIBXML_XPATH_ENABLED
+
+#define gen_nb_xmlXPathParserContextPtr 1
+static xmlXPathParserContextPtr gen_xmlXPathParserContextPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlXPathParserContextPtr(int no ATTRIBUTE_UNUSED, xmlXPathParserContextPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_valuePop(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath evaluation context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = valuePop(ctxt);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in valuePop",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_valuePush(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath evaluation context */
+    int n_ctxt;
+    xmlXPathObjectPtr value; /* the XPath object */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_value = 0;n_value < gen_nb_xmlXPathObjectPtr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        value = gen_xmlXPathObjectPtr(n_value, 1);
+
+        ret_val = valuePush(ctxt, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlXPathObjectPtr(n_value, value, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in valuePush",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathAddValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathAddValues(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathAddValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathBooleanFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathBooleanFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathBooleanFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCeilingFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathCeilingFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCeilingFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCompareValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int inf; /* less than (1) or greater than (0) */
+    int n_inf;
+    int strict; /* is the comparison strict */
+    int n_strict;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_inf = 0;n_inf < gen_nb_int;n_inf++) {
+    for (n_strict = 0;n_strict < gen_nb_int;n_strict++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        inf = gen_int(n_inf, 1);
+        strict = gen_int(n_strict, 2);
+
+        ret_val = xmlXPathCompareValues(ctxt, inf, strict);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_inf, inf, 1);
+        des_int(n_strict, strict, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCompareValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_inf);
+            printf(" %d", n_strict);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathConcatFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathConcatFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathConcatFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathContainsFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathContainsFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathContainsFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathCountFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathCountFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathCountFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDebugDumpCompExpr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * for the output */
+    int n_output;
+    xmlXPathCompExprPtr comp; /* the precompiled XPath expression */
+    int n_comp;
+    int depth; /* the indentation level. */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_comp = 0;n_comp < gen_nb_xmlXPathCompExprPtr;n_comp++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        comp = gen_xmlXPathCompExprPtr(n_comp, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlXPathDebugDumpCompExpr(output, comp, depth);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlXPathCompExprPtr(n_comp, comp, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDebugDumpCompExpr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_comp);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDebugDumpObject(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
+    int mem_base;
+    FILE * output; /* the FILE * to dump the output */
+    int n_output;
+    xmlXPathObjectPtr cur; /* the object to inspect */
+    int n_cur;
+    int depth; /* indentation level */
+    int n_depth;
+
+    for (n_output = 0;n_output < gen_nb_FILE_ptr;n_output++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlXPathObjectPtr;n_cur++) {
+    for (n_depth = 0;n_depth < gen_nb_int;n_depth++) {
+        mem_base = xmlMemBlocks();
+        output = gen_FILE_ptr(n_output, 0);
+        cur = gen_xmlXPathObjectPtr(n_cur, 1);
+        depth = gen_int(n_depth, 2);
+
+        xmlXPathDebugDumpObject(output, cur, depth);
+        call_tests++;
+        des_FILE_ptr(n_output, output, 0);
+        des_xmlXPathObjectPtr(n_cur, cur, 1);
+        des_int(n_depth, depth, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDebugDumpObject",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_output);
+            printf(" %d", n_cur);
+            printf(" %d", n_depth);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDifference(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathDifference(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDifference",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDistinct(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set */
+    int n_nodes;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+
+        ret_val = xmlXPathDistinct(nodes);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDistinct",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDistinctSorted(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set, sorted by document order */
+    int n_nodes;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+
+        ret_val = xmlXPathDistinctSorted(nodes);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDistinctSorted",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathDivValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathDivValues(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathDivValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEqualValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathEqualValues(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEqualValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathErr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* a XPath parser context */
+    int n_ctxt;
+    int error; /* the error code */
+    int n_error;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_error = 0;n_error < gen_nb_int;n_error++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        error = gen_int(n_error, 1);
+
+        xmlXPathErr(ctxt, error);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_error, error, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathErr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_error);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEvalExpr(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathEvalExpr(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEvalExpr",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathEvaluatePredicateResult(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlXPathObjectPtr res; /* the Predicate Expression evaluation result */
+    int n_res;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_res = 0;n_res < gen_nb_xmlXPathObjectPtr;n_res++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        res = gen_xmlXPathObjectPtr(n_res, 1);
+
+        ret_val = xmlXPathEvaluatePredicateResult(ctxt, res);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlXPathObjectPtr(n_res, res, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathEvaluatePredicateResult",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_res);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathFalseFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathFalseFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathFalseFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathFloorFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathFloorFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathFloorFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathFunctionLookup(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathFunctionLookupNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathHasSameNodes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathHasSameNodes(nodes1, nodes2);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathHasSameNodes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathIdFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathIdFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathIdFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathIntersection(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathIntersection(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathIntersection",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathIsNodeType(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlChar * name; /* a name string */
+    int n_name;
+
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        name = gen_const_xmlChar_ptr(n_name, 0);
+
+        ret_val = xmlXPathIsNodeType((const xmlChar *)name);
+        desret_int(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathIsNodeType",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathLangFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathLangFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathLangFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathLastFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathLastFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathLastFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathLeading(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathLeading(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathLeading",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathLeadingSorted(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set, sorted by document order */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set, sorted by document order */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathLeadingSorted(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathLeadingSorted",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathLocalNameFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathLocalNameFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathLocalNameFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathModValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathModValues(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathModValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathMultValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathMultValues(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathMultValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNamespaceURIFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathNamespaceURIFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNamespaceURIFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    int val; /* the boolean value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_int(n_val, 0);
+
+        ret_val = xmlXPathNewBoolean(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_int(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewCString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    char * val; /* the char * value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_const_char_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_const_char_ptr(n_val, 0);
+
+        ret_val = xmlXPathNewCString((const char *)val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_val, (const char *)val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewCString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewFloat(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    double val; /* the double value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_double;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_double(n_val, 0);
+
+        ret_val = xmlXPathNewFloat(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_double(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewFloat",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewNodeSet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr val; /* the NodePtr value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlNodePtr(n_val, 0);
+
+        ret_val = xmlXPathNewNodeSet(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewNodeSet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewNodeSetList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodeSetPtr val; /* an existing NodeSet */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlNodeSetPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlNodeSetPtr(n_val, 0);
+
+        ret_val = xmlXPathNewNodeSetList(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewNodeSetList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewParserContext(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNewString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlChar * val; /* the xmlChar * value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_const_xmlChar_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_const_xmlChar_ptr(n_val, 0);
+
+        ret_val = xmlXPathNewString((const xmlChar *)val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_val, (const xmlChar *)val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNewString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextAncestor(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextAncestor(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextAncestor",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextAncestorOrSelf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextAncestorOrSelf(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextAncestorOrSelf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextAttribute(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current attribute in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextAttribute(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextAttribute",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextChild(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextChild(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextChild",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextDescendant(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextDescendant(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextDescendant",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextDescendantOrSelf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextDescendantOrSelf(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextDescendantOrSelf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextFollowing(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextFollowing(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextFollowing",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextFollowingSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextFollowingSibling(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextFollowingSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextNamespace(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current attribute in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextNamespace(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextNamespace",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextParent(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextParent(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextParent",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextPreceding(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextPreceding(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextPreceding",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextPrecedingSibling(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextPrecedingSibling(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextPrecedingSibling",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNextSelf(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    xmlNodePtr cur; /* the current node in the traversal */
+    int n_cur;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_cur = 0;n_cur < gen_nb_xmlNodePtr;n_cur++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        cur = gen_xmlNodePtr(n_cur, 1);
+
+        ret_val = xmlXPathNextSelf(ctxt, cur);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_xmlNodePtr(n_cur, cur, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNextSelf",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_cur);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeLeading(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set */
+    int n_nodes;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlXPathNodeLeading(nodes, node);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeLeading",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeLeadingSorted(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set, sorted by document order */
+    int n_nodes;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlXPathNodeLeadingSorted(nodes, node);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeLeadingSorted",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetAdd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr cur; /* the initial node set */
+    int n_cur;
+    xmlNodePtr val; /* a new xmlNodePtr */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        val = gen_xmlNodePtr(n_val, 1);
+
+        xmlXPathNodeSetAdd(cur, val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_xmlNodePtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetAdd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetAddNs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr cur; /* the initial node set */
+    int n_cur;
+    xmlNodePtr node; /* the hosting node */
+    int n_node;
+    xmlNsPtr ns; /* a the namespace node */
+    int n_ns;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+    for (n_ns = 0;n_ns < gen_nb_xmlNsPtr;n_ns++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+        ns = gen_xmlNsPtr(n_ns, 2);
+
+        xmlXPathNodeSetAddNs(cur, node, ns);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        des_xmlNsPtr(n_ns, ns, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetAddNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_node);
+            printf(" %d", n_ns);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetAddUnique(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr cur; /* the initial node set */
+    int n_cur;
+    xmlNodePtr val; /* a new xmlNodePtr */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        val = gen_xmlNodePtr(n_val, 1);
+
+        xmlXPathNodeSetAddUnique(cur, val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_xmlNodePtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetAddUnique",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetContains(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlNodeSetPtr cur; /* the node-set */
+    int n_cur;
+    xmlNodePtr val; /* the node */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        val = gen_xmlNodePtr(n_val, 1);
+
+        ret_val = xmlXPathNodeSetContains(cur, val);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_xmlNodePtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetContains",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetDel(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr cur; /* the initial node set */
+    int n_cur;
+    xmlNodePtr val; /* an xmlNodePtr */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlNodePtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        val = gen_xmlNodePtr(n_val, 1);
+
+        xmlXPathNodeSetDel(cur, val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_xmlNodePtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetDel",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetMerge(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr val1; /* the first NodeSet or NULL */
+    int n_val1;
+    xmlNodeSetPtr val2; /* the second NodeSet */
+    int n_val2;
+
+    for (n_val1 = 0;n_val1 < gen_nb_xmlNodeSetPtr;n_val1++) {
+    for (n_val2 = 0;n_val2 < gen_nb_xmlNodeSetPtr;n_val2++) {
+        mem_base = xmlMemBlocks();
+        val1 = gen_xmlNodeSetPtr(n_val1, 0);
+        val2 = gen_xmlNodeSetPtr(n_val2, 1);
+
+        ret_val = xmlXPathNodeSetMerge(val1, val2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_val1, val1, 0);
+        des_xmlNodeSetPtr(n_val2, val2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetMerge",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val1);
+            printf(" %d", n_val2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetRemove(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr cur; /* the initial node set */
+    int n_cur;
+    int val; /* the index to remove */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlNodeSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlNodeSetPtr(n_cur, 0);
+        val = gen_int(n_val, 1);
+
+        xmlXPathNodeSetRemove(cur, val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_cur, cur, 0);
+        des_int(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetRemove",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeSetSort(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr set; /* the node set */
+    int n_set;
+
+    for (n_set = 0;n_set < gen_nb_xmlNodeSetPtr;n_set++) {
+        mem_base = xmlMemBlocks();
+        set = gen_xmlNodeSetPtr(n_set, 0);
+
+        xmlXPathNodeSetSort(set);
+        call_tests++;
+        des_xmlNodeSetPtr(n_set, set, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeSetSort",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_set);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeTrailing(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set */
+    int n_nodes;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlXPathNodeTrailing(nodes, node);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeTrailing",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNodeTrailingSorted(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes; /* a node-set, sorted by document order */
+    int n_nodes;
+    xmlNodePtr node; /* a node */
+    int n_node;
+
+    for (n_nodes = 0;n_nodes < gen_nb_xmlNodeSetPtr;n_nodes++) {
+    for (n_node = 0;n_node < gen_nb_xmlNodePtr;n_node++) {
+        mem_base = xmlMemBlocks();
+        nodes = gen_xmlNodeSetPtr(n_nodes, 0);
+        node = gen_xmlNodePtr(n_node, 1);
+
+        ret_val = xmlXPathNodeTrailingSorted(nodes, node);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes, nodes, 0);
+        des_xmlNodePtr(n_node, node, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNodeTrailingSorted",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes);
+            printf(" %d", n_node);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNormalizeFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathNormalizeFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNormalizeFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNotEqualValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathNotEqualValues(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNotEqualValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNotFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathNotFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNotFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNsLookup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    const xmlChar * ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * prefix; /* the namespace prefix value */
+    int n_prefix;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+
+        ret_val = xmlXPathNsLookup(ctxt, (const xmlChar *)prefix);
+        desret_const_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNsLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_prefix);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathNumberFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathNumberFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathNumberFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathParseNCName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathParseNCName(ctxt);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathParseNCName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathParseName(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathParseName(ctxt);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathParseName",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPopBoolean(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathPopBoolean(ctxt);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPopBoolean",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPopExternal(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    void * ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathPopExternal(ctxt);
+        desret_void_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPopExternal",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPopNodeSet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathPopNodeSet(ctxt);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPopNodeSet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPopNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathPopNumber(ctxt);
+        desret_double(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPopNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPopString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlChar * ret_val;
+    xmlXPathParserContextPtr ctxt; /* an XPath parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        ret_val = xmlXPathPopString(ctxt);
+        desret_xmlChar_ptr(ret_val);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPopString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathPositionFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathPositionFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathPositionFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterAllFunctions(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+
+        xmlXPathRegisterAllFunctions(ctxt);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisterAllFunctions",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterFuncLookup(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterFuncNS(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterNs(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * prefix; /* the namespace prefix cannot be NULL or empty string */
+    int n_prefix;
+    xmlChar * ns_uri; /* the namespace name */
+    int n_ns_uri;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
+    for (n_ns_uri = 0;n_ns_uri < gen_nb_const_xmlChar_ptr;n_ns_uri++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        prefix = gen_const_xmlChar_ptr(n_prefix, 1);
+        ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
+
+        ret_val = xmlXPathRegisterNs(ctxt, (const xmlChar *)prefix, (const xmlChar *)ns_uri);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
+        des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisterNs",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_prefix);
+            printf(" %d", n_ns_uri);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterVariable(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * name; /* the variable name */
+    int n_name;
+    xmlXPathObjectPtr value; /* the variable value or NULL */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_value = 0;n_value < gen_nb_xmlXPathObjectPtr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        value = gen_xmlXPathObjectPtr(n_value, 2);
+
+        ret_val = xmlXPathRegisterVariable(ctxt, (const xmlChar *)name, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_xmlXPathObjectPtr(n_value, value, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisterVariable",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterVariableLookup(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisterVariableNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    int ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * name; /* the variable name */
+    int n_name;
+    xmlChar * ns_uri; /* the variable namespace URI */
+    int n_ns_uri;
+    xmlXPathObjectPtr value; /* the variable value or NULL */
+    int n_value;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns_uri = 0;n_ns_uri < gen_nb_const_xmlChar_ptr;n_ns_uri++) {
+    for (n_value = 0;n_value < gen_nb_xmlXPathObjectPtr;n_value++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
+        value = gen_xmlXPathObjectPtr(n_value, 3);
+
+        ret_val = xmlXPathRegisterVariableNS(ctxt, (const xmlChar *)name, (const xmlChar *)ns_uri, value);
+        desret_int(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+        des_xmlXPathObjectPtr(n_value, value, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisterVariableNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_ns_uri);
+            printf(" %d", n_value);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisteredFuncsCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+
+        xmlXPathRegisteredFuncsCleanup(ctxt);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisteredFuncsCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisteredNsCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+
+        xmlXPathRegisteredNsCleanup(ctxt);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisteredNsCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRegisteredVariablesCleanup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+
+        xmlXPathRegisteredVariablesCleanup(ctxt);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRegisteredVariablesCleanup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRoot(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathRoot(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRoot",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathRoundFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathRoundFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathRoundFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathStartsWithFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathStartsWithFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathStartsWithFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathStringEvalNumber(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    double ret_val;
+    xmlChar * str; /* A string to scan */
+    int n_str;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+
+        ret_val = xmlXPathStringEvalNumber((const xmlChar *)str);
+        desret_double(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathStringEvalNumber",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathStringFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathStringFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathStringFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathStringLengthFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathStringLengthFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathStringLengthFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathSubValues(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathSubValues(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathSubValues",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathSubstringAfterFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathSubstringAfterFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathSubstringAfterFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathSubstringBeforeFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathSubstringBeforeFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathSubstringBeforeFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathSubstringFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathSubstringFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathSubstringFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathSumFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathSumFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathSumFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathTrailing(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathTrailing(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathTrailing",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathTrailingSorted(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlNodeSetPtr ret_val;
+    xmlNodeSetPtr nodes1; /* a node-set, sorted by document order */
+    int n_nodes1;
+    xmlNodeSetPtr nodes2; /* a node-set, sorted by document order */
+    int n_nodes2;
+
+    for (n_nodes1 = 0;n_nodes1 < gen_nb_xmlNodeSetPtr;n_nodes1++) {
+    for (n_nodes2 = 0;n_nodes2 < gen_nb_xmlNodeSetPtr;n_nodes2++) {
+        mem_base = xmlMemBlocks();
+        nodes1 = gen_xmlNodeSetPtr(n_nodes1, 0);
+        nodes2 = gen_xmlNodeSetPtr(n_nodes2, 1);
+
+        ret_val = xmlXPathTrailingSorted(nodes1, nodes2);
+        desret_xmlNodeSetPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_nodes1, nodes1, 0);
+        des_xmlNodeSetPtr(n_nodes2, nodes2, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathTrailingSorted",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_nodes1);
+            printf(" %d", n_nodes2);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathTranslateFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathTranslateFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathTranslateFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathTrueFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    int nargs; /* the number of arguments */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPathTrueFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathTrueFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathValueFlipSign(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPathValueFlipSign(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathValueFlipSign",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathVariableLookup(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * name; /* the variable name */
+    int n_name;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+
+        ret_val = xmlXPathVariableLookup(ctxt, (const xmlChar *)name);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathVariableLookup",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathVariableLookupNS(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathContextPtr ctxt; /* the XPath context */
+    int n_ctxt;
+    xmlChar * name; /* the variable name */
+    int n_name;
+    xmlChar * ns_uri; /* the variable namespace URI */
+    int n_ns_uri;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathContextPtr;n_ctxt++) {
+    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_ns_uri = 0;n_ns_uri < gen_nb_const_xmlChar_ptr;n_ns_uri++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathContextPtr(n_ctxt, 0);
+        name = gen_const_xmlChar_ptr(n_name, 1);
+        ns_uri = gen_const_xmlChar_ptr(n_ns_uri, 2);
+
+        ret_val = xmlXPathVariableLookupNS(ctxt, (const xmlChar *)name, (const xmlChar *)ns_uri);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathContextPtr(n_ctxt, ctxt, 0);
+        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_ns_uri, (const xmlChar *)ns_uri, 2);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathVariableLookupNS",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_name);
+            printf(" %d", n_ns_uri);
+            printf("\n");
+        }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathWrapCString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    char * val; /* the char * value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_char_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_char_ptr(n_val, 0);
+
+        ret_val = xmlXPathWrapCString(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_char_ptr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathWrapCString",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathWrapExternal(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    void * val; /* the user data */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_void_ptr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_void_ptr(n_val, 0);
+
+        ret_val = xmlXPathWrapExternal(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_void_ptr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathWrapExternal",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPathWrapNodeSet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodeSetPtr val; /* the NodePtr value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlNodeSetPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlNodeSetPtr(n_val, 0);
+
+        ret_val = xmlXPathWrapNodeSet(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPathWrapNodeSet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPatherror(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPATH_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPath Parser context */
+    int n_ctxt;
+    const char * file; /* the file name */
+    int n_file;
+    int line; /* the line number */
+    int n_line;
+    int no; /* the error number */
+    int n_no;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_file = 0;n_file < gen_nb_filepath;n_file++) {
+    for (n_line = 0;n_line < gen_nb_int;n_line++) {
+    for (n_no = 0;n_no < gen_nb_int;n_no++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        file = gen_filepath(n_file, 1);
+        line = gen_int(n_line, 2);
+        no = gen_int(n_no, 3);
+
+        xmlXPatherror(ctxt, file, line, no);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_filepath(n_file, file, 1);
+        des_int(n_line, line, 2);
+        des_int(n_no, no, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPatherror",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_file);
+            printf(" %d", n_line);
+            printf(" %d", n_no);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xpathInternals(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xpathInternals : 106 of 117 functions ...\n");
+    test_ret += test_valuePop();
+    test_ret += test_valuePush();
+    test_ret += test_xmlXPathAddValues();
+    test_ret += test_xmlXPathBooleanFunction();
+    test_ret += test_xmlXPathCeilingFunction();
+    test_ret += test_xmlXPathCompareValues();
+    test_ret += test_xmlXPathConcatFunction();
+    test_ret += test_xmlXPathContainsFunction();
+    test_ret += test_xmlXPathCountFunction();
+    test_ret += test_xmlXPathDebugDumpCompExpr();
+    test_ret += test_xmlXPathDebugDumpObject();
+    test_ret += test_xmlXPathDifference();
+    test_ret += test_xmlXPathDistinct();
+    test_ret += test_xmlXPathDistinctSorted();
+    test_ret += test_xmlXPathDivValues();
+    test_ret += test_xmlXPathEqualValues();
+    test_ret += test_xmlXPathErr();
+    test_ret += test_xmlXPathEvalExpr();
+    test_ret += test_xmlXPathEvaluatePredicateResult();
+    test_ret += test_xmlXPathFalseFunction();
+    test_ret += test_xmlXPathFloorFunction();
+    test_ret += test_xmlXPathFunctionLookup();
+    test_ret += test_xmlXPathFunctionLookupNS();
+    test_ret += test_xmlXPathHasSameNodes();
+    test_ret += test_xmlXPathIdFunction();
+    test_ret += test_xmlXPathIntersection();
+    test_ret += test_xmlXPathIsNodeType();
+    test_ret += test_xmlXPathLangFunction();
+    test_ret += test_xmlXPathLastFunction();
+    test_ret += test_xmlXPathLeading();
+    test_ret += test_xmlXPathLeadingSorted();
+    test_ret += test_xmlXPathLocalNameFunction();
+    test_ret += test_xmlXPathModValues();
+    test_ret += test_xmlXPathMultValues();
+    test_ret += test_xmlXPathNamespaceURIFunction();
+    test_ret += test_xmlXPathNewBoolean();
+    test_ret += test_xmlXPathNewCString();
+    test_ret += test_xmlXPathNewFloat();
+    test_ret += test_xmlXPathNewNodeSet();
+    test_ret += test_xmlXPathNewNodeSetList();
+    test_ret += test_xmlXPathNewParserContext();
+    test_ret += test_xmlXPathNewString();
+    test_ret += test_xmlXPathNextAncestor();
+    test_ret += test_xmlXPathNextAncestorOrSelf();
+    test_ret += test_xmlXPathNextAttribute();
+    test_ret += test_xmlXPathNextChild();
+    test_ret += test_xmlXPathNextDescendant();
+    test_ret += test_xmlXPathNextDescendantOrSelf();
+    test_ret += test_xmlXPathNextFollowing();
+    test_ret += test_xmlXPathNextFollowingSibling();
+    test_ret += test_xmlXPathNextNamespace();
+    test_ret += test_xmlXPathNextParent();
+    test_ret += test_xmlXPathNextPreceding();
+    test_ret += test_xmlXPathNextPrecedingSibling();
+    test_ret += test_xmlXPathNextSelf();
+    test_ret += test_xmlXPathNodeLeading();
+    test_ret += test_xmlXPathNodeLeadingSorted();
+    test_ret += test_xmlXPathNodeSetAdd();
+    test_ret += test_xmlXPathNodeSetAddNs();
+    test_ret += test_xmlXPathNodeSetAddUnique();
+    test_ret += test_xmlXPathNodeSetContains();
+    test_ret += test_xmlXPathNodeSetDel();
+    test_ret += test_xmlXPathNodeSetMerge();
+    test_ret += test_xmlXPathNodeSetRemove();
+    test_ret += test_xmlXPathNodeSetSort();
+    test_ret += test_xmlXPathNodeTrailing();
+    test_ret += test_xmlXPathNodeTrailingSorted();
+    test_ret += test_xmlXPathNormalizeFunction();
+    test_ret += test_xmlXPathNotEqualValues();
+    test_ret += test_xmlXPathNotFunction();
+    test_ret += test_xmlXPathNsLookup();
+    test_ret += test_xmlXPathNumberFunction();
+    test_ret += test_xmlXPathParseNCName();
+    test_ret += test_xmlXPathParseName();
+    test_ret += test_xmlXPathPopBoolean();
+    test_ret += test_xmlXPathPopExternal();
+    test_ret += test_xmlXPathPopNodeSet();
+    test_ret += test_xmlXPathPopNumber();
+    test_ret += test_xmlXPathPopString();
+    test_ret += test_xmlXPathPositionFunction();
+    test_ret += test_xmlXPathRegisterAllFunctions();
+    test_ret += test_xmlXPathRegisterFunc();
+    test_ret += test_xmlXPathRegisterFuncLookup();
+    test_ret += test_xmlXPathRegisterFuncNS();
+    test_ret += test_xmlXPathRegisterNs();
+    test_ret += test_xmlXPathRegisterVariable();
+    test_ret += test_xmlXPathRegisterVariableLookup();
+    test_ret += test_xmlXPathRegisterVariableNS();
+    test_ret += test_xmlXPathRegisteredFuncsCleanup();
+    test_ret += test_xmlXPathRegisteredNsCleanup();
+    test_ret += test_xmlXPathRegisteredVariablesCleanup();
+    test_ret += test_xmlXPathRoot();
+    test_ret += test_xmlXPathRoundFunction();
+    test_ret += test_xmlXPathStartsWithFunction();
+    test_ret += test_xmlXPathStringEvalNumber();
+    test_ret += test_xmlXPathStringFunction();
+    test_ret += test_xmlXPathStringLengthFunction();
+    test_ret += test_xmlXPathSubValues();
+    test_ret += test_xmlXPathSubstringAfterFunction();
+    test_ret += test_xmlXPathSubstringBeforeFunction();
+    test_ret += test_xmlXPathSubstringFunction();
+    test_ret += test_xmlXPathSumFunction();
+    test_ret += test_xmlXPathTrailing();
+    test_ret += test_xmlXPathTrailingSorted();
+    test_ret += test_xmlXPathTranslateFunction();
+    test_ret += test_xmlXPathTrueFunction();
+    test_ret += test_xmlXPathValueFlipSign();
+    test_ret += test_xmlXPathVariableLookup();
+    test_ret += test_xmlXPathVariableLookupNS();
+    test_ret += test_xmlXPathWrapCString();
+    test_ret += test_xmlXPathWrapExternal();
+    test_ret += test_xmlXPathWrapNodeSet();
+    test_ret += test_xmlXPatherror();
+
+    if (test_ret != 0)
+	printf("Module xpathInternals: %d errors\n", test_ret);
+    return(test_ret);
+}
+
+static int
+test_xmlXPtrBuildNodeList(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlNodePtr ret_val;
+    xmlXPathObjectPtr obj; /* the XPointer result from the evaluation. */
+    int n_obj;
+
+    for (n_obj = 0;n_obj < gen_nb_xmlXPathObjectPtr;n_obj++) {
+        mem_base = xmlMemBlocks();
+        obj = gen_xmlXPathObjectPtr(n_obj, 0);
+
+        ret_val = xmlXPtrBuildNodeList(obj);
+        desret_xmlNodePtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_obj, obj, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrBuildNodeList",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_obj);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrEval(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlChar * str; /* the XPointer expression */
+    int n_str;
+    xmlXPathContextPtr ctx; /* the XPointer context */
+    int n_ctx;
+
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
+    for (n_ctx = 0;n_ctx < gen_nb_xmlXPathContextPtr;n_ctx++) {
+        mem_base = xmlMemBlocks();
+        str = gen_const_xmlChar_ptr(n_str, 0);
+        ctx = gen_xmlXPathContextPtr(n_ctx, 1);
+
+        ret_val = xmlXPtrEval((const xmlChar *)str, ctx);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
+        des_xmlXPathContextPtr(n_ctx, ctx, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrEval",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_str);
+            printf(" %d", n_ctx);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrEvalRangePredicate(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPointer Parser context */
+    int n_ctxt;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+
+        xmlXPtrEvalRangePredicate(ctxt);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrEvalRangePredicate",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+#ifdef LIBXML_XPTR_ENABLED
+
+#define gen_nb_xmlLocationSetPtr 1
+static xmlLocationSetPtr gen_xmlLocationSetPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+static void des_xmlLocationSetPtr(int no ATTRIBUTE_UNUSED, xmlLocationSetPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
+}
+#endif
+
+
+static int
+test_xmlXPtrLocationSetAdd(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlLocationSetPtr cur; /* the initial range set */
+    int n_cur;
+    xmlXPathObjectPtr val; /* a new xmlXPathObjectPtr */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlLocationSetPtr(n_cur, 0);
+        val = gen_xmlXPathObjectPtr(n_val, 1);
+
+        xmlXPtrLocationSetAdd(cur, val);
+        call_tests++;
+        des_xmlLocationSetPtr(n_cur, cur, 0);
+        des_xmlXPathObjectPtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrLocationSetAdd",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrLocationSetCreate(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrLocationSetDel(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlLocationSetPtr cur; /* the initial range set */
+    int n_cur;
+    xmlXPathObjectPtr val; /* an xmlXPathObjectPtr */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlLocationSetPtr(n_cur, 0);
+        val = gen_xmlXPathObjectPtr(n_val, 1);
+
+        xmlXPtrLocationSetDel(cur, val);
+        call_tests++;
+        des_xmlLocationSetPtr(n_cur, cur, 0);
+        des_xmlXPathObjectPtr(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrLocationSetDel",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrLocationSetMerge(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrLocationSetRemove(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlLocationSetPtr cur; /* the initial range set */
+    int n_cur;
+    int val; /* the index to remove */
+    int n_val;
+
+    for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) {
+    for (n_val = 0;n_val < gen_nb_int;n_val++) {
+        mem_base = xmlMemBlocks();
+        cur = gen_xmlLocationSetPtr(n_cur, 0);
+        val = gen_int(n_val, 1);
+
+        xmlXPtrLocationSetRemove(cur, val);
+        call_tests++;
+        des_xmlLocationSetPtr(n_cur, cur, 0);
+        des_int(n_val, val, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrLocationSetRemove",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_cur);
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewCollapsedRange(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the starting and ending node */
+    int n_start;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+
+        ret_val = xmlXPtrNewCollapsedRange(start);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewCollapsedRange",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewContext(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewLocationSetNodeSet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodeSetPtr set; /* a node set */
+    int n_set;
+
+    for (n_set = 0;n_set < gen_nb_xmlNodeSetPtr;n_set++) {
+        mem_base = xmlMemBlocks();
+        set = gen_xmlNodeSetPtr(n_set, 0);
+
+        ret_val = xmlXPtrNewLocationSetNodeSet(set);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodeSetPtr(n_set, set, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewLocationSetNodeSet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_set);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewLocationSetNodes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the start NodePtr value */
+    int n_start;
+    xmlNodePtr end; /* the end NodePtr value or NULL */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlNodePtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+        end = gen_xmlNodePtr(n_end, 1);
+
+        ret_val = xmlXPtrNewLocationSetNodes(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        des_xmlNodePtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewLocationSetNodes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRange(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the starting node */
+    int n_start;
+    int startindex; /* the start index */
+    int n_startindex;
+    xmlNodePtr end; /* the ending point */
+    int n_end;
+    int endindex; /* the ending index */
+    int n_endindex;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+    for (n_startindex = 0;n_startindex < gen_nb_int;n_startindex++) {
+    for (n_end = 0;n_end < gen_nb_xmlNodePtr;n_end++) {
+    for (n_endindex = 0;n_endindex < gen_nb_int;n_endindex++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+        startindex = gen_int(n_startindex, 1);
+        end = gen_xmlNodePtr(n_end, 2);
+        endindex = gen_int(n_endindex, 3);
+
+        ret_val = xmlXPtrNewRange(start, startindex, end, endindex);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        des_int(n_startindex, startindex, 1);
+        des_xmlNodePtr(n_end, end, 2);
+        des_int(n_endindex, endindex, 3);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRange",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_startindex);
+            printf(" %d", n_end);
+            printf(" %d", n_endindex);
+            printf("\n");
+        }
+    }
+    }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRangeNodeObject(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the starting node */
+    int n_start;
+    xmlXPathObjectPtr end; /* the ending object */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlXPathObjectPtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+        end = gen_xmlXPathObjectPtr(n_end, 1);
+
+        ret_val = xmlXPtrNewRangeNodeObject(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        des_xmlXPathObjectPtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRangeNodeObject",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRangeNodePoint(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the starting node */
+    int n_start;
+    xmlXPathObjectPtr end; /* the ending point */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlXPathObjectPtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+        end = gen_xmlXPathObjectPtr(n_end, 1);
+
+        ret_val = xmlXPtrNewRangeNodePoint(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        des_xmlXPathObjectPtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRangeNodePoint",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRangeNodes(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlNodePtr start; /* the starting node */
+    int n_start;
+    xmlNodePtr end; /* the ending node */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlNodePtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlNodePtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlNodePtr(n_start, 0);
+        end = gen_xmlNodePtr(n_end, 1);
+
+        ret_val = xmlXPtrNewRangeNodes(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlNodePtr(n_start, start, 0);
+        des_xmlNodePtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRangeNodes",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRangePointNode(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr start; /* the starting point */
+    int n_start;
+    xmlNodePtr end; /* the ending node */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlXPathObjectPtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlNodePtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlXPathObjectPtr(n_start, 0);
+        end = gen_xmlNodePtr(n_end, 1);
+
+        ret_val = xmlXPtrNewRangePointNode(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_start, start, 0);
+        des_xmlNodePtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRangePointNode",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrNewRangePoints(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlXPathObjectPtr start; /* the starting point */
+    int n_start;
+    xmlXPathObjectPtr end; /* the ending point */
+    int n_end;
+
+    for (n_start = 0;n_start < gen_nb_xmlXPathObjectPtr;n_start++) {
+    for (n_end = 0;n_end < gen_nb_xmlXPathObjectPtr;n_end++) {
+        mem_base = xmlMemBlocks();
+        start = gen_xmlXPathObjectPtr(n_start, 0);
+        end = gen_xmlXPathObjectPtr(n_end, 1);
+
+        ret_val = xmlXPtrNewRangePoints(start, end);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlXPathObjectPtr(n_start, start, 0);
+        des_xmlXPathObjectPtr(n_end, end, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrNewRangePoints",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_start);
+            printf(" %d", n_end);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrRangeToFunction(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathParserContextPtr ctxt; /* the XPointer Parser context */
+    int n_ctxt;
+    int nargs; /* the number of args */
+    int n_nargs;
+
+    for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) {
+    for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) {
+        mem_base = xmlMemBlocks();
+        ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0);
+        nargs = gen_int(n_nargs, 1);
+
+        xmlXPtrRangeToFunction(ctxt, nargs);
+        call_tests++;
+        des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0);
+        des_int(n_nargs, nargs, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrRangeToFunction",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_ctxt);
+            printf(" %d", n_nargs);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlXPtrWrapLocationSet(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_XPTR_ENABLED)
+    int mem_base;
+    xmlXPathObjectPtr ret_val;
+    xmlLocationSetPtr val; /* the LocationSet value */
+    int n_val;
+
+    for (n_val = 0;n_val < gen_nb_xmlLocationSetPtr;n_val++) {
+        mem_base = xmlMemBlocks();
+        val = gen_xmlLocationSetPtr(n_val, 0);
+
+        ret_val = xmlXPtrWrapLocationSet(val);
+        desret_xmlXPathObjectPtr(ret_val);
+        call_tests++;
+        des_xmlLocationSetPtr(n_val, val, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlXPtrWrapLocationSet",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_val);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+static int
+test_xpointer(void) {
+    int test_ret = 0;
+
+    if (quiet == 0) printf("Testing xpointer : 17 of 21 functions ...\n");
+    test_ret += test_xmlXPtrBuildNodeList();
+    test_ret += test_xmlXPtrEval();
+    test_ret += test_xmlXPtrEvalRangePredicate();
+    test_ret += test_xmlXPtrLocationSetAdd();
+    test_ret += test_xmlXPtrLocationSetCreate();
+    test_ret += test_xmlXPtrLocationSetDel();
+    test_ret += test_xmlXPtrLocationSetMerge();
+    test_ret += test_xmlXPtrLocationSetRemove();
+    test_ret += test_xmlXPtrNewCollapsedRange();
+    test_ret += test_xmlXPtrNewContext();
+    test_ret += test_xmlXPtrNewLocationSetNodeSet();
+    test_ret += test_xmlXPtrNewLocationSetNodes();
+    test_ret += test_xmlXPtrNewRange();
+    test_ret += test_xmlXPtrNewRangeNodeObject();
+    test_ret += test_xmlXPtrNewRangeNodePoint();
+    test_ret += test_xmlXPtrNewRangeNodes();
+    test_ret += test_xmlXPtrNewRangePointNode();
+    test_ret += test_xmlXPtrNewRangePoints();
+    test_ret += test_xmlXPtrRangeToFunction();
+    test_ret += test_xmlXPtrWrapLocationSet();
+
+    if (test_ret != 0)
+	printf("Module xpointer: %d errors\n", test_ret);
+    return(test_ret);
+}
+static int
+test_module(const char *module) {
+    if (!strcmp(module, "HTMLparser")) return(test_HTMLparser());
+    if (!strcmp(module, "HTMLtree")) return(test_HTMLtree());
+    if (!strcmp(module, "SAX2")) return(test_SAX2());
+    if (!strcmp(module, "c14n")) return(test_c14n());
+    if (!strcmp(module, "catalog")) return(test_catalog());
+    if (!strcmp(module, "chvalid")) return(test_chvalid());
+    if (!strcmp(module, "debugXML")) return(test_debugXML());
+    if (!strcmp(module, "dict")) return(test_dict());
+    if (!strcmp(module, "encoding")) return(test_encoding());
+    if (!strcmp(module, "entities")) return(test_entities());
+    if (!strcmp(module, "hash")) return(test_hash());
+    if (!strcmp(module, "list")) return(test_list());
+    if (!strcmp(module, "nanoftp")) return(test_nanoftp());
+    if (!strcmp(module, "nanohttp")) return(test_nanohttp());
+    if (!strcmp(module, "parser")) return(test_parser());
+    if (!strcmp(module, "parserInternals")) return(test_parserInternals());
+    if (!strcmp(module, "pattern")) return(test_pattern());
+    if (!strcmp(module, "relaxng")) return(test_relaxng());
+    if (!strcmp(module, "schemasInternals")) return(test_schemasInternals());
+    if (!strcmp(module, "schematron")) return(test_schematron());
+    if (!strcmp(module, "tree")) return(test_tree());
+    if (!strcmp(module, "uri")) return(test_uri());
+    if (!strcmp(module, "valid")) return(test_valid());
+    if (!strcmp(module, "xinclude")) return(test_xinclude());
+    if (!strcmp(module, "xmlIO")) return(test_xmlIO());
+    if (!strcmp(module, "xmlautomata")) return(test_xmlautomata());
+    if (!strcmp(module, "xmlerror")) return(test_xmlerror());
+    if (!strcmp(module, "xmlmodule")) return(test_xmlmodule());
+    if (!strcmp(module, "xmlreader")) return(test_xmlreader());
+    if (!strcmp(module, "xmlregexp")) return(test_xmlregexp());
+    if (!strcmp(module, "xmlsave")) return(test_xmlsave());
+    if (!strcmp(module, "xmlschemas")) return(test_xmlschemas());
+    if (!strcmp(module, "xmlschemastypes")) return(test_xmlschemastypes());
+    if (!strcmp(module, "xmlstring")) return(test_xmlstring());
+    if (!strcmp(module, "xmlunicode")) return(test_xmlunicode());
+    if (!strcmp(module, "xmlwriter")) return(test_xmlwriter());
+    if (!strcmp(module, "xpath")) return(test_xpath());
+    if (!strcmp(module, "xpathInternals")) return(test_xpathInternals());
+    if (!strcmp(module, "xpointer")) return(test_xpointer());
+    return(0);
+}
diff --git a/src/testdso.c b/src/testdso.c
new file mode 100644
index 0000000..bd4ff08
--- /dev/null
+++ b/src/testdso.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+#define IN_LIBXML
+#include "libxml/xmlexports.h"
+
+XMLPUBFUN int hello_world(void);
+
+int hello_world(void)
+{
+  printf("Success!\n");
+  return 0;
+}
diff --git a/src/threads.c b/src/threads.c
new file mode 100644
index 0000000..cc67548
--- /dev/null
+++ b/src/threads.c
@@ -0,0 +1,990 @@
+/**
+ * threads.c: set of generic threading related routines
+ *
+ * See Copyright for the status of this software.
+ *
+ * Gary Pennington <Gary.Pennington@uk.sun.com>
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#elif defined HAVE_WIN32_THREADS
+#include <windows.h>
+#ifndef HAVE_COMPILER_TLS
+#include <process.h>
+#endif
+#endif
+
+#ifdef HAVE_BEOS_THREADS
+#include <OS.h>
+#include <TLS.h>
+#endif
+
+#if defined(SOLARIS)
+#include <note.h>
+#endif
+
+/* #define DEBUG_THREADS */
+
+#ifdef HAVE_PTHREAD_H
+
+static int libxml_is_threaded = -1;
+
+#endif /* HAVE_PTHREAD_H */
+
+/*
+ * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
+ *       to avoid some crazyness since xmlMalloc/xmlFree may actually
+ *       be hosted on allocated blocks needing them for the allocation ...
+ */
+
+/*
+ * xmlMutex are a simple mutual exception locks
+ */
+struct _xmlMutex {
+#ifdef HAVE_PTHREAD_H
+    pthread_mutex_t lock;
+#elif defined HAVE_WIN32_THREADS
+    HANDLE mutex;
+#elif defined HAVE_BEOS_THREADS
+    sem_id sem;
+    thread_id tid;
+#else
+    int empty;
+#endif
+};
+
+/*
+ * xmlRMutex are reentrant mutual exception locks
+ */
+struct _xmlRMutex {
+#ifdef HAVE_PTHREAD_H
+    pthread_mutex_t lock;
+    unsigned int held;
+    unsigned int waiters;
+    pthread_t tid;
+    pthread_cond_t cv;
+#elif defined HAVE_WIN32_THREADS
+    CRITICAL_SECTION cs;
+    unsigned int count;
+#elif defined HAVE_BEOS_THREADS
+    xmlMutexPtr lock;
+    thread_id tid;
+    int32 count;
+#else
+    int empty;
+#endif
+};
+
+/*
+ * This module still has some internal static data.
+ *   - xmlLibraryLock a global lock
+ *   - globalkey used for per-thread data
+ */
+
+#ifdef HAVE_PTHREAD_H
+static pthread_key_t globalkey;
+static pthread_t mainthread;
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
+#elif defined HAVE_WIN32_THREADS
+#if defined(HAVE_COMPILER_TLS)
+static __declspec(thread) xmlGlobalState tlstate;
+static __declspec(thread) int tlstate_inited = 0;
+#else /* HAVE_COMPILER_TLS */
+static DWORD globalkey = TLS_OUT_OF_INDEXES;
+#endif /* HAVE_COMPILER_TLS */
+static DWORD mainthread;
+static struct {
+    DWORD done;
+    DWORD control;
+} run_once = { 0, 0};
+static volatile LPCRITICAL_SECTION global_init_lock = NULL;
+
+/* endif HAVE_WIN32_THREADS */
+#elif defined HAVE_BEOS_THREADS
+int32 globalkey = 0;
+thread_id mainthread = 0;
+int32 run_once_init = 0;
+static int32 global_init_lock = -1;
+static vint32 global_init_count = 0;
+#endif
+
+static xmlRMutexPtr xmlLibraryLock = NULL;
+
+#ifdef LIBXML_THREAD_ENABLED
+static void xmlOnceInit(void);
+#endif
+
+/**
+ * xmlNewMutex:
+ *
+ * xmlNewMutex() is used to allocate a libxml2 token struct for use in
+ * synchronizing access to data.
+ *
+ * Returns a new simple mutex pointer or NULL in case of error
+ */
+xmlMutexPtr
+xmlNewMutex(void)
+{
+    xmlMutexPtr tok;
+
+    if ((tok = malloc(sizeof(xmlMutex))) == NULL)
+        return (NULL);
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0)
+        pthread_mutex_init(&tok->lock, NULL);
+#elif defined HAVE_WIN32_THREADS
+    tok->mutex = CreateMutex(NULL, FALSE, NULL);
+#elif defined HAVE_BEOS_THREADS
+    if ((tok->sem = create_sem(1, "xmlMutex")) < B_OK) {
+        free(tok);
+        return NULL;
+    }
+    tok->tid = -1;
+#endif
+    return (tok);
+}
+
+/**
+ * xmlFreeMutex:
+ * @tok:  the simple mutex
+ *
+ * xmlFreeMutex() is used to reclaim resources associated with a libxml2 token
+ * struct.
+ */
+void
+xmlFreeMutex(xmlMutexPtr tok)
+{
+    if (tok == NULL)
+        return;
+
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0)
+        pthread_mutex_destroy(&tok->lock);
+#elif defined HAVE_WIN32_THREADS
+    CloseHandle(tok->mutex);
+#elif defined HAVE_BEOS_THREADS
+    delete_sem(tok->sem);
+#endif
+    free(tok);
+}
+
+/**
+ * xmlMutexLock:
+ * @tok:  the simple mutex
+ *
+ * xmlMutexLock() is used to lock a libxml2 token.
+ */
+void
+xmlMutexLock(xmlMutexPtr tok)
+{
+    if (tok == NULL)
+        return;
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0)
+        pthread_mutex_lock(&tok->lock);
+#elif defined HAVE_WIN32_THREADS
+    WaitForSingleObject(tok->mutex, INFINITE);
+#elif defined HAVE_BEOS_THREADS
+    if (acquire_sem(tok->sem) != B_NO_ERROR) {
+#ifdef DEBUG_THREADS
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlMutexLock():BeOS:Couldn't aquire semaphore\n");
+        exit();
+#endif
+    }
+    tok->tid = find_thread(NULL);
+#endif
+
+}
+
+/**
+ * xmlMutexUnlock:
+ * @tok:  the simple mutex
+ *
+ * xmlMutexUnlock() is used to unlock a libxml2 token.
+ */
+void
+xmlMutexUnlock(xmlMutexPtr tok)
+{
+    if (tok == NULL)
+        return;
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0)
+        pthread_mutex_unlock(&tok->lock);
+#elif defined HAVE_WIN32_THREADS
+    ReleaseMutex(tok->mutex);
+#elif defined HAVE_BEOS_THREADS
+    if (tok->tid == find_thread(NULL)) {
+        tok->tid = -1;
+        release_sem(tok->sem);
+    }
+#endif
+}
+
+/**
+ * xmlNewRMutex:
+ *
+ * xmlRNewMutex() is used to allocate a reentrant mutex for use in
+ * synchronizing access to data. token_r is a re-entrant lock and thus useful
+ * for synchronizing access to data structures that may be manipulated in a
+ * recursive fashion.
+ *
+ * Returns the new reentrant mutex pointer or NULL in case of error
+ */
+xmlRMutexPtr
+xmlNewRMutex(void)
+{
+    xmlRMutexPtr tok;
+
+    if ((tok = malloc(sizeof(xmlRMutex))) == NULL)
+        return (NULL);
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0) {
+        pthread_mutex_init(&tok->lock, NULL);
+        tok->held = 0;
+        tok->waiters = 0;
+        pthread_cond_init(&tok->cv, NULL);
+    }
+#elif defined HAVE_WIN32_THREADS
+    InitializeCriticalSection(&tok->cs);
+    tok->count = 0;
+#elif defined HAVE_BEOS_THREADS
+    if ((tok->lock = xmlNewMutex()) == NULL) {
+        free(tok);
+        return NULL;
+    }
+    tok->count = 0;
+#endif
+    return (tok);
+}
+
+/**
+ * xmlFreeRMutex:
+ * @tok:  the reentrant mutex
+ *
+ * xmlRFreeMutex() is used to reclaim resources associated with a
+ * reentrant mutex.
+ */
+void
+xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
+{
+    if (tok == NULL)
+        return;
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded != 0) {
+        pthread_mutex_destroy(&tok->lock);
+        pthread_cond_destroy(&tok->cv);
+    }
+#elif defined HAVE_WIN32_THREADS
+    DeleteCriticalSection(&tok->cs);
+#elif defined HAVE_BEOS_THREADS
+    xmlFreeMutex(tok->lock);
+#endif
+    free(tok);
+}
+
+/**
+ * xmlRMutexLock:
+ * @tok:  the reentrant mutex
+ *
+ * xmlRMutexLock() is used to lock a libxml2 token_r.
+ */
+void
+xmlRMutexLock(xmlRMutexPtr tok)
+{
+    if (tok == NULL)
+        return;
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded == 0)
+        return;
+
+    pthread_mutex_lock(&tok->lock);
+    if (tok->held) {
+        if (pthread_equal(tok->tid, pthread_self())) {
+            tok->held++;
+            pthread_mutex_unlock(&tok->lock);
+            return;
+        } else {
+            tok->waiters++;
+            while (tok->held)
+                pthread_cond_wait(&tok->cv, &tok->lock);
+            tok->waiters--;
+        }
+    }
+    tok->tid = pthread_self();
+    tok->held = 1;
+    pthread_mutex_unlock(&tok->lock);
+#elif defined HAVE_WIN32_THREADS
+    EnterCriticalSection(&tok->cs);
+    ++tok->count;
+#elif defined HAVE_BEOS_THREADS
+    if (tok->lock->tid == find_thread(NULL)) {
+        tok->count++;
+        return;
+    } else {
+        xmlMutexLock(tok->lock);
+        tok->count = 1;
+    }
+#endif
+}
+
+/**
+ * xmlRMutexUnlock:
+ * @tok:  the reentrant mutex
+ *
+ * xmlRMutexUnlock() is used to unlock a libxml2 token_r.
+ */
+void
+xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
+{
+    if (tok == NULL)
+        return;
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded == 0)
+        return;
+
+    pthread_mutex_lock(&tok->lock);
+    tok->held--;
+    if (tok->held == 0) {
+        if (tok->waiters)
+            pthread_cond_signal(&tok->cv);
+        memset(&tok->tid, 0, sizeof(tok->tid));
+    }
+    pthread_mutex_unlock(&tok->lock);
+#elif defined HAVE_WIN32_THREADS
+    if (!--tok->count)
+        LeaveCriticalSection(&tok->cs);
+#elif defined HAVE_BEOS_THREADS
+    if (tok->lock->tid == find_thread(NULL)) {
+        tok->count--;
+        if (tok->count == 0) {
+            xmlMutexUnlock(tok->lock);
+        }
+        return;
+    }
+#endif
+}
+
+/**
+ * xmlGlobalInitMutexLock
+ *
+ * Makes sure that the global initialization mutex is initialized and
+ * locks it.
+ */
+void
+__xmlGlobalInitMutexLock(void)
+{
+    /* 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);
+#elif defined HAVE_WIN32_THREADS
+    LPCRITICAL_SECTION cs;
+
+    /* Create a new critical section */
+    if (global_init_lock == NULL) {
+        cs = malloc(sizeof(CRITICAL_SECTION));
+        if (cs == NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlGlobalInitMutexLock: out of memory\n");
+            return;
+        }
+        InitializeCriticalSection(cs);
+
+        /* Swap it into the global_init_lock */
+#ifdef InterlockedCompareExchangePointer
+        InterlockedCompareExchangePointer(&global_init_lock, cs, NULL);
+#else /* Use older void* version */
+        InterlockedCompareExchange((void **) &global_init_lock,
+                                   (void *) cs, NULL);
+#endif /* InterlockedCompareExchangePointer */
+
+        /* If another thread successfully recorded its critical
+         * section in the global_init_lock then discard the one
+         * allocated by this thread. */
+        if (global_init_lock != cs) {
+            DeleteCriticalSection(cs);
+            free(cs);
+        }
+    }
+
+    /* Lock the chosen critical section */
+    EnterCriticalSection(global_init_lock);
+#elif defined HAVE_BEOS_THREADS
+    int32 sem;
+
+    /* Allocate a new semaphore */
+    sem = create_sem(1, "xmlGlobalinitMutex");
+
+    while (global_init_lock == -1) {
+        if (atomic_add(&global_init_count, 1) == 0) {
+            global_init_lock = sem;
+        } else {
+            snooze(1);
+            atomic_add(&global_init_count, -1);
+        }
+    }
+
+    /* If another thread successfully recorded its critical
+     * section in the global_init_lock then discard the one
+     * allocated by this thread. */
+    if (global_init_lock != sem)
+        delete_sem(sem);
+
+    /* Acquire the chosen semaphore */
+    if (acquire_sem(global_init_lock) != B_NO_ERROR) {
+#ifdef DEBUG_THREADS
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphore\n");
+        exit();
+#endif
+    }
+#endif
+}
+
+void
+__xmlGlobalInitMutexUnlock(void)
+{
+#ifdef HAVE_PTHREAD_H
+    pthread_mutex_unlock(&global_init_lock);
+#elif defined HAVE_WIN32_THREADS
+    if (global_init_lock != NULL) {
+	LeaveCriticalSection(global_init_lock);
+    }
+#elif defined HAVE_BEOS_THREADS
+    release_sem(global_init_lock);
+#endif
+}
+
+/**
+ * xmlGlobalInitMutexDestroy
+ *
+ * Makes sure that the global initialization mutex is destroyed before
+ * application termination.
+ */
+void
+__xmlGlobalInitMutexDestroy(void)
+{
+#ifdef HAVE_PTHREAD_H
+#elif defined HAVE_WIN32_THREADS
+    if (global_init_lock != NULL) {
+        DeleteCriticalSection(global_init_lock);
+        free(global_init_lock);
+        global_init_lock = NULL;
+    }
+#endif
+}
+
+/************************************************************************
+ *									*
+ *			Per thread global state handling		*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_THREAD_ENABLED
+#ifdef xmlLastError
+#undef xmlLastError
+#endif
+
+/**
+ * xmlFreeGlobalState:
+ * @state:  a thread global state
+ *
+ * xmlFreeGlobalState() is called when a thread terminates with a non-NULL
+ * global state. It is is used here to reclaim memory resources.
+ */
+static void
+xmlFreeGlobalState(void *state)
+{
+    xmlGlobalState *gs = (xmlGlobalState *) state;
+
+    /* free any memory allocated in the thread's xmlLastError */
+    xmlResetError(&(gs->xmlLastError));
+    free(state);
+}
+
+/**
+ * xmlNewGlobalState:
+ *
+ * xmlNewGlobalState() allocates a global state. This structure is used to
+ * hold all data for use by a thread when supporting backwards compatibility
+ * of libxml2 to pre-thread-safe behaviour.
+ *
+ * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
+ */
+static xmlGlobalStatePtr
+xmlNewGlobalState(void)
+{
+    xmlGlobalState *gs;
+
+    gs = malloc(sizeof(xmlGlobalState));
+    if (gs == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+			"xmlGetGlobalState: out of memory\n");
+        return (NULL);
+    }
+
+    memset(gs, 0, sizeof(xmlGlobalState));
+    xmlInitializeGlobalState(gs);
+    return (gs);
+}
+#endif /* LIBXML_THREAD_ENABLED */
+
+#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 {
+    HANDLE thread;
+    void *memory;
+} xmlGlobalStateCleanupHelperParams;
+
+static void XMLCDECL
+xmlGlobalStateCleanupHelper(void *p)
+{
+    xmlGlobalStateCleanupHelperParams *params =
+        (xmlGlobalStateCleanupHelperParams *) p;
+    WaitForSingleObject(params->thread, INFINITE);
+    CloseHandle(params->thread);
+    xmlFreeGlobalState(params->memory);
+    free(params);
+    _endthread();
+}
+#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
+
+typedef struct _xmlGlobalStateCleanupHelperParams {
+    void *memory;
+    struct _xmlGlobalStateCleanupHelperParams *prev;
+    struct _xmlGlobalStateCleanupHelperParams *next;
+} xmlGlobalStateCleanupHelperParams;
+
+static xmlGlobalStateCleanupHelperParams *cleanup_helpers_head = NULL;
+static CRITICAL_SECTION cleanup_helpers_cs;
+
+#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
+#endif /* HAVE_COMPILER_TLS */
+#endif /* HAVE_WIN32_THREADS */
+
+#if defined HAVE_BEOS_THREADS
+
+/**
+ * xmlGlobalStateCleanup:
+ * @data: unused parameter
+ *
+ * Used for Beos only
+ */
+void
+xmlGlobalStateCleanup(void *data)
+{
+    void *globalval = tls_get(globalkey);
+
+    if (globalval != NULL)
+        xmlFreeGlobalState(globalval);
+}
+#endif
+
+/**
+ * xmlGetGlobalState:
+ *
+ * xmlGetGlobalState() is called to retrieve the global state for a thread.
+ *
+ * Returns the thread global state or NULL in case of error
+ */
+xmlGlobalStatePtr
+xmlGetGlobalState(void)
+{
+#ifdef HAVE_PTHREAD_H
+    xmlGlobalState *globalval;
+
+    if (libxml_is_threaded == 0)
+        return (NULL);
+
+    pthread_once(&once_control, xmlOnceInit);
+
+    if ((globalval = (xmlGlobalState *)
+         pthread_getspecific(globalkey)) == NULL) {
+        xmlGlobalState *tsd = xmlNewGlobalState();
+	if (tsd == NULL)
+	    return(NULL);
+
+        pthread_setspecific(globalkey, tsd);
+        return (tsd);
+    }
+    return (globalval);
+#elif defined HAVE_WIN32_THREADS
+#if defined(HAVE_COMPILER_TLS)
+    if (!tlstate_inited) {
+        tlstate_inited = 1;
+        xmlInitializeGlobalState(&tlstate);
+    }
+    return &tlstate;
+#else /* HAVE_COMPILER_TLS */
+    xmlGlobalState *globalval;
+    xmlGlobalStateCleanupHelperParams *p;
+
+    xmlOnceInit();
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+    globalval = (xmlGlobalState *) TlsGetValue(globalkey);
+#else
+    p = (xmlGlobalStateCleanupHelperParams *) TlsGetValue(globalkey);
+    globalval = (xmlGlobalState *) (p ? p->memory : NULL);
+#endif
+    if (globalval == NULL) {
+        xmlGlobalState *tsd = xmlNewGlobalState();
+
+        if (tsd == NULL)
+	    return(NULL);
+        p = (xmlGlobalStateCleanupHelperParams *)
+            malloc(sizeof(xmlGlobalStateCleanupHelperParams));
+	if (p == NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlGetGlobalState: out of memory\n");
+            xmlFreeGlobalState(tsd);
+	    return(NULL);
+	}
+        p->memory = tsd;
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+        DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &p->thread, 0, TRUE,
+                        DUPLICATE_SAME_ACCESS);
+        TlsSetValue(globalkey, tsd);
+        _beginthread(xmlGlobalStateCleanupHelper, 0, p);
+#else
+        EnterCriticalSection(&cleanup_helpers_cs);
+        if (cleanup_helpers_head != NULL) {
+            cleanup_helpers_head->prev = p;
+        }
+        p->next = cleanup_helpers_head;
+        p->prev = NULL;
+        cleanup_helpers_head = p;
+        TlsSetValue(globalkey, p);
+        LeaveCriticalSection(&cleanup_helpers_cs);
+#endif
+
+        return (tsd);
+    }
+    return (globalval);
+#endif /* HAVE_COMPILER_TLS */
+#elif defined HAVE_BEOS_THREADS
+    xmlGlobalState *globalval;
+
+    xmlOnceInit();
+
+    if ((globalval = (xmlGlobalState *) tls_get(globalkey)) == NULL) {
+        xmlGlobalState *tsd = xmlNewGlobalState();
+	if (tsd == NULL)
+	    return (NULL);
+
+        tls_set(globalkey, tsd);
+        on_exit_thread(xmlGlobalStateCleanup, NULL);
+        return (tsd);
+    }
+    return (globalval);
+#else
+    return (NULL);
+#endif
+}
+
+/************************************************************************
+ *									*
+ *			Library wide thread interfaces			*
+ *									*
+ ************************************************************************/
+
+/**
+ * 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
+ */
+int
+xmlGetThreadId(void)
+{
+#ifdef HAVE_PTHREAD_H
+    pthread_t id;
+    int ret;
+
+    if (libxml_is_threaded == 0)
+        return (0);
+    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
+    return find_thread(NULL);
+#else
+    return ((int) 0);
+#endif
+}
+
+/**
+ * xmlIsMainThread:
+ *
+ * xmlIsMainThread() check whether the current thread is the main thread.
+ *
+ * Returns 1 if the current thread is the main thread, 0 otherwise
+ */
+int
+xmlIsMainThread(void)
+{
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded == -1)
+        xmlInitThreads();
+    if (libxml_is_threaded == 0)
+        return (1);
+    pthread_once(&once_control, xmlOnceInit);
+#elif defined HAVE_WIN32_THREADS
+    xmlOnceInit();
+#elif defined HAVE_BEOS_THREADS
+    xmlOnceInit();
+#endif
+
+#ifdef DEBUG_THREADS
+    xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
+#endif
+#ifdef HAVE_PTHREAD_H
+    return (pthread_equal(mainthread,pthread_self()));
+#elif defined HAVE_WIN32_THREADS
+    return (mainthread == GetCurrentThreadId());
+#elif defined HAVE_BEOS_THREADS
+    return (mainthread == find_thread(NULL));
+#else
+    return (1);
+#endif
+}
+
+/**
+ * xmlLockLibrary:
+ *
+ * xmlLockLibrary() is used to take out a re-entrant lock on the libxml2
+ * library.
+ */
+void
+xmlLockLibrary(void)
+{
+#ifdef DEBUG_THREADS
+    xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");
+#endif
+    xmlRMutexLock(xmlLibraryLock);
+}
+
+/**
+ * xmlUnlockLibrary:
+ *
+ * xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2
+ * library.
+ */
+void
+xmlUnlockLibrary(void)
+{
+#ifdef DEBUG_THREADS
+    xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");
+#endif
+    xmlRMutexUnlock(xmlLibraryLock);
+}
+
+/**
+ * xmlInitThreads:
+ *
+ * xmlInitThreads() is used to to initialize all the thread related
+ * data of the libxml2 library.
+ */
+void
+xmlInitThreads(void)
+{
+#ifdef HAVE_PTHREAD_H
+    if (libxml_is_threaded == -1) {
+        if ((pthread_once != NULL) &&
+            (pthread_getspecific != NULL) &&
+            (pthread_setspecific != NULL) &&
+            (pthread_key_create != NULL) &&
+            (pthread_key_delete != NULL) &&
+            (pthread_mutex_init != NULL) &&
+            (pthread_mutex_destroy != NULL) &&
+            (pthread_mutex_lock != NULL) &&
+            (pthread_mutex_unlock != NULL) &&
+            (pthread_cond_init != NULL) &&
+            (pthread_cond_destroy != NULL) &&
+            (pthread_cond_wait != NULL) &&
+            (pthread_equal != NULL) &&
+            (pthread_self != NULL) &&
+            (pthread_cond_signal != NULL)) {
+            libxml_is_threaded = 1;
+
+/* fprintf(stderr, "Running multithreaded\n"); */
+        } else {
+
+/* fprintf(stderr, "Running without multithread\n"); */
+            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
+}
+
+/**
+ * xmlCleanupThreads:
+ *
+ * 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)
+{
+#ifdef DEBUG_THREADS
+    xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
+#endif
+#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;
+
+        EnterCriticalSection(&cleanup_helpers_cs);
+        p = cleanup_helpers_head;
+        while (p != NULL) {
+            xmlGlobalStateCleanupHelperParams *temp = p;
+
+            p = p->next;
+            xmlFreeGlobalState(temp->memory);
+            free(temp);
+        }
+        cleanup_helpers_head = 0;
+        LeaveCriticalSection(&cleanup_helpers_cs);
+        TlsFree(globalkey);
+        globalkey = TLS_OUT_OF_INDEXES;
+    }
+    DeleteCriticalSection(&cleanup_helpers_cs);
+#endif
+}
+
+#ifdef LIBXML_THREAD_ENABLED
+
+/**
+ * xmlOnceInit
+ *
+ * xmlOnceInit() is used to initialize the value of mainthread for use
+ * in other routines. This function should only be called using
+ * pthread_once() in association with the once_control variable to ensure
+ * that the function is only called once. See man pthread_once for more
+ * details.
+ */
+static void
+xmlOnceInit(void)
+{
+#ifdef HAVE_PTHREAD_H
+    (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
+    mainthread = pthread_self();
+#elif defined(HAVE_WIN32_THREADS)
+    if (!run_once.done) {
+        if (InterlockedIncrement(&run_once.control) == 1) {
+#if !defined(HAVE_COMPILER_TLS)
+            globalkey = TlsAlloc();
+#endif
+            mainthread = GetCurrentThreadId();
+            run_once.done = 1;
+        } else {
+            /* Another thread is working; give up our slice and
+             * wait until they're done. */
+            while (!run_once.done)
+                Sleep(0);
+        }
+    }
+#elif defined HAVE_BEOS_THREADS
+    if (atomic_add(&run_once_init, 1) == 0) {
+        globalkey = tls_allocate();
+        tls_set(globalkey, NULL);
+        mainthread = find_thread(NULL);
+    } else
+        atomic_add(&run_once_init, -1);
+#endif
+}
+#endif
+
+/**
+ * DllMain:
+ * @hinstDLL: handle to DLL instance
+ * @fdwReason: Reason code for entry
+ * @lpvReserved: generic pointer (depends upon reason code)
+ *
+ * Entry point for Windows library. It is being used to free thread-specific
+ * storage.
+ *
+ * Returns TRUE always
+ */
+#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)
+#else
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+#endif
+{
+    switch (fdwReason) {
+        case DLL_THREAD_DETACH:
+            if (globalkey != TLS_OUT_OF_INDEXES) {
+                xmlGlobalState *globalval = NULL;
+                xmlGlobalStateCleanupHelperParams *p =
+                    (xmlGlobalStateCleanupHelperParams *)
+                    TlsGetValue(globalkey);
+                globalval = (xmlGlobalState *) (p ? p->memory : NULL);
+                if (globalval) {
+                    xmlFreeGlobalState(globalval);
+                    TlsSetValue(globalkey, NULL);
+                }
+                if (p) {
+                    EnterCriticalSection(&cleanup_helpers_cs);
+                    if (p == cleanup_helpers_head)
+                        cleanup_helpers_head = p->next;
+                    else
+                        p->prev->next = p->next;
+                    if (p->next != NULL)
+                        p->next->prev = p->prev;
+                    LeaveCriticalSection(&cleanup_helpers_cs);
+                    free(p);
+                }
+            }
+            break;
+    }
+    return TRUE;
+}
+#endif
+#define bottom_threads
+#include "elfgcchack.h"
diff --git a/src/tree.c b/src/tree.c
new file mode 100644
index 0000000..1e1a23a
--- /dev/null
+++ b/src/tree.c
@@ -0,0 +1,9903 @@
+/*
+ * tree.c : implementation of access function for an XML tree.
+ *
+ * References:
+ *   XHTML 1.0 W3C REC: http://www.w3.org/TR/2002/REC-xhtml1-20020801/
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h> /* for memset() only ! */
+#include <limits.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/uri.h>
+#include <libxml/entities.h>
+#include <libxml/valid.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parserInternals.h>
+#include <libxml/globals.h>
+#ifdef LIBXML_HTML_ENABLED
+#include <libxml/HTMLtree.h>
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+#include <libxml/debugXML.h>
+#endif
+
+int __xmlRegisterCallbacks = 0;
+
+/************************************************************************
+ *									*
+ *		Forward declarations					*
+ *									*
+ ************************************************************************/
+
+static xmlNsPtr
+xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
+
+static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
+
+/************************************************************************
+ *									*
+ *		Tree memory error handler				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlTreeErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlTreeErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * xmlTreeErr:
+ * @code:  the error number
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlTreeErr(int code, xmlNodePtr node, const char *extra)
+{
+    const char *msg = NULL;
+
+    switch(code) {
+        case XML_TREE_INVALID_HEX:
+	    msg = "invalid hexadecimal character value\n";
+	    break;
+	case XML_TREE_INVALID_DEC:
+	    msg = "invalid decimal character value\n";
+	    break;
+	case XML_TREE_UNTERMINATED_ENTITY:
+	    msg = "unterminated entity reference %15s\n";
+	    break;
+	case XML_TREE_NOT_UTF8:
+	    msg = "string is not in UTF-8\n";
+	    break;
+	default:
+	    msg = "unexpected error number\n";
+    }
+    __xmlSimpleError(XML_FROM_TREE, code, node, msg, extra);
+}
+
+/************************************************************************
+ *									*
+ *		A few static variables and macros			*
+ *									*
+ ************************************************************************/
+/* #undef xmlStringText */
+const xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
+/* #undef xmlStringTextNoenc */
+const xmlChar xmlStringTextNoenc[] =
+              { 't', 'e', 'x', 't', 'n', 'o', 'e', 'n', 'c', 0 };
+/* #undef xmlStringComment */
+const xmlChar xmlStringComment[] = { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
+
+static int xmlCompressMode = 0;
+static int xmlCheckDTD = 1;
+
+#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) {		\
+    xmlNodePtr ulccur = (n)->children;					\
+    if (ulccur == NULL) {						\
+        (n)->last = NULL;						\
+    } else {								\
+        while (ulccur->next != NULL) {					\
+		ulccur->parent = (n);					\
+		ulccur = ulccur->next;					\
+	}								\
+	ulccur->parent = (n);						\
+	(n)->last = ulccur;						\
+}}
+
+#define IS_STR_XML(str) ((str != NULL) && (str[0] == 'x') && \
+  (str[1] == 'm') && (str[2] == 'l') && (str[3] == 0))
+
+/* #define DEBUG_BUFFER */
+/* #define DEBUG_TREE */
+
+/************************************************************************
+ *									*
+ *		Functions to move to entities.c once the		*
+ *		API freeze is smoothen and they can be made public.	*
+ *									*
+ ************************************************************************/
+#include <libxml/hash.h>
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlGetEntityFromDtd:
+ * @dtd:  A pointer to the DTD to search
+ * @name:  The entity name
+ *
+ * Do an entity lookup in the DTD entity hash table and
+ * return the corresponding entity, if found.
+ *
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+static xmlEntityPtr
+xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+    xmlEntitiesTablePtr table;
+
+    if((dtd != NULL) && (dtd->entities != NULL)) {
+	table = (xmlEntitiesTablePtr) dtd->entities;
+	return((xmlEntityPtr) xmlHashLookup(table, name));
+	/* return(xmlGetEntityFromTable(table, name)); */
+    }
+    return(NULL);
+}
+/**
+ * xmlGetParameterEntityFromDtd:
+ * @dtd:  A pointer to the DTD to search
+ * @name:  The entity name
+ *
+ * Do an entity lookup in the DTD pararmeter entity hash table and
+ * return the corresponding entity, if found.
+ *
+ * Returns A pointer to the entity structure or NULL if not found.
+ */
+static xmlEntityPtr
+xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+    xmlEntitiesTablePtr table;
+
+    if ((dtd != NULL) && (dtd->pentities != NULL)) {
+	table = (xmlEntitiesTablePtr) dtd->pentities;
+	return((xmlEntityPtr) xmlHashLookup(table, name));
+	/* return(xmlGetEntityFromTable(table, name)); */
+    }
+    return(NULL);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/************************************************************************
+ *									*
+ *			QName handling helper				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlBuildQName:
+ * @ncname:  the Name
+ * @prefix:  the prefix
+ * @memory:  preallocated memory
+ * @len:  preallocated memory length
+ *
+ * Builds the QName @prefix:@ncname in @memory if there is enough space
+ * and prefix is not NULL nor empty, otherwise allocate a new string.
+ * If prefix is NULL or empty it returns ncname.
+ *
+ * Returns the new string which must be freed by the caller if different from
+ *         @memory and @ncname or NULL in case of error
+ */
+xmlChar *
+xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
+	      xmlChar *memory, int len) {
+    int lenn, lenp;
+    xmlChar *ret;
+
+    if (ncname == NULL) return(NULL);
+    if (prefix == NULL) return((xmlChar *) ncname);
+
+    lenn = strlen((char *) ncname);
+    lenp = strlen((char *) prefix);
+
+    if ((memory == NULL) || (len < lenn + lenp + 2)) {
+	ret = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (ret == NULL) {
+	    xmlTreeErrMemory("building QName");
+	    return(NULL);
+	}
+    } else {
+	ret = memory;
+    }
+    memcpy(&ret[0], prefix, lenp);
+    ret[lenp] = ':';
+    memcpy(&ret[lenp + 1], ncname, lenn);
+    ret[lenn + lenp + 1] = 0;
+    return(ret);
+}
+
+/**
+ * xmlSplitQName2:
+ * @name:  the full QName
+ * @prefix:  a xmlChar **
+ *
+ * parse an XML qualified name string
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns NULL if not a QName, otherwise the local part, and prefix
+ *   is updated to get the Prefix if any.
+ */
+
+xmlChar *
+xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
+    int len = 0;
+    xmlChar *ret = NULL;
+
+    if (prefix == NULL) return(NULL);
+    *prefix = NULL;
+    if (name == NULL) return(NULL);
+
+#ifndef XML_XML_NAMESPACE
+    /* xml: prefix is not really a namespace */
+    if ((name[0] == 'x') && (name[1] == 'm') &&
+        (name[2] == 'l') && (name[3] == ':'))
+	return(NULL);
+#endif
+
+    /* nasty but valid */
+    if (name[0] == ':')
+	return(NULL);
+
+    /*
+     * we are not trying to validate but just to cut, and yes it will
+     * work even if this is as set of UTF-8 encoded chars
+     */
+    while ((name[len] != 0) && (name[len] != ':'))
+	len++;
+
+    if (name[len] == 0)
+	return(NULL);
+
+    *prefix = xmlStrndup(name, len);
+    if (*prefix == NULL) {
+	xmlTreeErrMemory("QName split");
+	return(NULL);
+    }
+    ret = xmlStrdup(&name[len + 1]);
+    if (ret == NULL) {
+	xmlTreeErrMemory("QName split");
+	if (*prefix != NULL) {
+	    xmlFree(*prefix);
+	    *prefix = NULL;
+	}
+	return(NULL);
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlSplitQName3:
+ * @name:  the full QName
+ * @len: an int *
+ *
+ * parse an XML qualified name string,i
+ *
+ * returns NULL if it is not a Qualified Name, otherwise, update len
+ *         with the lenght in byte of the prefix and return a pointer
+ *         to the start of the name without the prefix
+ */
+
+const xmlChar *
+xmlSplitQName3(const xmlChar *name, int *len) {
+    int l = 0;
+
+    if (name == NULL) return(NULL);
+    if (len == NULL) return(NULL);
+
+    /* nasty but valid */
+    if (name[0] == ':')
+	return(NULL);
+
+    /*
+     * we are not trying to validate but just to cut, and yes it will
+     * work even if this is as set of UTF-8 encoded chars
+     */
+    while ((name[l] != 0) && (name[l] != ':'))
+	l++;
+
+    if (name[l] == 0)
+	return(NULL);
+
+    *len = l;
+
+    return(&name[l+1]);
+}
+
+/************************************************************************
+ *									*
+ *		Check Name, NCName and QName strings			*
+ *									*
+ ************************************************************************/
+
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+/**
+ * xmlValidateNCName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of NCName
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlValidateNCName(const xmlChar *value, int space) {
+    const xmlChar *cur = value;
+    int c,l;
+
+    if (value == NULL)
+        return(-1);
+
+    /*
+     * First quick algorithm for ASCII range
+     */
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+	(*cur == '_'))
+	cur++;
+    else
+	goto try_complex;
+    while (((*cur >= 'a') && (*cur <= 'z')) ||
+	   ((*cur >= 'A') && (*cur <= 'Z')) ||
+	   ((*cur >= '0') && (*cur <= '9')) ||
+	   (*cur == '_') || (*cur == '-') || (*cur == '.'))
+	cur++;
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (*cur == 0)
+	return(0);
+
+try_complex:
+    /*
+     * Second check for chars outside the ASCII range
+     */
+    cur = value;
+    c = CUR_SCHAR(cur, l);
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if ((!IS_LETTER(c)) && (c != '_'))
+	return(1);
+    cur += l;
+    c = CUR_SCHAR(cur, l);
+    while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') ||
+	   (c == '-') || (c == '_') || IS_COMBINING(c) ||
+	   IS_EXTENDER(c)) {
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+    }
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (c != 0)
+	return(1);
+
+    return(0);
+}
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlValidateQName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of QName
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlValidateQName(const xmlChar *value, int space) {
+    const xmlChar *cur = value;
+    int c,l;
+
+    if (value == NULL)
+        return(-1);
+    /*
+     * First quick algorithm for ASCII range
+     */
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+	(*cur == '_'))
+	cur++;
+    else
+	goto try_complex;
+    while (((*cur >= 'a') && (*cur <= 'z')) ||
+	   ((*cur >= 'A') && (*cur <= 'Z')) ||
+	   ((*cur >= '0') && (*cur <= '9')) ||
+	   (*cur == '_') || (*cur == '-') || (*cur == '.'))
+	cur++;
+    if (*cur == ':') {
+	cur++;
+	if (((*cur >= 'a') && (*cur <= 'z')) ||
+	    ((*cur >= 'A') && (*cur <= 'Z')) ||
+	    (*cur == '_'))
+	    cur++;
+	else
+	    goto try_complex;
+	while (((*cur >= 'a') && (*cur <= 'z')) ||
+	       ((*cur >= 'A') && (*cur <= 'Z')) ||
+	       ((*cur >= '0') && (*cur <= '9')) ||
+	       (*cur == '_') || (*cur == '-') || (*cur == '.'))
+	    cur++;
+    }
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (*cur == 0)
+	return(0);
+
+try_complex:
+    /*
+     * Second check for chars outside the ASCII range
+     */
+    cur = value;
+    c = CUR_SCHAR(cur, l);
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if ((!IS_LETTER(c)) && (c != '_'))
+	return(1);
+    cur += l;
+    c = CUR_SCHAR(cur, l);
+    while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') ||
+	   (c == '-') || (c == '_') || IS_COMBINING(c) ||
+	   IS_EXTENDER(c)) {
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+    }
+    if (c == ':') {
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+	if ((!IS_LETTER(c)) && (c != '_'))
+	    return(1);
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+	while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') ||
+	       (c == '-') || (c == '_') || IS_COMBINING(c) ||
+	       IS_EXTENDER(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (c != 0)
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlValidateName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of Name
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlValidateName(const xmlChar *value, int space) {
+    const xmlChar *cur = value;
+    int c,l;
+
+    if (value == NULL)
+        return(-1);
+    /*
+     * First quick algorithm for ASCII range
+     */
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+	(*cur == '_') || (*cur == ':'))
+	cur++;
+    else
+	goto try_complex;
+    while (((*cur >= 'a') && (*cur <= 'z')) ||
+	   ((*cur >= 'A') && (*cur <= 'Z')) ||
+	   ((*cur >= '0') && (*cur <= '9')) ||
+	   (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
+	cur++;
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (*cur == 0)
+	return(0);
+
+try_complex:
+    /*
+     * Second check for chars outside the ASCII range
+     */
+    cur = value;
+    c = CUR_SCHAR(cur, l);
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if ((!IS_LETTER(c)) && (c != '_') && (c != ':'))
+	return(1);
+    cur += l;
+    c = CUR_SCHAR(cur, l);
+    while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
+	   (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+    }
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (c != 0)
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlValidateNMToken:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of NMToken
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlValidateNMToken(const xmlChar *value, int space) {
+    const xmlChar *cur = value;
+    int c,l;
+
+    if (value == NULL)
+        return(-1);
+    /*
+     * First quick algorithm for ASCII range
+     */
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (((*cur >= 'a') && (*cur <= 'z')) ||
+        ((*cur >= 'A') && (*cur <= 'Z')) ||
+        ((*cur >= '0') && (*cur <= '9')) ||
+        (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
+	cur++;
+    else
+	goto try_complex;
+    while (((*cur >= 'a') && (*cur <= 'z')) ||
+	   ((*cur >= 'A') && (*cur <= 'Z')) ||
+	   ((*cur >= '0') && (*cur <= '9')) ||
+	   (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
+	cur++;
+    if (space)
+	while (IS_BLANK_CH(*cur)) cur++;
+    if (*cur == 0)
+	return(0);
+
+try_complex:
+    /*
+     * Second check for chars outside the ASCII range
+     */
+    cur = value;
+    c = CUR_SCHAR(cur, l);
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (!(IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
+        (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)))
+	return(1);
+    cur += l;
+    c = CUR_SCHAR(cur, l);
+    while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
+	   (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
+	cur += l;
+	c = CUR_SCHAR(cur, l);
+    }
+    if (space) {
+	while (IS_BLANK(c)) {
+	    cur += l;
+	    c = CUR_SCHAR(cur, l);
+	}
+    }
+    if (c != 0)
+	return(1);
+    return(0);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Allocation and deallocation of basic structures		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSetBufferAllocationScheme:
+ * @scheme:  allocation method to use
+ *
+ * Set the buffer allocation method.  Types are
+ * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
+ * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
+ *                             improves performance
+ */
+void
+xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
+    if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
+        (scheme == XML_BUFFER_ALLOC_DOUBLEIT))
+	xmlBufferAllocScheme = scheme;
+}
+
+/**
+ * xmlGetBufferAllocationScheme:
+ *
+ * Types are
+ * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
+ * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
+ *                             improves performance
+ *
+ * Returns the current allocation scheme
+ */
+xmlBufferAllocationScheme
+xmlGetBufferAllocationScheme(void) {
+    return(xmlBufferAllocScheme);
+}
+
+/**
+ * xmlNewNs:
+ * @node:  the element carrying the namespace
+ * @href:  the URI associated
+ * @prefix:  the prefix for the namespace
+ *
+ * Creation of a new Namespace. This function will refuse to create
+ * a namespace with a similar prefix than an existing one present on this
+ * node.
+ * We use href==NULL in the case of an element creation where the namespace
+ * was not defined.
+ * Returns a new namespace pointer or NULL
+ */
+xmlNsPtr
+xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
+    xmlNsPtr cur;
+
+    if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
+	return(NULL);
+
+    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
+	return(NULL);
+
+    /*
+     * Allocate a new Namespace and fill the fields.
+     */
+    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building namespace");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNs));
+    cur->type = XML_LOCAL_NAMESPACE;
+
+    if (href != NULL)
+	cur->href = xmlStrdup(href);
+    if (prefix != NULL)
+	cur->prefix = xmlStrdup(prefix);
+
+    /*
+     * Add it at the end to preserve parsing order ...
+     * and checks for existing use of the prefix
+     */
+    if (node != NULL) {
+	if (node->nsDef == NULL) {
+	    node->nsDef = cur;
+	} else {
+	    xmlNsPtr prev = node->nsDef;
+
+	    if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
+		(xmlStrEqual(prev->prefix, cur->prefix))) {
+		xmlFreeNs(cur);
+		return(NULL);
+	    }
+	    while (prev->next != NULL) {
+	        prev = prev->next;
+		if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
+		    (xmlStrEqual(prev->prefix, cur->prefix))) {
+		    xmlFreeNs(cur);
+		    return(NULL);
+		}
+	    }
+	    prev->next = cur;
+	}
+    }
+    return(cur);
+}
+
+/**
+ * xmlSetNs:
+ * @node:  a node in the document
+ * @ns:  a namespace pointer
+ *
+ * Associate a namespace to a node, a posteriori.
+ */
+void
+xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
+    if (node == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlSetNs: node == NULL\n");
+#endif
+	return;
+    }
+    node->ns = ns;
+}
+
+/**
+ * xmlFreeNs:
+ * @cur:  the namespace pointer
+ *
+ * Free up the structures associated to a namespace
+ */
+void
+xmlFreeNs(xmlNsPtr cur) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlFreeNs : ns == NULL\n");
+#endif
+	return;
+    }
+    if (cur->href != NULL) xmlFree((char *) cur->href);
+    if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
+    xmlFree(cur);
+}
+
+/**
+ * xmlFreeNsList:
+ * @cur:  the first namespace pointer
+ *
+ * Free up all the structures associated to the chained namespaces.
+ */
+void
+xmlFreeNsList(xmlNsPtr cur) {
+    xmlNsPtr next;
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlFreeNsList : ns == NULL\n");
+#endif
+	return;
+    }
+    while (cur != NULL) {
+        next = cur->next;
+        xmlFreeNs(cur);
+	cur = next;
+    }
+}
+
+/**
+ * xmlNewDtd:
+ * @doc:  the document pointer
+ * @name:  the DTD name
+ * @ExternalID:  the external ID
+ * @SystemID:  the system ID
+ *
+ * Creation of a new DTD for the external subset. To create an
+ * internal subset, use xmlCreateIntSubset().
+ *
+ * Returns a pointer to the new DTD structure
+ */
+xmlDtdPtr
+xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
+                    const xmlChar *ExternalID, const xmlChar *SystemID) {
+    xmlDtdPtr cur;
+
+    if ((doc != NULL) && (doc->extSubset != NULL)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewDtd(%s): document %s already have a DTD %s\n",
+	    /* !!! */ (char *) name, doc->name,
+	    /* !!! */ (char *)doc->extSubset->name);
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new DTD and fill the fields.
+     */
+    cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building DTD");
+	return(NULL);
+    }
+    memset(cur, 0 , sizeof(xmlDtd));
+    cur->type = XML_DTD_NODE;
+
+    if (name != NULL)
+	cur->name = xmlStrdup(name);
+    if (ExternalID != NULL)
+	cur->ExternalID = xmlStrdup(ExternalID);
+    if (SystemID != NULL)
+	cur->SystemID = xmlStrdup(SystemID);
+    if (doc != NULL)
+	doc->extSubset = cur;
+    cur->doc = doc;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * xmlGetIntSubset:
+ * @doc:  the document pointer
+ *
+ * Get the internal subset of a document
+ * Returns a pointer to the DTD structure or NULL if not found
+ */
+
+xmlDtdPtr
+xmlGetIntSubset(xmlDocPtr doc) {
+    xmlNodePtr cur;
+
+    if (doc == NULL)
+	return(NULL);
+    cur = doc->children;
+    while (cur != NULL) {
+	if (cur->type == XML_DTD_NODE)
+	    return((xmlDtdPtr) cur);
+	cur = cur->next;
+    }
+    return((xmlDtdPtr) doc->intSubset);
+}
+
+/**
+ * xmlCreateIntSubset:
+ * @doc:  the document pointer
+ * @name:  the DTD name
+ * @ExternalID:  the external (PUBLIC) ID
+ * @SystemID:  the system ID
+ *
+ * Create the internal subset of a document
+ * Returns a pointer to the new DTD structure
+ */
+xmlDtdPtr
+xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
+                   const xmlChar *ExternalID, const xmlChar *SystemID) {
+    xmlDtdPtr cur;
+
+    if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+
+     "xmlCreateIntSubset(): document %s already have an internal subset\n",
+	    doc->name);
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new DTD and fill the fields.
+     */
+    cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building internal subset");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlDtd));
+    cur->type = XML_DTD_NODE;
+
+    if (name != NULL) {
+	cur->name = xmlStrdup(name);
+	if (cur->name == NULL) {
+	    xmlTreeErrMemory("building internal subset");
+	    xmlFree(cur);
+	    return(NULL);
+	}
+    }
+    if (ExternalID != NULL) {
+	cur->ExternalID = xmlStrdup(ExternalID);
+	if (cur->ExternalID  == NULL) {
+	    xmlTreeErrMemory("building internal subset");
+	    if (cur->name != NULL)
+	        xmlFree((char *)cur->name);
+	    xmlFree(cur);
+	    return(NULL);
+	}
+    }
+    if (SystemID != NULL) {
+	cur->SystemID = xmlStrdup(SystemID);
+	if (cur->SystemID == NULL) {
+	    xmlTreeErrMemory("building internal subset");
+	    if (cur->name != NULL)
+	        xmlFree((char *)cur->name);
+	    if (cur->ExternalID != NULL)
+	        xmlFree((char *)cur->ExternalID);
+	    xmlFree(cur);
+	    return(NULL);
+	}
+    }
+    if (doc != NULL) {
+	doc->intSubset = cur;
+	cur->parent = doc;
+	cur->doc = doc;
+	if (doc->children == NULL) {
+	    doc->children = (xmlNodePtr) cur;
+	    doc->last = (xmlNodePtr) cur;
+	} else {
+	    if (doc->type == XML_HTML_DOCUMENT_NODE) {
+		xmlNodePtr prev;
+
+		prev = doc->children;
+		prev->prev = (xmlNodePtr) cur;
+		cur->next = prev;
+		doc->children = (xmlNodePtr) cur;
+	    } else {
+		xmlNodePtr next;
+
+		next = doc->children;
+		while ((next != NULL) && (next->type != XML_ELEMENT_NODE))
+		    next = next->next;
+		if (next == NULL) {
+		    cur->prev = doc->last;
+		    cur->prev->next = (xmlNodePtr) cur;
+		    cur->next = NULL;
+		    doc->last = (xmlNodePtr) cur;
+		} else {
+		    cur->next = next;
+		    cur->prev = next->prev;
+		    if (cur->prev == NULL)
+			doc->children = (xmlNodePtr) cur;
+		    else
+			cur->prev->next = (xmlNodePtr) cur;
+		    next->prev = (xmlNodePtr) cur;
+		}
+	    }
+	}
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * DICT_FREE:
+ * @str:  a string
+ *
+ * Free a string if it is not owned by the "dict" dictionnary in the
+ * current scope
+ */
+#define DICT_FREE(str)						\
+	if ((str) && ((!dict) ||				\
+	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
+	    xmlFree((char *)(str));
+
+
+/**
+ * DICT_COPY:
+ * @str:  a string
+ *
+ * Copy a string using a "dict" dictionnary in the current scope,
+ * if availabe.
+ */
+#define DICT_COPY(str, cpy) \
+    if (str) { \
+	if (dict) { \
+	    if (xmlDictOwns(dict, (const xmlChar *)(str))) \
+		cpy = (xmlChar *) (str); \
+	    else \
+		cpy = (xmlChar *) xmlDictLookup((dict), (const xmlChar *)(str), -1); \
+	} else \
+	    cpy = xmlStrdup((const xmlChar *)(str)); }
+
+/**
+ * DICT_CONST_COPY:
+ * @str:  a string
+ *
+ * Copy a string using a "dict" dictionnary in the current scope,
+ * if availabe.
+ */
+#define DICT_CONST_COPY(str, cpy) \
+    if (str) { \
+	if (dict) { \
+	    if (xmlDictOwns(dict, (const xmlChar *)(str))) \
+		cpy = (const xmlChar *) (str); \
+	    else \
+		cpy = xmlDictLookup((dict), (const xmlChar *)(str), -1); \
+	} else \
+	    cpy = (const xmlChar *) xmlStrdup((const xmlChar *)(str)); }
+
+
+/**
+ * xmlFreeDtd:
+ * @cur:  the DTD structure to free up
+ *
+ * Free a DTD structure.
+ */
+void
+xmlFreeDtd(xmlDtdPtr cur) {
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) {
+	return;
+    }
+    if (cur->doc != NULL) dict = cur->doc->dict;
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
+    if (cur->children != NULL) {
+	xmlNodePtr next, c = cur->children;
+
+	/*
+	 * Cleanup all nodes which are not part of the specific lists
+	 * of notations, elements, attributes and entities.
+	 */
+        while (c != NULL) {
+	    next = c->next;
+	    if ((c->type != XML_NOTATION_NODE) &&
+	        (c->type != XML_ELEMENT_DECL) &&
+		(c->type != XML_ATTRIBUTE_DECL) &&
+		(c->type != XML_ENTITY_DECL)) {
+		xmlUnlinkNode(c);
+		xmlFreeNode(c);
+	    }
+	    c = next;
+	}
+    }
+    DICT_FREE(cur->name)
+    DICT_FREE(cur->SystemID)
+    DICT_FREE(cur->ExternalID)
+    /* TODO !!! */
+    if (cur->notations != NULL)
+        xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
+
+    if (cur->elements != NULL)
+        xmlFreeElementTable((xmlElementTablePtr) cur->elements);
+    if (cur->attributes != NULL)
+        xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
+    if (cur->entities != NULL)
+        xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+    if (cur->pentities != NULL)
+        xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
+
+    xmlFree(cur);
+}
+
+/**
+ * xmlNewDoc:
+ * @version:  xmlChar string giving the version of XML "1.0"
+ *
+ * Creates a new XML document
+ *
+ * Returns a new document
+ */
+xmlDocPtr
+xmlNewDoc(const xmlChar *version) {
+    xmlDocPtr cur;
+
+    if (version == NULL)
+	version = (const xmlChar *) "1.0";
+
+    /*
+     * Allocate a new document and fill the fields.
+     */
+    cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building doc");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlDoc));
+    cur->type = XML_DOCUMENT_NODE;
+
+    cur->version = xmlStrdup(version);
+    if (cur->version == NULL) {
+	xmlTreeErrMemory("building doc");
+	xmlFree(cur);
+	return(NULL);
+    }
+    cur->standalone = -1;
+    cur->compression = -1; /* not initialized */
+    cur->doc = cur;
+    cur->parseFlags = 0;
+    cur->properties = XML_DOC_USERBUILT;
+    /*
+     * The in memory encoding is always UTF8
+     * This field will never change and would
+     * be obsolete if not for binary compatibility.
+     */
+    cur->charset = XML_CHAR_ENCODING_UTF8;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * xmlFreeDoc:
+ * @cur:  pointer to the document
+ *
+ * Free up all the structures used by a document, tree included.
+ */
+void
+xmlFreeDoc(xmlDocPtr cur) {
+    xmlDtdPtr extSubset, intSubset;
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlFreeDoc : document == NULL\n");
+#endif
+	return;
+    }
+#ifdef LIBXML_DEBUG_RUNTIME
+#ifdef LIBXML_DEBUG_ENABLED
+    xmlDebugCheckDocument(stderr, cur);
+#endif
+#endif
+
+    if (cur != NULL) dict = cur->dict;
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
+    /*
+     * Do this before freeing the children list to avoid ID lookups
+     */
+    if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
+    cur->ids = NULL;
+    if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
+    cur->refs = NULL;
+    extSubset = cur->extSubset;
+    intSubset = cur->intSubset;
+    if (intSubset == extSubset)
+	extSubset = NULL;
+    if (extSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) cur->extSubset);
+	cur->extSubset = NULL;
+	xmlFreeDtd(extSubset);
+    }
+    if (intSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) cur->intSubset);
+	cur->intSubset = NULL;
+	xmlFreeDtd(intSubset);
+    }
+
+    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+    if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
+
+    DICT_FREE(cur->version)
+    DICT_FREE(cur->name)
+    DICT_FREE(cur->encoding)
+    DICT_FREE(cur->URL)
+    xmlFree(cur);
+    if (dict) xmlDictFree(dict);
+}
+
+/**
+ * xmlStringLenGetNodeList:
+ * @doc:  the document
+ * @value:  the value of the text
+ * @len:  the length of the string value
+ *
+ * Parse the value string and build the node list associated. Should
+ * produce a flat tree with only TEXTs and ENTITY_REFs.
+ * Returns a pointer to the first child
+ */
+xmlNodePtr
+xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
+    xmlNodePtr ret = NULL, last = NULL;
+    xmlNodePtr node;
+    xmlChar *val;
+    const xmlChar *cur = value, *end = cur + len;
+    const xmlChar *q;
+    xmlEntityPtr ent;
+
+    if (value == NULL) return(NULL);
+
+    q = cur;
+    while ((cur < end) && (*cur != 0)) {
+	if (cur[0] == '&') {
+	    int charval = 0;
+	    xmlChar tmp;
+
+	    /*
+	     * Save the current text.
+	     */
+            if (cur != q) {
+		if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
+		    xmlNodeAddContentLen(last, q, cur - q);
+		} else {
+		    node = xmlNewDocTextLen(doc, q, cur - q);
+		    if (node == NULL) return(ret);
+		    if (last == NULL)
+			last = ret = node;
+		    else {
+			last->next = node;
+			node->prev = last;
+			last = node;
+		    }
+		}
+	    }
+	    q = cur;
+	    if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) {
+		cur += 3;
+		if (cur < end)
+		    tmp = *cur;
+		else
+		    tmp = 0;
+		while (tmp != ';') { /* Non input consuming loop */
+		    if ((tmp >= '0') && (tmp <= '9'))
+			charval = charval * 16 + (tmp - '0');
+		    else if ((tmp >= 'a') && (tmp <= 'f'))
+			charval = charval * 16 + (tmp - 'a') + 10;
+		    else if ((tmp >= 'A') && (tmp <= 'F'))
+			charval = charval * 16 + (tmp - 'A') + 10;
+		    else {
+			xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc,
+			           NULL);
+			charval = 0;
+			break;
+		    }
+		    cur++;
+		    if (cur < end)
+			tmp = *cur;
+		    else
+			tmp = 0;
+		}
+		if (tmp == ';')
+		    cur++;
+		q = cur;
+	    } else if ((cur + 1 < end) && (cur[1] == '#')) {
+		cur += 2;
+		if (cur < end)
+		    tmp = *cur;
+		else
+		    tmp = 0;
+		while (tmp != ';') { /* Non input consuming loops */
+		    if ((tmp >= '0') && (tmp <= '9'))
+			charval = charval * 10 + (tmp - '0');
+		    else {
+			xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc,
+			           NULL);
+			charval = 0;
+			break;
+		    }
+		    cur++;
+		    if (cur < end)
+			tmp = *cur;
+		    else
+			tmp = 0;
+		}
+		if (tmp == ';')
+		    cur++;
+		q = cur;
+	    } else {
+		/*
+		 * Read the entity string
+		 */
+		cur++;
+		q = cur;
+		while ((cur < end) && (*cur != 0) && (*cur != ';')) cur++;
+		if ((cur >= end) || (*cur == 0)) {
+		    xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc,
+		               (const char *) q);
+		    return(ret);
+		}
+		if (cur != q) {
+		    /*
+		     * Predefined entities don't generate nodes
+		     */
+		    val = xmlStrndup(q, cur - q);
+		    ent = xmlGetDocEntity(doc, val);
+		    if ((ent != NULL) &&
+			(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+			if (last == NULL) {
+			    node = xmlNewDocText(doc, ent->content);
+			    last = ret = node;
+			} else if (last->type != XML_TEXT_NODE) {
+			    node = xmlNewDocText(doc, ent->content);
+			    last = xmlAddNextSibling(last, node);
+			} else
+			    xmlNodeAddContent(last, ent->content);
+
+		    } else {
+			/*
+			 * Create a new REFERENCE_REF node
+			 */
+			node = xmlNewReference(doc, val);
+			if (node == NULL) {
+			    if (val != NULL) xmlFree(val);
+			    return(ret);
+			}
+			else if ((ent != NULL) && (ent->children == NULL)) {
+			    xmlNodePtr temp;
+
+			    ent->children = xmlStringGetNodeList(doc,
+				    (const xmlChar*)node->content);
+			    ent->owner = 1;
+			    temp = ent->children;
+			    while (temp) {
+				temp->parent = (xmlNodePtr)ent;
+				ent->last = temp;
+				temp = temp->next;
+			    }
+			}
+			if (last == NULL) {
+			    last = ret = node;
+			} else {
+			    last = xmlAddNextSibling(last, node);
+			}
+		    }
+		    xmlFree(val);
+		}
+		cur++;
+		q = cur;
+	    }
+	    if (charval != 0) {
+		xmlChar buf[10];
+		int l;
+
+		l = xmlCopyCharMultiByte(buf, charval);
+		buf[l] = 0;
+		node = xmlNewDocText(doc, buf);
+		if (node != NULL) {
+		    if (last == NULL) {
+			last = ret = node;
+		    } else {
+			last = xmlAddNextSibling(last, node);
+		    }
+		}
+		charval = 0;
+	    }
+	} else
+	    cur++;
+    }
+    if ((cur != q) || (ret == NULL)) {
+        /*
+	 * Handle the last piece of text.
+	 */
+	if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
+	    xmlNodeAddContentLen(last, q, cur - q);
+	} else {
+	    node = xmlNewDocTextLen(doc, q, cur - q);
+	    if (node == NULL) return(ret);
+	    if (last == NULL) {
+		ret = node;
+	    } else {
+		xmlAddNextSibling(last, node);
+	    }
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlStringGetNodeList:
+ * @doc:  the document
+ * @value:  the value of the attribute
+ *
+ * Parse the value string and build the node list associated. Should
+ * produce a flat tree with only TEXTs and ENTITY_REFs.
+ * Returns a pointer to the first child
+ */
+xmlNodePtr
+xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
+    xmlNodePtr ret = NULL, last = NULL;
+    xmlNodePtr node;
+    xmlChar *val;
+    const xmlChar *cur = value;
+    const xmlChar *q;
+    xmlEntityPtr ent;
+
+    if (value == NULL) return(NULL);
+
+    q = cur;
+    while (*cur != 0) {
+	if (cur[0] == '&') {
+	    int charval = 0;
+	    xmlChar tmp;
+
+	    /*
+	     * Save the current text.
+	     */
+            if (cur != q) {
+		if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
+		    xmlNodeAddContentLen(last, q, cur - q);
+		} else {
+		    node = xmlNewDocTextLen(doc, q, cur - q);
+		    if (node == NULL) return(ret);
+		    if (last == NULL)
+			last = ret = node;
+		    else {
+			last->next = node;
+			node->prev = last;
+			last = node;
+		    }
+		}
+	    }
+	    q = cur;
+	    if ((cur[1] == '#') && (cur[2] == 'x')) {
+		cur += 3;
+		tmp = *cur;
+		while (tmp != ';') { /* Non input consuming loop */
+		    if ((tmp >= '0') && (tmp <= '9'))
+			charval = charval * 16 + (tmp - '0');
+		    else if ((tmp >= 'a') && (tmp <= 'f'))
+			charval = charval * 16 + (tmp - 'a') + 10;
+		    else if ((tmp >= 'A') && (tmp <= 'F'))
+			charval = charval * 16 + (tmp - 'A') + 10;
+		    else {
+			xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc,
+			           NULL);
+			charval = 0;
+			break;
+		    }
+		    cur++;
+		    tmp = *cur;
+		}
+		if (tmp == ';')
+		    cur++;
+		q = cur;
+	    } else if  (cur[1] == '#') {
+		cur += 2;
+		tmp = *cur;
+		while (tmp != ';') { /* Non input consuming loops */
+		    if ((tmp >= '0') && (tmp <= '9'))
+			charval = charval * 10 + (tmp - '0');
+		    else {
+			xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc,
+			           NULL);
+			charval = 0;
+			break;
+		    }
+		    cur++;
+		    tmp = *cur;
+		}
+		if (tmp == ';')
+		    cur++;
+		q = cur;
+	    } else {
+		/*
+		 * Read the entity string
+		 */
+		cur++;
+		q = cur;
+		while ((*cur != 0) && (*cur != ';')) cur++;
+		if (*cur == 0) {
+		    xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY,
+		               (xmlNodePtr) doc, (const char *) q);
+		    return(ret);
+		}
+		if (cur != q) {
+		    /*
+		     * Predefined entities don't generate nodes
+		     */
+		    val = xmlStrndup(q, cur - q);
+		    ent = xmlGetDocEntity(doc, val);
+		    if ((ent != NULL) &&
+			(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+			if (last == NULL) {
+			    node = xmlNewDocText(doc, ent->content);
+			    last = ret = node;
+			} else if (last->type != XML_TEXT_NODE) {
+			    node = xmlNewDocText(doc, ent->content);
+			    last = xmlAddNextSibling(last, node);
+			} else
+			    xmlNodeAddContent(last, ent->content);
+
+		    } else {
+			/*
+			 * Create a new REFERENCE_REF node
+			 */
+			node = xmlNewReference(doc, val);
+			if (node == NULL) {
+			    if (val != NULL) xmlFree(val);
+			    return(ret);
+			}
+			else if ((ent != NULL) && (ent->children == NULL)) {
+			    xmlNodePtr temp;
+
+			    ent->children = xmlStringGetNodeList(doc,
+				    (const xmlChar*)node->content);
+			    ent->owner = 1;
+			    temp = ent->children;
+			    while (temp) {
+				temp->parent = (xmlNodePtr)ent;
+				temp = temp->next;
+			    }
+			}
+			if (last == NULL) {
+			    last = ret = node;
+			} else {
+			    last = xmlAddNextSibling(last, node);
+			}
+		    }
+		    xmlFree(val);
+		}
+		cur++;
+		q = cur;
+	    }
+	    if (charval != 0) {
+		xmlChar buf[10];
+		int len;
+
+		len = xmlCopyCharMultiByte(buf, charval);
+		buf[len] = 0;
+		node = xmlNewDocText(doc, buf);
+		if (node != NULL) {
+		    if (last == NULL) {
+			last = ret = node;
+		    } else {
+			last = xmlAddNextSibling(last, node);
+		    }
+		}
+	    }
+	} else
+	    cur++;
+    }
+    if ((cur != q) || (ret == NULL)) {
+        /*
+	 * Handle the last piece of text.
+	 */
+	if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
+	    xmlNodeAddContentLen(last, q, cur - q);
+	} else {
+	    node = xmlNewDocTextLen(doc, q, cur - q);
+	    if (node == NULL) return(ret);
+	    if (last == NULL) {
+		last = ret = node;
+	    } else {
+		last = xmlAddNextSibling(last, node);
+	    }
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlNodeListGetString:
+ * @doc:  the document
+ * @list:  a Node list
+ * @inLine:  should we replace entity contents or show their external form
+ *
+ * Build the string equivalent to the text contained in the Node list
+ * made of TEXTs and ENTITY_REFs
+ *
+ * Returns a pointer to the string copy, the caller must free it with xmlFree().
+ */
+xmlChar *
+xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+{
+    xmlNodePtr node = list;
+    xmlChar *ret = NULL;
+    xmlEntityPtr ent;
+
+    if (list == NULL)
+        return (NULL);
+
+    while (node != NULL) {
+        if ((node->type == XML_TEXT_NODE) ||
+            (node->type == XML_CDATA_SECTION_NODE)) {
+            if (inLine) {
+                ret = xmlStrcat(ret, node->content);
+            } else {
+                xmlChar *buffer;
+
+                buffer = xmlEncodeEntitiesReentrant(doc, node->content);
+                if (buffer != NULL) {
+                    ret = xmlStrcat(ret, buffer);
+                    xmlFree(buffer);
+                }
+            }
+        } else if (node->type == XML_ENTITY_REF_NODE) {
+            if (inLine) {
+                ent = xmlGetDocEntity(doc, node->name);
+                if (ent != NULL) {
+                    xmlChar *buffer;
+
+                    /* an entity content can be any "well balanced chunk",
+                     * i.e. the result of the content [43] production:
+                     * http://www.w3.org/TR/REC-xml#NT-content.
+                     * So it can contain text, CDATA section or nested
+                     * entity reference nodes (among others).
+                     * -> we recursive  call xmlNodeListGetString()
+                     * which handles these types */
+                    buffer = xmlNodeListGetString(doc, ent->children, 1);
+                    if (buffer != NULL) {
+                        ret = xmlStrcat(ret, buffer);
+                        xmlFree(buffer);
+                    }
+                } else {
+                    ret = xmlStrcat(ret, node->content);
+                }
+            } else {
+                xmlChar buf[2];
+
+                buf[0] = '&';
+                buf[1] = 0;
+                ret = xmlStrncat(ret, buf, 1);
+                ret = xmlStrcat(ret, node->name);
+                buf[0] = ';';
+                buf[1] = 0;
+                ret = xmlStrncat(ret, buf, 1);
+            }
+        }
+#if 0
+        else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlGetNodeListString : invalid node type %d\n",
+                            node->type);
+        }
+#endif
+        node = node->next;
+    }
+    return (ret);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNodeListGetRawString:
+ * @doc:  the document
+ * @list:  a Node list
+ * @inLine:  should we replace entity contents or show their external form
+ *
+ * Builds the string equivalent to the text contained in the Node list
+ * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
+ * this function doesn't do any character encoding handling.
+ *
+ * Returns a pointer to the string copy, the caller must free it with xmlFree().
+ */
+xmlChar *
+xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+{
+    xmlNodePtr node = list;
+    xmlChar *ret = NULL;
+    xmlEntityPtr ent;
+
+    if (list == NULL)
+        return (NULL);
+
+    while (node != NULL) {
+        if ((node->type == XML_TEXT_NODE) ||
+            (node->type == XML_CDATA_SECTION_NODE)) {
+            if (inLine) {
+                ret = xmlStrcat(ret, node->content);
+            } else {
+                xmlChar *buffer;
+
+                buffer = xmlEncodeSpecialChars(doc, node->content);
+                if (buffer != NULL) {
+                    ret = xmlStrcat(ret, buffer);
+                    xmlFree(buffer);
+                }
+            }
+        } else if (node->type == XML_ENTITY_REF_NODE) {
+            if (inLine) {
+                ent = xmlGetDocEntity(doc, node->name);
+                if (ent != NULL) {
+                    xmlChar *buffer;
+
+                    /* an entity content can be any "well balanced chunk",
+                     * i.e. the result of the content [43] production:
+                     * http://www.w3.org/TR/REC-xml#NT-content.
+                     * So it can contain text, CDATA section or nested
+                     * entity reference nodes (among others).
+                     * -> we recursive  call xmlNodeListGetRawString()
+                     * which handles these types */
+                    buffer =
+                        xmlNodeListGetRawString(doc, ent->children, 1);
+                    if (buffer != NULL) {
+                        ret = xmlStrcat(ret, buffer);
+                        xmlFree(buffer);
+                    }
+                } else {
+                    ret = xmlStrcat(ret, node->content);
+                }
+            } else {
+                xmlChar buf[2];
+
+                buf[0] = '&';
+                buf[1] = 0;
+                ret = xmlStrncat(ret, buf, 1);
+                ret = xmlStrcat(ret, node->name);
+                buf[0] = ';';
+                buf[1] = 0;
+                ret = xmlStrncat(ret, buf, 1);
+            }
+        }
+#if 0
+        else {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlGetNodeListString : invalid node type %d\n",
+                            node->type);
+        }
+#endif
+        node = node->next;
+    }
+    return (ret);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+static xmlAttrPtr
+xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
+                   const xmlChar * name, const xmlChar * value,
+                   int eatname)
+{
+    xmlAttrPtr cur;
+    xmlDocPtr doc = NULL;
+
+    if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) {
+        if ((eatname == 1) &&
+	    ((node->doc == NULL) ||
+	     (!(xmlDictOwns(node->doc->dict, name)))))
+            xmlFree((xmlChar *) name);
+        return (NULL);
+    }
+
+    /*
+     * Allocate a new property and fill the fields.
+     */
+    cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
+    if (cur == NULL) {
+        if ((eatname == 1) &&
+	    ((node == NULL) || (node->doc == NULL) ||
+	     (!(xmlDictOwns(node->doc->dict, name)))))
+            xmlFree((xmlChar *) name);
+        xmlTreeErrMemory("building attribute");
+        return (NULL);
+    }
+    memset(cur, 0, sizeof(xmlAttr));
+    cur->type = XML_ATTRIBUTE_NODE;
+
+    cur->parent = node;
+    if (node != NULL) {
+        doc = node->doc;
+        cur->doc = doc;
+    }
+    cur->ns = ns;
+
+    if (eatname == 0) {
+        if ((doc != NULL) && (doc->dict != NULL))
+            cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1);
+        else
+            cur->name = xmlStrdup(name);
+    } else
+        cur->name = name;
+
+    if (value != NULL) {
+        xmlNodePtr tmp;
+
+        if(!xmlCheckUTF8(value)) {
+            xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) doc,
+                       NULL);
+            if (doc != NULL)
+                doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+        }
+        cur->children = xmlNewDocText(doc, value);
+        cur->last = NULL;
+        tmp = cur->children;
+        while (tmp != NULL) {
+            tmp->parent = (xmlNodePtr) cur;
+            if (tmp->next == NULL)
+                cur->last = tmp;
+            tmp = tmp->next;
+        }
+    }
+
+    /*
+     * Add it at the end to preserve parsing order ...
+     */
+    if (node != NULL) {
+        if (node->properties == NULL) {
+            node->properties = cur;
+        } else {
+            xmlAttrPtr prev = node->properties;
+
+            while (prev->next != NULL)
+                prev = prev->next;
+            prev->next = cur;
+            cur->prev = prev;
+        }
+    }
+
+    if ((value != NULL) && (node != NULL) &&
+        (xmlIsID(node->doc, node, cur) == 1))
+        xmlAddID(NULL, node->doc, value, cur);
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+        xmlRegisterNodeDefaultValue((xmlNodePtr) cur);
+    return (cur);
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlNewProp:
+ * @node:  the holding node
+ * @name:  the name of the attribute
+ * @value:  the value of the attribute
+ *
+ * Create a new property carried by a node.
+ * Returns a pointer to the attribute
+ */
+xmlAttrPtr
+xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewProp : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+	return xmlNewPropInternal(node, NULL, name, value, 0);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNewNsProp:
+ * @node:  the holding node
+ * @ns:  the namespace
+ * @name:  the name of the attribute
+ * @value:  the value of the attribute
+ *
+ * Create a new property tagged with a namespace and carried by a node.
+ * Returns a pointer to the attribute
+ */
+xmlAttrPtr
+xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
+           const xmlChar *value) {
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewNsProp : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    return xmlNewPropInternal(node, ns, name, value, 0);
+}
+
+/**
+ * xmlNewNsPropEatName:
+ * @node:  the holding node
+ * @ns:  the namespace
+ * @name:  the name of the attribute
+ * @value:  the value of the attribute
+ *
+ * Create a new property tagged with a namespace and carried by a node.
+ * Returns a pointer to the attribute
+ */
+xmlAttrPtr
+xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
+           const xmlChar *value) {
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewNsPropEatName : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    return xmlNewPropInternal(node, ns, name, value, 1);
+}
+
+/**
+ * xmlNewDocProp:
+ * @doc:  the document
+ * @name:  the name of the attribute
+ * @value:  the value of the attribute
+ *
+ * Create a new property carried by a document.
+ * Returns a pointer to the attribute
+ */
+xmlAttrPtr
+xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
+    xmlAttrPtr cur;
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewDocProp : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new property and fill the fields.
+     */
+    cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building attribute");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlAttr));
+    cur->type = XML_ATTRIBUTE_NODE;
+
+    if ((doc != NULL) && (doc->dict != NULL))
+	cur->name = xmlDictLookup(doc->dict, name, -1);
+    else
+	cur->name = xmlStrdup(name);
+    cur->doc = doc;
+    if (value != NULL) {
+	xmlNodePtr tmp;
+
+	cur->children = xmlStringGetNodeList(doc, value);
+	cur->last = NULL;
+
+	tmp = cur->children;
+	while (tmp != NULL) {
+	    tmp->parent = (xmlNodePtr) cur;
+	    if (tmp->next == NULL)
+		cur->last = tmp;
+	    tmp = tmp->next;
+	}
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * xmlFreePropList:
+ * @cur:  the first property in the list
+ *
+ * Free a property and all its siblings, all the children are freed too.
+ */
+void
+xmlFreePropList(xmlAttrPtr cur) {
+    xmlAttrPtr next;
+    if (cur == NULL) return;
+    while (cur != NULL) {
+        next = cur->next;
+        xmlFreeProp(cur);
+	cur = next;
+    }
+}
+
+/**
+ * xmlFreeProp:
+ * @cur:  an attribute
+ *
+ * Free one attribute, all the content is freed too
+ */
+void
+xmlFreeProp(xmlAttrPtr cur) {
+    xmlDictPtr dict = NULL;
+    if (cur == NULL) return;
+
+    if (cur->doc != NULL) dict = cur->doc->dict;
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
+    /* Check for ID removal -> leading to invalid references ! */
+    if ((cur->doc != NULL) && (cur->atype == XML_ATTRIBUTE_ID)) {
+	    xmlRemoveID(cur->doc, cur);
+    }
+    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+    DICT_FREE(cur->name)
+    xmlFree(cur);
+}
+
+/**
+ * xmlRemoveProp:
+ * @cur:  an attribute
+ *
+ * Unlink and free one attribute, all the content is freed too
+ * Note this doesn't work for namespace definition attributes
+ *
+ * Returns 0 if success and -1 in case of error.
+ */
+int
+xmlRemoveProp(xmlAttrPtr cur) {
+    xmlAttrPtr tmp;
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlRemoveProp : cur == NULL\n");
+#endif
+	return(-1);
+    }
+    if (cur->parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlRemoveProp : cur->parent == NULL\n");
+#endif
+	return(-1);
+    }
+    tmp = cur->parent->properties;
+    if (tmp == cur) {
+        cur->parent->properties = cur->next;
+		if (cur->next != NULL)
+			cur->next->prev = NULL;
+	xmlFreeProp(cur);
+	return(0);
+    }
+    while (tmp != NULL) {
+	if (tmp->next == cur) {
+	    tmp->next = cur->next;
+	    if (tmp->next != NULL)
+		tmp->next->prev = tmp;
+	    xmlFreeProp(cur);
+	    return(0);
+	}
+        tmp = tmp->next;
+    }
+#ifdef DEBUG_TREE
+    xmlGenericError(xmlGenericErrorContext,
+	    "xmlRemoveProp : attribute not owned by its node\n");
+#endif
+    return(-1);
+}
+
+/**
+ * xmlNewDocPI:
+ * @doc:  the target document
+ * @name:  the processing instruction name
+ * @content:  the PI content
+ *
+ * Creation of a processing instruction element.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewPI : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building PI");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_PI_NODE;
+
+    if ((doc != NULL) && (doc->dict != NULL))
+        cur->name = xmlDictLookup(doc->dict, name, -1);
+    else
+	cur->name = xmlStrdup(name);
+    if (content != NULL) {
+	cur->content = xmlStrdup(content);
+    }
+    cur->doc = doc;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * xmlNewPI:
+ * @name:  the processing instruction name
+ * @content:  the PI content
+ *
+ * Creation of a processing instruction element.
+ * Use xmlDocNewPI preferably to get string interning
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewPI(const xmlChar *name, const xmlChar *content) {
+    return(xmlNewDocPI(NULL, name, content));
+}
+
+/**
+ * xmlNewNode:
+ * @ns:  namespace if any
+ * @name:  the node name
+ *
+ * Creation of a new node element. @ns is optional (NULL).
+ *
+ * Returns a pointer to the new node object. Uses xmlStrdup() to make
+ * copy of @name.
+ */
+xmlNodePtr
+xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
+    xmlNodePtr cur;
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewNode : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building node");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_ELEMENT_NODE;
+
+    cur->name = xmlStrdup(name);
+    cur->ns = ns;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewNodeEatName:
+ * @ns:  namespace if any
+ * @name:  the node name
+ *
+ * Creation of a new node element. @ns is optional (NULL).
+ *
+ * Returns a pointer to the new node object, with pointer @name as
+ * new node's name. Use xmlNewNode() if a copy of @name string is
+ * is needed as new node's name.
+ */
+xmlNodePtr
+xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
+    xmlNodePtr cur;
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewNode : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building node");
+	/* we can't check here that name comes from the doc dictionnary */
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_ELEMENT_NODE;
+
+    cur->name = name;
+    cur->ns = ns;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
+    return(cur);
+}
+
+/**
+ * xmlNewDocNode:
+ * @doc:  the document
+ * @ns:  namespace if any
+ * @name:  the node name
+ * @content:  the XML text content if any
+ *
+ * Creation of a new node element within a document. @ns and @content
+ * are optional (NULL).
+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
+ *       references, but XML special chars need to be escaped first by using
+ *       xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
+ *       need entities support.
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
+              const xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    if ((doc != NULL) && (doc->dict != NULL))
+        cur = xmlNewNodeEatName(ns, (xmlChar *)
+	                        xmlDictLookup(doc->dict, name, -1));
+    else
+	cur = xmlNewNode(ns, name);
+    if (cur != NULL) {
+        cur->doc = doc;
+	if (content != NULL) {
+	    cur->children = xmlStringGetNodeList(doc, content);
+	    UPDATE_LAST_CHILD_AND_PARENT(cur)
+	}
+    }
+
+    return(cur);
+}
+
+/**
+ * xmlNewDocNodeEatName:
+ * @doc:  the document
+ * @ns:  namespace if any
+ * @name:  the node name
+ * @content:  the XML text content if any
+ *
+ * Creation of a new node element within a document. @ns and @content
+ * are optional (NULL).
+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
+ *       references, but XML special chars need to be escaped first by using
+ *       xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
+ *       need entities support.
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
+              xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    cur = xmlNewNodeEatName(ns, name);
+    if (cur != NULL) {
+        cur->doc = doc;
+	if (content != NULL) {
+	    cur->children = xmlStringGetNodeList(doc, content);
+	    UPDATE_LAST_CHILD_AND_PARENT(cur)
+	}
+    } else {
+        /* if name don't come from the doc dictionnary free it here */
+        if ((name != NULL) && (doc != NULL) &&
+	    (!(xmlDictOwns(doc->dict, name))))
+	    xmlFree(name);
+    }
+    return(cur);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNewDocRawNode:
+ * @doc:  the document
+ * @ns:  namespace if any
+ * @name:  the node name
+ * @content:  the text content if any
+ *
+ * Creation of a new node element within a document. @ns and @content
+ * are optional (NULL).
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
+                 const xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    cur = xmlNewDocNode(doc, ns, name, NULL);
+    if (cur != NULL) {
+        cur->doc = doc;
+	if (content != NULL) {
+	    cur->children = xmlNewDocText(doc, content);
+	    UPDATE_LAST_CHILD_AND_PARENT(cur)
+	}
+    }
+    return(cur);
+}
+
+/**
+ * xmlNewDocFragment:
+ * @doc:  the document owning the fragment
+ *
+ * Creation of a new Fragment node.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocFragment(xmlDocPtr doc) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new DocumentFragment node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building fragment");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_DOCUMENT_FRAG_NODE;
+
+    cur->doc = doc;
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNewText:
+ * @content:  the text content
+ *
+ * Creation of a new text node.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewText(const xmlChar *content) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building text");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_TEXT_NODE;
+
+    cur->name = xmlStringText;
+    if (content != NULL) {
+	cur->content = xmlStrdup(content);
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNewTextChild:
+ * @parent:  the parent node
+ * @ns:  a namespace if any
+ * @name:  the name of the child
+ * @content:  the text content of the child if any.
+ *
+ * Creation of a new child element, added at the end of @parent children list.
+ * @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
+ * created element inherits the namespace of @parent. If @content is non NULL,
+ * a child TEXT node will be created containing the string @content.
+ * NOTE: Use xmlNewChild() if @content will contain entities that need to be
+ * preserved. Use this function, xmlNewTextChild(), if you need to ensure that
+ * reserved XML chars that might appear in @content, such as the ampersand,
+ * greater-than or less-than signs, are automatically replaced by their XML
+ * escaped entity representations.
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
+            const xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur, prev;
+
+    if (parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextChild : parent == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextChild : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node
+     */
+    if (parent->type == XML_ELEMENT_NODE) {
+	if (ns == NULL)
+	    cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
+	else
+	    cur = xmlNewDocRawNode(parent->doc, ns, name, content);
+    } else if ((parent->type == XML_DOCUMENT_NODE) ||
+	       (parent->type == XML_HTML_DOCUMENT_NODE)) {
+	if (ns == NULL)
+	    cur = xmlNewDocRawNode((xmlDocPtr) parent, NULL, name, content);
+	else
+	    cur = xmlNewDocRawNode((xmlDocPtr) parent, ns, name, content);
+    } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
+	    cur = xmlNewDocRawNode( parent->doc, ns, name, content);
+    } else {
+	return(NULL);
+    }
+    if (cur == NULL) return(NULL);
+
+    /*
+     * add the new element at the end of the children list.
+     */
+    cur->type = XML_ELEMENT_NODE;
+    cur->parent = parent;
+    cur->doc = parent->doc;
+    if (parent->children == NULL) {
+        parent->children = cur;
+	parent->last = cur;
+    } else {
+        prev = parent->last;
+	prev->next = cur;
+	cur->prev = prev;
+	parent->last = cur;
+    }
+
+    return(cur);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNewCharRef:
+ * @doc: the document
+ * @name:  the char ref string, starting with # or "&# ... ;"
+ *
+ * Creation of a new character reference node.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
+    xmlNodePtr cur;
+
+    if (name == NULL)
+        return(NULL);
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building character reference");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_ENTITY_REF_NODE;
+
+    cur->doc = doc;
+    if (name[0] == '&') {
+        int len;
+        name++;
+	len = xmlStrlen(name);
+	if (name[len - 1] == ';')
+	    cur->name = xmlStrndup(name, len - 1);
+	else
+	    cur->name = xmlStrndup(name, len);
+    } else
+	cur->name = xmlStrdup(name);
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewReference:
+ * @doc: the document
+ * @name:  the reference name, or the reference string with & and ;
+ *
+ * Creation of a new reference node.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
+    xmlNodePtr cur;
+    xmlEntityPtr ent;
+
+    if (name == NULL)
+        return(NULL);
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building reference");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_ENTITY_REF_NODE;
+
+    cur->doc = doc;
+    if (name[0] == '&') {
+        int len;
+        name++;
+	len = xmlStrlen(name);
+	if (name[len - 1] == ';')
+	    cur->name = xmlStrndup(name, len - 1);
+	else
+	    cur->name = xmlStrndup(name, len);
+    } else
+	cur->name = xmlStrdup(name);
+
+    ent = xmlGetDocEntity(doc, cur->name);
+    if (ent != NULL) {
+	cur->content = ent->content;
+	/*
+	 * The parent pointer in entity is a DTD pointer and thus is NOT
+	 * updated.  Not sure if this is 100% correct.
+	 *  -George
+	 */
+	cur->children = (xmlNodePtr) ent;
+	cur->last = (xmlNodePtr) ent;
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewDocText:
+ * @doc: the document
+ * @content:  the text content
+ *
+ * Creation of a new text node within a document.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    cur = xmlNewText(content);
+    if (cur != NULL) cur->doc = doc;
+    return(cur);
+}
+
+/**
+ * xmlNewTextLen:
+ * @content:  the text content
+ * @len:  the text len.
+ *
+ * Creation of a new text node with an extra parameter for the content's length
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewTextLen(const xmlChar *content, int len) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building text");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_TEXT_NODE;
+
+    cur->name = xmlStringText;
+    if (content != NULL) {
+	cur->content = xmlStrndup(content, len);
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewDocTextLen:
+ * @doc: the document
+ * @content:  the text content
+ * @len:  the text len.
+ *
+ * Creation of a new text node with an extra content length parameter. The
+ * text node pertain to a given document.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
+    xmlNodePtr cur;
+
+    cur = xmlNewTextLen(content, len);
+    if (cur != NULL) cur->doc = doc;
+    return(cur);
+}
+
+/**
+ * xmlNewComment:
+ * @content:  the comment content
+ *
+ * Creation of a new node containing a comment.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewComment(const xmlChar *content) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building comment");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_COMMENT_NODE;
+
+    cur->name = xmlStringComment;
+    if (content != NULL) {
+	cur->content = xmlStrdup(content);
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewCDataBlock:
+ * @doc:  the document
+ * @content:  the CDATA block content content
+ * @len:  the length of the block
+ *
+ * Creation of a new node containing a CDATA block.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (cur == NULL) {
+	xmlTreeErrMemory("building CDATA");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNode));
+    cur->type = XML_CDATA_SECTION_NODE;
+    cur->doc = doc;
+
+    if (content != NULL) {
+	cur->content = xmlStrndup(content, len);
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	xmlRegisterNodeDefaultValue(cur);
+    return(cur);
+}
+
+/**
+ * xmlNewDocComment:
+ * @doc:  the document
+ * @content:  the comment content
+ *
+ * Creation of a new node containing a comment within a document.
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
+    xmlNodePtr cur;
+
+    cur = xmlNewComment(content);
+    if (cur != NULL) cur->doc = doc;
+    return(cur);
+}
+
+/**
+ * xmlSetTreeDoc:
+ * @tree:  the top element
+ * @doc:  the document
+ *
+ * update all nodes under the tree to point to the right document
+ */
+void
+xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
+    xmlAttrPtr prop;
+
+    if (tree == NULL)
+	return;
+    if (tree->doc != doc) {
+	if(tree->type == XML_ELEMENT_NODE) {
+	    prop = tree->properties;
+	    while (prop != NULL) {
+		prop->doc = doc;
+		xmlSetListDoc(prop->children, doc);
+		prop = prop->next;
+	    }
+	}
+	if (tree->children != NULL)
+	    xmlSetListDoc(tree->children, doc);
+	tree->doc = doc;
+    }
+}
+
+/**
+ * xmlSetListDoc:
+ * @list:  the first element
+ * @doc:  the document
+ *
+ * update all nodes in the list to point to the right document
+ */
+void
+xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
+    xmlNodePtr cur;
+
+    if (list == NULL)
+	return;
+    cur = list;
+    while (cur != NULL) {
+	if (cur->doc != doc)
+	    xmlSetTreeDoc(cur, doc);
+	cur = cur->next;
+    }
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlNewChild:
+ * @parent:  the parent node
+ * @ns:  a namespace if any
+ * @name:  the name of the child
+ * @content:  the XML content of the child if any.
+ *
+ * Creation of a new child element, added at the end of @parent children list.
+ * @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
+ * created element inherits the namespace of @parent. If @content is non NULL,
+ * a child list containing the TEXTs and ENTITY_REFs node will be created.
+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
+ *       references. XML special chars must be escaped first by using
+ *       xmlEncodeEntitiesReentrant(), or xmlNewTextChild() should be used.
+ *
+ * Returns a pointer to the new node object.
+ */
+xmlNodePtr
+xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+            const xmlChar *name, const xmlChar *content) {
+    xmlNodePtr cur, prev;
+
+    if (parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewChild : parent == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (name == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewChild : name == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node
+     */
+    if (parent->type == XML_ELEMENT_NODE) {
+	if (ns == NULL)
+	    cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
+	else
+	    cur = xmlNewDocNode(parent->doc, ns, name, content);
+    } else if ((parent->type == XML_DOCUMENT_NODE) ||
+	       (parent->type == XML_HTML_DOCUMENT_NODE)) {
+	if (ns == NULL)
+	    cur = xmlNewDocNode((xmlDocPtr) parent, NULL, name, content);
+	else
+	    cur = xmlNewDocNode((xmlDocPtr) parent, ns, name, content);
+    } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
+	    cur = xmlNewDocNode( parent->doc, ns, name, content);
+    } else {
+	return(NULL);
+    }
+    if (cur == NULL) return(NULL);
+
+    /*
+     * add the new element at the end of the children list.
+     */
+    cur->type = XML_ELEMENT_NODE;
+    cur->parent = parent;
+    cur->doc = parent->doc;
+    if (parent->children == NULL) {
+        parent->children = cur;
+	parent->last = cur;
+    } else {
+        prev = parent->last;
+	prev->next = cur;
+	cur->prev = prev;
+	parent->last = cur;
+    }
+
+    return(cur);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlAddPropSibling:
+ * @prev:  the attribute to which @prop is added after
+ * @cur:   the base attribute passed to calling function
+ * @prop:  the new attribute
+ *
+ * Add a new attribute after @prev using @cur as base attribute.
+ * When inserting before @cur, @prev is passed as @cur->prev.
+ * When inserting after @cur, @prev is passed as @cur.
+ * If an existing attribute is found it is detroyed prior to adding @prop.
+ *
+ * Returns the attribute being inserted or NULL in case of error.
+ */
+static xmlNodePtr
+xmlAddPropSibling(xmlNodePtr prev, xmlNodePtr cur, xmlNodePtr prop) {
+	xmlAttrPtr attr;
+
+	if (cur->type != XML_ATTRIBUTE_NODE)
+		return(NULL);
+
+	/* check if an attribute with the same name exists */
+	if (prop->ns == NULL)
+		attr = xmlHasNsProp(cur->parent, prop->name, NULL);
+	else
+		attr = xmlHasNsProp(cur->parent, prop->name, prop->ns->href);
+
+	if (prop->doc != cur->doc) {
+		xmlSetTreeDoc(prop, cur->doc);
+	}
+	prop->parent = cur->parent;
+	prop->prev = prev;
+	if (prev != NULL) {
+		prop->next = prev->next;
+		prev->next = prop;
+		if (prop->next)
+			prop->next->prev = prop;
+	} else {
+		prop->next = cur;
+		cur->prev = prop;
+	}
+	if (prop->prev == NULL && prop->parent != NULL)
+		prop->parent->properties = (xmlAttrPtr) prop;
+	if ((attr != NULL) && (attr->type != XML_ATTRIBUTE_DECL)) {
+		/* different instance, destroy it (attributes must be unique) */
+		xmlRemoveProp((xmlAttrPtr) attr);
+	}
+	return prop;
+}
+
+/**
+ * xmlAddNextSibling:
+ * @cur:  the child node
+ * @elem:  the new node
+ *
+ * Add a new node @elem as the next sibling of @cur
+ * If the new node was already inserted in a document it is
+ * first unlinked from its existing context.
+ * As a result of text merging @elem may be freed.
+ * If the new node is ATTRIBUTE, it is added into properties instead of children.
+ * If there is an attribute with equal name, it is first destroyed.
+ *
+ * Returns the new node or NULL in case of error.
+ */
+xmlNodePtr
+xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddNextSibling : cur == NULL\n");
+#endif
+	return(NULL);
+    }
+    if (elem == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddNextSibling : elem == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (cur == elem) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddNextSibling : cur == elem\n");
+#endif
+	return(NULL);
+    }
+
+    xmlUnlinkNode(elem);
+
+    if (elem->type == XML_TEXT_NODE) {
+	if (cur->type == XML_TEXT_NODE) {
+	    xmlNodeAddContent(cur, elem->content);
+	    xmlFreeNode(elem);
+	    return(cur);
+	}
+	if ((cur->next != NULL) && (cur->next->type == XML_TEXT_NODE) &&
+            (cur->name == cur->next->name)) {
+	    xmlChar *tmp;
+
+	    tmp = xmlStrdup(elem->content);
+	    tmp = xmlStrcat(tmp, cur->next->content);
+	    xmlNodeSetContent(cur->next, tmp);
+	    xmlFree(tmp);
+	    xmlFreeNode(elem);
+	    return(cur->next);
+	}
+    } else if (elem->type == XML_ATTRIBUTE_NODE) {
+		return xmlAddPropSibling(cur, cur, elem);
+    }
+
+    if (elem->doc != cur->doc) {
+	xmlSetTreeDoc(elem, cur->doc);
+    }
+    elem->parent = cur->parent;
+    elem->prev = cur;
+    elem->next = cur->next;
+    cur->next = elem;
+    if (elem->next != NULL)
+	elem->next->prev = elem;
+    if ((elem->parent != NULL) && (elem->parent->last == cur))
+	elem->parent->last = elem;
+    return(elem);
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlAddPrevSibling:
+ * @cur:  the child node
+ * @elem:  the new node
+ *
+ * Add a new node @elem as the previous sibling of @cur
+ * merging adjacent TEXT nodes (@elem may be freed)
+ * If the new node was already inserted in a document it is
+ * first unlinked from its existing context.
+ * If the new node is ATTRIBUTE, it is added into properties instead of children.
+ * If there is an attribute with equal name, it is first destroyed.
+ *
+ * Returns the new node or NULL in case of error.
+ */
+xmlNodePtr
+xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddPrevSibling : cur == NULL\n");
+#endif
+	return(NULL);
+    }
+    if (elem == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddPrevSibling : elem == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (cur == elem) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddPrevSibling : cur == elem\n");
+#endif
+	return(NULL);
+    }
+
+    xmlUnlinkNode(elem);
+
+    if (elem->type == XML_TEXT_NODE) {
+	if (cur->type == XML_TEXT_NODE) {
+	    xmlChar *tmp;
+
+	    tmp = xmlStrdup(elem->content);
+	    tmp = xmlStrcat(tmp, cur->content);
+	    xmlNodeSetContent(cur, tmp);
+	    xmlFree(tmp);
+	    xmlFreeNode(elem);
+	    return(cur);
+	}
+	if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE) &&
+            (cur->name == cur->prev->name)) {
+	    xmlNodeAddContent(cur->prev, elem->content);
+	    xmlFreeNode(elem);
+	    return(cur->prev);
+	}
+    } else if (elem->type == XML_ATTRIBUTE_NODE) {
+		return xmlAddPropSibling(cur->prev, cur, elem);
+    }
+
+    if (elem->doc != cur->doc) {
+	xmlSetTreeDoc(elem, cur->doc);
+    }
+    elem->parent = cur->parent;
+    elem->next = cur;
+    elem->prev = cur->prev;
+    cur->prev = elem;
+    if (elem->prev != NULL)
+	elem->prev->next = elem;
+    if ((elem->parent != NULL) && (elem->parent->children == cur)) {
+		elem->parent->children = elem;
+    }
+    return(elem);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlAddSibling:
+ * @cur:  the child node
+ * @elem:  the new node
+ *
+ * Add a new element @elem to the list of siblings of @cur
+ * merging adjacent TEXT nodes (@elem may be freed)
+ * If the new element was already inserted in a document it is
+ * first unlinked from its existing context.
+ *
+ * Returns the new element or NULL in case of error.
+ */
+xmlNodePtr
+xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
+    xmlNodePtr parent;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddSibling : cur == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (elem == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddSibling : elem == NULL\n");
+#endif
+	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.
+     */
+    if ((cur->type != XML_ATTRIBUTE_NODE) && (cur->parent != NULL) &&
+	(cur->parent->children != NULL) &&
+	(cur->parent->last != NULL) &&
+	(cur->parent->last->next == NULL)) {
+	cur = cur->parent->last;
+    } else {
+	while (cur->next != NULL) cur = cur->next;
+    }
+
+    xmlUnlinkNode(elem);
+
+    if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE) &&
+        (cur->name == elem->name)) {
+	xmlNodeAddContent(cur, elem->content);
+	xmlFreeNode(elem);
+	return(cur);
+    } else if (elem->type == XML_ATTRIBUTE_NODE) {
+		return xmlAddPropSibling(cur, cur, elem);
+    }
+
+    if (elem->doc != cur->doc) {
+	xmlSetTreeDoc(elem, cur->doc);
+    }
+    parent = cur->parent;
+    elem->prev = cur;
+    elem->next = NULL;
+    elem->parent = parent;
+    cur->next = elem;
+    if (parent != NULL)
+	parent->last = elem;
+
+    return(elem);
+}
+
+/**
+ * xmlAddChildList:
+ * @parent:  the parent node
+ * @cur:  the first node in the list
+ *
+ * Add a list of node at the end of the child list of the parent
+ * merging adjacent TEXT nodes (@cur may be freed)
+ *
+ * Returns the last child or NULL in case of error.
+ */
+xmlNodePtr
+xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
+    xmlNodePtr prev;
+
+    if (parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddChildList : parent == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddChildList : child == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if ((cur->doc != NULL) && (parent->doc != NULL) &&
+        (cur->doc != parent->doc)) {
+#ifdef DEBUG_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"Elements moved to a different document\n");
+#endif
+    }
+
+    /*
+     * add the first element at the end of the children list.
+     */
+
+    if (parent->children == NULL) {
+        parent->children = cur;
+    } else {
+	/*
+	 * If cur and parent->last both are TEXT nodes, then merge them.
+	 */
+	if ((cur->type == XML_TEXT_NODE) &&
+	    (parent->last->type == XML_TEXT_NODE) &&
+	    (cur->name == parent->last->name)) {
+	    xmlNodeAddContent(parent->last, cur->content);
+	    /*
+	     * if it's the only child, nothing more to be done.
+	     */
+	    if (cur->next == NULL) {
+		xmlFreeNode(cur);
+		return(parent->last);
+	    }
+	    prev = cur;
+	    cur = cur->next;
+	    xmlFreeNode(prev);
+	}
+        prev = parent->last;
+	prev->next = cur;
+	cur->prev = prev;
+    }
+    while (cur->next != NULL) {
+	cur->parent = parent;
+	if (cur->doc != parent->doc) {
+	    xmlSetTreeDoc(cur, parent->doc);
+	}
+        cur = cur->next;
+    }
+    cur->parent = parent;
+    /* the parent may not be linked to a doc ! */
+    if (cur->doc != parent->doc) {
+        xmlSetTreeDoc(cur, parent->doc);
+    }
+    parent->last = cur;
+
+    return(cur);
+}
+
+/**
+ * xmlAddChild:
+ * @parent:  the parent node
+ * @cur:  the child node
+ *
+ * Add a new node to @parent, at the end of the child (or property) list
+ * merging adjacent TEXT nodes (in which case @cur is freed)
+ * If the new node is ATTRIBUTE, it is added into properties instead of children.
+ * If there is an attribute with equal name, it is first destroyed.
+ *
+ * Returns the child or NULL in case of error.
+ */
+xmlNodePtr
+xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
+    xmlNodePtr prev;
+
+    if (parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddChild : parent == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddChild : child == NULL\n");
+#endif
+	return(NULL);
+    }
+
+    if (parent == cur) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddChild : parent == cur\n");
+#endif
+	return(NULL);
+    }
+    /*
+     * If cur is a TEXT node, merge its content with adjacent TEXT nodes
+     * cur is then freed.
+     */
+    if (cur->type == XML_TEXT_NODE) {
+	if ((parent->type == XML_TEXT_NODE) &&
+	    (parent->content != NULL) &&
+	    (parent->name == cur->name)) {
+	    xmlNodeAddContent(parent, cur->content);
+	    xmlFreeNode(cur);
+	    return(parent);
+	}
+	if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE) &&
+	    (parent->last->name == cur->name) &&
+	    (parent->last != cur)) {
+	    xmlNodeAddContent(parent->last, cur->content);
+	    xmlFreeNode(cur);
+	    return(parent->last);
+	}
+    }
+
+    /*
+     * add the new element at the end of the children list.
+     */
+    prev = cur->parent;
+    cur->parent = parent;
+    if (cur->doc != parent->doc) {
+	xmlSetTreeDoc(cur, parent->doc);
+    }
+    /* this check prevents a loop on tree-traversions if a developer
+     * tries to add a node to its parent multiple times
+     */
+    if (prev == parent)
+	return(cur);
+
+    /*
+     * Coalescing
+     */
+    if ((parent->type == XML_TEXT_NODE) &&
+	(parent->content != NULL) &&
+	(parent != cur)) {
+	xmlNodeAddContent(parent, cur->content);
+	xmlFreeNode(cur);
+	return(parent);
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+		if (parent->type != XML_ELEMENT_NODE)
+			return(NULL);
+	if (parent->properties != NULL) {
+	    /* check if an attribute with the same name exists */
+	    xmlAttrPtr lastattr;
+
+	    if (cur->ns == NULL)
+		lastattr = xmlHasNsProp(parent, cur->name, NULL);
+	    else
+		lastattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
+	    if ((lastattr != NULL) && (lastattr != (xmlAttrPtr) cur) && (lastattr->type != XML_ATTRIBUTE_DECL)) {
+		/* different instance, destroy it (attributes must be unique) */
+			xmlUnlinkNode((xmlNodePtr) lastattr);
+		xmlFreeProp(lastattr);
+	    }
+		if (lastattr == (xmlAttrPtr) cur)
+			return(cur);
+
+	}
+	if (parent->properties == NULL) {
+	    parent->properties = (xmlAttrPtr) cur;
+	} else {
+	    /* find the end */
+	    xmlAttrPtr lastattr = parent->properties;
+	    while (lastattr->next != NULL) {
+		lastattr = lastattr->next;
+	    }
+	    lastattr->next = (xmlAttrPtr) cur;
+	    ((xmlAttrPtr) cur)->prev = lastattr;
+	}
+    } else {
+	if (parent->children == NULL) {
+	    parent->children = cur;
+	    parent->last = cur;
+	} else {
+	    prev = parent->last;
+	    prev->next = cur;
+	    cur->prev = prev;
+	    parent->last = cur;
+	}
+    }
+    return(cur);
+}
+
+/**
+ * xmlGetLastChild:
+ * @parent:  the parent node
+ *
+ * Search the last child of a node.
+ * Returns the last child or NULL if none.
+ */
+xmlNodePtr
+xmlGetLastChild(xmlNodePtr parent) {
+    if (parent == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlGetLastChild : parent == NULL\n");
+#endif
+	return(NULL);
+    }
+    return(parent->last);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/*
+ * 5 interfaces from DOM ElementTraversal
+ */
+
+/**
+ * xmlChildElementCount:
+ * @parent: the parent node
+ *
+ * Finds the current number of child nodes of that element which are
+ * element nodes.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the count of element child or 0 if not available
+ */
+unsigned long
+xmlChildElementCount(xmlNodePtr parent) {
+    unsigned long ret = 0;
+    xmlNodePtr cur = NULL;
+
+    if (parent == NULL)
+        return(0);
+    switch (parent->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+            cur = parent->children;
+            break;
+        default:
+            return(0);
+    }
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE)
+            ret++;
+        cur = cur->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlFirstElementChild:
+ * @parent: the parent node
+ *
+ * Finds the first child node of that element which is a Element node
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the first element child or NULL if not available
+ */
+xmlNodePtr
+xmlFirstElementChild(xmlNodePtr parent) {
+    xmlNodePtr cur = NULL;
+
+    if (parent == NULL)
+        return(NULL);
+    switch (parent->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+            cur = parent->children;
+            break;
+        default:
+            return(NULL);
+    }
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE)
+            return(cur);
+        cur = cur->next;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlLastElementChild:
+ * @parent: the parent node
+ *
+ * Finds the last child node of that element which is a Element node
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the last element child or NULL if not available
+ */
+xmlNodePtr
+xmlLastElementChild(xmlNodePtr parent) {
+    xmlNodePtr cur = NULL;
+
+    if (parent == NULL)
+        return(NULL);
+    switch (parent->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+            cur = parent->last;
+            break;
+        default:
+            return(NULL);
+    }
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE)
+            return(cur);
+        cur = cur->prev;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlPreviousElementSibling:
+ * @node: the current node
+ *
+ * Finds the first closest previous sibling of the node which is an
+ * element node.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the previous element sibling or NULL if not available
+ */
+xmlNodePtr
+xmlPreviousElementSibling(xmlNodePtr node) {
+    if (node == NULL)
+        return(NULL);
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            node = node->prev;
+            break;
+        default:
+            return(NULL);
+    }
+    while (node != NULL) {
+        if (node->type == XML_ELEMENT_NODE)
+            return(node);
+        node = node->prev;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlNextElementSibling:
+ * @node: the current node
+ *
+ * Finds the first closest next sibling of the node which is an
+ * element node.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the next element sibling or NULL if not available
+ */
+xmlNodePtr
+xmlNextElementSibling(xmlNodePtr node) {
+    if (node == NULL)
+        return(NULL);
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DTD_NODE:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            node = node->next;
+            break;
+        default:
+            return(NULL);
+    }
+    while (node != NULL) {
+        if (node->type == XML_ELEMENT_NODE)
+            return(node);
+        node = node->next;
+    }
+    return(NULL);
+}
+
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlFreeNodeList:
+ * @cur:  the first node in the list
+ *
+ * Free a node and all its siblings, this is a recursive behaviour, all
+ * the children are freed too.
+ */
+void
+xmlFreeNodeList(xmlNodePtr cur) {
+    xmlNodePtr next;
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) return;
+    if (cur->type == XML_NAMESPACE_DECL) {
+	xmlFreeNsList((xmlNsPtr) cur);
+	return;
+    }
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+	(cur->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+	(cur->type == XML_HTML_DOCUMENT_NODE)) {
+	xmlFreeDoc((xmlDocPtr) cur);
+	return;
+    }
+    if (cur->doc != NULL) dict = cur->doc->dict;
+    while (cur != NULL) {
+        next = cur->next;
+	if (cur->type != XML_DTD_NODE) {
+
+	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+		xmlDeregisterNodeDefaultValue(cur);
+
+	    if ((cur->children != NULL) &&
+		(cur->type != XML_ENTITY_REF_NODE))
+		xmlFreeNodeList(cur->children);
+	    if (((cur->type == XML_ELEMENT_NODE) ||
+		 (cur->type == XML_XINCLUDE_START) ||
+		 (cur->type == XML_XINCLUDE_END)) &&
+		(cur->properties != NULL))
+		xmlFreePropList(cur->properties);
+	    if ((cur->type != XML_ELEMENT_NODE) &&
+		(cur->type != XML_XINCLUDE_START) &&
+		(cur->type != XML_XINCLUDE_END) &&
+		(cur->type != XML_ENTITY_REF_NODE) &&
+		(cur->content != (xmlChar *) &(cur->properties))) {
+		DICT_FREE(cur->content)
+	    }
+	    if (((cur->type == XML_ELEMENT_NODE) ||
+	         (cur->type == XML_XINCLUDE_START) ||
+		 (cur->type == XML_XINCLUDE_END)) &&
+		(cur->nsDef != NULL))
+		xmlFreeNsList(cur->nsDef);
+
+	    /*
+	     * When a node is a text node or a comment, it uses a global static
+	     * variable for the name of the node.
+	     * Otherwise the node name might come from the document's
+	     * dictionnary
+	     */
+	    if ((cur->name != NULL) &&
+		(cur->type != XML_TEXT_NODE) &&
+		(cur->type != XML_COMMENT_NODE))
+		DICT_FREE(cur->name)
+	    xmlFree(cur);
+	}
+	cur = next;
+    }
+}
+
+/**
+ * xmlFreeNode:
+ * @cur:  the node
+ *
+ * Free a node, this is a recursive behaviour, all the children are freed too.
+ * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
+ */
+void
+xmlFreeNode(xmlNodePtr cur) {
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) return;
+
+    /* use xmlFreeDtd for DTD nodes */
+    if (cur->type == XML_DTD_NODE) {
+	xmlFreeDtd((xmlDtdPtr) cur);
+	return;
+    }
+    if (cur->type == XML_NAMESPACE_DECL) {
+	xmlFreeNs((xmlNsPtr) cur);
+        return;
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+	xmlFreeProp((xmlAttrPtr) cur);
+	return;
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue(cur);
+
+    if (cur->doc != NULL) dict = cur->doc->dict;
+
+    if (cur->type == XML_ENTITY_DECL) {
+        xmlEntityPtr ent = (xmlEntityPtr) cur;
+	DICT_FREE(ent->SystemID);
+	DICT_FREE(ent->ExternalID);
+    }
+    if ((cur->children != NULL) &&
+	(cur->type != XML_ENTITY_REF_NODE))
+	xmlFreeNodeList(cur->children);
+    if (((cur->type == XML_ELEMENT_NODE) ||
+	 (cur->type == XML_XINCLUDE_START) ||
+	 (cur->type == XML_XINCLUDE_END)) &&
+	(cur->properties != NULL))
+	xmlFreePropList(cur->properties);
+    if ((cur->type != XML_ELEMENT_NODE) &&
+	(cur->content != NULL) &&
+	(cur->type != XML_ENTITY_REF_NODE) &&
+	(cur->type != XML_XINCLUDE_END) &&
+	(cur->type != XML_XINCLUDE_START) &&
+	(cur->content != (xmlChar *) &(cur->properties))) {
+	DICT_FREE(cur->content)
+    }
+
+    /*
+     * When a node is a text node or a comment, it uses a global static
+     * variable for the name of the node.
+     * Otherwise the node name might come from the document's dictionnary
+     */
+    if ((cur->name != NULL) &&
+        (cur->type != XML_TEXT_NODE) &&
+        (cur->type != XML_COMMENT_NODE))
+	DICT_FREE(cur->name)
+
+    if (((cur->type == XML_ELEMENT_NODE) ||
+	 (cur->type == XML_XINCLUDE_START) ||
+	 (cur->type == XML_XINCLUDE_END)) &&
+	(cur->nsDef != NULL))
+	xmlFreeNsList(cur->nsDef);
+    xmlFree(cur);
+}
+
+/**
+ * xmlUnlinkNode:
+ * @cur:  the node
+ *
+ * Unlink a node from it's current context, the node is not freed
+ */
+void
+xmlUnlinkNode(xmlNodePtr cur) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlUnlinkNode : node == NULL\n");
+#endif
+	return;
+    }
+    if (cur->type == XML_DTD_NODE) {
+	xmlDocPtr doc;
+	doc = cur->doc;
+	if (doc != NULL) {
+	    if (doc->intSubset == (xmlDtdPtr) cur)
+		doc->intSubset = NULL;
+	    if (doc->extSubset == (xmlDtdPtr) cur)
+		doc->extSubset = NULL;
+	}
+    }
+    if (cur->type == XML_ENTITY_DECL) {
+        xmlDocPtr doc;
+	doc = cur->doc;
+	if (doc != NULL) {
+	    if (doc->intSubset != NULL) {
+	        if (xmlHashLookup(doc->intSubset->entities, cur->name) == cur)
+		    xmlHashRemoveEntry(doc->intSubset->entities, cur->name,
+		                       NULL);
+	        if (xmlHashLookup(doc->intSubset->pentities, cur->name) == cur)
+		    xmlHashRemoveEntry(doc->intSubset->pentities, cur->name,
+		                       NULL);
+	    }
+	    if (doc->extSubset != NULL) {
+	        if (xmlHashLookup(doc->extSubset->entities, cur->name) == cur)
+		    xmlHashRemoveEntry(doc->extSubset->entities, cur->name,
+		                       NULL);
+	        if (xmlHashLookup(doc->extSubset->pentities, cur->name) == cur)
+		    xmlHashRemoveEntry(doc->extSubset->pentities, cur->name,
+		                       NULL);
+	    }
+	}
+    }
+    if (cur->parent != NULL) {
+	xmlNodePtr parent;
+	parent = cur->parent;
+	if (cur->type == XML_ATTRIBUTE_NODE) {
+	    if (parent->properties == (xmlAttrPtr) cur)
+		parent->properties = ((xmlAttrPtr) cur)->next;
+	} else {
+	    if (parent->children == cur)
+		parent->children = cur->next;
+	    if (parent->last == cur)
+		parent->last = cur->prev;
+	}
+	cur->parent = NULL;
+    }
+    if (cur->next != NULL)
+        cur->next->prev = cur->prev;
+    if (cur->prev != NULL)
+        cur->prev->next = cur->next;
+    cur->next = cur->prev = NULL;
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+/**
+ * xmlReplaceNode:
+ * @old:  the old node
+ * @cur:  the node
+ *
+ * Unlink the old node from its current context, prune the new one
+ * at the same place. If @cur was already inserted in a document it is
+ * first unlinked from its existing context.
+ *
+ * Returns the @old node
+ */
+xmlNodePtr
+xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
+    if (old == cur) return(NULL);
+    if ((old == NULL) || (old->parent == NULL)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlReplaceNode : old == NULL or without parent\n");
+#endif
+	return(NULL);
+    }
+    if (cur == NULL) {
+	xmlUnlinkNode(old);
+	return(old);
+    }
+    if (cur == old) {
+	return(old);
+    }
+    if ((old->type==XML_ATTRIBUTE_NODE) && (cur->type!=XML_ATTRIBUTE_NODE)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlReplaceNode : Trying to replace attribute node with other node type\n");
+#endif
+	return(old);
+    }
+    if ((cur->type==XML_ATTRIBUTE_NODE) && (old->type!=XML_ATTRIBUTE_NODE)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlReplaceNode : Trying to replace a non-attribute node with attribute node\n");
+#endif
+	return(old);
+    }
+    xmlUnlinkNode(cur);
+    xmlSetTreeDoc(cur, old->doc);
+    cur->parent = old->parent;
+    cur->next = old->next;
+    if (cur->next != NULL)
+	cur->next->prev = cur;
+    cur->prev = old->prev;
+    if (cur->prev != NULL)
+	cur->prev->next = cur;
+    if (cur->parent != NULL) {
+	if (cur->type == XML_ATTRIBUTE_NODE) {
+	    if (cur->parent->properties == (xmlAttrPtr)old)
+		cur->parent->properties = ((xmlAttrPtr) cur);
+	} else {
+	    if (cur->parent->children == old)
+		cur->parent->children = cur;
+	    if (cur->parent->last == old)
+		cur->parent->last = cur;
+	}
+    }
+    old->next = old->prev = NULL;
+    old->parent = NULL;
+    return(old);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Copy operations						*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCopyNamespace:
+ * @cur:  the namespace
+ *
+ * Do a copy of the namespace.
+ *
+ * Returns: a new #xmlNsPtr, or NULL in case of error.
+ */
+xmlNsPtr
+xmlCopyNamespace(xmlNsPtr cur) {
+    xmlNsPtr ret;
+
+    if (cur == NULL) return(NULL);
+    switch (cur->type) {
+	case XML_LOCAL_NAMESPACE:
+	    ret = xmlNewNs(NULL, cur->href, cur->prefix);
+	    break;
+	default:
+#ifdef DEBUG_TREE
+	    xmlGenericError(xmlGenericErrorContext,
+		    "xmlCopyNamespace: invalid type %d\n", cur->type);
+#endif
+	    return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlCopyNamespaceList:
+ * @cur:  the first namespace
+ *
+ * Do a copy of an namespace list.
+ *
+ * Returns: a new #xmlNsPtr, or NULL in case of error.
+ */
+xmlNsPtr
+xmlCopyNamespaceList(xmlNsPtr cur) {
+    xmlNsPtr ret = NULL;
+    xmlNsPtr p = NULL,q;
+
+    while (cur != NULL) {
+        q = xmlCopyNamespace(cur);
+	if (p == NULL) {
+	    ret = p = q;
+	} else {
+	    p->next = q;
+	    p = q;
+	}
+	cur = cur->next;
+    }
+    return(ret);
+}
+
+static xmlNodePtr
+xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
+
+static xmlAttrPtr
+xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
+    xmlAttrPtr ret;
+
+    if (cur == NULL) return(NULL);
+    if (target != NULL)
+	ret = xmlNewDocProp(target->doc, cur->name, NULL);
+    else if (doc != NULL)
+	ret = xmlNewDocProp(doc, cur->name, NULL);
+    else if (cur->parent != NULL)
+	ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
+    else if (cur->children != NULL)
+	ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
+    else
+	ret = xmlNewDocProp(NULL, cur->name, NULL);
+    if (ret == NULL) return(NULL);
+    ret->parent = target;
+
+    if ((cur->ns != NULL) && (target != NULL)) {
+      xmlNsPtr ns;
+
+      ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
+      if (ns == NULL) {
+        /*
+         * Humm, we are copying an element whose namespace is defined
+         * out of the new tree scope. Search it in the original tree
+         * and add it at the top of the new tree
+         */
+        ns = xmlSearchNs(cur->doc, cur->parent, cur->ns->prefix);
+        if (ns != NULL) {
+          xmlNodePtr root = target;
+          xmlNodePtr pred = NULL;
+
+          while (root->parent != NULL) {
+            pred = root;
+            root = root->parent;
+          }
+          if (root == (xmlNodePtr) target->doc) {
+            /* correct possibly cycling above the document elt */
+            root = pred;
+          }
+          ret->ns = xmlNewNs(root, ns->href, ns->prefix);
+        }
+      } else {
+        /*
+         * we have to find something appropriate here since
+         * we cant be sure, that the namespce we found is identified
+         * by the prefix
+         */
+        if (xmlStrEqual(ns->href, cur->ns->href)) {
+          /* this is the nice case */
+          ret->ns = ns;
+        } else {
+          /*
+           * we are in trouble: we need a new reconcilied namespace.
+           * This is expensive
+           */
+          ret->ns = xmlNewReconciliedNs(target->doc, target, cur->ns);
+        }
+      }
+
+    } else
+        ret->ns = NULL;
+
+    if (cur->children != NULL) {
+	xmlNodePtr tmp;
+
+	ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
+	ret->last = NULL;
+	tmp = ret->children;
+	while (tmp != NULL) {
+	    /* tmp->parent = (xmlNodePtr)ret; */
+	    if (tmp->next == NULL)
+	        ret->last = tmp;
+	    tmp = tmp->next;
+	}
+    }
+    /*
+     * Try to handle IDs
+     */
+    if ((target!= NULL) && (cur!= NULL) &&
+	(target->doc != NULL) && (cur->doc != NULL) &&
+	(cur->doc->ids != NULL) && (cur->parent != NULL)) {
+	if (xmlIsID(cur->doc, cur->parent, cur)) {
+	    xmlChar *id;
+
+	    id = xmlNodeListGetString(cur->doc, cur->children, 1);
+	    if (id != NULL) {
+		xmlAddID(NULL, target->doc, id, ret);
+		xmlFree(id);
+	    }
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlCopyProp:
+ * @target:  the element where the attribute will be grafted
+ * @cur:  the attribute
+ *
+ * Do a copy of the attribute.
+ *
+ * Returns: a new #xmlAttrPtr, or NULL in case of error.
+ */
+xmlAttrPtr
+xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
+	return xmlCopyPropInternal(NULL, target, cur);
+}
+
+/**
+ * xmlCopyPropList:
+ * @target:  the element where the attributes will be grafted
+ * @cur:  the first attribute
+ *
+ * Do a copy of an attribute list.
+ *
+ * Returns: a new #xmlAttrPtr, or NULL in case of error.
+ */
+xmlAttrPtr
+xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
+    xmlAttrPtr ret = NULL;
+    xmlAttrPtr p = NULL,q;
+
+    while (cur != NULL) {
+        q = xmlCopyProp(target, cur);
+	if (q == NULL)
+	    return(NULL);
+	if (p == NULL) {
+	    ret = p = q;
+	} else {
+	    p->next = q;
+	    q->prev = p;
+	    p = q;
+	}
+	cur = cur->next;
+    }
+    return(ret);
+}
+
+/*
+ * NOTE about the CopyNode operations !
+ *
+ * They are split into external and internal parts for one
+ * tricky reason: namespaces. Doing a direct copy of a node
+ * say RPM:Copyright without changing the namespace pointer to
+ * something else can produce stale links. One way to do it is
+ * to keep a reference counter but this doesn't work as soon
+ * as one move the element or the subtree out of the scope of
+ * the existing namespace. The actual solution seems to add
+ * a copy of the namespace at the top of the copied tree if
+ * not available in the subtree.
+ * Hence two functions, the public front-end call the inner ones
+ * The argument "recursive" normally indicates a recursive copy
+ * of the node with values 0 (no) and 1 (yes).  For XInclude,
+ * however, we allow a value of 2 to indicate copy properties and
+ * namespace info, but don't recurse on children.
+ */
+
+static xmlNodePtr
+xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
+                  int extended) {
+    xmlNodePtr ret;
+
+    if (node == NULL) return(NULL);
+    switch (node->type) {
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ELEMENT_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+	    break;
+        case XML_ATTRIBUTE_NODE:
+		return((xmlNodePtr) xmlCopyPropInternal(doc, parent, (xmlAttrPtr) node));
+        case XML_NAMESPACE_DECL:
+	    return((xmlNodePtr) xmlCopyNamespaceList((xmlNsPtr) node));
+
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+#ifdef LIBXML_TREE_ENABLED
+	    return((xmlNodePtr) xmlCopyDoc((xmlDocPtr) node, extended));
+#endif /* LIBXML_TREE_ENABLED */
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+            return(NULL);
+    }
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+    if (ret == NULL) {
+	xmlTreeErrMemory("copying node");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlNode));
+    ret->type = node->type;
+
+    ret->doc = doc;
+    ret->parent = parent;
+    if (node->name == xmlStringText)
+	ret->name = xmlStringText;
+    else if (node->name == xmlStringTextNoenc)
+	ret->name = xmlStringTextNoenc;
+    else if (node->name == xmlStringComment)
+	ret->name = xmlStringComment;
+    else if (node->name != NULL) {
+        if ((doc != NULL) && (doc->dict != NULL))
+	    ret->name = xmlDictLookup(doc->dict, node->name, -1);
+	else
+	    ret->name = xmlStrdup(node->name);
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->content != NULL) &&
+	(node->type != XML_ENTITY_REF_NODE) &&
+	(node->type != XML_XINCLUDE_END) &&
+	(node->type != XML_XINCLUDE_START)) {
+	ret->content = xmlStrdup(node->content);
+    }else{
+      if (node->type == XML_ELEMENT_NODE)
+        ret->line = node->line;
+    }
+    if (parent != NULL) {
+	xmlNodePtr tmp;
+
+	/*
+	 * this is a tricky part for the node register thing:
+	 * in case ret does get coalesced in xmlAddChild
+	 * the deregister-node callback is called; so we register ret now already
+	 */
+	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+	    xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
+
+        tmp = xmlAddChild(parent, ret);
+	/* node could have coalesced */
+	if (tmp != ret)
+	    return(tmp);
+    }
+
+    if (!extended)
+	goto out;
+    if (((node->type == XML_ELEMENT_NODE) ||
+         (node->type == XML_XINCLUDE_START)) && (node->nsDef != NULL))
+        ret->nsDef = xmlCopyNamespaceList(node->nsDef);
+
+    if (node->ns != NULL) {
+        xmlNsPtr ns;
+
+	ns = xmlSearchNs(doc, ret, node->ns->prefix);
+	if (ns == NULL) {
+	    /*
+	     * Humm, we are copying an element whose namespace is defined
+	     * out of the new tree scope. Search it in the original tree
+	     * and add it at the top of the new tree
+	     */
+	    ns = xmlSearchNs(node->doc, node, node->ns->prefix);
+	    if (ns != NULL) {
+	        xmlNodePtr root = ret;
+
+		while (root->parent != NULL) root = root->parent;
+		ret->ns = xmlNewNs(root, ns->href, ns->prefix);
+		} else {
+			ret->ns = xmlNewReconciliedNs(doc, ret, node->ns);
+	    }
+	} else {
+	    /*
+	     * reference the existing namespace definition in our own tree.
+	     */
+	    ret->ns = ns;
+	}
+    }
+    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)) {
+	    /*
+	     * The copied node will go into a separate document, so
+	     * to avoid dangling references to the ENTITY_DECL node
+	     * we cannot keep the reference. Try to find it in the
+	     * target document.
+	     */
+	    ret->children = (xmlNodePtr) xmlGetDocEntity(doc, ret->name);
+	} else {
+            ret->children = node->children;
+	}
+	ret->last = ret->children;
+    } else if ((node->children != NULL) && (extended != 2)) {
+        ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
+	UPDATE_LAST_CHILD_AND_PARENT(ret)
+    }
+
+out:
+    /* if parent != NULL we already registered the node above */
+    if ((parent == NULL) &&
+        ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)))
+	xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
+    return(ret);
+}
+
+static xmlNodePtr
+xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
+    xmlNodePtr ret = NULL;
+    xmlNodePtr p = NULL,q;
+
+    while (node != NULL) {
+#ifdef LIBXML_TREE_ENABLED
+	if (node->type == XML_DTD_NODE ) {
+	    if (doc == NULL) {
+		node = node->next;
+		continue;
+	    }
+	    if (doc->intSubset == NULL) {
+		q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
+		q->doc = doc;
+		q->parent = parent;
+		doc->intSubset = (xmlDtdPtr) q;
+		xmlAddChild(parent, q);
+	    } else {
+		q = (xmlNodePtr) doc->intSubset;
+		xmlAddChild(parent, q);
+	    }
+	} else
+#endif /* LIBXML_TREE_ENABLED */
+	    q = xmlStaticCopyNode(node, doc, parent, 1);
+	if (ret == NULL) {
+	    q->prev = NULL;
+	    ret = p = q;
+	} else if (p != q) {
+	/* the test is required if xmlStaticCopyNode coalesced 2 text nodes */
+	    p->next = q;
+	    q->prev = p;
+	    p = q;
+	}
+	node = node->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlCopyNode:
+ * @node:  the node
+ * @extended:   if 1 do a recursive copy (properties, namespaces and children
+ *			when applicable)
+ *		if 2 copy properties and namespaces (when applicable)
+ *
+ * Do a copy of the node.
+ *
+ * Returns: a new #xmlNodePtr, or NULL in case of error.
+ */
+xmlNodePtr
+xmlCopyNode(const xmlNodePtr node, int extended) {
+    xmlNodePtr ret;
+
+    ret = xmlStaticCopyNode(node, NULL, NULL, extended);
+    return(ret);
+}
+
+/**
+ * xmlDocCopyNode:
+ * @node:  the node
+ * @doc:  the document
+ * @extended:   if 1 do a recursive copy (properties, namespaces and children
+ *			when applicable)
+ *		if 2 copy properties and namespaces (when applicable)
+ *
+ * Do a copy of the node to a given document.
+ *
+ * Returns: a new #xmlNodePtr, or NULL in case of error.
+ */
+xmlNodePtr
+xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
+    xmlNodePtr ret;
+
+    ret = xmlStaticCopyNode(node, doc, NULL, extended);
+    return(ret);
+}
+
+/**
+ * xmlDocCopyNodeList:
+ * @doc: the target document
+ * @node:  the first node in the list.
+ *
+ * Do a recursive copy of the node list.
+ *
+ * Returns: a new #xmlNodePtr, or NULL in case of error.
+ */
+xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, const xmlNodePtr node) {
+    xmlNodePtr ret = xmlStaticCopyNodeList(node, doc, NULL);
+    return(ret);
+}
+
+/**
+ * xmlCopyNodeList:
+ * @node:  the first node in the list.
+ *
+ * Do a recursive copy of the node list.
+ * Use xmlDocCopyNodeList() if possible to ensure string interning.
+ *
+ * Returns: a new #xmlNodePtr, or NULL in case of error.
+ */
+xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
+    xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
+    return(ret);
+}
+
+#if defined(LIBXML_TREE_ENABLED)
+/**
+ * xmlCopyDtd:
+ * @dtd:  the dtd
+ *
+ * Do a copy of the dtd.
+ *
+ * Returns: a new #xmlDtdPtr, or NULL in case of error.
+ */
+xmlDtdPtr
+xmlCopyDtd(xmlDtdPtr dtd) {
+    xmlDtdPtr ret;
+    xmlNodePtr cur, p = NULL, q;
+
+    if (dtd == NULL) return(NULL);
+    ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID);
+    if (ret == NULL) return(NULL);
+    if (dtd->entities != NULL)
+        ret->entities = (void *) xmlCopyEntitiesTable(
+	                    (xmlEntitiesTablePtr) dtd->entities);
+    if (dtd->notations != NULL)
+        ret->notations = (void *) xmlCopyNotationTable(
+	                    (xmlNotationTablePtr) dtd->notations);
+    if (dtd->elements != NULL)
+        ret->elements = (void *) xmlCopyElementTable(
+	                    (xmlElementTablePtr) dtd->elements);
+    if (dtd->attributes != NULL)
+        ret->attributes = (void *) xmlCopyAttributeTable(
+	                    (xmlAttributeTablePtr) dtd->attributes);
+    if (dtd->pentities != NULL)
+	ret->pentities = (void *) xmlCopyEntitiesTable(
+			    (xmlEntitiesTablePtr) dtd->pentities);
+
+    cur = dtd->children;
+    while (cur != NULL) {
+	q = NULL;
+
+	if (cur->type == XML_ENTITY_DECL) {
+	    xmlEntityPtr tmp = (xmlEntityPtr) cur;
+	    switch (tmp->etype) {
+		case XML_INTERNAL_GENERAL_ENTITY:
+		case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+		case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+		    q = (xmlNodePtr) xmlGetEntityFromDtd(ret, tmp->name);
+		    break;
+		case XML_INTERNAL_PARAMETER_ENTITY:
+		case XML_EXTERNAL_PARAMETER_ENTITY:
+		    q = (xmlNodePtr)
+			xmlGetParameterEntityFromDtd(ret, tmp->name);
+		    break;
+		case XML_INTERNAL_PREDEFINED_ENTITY:
+		    break;
+	    }
+	} else if (cur->type == XML_ELEMENT_DECL) {
+	    xmlElementPtr tmp = (xmlElementPtr) cur;
+	    q = (xmlNodePtr)
+		xmlGetDtdQElementDesc(ret, tmp->name, tmp->prefix);
+	} else if (cur->type == XML_ATTRIBUTE_DECL) {
+	    xmlAttributePtr tmp = (xmlAttributePtr) cur;
+	    q = (xmlNodePtr)
+		xmlGetDtdQAttrDesc(ret, tmp->elem, tmp->name, tmp->prefix);
+	} else if (cur->type == XML_COMMENT_NODE) {
+	    q = xmlCopyNode(cur, 0);
+	}
+
+	if (q == NULL) {
+	    cur = cur->next;
+	    continue;
+	}
+
+	if (p == NULL)
+	    ret->children = q;
+	else
+	    p->next = q;
+
+	q->prev = p;
+	q->parent = (xmlNodePtr) ret;
+	q->next = NULL;
+	ret->last = q;
+	p = q;
+	cur = cur->next;
+    }
+
+    return(ret);
+}
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlCopyDoc:
+ * @doc:  the document
+ * @recursive:  if not zero do a recursive copy.
+ *
+ * Do a copy of the document info. If recursive, the content tree will
+ * be copied too as well as DTD, namespaces and entities.
+ *
+ * Returns: a new #xmlDocPtr, or NULL in case of error.
+ */
+xmlDocPtr
+xmlCopyDoc(xmlDocPtr doc, int recursive) {
+    xmlDocPtr ret;
+
+    if (doc == NULL) return(NULL);
+    ret = xmlNewDoc(doc->version);
+    if (ret == NULL) return(NULL);
+    if (doc->name != NULL)
+        ret->name = xmlMemStrdup(doc->name);
+    if (doc->encoding != NULL)
+        ret->encoding = xmlStrdup(doc->encoding);
+    if (doc->URL != NULL)
+        ret->URL = xmlStrdup(doc->URL);
+    ret->charset = doc->charset;
+    ret->compression = doc->compression;
+    ret->standalone = doc->standalone;
+    if (!recursive) return(ret);
+
+    ret->last = NULL;
+    ret->children = NULL;
+#ifdef LIBXML_TREE_ENABLED
+    if (doc->intSubset != NULL) {
+        ret->intSubset = xmlCopyDtd(doc->intSubset);
+	xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
+	ret->intSubset->parent = ret;
+    }
+#endif
+    if (doc->oldNs != NULL)
+        ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
+    if (doc->children != NULL) {
+	xmlNodePtr tmp;
+
+	ret->children = xmlStaticCopyNodeList(doc->children, ret,
+		                               (xmlNodePtr)ret);
+	ret->last = NULL;
+	tmp = ret->children;
+	while (tmp != NULL) {
+	    if (tmp->next == NULL)
+	        ret->last = tmp;
+	    tmp = tmp->next;
+	}
+    }
+    return(ret);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Content access functions				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlGetLineNo:
+ * @node: valid node
+ *
+ * Get line number of @node. This requires activation of this option
+ * before invoking the parser by calling xmlLineNumbersDefault(1)
+ *
+ * Returns the line number if successful, -1 otherwise
+ */
+long
+xmlGetLineNo(xmlNodePtr node)
+{
+    long result = -1;
+
+    if (!node)
+        return result;
+    if ((node->type == XML_ELEMENT_NODE) ||
+        (node->type == XML_TEXT_NODE) ||
+	(node->type == XML_COMMENT_NODE) ||
+	(node->type == XML_PI_NODE))
+        result = (long) node->line;
+    else if ((node->prev != NULL) &&
+             ((node->prev->type == XML_ELEMENT_NODE) ||
+	      (node->prev->type == XML_TEXT_NODE) ||
+	      (node->prev->type == XML_COMMENT_NODE) ||
+	      (node->prev->type == XML_PI_NODE)))
+        result = xmlGetLineNo(node->prev);
+    else if ((node->parent != NULL) &&
+             (node->parent->type == XML_ELEMENT_NODE))
+        result = xmlGetLineNo(node->parent);
+
+    return result;
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
+/**
+ * xmlGetNodePath:
+ * @node: a node
+ *
+ * Build a structure based Path for the given node
+ *
+ * Returns the new path or NULL in case of error. The caller must free
+ *     the returned string
+ */
+xmlChar *
+xmlGetNodePath(xmlNodePtr node)
+{
+    xmlNodePtr cur, tmp, next;
+    xmlChar *buffer = NULL, *temp;
+    size_t buf_len;
+    xmlChar *buf;
+    const char *sep;
+    const char *name;
+    char nametemp[100];
+    int occur = 0, generic;
+
+    if (node == NULL)
+        return (NULL);
+
+    buf_len = 500;
+    buffer = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar));
+    if (buffer == NULL) {
+	xmlTreeErrMemory("getting node path");
+        return (NULL);
+    }
+    buf = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar));
+    if (buf == NULL) {
+	xmlTreeErrMemory("getting node path");
+        xmlFree(buffer);
+        return (NULL);
+    }
+
+    buffer[0] = 0;
+    cur = node;
+    do {
+        name = "";
+        sep = "?";
+        occur = 0;
+        if ((cur->type == XML_DOCUMENT_NODE) ||
+            (cur->type == XML_HTML_DOCUMENT_NODE)) {
+            if (buffer[0] == '/')
+                break;
+            sep = "/";
+            next = NULL;
+        } else if (cur->type == XML_ELEMENT_NODE) {
+	    generic = 0;
+            sep = "/";
+            name = (const char *) cur->name;
+            if (cur->ns) {
+		if (cur->ns->prefix != NULL) {
+                    snprintf(nametemp, sizeof(nametemp) - 1, "%s:%s",
+			(char *)cur->ns->prefix, (char *)cur->name);
+		    nametemp[sizeof(nametemp) - 1] = 0;
+		    name = nametemp;
+		} else {
+		    /*
+		    * We cannot express named elements in the default
+		    * namespace, so use "*".
+		    */
+		    generic = 1;
+		    name = "*";
+		}
+            }
+            next = cur->parent;
+
+            /*
+             * Thumbler index computation
+	     * TODO: the ocurence test seems bogus for namespaced names
+             */
+            tmp = cur->prev;
+            while (tmp != NULL) {
+                if ((tmp->type == XML_ELEMENT_NODE) &&
+		    (generic ||
+		     (xmlStrEqual(cur->name, tmp->name) &&
+		     ((tmp->ns == cur->ns) ||
+		      ((tmp->ns != NULL) && (cur->ns != NULL) &&
+		       (xmlStrEqual(cur->ns->prefix, tmp->ns->prefix)))))))
+                    occur++;
+                tmp = tmp->prev;
+            }
+            if (occur == 0) {
+                tmp = cur->next;
+                while (tmp != NULL && occur == 0) {
+                    if ((tmp->type == XML_ELEMENT_NODE) &&
+			(generic ||
+			 (xmlStrEqual(cur->name, tmp->name) &&
+			 ((tmp->ns == cur->ns) ||
+			  ((tmp->ns != NULL) && (cur->ns != NULL) &&
+			   (xmlStrEqual(cur->ns->prefix, tmp->ns->prefix)))))))
+                        occur++;
+                    tmp = tmp->next;
+                }
+                if (occur != 0)
+                    occur = 1;
+            } else
+                occur++;
+        } else if (cur->type == XML_COMMENT_NODE) {
+            sep = "/";
+	    name = "comment()";
+            next = cur->parent;
+
+            /*
+             * Thumbler index computation
+             */
+            tmp = cur->prev;
+            while (tmp != NULL) {
+                if (tmp->type == XML_COMMENT_NODE)
+		    occur++;
+                tmp = tmp->prev;
+            }
+            if (occur == 0) {
+                tmp = cur->next;
+                while (tmp != NULL && occur == 0) {
+		  if (tmp->type == XML_COMMENT_NODE)
+		    occur++;
+                    tmp = tmp->next;
+                }
+                if (occur != 0)
+                    occur = 1;
+            } else
+                occur++;
+        } else if ((cur->type == XML_TEXT_NODE) ||
+                   (cur->type == XML_CDATA_SECTION_NODE)) {
+            sep = "/";
+	    name = "text()";
+            next = cur->parent;
+
+            /*
+             * Thumbler index computation
+             */
+            tmp = cur->prev;
+            while (tmp != NULL) {
+                if ((tmp->type == XML_TEXT_NODE) ||
+		    (tmp->type == XML_CDATA_SECTION_NODE))
+		    occur++;
+                tmp = tmp->prev;
+            }
+	    /*
+	    * Evaluate if this is the only text- or CDATA-section-node;
+	    * if yes, then we'll get "text()", otherwise "text()[1]".
+	    */
+            if (occur == 0) {
+                tmp = cur->next;
+                while (tmp != NULL) {
+		    if ((tmp->type == XML_TEXT_NODE) ||
+			(tmp->type == XML_CDATA_SECTION_NODE))
+		    {
+			occur = 1;
+			break;
+		    }
+		    tmp = tmp->next;
+		}
+            } else
+                occur++;
+        } else if (cur->type == XML_PI_NODE) {
+            sep = "/";
+	    snprintf(nametemp, sizeof(nametemp) - 1,
+		     "processing-instruction('%s')", (char *)cur->name);
+            nametemp[sizeof(nametemp) - 1] = 0;
+            name = nametemp;
+
+	    next = cur->parent;
+
+            /*
+             * Thumbler index computation
+             */
+            tmp = cur->prev;
+            while (tmp != NULL) {
+                if ((tmp->type == XML_PI_NODE) &&
+		    (xmlStrEqual(cur->name, tmp->name)))
+                    occur++;
+                tmp = tmp->prev;
+            }
+            if (occur == 0) {
+                tmp = cur->next;
+                while (tmp != NULL && occur == 0) {
+                    if ((tmp->type == XML_PI_NODE) &&
+			(xmlStrEqual(cur->name, tmp->name)))
+                        occur++;
+                    tmp = tmp->next;
+                }
+                if (occur != 0)
+                    occur = 1;
+            } else
+                occur++;
+
+        } else if (cur->type == XML_ATTRIBUTE_NODE) {
+            sep = "/@";
+            name = (const char *) (((xmlAttrPtr) cur)->name);
+            if (cur->ns) {
+	        if (cur->ns->prefix != NULL)
+                    snprintf(nametemp, sizeof(nametemp) - 1, "%s:%s",
+			(char *)cur->ns->prefix, (char *)cur->name);
+		else
+		    snprintf(nametemp, sizeof(nametemp) - 1, "%s",
+			(char *)cur->name);
+                nametemp[sizeof(nametemp) - 1] = 0;
+                name = nametemp;
+            }
+            next = ((xmlAttrPtr) cur)->parent;
+        } else {
+            next = cur->parent;
+        }
+
+        /*
+         * Make sure there is enough room
+         */
+        if (xmlStrlen(buffer) + sizeof(nametemp) + 20 > buf_len) {
+            buf_len =
+                2 * buf_len + xmlStrlen(buffer) + sizeof(nametemp) + 20;
+            temp = (xmlChar *) xmlRealloc(buffer, buf_len);
+            if (temp == NULL) {
+		xmlTreeErrMemory("getting node path");
+                xmlFree(buf);
+                xmlFree(buffer);
+                return (NULL);
+            }
+            buffer = temp;
+            temp = (xmlChar *) xmlRealloc(buf, buf_len);
+            if (temp == NULL) {
+		xmlTreeErrMemory("getting node path");
+                xmlFree(buf);
+                xmlFree(buffer);
+                return (NULL);
+            }
+            buf = temp;
+        }
+        if (occur == 0)
+            snprintf((char *) buf, buf_len, "%s%s%s",
+                     sep, name, (char *) buffer);
+        else
+            snprintf((char *) buf, buf_len, "%s%s[%d]%s",
+                     sep, name, occur, (char *) buffer);
+        snprintf((char *) buffer, buf_len, "%s", (char *)buf);
+        cur = next;
+    } while (cur != NULL);
+    xmlFree(buf);
+    return (buffer);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlDocGetRootElement:
+ * @doc:  the document
+ *
+ * Get the root element of the document (doc->children is a list
+ * containing possibly comments, PIs, etc ...).
+ *
+ * Returns the #xmlNodePtr for the root or NULL
+ */
+xmlNodePtr
+xmlDocGetRootElement(xmlDocPtr doc) {
+    xmlNodePtr ret;
+
+    if (doc == NULL) return(NULL);
+    ret = doc->children;
+    while (ret != NULL) {
+	if (ret->type == XML_ELEMENT_NODE)
+	    return(ret);
+        ret = ret->next;
+    }
+    return(ret);
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
+/**
+ * xmlDocSetRootElement:
+ * @doc:  the document
+ * @root:  the new document root element, if root is NULL no action is taken,
+ *         to remove a node from a document use xmlUnlinkNode(root) instead.
+ *
+ * Set the root element of the document (doc->children is a list
+ * containing possibly comments, PIs, etc ...).
+ *
+ * Returns the old root element if any was found, NULL if root was NULL
+ */
+xmlNodePtr
+xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
+    xmlNodePtr old = NULL;
+
+    if (doc == NULL) return(NULL);
+    if (root == NULL)
+	return(NULL);
+    xmlUnlinkNode(root);
+    xmlSetTreeDoc(root, doc);
+    root->parent = (xmlNodePtr) doc;
+    old = doc->children;
+    while (old != NULL) {
+	if (old->type == XML_ELEMENT_NODE)
+	    break;
+        old = old->next;
+    }
+    if (old == NULL) {
+	if (doc->children == NULL) {
+	    doc->children = root;
+	    doc->last = root;
+	} else {
+	    xmlAddSibling(doc->children, root);
+	}
+    } else {
+	xmlReplaceNode(old, root);
+    }
+    return(old);
+}
+#endif
+
+#if defined(LIBXML_TREE_ENABLED)
+/**
+ * xmlNodeSetLang:
+ * @cur:  the node being changed
+ * @lang:  the language description
+ *
+ * Set the language of a node, i.e. the values of the xml:lang
+ * attribute.
+ */
+void
+xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
+    xmlNsPtr ns;
+
+    if (cur == NULL) return;
+    switch(cur->type) {
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_NOTATION_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_PI_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+	case XML_NAMESPACE_DECL:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+	    return;
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    break;
+    }
+    ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
+    if (ns == NULL)
+	return;
+    xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNodeGetLang:
+ * @cur:  the node being checked
+ *
+ * Searches the language of a node, i.e. the values of the xml:lang
+ * attribute or the one carried by the nearest ancestor.
+ *
+ * Returns a pointer to the lang value, or NULL if not found
+ *     It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlNodeGetLang(xmlNodePtr cur) {
+    xmlChar *lang;
+
+    while (cur != NULL) {
+        lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE);
+	if (lang != NULL)
+	    return(lang);
+	cur = cur->parent;
+    }
+    return(NULL);
+}
+
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNodeSetSpacePreserve:
+ * @cur:  the node being changed
+ * @val:  the xml:space value ("0": default, 1: "preserve")
+ *
+ * Set (or reset) the space preserving behaviour of a node, i.e. the
+ * value of the xml:space attribute.
+ */
+void
+xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
+    xmlNsPtr ns;
+
+    if (cur == NULL) return;
+    switch(cur->type) {
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_NOTATION_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_PI_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return;
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    break;
+    }
+    ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
+    if (ns == NULL)
+	return;
+    switch (val) {
+    case 0:
+	xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "default");
+	break;
+    case 1:
+	xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "preserve");
+	break;
+    }
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNodeGetSpacePreserve:
+ * @cur:  the node being checked
+ *
+ * Searches the space preserving behaviour of a node, i.e. the values
+ * of the xml:space attribute or the one carried by the nearest
+ * ancestor.
+ *
+ * Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
+ */
+int
+xmlNodeGetSpacePreserve(xmlNodePtr cur) {
+    xmlChar *space;
+
+    while (cur != NULL) {
+	space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE);
+	if (space != NULL) {
+	    if (xmlStrEqual(space, BAD_CAST "preserve")) {
+		xmlFree(space);
+		return(1);
+	    }
+	    if (xmlStrEqual(space, BAD_CAST "default")) {
+		xmlFree(space);
+		return(0);
+	    }
+	    xmlFree(space);
+	}
+	cur = cur->parent;
+    }
+    return(-1);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNodeSetName:
+ * @cur:  the node being changed
+ * @name:  the new tag name
+ *
+ * Set (or reset) the name of a node.
+ */
+void
+xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
+    xmlDocPtr doc;
+    xmlDictPtr dict;
+
+    if (cur == NULL) return;
+    if (name == NULL) return;
+    switch(cur->type) {
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_NOTATION_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return;
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+        case XML_PI_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_DTD_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+	    break;
+    }
+    doc = cur->doc;
+    if (doc != NULL)
+	dict = doc->dict;
+    else
+        dict = NULL;
+    if (dict != NULL) {
+        if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
+	    xmlFree((xmlChar *) cur->name);
+	cur->name = xmlDictLookup(dict, name, -1);
+    } else {
+	if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
+	cur->name = xmlStrdup(name);
+    }
+}
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
+/**
+ * xmlNodeSetBase:
+ * @cur:  the node being changed
+ * @uri:  the new base URI
+ *
+ * Set (or reset) the base URI of a node, i.e. the value of the
+ * xml:base attribute.
+ */
+void
+xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
+    xmlNsPtr ns;
+    xmlChar* fixed;
+
+    if (cur == NULL) return;
+    switch(cur->type) {
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_COMMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_PI_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+	    return;
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    break;
+        case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+        case XML_HTML_DOCUMENT_NODE: {
+	    xmlDocPtr doc = (xmlDocPtr) cur;
+
+	    if (doc->URL != NULL)
+		xmlFree((xmlChar *) doc->URL);
+	    if (uri == NULL)
+		doc->URL = NULL;
+	    else
+		doc->URL = xmlPathToURI(uri);
+	    return;
+	}
+    }
+
+    ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
+    if (ns == NULL)
+	return;
+    fixed = xmlPathToURI(uri);
+    if (fixed != NULL) {
+	xmlSetNsProp(cur, ns, BAD_CAST "base", fixed);
+	xmlFree(fixed);
+    } else {
+	xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
+    }
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNodeGetBase:
+ * @doc:  the document the node pertains to
+ * @cur:  the node being checked
+ *
+ * Searches for the BASE URL. The code should work on both XML
+ * and HTML document even if base mechanisms are completely different.
+ * It returns the base as defined in RFC 2396 sections
+ * 5.1.1. Base URI within Document Content
+ * and
+ * 5.1.2. Base URI from the Encapsulating Entity
+ * However it does not return the document base (5.1.3), use
+ * 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().
+ */
+xmlChar *
+xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
+    xmlChar *oldbase = NULL;
+    xmlChar *base, *newbase;
+
+    if ((cur == NULL) && (doc == NULL))
+        return(NULL);
+    if (doc == NULL) doc = cur->doc;
+    if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
+        cur = doc->children;
+	while ((cur != NULL) && (cur->name != NULL)) {
+	    if (cur->type != XML_ELEMENT_NODE) {
+	        cur = cur->next;
+		continue;
+	    }
+	    if (!xmlStrcasecmp(cur->name, BAD_CAST "html")) {
+	        cur = cur->children;
+		continue;
+	    }
+	    if (!xmlStrcasecmp(cur->name, BAD_CAST "head")) {
+	        cur = cur->children;
+		continue;
+	    }
+	    if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
+                return(xmlGetProp(cur, BAD_CAST "href"));
+	    }
+	    cur = cur->next;
+	}
+	return(NULL);
+    }
+    while (cur != NULL) {
+	if (cur->type == XML_ENTITY_DECL) {
+	    xmlEntityPtr ent = (xmlEntityPtr) cur;
+	    return(xmlStrdup(ent->URI));
+	}
+	if (cur->type == XML_ELEMENT_NODE) {
+	    base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+	    if (base != NULL) {
+		if (oldbase != NULL) {
+		    newbase = xmlBuildURI(oldbase, base);
+		    if (newbase != NULL) {
+			xmlFree(oldbase);
+			xmlFree(base);
+			oldbase = newbase;
+		    } else {
+			xmlFree(oldbase);
+			xmlFree(base);
+			return(NULL);
+		    }
+		} else {
+		    oldbase = base;
+		}
+		if ((!xmlStrncmp(oldbase, BAD_CAST "http://", 7)) ||
+		    (!xmlStrncmp(oldbase, BAD_CAST "ftp://", 6)) ||
+		    (!xmlStrncmp(oldbase, BAD_CAST "urn:", 4)))
+		    return(oldbase);
+	    }
+	}
+	cur = cur->parent;
+    }
+    if ((doc != NULL) && (doc->URL != NULL)) {
+	if (oldbase == NULL)
+	    return(xmlStrdup(doc->URL));
+	newbase = xmlBuildURI(oldbase, doc->URL);
+	xmlFree(oldbase);
+	return(newbase);
+    }
+    return(oldbase);
+}
+
+/**
+ * xmlNodeBufGetContent:
+ * @buffer:  a buffer
+ * @cur:  the node being read
+ *
+ * Read the value of a node @cur, this can be either the text carried
+ * directly by this node if it's a TEXT node or the aggregate string
+ * of the values carried by this node child's (TEXT and ENTITY_REF).
+ * Entity references are substituted.
+ * Fills up the buffer @buffer with this value
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
+{
+    if ((cur == NULL) || (buffer == NULL)) return(-1);
+    switch (cur->type) {
+        case XML_CDATA_SECTION_NODE:
+        case XML_TEXT_NODE:
+	    xmlBufferCat(buffer, cur->content);
+            break;
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ELEMENT_NODE:{
+                xmlNodePtr tmp = cur;
+
+                while (tmp != NULL) {
+                    switch (tmp->type) {
+                        case XML_CDATA_SECTION_NODE:
+                        case XML_TEXT_NODE:
+                            if (tmp->content != NULL)
+                                xmlBufferCat(buffer, tmp->content);
+                            break;
+                        case XML_ENTITY_REF_NODE:
+                            xmlNodeBufGetContent(buffer, tmp);
+                            break;
+                        default:
+                            break;
+                    }
+                    /*
+                     * Skip to next node
+                     */
+                    if (tmp->children != NULL) {
+                        if (tmp->children->type != XML_ENTITY_DECL) {
+                            tmp = tmp->children;
+                            continue;
+                        }
+                    }
+                    if (tmp == cur)
+                        break;
+
+                    if (tmp->next != NULL) {
+                        tmp = tmp->next;
+                        continue;
+                    }
+
+                    do {
+                        tmp = tmp->parent;
+                        if (tmp == NULL)
+                            break;
+                        if (tmp == cur) {
+                            tmp = NULL;
+                            break;
+                        }
+                        if (tmp->next != NULL) {
+                            tmp = tmp->next;
+                            break;
+                        }
+                    } while (tmp != NULL);
+                }
+		break;
+            }
+        case XML_ATTRIBUTE_NODE:{
+                xmlAttrPtr attr = (xmlAttrPtr) cur;
+		xmlNodePtr tmp = attr->children;
+
+		while (tmp != NULL) {
+		    if (tmp->type == XML_TEXT_NODE)
+		        xmlBufferCat(buffer, tmp->content);
+		    else
+		        xmlNodeBufGetContent(buffer, tmp);
+		    tmp = tmp->next;
+		}
+                break;
+            }
+        case XML_COMMENT_NODE:
+        case XML_PI_NODE:
+	    xmlBufferCat(buffer, cur->content);
+            break;
+        case XML_ENTITY_REF_NODE:{
+                xmlEntityPtr ent;
+                xmlNodePtr tmp;
+
+                /* lookup entity declaration */
+                ent = xmlGetDocEntity(cur->doc, cur->name);
+                if (ent == NULL)
+                    return(-1);
+
+                /* an entity content can be any "well balanced chunk",
+                 * i.e. the result of the content [43] production:
+                 * http://www.w3.org/TR/REC-xml#NT-content
+                 * -> we iterate through child nodes and recursive call
+                 * xmlNodeGetContent() which handles all possible node types */
+                tmp = ent->children;
+                while (tmp) {
+		    xmlNodeBufGetContent(buffer, tmp);
+                    tmp = tmp->next;
+                }
+		break;
+            }
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            break;
+        case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+        case XML_HTML_DOCUMENT_NODE:
+	    cur = cur->children;
+	    while (cur!= NULL) {
+		if ((cur->type == XML_ELEMENT_NODE) ||
+		    (cur->type == XML_TEXT_NODE) ||
+		    (cur->type == XML_CDATA_SECTION_NODE)) {
+		    xmlNodeBufGetContent(buffer, cur);
+		}
+		cur = cur->next;
+	    }
+	    break;
+        case XML_NAMESPACE_DECL:
+	    xmlBufferCat(buffer, ((xmlNsPtr) cur)->href);
+	    break;
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+            break;
+    }
+    return(0);
+}
+/**
+ * xmlNodeGetContent:
+ * @cur:  the node being read
+ *
+ * Read the value of a node, this can be either the text carried
+ * directly by this node if it's a TEXT node or the aggregate string
+ * of the values carried by this node child's (TEXT and ENTITY_REF).
+ * Entity references are substituted.
+ * Returns a new #xmlChar * or NULL if no content is available.
+ *     It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlNodeGetContent(xmlNodePtr cur)
+{
+    if (cur == NULL)
+        return (NULL);
+    switch (cur->type) {
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ELEMENT_NODE:{
+                xmlBufferPtr buffer;
+                xmlChar *ret;
+
+                buffer = xmlBufferCreateSize(64);
+                if (buffer == NULL)
+                    return (NULL);
+		xmlNodeBufGetContent(buffer, cur);
+                ret = buffer->content;
+                buffer->content = NULL;
+                xmlBufferFree(buffer);
+                return (ret);
+            }
+        case XML_ATTRIBUTE_NODE:
+	    return(xmlGetPropNodeValueInternal((xmlAttrPtr) cur));
+        case XML_COMMENT_NODE:
+        case XML_PI_NODE:
+            if (cur->content != NULL)
+                return (xmlStrdup(cur->content));
+            return (NULL);
+        case XML_ENTITY_REF_NODE:{
+                xmlEntityPtr ent;
+                xmlBufferPtr buffer;
+                xmlChar *ret;
+
+                /* lookup entity declaration */
+                ent = xmlGetDocEntity(cur->doc, cur->name);
+                if (ent == NULL)
+                    return (NULL);
+
+                buffer = xmlBufferCreate();
+                if (buffer == NULL)
+                    return (NULL);
+
+                xmlNodeBufGetContent(buffer, cur);
+
+                ret = buffer->content;
+                buffer->content = NULL;
+                xmlBufferFree(buffer);
+                return (ret);
+            }
+        case XML_ENTITY_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_NOTATION_NODE:
+        case XML_DTD_NODE:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            return (NULL);
+        case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+        case XML_HTML_DOCUMENT_NODE: {
+	    xmlBufferPtr buffer;
+	    xmlChar *ret;
+
+	    buffer = xmlBufferCreate();
+	    if (buffer == NULL)
+		return (NULL);
+
+	    xmlNodeBufGetContent(buffer, (xmlNodePtr) cur);
+
+	    ret = buffer->content;
+	    buffer->content = NULL;
+	    xmlBufferFree(buffer);
+	    return (ret);
+	}
+        case XML_NAMESPACE_DECL: {
+	    xmlChar *tmp;
+
+	    tmp = xmlStrdup(((xmlNsPtr) cur)->href);
+            return (tmp);
+	}
+        case XML_ELEMENT_DECL:
+            /* TODO !!! */
+            return (NULL);
+        case XML_ATTRIBUTE_DECL:
+            /* TODO !!! */
+            return (NULL);
+        case XML_ENTITY_DECL:
+            /* TODO !!! */
+            return (NULL);
+        case XML_CDATA_SECTION_NODE:
+        case XML_TEXT_NODE:
+            if (cur->content != NULL)
+                return (xmlStrdup(cur->content));
+            return (NULL);
+    }
+    return (NULL);
+}
+
+/**
+ * xmlNodeSetContent:
+ * @cur:  the node being modified
+ * @content:  the new value of the content
+ *
+ * Replace the content of a node.
+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
+ *       references, but XML special chars need to be escaped first by using
+ *       xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
+ */
+void
+xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNodeSetContent : node == NULL\n");
+#endif
+	return;
+    }
+    switch (cur->type) {
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+	    cur->children = xmlStringGetNodeList(cur->doc, content);
+	    UPDATE_LAST_CHILD_AND_PARENT(cur)
+	    break;
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+	    if ((cur->content != NULL) &&
+	        (cur->content != (xmlChar *) &(cur->properties))) {
+	        if (!((cur->doc != NULL) && (cur->doc->dict != NULL) &&
+		    (xmlDictOwns(cur->doc->dict, cur->content))))
+		    xmlFree(cur->content);
+	    }
+	    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+	    cur->last = cur->children = NULL;
+	    if (content != NULL) {
+		cur->content = xmlStrdup(content);
+	    } else
+		cur->content = NULL;
+	    cur->properties = NULL;
+	    cur->nsDef = NULL;
+	    break;
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    break;
+        case XML_NOTATION_NODE:
+	    break;
+        case XML_DTD_NODE:
+	    break;
+	case XML_NAMESPACE_DECL:
+	    break;
+        case XML_ELEMENT_DECL:
+	    /* TODO !!! */
+	    break;
+        case XML_ATTRIBUTE_DECL:
+	    /* TODO !!! */
+	    break;
+        case XML_ENTITY_DECL:
+	    /* TODO !!! */
+	    break;
+    }
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlNodeSetContentLen:
+ * @cur:  the node being modified
+ * @content:  the new value of the content
+ * @len:  the size of @content
+ *
+ * Replace the content of a node.
+ * NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
+ *       references, but XML special chars need to be escaped first by using
+ *       xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
+ */
+void
+xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNodeSetContentLen : node == NULL\n");
+#endif
+	return;
+    }
+    switch (cur->type) {
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+	    cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
+	    UPDATE_LAST_CHILD_AND_PARENT(cur)
+	    break;
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_NOTATION_NODE:
+	    if ((cur->content != NULL) &&
+	        (cur->content != (xmlChar *) &(cur->properties))) {
+	        if (!((cur->doc != NULL) && (cur->doc->dict != NULL) &&
+		    (xmlDictOwns(cur->doc->dict, cur->content))))
+		    xmlFree(cur->content);
+	    }
+	    if (cur->children != NULL) xmlFreeNodeList(cur->children);
+	    cur->children = cur->last = NULL;
+	    if (content != NULL) {
+		cur->content = xmlStrndup(content, len);
+	    } else
+		cur->content = NULL;
+	    cur->properties = NULL;
+	    cur->nsDef = NULL;
+	    break;
+        case XML_DOCUMENT_NODE:
+        case XML_DTD_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    break;
+        case XML_ELEMENT_DECL:
+	    /* TODO !!! */
+	    break;
+        case XML_ATTRIBUTE_DECL:
+	    /* TODO !!! */
+	    break;
+        case XML_ENTITY_DECL:
+	    /* TODO !!! */
+	    break;
+    }
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNodeAddContentLen:
+ * @cur:  the node being modified
+ * @content:  extra content
+ * @len:  the size of @content
+ *
+ * Append the extra substring to the node content.
+ * NOTE: In contrast to xmlNodeSetContentLen(), @content is supposed to be
+ *       raw text, so unescaped XML special chars are allowed, entity
+ *       references are not supported.
+ */
+void
+xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNodeAddContentLen : node == NULL\n");
+#endif
+	return;
+    }
+    if (len <= 0) return;
+    switch (cur->type) {
+        case XML_DOCUMENT_FRAG_NODE:
+        case XML_ELEMENT_NODE: {
+	    xmlNodePtr last, newNode, tmp;
+
+	    last = cur->last;
+	    newNode = xmlNewTextLen(content, len);
+	    if (newNode != NULL) {
+		tmp = xmlAddChild(cur, newNode);
+		if (tmp != newNode)
+		    return;
+	        if ((last != NULL) && (last->next == newNode)) {
+		    xmlTextMerge(last, newNode);
+		}
+	    }
+	    break;
+	}
+        case XML_ATTRIBUTE_NODE:
+	    break;
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_ENTITY_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_NOTATION_NODE:
+	    if (content != NULL) {
+	        if ((cur->content == (xmlChar *) &(cur->properties)) ||
+		    ((cur->doc != NULL) && (cur->doc->dict != NULL) &&
+			    xmlDictOwns(cur->doc->dict, cur->content))) {
+		    cur->content = xmlStrncatNew(cur->content, content, len);
+		    cur->properties = NULL;
+		    cur->nsDef = NULL;
+		    break;
+		}
+		cur->content = xmlStrncat(cur->content, content, len);
+            }
+        case XML_DOCUMENT_NODE:
+        case XML_DTD_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+	case XML_NAMESPACE_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    break;
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+	    break;
+    }
+}
+
+/**
+ * xmlNodeAddContent:
+ * @cur:  the node being modified
+ * @content:  extra content
+ *
+ * Append the extra substring to the node content.
+ * NOTE: In contrast to xmlNodeSetContent(), @content is supposed to be
+ *       raw text, so unescaped XML special chars are allowed, entity
+ *       references are not supported.
+ */
+void
+xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
+    int len;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNodeAddContent : node == NULL\n");
+#endif
+	return;
+    }
+    if (content == NULL) return;
+    len = xmlStrlen(content);
+    xmlNodeAddContentLen(cur, content, len);
+}
+
+/**
+ * xmlTextMerge:
+ * @first:  the first text node
+ * @second:  the second text node being merged
+ *
+ * Merge two text nodes into one
+ * Returns the first text node augmented
+ */
+xmlNodePtr
+xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
+    if (first == NULL) return(second);
+    if (second == NULL) return(first);
+    if (first->type != XML_TEXT_NODE) return(first);
+    if (second->type != XML_TEXT_NODE) return(first);
+    if (second->name != first->name)
+	return(first);
+    xmlNodeAddContent(first, second->content);
+    xmlUnlinkNode(second);
+    xmlFreeNode(second);
+    return(first);
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlGetNsList:
+ * @doc:  the document
+ * @node:  the current node
+ *
+ * Search all the namespace applying to a given element.
+ * Returns an NULL terminated array of all the #xmlNsPtr found
+ *         that need to be freed by the caller or NULL if no
+ *         namespace if defined
+ */
+xmlNsPtr *
+xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
+{
+    xmlNsPtr cur;
+    xmlNsPtr *ret = NULL;
+    int nbns = 0;
+    int maxns = 10;
+    int i;
+
+    while (node != NULL) {
+        if (node->type == XML_ELEMENT_NODE) {
+            cur = node->nsDef;
+            while (cur != NULL) {
+                if (ret == NULL) {
+                    ret =
+                        (xmlNsPtr *) xmlMalloc((maxns + 1) *
+                                               sizeof(xmlNsPtr));
+                    if (ret == NULL) {
+			xmlTreeErrMemory("getting namespace list");
+                        return (NULL);
+                    }
+                    ret[nbns] = NULL;
+                }
+                for (i = 0; i < nbns; i++) {
+                    if ((cur->prefix == ret[i]->prefix) ||
+                        (xmlStrEqual(cur->prefix, ret[i]->prefix)))
+                        break;
+                }
+                if (i >= nbns) {
+                    if (nbns >= maxns) {
+                        maxns *= 2;
+                        ret = (xmlNsPtr *) xmlRealloc(ret,
+                                                      (maxns +
+                                                       1) *
+                                                      sizeof(xmlNsPtr));
+                        if (ret == NULL) {
+			    xmlTreeErrMemory("getting namespace list");
+                            return (NULL);
+                        }
+                    }
+                    ret[nbns++] = cur;
+                    ret[nbns] = NULL;
+                }
+
+                cur = cur->next;
+            }
+        }
+        node = node->parent;
+    }
+    return (ret);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+/*
+* xmlTreeEnsureXMLDecl:
+* @doc: the doc
+*
+* Ensures that there is an XML namespace declaration on the doc.
+*
+* Returns the XML ns-struct or NULL on API and internal errors.
+*/
+static xmlNsPtr
+xmlTreeEnsureXMLDecl(xmlDocPtr doc)
+{
+    if (doc == NULL)
+	return (NULL);
+    if (doc->oldNs != NULL)
+	return (doc->oldNs);
+    {
+	xmlNsPtr ns;
+	ns = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+	if (ns == NULL) {
+	    xmlTreeErrMemory(
+		"allocating the XML namespace");
+	    return (NULL);
+	}
+	memset(ns, 0, sizeof(xmlNs));
+	ns->type = XML_LOCAL_NAMESPACE;
+	ns->href = xmlStrdup(XML_XML_NAMESPACE);
+	ns->prefix = xmlStrdup((const xmlChar *)"xml");
+	doc->oldNs = ns;
+	return (ns);
+    }
+}
+
+/**
+ * xmlSearchNs:
+ * @doc:  the document
+ * @node:  the current node
+ * @nameSpace:  the namespace prefix
+ *
+ * Search a Ns registered under a given name space for a document.
+ * recurse on the parents until it finds the defined namespace
+ * or return NULL otherwise.
+ * @nameSpace can be NULL, this is a search for the default namespace.
+ * We don't allow to cross entities boundaries. If you don't declare
+ * the namespace within those you will be in troubles !!! A warning
+ * is generated to cover this case.
+ *
+ * Returns the namespace pointer or NULL.
+ */
+xmlNsPtr
+xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
+
+    xmlNsPtr cur;
+    xmlNodePtr orig = node;
+
+    if (node == NULL) return(NULL);
+    if ((nameSpace != NULL) &&
+	(xmlStrEqual(nameSpace, (const xmlChar *)"xml"))) {
+	if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
+	    /*
+	     * The XML-1.0 namespace is normally held on the root
+	     * element. In this case exceptionally create it on the
+	     * node element.
+	     */
+	    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+	    if (cur == NULL) {
+		xmlTreeErrMemory("searching namespace");
+		return(NULL);
+	    }
+	    memset(cur, 0, sizeof(xmlNs));
+	    cur->type = XML_LOCAL_NAMESPACE;
+	    cur->href = xmlStrdup(XML_XML_NAMESPACE);
+	    cur->prefix = xmlStrdup((const xmlChar *)"xml");
+	    cur->next = node->nsDef;
+	    node->nsDef = cur;
+	    return(cur);
+	}
+	if (doc == NULL) {
+	    doc = node->doc;
+	    if (doc == NULL)
+		return(NULL);
+	}
+	/*
+	* Return the XML namespace declaration held by the doc.
+	*/
+	if (doc->oldNs == NULL)
+	    return(xmlTreeEnsureXMLDecl(doc));
+	else
+	    return(doc->oldNs);
+    }
+    while (node != NULL) {
+	if ((node->type == XML_ENTITY_REF_NODE) ||
+	    (node->type == XML_ENTITY_NODE) ||
+	    (node->type == XML_ENTITY_DECL))
+	    return(NULL);
+	if (node->type == XML_ELEMENT_NODE) {
+	    cur = node->nsDef;
+	    while (cur != NULL) {
+		if ((cur->prefix == NULL) && (nameSpace == NULL) &&
+		    (cur->href != NULL))
+		    return(cur);
+		if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+		    (cur->href != NULL) &&
+		    (xmlStrEqual(cur->prefix, nameSpace)))
+		    return(cur);
+		cur = cur->next;
+	    }
+	    if (orig != node) {
+	        cur = node->ns;
+	        if (cur != NULL) {
+		    if ((cur->prefix == NULL) && (nameSpace == NULL) &&
+		        (cur->href != NULL))
+		        return(cur);
+		    if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+		        (cur->href != NULL) &&
+		        (xmlStrEqual(cur->prefix, nameSpace)))
+		        return(cur);
+	        }
+	    }
+	}
+	node = node->parent;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlNsInScope:
+ * @doc:  the document
+ * @node:  the current node
+ * @ancestor:  the ancestor carrying the namespace
+ * @prefix:  the namespace prefix
+ *
+ * Verify that the given namespace held on @ancestor is still in scope
+ * on node.
+ *
+ * Returns 1 if true, 0 if false and -1 in case of error.
+ */
+static int
+xmlNsInScope(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
+             xmlNodePtr ancestor, const xmlChar * prefix)
+{
+    xmlNsPtr tst;
+
+    while ((node != NULL) && (node != ancestor)) {
+        if ((node->type == XML_ENTITY_REF_NODE) ||
+            (node->type == XML_ENTITY_NODE) ||
+            (node->type == XML_ENTITY_DECL))
+            return (-1);
+        if (node->type == XML_ELEMENT_NODE) {
+            tst = node->nsDef;
+            while (tst != NULL) {
+                if ((tst->prefix == NULL)
+                    && (prefix == NULL))
+                    return (0);
+                if ((tst->prefix != NULL)
+                    && (prefix != NULL)
+                    && (xmlStrEqual(tst->prefix, prefix)))
+                    return (0);
+                tst = tst->next;
+            }
+        }
+        node = node->parent;
+    }
+    if (node != ancestor)
+        return (-1);
+    return (1);
+}
+
+/**
+ * xmlSearchNsByHref:
+ * @doc:  the document
+ * @node:  the current node
+ * @href:  the namespace value
+ *
+ * Search a Ns aliasing a given URI. Recurse on the parents until it finds
+ * the defined namespace or return NULL otherwise.
+ * Returns the namespace pointer or NULL.
+ */
+xmlNsPtr
+xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
+{
+    xmlNsPtr cur;
+    xmlNodePtr orig = node;
+    int is_attr;
+
+    if ((node == NULL) || (href == NULL))
+        return (NULL);
+    if (xmlStrEqual(href, XML_XML_NAMESPACE)) {
+        /*
+         * Only the document can hold the XML spec namespace.
+         */
+        if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
+            /*
+             * The XML-1.0 namespace is normally held on the root
+             * element. In this case exceptionally create it on the
+             * node element.
+             */
+            cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+            if (cur == NULL) {
+		xmlTreeErrMemory("searching namespace");
+                return (NULL);
+            }
+            memset(cur, 0, sizeof(xmlNs));
+            cur->type = XML_LOCAL_NAMESPACE;
+            cur->href = xmlStrdup(XML_XML_NAMESPACE);
+            cur->prefix = xmlStrdup((const xmlChar *) "xml");
+            cur->next = node->nsDef;
+            node->nsDef = cur;
+            return (cur);
+        }
+	if (doc == NULL) {
+	    doc = node->doc;
+	    if (doc == NULL)
+		return(NULL);
+	}
+	/*
+	* Return the XML namespace declaration held by the doc.
+	*/
+	if (doc->oldNs == NULL)
+	    return(xmlTreeEnsureXMLDecl(doc));
+	else
+	    return(doc->oldNs);
+    }
+    is_attr = (node->type == XML_ATTRIBUTE_NODE);
+    while (node != NULL) {
+        if ((node->type == XML_ENTITY_REF_NODE) ||
+            (node->type == XML_ENTITY_NODE) ||
+            (node->type == XML_ENTITY_DECL))
+            return (NULL);
+        if (node->type == XML_ELEMENT_NODE) {
+            cur = node->nsDef;
+            while (cur != NULL) {
+                if ((cur->href != NULL) && (href != NULL) &&
+                    (xmlStrEqual(cur->href, href))) {
+		    if (((!is_attr) || (cur->prefix != NULL)) &&
+		        (xmlNsInScope(doc, orig, node, cur->prefix) == 1))
+			return (cur);
+                }
+                cur = cur->next;
+            }
+            if (orig != node) {
+                cur = node->ns;
+                if (cur != NULL) {
+                    if ((cur->href != NULL) && (href != NULL) &&
+                        (xmlStrEqual(cur->href, href))) {
+			if (((!is_attr) || (cur->prefix != NULL)) &&
+		            (xmlNsInScope(doc, orig, node, cur->prefix) == 1))
+			    return (cur);
+                    }
+                }
+            }
+        }
+        node = node->parent;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlNewReconciliedNs:
+ * @doc:  the document
+ * @tree:  a node expected to hold the new namespace
+ * @ns:  the original namespace
+ *
+ * This function tries to locate a namespace definition in a tree
+ * ancestors, or create a new namespace definition node similar to
+ * @ns trying to reuse the same prefix. However if the given prefix is
+ * null (default namespace) or reused within the subtree defined by
+ * @tree or on one of its ancestors then a new prefix is generated.
+ * Returns the (new) namespace definition or NULL in case of error
+ */
+static xmlNsPtr
+xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
+    xmlNsPtr def;
+    xmlChar prefix[50];
+    int counter = 1;
+
+    if (tree == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewReconciliedNs : tree == NULL\n");
+#endif
+	return(NULL);
+    }
+    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewReconciliedNs : ns == NULL\n");
+#endif
+	return(NULL);
+    }
+    /*
+     * Search an existing namespace definition inherited.
+     */
+    def = xmlSearchNsByHref(doc, tree, ns->href);
+    if (def != NULL)
+        return(def);
+
+    /*
+     * Find a close prefix which is not already in use.
+     * Let's strip namespace prefixes longer than 20 chars !
+     */
+    if (ns->prefix == NULL)
+	snprintf((char *) prefix, sizeof(prefix), "default");
+    else
+	snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
+
+    def = xmlSearchNs(doc, tree, prefix);
+    while (def != NULL) {
+        if (counter > 1000) return(NULL);
+	if (ns->prefix == NULL)
+	    snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
+	else
+	    snprintf((char *) prefix, sizeof(prefix), "%.20s%d",
+		(char *)ns->prefix, counter++);
+	def = xmlSearchNs(doc, tree, prefix);
+    }
+
+    /*
+     * OK, now we are ready to create a new one.
+     */
+    def = xmlNewNs(tree, ns->href, prefix);
+    return(def);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlReconciliateNs:
+ * @doc:  the document
+ * @tree:  a node defining the subtree to reconciliate
+ *
+ * This function checks that all the namespaces declared within the given
+ * tree are properly declared. This is needed for example after Copy or Cut
+ * and then paste operations. The subtree may still hold pointers to
+ * namespace declarations outside the subtree or invalid/masked. As much
+ * as possible the function try to reuse the existing namespaces found in
+ * the new environment. If not possible the new namespaces are redeclared
+ * on @tree at the top of the given subtree.
+ * Returns the number of namespace declarations created or -1 in case of error.
+ */
+int
+xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
+    xmlNsPtr *oldNs = NULL;
+    xmlNsPtr *newNs = NULL;
+    int sizeCache = 0;
+    int nbCache = 0;
+
+    xmlNsPtr n;
+    xmlNodePtr node = tree;
+    xmlAttrPtr attr;
+    int ret = 0, i;
+
+    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) return(-1);
+    if ((doc == NULL) || (doc->type != XML_DOCUMENT_NODE)) return(-1);
+    if (node->doc != doc) return(-1);
+    while (node != NULL) {
+        /*
+	 * Reconciliate the node namespace
+	 */
+	if (node->ns != NULL) {
+	    /*
+	     * initialize the cache if needed
+	     */
+	    if (sizeCache == 0) {
+		sizeCache = 10;
+		oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
+					       sizeof(xmlNsPtr));
+		if (oldNs == NULL) {
+		    xmlTreeErrMemory("fixing namespaces");
+		    return(-1);
+		}
+		newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
+					       sizeof(xmlNsPtr));
+		if (newNs == NULL) {
+		    xmlTreeErrMemory("fixing namespaces");
+		    xmlFree(oldNs);
+		    return(-1);
+		}
+	    }
+	    for (i = 0;i < nbCache;i++) {
+	        if (oldNs[i] == node->ns) {
+		    node->ns = newNs[i];
+		    break;
+		}
+	    }
+	    if (i == nbCache) {
+	        /*
+		 * OK we need to recreate a new namespace definition
+		 */
+		n = xmlNewReconciliedNs(doc, tree, node->ns);
+		if (n != NULL) { /* :-( what if else ??? */
+		    /*
+		     * check if we need to grow the cache buffers.
+		     */
+		    if (sizeCache <= nbCache) {
+		        sizeCache *= 2;
+			oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
+			                               sizeof(xmlNsPtr));
+		        if (oldNs == NULL) {
+			    xmlTreeErrMemory("fixing namespaces");
+			    xmlFree(newNs);
+			    return(-1);
+			}
+			newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
+			                               sizeof(xmlNsPtr));
+		        if (newNs == NULL) {
+			    xmlTreeErrMemory("fixing namespaces");
+			    xmlFree(oldNs);
+			    return(-1);
+			}
+		    }
+		    newNs[nbCache] = n;
+		    oldNs[nbCache++] = node->ns;
+		    node->ns = n;
+                }
+	    }
+	}
+	/*
+	 * now check for namespace hold by attributes on the node.
+	 */
+	if (node->type == XML_ELEMENT_NODE) {
+	    attr = node->properties;
+	    while (attr != NULL) {
+		if (attr->ns != NULL) {
+		    /*
+		     * initialize the cache if needed
+		     */
+		    if (sizeCache == 0) {
+			sizeCache = 10;
+			oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
+						       sizeof(xmlNsPtr));
+			if (oldNs == NULL) {
+			    xmlTreeErrMemory("fixing namespaces");
+			    return(-1);
+			}
+			newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
+						       sizeof(xmlNsPtr));
+			if (newNs == NULL) {
+			    xmlTreeErrMemory("fixing namespaces");
+			    xmlFree(oldNs);
+			    return(-1);
+			}
+		    }
+		    for (i = 0;i < nbCache;i++) {
+			if (oldNs[i] == attr->ns) {
+			    attr->ns = newNs[i];
+			    break;
+			}
+		    }
+		    if (i == nbCache) {
+			/*
+			 * OK we need to recreate a new namespace definition
+			 */
+			n = xmlNewReconciliedNs(doc, tree, attr->ns);
+			if (n != NULL) { /* :-( what if else ??? */
+			    /*
+			     * check if we need to grow the cache buffers.
+			     */
+			    if (sizeCache <= nbCache) {
+				sizeCache *= 2;
+				oldNs = (xmlNsPtr *) xmlRealloc(oldNs,
+				           sizeCache * sizeof(xmlNsPtr));
+				if (oldNs == NULL) {
+				    xmlTreeErrMemory("fixing namespaces");
+				    xmlFree(newNs);
+				    return(-1);
+				}
+				newNs = (xmlNsPtr *) xmlRealloc(newNs,
+				           sizeCache * sizeof(xmlNsPtr));
+				if (newNs == NULL) {
+				    xmlTreeErrMemory("fixing namespaces");
+				    xmlFree(oldNs);
+				    return(-1);
+				}
+			    }
+			    newNs[nbCache] = n;
+			    oldNs[nbCache++] = attr->ns;
+			    attr->ns = n;
+			}
+		    }
+		}
+		attr = attr->next;
+	    }
+	}
+
+	/*
+	 * Browse the full subtree, deep first
+	 */
+        if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
+	    /* deep first */
+	    node = node->children;
+	} else if ((node != tree) && (node->next != NULL)) {
+	    /* then siblings */
+	    node = node->next;
+	} else if (node != tree) {
+	    /* go up to parents->next if needed */
+	    while (node != tree) {
+	        if (node->parent != NULL)
+		    node = node->parent;
+		if ((node != tree) && (node->next != NULL)) {
+		    node = node->next;
+		    break;
+		}
+		if (node->parent == NULL) {
+		    node = NULL;
+		    break;
+		}
+	    }
+	    /* exit condition */
+	    if (node == tree)
+	        node = NULL;
+	} else
+	    break;
+    }
+    if (oldNs != NULL)
+	xmlFree(oldNs);
+    if (newNs != NULL)
+	xmlFree(newNs);
+    return(ret);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+static xmlAttrPtr
+xmlGetPropNodeInternal(xmlNodePtr node, const xmlChar *name,
+		       const xmlChar *nsName, int useDTD)
+{
+    xmlAttrPtr prop;
+
+    if ((node == NULL) || (node->type != XML_ELEMENT_NODE) || (name == NULL))
+	return(NULL);
+
+    if (node->properties != NULL) {
+	prop = node->properties;
+	if (nsName == NULL) {
+	    /*
+	    * We want the attr to be in no namespace.
+	    */
+	    do {
+		if ((prop->ns == NULL) && xmlStrEqual(prop->name, name)) {
+		    return(prop);
+		}
+		prop = prop->next;
+	    } while (prop != NULL);
+	} else {
+	    /*
+	    * We want the attr to be in the specified namespace.
+	    */
+	    do {
+		if ((prop->ns != NULL) && xmlStrEqual(prop->name, name) &&
+		    ((prop->ns->href == nsName) ||
+		     xmlStrEqual(prop->ns->href, nsName)))
+		{
+		    return(prop);
+		}
+		prop = prop->next;
+	    } while (prop != NULL);
+	}
+    }
+
+#ifdef LIBXML_TREE_ENABLED
+    if (! useDTD)
+	return(NULL);
+    /*
+     * Check if there is a default/fixed attribute declaration in
+     * the internal or external subset.
+     */
+    if ((node->doc != NULL) && (node->doc->intSubset != NULL)) {
+	xmlDocPtr doc = node->doc;
+	xmlAttributePtr attrDecl = NULL;
+	xmlChar *elemQName, *tmpstr = NULL;
+
+	/*
+	* We need the QName of the element for the DTD-lookup.
+	*/
+	if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
+	    tmpstr = xmlStrdup(node->ns->prefix);
+	    tmpstr = xmlStrcat(tmpstr, BAD_CAST ":");
+	    tmpstr = xmlStrcat(tmpstr, node->name);
+	    if (tmpstr == NULL)
+		return(NULL);
+	    elemQName = tmpstr;
+	} else
+	    elemQName = (xmlChar *) node->name;
+	if (nsName == NULL) {
+	    /*
+	    * The common and nice case: Attr in no namespace.
+	    */
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset,
+		elemQName, name, NULL);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset,
+		    elemQName, name, NULL);
+	    }
+	} else {
+	    xmlNsPtr *nsList, *cur;
+
+	    /*
+	    * The ugly case: Search using the prefixes of in-scope
+	    * ns-decls corresponding to @nsName.
+	    */
+	    nsList = xmlGetNsList(node->doc, node);
+	    if (nsList == NULL) {
+		if (tmpstr != NULL)
+		    xmlFree(tmpstr);
+		return(NULL);
+	    }
+	    cur = nsList;
+	    while (*cur != NULL) {
+		if (xmlStrEqual((*cur)->href, nsName)) {
+		    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elemQName,
+			name, (*cur)->prefix);
+		    if (attrDecl)
+			break;
+		    if (doc->extSubset != NULL) {
+			attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elemQName,
+			    name, (*cur)->prefix);
+			if (attrDecl)
+			    break;
+		    }
+		}
+		cur++;
+	    }
+	    xmlFree(nsList);
+	}
+	if (tmpstr != NULL)
+	    xmlFree(tmpstr);
+	/*
+	* Only default/fixed attrs are relevant.
+	*/
+	if ((attrDecl != NULL) && (attrDecl->defaultValue != NULL))
+	    return((xmlAttrPtr) attrDecl);
+    }
+#endif /* LIBXML_TREE_ENABLED */
+    return(NULL);
+}
+
+static xmlChar*
+xmlGetPropNodeValueInternal(xmlAttrPtr prop)
+{
+    if (prop == NULL)
+	return(NULL);
+    if (prop->type == XML_ATTRIBUTE_NODE) {
+	/*
+	* Note that we return at least the empty string.
+	*   TODO: Do we really always want that?
+	*/
+	if (prop->children != NULL) {
+	    if ((prop->children->next == NULL) &&
+		((prop->children->type == XML_TEXT_NODE) ||
+		(prop->children->type == XML_CDATA_SECTION_NODE)))
+	    {
+		/*
+		* Optimization for the common case: only 1 text node.
+		*/
+		return(xmlStrdup(prop->children->content));
+	    } else {
+		xmlChar *ret;
+
+		ret = xmlNodeListGetString(prop->doc, prop->children, 1);
+		if (ret != NULL)
+		    return(ret);
+	    }
+	}
+	return(xmlStrdup((xmlChar *)""));
+    } else if (prop->type == XML_ATTRIBUTE_DECL) {
+	return(xmlStrdup(((xmlAttributePtr)prop)->defaultValue));
+    }
+    return(NULL);
+}
+
+/**
+ * xmlHasProp:
+ * @node:  the node
+ * @name:  the attribute name
+ *
+ * Search an attribute associated to a node
+ * This function also looks in DTD attribute declaration for #FIXED or
+ * default declaration values unless DTD use has been turned off.
+ *
+ * Returns the attribute or the attribute declaration or NULL if
+ *         neither was found.
+ */
+xmlAttrPtr
+xmlHasProp(xmlNodePtr node, const xmlChar *name) {
+    xmlAttrPtr prop;
+    xmlDocPtr doc;
+
+    if ((node == NULL) || (node->type != XML_ELEMENT_NODE) || (name == NULL))
+        return(NULL);
+    /*
+     * Check on the properties attached to the node
+     */
+    prop = node->properties;
+    while (prop != NULL) {
+        if (xmlStrEqual(prop->name, name))  {
+	    return(prop);
+        }
+	prop = prop->next;
+    }
+    if (!xmlCheckDTD) return(NULL);
+
+    /*
+     * Check if there is a default declaration in the internal
+     * or external subsets
+     */
+    doc =  node->doc;
+    if (doc != NULL) {
+        xmlAttributePtr attrDecl;
+        if (doc->intSubset != NULL) {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
+            if ((attrDecl != NULL) && (attrDecl->defaultValue != NULL))
+              /* return attribute declaration only if a default value is given
+                 (that includes #FIXED declarations) */
+		return((xmlAttrPtr) attrDecl);
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * xmlHasNsProp:
+ * @node:  the node
+ * @name:  the attribute name
+ * @nameSpace:  the URI of the namespace
+ *
+ * Search for an attribute associated to a node
+ * This attribute has to be anchored in the namespace specified.
+ * This does the entity substitution.
+ * This function looks in DTD attribute declaration for #FIXED or
+ * default declaration values unless DTD use has been turned off.
+ * Note that a namespace of NULL indicates to use the default namespace.
+ *
+ * Returns the attribute or the attribute declaration or NULL
+ *     if neither was found.
+ */
+xmlAttrPtr
+xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+
+    return(xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD));
+}
+
+/**
+ * xmlGetProp:
+ * @node:  the node
+ * @name:  the attribute name
+ *
+ * Search and get the value of an attribute associated to a node
+ * This does the entity substitution.
+ * This function looks in DTD attribute declaration for #FIXED or
+ * default declaration values unless DTD use has been turned off.
+ * NOTE: this function acts independently of namespaces associated
+ *       to the attribute. Use xmlGetNsProp() or xmlGetNoNsProp()
+ *       for namespace aware processing.
+ *
+ * Returns the attribute value or NULL if not found.
+ *     It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlGetProp(xmlNodePtr node, const xmlChar *name) {
+    xmlAttrPtr prop;
+
+    prop = xmlHasProp(node, name);
+    if (prop == NULL)
+	return(NULL);
+    return(xmlGetPropNodeValueInternal(prop));
+}
+
+/**
+ * xmlGetNoNsProp:
+ * @node:  the node
+ * @name:  the attribute name
+ *
+ * Search and get the value of an attribute associated to a node
+ * This does the entity substitution.
+ * This function looks in DTD attribute declaration for #FIXED or
+ * default declaration values unless DTD use has been turned off.
+ * This function is similar to xmlGetProp except it will accept only
+ * an attribute in no namespace.
+ *
+ * Returns the attribute value or NULL if not found.
+ *     It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name) {
+    xmlAttrPtr prop;
+
+    prop = xmlGetPropNodeInternal(node, name, NULL, xmlCheckDTD);
+    if (prop == NULL)
+	return(NULL);
+    return(xmlGetPropNodeValueInternal(prop));
+}
+
+/**
+ * xmlGetNsProp:
+ * @node:  the node
+ * @name:  the attribute name
+ * @nameSpace:  the URI of the namespace
+ *
+ * Search and get the value of an attribute associated to a node
+ * This attribute has to be anchored in the namespace specified.
+ * This does the entity substitution.
+ * This function looks in DTD attribute declaration for #FIXED or
+ * default declaration values unless DTD use has been turned off.
+ *
+ * Returns the attribute value or NULL if not found.
+ *     It's up to the caller to free the memory with xmlFree().
+ */
+xmlChar *
+xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+    xmlAttrPtr prop;
+
+    prop = xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD);
+    if (prop == NULL)
+	return(NULL);
+    return(xmlGetPropNodeValueInternal(prop));
+}
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlUnsetProp:
+ * @node:  the node
+ * @name:  the attribute name
+ *
+ * Remove an attribute carried by a node.
+ * This handles only attributes in no namespace.
+ * Returns 0 if successful, -1 if not found
+ */
+int
+xmlUnsetProp(xmlNodePtr node, const xmlChar *name) {
+    xmlAttrPtr prop;
+
+    prop = xmlGetPropNodeInternal(node, name, NULL, 0);
+    if (prop == NULL)
+	return(-1);
+    xmlUnlinkNode((xmlNodePtr) prop);
+    xmlFreeProp(prop);
+    return(0);
+}
+
+/**
+ * xmlUnsetNsProp:
+ * @node:  the node
+ * @ns:  the namespace definition
+ * @name:  the attribute name
+ *
+ * Remove an attribute carried by a node.
+ * Returns 0 if successful, -1 if not found
+ */
+int
+xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name) {
+    xmlAttrPtr prop;
+
+    prop = xmlGetPropNodeInternal(node, name, (ns != NULL) ? ns->href : NULL, 0);
+    if (prop == NULL)
+	return(-1);
+    xmlUnlinkNode((xmlNodePtr) prop);
+    xmlFreeProp(prop);
+    return(0);
+}
+#endif
+
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+/**
+ * xmlSetProp:
+ * @node:  the node
+ * @name:  the attribute name (a QName)
+ * @value:  the attribute value
+ *
+ * Set (or reset) an attribute carried by a node.
+ * If @name has a prefix, then the corresponding
+ * namespace-binding will be used, if in scope; it is an
+ * error it there's no such ns-binding for the prefix in
+ * scope.
+ * Returns the attribute pointer.
+ *
+ */
+xmlAttrPtr
+xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
+    int len;
+    const xmlChar *nqname;
+
+    if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE))
+	return(NULL);
+
+    /*
+     * handle QNames
+     */
+    nqname = xmlSplitQName3(name, &len);
+    if (nqname != NULL) {
+        xmlNsPtr ns;
+	xmlChar *prefix = xmlStrndup(name, len);
+	ns = xmlSearchNs(node->doc, node, prefix);
+	if (prefix != NULL)
+	    xmlFree(prefix);
+	if (ns != NULL)
+	    return(xmlSetNsProp(node, ns, nqname, value));
+    }
+    return(xmlSetNsProp(node, NULL, name, value));
+}
+
+/**
+ * xmlSetNsProp:
+ * @node:  the node
+ * @ns:  the namespace definition
+ * @name:  the attribute name
+ * @value:  the attribute value
+ *
+ * Set (or reset) an attribute carried by a node.
+ * The ns structure must be in scope, this is not checked
+ *
+ * Returns the attribute pointer.
+ */
+xmlAttrPtr
+xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
+	     const xmlChar *value)
+{
+    xmlAttrPtr prop;
+
+    if (ns && (ns->href == NULL))
+	return(NULL);
+    prop = xmlGetPropNodeInternal(node, name, (ns != NULL) ? ns->href : NULL, 0);
+    if (prop != NULL) {
+	/*
+	* Modify the attribute's value.
+	*/
+	if (prop->atype == XML_ATTRIBUTE_ID) {
+	    xmlRemoveID(node->doc, prop);
+	    prop->atype = XML_ATTRIBUTE_ID;
+	}
+	if (prop->children != NULL)
+	    xmlFreeNodeList(prop->children);
+	prop->children = NULL;
+	prop->last = NULL;
+	prop->ns = ns;
+	if (value != NULL) {
+	    xmlNodePtr tmp;
+
+	    if(!xmlCheckUTF8(value)) {
+	        xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) node->doc,
+	                   NULL);
+                if (node->doc != NULL)
+                    node->doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+	    }
+	    prop->children = xmlNewDocText(node->doc, value);
+	    prop->last = NULL;
+	    tmp = prop->children;
+	    while (tmp != NULL) {
+		tmp->parent = (xmlNodePtr) prop;
+		if (tmp->next == NULL)
+		    prop->last = tmp;
+		tmp = tmp->next;
+	    }
+	}
+	if (prop->atype == XML_ATTRIBUTE_ID)
+	    xmlAddID(NULL, node->doc, value, prop);
+	return(prop);
+    }
+    /*
+    * No equal attr found; create a new one.
+    */
+    return(xmlNewPropInternal(node, ns, name, value, 0));
+}
+
+#endif /* LIBXML_TREE_ENABLED */
+
+/**
+ * xmlNodeIsText:
+ * @node:  the node
+ *
+ * Is this node a Text node ?
+ * Returns 1 yes, 0 no
+ */
+int
+xmlNodeIsText(xmlNodePtr node) {
+    if (node == NULL) return(0);
+
+    if (node->type == XML_TEXT_NODE) return(1);
+    return(0);
+}
+
+/**
+ * xmlIsBlankNode:
+ * @node:  the node
+ *
+ * Checks whether this node is an empty or whitespace only
+ * (and possibly ignorable) text-node.
+ *
+ * Returns 1 yes, 0 no
+ */
+int
+xmlIsBlankNode(xmlNodePtr node) {
+    const xmlChar *cur;
+    if (node == NULL) return(0);
+
+    if ((node->type != XML_TEXT_NODE) &&
+        (node->type != XML_CDATA_SECTION_NODE))
+	return(0);
+    if (node->content == NULL) return(1);
+    cur = node->content;
+    while (*cur != 0) {
+	if (!IS_BLANK_CH(*cur)) return(0);
+	cur++;
+    }
+
+    return(1);
+}
+
+/**
+ * xmlTextConcat:
+ * @node:  the node
+ * @content:  the content
+ * @len:  @content length
+ *
+ * Concat the given string at the end of the existing node content
+ *
+ * Returns -1 in case of error, 0 otherwise
+ */
+
+int
+xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
+    if (node == NULL) return(-1);
+
+    if ((node->type != XML_TEXT_NODE) &&
+        (node->type != XML_CDATA_SECTION_NODE) &&
+	(node->type != XML_COMMENT_NODE) &&
+	(node->type != XML_PI_NODE)) {
+#ifdef DEBUG_TREE
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlTextConcat: node is not text nor CDATA\n");
+#endif
+        return(-1);
+    }
+    /* need to check if content is currently in the dictionary */
+    if ((node->content == (xmlChar *) &(node->properties)) ||
+        ((node->doc != NULL) && (node->doc->dict != NULL) &&
+		xmlDictOwns(node->doc->dict, node->content))) {
+	node->content = xmlStrncatNew(node->content, content, len);
+    } else {
+        node->content = xmlStrncat(node->content, content, len);
+    }
+    node->properties = NULL;
+    if (node->content == NULL)
+        return(-1);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			Output : to a FILE or in memory			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlBufferCreate:
+ *
+ * routine to create an XML buffer.
+ * returns the new structure.
+ */
+xmlBufferPtr
+xmlBufferCreate(void) {
+    xmlBufferPtr ret;
+
+    ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
+    if (ret == NULL) {
+	xmlTreeErrMemory("creating buffer");
+        return(NULL);
+    }
+    ret->use = 0;
+    ret->size = xmlDefaultBufferSize;
+    ret->alloc = xmlBufferAllocScheme;
+    ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
+    if (ret->content == NULL) {
+	xmlTreeErrMemory("creating buffer");
+	xmlFree(ret);
+        return(NULL);
+    }
+    ret->content[0] = 0;
+    ret->contentIO = NULL;
+    return(ret);
+}
+
+/**
+ * xmlBufferCreateSize:
+ * @size: initial size of buffer
+ *
+ * routine to create an XML buffer.
+ * returns the new structure.
+ */
+xmlBufferPtr
+xmlBufferCreateSize(size_t size) {
+    xmlBufferPtr ret;
+
+    ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
+    if (ret == NULL) {
+	xmlTreeErrMemory("creating buffer");
+        return(NULL);
+    }
+    ret->use = 0;
+    ret->alloc = xmlBufferAllocScheme;
+    ret->size = (size ? size+2 : 0);         /* +1 for ending null */
+    if (ret->size){
+        ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
+        if (ret->content == NULL) {
+	    xmlTreeErrMemory("creating buffer");
+            xmlFree(ret);
+            return(NULL);
+        }
+        ret->content[0] = 0;
+    } else
+	ret->content = NULL;
+    ret->contentIO = NULL;
+    return(ret);
+}
+
+/**
+ * xmlBufferCreateStatic:
+ * @mem: the memory area
+ * @size:  the size in byte
+ *
+ * routine to create an XML buffer from an immutable memory area.
+ * The area won't be modified nor copied, and is expected to be
+ * present until the end of the buffer lifetime.
+ *
+ * returns the new structure.
+ */
+xmlBufferPtr
+xmlBufferCreateStatic(void *mem, size_t size) {
+    xmlBufferPtr ret;
+
+    if ((mem == NULL) || (size == 0))
+        return(NULL);
+
+    ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
+    if (ret == NULL) {
+	xmlTreeErrMemory("creating buffer");
+        return(NULL);
+    }
+    ret->use = size;
+    ret->size = size;
+    ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE;
+    ret->content = (xmlChar *) mem;
+    return(ret);
+}
+
+/**
+ * xmlBufferSetAllocationScheme:
+ * @buf:  the buffer to tune
+ * @scheme:  allocation scheme to use
+ *
+ * Sets the allocation scheme for this buffer
+ */
+void
+xmlBufferSetAllocationScheme(xmlBufferPtr buf,
+                             xmlBufferAllocationScheme scheme) {
+    if (buf == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferSetAllocationScheme: buf == NULL\n");
+#endif
+        return;
+    }
+    if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
+        (buf->alloc == XML_BUFFER_ALLOC_IO)) return;
+    if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
+        (scheme == XML_BUFFER_ALLOC_EXACT) ||
+        (scheme == XML_BUFFER_ALLOC_IMMUTABLE))
+	buf->alloc = scheme;
+}
+
+/**
+ * xmlBufferFree:
+ * @buf:  the buffer to free
+ *
+ * Frees an XML buffer. It frees both the content and the structure which
+ * encapsulate it.
+ */
+void
+xmlBufferFree(xmlBufferPtr buf) {
+    if (buf == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferFree: buf == NULL\n");
+#endif
+	return;
+    }
+
+    if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
+        (buf->contentIO != NULL)) {
+        xmlFree(buf->contentIO);
+    } else if ((buf->content != NULL) &&
+        (buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)) {
+        xmlFree(buf->content);
+    }
+    xmlFree(buf);
+}
+
+/**
+ * xmlBufferEmpty:
+ * @buf:  the buffer
+ *
+ * empty a buffer.
+ */
+void
+xmlBufferEmpty(xmlBufferPtr buf) {
+    if (buf == NULL) return;
+    if (buf->content == NULL) return;
+    buf->use = 0;
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) {
+        buf->content = BAD_CAST "";
+    } else if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
+               (buf->contentIO != NULL)) {
+        size_t start_buf = buf->content - buf->contentIO;
+
+	buf->size += start_buf;
+        buf->content = buf->contentIO;
+        buf->content[0] = 0;
+    } else {
+        buf->content[0] = 0;
+    }
+}
+
+/**
+ * xmlBufferShrink:
+ * @buf:  the buffer to dump
+ * @len:  the number of xmlChar to remove
+ *
+ * Remove the beginning of an XML buffer.
+ *
+ * Returns the number of #xmlChar removed, or -1 in case of failure.
+ */
+int
+xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
+    if (buf == NULL) return(-1);
+    if (len == 0) return(0);
+    if (len > buf->use) return(-1);
+
+    buf->use -= len;
+    if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
+        ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
+	/*
+	 * we just move the content pointer, but also make sure
+	 * the perceived buffer size has shrinked accordingly
+	 */
+        buf->content += len;
+	buf->size -= len;
+
+        /*
+	 * sometimes though it maybe be better to really shrink
+	 * on IO buffers
+	 */
+	if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
+	    size_t start_buf = buf->content - buf->contentIO;
+	    if (start_buf >= buf->size) {
+		memmove(buf->contentIO, &buf->content[0], buf->use);
+		buf->content = buf->contentIO;
+		buf->content[buf->use] = 0;
+		buf->size += start_buf;
+	    }
+	}
+    } else {
+	memmove(buf->content, &buf->content[len], buf->use);
+	buf->content[buf->use] = 0;
+    }
+    return(len);
+}
+
+/**
+ * xmlBufferGrow:
+ * @buf:  the buffer
+ * @len:  the minimum free size to allocate
+ *
+ * Grow the available space of an XML buffer.
+ *
+ * Returns the new available space or -1 in case of error
+ */
+int
+xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
+    int size;
+    xmlChar *newbuf;
+
+    if (buf == NULL) return(-1);
+
+    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)
+     * 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
+        size = buf->use + len + 100;
+#else
+    size = buf->use + len + 100;
+#endif
+
+    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
+        size_t start_buf = buf->content - buf->contentIO;
+
+	newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
+	if (newbuf == NULL) {
+	    xmlTreeErrMemory("growing buffer");
+	    return(-1);
+	}
+	buf->contentIO = newbuf;
+	buf->content = newbuf + start_buf;
+    } else {
+	newbuf = (xmlChar *) xmlRealloc(buf->content, size);
+	if (newbuf == NULL) {
+	    xmlTreeErrMemory("growing buffer");
+	    return(-1);
+	}
+	buf->content = newbuf;
+    }
+    buf->size = size;
+    return(buf->size - buf->use);
+}
+
+/**
+ * xmlBufferDump:
+ * @file:  the file output
+ * @buf:  the buffer to dump
+ *
+ * Dumps an XML buffer to  a FILE *.
+ * Returns the number of #xmlChar written
+ */
+int
+xmlBufferDump(FILE *file, xmlBufferPtr buf) {
+    int ret;
+
+    if (buf == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferDump: buf == NULL\n");
+#endif
+	return(0);
+    }
+    if (buf->content == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferDump: buf->content == NULL\n");
+#endif
+	return(0);
+    }
+    if (file == NULL)
+	file = stdout;
+    ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
+    return(ret);
+}
+
+/**
+ * xmlBufferContent:
+ * @buf:  the buffer
+ *
+ * Function to extract the content of a buffer
+ *
+ * Returns the internal content
+ */
+
+const xmlChar *
+xmlBufferContent(const xmlBufferPtr buf)
+{
+    if(!buf)
+        return NULL;
+
+    return buf->content;
+}
+
+/**
+ * xmlBufferLength:
+ * @buf:  the buffer
+ *
+ * Function to get the length of a buffer
+ *
+ * Returns the length of data in the internal content
+ */
+
+int
+xmlBufferLength(const xmlBufferPtr buf)
+{
+    if(!buf)
+        return 0;
+
+    return buf->use;
+}
+
+/**
+ * xmlBufferResize:
+ * @buf:  the buffer to resize
+ * @size:  the desired size
+ *
+ * Resize a buffer to accommodate minimum size of @size.
+ *
+ * Returns  0 in case of problems, 1 otherwise
+ */
+int
+xmlBufferResize(xmlBufferPtr buf, unsigned int size)
+{
+    unsigned int newSize;
+    xmlChar* rebuf = NULL;
+    size_t start_buf;
+
+    if (buf == NULL)
+        return(0);
+
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
+
+    /* Don't resize if we don't have to */
+    if (size < buf->size)
+        return 1;
+
+    /* figure out new size */
+    switch (buf->alloc){
+	case XML_BUFFER_ALLOC_IO:
+	case XML_BUFFER_ALLOC_DOUBLEIT:
+	    /*take care of empty case*/
+	    newSize = (buf->size ? buf->size*2 : size + 10);
+	    while (size > newSize) {
+	        if (newSize > UINT_MAX / 2) {
+	            xmlTreeErrMemory("growing buffer");
+	            return 0;
+	        }
+	        newSize *= 2;
+	    }
+	    break;
+	case XML_BUFFER_ALLOC_EXACT:
+	    newSize = size+10;
+	    break;
+	default:
+	    newSize = size+10;
+	    break;
+    }
+
+    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
+        start_buf = buf->content - buf->contentIO;
+
+        if (start_buf > newSize) {
+	    /* move data back to start */
+	    memmove(buf->contentIO, buf->content, buf->use);
+	    buf->content = buf->contentIO;
+	    buf->content[buf->use] = 0;
+	    buf->size += start_buf;
+	} else {
+	    rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
+	    if (rebuf == NULL) {
+		xmlTreeErrMemory("growing buffer");
+		return 0;
+	    }
+	    buf->contentIO = rebuf;
+	    buf->content = rebuf + start_buf;
+	}
+    } else {
+	if (buf->content == NULL) {
+	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
+	} else if (buf->size - buf->use < 100) {
+	    rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
+        } else {
+	    /*
+	     * if we are reallocating a buffer far from being full, it's
+	     * better to make a new allocation and copy only the used range
+	     * and free the old one.
+	     */
+	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
+	    if (rebuf != NULL) {
+		memcpy(rebuf, buf->content, buf->use);
+		xmlFree(buf->content);
+		rebuf[buf->use] = 0;
+	    }
+	}
+	if (rebuf == NULL) {
+	    xmlTreeErrMemory("growing buffer");
+	    return 0;
+	}
+	buf->content = rebuf;
+    }
+    buf->size = newSize;
+
+    return 1;
+}
+
+/**
+ * xmlBufferAdd:
+ * @buf:  the buffer to dump
+ * @str:  the #xmlChar string
+ * @len:  the number of #xmlChar to add
+ *
+ * Add a string range to an XML buffer. if len == -1, the length of
+ * str is recomputed.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
+    unsigned int needSize;
+
+    if ((str == NULL) || (buf == NULL)) {
+	return -1;
+    }
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
+    if (len < -1) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferAdd: len < 0\n");
+#endif
+	return -1;
+    }
+    if (len == 0) return 0;
+
+    if (len < 0)
+        len = xmlStrlen(str);
+
+    if (len < 0) return -1;
+    if (len == 0) return 0;
+
+    needSize = buf->use + len + 2;
+    if (needSize > buf->size){
+        if (!xmlBufferResize(buf, needSize)){
+	    xmlTreeErrMemory("growing buffer");
+            return XML_ERR_NO_MEMORY;
+        }
+    }
+
+    memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
+    buf->use += len;
+    buf->content[buf->use] = 0;
+    return 0;
+}
+
+/**
+ * xmlBufferAddHead:
+ * @buf:  the buffer
+ * @str:  the #xmlChar string
+ * @len:  the number of #xmlChar to add
+ *
+ * Add a string range to the beginning of an XML buffer.
+ * if len == -1, the length of @str is recomputed.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
+    unsigned int needSize;
+
+    if (buf == NULL)
+        return(-1);
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
+    if (str == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferAddHead: str == NULL\n");
+#endif
+	return -1;
+    }
+    if (len < -1) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferAddHead: len < 0\n");
+#endif
+	return -1;
+    }
+    if (len == 0) return 0;
+
+    if (len < 0)
+        len = xmlStrlen(str);
+
+    if (len <= 0) return -1;
+
+    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
+        size_t start_buf = buf->content - buf->contentIO;
+
+	if (start_buf > (unsigned int) len) {
+	    /*
+	     * We can add it in the space previously shrinked
+	     */
+	    buf->content -= len;
+            memmove(&buf->content[0], str, len);
+	    buf->use += len;
+	    buf->size += len;
+	    return(0);
+	}
+    }
+    needSize = buf->use + len + 2;
+    if (needSize > buf->size){
+        if (!xmlBufferResize(buf, needSize)){
+	    xmlTreeErrMemory("growing buffer");
+            return XML_ERR_NO_MEMORY;
+        }
+    }
+
+    memmove(&buf->content[len], &buf->content[0], buf->use);
+    memmove(&buf->content[0], str, len);
+    buf->use += len;
+    buf->content[buf->use] = 0;
+    return 0;
+}
+
+/**
+ * xmlBufferCat:
+ * @buf:  the buffer to add to
+ * @str:  the #xmlChar string
+ *
+ * Append a zero terminated string to an XML buffer.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
+    if (buf == NULL)
+        return(-1);
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
+    if (str == NULL) return -1;
+    return xmlBufferAdd(buf, str, -1);
+}
+
+/**
+ * xmlBufferCCat:
+ * @buf:  the buffer to dump
+ * @str:  the C char string
+ *
+ * Append a zero terminated C string to an XML buffer.
+ *
+ * Returns 0 successful, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlBufferCCat(xmlBufferPtr buf, const char *str) {
+    const char *cur;
+
+    if (buf == NULL)
+        return(-1);
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
+    if (str == NULL) {
+#ifdef DEBUG_BUFFER
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlBufferCCat: str == NULL\n");
+#endif
+	return -1;
+    }
+    for (cur = str;*cur != 0;cur++) {
+        if (buf->use  + 10 >= buf->size) {
+            if (!xmlBufferResize(buf, buf->use+10)){
+		xmlTreeErrMemory("growing buffer");
+                return XML_ERR_NO_MEMORY;
+            }
+        }
+        buf->content[buf->use++] = *cur;
+    }
+    buf->content[buf->use] = 0;
+    return 0;
+}
+
+/**
+ * xmlBufferWriteCHAR:
+ * @buf:  the XML buffer
+ * @string:  the string to add
+ *
+ * routine which manages and grows an output buffer. This one adds
+ * xmlChars at the end of the buffer.
+ */
+void
+xmlBufferWriteCHAR(xmlBufferPtr buf, const xmlChar *string) {
+    if (buf == NULL)
+        return;
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+    xmlBufferCat(buf, string);
+}
+
+/**
+ * xmlBufferWriteChar:
+ * @buf:  the XML buffer output
+ * @string:  the string to add
+ *
+ * routine which manage and grows an output buffer. This one add
+ * C chars at the end of the array.
+ */
+void
+xmlBufferWriteChar(xmlBufferPtr buf, const char *string) {
+    if (buf == NULL)
+        return;
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+    xmlBufferCCat(buf, string);
+}
+
+
+/**
+ * xmlBufferWriteQuotedString:
+ * @buf:  the XML buffer output
+ * @string:  the string to add
+ *
+ * routine which manage and grows an output buffer. This one writes
+ * a quoted or double quoted #xmlChar string, checking first if it holds
+ * quote or double-quotes internally
+ */
+void
+xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
+    const xmlChar *cur, *base;
+    if (buf == NULL)
+        return;
+    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
+    if (xmlStrchr(string, '\"')) {
+        if (xmlStrchr(string, '\'')) {
+#ifdef DEBUG_BUFFER
+	    xmlGenericError(xmlGenericErrorContext,
+ "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
+#endif
+	    xmlBufferCCat(buf, "\"");
+            base = cur = string;
+            while(*cur != 0){
+                if(*cur == '"'){
+                    if (base != cur)
+                        xmlBufferAdd(buf, base, cur - base);
+                    xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
+                    cur++;
+                    base = cur;
+                }
+                else {
+                    cur++;
+                }
+            }
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+	    xmlBufferCCat(buf, "\"");
+	}
+        else{
+	    xmlBufferCCat(buf, "\'");
+            xmlBufferCat(buf, string);
+	    xmlBufferCCat(buf, "\'");
+        }
+    } else {
+        xmlBufferCCat(buf, "\"");
+        xmlBufferCat(buf, string);
+        xmlBufferCCat(buf, "\"");
+    }
+}
+
+
+/**
+ * xmlGetDocCompressMode:
+ * @doc:  the document
+ *
+ * get the compression ratio for a document, ZLIB based
+ * Returns 0 (uncompressed) to 9 (max compression)
+ */
+int
+xmlGetDocCompressMode (xmlDocPtr doc) {
+    if (doc == NULL) return(-1);
+    return(doc->compression);
+}
+
+/**
+ * xmlSetDocCompressMode:
+ * @doc:  the document
+ * @mode:  the compression ratio
+ *
+ * set the compression ratio for a document, ZLIB based
+ * Correct values: 0 (uncompressed) to 9 (max compression)
+ */
+void
+xmlSetDocCompressMode (xmlDocPtr doc, int mode) {
+    if (doc == NULL) return;
+    if (mode < 0) doc->compression = 0;
+    else if (mode > 9) doc->compression = 9;
+    else doc->compression = mode;
+}
+
+/**
+ * xmlGetCompressMode:
+ *
+ * get the default compression mode used, ZLIB based.
+ * Returns 0 (uncompressed) to 9 (max compression)
+ */
+int
+xmlGetCompressMode(void)
+{
+    return (xmlCompressMode);
+}
+
+/**
+ * xmlSetCompressMode:
+ * @mode:  the compression ratio
+ *
+ * set the default compression mode used, ZLIB based
+ * Correct values: 0 (uncompressed) to 9 (max compression)
+ */
+void
+xmlSetCompressMode(int mode) {
+    if (mode < 0) xmlCompressMode = 0;
+    else if (mode > 9) xmlCompressMode = 9;
+    else xmlCompressMode = mode;
+}
+
+#define XML_TREE_NSMAP_PARENT -1
+#define XML_TREE_NSMAP_XML -2
+#define XML_TREE_NSMAP_DOC -3
+#define XML_TREE_NSMAP_CUSTOM -4
+
+typedef struct xmlNsMapItem *xmlNsMapItemPtr;
+struct xmlNsMapItem {
+    xmlNsMapItemPtr next;
+    xmlNsMapItemPtr prev;
+    xmlNsPtr oldNs; /* old ns decl reference */
+    xmlNsPtr newNs; /* new ns decl reference */
+    int shadowDepth; /* Shadowed at this depth */
+    /*
+    * depth:
+    * >= 0 == @node's ns-decls
+    * -1   == @parent's ns-decls
+    * -2   == the doc->oldNs XML ns-decl
+    * -3   == the doc->oldNs storage ns-decls
+    * -4   == ns-decls provided via custom ns-handling
+    */
+    int depth;
+};
+
+typedef struct xmlNsMap *xmlNsMapPtr;
+struct xmlNsMap {
+    xmlNsMapItemPtr first;
+    xmlNsMapItemPtr last;
+    xmlNsMapItemPtr pool;
+};
+
+#define XML_NSMAP_NOTEMPTY(m) (((m) != NULL) && ((m)->first != NULL))
+#define XML_NSMAP_FOREACH(m, i) for (i = (m)->first; i != NULL; i = (i)->next)
+#define XML_NSMAP_POP(m, i) \
+    i = (m)->last; \
+    (m)->last = (i)->prev; \
+    if ((m)->last == NULL) \
+	(m)->first = NULL; \
+    else \
+	(m)->last->next = NULL; \
+    (i)->next = (m)->pool; \
+    (m)->pool = i;
+
+/*
+* xmlDOMWrapNsMapFree:
+* @map: the ns-map
+*
+* Frees the ns-map
+*/
+static void
+xmlDOMWrapNsMapFree(xmlNsMapPtr nsmap)
+{
+    xmlNsMapItemPtr cur, tmp;
+
+    if (nsmap == NULL)
+	return;
+    cur = nsmap->pool;
+    while (cur != NULL) {
+	tmp = cur;
+	cur = cur->next;
+	xmlFree(tmp);
+    }
+    cur = nsmap->first;
+    while (cur != NULL) {
+	tmp = cur;
+	cur = cur->next;
+	xmlFree(tmp);
+    }
+    xmlFree(nsmap);
+}
+
+/*
+* xmlDOMWrapNsMapAddItem:
+* @map: the ns-map
+* @oldNs: the old ns-struct
+* @newNs: the new ns-struct
+* @depth: depth and ns-kind information
+*
+* Adds an ns-mapping item.
+*/
+static xmlNsMapItemPtr
+xmlDOMWrapNsMapAddItem(xmlNsMapPtr *nsmap, int position,
+		       xmlNsPtr oldNs, xmlNsPtr newNs, int depth)
+{
+    xmlNsMapItemPtr ret;
+    xmlNsMapPtr map;
+
+    if (nsmap == NULL)
+	return(NULL);
+    if ((position != -1) && (position != 0))
+	return(NULL);
+    map = *nsmap;
+
+    if (map == NULL) {
+	/*
+	* Create the ns-map.
+	*/
+	map = (xmlNsMapPtr) xmlMalloc(sizeof(struct xmlNsMap));
+	if (map == NULL) {
+	    xmlTreeErrMemory("allocating namespace map");
+	    return (NULL);
+	}
+	memset(map, 0, sizeof(struct xmlNsMap));
+	*nsmap = map;
+    }
+
+    if (map->pool != NULL) {
+	/*
+	* Reuse an item from the pool.
+	*/
+	ret = map->pool;
+	map->pool = ret->next;
+	memset(ret, 0, sizeof(struct xmlNsMapItem));
+    } else {
+	/*
+	* Create a new item.
+	*/
+	ret = (xmlNsMapItemPtr) xmlMalloc(sizeof(struct xmlNsMapItem));
+	if (ret == NULL) {
+	    xmlTreeErrMemory("allocating namespace map item");
+	    return (NULL);
+	}
+	memset(ret, 0, sizeof(struct xmlNsMapItem));
+    }
+
+    if (map->first == NULL) {
+	/*
+	* First ever.
+	*/
+	map->first = ret;
+	map->last = ret;
+    } else if (position == -1) {
+	/*
+	* Append.
+	*/
+	ret->prev = map->last;
+	map->last->next = ret;
+	map->last = ret;
+    } else if (position == 0) {
+	/*
+	* Set on first position.
+	*/
+	map->first->prev = ret;
+	ret->next = map->first;
+	map->first = ret;
+    } else
+	return(NULL);
+
+    ret->oldNs = oldNs;
+    ret->newNs = newNs;
+    ret->shadowDepth = -1;
+    ret->depth = depth;
+    return (ret);
+}
+
+/*
+* xmlDOMWrapStoreNs:
+* @doc: the doc
+* @nsName: the namespace name
+* @prefix: the prefix
+*
+* Creates or reuses an xmlNs struct on doc->oldNs with
+* the given prefix and namespace name.
+*
+* Returns the aquired ns struct or NULL in case of an API
+*         or internal error.
+*/
+static xmlNsPtr
+xmlDOMWrapStoreNs(xmlDocPtr doc,
+		   const xmlChar *nsName,
+		   const xmlChar *prefix)
+{
+    xmlNsPtr ns;
+
+    if (doc == NULL)
+	return (NULL);
+    ns = xmlTreeEnsureXMLDecl(doc);
+    if (ns == NULL)
+	return (NULL);
+    if (ns->next != NULL) {
+	/* Reuse. */
+	ns = ns->next;
+	while (ns != NULL) {
+	    if (((ns->prefix == prefix) ||
+		xmlStrEqual(ns->prefix, prefix)) &&
+		xmlStrEqual(ns->href, nsName)) {
+		return (ns);
+	    }
+	    if (ns->next == NULL)
+		break;
+	    ns = ns->next;
+	}
+    }
+    /* Create. */
+    if (ns != NULL) {
+        ns->next = xmlNewNs(NULL, nsName, prefix);
+        return (ns->next);
+    }
+    return(NULL);
+}
+
+/*
+* xmlDOMWrapNewCtxt:
+*
+* Allocates and initializes a new DOM-wrapper context.
+*
+* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal errror.
+*/
+xmlDOMWrapCtxtPtr
+xmlDOMWrapNewCtxt(void)
+{
+    xmlDOMWrapCtxtPtr ret;
+
+    ret = xmlMalloc(sizeof(xmlDOMWrapCtxt));
+    if (ret == NULL) {
+	xmlTreeErrMemory("allocating DOM-wrapper context");
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlDOMWrapCtxt));
+    return (ret);
+}
+
+/*
+* xmlDOMWrapFreeCtxt:
+* @ctxt: the DOM-wrapper context
+*
+* Frees the DOM-wrapper context.
+*/
+void
+xmlDOMWrapFreeCtxt(xmlDOMWrapCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+	return;
+    if (ctxt->namespaceMap != NULL)
+	xmlDOMWrapNsMapFree((xmlNsMapPtr) ctxt->namespaceMap);
+    /*
+    * TODO: Store the namespace map in the context.
+    */
+    xmlFree(ctxt);
+}
+
+/*
+* xmlTreeLookupNsListByPrefix:
+* @nsList: a list of ns-structs
+* @prefix: the searched prefix
+*
+* Searches for a ns-decl with the given prefix in @nsList.
+*
+* Returns the ns-decl if found, NULL if not found and on
+*         API errors.
+*/
+static xmlNsPtr
+xmlTreeNSListLookupByPrefix(xmlNsPtr nsList, const xmlChar *prefix)
+{
+    if (nsList == NULL)
+	return (NULL);
+    {
+	xmlNsPtr ns;
+	ns = nsList;
+	do {
+	    if ((prefix == ns->prefix) ||
+		xmlStrEqual(prefix, ns->prefix)) {
+		return (ns);
+	    }
+	    ns = ns->next;
+	} while (ns != NULL);
+    }
+    return (NULL);
+}
+
+/*
+*
+* xmlDOMWrapNSNormGatherInScopeNs:
+* @map: the namespace map
+* @node: the node to start with
+*
+* Puts in-scope namespaces into the ns-map.
+*
+* Returns 0 on success, -1 on API or internal errors.
+*/
+static int
+xmlDOMWrapNSNormGatherInScopeNs(xmlNsMapPtr *map,
+				xmlNodePtr node)
+{
+    xmlNodePtr cur;
+    xmlNsPtr ns;
+    xmlNsMapItemPtr mi;
+    int shadowed;
+
+    if ((map == NULL) || (*map != NULL))
+	return (-1);
+    /*
+    * Get in-scope ns-decls of @parent.
+    */
+    cur = node;
+    while ((cur != NULL) && (cur != (xmlNodePtr) cur->doc)) {
+	if (cur->type == XML_ELEMENT_NODE) {
+	    if (cur->nsDef != NULL) {
+		ns = cur->nsDef;
+		do {
+		    shadowed = 0;
+		    if (XML_NSMAP_NOTEMPTY(*map)) {
+			/*
+			* Skip shadowed prefixes.
+			*/
+			XML_NSMAP_FOREACH(*map, mi) {
+			    if ((ns->prefix == mi->newNs->prefix) ||
+				xmlStrEqual(ns->prefix, mi->newNs->prefix)) {
+				shadowed = 1;
+				break;
+			    }
+			}
+		    }
+		    /*
+		    * Insert mapping.
+		    */
+		    mi = xmlDOMWrapNsMapAddItem(map, 0, NULL,
+			ns, XML_TREE_NSMAP_PARENT);
+		    if (mi == NULL)
+			return (-1);
+		    if (shadowed)
+			mi->shadowDepth = 0;
+		    ns = ns->next;
+		} while (ns != NULL);
+	    }
+	}
+	cur = cur->parent;
+    }
+    return (0);
+}
+
+/*
+* XML_TREE_ADOPT_STR: If we have a dest-dict, put @str in the dict;
+* otherwise copy it, when it was in the source-dict.
+*/
+#define XML_TREE_ADOPT_STR(str) \
+    if (adoptStr && (str != NULL)) { \
+	if (destDoc->dict) { \
+	    const xmlChar *old = str;	\
+	    str = xmlDictLookup(destDoc->dict, str, -1); \
+	    if ((sourceDoc == NULL) || (sourceDoc->dict == NULL) || \
+	        (!xmlDictOwns(sourceDoc->dict, old))) \
+		xmlFree((char *)old); \
+	} else if ((sourceDoc) && (sourceDoc->dict) && \
+	    xmlDictOwns(sourceDoc->dict, str)) { \
+	    str = BAD_CAST xmlStrdup(str); \
+	} \
+    }
+
+/*
+* XML_TREE_ADOPT_STR_2: If @str was in the source-dict, then
+* put it in dest-dict or copy it.
+*/
+#define XML_TREE_ADOPT_STR_2(str) \
+    if (adoptStr && (str != NULL) && (sourceDoc != NULL) && \
+	(sourceDoc->dict != NULL) && \
+	xmlDictOwns(sourceDoc->dict, cur->content)) { \
+	if (destDoc->dict) \
+	    cur->content = (xmlChar *) \
+		xmlDictLookup(destDoc->dict, cur->content, -1); \
+	else \
+	    cur->content = xmlStrdup(BAD_CAST cur->content); \
+    }
+
+/*
+* xmlDOMWrapNSNormAddNsMapItem2:
+*
+* For internal use. Adds a ns-decl mapping.
+*
+* Returns 0 on success, -1 on internal errors.
+*/
+static int
+xmlDOMWrapNSNormAddNsMapItem2(xmlNsPtr **list, int *size, int *number,
+			xmlNsPtr oldNs, xmlNsPtr newNs)
+{
+    if (*list == NULL) {
+	*list = (xmlNsPtr *) xmlMalloc(6 * sizeof(xmlNsPtr));
+	if (*list == NULL) {
+	    xmlTreeErrMemory("alloc ns map item");
+	    return(-1);
+	}
+	*size = 3;
+	*number = 0;
+    } else if ((*number) >= (*size)) {
+	*size *= 2;
+	*list = (xmlNsPtr *) xmlRealloc(*list,
+	    (*size) * 2 * sizeof(xmlNsPtr));
+	if (*list == NULL) {
+	    xmlTreeErrMemory("realloc ns map item");
+	    return(-1);
+	}
+    }
+    (*list)[2 * (*number)] = oldNs;
+    (*list)[2 * (*number) +1] = newNs;
+    (*number)++;
+    return (0);
+}
+
+/*
+* xmlDOMWrapRemoveNode:
+* @ctxt: a DOM wrapper context
+* @doc: the doc
+* @node: the node to be removed.
+* @options: set of options, unused at the moment
+*
+* Unlinks the given node from its owner.
+* This will substitute ns-references to node->nsDef for
+* ns-references to doc->oldNs, thus ensuring the removed
+* branch to be autark wrt ns-references.
+*
+* NOTE: This function was not intensively tested.
+*
+* Returns 0 on success, 1 if the node is not supported,
+*         -1 on API and internal errors.
+*/
+int
+xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
+		     xmlNodePtr node, int options ATTRIBUTE_UNUSED)
+{
+    xmlNsPtr *list = NULL;
+    int sizeList, nbList, i, j;
+    xmlNsPtr ns;
+
+    if ((node == NULL) || (doc == NULL) || (node->doc != doc))
+	return (-1);
+
+    /* TODO: 0 or -1 ? */
+    if (node->parent == NULL)
+	return (0);
+
+    switch (node->type) {
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_ENTITY_REF_NODE:
+	case XML_PI_NODE:
+	case XML_COMMENT_NODE:
+	    xmlUnlinkNode(node);
+	    return (0);
+	case XML_ELEMENT_NODE:
+	case XML_ATTRIBUTE_NODE:
+	    break;
+	default:
+	    return (1);
+    }
+    xmlUnlinkNode(node);
+    /*
+    * Save out-of-scope ns-references in doc->oldNs.
+    */
+    do {
+	switch (node->type) {
+	    case XML_ELEMENT_NODE:
+		if ((ctxt == NULL) && (node->nsDef != NULL)) {
+		    ns = node->nsDef;
+		    do {
+			if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList,
+			    &nbList, ns, ns) == -1)
+			    goto internal_error;
+			ns = ns->next;
+		    } while (ns != NULL);
+		}
+		/* No break on purpose. */
+	    case XML_ATTRIBUTE_NODE:
+		if (node->ns != NULL) {
+		    /*
+		    * Find a mapping.
+		    */
+		    if (list != NULL) {
+			for (i = 0, j = 0; i < nbList; i++, j += 2) {
+			    if (node->ns == list[j]) {
+				node->ns = list[++j];
+				goto next_node;
+			    }
+			}
+		    }
+		    ns = NULL;
+		    if (ctxt != NULL) {
+			/*
+			* User defined.
+			*/
+		    } else {
+			/*
+			* Add to doc's oldNs.
+			*/
+			ns = xmlDOMWrapStoreNs(doc, node->ns->href,
+			    node->ns->prefix);
+			if (ns == NULL)
+			    goto internal_error;
+		    }
+		    if (ns != NULL) {
+			/*
+			* Add mapping.
+			*/
+			if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList,
+			    &nbList, node->ns, ns) == -1)
+			    goto internal_error;
+		    }
+		    node->ns = ns;
+		}
+		if ((node->type == XML_ELEMENT_NODE) &&
+		    (node->properties != NULL)) {
+		    node = (xmlNodePtr) node->properties;
+		    continue;
+		}
+		break;
+	    default:
+		goto next_sibling;
+	}
+next_node:
+	if ((node->type == XML_ELEMENT_NODE) &&
+	    (node->children != NULL)) {
+	    node = node->children;
+	    continue;
+	}
+next_sibling:
+	if (node == NULL)
+	    break;
+	if (node->next != NULL)
+	    node = node->next;
+	else {
+	    node = node->parent;
+	    goto next_sibling;
+	}
+    } while (node != NULL);
+
+    if (list != NULL)
+	xmlFree(list);
+    return (0);
+
+internal_error:
+    if (list != NULL)
+	xmlFree(list);
+    return (-1);
+}
+
+/*
+* xmlSearchNsByNamespaceStrict:
+* @doc: the document
+* @node: the start node
+* @nsName: the searched namespace name
+* @retNs: the resulting ns-decl
+* @prefixed: if the found ns-decl must have a prefix (for attributes)
+*
+* Dynamically searches for a ns-declaration which matches
+* the given @nsName in the ancestor-or-self axis of @node.
+*
+* Returns 1 if a ns-decl was found, 0 if not and -1 on API
+*         and internal errors.
+*/
+static int
+xmlSearchNsByNamespaceStrict(xmlDocPtr doc, xmlNodePtr node,
+			     const xmlChar* nsName,
+			     xmlNsPtr *retNs, int prefixed)
+{
+    xmlNodePtr cur, prev = NULL, out = NULL;
+    xmlNsPtr ns, prevns;
+
+    if ((doc == NULL) || (nsName == NULL) || (retNs == NULL))
+	return (-1);
+
+    *retNs = NULL;
+    if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
+	*retNs = xmlTreeEnsureXMLDecl(doc);
+	if (*retNs == NULL)
+	    return (-1);
+	return (1);
+    }
+    cur = node;
+    do {
+	if (cur->type == XML_ELEMENT_NODE) {
+	    if (cur->nsDef != NULL) {
+		for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
+		    if (prefixed && (ns->prefix == NULL))
+			continue;
+		    if (prev != NULL) {
+			/*
+			* Check the last level of ns-decls for a
+			* shadowing prefix.
+			*/
+			prevns = prev->nsDef;
+			do {
+			    if ((prevns->prefix == ns->prefix) ||
+				((prevns->prefix != NULL) &&
+				(ns->prefix != NULL) &&
+				xmlStrEqual(prevns->prefix, ns->prefix))) {
+				/*
+				* Shadowed.
+				*/
+				break;
+			    }
+			    prevns = prevns->next;
+			} while (prevns != NULL);
+			if (prevns != NULL)
+			    continue;
+		    }
+		    /*
+		    * Ns-name comparison.
+		    */
+		    if ((nsName == ns->href) ||
+			xmlStrEqual(nsName, ns->href)) {
+			/*
+			* At this point the prefix can only be shadowed,
+			* if we are the the (at least) 3rd level of
+			* ns-decls.
+			*/
+			if (out) {
+			    int ret;
+
+			    ret = xmlNsInScope(doc, node, prev, ns->prefix);
+			    if (ret < 0)
+				return (-1);
+			    /*
+			    * TODO: Should we try to find a matching ns-name
+			    * only once? This here keeps on searching.
+			    * I think we should try further since, there might
+			    * be an other matching ns-decl with an unshadowed
+			    * prefix.
+			    */
+			    if (! ret)
+				continue;
+			}
+			*retNs = ns;
+			return (1);
+		    }
+		}
+		out = prev;
+		prev = cur;
+	    }
+	} else if ((cur->type == XML_ENTITY_NODE) ||
+            (cur->type == XML_ENTITY_DECL))
+	    return (0);
+	cur = cur->parent;
+    } while ((cur != NULL) && (cur->doc != (xmlDocPtr) cur));
+    return (0);
+}
+
+/*
+* xmlSearchNsByPrefixStrict:
+* @doc: the document
+* @node: the start node
+* @prefix: the searched namespace prefix
+* @retNs: the resulting ns-decl
+*
+* Dynamically searches for a ns-declaration which matches
+* the given @nsName in the ancestor-or-self axis of @node.
+*
+* Returns 1 if a ns-decl was found, 0 if not and -1 on API
+*         and internal errors.
+*/
+static int
+xmlSearchNsByPrefixStrict(xmlDocPtr doc, xmlNodePtr node,
+			  const xmlChar* prefix,
+			  xmlNsPtr *retNs)
+{
+    xmlNodePtr cur;
+    xmlNsPtr ns;
+
+    if ((doc == NULL) || (node == NULL))
+	return (-1);
+
+    if (retNs)
+	*retNs = NULL;
+    if (IS_STR_XML(prefix)) {
+	if (retNs) {
+	    *retNs = xmlTreeEnsureXMLDecl(doc);
+	    if (*retNs == NULL)
+		return (-1);
+	}
+	return (1);
+    }
+    cur = node;
+    do {
+	if (cur->type == XML_ELEMENT_NODE) {
+	    if (cur->nsDef != NULL) {
+		ns = cur->nsDef;
+		do {
+		    if ((prefix == ns->prefix) ||
+			xmlStrEqual(prefix, ns->prefix))
+		    {
+			/*
+			* Disabled namespaces, e.g. xmlns:abc="".
+			*/
+			if (ns->href == NULL)
+			    return(0);
+			if (retNs)
+			    *retNs = ns;
+			return (1);
+		    }
+		    ns = ns->next;
+		} while (ns != NULL);
+	    }
+	} else if ((cur->type == XML_ENTITY_NODE) ||
+            (cur->type == XML_ENTITY_DECL))
+	    return (0);
+	cur = cur->parent;
+    } while ((cur != NULL) && (cur->doc != (xmlDocPtr) cur));
+    return (0);
+}
+
+/*
+* xmlDOMWrapNSNormDeclareNsForced:
+* @doc: the doc
+* @elem: the element-node to declare on
+* @nsName: the namespace-name of the ns-decl
+* @prefix: the preferred prefix of the ns-decl
+* @checkShadow: ensure that the new ns-decl doesn't shadow ancestor ns-decls
+*
+* Declares a new namespace on @elem. It tries to use the
+* given @prefix; if a ns-decl with the given prefix is already existent
+* on @elem, it will generate an other prefix.
+*
+* Returns 1 if a ns-decl was found, 0 if not and -1 on API
+*         and internal errors.
+*/
+static xmlNsPtr
+xmlDOMWrapNSNormDeclareNsForced(xmlDocPtr doc,
+				xmlNodePtr elem,
+				const xmlChar *nsName,
+				const xmlChar *prefix,
+				int checkShadow)
+{
+
+    xmlNsPtr ret;
+    char buf[50];
+    const xmlChar *pref;
+    int counter = 0;
+    /*
+    * Create a ns-decl on @anchor.
+    */
+    pref = prefix;
+    while (1) {
+	/*
+	* Lookup whether the prefix is unused in elem's ns-decls.
+	*/
+	if ((elem->nsDef != NULL) &&
+	    (xmlTreeNSListLookupByPrefix(elem->nsDef, pref) != NULL))
+	    goto ns_next_prefix;
+	if (checkShadow && elem->parent &&
+	    ((xmlNodePtr) elem->parent->doc != elem->parent)) {
+	    /*
+	    * Does it shadow ancestor ns-decls?
+	    */
+	    if (xmlSearchNsByPrefixStrict(doc, elem->parent, pref, NULL) == 1)
+		goto ns_next_prefix;
+	}
+	ret = xmlNewNs(NULL, nsName, pref);
+	if (ret == NULL)
+	    return (NULL);
+	if (elem->nsDef == NULL)
+	    elem->nsDef = ret;
+	else {
+	    xmlNsPtr ns2 = elem->nsDef;
+	    while (ns2->next != NULL)
+		ns2 = ns2->next;
+	    ns2->next = ret;
+	}
+	return (ret);
+ns_next_prefix:
+	counter++;
+	if (counter > 1000)
+	    return (NULL);
+	if (prefix == NULL) {
+	    snprintf((char *) buf, sizeof(buf),
+		"ns_%d", counter);
+	} else
+	    snprintf((char *) buf, sizeof(buf),
+	    "%.30s_%d", (char *)prefix, counter);
+	pref = BAD_CAST buf;
+    }
+}
+
+/*
+* xmlDOMWrapNSNormAquireNormalizedNs:
+* @doc: the doc
+* @elem: the element-node to declare namespaces on
+* @ns: the ns-struct to use for the search
+* @retNs: the found/created ns-struct
+* @nsMap: the ns-map
+* @depth: the current tree depth
+* @ancestorsOnly: search in ancestor ns-decls only
+* @prefixed: if the searched ns-decl must have a prefix (for attributes)
+*
+* Searches for a matching ns-name in the ns-decls of @nsMap, if not
+* found it will either declare it on @elem, or store it in doc->oldNs.
+* If a new ns-decl needs to be declared on @elem, it tries to use the
+* @ns->prefix for it, if this prefix is already in use on @elem, it will
+* change the prefix or the new ns-decl.
+*
+* Returns 0 if succeeded, -1 otherwise and on API/internal errors.
+*/
+static int
+xmlDOMWrapNSNormAquireNormalizedNs(xmlDocPtr doc,
+				   xmlNodePtr elem,
+				   xmlNsPtr ns,
+				   xmlNsPtr *retNs,
+				   xmlNsMapPtr *nsMap,
+
+				   int depth,
+				   int ancestorsOnly,
+				   int prefixed)
+{
+    xmlNsMapItemPtr mi;
+
+    if ((doc == NULL) || (ns == NULL) || (retNs == NULL) ||
+	(nsMap == NULL))
+	return (-1);
+
+    *retNs = NULL;
+    /*
+    * Handle XML namespace.
+    */
+    if (IS_STR_XML(ns->prefix)) {
+	/*
+	* Insert XML namespace mapping.
+	*/
+	*retNs = xmlTreeEnsureXMLDecl(doc);
+	if (*retNs == NULL)
+	    return (-1);
+	return (0);
+    }
+    /*
+    * If the search should be done in ancestors only and no
+    * @elem (the first ancestor) was specified, then skip the search.
+    */
+    if ((XML_NSMAP_NOTEMPTY(*nsMap)) &&
+	(! (ancestorsOnly && (elem == NULL))))
+    {
+	/*
+	* Try to find an equal ns-name in in-scope ns-decls.
+	*/
+	XML_NSMAP_FOREACH(*nsMap, mi) {
+	    if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+		/*
+		* ancestorsOnly: This should be turned on to gain speed,
+		* if one knows that the branch itself was already
+		* ns-wellformed and no stale references existed.
+		* I.e. it searches in the ancestor axis only.
+		*/
+		((! ancestorsOnly) || (mi->depth == XML_TREE_NSMAP_PARENT)) &&
+		/* Skip shadowed prefixes. */
+		(mi->shadowDepth == -1) &&
+		/* Skip xmlns="" or xmlns:foo="". */
+		((mi->newNs->href != NULL) &&
+		(mi->newNs->href[0] != 0)) &&
+		/* Ensure a prefix if wanted. */
+		((! prefixed) || (mi->newNs->prefix != NULL)) &&
+		/* Equal ns name */
+		((mi->newNs->href == ns->href) ||
+		xmlStrEqual(mi->newNs->href, ns->href))) {
+		/* Set the mapping. */
+		mi->oldNs = ns;
+		*retNs = mi->newNs;
+		return (0);
+	    }
+	}
+    }
+    /*
+    * No luck, the namespace is out of scope or shadowed.
+    */
+    if (elem == NULL) {
+	xmlNsPtr tmpns;
+
+	/*
+	* Store ns-decls in "oldNs" of the document-node.
+	*/
+	tmpns = xmlDOMWrapStoreNs(doc, ns->href, ns->prefix);
+	if (tmpns == NULL)
+	    return (-1);
+	/*
+	* Insert mapping.
+	*/
+	if (xmlDOMWrapNsMapAddItem(nsMap, -1, ns,
+		tmpns, XML_TREE_NSMAP_DOC) == NULL) {
+	    xmlFreeNs(tmpns);
+	    return (-1);
+	}
+	*retNs = tmpns;
+    } else {
+	xmlNsPtr tmpns;
+
+	tmpns = xmlDOMWrapNSNormDeclareNsForced(doc, elem, ns->href,
+	    ns->prefix, 0);
+	if (tmpns == NULL)
+	    return (-1);
+
+	if (*nsMap != NULL) {
+	    /*
+	    * Does it shadow ancestor ns-decls?
+	    */
+	    XML_NSMAP_FOREACH(*nsMap, mi) {
+		if ((mi->depth < depth) &&
+		    (mi->shadowDepth == -1) &&
+		    ((ns->prefix == mi->newNs->prefix) ||
+		    xmlStrEqual(ns->prefix, mi->newNs->prefix))) {
+		    /*
+		    * Shadows.
+		    */
+		    mi->shadowDepth = depth;
+		    break;
+		}
+	    }
+	}
+	if (xmlDOMWrapNsMapAddItem(nsMap, -1, ns, tmpns, depth) == NULL) {
+	    xmlFreeNs(tmpns);
+	    return (-1);
+	}
+	*retNs = tmpns;
+    }
+    return (0);
+}
+
+typedef enum {
+    XML_DOM_RECONNS_REMOVEREDUND = 1<<0
+} xmlDOMReconcileNSOptions;
+
+/*
+* xmlDOMWrapReconcileNamespaces:
+* @ctxt: DOM wrapper context, unused at the moment
+* @elem: the element-node
+* @options: option flags
+*
+* Ensures that ns-references point to ns-decls hold on element-nodes.
+* Ensures that the tree is namespace wellformed by creating additional
+* ns-decls where needed. Note that, since prefixes of already existent
+* ns-decls can be shadowed by this process, it could break QNames in
+* attribute values or element content.
+*
+* NOTE: This function was not intensively tested.
+*
+* Returns 0 if succeeded, -1 otherwise and on API/internal errors.
+*/
+
+int
+xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
+			      xmlNodePtr elem,
+			      int options)
+{
+    int depth = -1, adoptns = 0, parnsdone = 0;
+    xmlNsPtr ns, prevns;
+    xmlDocPtr doc;
+    xmlNodePtr cur, curElem = NULL;
+    xmlNsMapPtr nsMap = NULL;
+    xmlNsMapItemPtr /* topmi = NULL, */ mi;
+    /* @ancestorsOnly should be set by an option flag. */
+    int ancestorsOnly = 0;
+    int optRemoveRedundantNS =
+	((xmlDOMReconcileNSOptions) options & XML_DOM_RECONNS_REMOVEREDUND) ? 1 : 0;
+    xmlNsPtr *listRedund = NULL;
+    int sizeRedund = 0, nbRedund = 0, ret, i, j;
+
+    if ((elem == NULL) || (elem->doc == NULL) ||
+	(elem->type != XML_ELEMENT_NODE))
+	return (-1);
+
+    doc = elem->doc;
+    cur = elem;
+    do {
+	switch (cur->type) {
+	    case XML_ELEMENT_NODE:
+		adoptns = 1;
+		curElem = cur;
+		depth++;
+		/*
+		* Namespace declarations.
+		*/
+		if (cur->nsDef != NULL) {
+		    prevns = NULL;
+		    ns = cur->nsDef;
+		    while (ns != NULL) {
+			if (! parnsdone) {
+			    if ((elem->parent) &&
+				((xmlNodePtr) elem->parent->doc != elem->parent)) {
+				/*
+				* Gather ancestor in-scope ns-decls.
+				*/
+				if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
+				    elem->parent) == -1)
+				    goto internal_error;
+			    }
+			    parnsdone = 1;
+			}
+
+			/*
+			* Lookup the ns ancestor-axis for equal ns-decls in scope.
+			*/
+			if (optRemoveRedundantNS && XML_NSMAP_NOTEMPTY(nsMap)) {
+			    XML_NSMAP_FOREACH(nsMap, mi) {
+				if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+				    (mi->shadowDepth == -1) &&
+				    ((ns->prefix == mi->newNs->prefix) ||
+				      xmlStrEqual(ns->prefix, mi->newNs->prefix)) &&
+				    ((ns->href == mi->newNs->href) ||
+				      xmlStrEqual(ns->href, mi->newNs->href)))
+				{
+				    /*
+				    * A redundant ns-decl was found.
+				    * Add it to the list of redundant ns-decls.
+				    */
+				    if (xmlDOMWrapNSNormAddNsMapItem2(&listRedund,
+					&sizeRedund, &nbRedund, ns, mi->newNs) == -1)
+					goto internal_error;
+				    /*
+				    * Remove the ns-decl from the element-node.
+				    */
+				    if (prevns)
+					prevns->next = ns->next;
+				    else
+					cur->nsDef = ns->next;
+				    goto next_ns_decl;
+				}
+			    }
+			}
+
+			/*
+			* Skip ns-references handling if the referenced
+			* ns-decl is declared on the same element.
+			*/
+			if ((cur->ns != NULL) && adoptns && (cur->ns == ns))
+			    adoptns = 0;
+			/*
+			* Does it shadow any ns-decl?
+			*/
+			if (XML_NSMAP_NOTEMPTY(nsMap)) {
+			    XML_NSMAP_FOREACH(nsMap, mi) {
+				if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+				    (mi->shadowDepth == -1) &&
+				    ((ns->prefix == mi->newNs->prefix) ||
+				    xmlStrEqual(ns->prefix, mi->newNs->prefix))) {
+
+				    mi->shadowDepth = depth;
+				}
+			    }
+			}
+			/*
+			* Push mapping.
+			*/
+			if (xmlDOMWrapNsMapAddItem(&nsMap, -1, ns, ns,
+			    depth) == NULL)
+			    goto internal_error;
+
+			prevns = ns;
+next_ns_decl:
+			ns = ns->next;
+		    }
+		}
+		if (! adoptns)
+		    goto ns_end;
+		/* No break on purpose. */
+	    case XML_ATTRIBUTE_NODE:
+		/* No ns, no fun. */
+		if (cur->ns == NULL)
+		    goto ns_end;
+
+		if (! parnsdone) {
+		    if ((elem->parent) &&
+			((xmlNodePtr) elem->parent->doc != elem->parent)) {
+			if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
+				elem->parent) == -1)
+			    goto internal_error;
+		    }
+		    parnsdone = 1;
+		}
+		/*
+		* Adjust the reference if this was a redundant ns-decl.
+		*/
+		if (listRedund) {
+		   for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
+		       if (cur->ns == listRedund[j]) {
+			   cur->ns = listRedund[++j];
+			   break;
+		       }
+		   }
+		}
+		/*
+		* Adopt ns-references.
+		*/
+		if (XML_NSMAP_NOTEMPTY(nsMap)) {
+		    /*
+		    * Search for a mapping.
+		    */
+		    XML_NSMAP_FOREACH(nsMap, mi) {
+			if ((mi->shadowDepth == -1) &&
+			    (cur->ns == mi->oldNs)) {
+
+			    cur->ns = mi->newNs;
+			    goto ns_end;
+			}
+		    }
+		}
+		/*
+		* Aquire a normalized ns-decl and add it to the map.
+		*/
+		if (xmlDOMWrapNSNormAquireNormalizedNs(doc, curElem,
+			cur->ns, &ns,
+			&nsMap, depth,
+			ancestorsOnly,
+			(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1)
+		    goto internal_error;
+		cur->ns = ns;
+
+ns_end:
+		if ((cur->type == XML_ELEMENT_NODE) &&
+		    (cur->properties != NULL)) {
+		    /*
+		    * Process attributes.
+		    */
+		    cur = (xmlNodePtr) cur->properties;
+		    continue;
+		}
+		break;
+	    default:
+		goto next_sibling;
+	}
+into_content:
+	if ((cur->type == XML_ELEMENT_NODE) &&
+	    (cur->children != NULL)) {
+	    /*
+	    * Process content of element-nodes only.
+	    */
+	    cur = cur->children;
+	    continue;
+	}
+next_sibling:
+	if (cur == elem)
+	    break;
+	if (cur->type == XML_ELEMENT_NODE) {
+	    if (XML_NSMAP_NOTEMPTY(nsMap)) {
+		/*
+		* Pop mappings.
+		*/
+		while ((nsMap->last != NULL) &&
+		    (nsMap->last->depth >= depth))
+		{
+		    XML_NSMAP_POP(nsMap, mi)
+		}
+		/*
+		* Unshadow.
+		*/
+		XML_NSMAP_FOREACH(nsMap, mi) {
+		    if (mi->shadowDepth >= depth)
+			mi->shadowDepth = -1;
+		}
+	    }
+	    depth--;
+	}
+	if (cur->next != NULL)
+	    cur = cur->next;
+	else {
+	    if (cur->type == XML_ATTRIBUTE_NODE) {
+		cur = cur->parent;
+		goto into_content;
+	    }
+	    cur = cur->parent;
+	    goto next_sibling;
+	}
+    } while (cur != NULL);
+
+    ret = 0;
+    goto exit;
+internal_error:
+    ret = -1;
+exit:
+    if (listRedund) {
+	for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
+	    xmlFreeNs(listRedund[j]);
+	}
+	xmlFree(listRedund);
+    }
+    if (nsMap != NULL)
+	xmlDOMWrapNsMapFree(nsMap);
+    return (ret);
+}
+
+/*
+* xmlDOMWrapAdoptBranch:
+* @ctxt: the optional context for custom processing
+* @sourceDoc: the optional sourceDoc
+* @node: the element-node to start with
+* @destDoc: the destination doc for adoption
+* @destParent: the optional new parent of @node in @destDoc
+* @options: option flags
+*
+* Ensures that ns-references point to @destDoc: either to
+* elements->nsDef entries if @destParent is given, or to
+* @destDoc->oldNs otherwise.
+* If @destParent is given, it ensures that the tree is namespace
+* wellformed by creating additional ns-decls where needed.
+* Note that, since prefixes of already existent ns-decls can be
+* shadowed by this process, it could break QNames in attribute
+* values or element content.
+*
+* NOTE: This function was not intensively tested.
+*
+* Returns 0 if succeeded, -1 otherwise and on API/internal errors.
+*/
+static int
+xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
+		      xmlDocPtr sourceDoc,
+		      xmlNodePtr node,
+		      xmlDocPtr destDoc,
+		      xmlNodePtr destParent,
+		      int options ATTRIBUTE_UNUSED)
+{
+    int ret = 0;
+    xmlNodePtr cur, curElem = NULL;
+    xmlNsMapPtr nsMap = NULL;
+    xmlNsMapItemPtr mi;
+    xmlNsPtr ns = NULL;
+    int depth = -1, adoptStr = 1;
+    /* gather @parent's ns-decls. */
+    int parnsdone;
+    /* @ancestorsOnly should be set per option. */
+    int ancestorsOnly = 0;
+
+    /*
+    * Optimize string adoption for equal or none dicts.
+    */
+    if ((sourceDoc != NULL) &&
+	(sourceDoc->dict == destDoc->dict))
+	adoptStr = 0;
+    else
+	adoptStr = 1;
+
+    /*
+    * Get the ns-map from the context if available.
+    */
+    if (ctxt)
+	nsMap = (xmlNsMapPtr) ctxt->namespaceMap;
+    /*
+    * Disable search for ns-decls in the parent-axis of the
+    * desination element, if:
+    * 1) there's no destination parent
+    * 2) custom ns-reference handling is used
+    */
+    if ((destParent == NULL) ||
+	(ctxt && ctxt->getNsForNodeFunc))
+    {
+	parnsdone = 1;
+    } else
+	parnsdone = 0;
+
+    cur = node;
+    while (cur != NULL) {
+	/*
+	* Paranoid source-doc sanity check.
+	*/
+	if (cur->doc != sourceDoc) {
+	    /*
+	    * We'll assume XIncluded nodes if the doc differs.
+	    * TODO: Do we need to reconciliate XIncluded nodes?
+	    * This here skips XIncluded nodes and tries to handle
+	    * broken sequences.
+	    */
+	    if (cur->next == NULL)
+		goto leave_node;
+	    do {
+		cur = cur->next;
+		if ((cur->type == XML_XINCLUDE_END) ||
+		    (cur->doc == node->doc))
+		    break;
+	    } while (cur->next != NULL);
+
+	    if (cur->doc != node->doc)
+		goto leave_node;
+	}
+	cur->doc = destDoc;
+	switch (cur->type) {
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		/*
+		* TODO
+		*/
+		return (-1);
+	    case XML_ELEMENT_NODE:
+		curElem = cur;
+		depth++;
+		/*
+		* Namespace declarations.
+		* - ns->href and ns->prefix are never in the dict, so
+		*   we need not move the values over to the destination dict.
+		* - Note that for custom handling of ns-references,
+		*   the ns-decls need not be stored in the ns-map,
+		*   since they won't be referenced by node->ns.
+		*/
+		if ((cur->nsDef) &&
+		    ((ctxt == NULL) || (ctxt->getNsForNodeFunc == NULL)))
+		{
+		    if (! parnsdone) {
+			/*
+			* Gather @parent's in-scope ns-decls.
+			*/
+			if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
+			    destParent) == -1)
+			    goto internal_error;
+			parnsdone = 1;
+		    }
+		    for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
+			/*
+			* NOTE: ns->prefix and ns->href are never in the dict.
+			* XML_TREE_ADOPT_STR(ns->prefix)
+			* XML_TREE_ADOPT_STR(ns->href)
+			*/
+			/*
+			* Does it shadow any ns-decl?
+			*/
+			if (XML_NSMAP_NOTEMPTY(nsMap)) {
+			    XML_NSMAP_FOREACH(nsMap, mi) {
+				if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+				    (mi->shadowDepth == -1) &&
+				    ((ns->prefix == mi->newNs->prefix) ||
+				    xmlStrEqual(ns->prefix,
+				    mi->newNs->prefix))) {
+
+				    mi->shadowDepth = depth;
+				}
+			    }
+			}
+			/*
+			* Push mapping.
+			*/
+			if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
+			    ns, ns, depth) == NULL)
+			    goto internal_error;
+		    }
+		}
+		/* No break on purpose. */
+	    case XML_ATTRIBUTE_NODE:
+		/* No namespace, no fun. */
+		if (cur->ns == NULL)
+		    goto ns_end;
+
+		if (! parnsdone) {
+		    if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
+			destParent) == -1)
+			goto internal_error;
+		    parnsdone = 1;
+		}
+		/*
+		* Adopt ns-references.
+		*/
+		if (XML_NSMAP_NOTEMPTY(nsMap)) {
+		    /*
+		    * Search for a mapping.
+		    */
+		    XML_NSMAP_FOREACH(nsMap, mi) {
+			if ((mi->shadowDepth == -1) &&
+			    (cur->ns == mi->oldNs)) {
+
+			    cur->ns = mi->newNs;
+			    goto ns_end;
+			}
+		    }
+		}
+		/*
+		* No matching namespace in scope. We need a new one.
+		*/
+		if ((ctxt) && (ctxt->getNsForNodeFunc)) {
+		    /*
+		    * User-defined behaviour.
+		    */
+		    ns = ctxt->getNsForNodeFunc(ctxt, cur,
+			cur->ns->href, cur->ns->prefix);
+		    /*
+		    * Insert mapping if ns is available; it's the users fault
+		    * if not.
+		    */
+		    if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
+			    cur->ns, ns, XML_TREE_NSMAP_CUSTOM) == NULL)
+			goto internal_error;
+		    cur->ns = ns;
+		} else {
+		    /*
+		    * Aquire a normalized ns-decl and add it to the map.
+		    */
+		    if (xmlDOMWrapNSNormAquireNormalizedNs(destDoc,
+			/* ns-decls on curElem or on destDoc->oldNs */
+			destParent ? curElem : NULL,
+			cur->ns, &ns,
+			&nsMap, depth,
+			ancestorsOnly,
+			/* ns-decls must be prefixed for attributes. */
+			(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1)
+			goto internal_error;
+		    cur->ns = ns;
+		}
+ns_end:
+		/*
+		* Further node properties.
+		* TODO: Is this all?
+		*/
+		XML_TREE_ADOPT_STR(cur->name)
+		if (cur->type == XML_ELEMENT_NODE) {
+		    cur->psvi = NULL;
+		    cur->line = 0;
+		    cur->extra = 0;
+		    /*
+		    * Walk attributes.
+		    */
+		    if (cur->properties != NULL) {
+			/*
+			* Process first attribute node.
+			*/
+			cur = (xmlNodePtr) cur->properties;
+			continue;
+		    }
+		} else {
+		    /*
+		    * Attributes.
+		    */
+		    if ((sourceDoc != NULL) &&
+			(((xmlAttrPtr) cur)->atype == XML_ATTRIBUTE_ID))
+		    {
+			xmlRemoveID(sourceDoc, (xmlAttrPtr) cur);
+		    }
+		    ((xmlAttrPtr) cur)->atype = 0;
+		    ((xmlAttrPtr) cur)->psvi = NULL;
+		}
+		break;
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+		/*
+		* This puts the content in the dest dict, only if
+		* it was previously in the source dict.
+		*/
+		XML_TREE_ADOPT_STR_2(cur->content)
+		goto leave_node;
+	    case XML_ENTITY_REF_NODE:
+		/*
+		* Remove reference to the entitity-node.
+		*/
+		cur->content = NULL;
+		cur->children = NULL;
+		cur->last = NULL;
+		if ((destDoc->intSubset) || (destDoc->extSubset)) {
+		    xmlEntityPtr ent;
+		    /*
+		    * Assign new entity-node if available.
+		    */
+		    ent = xmlGetDocEntity(destDoc, cur->name);
+		    if (ent != NULL) {
+			cur->content = ent->content;
+			cur->children = (xmlNodePtr) ent;
+			cur->last = (xmlNodePtr) ent;
+		    }
+		}
+		goto leave_node;
+	    case XML_PI_NODE:
+		XML_TREE_ADOPT_STR(cur->name)
+		XML_TREE_ADOPT_STR_2(cur->content)
+		break;
+	    case XML_COMMENT_NODE:
+		break;
+	    default:
+		goto internal_error;
+	}
+	/*
+	* Walk the tree.
+	*/
+	if (cur->children != NULL) {
+	    cur = cur->children;
+	    continue;
+	}
+
+leave_node:
+	if (cur == node)
+	    break;
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_XINCLUDE_START) ||
+	    (cur->type == XML_XINCLUDE_END))
+	{
+	    /*
+	    * TODO: Do we expect nsDefs on XML_XINCLUDE_START?
+	    */
+	    if (XML_NSMAP_NOTEMPTY(nsMap)) {
+		/*
+		* Pop mappings.
+		*/
+		while ((nsMap->last != NULL) &&
+		    (nsMap->last->depth >= depth))
+		{
+		    XML_NSMAP_POP(nsMap, mi)
+		}
+		/*
+		* Unshadow.
+		*/
+		XML_NSMAP_FOREACH(nsMap, mi) {
+		    if (mi->shadowDepth >= depth)
+			mi->shadowDepth = -1;
+		}
+	    }
+	    depth--;
+	}
+	if (cur->next != NULL)
+	    cur = cur->next;
+	else if ((cur->type == XML_ATTRIBUTE_NODE) &&
+	    (cur->parent->children != NULL))
+	{
+	    cur = cur->parent->children;
+	} else {
+	    cur = cur->parent;
+	    goto leave_node;
+	}
+    }
+
+    goto exit;
+
+internal_error:
+    ret = -1;
+
+exit:
+    /*
+    * Cleanup.
+    */
+    if (nsMap != NULL) {
+	if ((ctxt) && (ctxt->namespaceMap == nsMap)) {
+	    /*
+	    * Just cleanup the map but don't free.
+	    */
+	    if (nsMap->first) {
+		if (nsMap->pool)
+		    nsMap->last->next = nsMap->pool;
+		nsMap->pool = nsMap->first;
+		nsMap->first = NULL;
+	    }
+	} else
+	    xmlDOMWrapNsMapFree(nsMap);
+    }
+    return(ret);
+}
+
+/*
+* xmlDOMWrapCloneNode:
+* @ctxt: the optional context for custom processing
+* @sourceDoc: the optional sourceDoc
+* @node: the node to start with
+* @resNode: the clone of the given @node
+* @destDoc: the destination doc
+* @destParent: the optional new parent of @node in @destDoc
+* @deep: descend into child if set
+* @options: option flags
+*
+* References of out-of scope ns-decls are remapped to point to @destDoc:
+* 1) If @destParent is given, then nsDef entries on element-nodes are used
+* 2) If *no* @destParent is given, then @destDoc->oldNs entries are used.
+*    This is the case when you don't know already where the cloned branch
+*    will be added to.
+*
+* If @destParent is given, it ensures that the tree is namespace
+* wellformed by creating additional ns-decls where needed.
+* Note that, since prefixes of already existent ns-decls can be
+* shadowed by this process, it could break QNames in attribute
+* values or element content.
+* TODO:
+*   1) What to do with XInclude? Currently this returns an error for XInclude.
+*
+* Returns 0 if the operation succeeded,
+*         1 if a node of unsupported (or not yet supported) type was given,
+*         -1 on API/internal errors.
+*/
+
+int
+xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
+		      xmlDocPtr sourceDoc,
+		      xmlNodePtr node,
+		      xmlNodePtr *resNode,
+		      xmlDocPtr destDoc,
+		      xmlNodePtr destParent,
+		      int deep,
+		      int options ATTRIBUTE_UNUSED)
+{
+    int ret = 0;
+    xmlNodePtr cur, curElem = NULL;
+    xmlNsMapPtr nsMap = NULL;
+    xmlNsMapItemPtr mi;
+    xmlNsPtr ns;
+    int depth = -1;
+    /* int adoptStr = 1; */
+    /* gather @parent's ns-decls. */
+    int parnsdone = 0;
+    /*
+    * @ancestorsOnly:
+    * TODO: @ancestorsOnly should be set per option.
+    *
+    */
+    int ancestorsOnly = 0;
+    xmlNodePtr resultClone = NULL, clone = NULL, parentClone = NULL, prevClone = NULL;
+    xmlNsPtr cloneNs = NULL, *cloneNsDefSlot = NULL;
+    xmlDictPtr dict; /* The destination dict */
+
+    if ((node == NULL) || (resNode == NULL) || (destDoc == NULL))
+	return(-1);
+    /*
+    * TODO: Initially we support only element-nodes.
+    */
+    if (node->type != XML_ELEMENT_NODE)
+	return(1);
+    /*
+    * Check node->doc sanity.
+    */
+    if ((node->doc != NULL) && (sourceDoc != NULL) &&
+	(node->doc != sourceDoc)) {
+	/*
+	* Might be an XIncluded node.
+	*/
+	return (-1);
+    }
+    if (sourceDoc == NULL)
+	sourceDoc = node->doc;
+    if (sourceDoc == NULL)
+        return (-1);
+
+    dict = destDoc->dict;
+    /*
+    * Reuse the namespace map of the context.
+    */
+    if (ctxt)
+	nsMap = (xmlNsMapPtr) ctxt->namespaceMap;
+
+    *resNode = NULL;
+
+    cur = node;
+    while (cur != NULL) {
+	if (cur->doc != sourceDoc) {
+	    /*
+	    * We'll assume XIncluded nodes if the doc differs.
+	    * TODO: Do we need to reconciliate XIncluded nodes?
+	    * TODO: This here returns -1 in this case.
+	    */
+	    goto internal_error;
+	}
+	/*
+	* Create a new node.
+	*/
+	switch (cur->type) {
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		/*
+		* TODO: What to do with XInclude?
+		*/
+		goto internal_error;
+		break;
+	    case XML_ELEMENT_NODE:
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+	    case XML_COMMENT_NODE:
+	    case XML_PI_NODE:
+	    case XML_DOCUMENT_FRAG_NODE:
+	    case XML_ENTITY_REF_NODE:
+	    case XML_ENTITY_NODE:
+		/*
+		* Nodes of xmlNode structure.
+		*/
+		clone = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+		if (clone == NULL) {
+		    xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating a node");
+		    goto internal_error;
+		}
+		memset(clone, 0, sizeof(xmlNode));
+		/*
+		* Set hierachical links.
+		*/
+		if (resultClone != NULL) {
+		    clone->parent = parentClone;
+		    if (prevClone) {
+			prevClone->next = clone;
+			clone->prev = prevClone;
+		    } else
+			parentClone->children = clone;
+		} else
+		    resultClone = clone;
+
+		break;
+	    case XML_ATTRIBUTE_NODE:
+		/*
+		* Attributes (xmlAttr).
+		*/
+		clone = (xmlNodePtr) xmlMalloc(sizeof(xmlAttr));
+		if (clone == NULL) {
+		    xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating an attr-node");
+		    goto internal_error;
+		}
+		memset(clone, 0, sizeof(xmlAttr));
+		/*
+		* Set hierachical links.
+		* TODO: Change this to add to the end of attributes.
+		*/
+		if (resultClone != NULL) {
+		    clone->parent = parentClone;
+		    if (prevClone) {
+			prevClone->next = clone;
+			clone->prev = prevClone;
+		    } else
+			parentClone->properties = (xmlAttrPtr) clone;
+		} else
+		    resultClone = clone;
+		break;
+	    default:
+		/*
+		* TODO QUESTION: Any other nodes expected?
+		*/
+		goto internal_error;
+	}
+
+	clone->type = cur->type;
+	clone->doc = destDoc;
+
+	/*
+	* Clone the name of the node if any.
+	*/
+	if (cur->name == xmlStringText)
+	    clone->name = xmlStringText;
+	else if (cur->name == xmlStringTextNoenc)
+	    /*
+	    * NOTE: Although xmlStringTextNoenc is never assigned to a node
+	    *   in tree.c, it might be set in Libxslt via
+	    *   "xsl:disable-output-escaping".
+	    */
+	    clone->name = xmlStringTextNoenc;
+	else if (cur->name == xmlStringComment)
+	    clone->name = xmlStringComment;
+	else if (cur->name != NULL) {
+	    DICT_CONST_COPY(cur->name, clone->name);
+	}
+
+	switch (cur->type) {
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		/*
+		* TODO
+		*/
+		return (-1);
+	    case XML_ELEMENT_NODE:
+		curElem = cur;
+		depth++;
+		/*
+		* Namespace declarations.
+		*/
+		if (cur->nsDef != NULL) {
+		    if (! parnsdone) {
+			if (destParent && (ctxt == NULL)) {
+			    /*
+			    * Gather @parent's in-scope ns-decls.
+			    */
+			    if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap,
+				destParent) == -1)
+				goto internal_error;
+			}
+			parnsdone = 1;
+		    }
+		    /*
+		    * Clone namespace declarations.
+		    */
+		    cloneNsDefSlot = &(clone->nsDef);
+		    for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
+			/*
+			* Create a new xmlNs.
+			*/
+			cloneNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+			if (cloneNs == NULL) {
+			    xmlTreeErrMemory("xmlDOMWrapCloneNode(): "
+				"allocating namespace");
+			    return(-1);
+			}
+			memset(cloneNs, 0, sizeof(xmlNs));
+			cloneNs->type = XML_LOCAL_NAMESPACE;
+
+			if (ns->href != NULL)
+			    cloneNs->href = xmlStrdup(ns->href);
+			if (ns->prefix != NULL)
+			    cloneNs->prefix = xmlStrdup(ns->prefix);
+
+			*cloneNsDefSlot = cloneNs;
+			cloneNsDefSlot = &(cloneNs->next);
+
+			/*
+			* Note that for custom handling of ns-references,
+			* the ns-decls need not be stored in the ns-map,
+			* since they won't be referenced by node->ns.
+			*/
+			if ((ctxt == NULL) ||
+			    (ctxt->getNsForNodeFunc == NULL))
+			{
+			    /*
+			    * Does it shadow any ns-decl?
+			    */
+			    if (XML_NSMAP_NOTEMPTY(nsMap)) {
+				XML_NSMAP_FOREACH(nsMap, mi) {
+				    if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+					(mi->shadowDepth == -1) &&
+					((ns->prefix == mi->newNs->prefix) ||
+					xmlStrEqual(ns->prefix,
+					mi->newNs->prefix))) {
+					/*
+					* Mark as shadowed at the current
+					* depth.
+					*/
+					mi->shadowDepth = depth;
+				    }
+				}
+			    }
+			    /*
+			    * Push mapping.
+			    */
+			    if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
+				ns, cloneNs, depth) == NULL)
+				goto internal_error;
+			}
+		    }
+		}
+		/* cur->ns will be processed further down. */
+		break;
+	    case XML_ATTRIBUTE_NODE:
+		/* IDs will be processed further down. */
+		/* cur->ns will be processed further down. */
+		break;
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+		/*
+		* Note that this will also cover the values of attributes.
+		*/
+		DICT_COPY(cur->content, clone->content);
+		goto leave_node;
+	    case XML_ENTITY_NODE:
+		/* TODO: What to do here? */
+		goto leave_node;
+	    case XML_ENTITY_REF_NODE:
+		if (sourceDoc != destDoc) {
+		    if ((destDoc->intSubset) || (destDoc->extSubset)) {
+			xmlEntityPtr ent;
+			/*
+			* Different doc: Assign new entity-node if available.
+			*/
+			ent = xmlGetDocEntity(destDoc, cur->name);
+			if (ent != NULL) {
+			    clone->content = ent->content;
+			    clone->children = (xmlNodePtr) ent;
+			    clone->last = (xmlNodePtr) ent;
+			}
+		    }
+		} else {
+		    /*
+		    * Same doc: Use the current node's entity declaration
+		    * and value.
+		    */
+		    clone->content = cur->content;
+		    clone->children = cur->children;
+		    clone->last = cur->last;
+		}
+		goto leave_node;
+	    case XML_PI_NODE:
+		DICT_COPY(cur->content, clone->content);
+		goto leave_node;
+	    case XML_COMMENT_NODE:
+		DICT_COPY(cur->content, clone->content);
+		goto leave_node;
+	    default:
+		goto internal_error;
+	}
+
+	if (cur->ns == NULL)
+	    goto end_ns_reference;
+
+/* handle_ns_reference: */
+	/*
+	** The following will take care of references to ns-decls ********
+	** and is intended only for element- and attribute-nodes.
+	**
+	*/
+	if (! parnsdone) {
+	    if (destParent && (ctxt == NULL)) {
+		if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap, destParent) == -1)
+		    goto internal_error;
+	    }
+	    parnsdone = 1;
+	}
+	/*
+	* Adopt ns-references.
+	*/
+	if (XML_NSMAP_NOTEMPTY(nsMap)) {
+	    /*
+	    * Search for a mapping.
+	    */
+	    XML_NSMAP_FOREACH(nsMap, mi) {
+		if ((mi->shadowDepth == -1) &&
+		    (cur->ns == mi->oldNs)) {
+		    /*
+		    * This is the nice case: a mapping was found.
+		    */
+		    clone->ns = mi->newNs;
+		    goto end_ns_reference;
+		}
+	    }
+	}
+	/*
+	* No matching namespace in scope. We need a new one.
+	*/
+	if ((ctxt != NULL) && (ctxt->getNsForNodeFunc != NULL)) {
+	    /*
+	    * User-defined behaviour.
+	    */
+	    ns = ctxt->getNsForNodeFunc(ctxt, cur,
+		cur->ns->href, cur->ns->prefix);
+	    /*
+	    * Add user's mapping.
+	    */
+	    if (xmlDOMWrapNsMapAddItem(&nsMap, -1,
+		cur->ns, ns, XML_TREE_NSMAP_CUSTOM) == NULL)
+		goto internal_error;
+	    clone->ns = ns;
+	} else {
+	    /*
+	    * Aquire a normalized ns-decl and add it to the map.
+	    */
+	    if (xmlDOMWrapNSNormAquireNormalizedNs(destDoc,
+		/* ns-decls on curElem or on destDoc->oldNs */
+		destParent ? curElem : NULL,
+		cur->ns, &ns,
+		&nsMap, depth,
+		/* if we need to search only in the ancestor-axis */
+		ancestorsOnly,
+		/* ns-decls must be prefixed for attributes. */
+		(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1)
+		goto internal_error;
+	    clone->ns = ns;
+	}
+
+end_ns_reference:
+
+	/*
+	* Some post-processing.
+	*
+	* Handle ID attributes.
+	*/
+	if ((clone->type == XML_ATTRIBUTE_NODE) &&
+	    (clone->parent != NULL))
+	{
+	    if (xmlIsID(destDoc, clone->parent, (xmlAttrPtr) clone)) {
+
+		xmlChar *idVal;
+
+		idVal = xmlNodeListGetString(cur->doc, cur->children, 1);
+		if (idVal != NULL) {
+		    if (xmlAddID(NULL, destDoc, idVal, (xmlAttrPtr) cur) == NULL) {
+			/* TODO: error message. */
+			xmlFree(idVal);
+			goto internal_error;
+		    }
+		    xmlFree(idVal);
+		}
+	    }
+	}
+	/*
+	**
+	** The following will traverse the tree **************************
+	**
+	*
+	* Walk the element's attributes before descending into child-nodes.
+	*/
+	if ((cur->type == XML_ELEMENT_NODE) && (cur->properties != NULL)) {
+	    prevClone = NULL;
+	    parentClone = clone;
+	    cur = (xmlNodePtr) cur->properties;
+	    continue;
+	}
+into_content:
+	/*
+	* Descend into child-nodes.
+	*/
+	if (cur->children != NULL) {
+	    if (deep || (cur->type == XML_ATTRIBUTE_NODE)) {
+		prevClone = NULL;
+		parentClone = clone;
+		cur = cur->children;
+		continue;
+	    }
+	}
+
+leave_node:
+	/*
+	* At this point we are done with the node, its content
+	* and an element-nodes's attribute-nodes.
+	*/
+	if (cur == node)
+	    break;
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_XINCLUDE_START) ||
+	    (cur->type == XML_XINCLUDE_END)) {
+	    /*
+	    * TODO: Do we expect nsDefs on XML_XINCLUDE_START?
+	    */
+	    if (XML_NSMAP_NOTEMPTY(nsMap)) {
+		/*
+		* Pop mappings.
+		*/
+		while ((nsMap->last != NULL) &&
+		    (nsMap->last->depth >= depth))
+		{
+		    XML_NSMAP_POP(nsMap, mi)
+		}
+		/*
+		* Unshadow.
+		*/
+		XML_NSMAP_FOREACH(nsMap, mi) {
+		    if (mi->shadowDepth >= depth)
+			mi->shadowDepth = -1;
+		}
+	    }
+	    depth--;
+	}
+	if (cur->next != NULL) {
+	    prevClone = clone;
+	    cur = cur->next;
+	} else if (cur->type != XML_ATTRIBUTE_NODE) {
+	    /*
+	    * Set clone->last.
+	    */
+	    if (clone->parent != NULL)
+		clone->parent->last = clone;
+	    clone = clone->parent;
+	    parentClone = clone->parent;
+	    /*
+	    * Process parent --> next;
+	    */
+	    cur = cur->parent;
+	    goto leave_node;
+	} else {
+	    /* This is for attributes only. */
+	    clone = clone->parent;
+	    parentClone = clone->parent;
+	    /*
+	    * Process parent-element --> children.
+	    */
+	    cur = cur->parent;
+	    goto into_content;
+	}
+    }
+    goto exit;
+
+internal_error:
+    ret = -1;
+
+exit:
+    /*
+    * Cleanup.
+    */
+    if (nsMap != NULL) {
+	if ((ctxt) && (ctxt->namespaceMap == nsMap)) {
+	    /*
+	    * Just cleanup the map but don't free.
+	    */
+	    if (nsMap->first) {
+		if (nsMap->pool)
+		    nsMap->last->next = nsMap->pool;
+		nsMap->pool = nsMap->first;
+		nsMap->first = NULL;
+	    }
+	} else
+	    xmlDOMWrapNsMapFree(nsMap);
+    }
+    /*
+    * TODO: Should we try a cleanup of the cloned node in case of a
+    * fatal error?
+    */
+    *resNode = resultClone;
+    return (ret);
+}
+
+/*
+* xmlDOMWrapAdoptAttr:
+* @ctxt: the optional context for custom processing
+* @sourceDoc: the optional source document of attr
+* @attr: the attribute-node to be adopted
+* @destDoc: the destination doc for adoption
+* @destParent: the optional new parent of @attr in @destDoc
+* @options: option flags
+*
+* @attr is adopted by @destDoc.
+* Ensures that ns-references point to @destDoc: either to
+* elements->nsDef entries if @destParent is given, or to
+* @destDoc->oldNs otherwise.
+*
+* Returns 0 if succeeded, -1 otherwise and on API/internal errors.
+*/
+static int
+xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
+		    xmlDocPtr sourceDoc,
+		    xmlAttrPtr attr,
+		    xmlDocPtr destDoc,
+		    xmlNodePtr destParent,
+		    int options ATTRIBUTE_UNUSED)
+{
+    xmlNodePtr cur;
+    int adoptStr = 1;
+
+    if ((attr == NULL) || (destDoc == NULL))
+	return (-1);
+
+    attr->doc = destDoc;
+    if (attr->ns != NULL) {
+	xmlNsPtr ns = NULL;
+
+	if (ctxt != NULL) {
+	    /* TODO: User defined. */
+	}
+	/* XML Namespace. */
+	if (IS_STR_XML(attr->ns->prefix)) {
+	    ns = xmlTreeEnsureXMLDecl(destDoc);
+	} else if (destParent == NULL) {
+	    /*
+	    * Store in @destDoc->oldNs.
+	    */
+	    ns = xmlDOMWrapStoreNs(destDoc, attr->ns->href, attr->ns->prefix);
+	} else {
+	    /*
+	    * Declare on @destParent.
+	    */
+	    if (xmlSearchNsByNamespaceStrict(destDoc, destParent, attr->ns->href,
+		&ns, 1) == -1)
+		goto internal_error;
+	    if (ns == NULL) {
+		ns = xmlDOMWrapNSNormDeclareNsForced(destDoc, destParent,
+		    attr->ns->href, attr->ns->prefix, 1);
+	    }
+	}
+	if (ns == NULL)
+	    goto internal_error;
+	attr->ns = ns;
+    }
+
+    XML_TREE_ADOPT_STR(attr->name);
+    attr->atype = 0;
+    attr->psvi = NULL;
+    /*
+    * Walk content.
+    */
+    if (attr->children == NULL)
+	return (0);
+    cur = attr->children;
+    while (cur != NULL) {
+	cur->doc = destDoc;
+	switch (cur->type) {
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+		XML_TREE_ADOPT_STR_2(cur->content)
+		break;
+	    case XML_ENTITY_REF_NODE:
+		/*
+		* Remove reference to the entitity-node.
+		*/
+		cur->content = NULL;
+		cur->children = NULL;
+		cur->last = NULL;
+		if ((destDoc->intSubset) || (destDoc->extSubset)) {
+		    xmlEntityPtr ent;
+		    /*
+		    * Assign new entity-node if available.
+		    */
+		    ent = xmlGetDocEntity(destDoc, cur->name);
+		    if (ent != NULL) {
+			cur->content = ent->content;
+			cur->children = (xmlNodePtr) ent;
+			cur->last = (xmlNodePtr) ent;
+		    }
+		}
+		break;
+	    default:
+		break;
+	}
+	if (cur->children != NULL) {
+	    cur = cur->children;
+	    continue;
+	}
+next_sibling:
+	if (cur == (xmlNodePtr) attr)
+	    break;
+	if (cur->next != NULL)
+	    cur = cur->next;
+	else {
+	    cur = cur->parent;
+	    goto next_sibling;
+	}
+    }
+    return (0);
+internal_error:
+    return (-1);
+}
+
+/*
+* xmlDOMWrapAdoptNode:
+* @ctxt: the optional context for custom processing
+* @sourceDoc: the optional sourceDoc
+* @node: the node to start with
+* @destDoc: the destination doc
+* @destParent: the optional new parent of @node in @destDoc
+* @options: option flags
+*
+* References of out-of scope ns-decls are remapped to point to @destDoc:
+* 1) If @destParent is given, then nsDef entries on element-nodes are used
+* 2) If *no* @destParent is given, then @destDoc->oldNs entries are used
+*    This is the case when you have an unliked node and just want to move it
+*    to the context of
+*
+* If @destParent is given, it ensures that the tree is namespace
+* wellformed by creating additional ns-decls where needed.
+* Note that, since prefixes of already existent ns-decls can be
+* shadowed by this process, it could break QNames in attribute
+* values or element content.
+* NOTE: This function was not intensively tested.
+*
+* Returns 0 if the operation succeeded,
+*         1 if a node of unsupported type was given,
+*         2 if a node of not yet supported type was given and
+*         -1 on API/internal errors.
+*/
+int
+xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
+		    xmlDocPtr sourceDoc,
+		    xmlNodePtr node,
+		    xmlDocPtr destDoc,
+		    xmlNodePtr destParent,
+		    int options)
+{
+    if ((node == NULL) || (destDoc == NULL) ||
+	((destParent != NULL) && (destParent->doc != destDoc)))
+	return(-1);
+    /*
+    * Check node->doc sanity.
+    */
+    if ((node->doc != NULL) && (sourceDoc != NULL) &&
+	(node->doc != sourceDoc)) {
+	/*
+	* Might be an XIncluded node.
+	*/
+	return (-1);
+    }
+    if (sourceDoc == NULL)
+	sourceDoc = node->doc;
+    if (sourceDoc == destDoc)
+	return (-1);
+    switch (node->type) {
+	case XML_ELEMENT_NODE:
+	case XML_ATTRIBUTE_NODE:
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_ENTITY_REF_NODE:
+	case XML_PI_NODE:
+	case XML_COMMENT_NODE:
+	    break;
+	case XML_DOCUMENT_FRAG_NODE:
+	    /* TODO: Support document-fragment-nodes. */
+	    return (2);
+	default:
+	    return (1);
+    }
+    /*
+    * Unlink only if @node was not already added to @destParent.
+    */
+    if ((node->parent != NULL) && (destParent != node->parent))
+	xmlUnlinkNode(node);
+
+    if (node->type == XML_ELEMENT_NODE) {
+	    return (xmlDOMWrapAdoptBranch(ctxt, sourceDoc, node,
+		    destDoc, destParent, options));
+    } else if (node->type == XML_ATTRIBUTE_NODE) {
+	    return (xmlDOMWrapAdoptAttr(ctxt, sourceDoc,
+		(xmlAttrPtr) node, destDoc, destParent, options));
+    } else {
+	xmlNodePtr cur = node;
+	int adoptStr = 1;
+
+	cur->doc = destDoc;
+	/*
+	* Optimize string adoption.
+	*/
+	if ((sourceDoc != NULL) &&
+	    (sourceDoc->dict == destDoc->dict))
+		adoptStr = 0;
+	switch (node->type) {
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+		XML_TREE_ADOPT_STR_2(node->content)
+		    break;
+	    case XML_ENTITY_REF_NODE:
+		/*
+		* Remove reference to the entitity-node.
+		*/
+		node->content = NULL;
+		node->children = NULL;
+		node->last = NULL;
+		if ((destDoc->intSubset) || (destDoc->extSubset)) {
+		    xmlEntityPtr ent;
+		    /*
+		    * Assign new entity-node if available.
+		    */
+		    ent = xmlGetDocEntity(destDoc, node->name);
+		    if (ent != NULL) {
+			node->content = ent->content;
+			node->children = (xmlNodePtr) ent;
+			node->last = (xmlNodePtr) ent;
+		    }
+		}
+		XML_TREE_ADOPT_STR(node->name)
+		break;
+	    case XML_PI_NODE: {
+		XML_TREE_ADOPT_STR(node->name)
+		XML_TREE_ADOPT_STR_2(node->content)
+		break;
+	    }
+	    default:
+		break;
+	}
+    }
+    return (0);
+}
+
+#define bottom_tree
+#include "elfgcchack.h"
diff --git a/src/trio.c b/src/trio.c
new file mode 100644
index 0000000..b116ccc
--- /dev/null
+++ b/src/trio.c
@@ -0,0 +1,6869 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ *************************************************************************
+ *
+ * A note to trio contributors:
+ *
+ * Avoid heap allocation at all costs to ensure that the trio functions
+ * are async-safe. The exceptions are the printf/fprintf functions, which
+ * uses fputc, and the asprintf functions and the <alloc> modifier, which
+ * by design are required to allocate form the heap.
+ *
+ ************************************************************************/
+
+/*
+ * TODO:
+ *  - Scan is probably too permissive about its modifiers.
+ *  - C escapes in %#[] ?
+ *  - Multibyte characters (done for format parsing, except scan groups)
+ *  - Complex numbers? (C99 _Complex)
+ *  - Boolean values? (C99 _Bool)
+ *  - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
+ *    to print the mantissa, e.g. NaN(0xc000000000000000)
+ *  - Should we support the GNU %a alloc modifier? GNU has an ugly hack
+ *    for %a, because C99 used %a for other purposes. If specified as
+ *    %as or %a[ it is interpreted as the alloc modifier, otherwise as
+ *    the C99 hex-float. This means that you cannot scan %as as a hex-float
+ *    immediately followed by an 's'.
+ *  - Scanning of collating symbols.
+ */
+
+/*************************************************************************
+ * Trio include files
+ */
+#include "triodef.h"
+#include "trio.h"
+#include "triop.h"
+#include "trionan.h"
+#if !defined(TRIO_MINIMAL)
+# include "triostr.h"
+#endif
+
+/**************************************************************************
+ *
+ * Definitions
+ *
+ *************************************************************************/
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+
+#if (defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) \
+     || defined(USE_MULTIBYTE) || TRIO_WIDECHAR) \
+    && !defined(_WIN32_WCE)
+# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
+# if !defined(MB_LEN_MAX)
+#  define MB_LEN_MAX 6
+# endif
+#endif
+
+#if (defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1100)) || defined(TRIO_COMPILER_BCB)
+# define TRIO_COMPILER_SUPPORTS_MSVC_INT
+#endif
+
+#if defined(_WIN32_WCE)
+#include <wincecompat.h>
+#endif
+
+/*************************************************************************
+ * Generic definitions
+ */
+
+#if !(defined(DEBUG) || defined(NDEBUG))
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#if !defined(TRIO_COMPILER_SUPPORTS_C99)
+# define isblank(x) (((x)==32) || ((x)==9))
+#endif
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
+#include <stddef.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+#define NIL ((char)0)
+#ifndef FALSE
+# define FALSE (1 == 0)
+# define TRUE (! FALSE)
+#endif
+#define BOOLEAN_T int
+
+/* mincore() can be used for debugging purposes */
+#define VALID(x) (NULL != (x))
+
+#if TRIO_ERRORS
+  /*
+   * Encode the error code and the position. This is decoded
+   * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
+   */
+# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
+#else
+# define TRIO_ERROR_RETURN(x,y) (-1)
+#endif
+
+typedef unsigned long trio_flags_t;
+
+
+/*************************************************************************
+ * Platform specific definitions
+ */
+#if defined(TRIO_PLATFORM_UNIX)
+# include <unistd.h>
+# include <signal.h>
+# include <locale.h>
+# define USE_LOCALE
+#endif /* TRIO_PLATFORM_UNIX */
+#if defined(TRIO_PLATFORM_VMS)
+# include <unistd.h>
+#endif
+#if defined(TRIO_PLATFORM_WIN32)
+# if defined(_WIN32_WCE)
+#  include <wincecompat.h>
+# else
+#  include <io.h>
+#  define read _read
+#  define write _write
+# endif
+#endif /* TRIO_PLATFORM_WIN32 */
+
+#if TRIO_WIDECHAR
+# if defined(TRIO_COMPILER_SUPPORTS_ISO94)
+#  include <wchar.h>
+#  include <wctype.h>
+typedef wchar_t trio_wchar_t;
+typedef wint_t trio_wint_t;
+# else
+typedef char trio_wchar_t;
+typedef int trio_wint_t;
+#  define WCONST(x) L ## x
+#  define WEOF EOF
+#  define iswalnum(x) isalnum(x)
+#  define iswalpha(x) isalpha(x)
+#  define iswblank(x) isblank(x)
+#  define iswcntrl(x) iscntrl(x)
+#  define iswdigit(x) isdigit(x)
+#  define iswgraph(x) isgraph(x)
+#  define iswlower(x) islower(x)
+#  define iswprint(x) isprint(x)
+#  define iswpunct(x) ispunct(x)
+#  define iswspace(x) isspace(x)
+#  define iswupper(x) isupper(x)
+#  define iswxdigit(x) isxdigit(x)
+# endif
+#endif
+
+
+/*************************************************************************
+ * Compiler dependent definitions
+ */
+
+/* Support for long long */
+#ifndef __cplusplus
+# if !defined(USE_LONGLONG)
+#  if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
+#   define USE_LONGLONG
+#  elif defined(TRIO_COMPILER_SUNPRO)
+#   define USE_LONGLONG
+#  elif defined(_LONG_LONG) || defined(_LONGLONG)
+#   define USE_LONGLONG
+#  endif
+# endif
+#endif
+
+/* The extra long numbers */
+#if defined(USE_LONGLONG)
+typedef signed long long int trio_longlong_t;
+typedef unsigned long long int trio_ulonglong_t;
+#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)
+typedef signed __int64 trio_longlong_t;
+typedef unsigned __int64 trio_ulonglong_t;
+#else
+typedef TRIO_SIGNED long int trio_longlong_t;
+typedef unsigned long int trio_ulonglong_t;
+#endif
+
+/* Maximal and fixed integer types */
+#if defined(TRIO_COMPILER_SUPPORTS_C99)
+# include <stdint.h>
+typedef intmax_t trio_intmax_t;
+typedef uintmax_t trio_uintmax_t;
+typedef int8_t trio_int8_t;
+typedef int16_t trio_int16_t;
+typedef int32_t trio_int32_t;
+typedef int64_t trio_int64_t;
+#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
+# include <inttypes.h>
+typedef intmax_t trio_intmax_t;
+typedef uintmax_t trio_uintmax_t;
+typedef int8_t trio_int8_t;
+typedef int16_t trio_int16_t;
+typedef int32_t trio_int32_t;
+typedef int64_t trio_int64_t;
+#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)
+typedef trio_longlong_t trio_intmax_t;
+typedef trio_ulonglong_t trio_uintmax_t;
+typedef __int8 trio_int8_t;
+typedef __int16 trio_int16_t;
+typedef __int32 trio_int32_t;
+typedef __int64 trio_int64_t;
+#else
+typedef trio_longlong_t trio_intmax_t;
+typedef trio_ulonglong_t trio_uintmax_t;
+# if defined(TRIO_INT8_T)
+typedef TRIO_INT8_T trio_int8_t;
+# else
+typedef TRIO_SIGNED char trio_int8_t;
+# endif
+# if defined(TRIO_INT16_T)
+typedef TRIO_INT16_T trio_int16_t;
+# else
+typedef TRIO_SIGNED short trio_int16_t;
+# endif
+# if defined(TRIO_INT32_T)
+typedef TRIO_INT32_T trio_int32_t;
+# else
+typedef TRIO_SIGNED int trio_int32_t;
+# endif
+# if defined(TRIO_INT64_T)
+typedef TRIO_INT64_T trio_int64_t;
+# else
+typedef trio_longlong_t trio_int64_t;
+# endif
+#endif
+
+#if (!(defined(TRIO_COMPILER_SUPPORTS_C99) \
+ || defined(TRIO_COMPILER_SUPPORTS_UNIX01))) \
+ && !defined(_WIN32_WCE)
+# define floorl(x) floor((double)(x))
+# define fmodl(x,y) fmod((double)(x),(double)(y))
+# define powl(x,y) pow((double)(x),(double)(y))
+#endif
+
+#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
+
+/*************************************************************************
+ * Internal Definitions
+ */
+
+#ifndef DECIMAL_DIG
+# define DECIMAL_DIG DBL_DIG
+#endif
+
+/* Long double sizes */
+#ifdef LDBL_DIG
+# define MAX_MANTISSA_DIGITS LDBL_DIG
+# define MAX_EXPONENT_DIGITS 4
+# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
+#else
+# define MAX_MANTISSA_DIGITS DECIMAL_DIG
+# define MAX_EXPONENT_DIGITS 3
+# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
+#endif
+
+#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
+# undef LDBL_DIG
+# undef LDBL_MANT_DIG
+# undef LDBL_EPSILON
+# define LDBL_DIG DBL_DIG
+# define LDBL_MANT_DIG DBL_MANT_DIG
+# define LDBL_EPSILON DBL_EPSILON
+#endif
+
+/* The maximal number of digits is for base 2 */
+#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
+/* The width of a pointer. The number of bits in a hex digit is 4 */
+#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
+
+/* Infinite and Not-A-Number for floating-point */
+#define INFINITE_LOWER "inf"
+#define INFINITE_UPPER "INF"
+#define LONG_INFINITE_LOWER "infinite"
+#define LONG_INFINITE_UPPER "INFINITE"
+#define NAN_LOWER "nan"
+#define NAN_UPPER "NAN"
+
+/* Various constants */
+enum {
+  TYPE_PRINT = 1,
+  TYPE_SCAN  = 2,
+
+  /* Flags. FLAGS_LAST must be less than ULONG_MAX */
+  FLAGS_NEW                 = 0,
+  FLAGS_STICKY              = 1,
+  FLAGS_SPACE               = 2 * FLAGS_STICKY,
+  FLAGS_SHOWSIGN            = 2 * FLAGS_SPACE,
+  FLAGS_LEFTADJUST          = 2 * FLAGS_SHOWSIGN,
+  FLAGS_ALTERNATIVE         = 2 * FLAGS_LEFTADJUST,
+  FLAGS_SHORT               = 2 * FLAGS_ALTERNATIVE,
+  FLAGS_SHORTSHORT          = 2 * FLAGS_SHORT,
+  FLAGS_LONG                = 2 * FLAGS_SHORTSHORT,
+  FLAGS_QUAD                = 2 * FLAGS_LONG,
+  FLAGS_LONGDOUBLE          = 2 * FLAGS_QUAD,
+  FLAGS_SIZE_T              = 2 * FLAGS_LONGDOUBLE,
+  FLAGS_PTRDIFF_T           = 2 * FLAGS_SIZE_T,
+  FLAGS_INTMAX_T            = 2 * FLAGS_PTRDIFF_T,
+  FLAGS_NILPADDING          = 2 * FLAGS_INTMAX_T,
+  FLAGS_UNSIGNED            = 2 * FLAGS_NILPADDING,
+  FLAGS_UPPER               = 2 * FLAGS_UNSIGNED,
+  FLAGS_WIDTH               = 2 * FLAGS_UPPER,
+  FLAGS_WIDTH_PARAMETER     = 2 * FLAGS_WIDTH,
+  FLAGS_PRECISION           = 2 * FLAGS_WIDTH_PARAMETER,
+  FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
+  FLAGS_BASE                = 2 * FLAGS_PRECISION_PARAMETER,
+  FLAGS_BASE_PARAMETER      = 2 * FLAGS_BASE,
+  FLAGS_FLOAT_E             = 2 * FLAGS_BASE_PARAMETER,
+  FLAGS_FLOAT_G             = 2 * FLAGS_FLOAT_E,
+  FLAGS_QUOTE               = 2 * FLAGS_FLOAT_G,
+  FLAGS_WIDECHAR            = 2 * FLAGS_QUOTE,
+  FLAGS_ALLOC               = 2 * FLAGS_WIDECHAR,
+  FLAGS_IGNORE              = 2 * FLAGS_ALLOC,
+  FLAGS_IGNORE_PARAMETER    = 2 * FLAGS_IGNORE,
+  FLAGS_VARSIZE_PARAMETER   = 2 * FLAGS_IGNORE_PARAMETER,
+  FLAGS_FIXED_SIZE          = 2 * FLAGS_VARSIZE_PARAMETER,
+  FLAGS_LAST                = FLAGS_FIXED_SIZE,
+  /* Reused flags */
+  FLAGS_EXCLUDE             = FLAGS_SHORT,
+  FLAGS_USER_DEFINED        = FLAGS_IGNORE,
+  FLAGS_ROUNDING            = FLAGS_INTMAX_T,
+  /* Compounded flags */
+  FLAGS_ALL_VARSIZES        = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
+  FLAGS_ALL_SIZES           = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
+
+  NO_POSITION  = -1,
+  NO_WIDTH     =  0,
+  NO_PRECISION = -1,
+  NO_SIZE      = -1,
+
+  /* Do not change these */
+  NO_BASE      = -1,
+  MIN_BASE     =  2,
+  MAX_BASE     = 36,
+  BASE_BINARY  =  2,
+  BASE_OCTAL   =  8,
+  BASE_DECIMAL = 10,
+  BASE_HEX     = 16,
+
+  /* Maximal number of allowed parameters */
+  MAX_PARAMETERS = 64,
+  /* Maximal number of characters in class */
+  MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
+
+  /* Maximal string lengths for user-defined specifiers */
+  MAX_USER_NAME = 64,
+  MAX_USER_DATA = 256,
+  
+  /* Maximal length of locale separator strings */
+  MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
+  /* Maximal number of integers in grouping */
+  MAX_LOCALE_GROUPS = 64,
+
+  /* Initial size of asprintf buffer */
+  DYNAMIC_START_SIZE = 32
+};
+
+#define NO_GROUPING ((int)CHAR_MAX)
+
+/* Fundamental formatting parameter types */
+#define FORMAT_UNKNOWN   0
+#define FORMAT_INT       1
+#define FORMAT_DOUBLE    2
+#define FORMAT_CHAR      3
+#define FORMAT_STRING    4
+#define FORMAT_POINTER   5
+#define FORMAT_COUNT     6
+#define FORMAT_PARAMETER 7
+#define FORMAT_GROUP     8
+#if TRIO_GNU
+# define FORMAT_ERRNO    9
+#endif
+#if TRIO_EXTENSION
+# define FORMAT_USER_DEFINED 10
+#endif
+
+/* Character constants */
+#define CHAR_IDENTIFIER '%'
+#define CHAR_BACKSLASH '\\'
+#define CHAR_QUOTE '\"'
+#define CHAR_ADJUST ' '
+
+/* Character class expressions */
+#define CLASS_ALNUM "[:alnum:]"
+#define CLASS_ALPHA "[:alpha:]"
+#define CLASS_BLANK "[:blank:]"
+#define CLASS_CNTRL "[:cntrl:]"
+#define CLASS_DIGIT "[:digit:]"
+#define CLASS_GRAPH "[:graph:]"
+#define CLASS_LOWER "[:lower:]"
+#define CLASS_PRINT "[:print:]"
+#define CLASS_PUNCT "[:punct:]"
+#define CLASS_SPACE "[:space:]"
+#define CLASS_UPPER "[:upper:]"
+#define CLASS_XDIGIT "[:xdigit:]"
+
+/*
+ * SPECIFIERS:
+ *
+ *
+ * a  Hex-float
+ * A  Hex-float
+ * c  Character
+ * C  Widechar character (wint_t)
+ * d  Decimal
+ * e  Float
+ * E  Float
+ * F  Float
+ * F  Float
+ * g  Float
+ * G  Float
+ * i  Integer
+ * m  Error message
+ * n  Count
+ * o  Octal
+ * p  Pointer
+ * s  String
+ * S  Widechar string (wchar_t *)
+ * u  Unsigned
+ * x  Hex
+ * X  Hex
+ * [] Group
+ * <> User-defined
+ *
+ * Reserved:
+ *
+ * D  Binary Coded Decimal %D(length,precision) (OS/390)
+ */
+#define SPECIFIER_CHAR 'c'
+#define SPECIFIER_STRING 's'
+#define SPECIFIER_DECIMAL 'd'
+#define SPECIFIER_INTEGER 'i'
+#define SPECIFIER_UNSIGNED 'u'
+#define SPECIFIER_OCTAL 'o'
+#define SPECIFIER_HEX 'x'
+#define SPECIFIER_HEX_UPPER 'X'
+#define SPECIFIER_FLOAT_E 'e'
+#define SPECIFIER_FLOAT_E_UPPER 'E'
+#define SPECIFIER_FLOAT_F 'f'
+#define SPECIFIER_FLOAT_F_UPPER 'F'
+#define SPECIFIER_FLOAT_G 'g'
+#define SPECIFIER_FLOAT_G_UPPER 'G'
+#define SPECIFIER_POINTER 'p'
+#define SPECIFIER_GROUP '['
+#define SPECIFIER_UNGROUP ']'
+#define SPECIFIER_COUNT 'n'
+#if TRIO_UNIX98
+# define SPECIFIER_CHAR_UPPER 'C'
+# define SPECIFIER_STRING_UPPER 'S'
+#endif
+#if TRIO_C99
+# define SPECIFIER_HEXFLOAT 'a'
+# define SPECIFIER_HEXFLOAT_UPPER 'A'
+#endif
+#if TRIO_GNU
+# define SPECIFIER_ERRNO 'm'
+#endif
+#if TRIO_EXTENSION
+# define SPECIFIER_BINARY 'b'
+# define SPECIFIER_BINARY_UPPER 'B'
+# define SPECIFIER_USER_DEFINED_BEGIN '<'
+# define SPECIFIER_USER_DEFINED_END '>'
+# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
+#endif
+
+/*
+ * QUALIFIERS:
+ *
+ *
+ * Numbers = d,i,o,u,x,X
+ * Float = a,A,e,E,f,F,g,G
+ * String = s
+ * Char = c
+ *
+ *
+ * 9$ Position
+ *      Use the 9th parameter. 9 can be any number between 1 and
+ *      the maximal argument
+ *
+ * 9 Width
+ *      Set width to 9. 9 can be any number, but must not be postfixed
+ *      by '$'
+ *
+ * h  Short
+ *    Numbers:
+ *      (unsigned) short int
+ *
+ * hh Short short
+ *    Numbers:
+ *      (unsigned) char
+ *
+ * l  Long
+ *    Numbers:
+ *      (unsigned) long int
+ *    String:
+ *      as the S specifier
+ *    Char:
+ *      as the C specifier
+ *
+ * ll Long Long
+ *    Numbers:
+ *      (unsigned) long long int
+ *
+ * L  Long Double
+ *    Float
+ *      long double
+ *
+ * #  Alternative
+ *    Float:
+ *      Decimal-point is always present
+ *    String:
+ *      non-printable characters are handled as \number
+ *
+ *    Spacing
+ *
+ * +  Sign
+ *
+ * -  Alignment
+ *
+ * .  Precision
+ *
+ * *  Parameter
+ *    print: use parameter
+ *    scan: no parameter (ignore)
+ *
+ * q  Quad
+ *
+ * Z  size_t
+ *
+ * w  Widechar
+ *
+ * '  Thousands/quote
+ *    Numbers:
+ *      Integer part grouped in thousands
+ *    Binary numbers:
+ *      Number grouped in nibbles (4 bits)
+ *    String:
+ *      Quoted string
+ *
+ * j  intmax_t
+ * t  prtdiff_t
+ * z  size_t
+ *
+ * !  Sticky
+ * @  Parameter (for both print and scan)
+ *
+ * I  n-bit Integer
+ *    Numbers:
+ *      The following options exists
+ *        I8  = 8-bit integer
+ *        I16 = 16-bit integer
+ *        I32 = 32-bit integer
+ *        I64 = 64-bit integer
+ */
+#define QUALIFIER_POSITION '$'
+#define QUALIFIER_SHORT 'h'
+#define QUALIFIER_LONG 'l'
+#define QUALIFIER_LONG_UPPER 'L'
+#define QUALIFIER_ALTERNATIVE '#'
+#define QUALIFIER_SPACE ' '
+#define QUALIFIER_PLUS '+'
+#define QUALIFIER_MINUS '-'
+#define QUALIFIER_DOT '.'
+#define QUALIFIER_STAR '*'
+#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
+#if TRIO_C99
+# define QUALIFIER_SIZE_T 'z'
+# define QUALIFIER_PTRDIFF_T 't'
+# define QUALIFIER_INTMAX_T 'j'
+#endif
+#if TRIO_BSD || TRIO_GNU
+# define QUALIFIER_QUAD 'q'
+#endif
+#if TRIO_GNU
+# define QUALIFIER_SIZE_T_UPPER 'Z'
+#endif
+#if TRIO_MISC
+# define QUALIFIER_WIDECHAR 'w'
+#endif
+#if TRIO_MICROSOFT
+# define QUALIFIER_FIXED_SIZE 'I'
+#endif
+#if TRIO_EXTENSION
+# define QUALIFIER_QUOTE '\''
+# define QUALIFIER_STICKY '!'
+# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
+# define QUALIFIER_PARAM '@' /* Experimental */
+# define QUALIFIER_COLON ':' /* For scanlists */
+# define QUALIFIER_EQUAL '=' /* For scanlists */
+# define QUALIFIER_ROUNDING_UPPER 'R'
+#endif
+
+
+/*************************************************************************
+ *
+ * Internal Structures
+ *
+ *************************************************************************/
+
+/* Parameters */
+typedef struct {
+  /* An indication of which entry in the data union is used */
+  int type;
+  /* The flags */
+  trio_flags_t flags;
+  /* The width qualifier */
+  int width;
+  /* The precision qualifier */
+  int precision;
+  /* The base qualifier */
+  int base;
+  /* The size for the variable size qualifier */
+  int varsize;
+  /* The marker of the end of the specifier */
+  int indexAfterSpecifier;
+  /* The data from the argument list */
+  union {
+    char *string;
+#if TRIO_WIDECHAR
+    trio_wchar_t *wstring;
+#endif
+    trio_pointer_t pointer;
+    union {
+      trio_intmax_t as_signed;
+      trio_uintmax_t as_unsigned;
+    } number;
+    double doubleNumber;
+    double *doublePointer;
+    trio_long_double_t longdoubleNumber;
+    trio_long_double_t *longdoublePointer;
+    int errorNumber;
+  } data;
+  /* For the user-defined specifier */
+  char user_name[MAX_USER_NAME];
+  char user_data[MAX_USER_DATA];
+} trio_parameter_t;
+
+/* Container for customized functions */
+typedef struct {
+  union {
+    trio_outstream_t out;
+    trio_instream_t in;
+  } stream;
+  trio_pointer_t closure;
+} trio_custom_t;
+
+/* General trio "class" */
+typedef struct _trio_class_t {
+  /*
+   * The function to write characters to a stream.
+   */
+  void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
+  /*
+   * The function to read characters from a stream.
+   */
+  void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
+  /*
+   * The current location in the stream.
+   */
+  trio_pointer_t location;
+  /*
+   * The character currently being processed.
+   */
+  int current;
+  /*
+   * The number of characters that would have been written/read
+   * if there had been sufficient space.
+   */
+  int processed;
+  /*
+   * The number of characters that are actually written/read.
+   * Processed and committed will only differ for the *nprintf
+   * and *nscanf functions.
+   */
+  int committed;
+  /*
+   * The upper limit of characters that may be written/read.
+   */
+  int max;
+  /*
+   * The last output error that was detected.
+   */
+  int error;
+} trio_class_t;
+
+/* References (for user-defined callbacks) */
+typedef struct _trio_reference_t {
+  trio_class_t *data;
+  trio_parameter_t *parameter;
+} trio_reference_t;
+
+/* Registered entries (for user-defined callbacks) */
+typedef struct _trio_userdef_t {
+  struct _trio_userdef_t *next;
+  trio_callback_t callback;
+  char *name;
+} trio_userdef_t;
+
+/*************************************************************************
+ *
+ * Internal Variables
+ *
+ *************************************************************************/
+
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
+
+/*
+ * Need this to workaround a parser bug in HP C/iX compiler that fails
+ * to resolves macro definitions that includes type 'long double',
+ * e.g: va_arg(arg_ptr, long double)
+ */
+#if defined(TRIO_PLATFORM_MPEIX)
+static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
+#endif
+
+static TRIO_CONST char internalNullString[] = "(nil)";
+
+#if defined(USE_LOCALE)
+static struct lconv *internalLocaleValues = NULL;
+#endif
+
+/*
+ * UNIX98 says "in a locale where the radix character is not defined,
+ * the radix character defaults to a period (.)"
+ */
+static int internalDecimalPointLength = 1;
+static int internalThousandSeparatorLength = 1;
+static char internalDecimalPoint = '.';
+static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
+static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
+static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
+
+static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static BOOLEAN_T internalDigitsUnconverted = TRUE;
+static int internalDigitArray[128];
+#if TRIO_EXTENSION
+static BOOLEAN_T internalCollationUnconverted = TRUE;
+static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
+#endif
+
+#if TRIO_EXTENSION
+static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
+static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
+static trio_userdef_t *internalUserDef = NULL;
+#endif
+
+
+/*************************************************************************
+ *
+ * Internal Functions
+ *
+ ************************************************************************/
+
+#if defined(TRIO_MINIMAL)
+# define TRIO_STRING_PUBLIC static
+# include "triostr.c"
+#endif /* defined(TRIO_MINIMAL) */
+
+/*************************************************************************
+ * TrioIsQualifier
+ *
+ * Description:
+ *  Remember to add all new qualifiers to this function.
+ *  QUALIFIER_POSITION must not be added.
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioIsQualifier
+TRIO_ARGS1((character),
+	   TRIO_CONST char character)
+{
+  /* QUALIFIER_POSITION is not included */
+  switch (character)
+    {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+    case QUALIFIER_PLUS:
+    case QUALIFIER_MINUS:
+    case QUALIFIER_SPACE:
+    case QUALIFIER_DOT:
+    case QUALIFIER_STAR:
+    case QUALIFIER_ALTERNATIVE:
+    case QUALIFIER_SHORT:
+    case QUALIFIER_LONG:
+    case QUALIFIER_LONG_UPPER:
+    case QUALIFIER_CIRCUMFLEX:
+#if defined(QUALIFIER_SIZE_T)
+    case QUALIFIER_SIZE_T:
+#endif
+#if defined(QUALIFIER_PTRDIFF_T)
+    case QUALIFIER_PTRDIFF_T:
+#endif
+#if defined(QUALIFIER_INTMAX_T)
+    case QUALIFIER_INTMAX_T:
+#endif
+#if defined(QUALIFIER_QUAD)
+    case QUALIFIER_QUAD:
+#endif
+#if defined(QUALIFIER_SIZE_T_UPPER)
+    case QUALIFIER_SIZE_T_UPPER:
+#endif
+#if defined(QUALIFIER_WIDECHAR)
+    case QUALIFIER_WIDECHAR:
+#endif
+#if defined(QUALIFIER_QUOTE)
+    case QUALIFIER_QUOTE:
+#endif
+#if defined(QUALIFIER_STICKY)
+    case QUALIFIER_STICKY:
+#endif
+#if defined(QUALIFIER_VARSIZE)
+    case QUALIFIER_VARSIZE:
+#endif
+#if defined(QUALIFIER_PARAM)
+    case QUALIFIER_PARAM:
+#endif
+#if defined(QUALIFIER_FIXED_SIZE)
+    case QUALIFIER_FIXED_SIZE:
+#endif
+#if defined(QUALIFIER_ROUNDING_UPPER)
+    case QUALIFIER_ROUNDING_UPPER:
+#endif
+      return TRUE;
+    default:
+      return FALSE;
+    }
+}
+
+/*************************************************************************
+ * TrioSetLocale
+ */
+#if defined(USE_LOCALE)
+TRIO_PRIVATE void
+TrioSetLocale(TRIO_NOARGS)
+{
+  internalLocaleValues = (struct lconv *)localeconv();
+  if (internalLocaleValues)
+    {
+      if ((internalLocaleValues->decimal_point) &&
+	  (internalLocaleValues->decimal_point[0] != NIL))
+	{
+	  internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
+	  if (internalDecimalPointLength == 1)
+	    {
+	      internalDecimalPoint = internalLocaleValues->decimal_point[0];
+	    }
+	  else
+	    {
+	      internalDecimalPoint = NIL;
+	      trio_copy_max(internalDecimalPointString,
+			    sizeof(internalDecimalPointString),
+			    internalLocaleValues->decimal_point);
+	    }
+	}
+      if ((internalLocaleValues->thousands_sep) &&
+	  (internalLocaleValues->thousands_sep[0] != NIL))
+	{
+	  trio_copy_max(internalThousandSeparator,
+			sizeof(internalThousandSeparator),
+			internalLocaleValues->thousands_sep);
+	  internalThousandSeparatorLength = trio_length(internalThousandSeparator);
+	}
+      if ((internalLocaleValues->grouping) &&
+	  (internalLocaleValues->grouping[0] != NIL))
+	{
+	  trio_copy_max(internalGrouping,
+			sizeof(internalGrouping),
+			internalLocaleValues->grouping);
+	}
+    }
+}
+#endif /* defined(USE_LOCALE) */
+
+TRIO_PRIVATE int
+TrioCalcThousandSeparatorLength
+TRIO_ARGS1((digits),
+	   int digits)
+{
+#if TRIO_EXTENSION
+  int count = 0;
+  int step = NO_GROUPING;
+  char *groupingPointer = internalGrouping;
+
+  while (digits > 0)
+    {
+      if (*groupingPointer == CHAR_MAX)
+	{
+	  /* Disable grouping */
+	  break; /* while */
+	}
+      else if (*groupingPointer == 0)
+	{
+	  /* Repeat last group */
+	  if (step == NO_GROUPING)
+	    {
+	      /* Error in locale */
+	      break; /* while */
+	    }
+	}
+      else
+	{
+	  step = *groupingPointer++;
+	}
+      if (digits > step)
+	count += internalThousandSeparatorLength;
+      digits -= step;
+    }
+  return count;
+#else
+  return 0;
+#endif
+}
+
+TRIO_PRIVATE BOOLEAN_T
+TrioFollowedBySeparator
+TRIO_ARGS1((position),
+	   int position)
+{
+#if TRIO_EXTENSION
+  int step = 0;
+  char *groupingPointer = internalGrouping;
+
+  position--;
+  if (position == 0)
+    return FALSE;
+  while (position > 0)
+    {
+      if (*groupingPointer == CHAR_MAX)
+	{
+	  /* Disable grouping */
+	  break; /* while */
+	}
+      else if (*groupingPointer != 0)
+	{
+	  step = *groupingPointer++;
+	}
+      if (step == 0)
+	break;
+      position -= step;
+    }
+  return (position == 0);
+#else
+  return FALSE;
+#endif
+}
+
+/*************************************************************************
+ * TrioGetPosition
+ *
+ * Get the %n$ position.
+ */
+TRIO_PRIVATE int
+TrioGetPosition
+TRIO_ARGS2((format, indexPointer),
+	   TRIO_CONST char *format,
+	   int *indexPointer)
+{
+#if TRIO_UNIX98
+  char *tmpformat;
+  int number = 0;
+  int index = *indexPointer;
+
+  number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL);
+  index = (int)(tmpformat - format);
+  if ((number != 0) && (QUALIFIER_POSITION == format[index++]))
+    {
+      *indexPointer = index;
+      /*
+       * number is decreased by 1, because n$ starts from 1, whereas
+       * the array it is indexing starts from 0.
+       */
+      return number - 1;
+    }
+#endif
+  return NO_POSITION;
+}
+
+#if TRIO_EXTENSION
+/*************************************************************************
+ * TrioFindNamespace
+ *
+ * Find registered user-defined specifier.
+ * The prev argument is used for optimization only.
+ */
+TRIO_PRIVATE trio_userdef_t *
+TrioFindNamespace
+TRIO_ARGS2((name, prev),
+	   TRIO_CONST char *name,
+	   trio_userdef_t **prev)
+{
+  trio_userdef_t *def;
+  
+  if (internalEnterCriticalRegion)
+    (void)internalEnterCriticalRegion(NULL);
+  
+  for (def = internalUserDef; def; def = def->next)
+    {
+      /* Case-sensitive string comparison */
+      if (trio_equal_case(def->name, name))
+	break;
+      
+      if (prev)
+	*prev = def;
+    }
+  
+  if (internalLeaveCriticalRegion)
+    (void)internalLeaveCriticalRegion(NULL);
+  
+  return def;
+}
+#endif
+
+/*************************************************************************
+ * TrioPower
+ *
+ * Description:
+ *  Calculate pow(base, exponent), where number and exponent are integers.
+ */
+TRIO_PRIVATE trio_long_double_t
+TrioPower
+TRIO_ARGS2((number, exponent),
+	   int number,
+	   int exponent)
+{
+  trio_long_double_t result;
+
+  if (number == 10)
+    {
+      switch (exponent)
+	{
+	  /* Speed up calculation of common cases */
+	case 0:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
+	  break;
+	case 1:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
+	  break;
+	case 2:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
+	  break;
+	case 3:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
+	  break;
+	case 4:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
+	  break;
+	case 5:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
+	  break;
+	case 6:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
+	  break;
+	case 7:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
+	  break;
+	case 8:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
+	  break;
+	case 9:
+	  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
+	  break;
+	default:
+	  result = powl((trio_long_double_t)number,
+			(trio_long_double_t)exponent);
+	  break;
+	}
+    }
+  else
+    {
+      return powl((trio_long_double_t)number, (trio_long_double_t)exponent);
+    }
+  return result;
+}
+
+/*************************************************************************
+ * TrioLogarithm
+ */
+TRIO_PRIVATE double
+TrioLogarithm
+TRIO_ARGS2((number, base),
+	   double number,
+	   int base)
+{
+  double result;
+
+  if (number <= 0.0)
+    {
+      /* xlC crashes on log(0) */
+      result = (number == 0.0) ? trio_ninf() : trio_nan();
+    }
+  else
+    {
+      if (base == 10)
+	{
+	  result = log10(number);
+	}
+      else
+	{
+	  result = log10(number) / log10((double)base);
+	}
+    }
+  return result;
+}
+
+/*************************************************************************
+ * TrioLogarithmBase
+ */
+TRIO_PRIVATE double
+TrioLogarithmBase
+TRIO_ARGS1((base),
+	   int base)
+{
+  switch (base)
+    {
+    case BASE_BINARY : return 1.0;
+    case BASE_OCTAL  : return 3.0;
+    case BASE_DECIMAL: return 3.321928094887362345;
+    case BASE_HEX    : return 4.0;
+    default          : return TrioLogarithm((double)base, 2);
+    }
+}
+
+/*************************************************************************
+ * TrioParse
+ *
+ * Description:
+ *  Parse the format string
+ */
+TRIO_PRIVATE int
+TrioParse
+TRIO_ARGS5((type, format, parameters, arglist, argarray),
+	   int type,
+	   TRIO_CONST char *format,
+	   trio_parameter_t *parameters,
+	   va_list *arglist,
+	   trio_pointer_t *argarray)
+{
+  /* Count the number of times a parameter is referenced */
+  unsigned short usedEntries[MAX_PARAMETERS];
+  /* Parameter counters */
+  int parameterPosition;
+  int currentParam;
+  int maxParam = -1;
+  /* Utility variables */
+  trio_flags_t flags;
+  int width;
+  int precision;
+  int varsize;
+  int base;
+  int index;  /* Index into formatting string */
+  int dots;  /* Count number of dots in modifier part */
+  BOOLEAN_T positional;  /* Does the specifier have a positional? */
+  BOOLEAN_T gotSticky = FALSE;  /* Are there any sticky modifiers at all? */
+  /*
+   * indices specifies the order in which the parameters must be
+   * read from the va_args (this is necessary to handle positionals)
+   */
+  int indices[MAX_PARAMETERS];
+  int pos = 0;
+  /* Various variables */
+  char ch;
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  int charlen;
+#endif
+  int save_errno;
+  int i = -1;
+  int num;
+  char *tmpformat;
+
+  /* One and only one of arglist and argarray must be used */
+  assert((arglist != NULL) ^ (argarray != NULL));
+  
+  /*
+   * The 'parameters' array is not initialized, but we need to
+   * know which entries we have used.
+   */
+  memset(usedEntries, 0, sizeof(usedEntries));
+
+  save_errno = errno;
+  index = 0;
+  parameterPosition = 0;
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  (void)mblen(NULL, 0);
+#endif
+  
+  while (format[index])
+    {
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+      if (! isascii(format[index]))
+	{
+	  /*
+	   * Multibyte characters cannot be legal specifiers or
+	   * modifiers, so we skip over them.
+	   */
+	  charlen = mblen(&format[index], MB_LEN_MAX);
+	  index += (charlen > 0) ? charlen : 1;
+	  continue; /* while */
+	}
+#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
+      if (CHAR_IDENTIFIER == format[index++])
+	{
+	  if (CHAR_IDENTIFIER == format[index])
+	    {
+	      index++;
+	      continue; /* while */
+	    }
+
+	  flags = FLAGS_NEW;
+	  dots = 0;
+	  currentParam = TrioGetPosition(format, &index);
+	  positional = (NO_POSITION != currentParam);
+	  if (!positional)
+	    {
+	      /* We have no positional, get the next counter */
+	      currentParam = parameterPosition;
+	    }
+          if(currentParam >= MAX_PARAMETERS)
+	    {
+	      /* Bail out completely to make the error more obvious */
+	      return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index);
+	    }
+
+	  if (currentParam > maxParam)
+	    maxParam = currentParam;
+
+	  /* Default values */
+	  width = NO_WIDTH;
+	  precision = NO_PRECISION;
+	  base = NO_BASE;
+	  varsize = NO_SIZE;
+
+	  while (TrioIsQualifier(format[index]))
+	    {
+	      ch = format[index++];
+
+	      switch (ch)
+		{
+		case QUALIFIER_SPACE:
+		  flags |= FLAGS_SPACE;
+		  break;
+
+		case QUALIFIER_PLUS:
+		  flags |= FLAGS_SHOWSIGN;
+		  break;
+
+		case QUALIFIER_MINUS:
+		  flags |= FLAGS_LEFTADJUST;
+		  flags &= ~FLAGS_NILPADDING;
+		  break;
+
+		case QUALIFIER_ALTERNATIVE:
+		  flags |= FLAGS_ALTERNATIVE;
+		  break;
+
+		case QUALIFIER_DOT:
+		  if (dots == 0) /* Precision */
+		    {
+		      dots++;
+
+		      /* Skip if no precision */
+		      if (QUALIFIER_DOT == format[index])
+			break;
+		      
+		      /* After the first dot we have the precision */
+		      flags |= FLAGS_PRECISION;
+		      if ((QUALIFIER_STAR == format[index])
+#if defined(QUALIFIER_PARAM)
+			  || (QUALIFIER_PARAM == format[index])
+#endif
+			  )
+			{
+			  index++;
+			  flags |= FLAGS_PRECISION_PARAMETER;
+
+			  precision = TrioGetPosition(format, &index);
+			  if (precision == NO_POSITION)
+			    {
+			      parameterPosition++;
+			      if (positional)
+				precision = parameterPosition;
+			      else
+				{
+				  precision = currentParam;
+				  currentParam = precision + 1;
+				}
+			    }
+			  else
+			    {
+			      if (! positional)
+				currentParam = precision + 1;
+			      if (width > maxParam)
+				maxParam = precision;
+			    }
+			  if (currentParam > maxParam)
+			    maxParam = currentParam;
+			}
+		      else
+			{
+			  precision = trio_to_long(&format[index],
+						   &tmpformat,
+						   BASE_DECIMAL);
+			  index = (int)(tmpformat - format);
+			}
+		    }
+		  else if (dots == 1) /* Base */
+		    {
+		      dots++;
+		      
+		      /* After the second dot we have the base */
+		      flags |= FLAGS_BASE;
+		      if ((QUALIFIER_STAR == format[index])
+#if defined(QUALIFIER_PARAM)
+			  || (QUALIFIER_PARAM == format[index])
+#endif
+			  )
+			{
+			  index++;
+			  flags |= FLAGS_BASE_PARAMETER;
+			  base = TrioGetPosition(format, &index);
+			  if (base == NO_POSITION)
+			    {
+			      parameterPosition++;
+			      if (positional)
+				base = parameterPosition;
+			      else
+				{
+				  base = currentParam;
+				  currentParam = base + 1;
+				}
+			    }
+			  else
+			    {
+			      if (! positional)
+				currentParam = base + 1;
+			      if (base > maxParam)
+				maxParam = base;
+			    }
+			  if (currentParam > maxParam)
+			    maxParam = currentParam;
+			}
+		      else
+			{
+			  base = trio_to_long(&format[index],
+					      &tmpformat,
+					      BASE_DECIMAL);
+			  if (base > MAX_BASE)
+			    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+			  index = (int)(tmpformat - format);
+			}
+		    }
+		  else
+		    {
+		      return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		    }
+		  break; /* QUALIFIER_DOT */
+
+#if defined(QUALIFIER_PARAM)
+		case QUALIFIER_PARAM:
+		  type = TYPE_PRINT;
+		  /* FALLTHROUGH */
+#endif
+		case QUALIFIER_STAR:
+		  /* This has different meanings for print and scan */
+		  if (TYPE_PRINT == type)
+		    {
+		      /* Read with from parameter */
+		      flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
+		      width = TrioGetPosition(format, &index);
+		      if (width == NO_POSITION)
+			{
+			  parameterPosition++;
+			  if (positional)
+			    width = parameterPosition;
+			  else
+			    {
+			      width = currentParam;
+			      currentParam = width + 1;
+			    }
+			}
+		      else
+			{
+			  if (! positional)
+			    currentParam = width + 1;
+			  if (width > maxParam)
+			    maxParam = width;
+			}
+		      if (currentParam > maxParam)
+			maxParam = currentParam;
+		    }
+		  else
+		    {
+		      /* Scan, but do not store result */
+		      flags |= FLAGS_IGNORE;
+		    }
+
+		  break; /* QUALIFIER_STAR */
+
+		case '0':
+		  if (! (flags & FLAGS_LEFTADJUST))
+		    flags |= FLAGS_NILPADDING;
+		  /* FALLTHROUGH */
+		case '1': case '2': case '3': case '4':
+		case '5': case '6': case '7': case '8': case '9':
+		  flags |= FLAGS_WIDTH;
+		  /* &format[index - 1] is used to "rewind" the read
+		   * character from format
+		   */
+		  width = trio_to_long(&format[index - 1],
+				       &tmpformat,
+				       BASE_DECIMAL);
+		  index = (int)(tmpformat - format);
+		  break;
+
+		case QUALIFIER_SHORT:
+		  if (flags & FLAGS_SHORTSHORT)
+		    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		  else if (flags & FLAGS_SHORT)
+		    flags |= FLAGS_SHORTSHORT;
+		  else
+		    flags |= FLAGS_SHORT;
+		  break;
+
+		case QUALIFIER_LONG:
+		  if (flags & FLAGS_QUAD)
+		    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		  else if (flags & FLAGS_LONG)
+		    flags |= FLAGS_QUAD;
+		  else
+		    flags |= FLAGS_LONG;
+		  break;
+
+		case QUALIFIER_LONG_UPPER:
+		  flags |= FLAGS_LONGDOUBLE;
+		  break;
+
+#if defined(QUALIFIER_SIZE_T)
+		case QUALIFIER_SIZE_T:
+		  flags |= FLAGS_SIZE_T;
+		  /* Modify flags for later truncation of number */
+		  if (sizeof(size_t) == sizeof(trio_ulonglong_t))
+		    flags |= FLAGS_QUAD;
+		  else if (sizeof(size_t) == sizeof(long))
+		    flags |= FLAGS_LONG;
+		  break;
+#endif
+
+#if defined(QUALIFIER_PTRDIFF_T)
+		case QUALIFIER_PTRDIFF_T:
+		  flags |= FLAGS_PTRDIFF_T;
+		  if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
+		    flags |= FLAGS_QUAD;
+		  else if (sizeof(ptrdiff_t) == sizeof(long))
+		    flags |= FLAGS_LONG;
+		  break;
+#endif
+
+#if defined(QUALIFIER_INTMAX_T)
+		case QUALIFIER_INTMAX_T:
+		  flags |= FLAGS_INTMAX_T;
+		  if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
+		    flags |= FLAGS_QUAD;
+		  else if (sizeof(trio_intmax_t) == sizeof(long))
+		    flags |= FLAGS_LONG;
+		  break;
+#endif
+
+#if defined(QUALIFIER_QUAD)
+		case QUALIFIER_QUAD:
+		  flags |= FLAGS_QUAD;
+		  break;
+#endif
+
+#if defined(QUALIFIER_FIXED_SIZE)
+		case QUALIFIER_FIXED_SIZE:
+		  if (flags & FLAGS_FIXED_SIZE)
+		    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+
+		  if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE |
+			       FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER))
+		    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+
+		  if ((format[index] == '6') &&
+		      (format[index + 1] == '4'))
+		    {
+		      varsize = sizeof(trio_int64_t);
+		      index += 2;
+		    }
+		  else if ((format[index] == '3') &&
+			   (format[index + 1] == '2'))
+		    {
+		      varsize = sizeof(trio_int32_t);
+		      index += 2;
+		    }
+		  else if ((format[index] == '1') &&
+			   (format[index + 1] == '6'))
+		    {
+		      varsize = sizeof(trio_int16_t);
+		      index += 2;
+		    }
+		  else if (format[index] == '8')
+		    {
+		      varsize = sizeof(trio_int8_t);
+		      index++;
+		    }
+		  else
+		    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		  
+		  flags |= FLAGS_FIXED_SIZE;
+		  break;
+#endif
+
+#if defined(QUALIFIER_WIDECHAR)
+		case QUALIFIER_WIDECHAR:
+		  flags |= FLAGS_WIDECHAR;
+		  break;
+#endif
+
+#if defined(QUALIFIER_SIZE_T_UPPER)
+		case QUALIFIER_SIZE_T_UPPER:
+		  break;
+#endif
+
+#if defined(QUALIFIER_QUOTE)
+		case QUALIFIER_QUOTE:
+		  flags |= FLAGS_QUOTE;
+		  break;
+#endif
+
+#if defined(QUALIFIER_STICKY)
+		case QUALIFIER_STICKY:
+		  flags |= FLAGS_STICKY;
+		  gotSticky = TRUE;
+		  break;
+#endif
+		  
+#if defined(QUALIFIER_VARSIZE)
+		case QUALIFIER_VARSIZE:
+		  flags |= FLAGS_VARSIZE_PARAMETER;
+		  parameterPosition++;
+		  if (positional)
+		    varsize = parameterPosition;
+		  else
+		    {
+		      varsize = currentParam;
+		      currentParam = varsize + 1;
+		    }
+		  if (currentParam > maxParam)
+		    maxParam = currentParam;
+		  break;
+#endif
+
+#if defined(QUALIFIER_ROUNDING_UPPER)
+		case QUALIFIER_ROUNDING_UPPER:
+		  flags |= FLAGS_ROUNDING;
+		  break;
+#endif
+
+		default:
+		  /* Bail out completely to make the error more obvious */
+                  return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		}
+	    } /* while qualifier */
+
+	  /*
+	   * Parameters only need the type and value. The value is
+	   * read later.
+	   */
+	  if (flags & FLAGS_WIDTH_PARAMETER)
+	    {
+	      usedEntries[width] += 1;
+	      parameters[pos].type = FORMAT_PARAMETER;
+	      parameters[pos].flags = 0;
+	      indices[width] = pos;
+	      width = pos++;
+	    }
+	  if (flags & FLAGS_PRECISION_PARAMETER)
+	    {
+	      usedEntries[precision] += 1;
+	      parameters[pos].type = FORMAT_PARAMETER;
+	      parameters[pos].flags = 0;
+	      indices[precision] = pos;
+	      precision = pos++;
+	    }
+	  if (flags & FLAGS_BASE_PARAMETER)
+	    {
+	      usedEntries[base] += 1;
+	      parameters[pos].type = FORMAT_PARAMETER;
+	      parameters[pos].flags = 0;
+	      indices[base] = pos;
+	      base = pos++;
+	    }
+	  if (flags & FLAGS_VARSIZE_PARAMETER)
+	    {
+	      usedEntries[varsize] += 1;
+	      parameters[pos].type = FORMAT_PARAMETER;
+	      parameters[pos].flags = 0;
+	      indices[varsize] = pos;
+	      varsize = pos++;
+	    }
+	  
+	  indices[currentParam] = pos;
+	  
+	  switch (format[index++])
+	    {
+#if defined(SPECIFIER_CHAR_UPPER)
+	    case SPECIFIER_CHAR_UPPER:
+	      flags |= FLAGS_WIDECHAR;
+	      /* FALLTHROUGH */
+#endif
+	    case SPECIFIER_CHAR:
+	      if (flags & FLAGS_LONG)
+		flags |= FLAGS_WIDECHAR;
+	      else if (flags & FLAGS_SHORT)
+		flags &= ~FLAGS_WIDECHAR;
+	      parameters[pos].type = FORMAT_CHAR;
+	      break;
+
+#if defined(SPECIFIER_STRING_UPPER)
+	    case SPECIFIER_STRING_UPPER:
+	      flags |= FLAGS_WIDECHAR;
+	      /* FALLTHROUGH */
+#endif
+	    case SPECIFIER_STRING:
+	      if (flags & FLAGS_LONG)
+		flags |= FLAGS_WIDECHAR;
+	      else if (flags & FLAGS_SHORT)
+		flags &= ~FLAGS_WIDECHAR;
+	      parameters[pos].type = FORMAT_STRING;
+	      break;
+
+	    case SPECIFIER_GROUP:
+	      if (TYPE_SCAN == type)
+		{
+		  int depth = 1;
+		  parameters[pos].type = FORMAT_GROUP;
+		  if (format[index] == QUALIFIER_CIRCUMFLEX)
+		    index++;
+		  if (format[index] == SPECIFIER_UNGROUP)
+		    index++;
+		  if (format[index] == QUALIFIER_MINUS)
+		    index++;
+		  /* Skip nested brackets */
+		  while (format[index] != NIL)
+		    {
+		      if (format[index] == SPECIFIER_GROUP)
+			{
+			  depth++;
+			}
+		      else if (format[index] == SPECIFIER_UNGROUP)
+			{
+			  if (--depth <= 0)
+			    {
+			      index++;
+			      break;
+			    }
+			}
+		      index++;
+		    }
+		}
+	      break;
+	      
+	    case SPECIFIER_INTEGER:
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+	      
+	    case SPECIFIER_UNSIGNED:
+	      flags |= FLAGS_UNSIGNED;
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+
+	    case SPECIFIER_DECIMAL:
+	      /* Disable base modifier */
+	      flags &= ~FLAGS_BASE_PARAMETER;
+	      base = BASE_DECIMAL;
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+
+	    case SPECIFIER_OCTAL:
+	      flags |= FLAGS_UNSIGNED;
+	      flags &= ~FLAGS_BASE_PARAMETER;
+	      base = BASE_OCTAL;
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+
+#if defined(SPECIFIER_BINARY)
+	    case SPECIFIER_BINARY_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+	    case SPECIFIER_BINARY:
+	      flags |= FLAGS_NILPADDING;
+	      flags &= ~FLAGS_BASE_PARAMETER;
+	      base = BASE_BINARY;
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+#endif
+
+	    case SPECIFIER_HEX_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+	    case SPECIFIER_HEX:
+	      flags |= FLAGS_UNSIGNED;
+	      flags &= ~FLAGS_BASE_PARAMETER;
+	      base = BASE_HEX;
+	      parameters[pos].type = FORMAT_INT;
+	      break;
+
+	    case SPECIFIER_FLOAT_E_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+	    case SPECIFIER_FLOAT_E:
+	      flags |= FLAGS_FLOAT_E;
+	      parameters[pos].type = FORMAT_DOUBLE;
+	      break;
+
+	    case SPECIFIER_FLOAT_G_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+	    case SPECIFIER_FLOAT_G:
+	      flags |= FLAGS_FLOAT_G;
+	      parameters[pos].type = FORMAT_DOUBLE;
+	      break;
+
+	    case SPECIFIER_FLOAT_F_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+	    case SPECIFIER_FLOAT_F:
+	      parameters[pos].type = FORMAT_DOUBLE;
+	      break;
+
+	    case SPECIFIER_POINTER:
+	      if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
+		flags |= FLAGS_QUAD;
+	      else if (sizeof(trio_pointer_t) == sizeof(long))
+		flags |= FLAGS_LONG;
+	      parameters[pos].type = FORMAT_POINTER;
+	      break;
+
+	    case SPECIFIER_COUNT:
+	      parameters[pos].type = FORMAT_COUNT;
+	      break;
+
+#if defined(SPECIFIER_HEXFLOAT)
+# if defined(SPECIFIER_HEXFLOAT_UPPER)
+	    case SPECIFIER_HEXFLOAT_UPPER:
+	      flags |= FLAGS_UPPER;
+	      /* FALLTHROUGH */
+# endif
+	    case SPECIFIER_HEXFLOAT:
+	      base = BASE_HEX;
+	      parameters[pos].type = FORMAT_DOUBLE;
+	      break;
+#endif
+
+#if defined(FORMAT_ERRNO)
+	    case SPECIFIER_ERRNO:
+	      parameters[pos].type = FORMAT_ERRNO;
+	      break;
+#endif
+
+#if defined(SPECIFIER_USER_DEFINED_BEGIN)
+	    case SPECIFIER_USER_DEFINED_BEGIN:
+	      {
+		unsigned int max;
+		int without_namespace = TRUE;
+		
+		parameters[pos].type = FORMAT_USER_DEFINED;
+		parameters[pos].user_name[0] = NIL;
+		tmpformat = (char *)&format[index];
+	      
+		while ((ch = format[index]))
+		  {
+		    index++;
+		    if (ch == SPECIFIER_USER_DEFINED_END)
+		      {
+			if (without_namespace)
+			  {
+			    /* We must get the handle first */
+			    parameters[pos].type = FORMAT_PARAMETER;
+			    parameters[pos].indexAfterSpecifier = index;
+			    parameters[pos].flags = FLAGS_USER_DEFINED;
+			    /* Adjust parameters for insertion of new one */
+			    pos++;
+			    usedEntries[currentParam] += 1;
+			    parameters[pos].type = FORMAT_USER_DEFINED;
+			    currentParam++;
+			    indices[currentParam] = pos;
+			    if (currentParam > maxParam)
+			      maxParam = currentParam;
+			  }
+			/* Copy the user data */
+			max = (unsigned int)(&format[index] - tmpformat);
+			if (max > MAX_USER_DATA)
+			  max = MAX_USER_DATA;
+			trio_copy_max(parameters[pos].user_data,
+				      max,
+				      tmpformat);
+			break; /* while */
+		      }
+		    if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
+		      {
+			without_namespace = FALSE;
+			/* Copy the namespace for later looking-up */
+			max = (int)(&format[index] - tmpformat);
+			if (max > MAX_USER_NAME)
+			  max = MAX_USER_NAME;
+			trio_copy_max(parameters[pos].user_name,
+				      max,
+				      tmpformat);
+			tmpformat = (char *)&format[index];
+		      }
+		  }
+		if (ch != SPECIFIER_USER_DEFINED_END)
+		  return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+	      }
+	      break;
+#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */
+	      
+	    default:
+	      /* Bail out completely to make the error more obvious */
+              return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+	    }
+
+	  /*  Count the number of times this entry has been used */
+	  usedEntries[currentParam] += 1;
+	  
+	  /* Find last sticky parameters */
+	  if (gotSticky && !(flags & FLAGS_STICKY))
+	    {
+	      for (i = pos - 1; i >= 0; i--)
+		{
+		  if (parameters[i].type == FORMAT_PARAMETER)
+		    continue;
+		  if ((parameters[i].flags & FLAGS_STICKY) &&
+		      (parameters[i].type == parameters[pos].type))
+		    {
+		      /* Do not overwrite current qualifiers */
+		      flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
+		      if (width == NO_WIDTH)
+			width = parameters[i].width;
+		      if (precision == NO_PRECISION)
+			precision = parameters[i].precision;
+		      if (base == NO_BASE)
+			base = parameters[i].base;
+		      break;
+		    }
+		}
+	    }
+	  
+	  parameters[pos].indexAfterSpecifier = index;
+	  parameters[pos].flags = flags;
+	  parameters[pos].width = width;
+	  parameters[pos].precision = precision;
+	  parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base;
+	  parameters[pos].varsize = varsize;
+	  pos++;
+	  
+	  if (! positional)
+	    parameterPosition++;
+	  
+	} /* if identifier */
+      
+    } /* while format characters left */
+
+  for (num = 0; num <= maxParam; num++)
+    {
+      if (usedEntries[num] != 1)
+	{
+	  if (usedEntries[num] == 0) /* gap detected */
+	    return TRIO_ERROR_RETURN(TRIO_EGAP, num);
+	  else /* double references detected */
+	    return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
+	}
+      
+      i = indices[num];
+
+      /*
+       * FORMAT_PARAMETERS are only present if they must be read,
+       * so it makes no sense to check the ignore flag (besides,
+       * the flags variable is not set for that particular type)
+       */
+      if ((parameters[i].type != FORMAT_PARAMETER) &&
+	  (parameters[i].flags & FLAGS_IGNORE))
+	continue; /* for all arguments */
+
+      /*
+       * The stack arguments are read according to ANSI C89
+       * default argument promotions:
+       *
+       *  char           = int
+       *  short          = int
+       *  unsigned char  = unsigned int
+       *  unsigned short = unsigned int
+       *  float          = double
+       *
+       * In addition to the ANSI C89 these types are read (the
+       * default argument promotions of C99 has not been
+       * considered yet)
+       *
+       *  long long
+       *  long double
+       *  size_t
+       *  ptrdiff_t
+       *  intmax_t
+       */
+      switch (parameters[i].type)
+	{
+	case FORMAT_GROUP:
+	case FORMAT_STRING:
+#if TRIO_WIDECHAR
+	  if (flags & FLAGS_WIDECHAR)
+	    {
+	      parameters[i].data.wstring = (argarray == NULL)
+		? va_arg(*arglist, trio_wchar_t *)
+		: (trio_wchar_t *)(argarray[num]);
+	    }
+	  else
+#endif
+	    {
+	      parameters[i].data.string = (argarray == NULL)
+		? va_arg(*arglist, char *)
+		: (char *)(argarray[num]);
+	    }
+	  break;
+
+#if defined(FORMAT_USER_DEFINED)
+	case FORMAT_USER_DEFINED:
+#endif
+	case FORMAT_POINTER:
+	case FORMAT_COUNT:
+	case FORMAT_UNKNOWN:
+	  parameters[i].data.pointer = (argarray == NULL)
+	    ? va_arg(*arglist, trio_pointer_t )
+	    : argarray[num];
+	  break;
+
+	case FORMAT_CHAR:
+	case FORMAT_INT:
+	  if (TYPE_SCAN == type)
+	    {
+              if (argarray == NULL)
+                parameters[i].data.pointer = 
+                  (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
+              else
+                {
+                  if (parameters[i].type == FORMAT_CHAR)
+                    parameters[i].data.pointer =
+                      (trio_pointer_t)((char *)argarray[num]);
+                  else if (parameters[i].flags & FLAGS_SHORT)
+                    parameters[i].data.pointer =
+                      (trio_pointer_t)((short *)argarray[num]);
+                  else
+                    parameters[i].data.pointer =
+                      (trio_pointer_t)((int *)argarray[num]);
+                }
+	    }
+	  else
+	    {
+#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE)
+	      if (parameters[i].flags
+		  & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
+		{
+		  if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
+		    {
+		      /*
+		       * Variable sizes are mapped onto the fixed sizes, in
+		       * accordance with integer promotion.
+		       *
+		       * Please note that this may not be portable, as we
+		       * only guess the size, not the layout of the numbers.
+		       * For example, if int is little-endian, and long is
+		       * big-endian, then this will fail.
+		       */
+		      varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
+		    }
+		  else
+		    {
+		      /* Used for the I<bits> modifiers */
+		      varsize = parameters[i].varsize;
+		    }
+		  parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
+		  
+		  if (varsize <= (int)sizeof(int))
+		    ;
+		  else if (varsize <= (int)sizeof(long))
+		    parameters[i].flags |= FLAGS_LONG;
+#if defined(QUALIFIER_INTMAX_T)
+		  else if (varsize <= (int)sizeof(trio_longlong_t))
+		    parameters[i].flags |= FLAGS_QUAD;
+		  else
+		    parameters[i].flags |= FLAGS_INTMAX_T;
+#else
+		  else
+		    parameters[i].flags |= FLAGS_QUAD;
+#endif
+		}
+#endif /* defined(QUALIFIER_VARSIZE) */
+#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
+	      if (parameters[i].flags & FLAGS_SIZE_T)
+		parameters[i].data.number.as_unsigned = (argarray == NULL)
+		  ? (trio_uintmax_t)va_arg(*arglist, size_t)
+		  : (trio_uintmax_t)(*((size_t *)argarray[num]));
+	      else
+#endif
+#if defined(QUALIFIER_PTRDIFF_T)
+	      if (parameters[i].flags & FLAGS_PTRDIFF_T)
+		parameters[i].data.number.as_unsigned = (argarray == NULL)
+		  ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
+		  : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
+	      else
+#endif
+#if defined(QUALIFIER_INTMAX_T)
+	      if (parameters[i].flags & FLAGS_INTMAX_T)
+		parameters[i].data.number.as_unsigned = (argarray == NULL)
+		  ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
+		  : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
+	      else
+#endif
+	      if (parameters[i].flags & FLAGS_QUAD)
+		parameters[i].data.number.as_unsigned = (argarray == NULL)
+		  ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
+		  : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
+	      else if (parameters[i].flags & FLAGS_LONG)
+		parameters[i].data.number.as_unsigned = (argarray == NULL)
+		  ? (trio_uintmax_t)va_arg(*arglist, long)
+		  : (trio_uintmax_t)(*((long *)argarray[num]));
+	      else
+		{
+		  if (argarray == NULL)
+		    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
+		  else
+		    {
+		      if (parameters[i].type == FORMAT_CHAR)
+			parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
+		      else if (parameters[i].flags & FLAGS_SHORT)
+			parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
+		      else
+			parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
+		    }
+		}
+	    }
+	  break;
+
+	case FORMAT_PARAMETER:
+	  /*
+	   * The parameter for the user-defined specifier is a pointer,
+	   * whereas the rest (width, precision, base) uses an integer.
+	   */
+	  if (parameters[i].flags & FLAGS_USER_DEFINED)
+	    parameters[i].data.pointer = (argarray == NULL)
+	      ? va_arg(*arglist, trio_pointer_t )
+	      : argarray[num];
+	  else
+	    parameters[i].data.number.as_unsigned = (argarray == NULL)
+	      ? (trio_uintmax_t)va_arg(*arglist, int)
+	      : (trio_uintmax_t)(*((int *)argarray[num]));
+	  break;
+
+	case FORMAT_DOUBLE:
+	  if (TYPE_SCAN == type)
+	    {
+	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
+		parameters[i].data.longdoublePointer = (argarray == NULL)
+		  ? va_arg(*arglist, trio_long_double_t *)
+		  : (trio_long_double_t *)argarray[num];
+	      else
+                {
+		  if (parameters[i].flags & FLAGS_LONG)
+		    parameters[i].data.doublePointer = (argarray == NULL)
+		      ? va_arg(*arglist, double *)
+		      : (double *)argarray[num];
+		  else
+		    parameters[i].data.doublePointer = (argarray == NULL)
+		      ? (double *)va_arg(*arglist, float *)
+		      : (double *)((float *)argarray[num]);
+                }
+	    }
+	  else
+	    {
+	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
+		parameters[i].data.longdoubleNumber = (argarray == NULL)
+		  ? va_arg(*arglist, trio_long_double_t)
+		  : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
+	      else
+		{
+		  if (argarray == NULL)
+		    parameters[i].data.longdoubleNumber =
+		      (trio_long_double_t)va_arg(*arglist, double);
+		  else
+		    {
+		      if (parameters[i].flags & FLAGS_SHORT)
+			parameters[i].data.longdoubleNumber =
+			  (trio_long_double_t)(*((float *)argarray[num]));
+		      else
+			parameters[i].data.longdoubleNumber =
+			  (trio_long_double_t)(*((double *)argarray[num]));
+		    }
+		}
+	    }
+	  break;
+
+#if defined(FORMAT_ERRNO)
+	case FORMAT_ERRNO:
+	  parameters[i].data.errorNumber = save_errno;
+	  break;
+#endif
+
+	default:
+	  break;
+	}
+    } /* for all specifiers */
+  return num;
+}
+
+
+/*************************************************************************
+ *
+ * FORMATTING
+ *
+ ************************************************************************/
+
+
+/*************************************************************************
+ * TrioWriteNumber
+ *
+ * Description:
+ *  Output a number.
+ *  The complexity of this function is a result of the complexity
+ *  of the dependencies of the flags.
+ */
+TRIO_PRIVATE void
+TrioWriteNumber
+TRIO_ARGS6((self, number, flags, width, precision, base),
+	   trio_class_t *self,
+	   trio_uintmax_t number,
+	   trio_flags_t flags,
+	   int width,
+	   int precision,
+	   int base)
+{
+  BOOLEAN_T isNegative;
+  BOOLEAN_T isNumberZero;
+  BOOLEAN_T isPrecisionZero;
+  BOOLEAN_T ignoreNumber;
+  char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
+  char *bufferend;
+  char *pointer;
+  TRIO_CONST char *digits;
+  int i;
+  int length;
+  char *p;
+  int count;
+
+  assert(VALID(self));
+  assert(VALID(self->OutStream));
+  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
+
+  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
+  if (base == NO_BASE)
+    base = BASE_DECIMAL;
+
+  isNumberZero = (number == 0);
+  isPrecisionZero = (precision == 0);
+  ignoreNumber = (isNumberZero
+		  && isPrecisionZero
+		  && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));
+
+  if (flags & FLAGS_UNSIGNED)
+    {
+      isNegative = FALSE;
+      flags &= ~FLAGS_SHOWSIGN;
+    }
+  else
+    {
+      isNegative = ((trio_intmax_t)number < 0);
+      if (isNegative)
+	number = -((trio_intmax_t)number);
+    }
+
+  if (flags & FLAGS_QUAD)
+    number &= (trio_ulonglong_t)-1;
+  else if (flags & FLAGS_LONG)
+    number &= (unsigned long)-1;
+  else
+    number &= (unsigned int)-1;
+  
+  /* Build number */
+  pointer = bufferend = &buffer[sizeof(buffer) - 1];
+  *pointer-- = NIL;
+  for (i = 1; i < (int)sizeof(buffer); i++)
+    {
+      *pointer-- = digits[number % base];
+      number /= base;
+      if (number == 0)
+	break;
+
+      if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
+	{
+	  /*
+	   * We are building the number from the least significant
+	   * to the most significant digit, so we have to copy the
+	   * thousand separator backwards
+	   */
+	  length = internalThousandSeparatorLength;
+	  if (((int)(pointer - buffer) - length) > 0)
+	    {
+	      p = &internalThousandSeparator[length - 1];
+	      while (length-- > 0)
+		*pointer-- = *p--;
+	    }
+	}
+    }
+
+  if (! ignoreNumber)
+    {
+      /* Adjust width */
+      width -= (bufferend - pointer) - 1;
+    }
+
+  /* Adjust precision */
+  if (NO_PRECISION != precision)
+    {
+      precision -= (bufferend - pointer) - 1;
+      if (precision < 0)
+	precision = 0;
+      flags |= FLAGS_NILPADDING;
+    }
+
+  /* Calculate padding */
+  count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
+    ? precision
+    : 0;
+  
+  /* Adjust width further */
+  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
+    width--;
+  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
+    {
+      switch (base)
+	{
+	case BASE_BINARY:
+	case BASE_HEX:
+	  width -= 2;
+	  break;
+	case BASE_OCTAL:
+	  if (!(flags & FLAGS_NILPADDING) || (count == 0))
+	    width--;
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  /* Output prefixes spaces if needed */
+  if (! ((flags & FLAGS_LEFTADJUST) ||
+	 ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
+    {
+      while (width-- > count)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+
+  /* width has been adjusted for signs and alternatives */
+  if (isNegative)
+    self->OutStream(self, '-');
+  else if (flags & FLAGS_SHOWSIGN)
+    self->OutStream(self, '+');
+  else if (flags & FLAGS_SPACE)
+    self->OutStream(self, ' ');
+
+  /* Prefix is not written when the value is zero */
+  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
+    {
+      switch (base)
+	{
+	case BASE_BINARY:
+	  self->OutStream(self, '0');
+	  self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
+	  break;
+
+	case BASE_OCTAL:
+	  if (!(flags & FLAGS_NILPADDING) || (count == 0))
+	    self->OutStream(self, '0');
+	  break;
+
+	case BASE_HEX:
+	  self->OutStream(self, '0');
+	  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
+	  break;
+
+	default:
+	  break;
+	} /* switch base */
+    }
+
+  /* Output prefixed zero padding if needed */
+  if (flags & FLAGS_NILPADDING)
+    {
+      if (precision == NO_PRECISION)
+	precision = width;
+      while (precision-- > 0)
+	{
+	  self->OutStream(self, '0');
+	  width--;
+	}
+    }
+
+  if (! ignoreNumber)
+    {
+      /* Output the number itself */
+      while (*(++pointer))
+	{
+	  self->OutStream(self, *pointer);
+	}
+    }
+
+  /* Output trailing spaces if needed */
+  if (flags & FLAGS_LEFTADJUST)
+    {
+      while (width-- > 0)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+}
+
+/*************************************************************************
+ * TrioWriteStringCharacter
+ *
+ * Description:
+ *  Output a single character of a string
+ */
+TRIO_PRIVATE void
+TrioWriteStringCharacter
+TRIO_ARGS3((self, ch, flags),
+	   trio_class_t *self,
+	   int ch,
+	   trio_flags_t flags)
+{
+  if (flags & FLAGS_ALTERNATIVE)
+    {
+      if (! isprint(ch))
+	{
+	  /*
+	   * Non-printable characters are converted to C escapes or
+	   * \number, if no C escape exists.
+	   */
+	  self->OutStream(self, CHAR_BACKSLASH);
+	  switch (ch)
+	    {
+	    case '\007': self->OutStream(self, 'a'); break;
+	    case '\b': self->OutStream(self, 'b'); break;
+	    case '\f': self->OutStream(self, 'f'); break;
+	    case '\n': self->OutStream(self, 'n'); break;
+	    case '\r': self->OutStream(self, 'r'); break;
+	    case '\t': self->OutStream(self, 't'); break;
+	    case '\v': self->OutStream(self, 'v'); break;
+	    case '\\': self->OutStream(self, '\\'); break;
+	    default:
+	      self->OutStream(self, 'x');
+	      TrioWriteNumber(self, (trio_uintmax_t)ch,
+			      FLAGS_UNSIGNED | FLAGS_NILPADDING,
+			      2, 2, BASE_HEX);
+	      break;
+	    }
+	}
+      else if (ch == CHAR_BACKSLASH)
+	{
+	  self->OutStream(self, CHAR_BACKSLASH);
+	  self->OutStream(self, CHAR_BACKSLASH);
+	}
+      else
+	{
+	  self->OutStream(self, ch);
+	}
+    }
+  else
+    {
+      self->OutStream(self, ch);
+    }
+}
+
+/*************************************************************************
+ * TrioWriteString
+ *
+ * Description:
+ *  Output a string
+ */
+TRIO_PRIVATE void
+TrioWriteString
+TRIO_ARGS5((self, string, flags, width, precision),
+	   trio_class_t *self,
+	   TRIO_CONST char *string,
+	   trio_flags_t flags,
+	   int width,
+	   int precision)
+{
+  int length;
+  int ch;
+
+  assert(VALID(self));
+  assert(VALID(self->OutStream));
+
+  if (string == NULL)
+    {
+      string = internalNullString;
+      length = sizeof(internalNullString) - 1;
+      /* Disable quoting for the null pointer */
+      flags &= (~FLAGS_QUOTE);
+      width = 0;
+    }
+  else
+    {
+      length = trio_length(string);
+    }
+  if ((NO_PRECISION != precision) &&
+      (precision < length))
+    {
+      length = precision;
+    }
+  width -= length;
+
+  if (flags & FLAGS_QUOTE)
+    self->OutStream(self, CHAR_QUOTE);
+
+  if (! (flags & FLAGS_LEFTADJUST))
+    {
+      while (width-- > 0)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+
+  while (length-- > 0)
+    {
+      /* The ctype parameters must be an unsigned char (or EOF) */
+      ch = (int)((unsigned char)(*string++));
+      TrioWriteStringCharacter(self, ch, flags);
+    }
+
+  if (flags & FLAGS_LEFTADJUST)
+    {
+      while (width-- > 0)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+  if (flags & FLAGS_QUOTE)
+    self->OutStream(self, CHAR_QUOTE);
+}
+
+/*************************************************************************
+ * TrioWriteWideStringCharacter
+ *
+ * Description:
+ *  Output a wide string as a multi-byte sequence
+ */
+#if TRIO_WIDECHAR
+TRIO_PRIVATE int
+TrioWriteWideStringCharacter
+TRIO_ARGS4((self, wch, flags, width),
+	   trio_class_t *self,
+	   trio_wchar_t wch,
+	   trio_flags_t flags,
+	   int width)
+{
+  int size;
+  int i;
+  int ch;
+  char *string;
+  char buffer[MB_LEN_MAX + 1];
+
+  if (width == NO_WIDTH)
+    width = sizeof(buffer);
+  
+  size = wctomb(buffer, wch);
+  if ((size <= 0) || (size > width) || (buffer[0] == NIL))
+    return 0;
+
+  string = buffer;
+  i = size;
+  while ((width >= i) && (width-- > 0) && (i-- > 0))
+    {
+      /* The ctype parameters must be an unsigned char (or EOF) */
+      ch = (int)((unsigned char)(*string++));
+      TrioWriteStringCharacter(self, ch, flags);
+    }
+  return size;
+}
+#endif /* TRIO_WIDECHAR */
+
+/*************************************************************************
+ * TrioWriteWideString
+ *
+ * Description:
+ *  Output a wide character string as a multi-byte string
+ */
+#if TRIO_WIDECHAR
+TRIO_PRIVATE void
+TrioWriteWideString
+TRIO_ARGS5((self, wstring, flags, width, precision),
+	   trio_class_t *self,
+	   TRIO_CONST trio_wchar_t *wstring,
+	   trio_flags_t flags,
+	   int width,
+	   int precision)
+{
+  int length;
+  int size;
+
+  assert(VALID(self));
+  assert(VALID(self->OutStream));
+
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  (void)mblen(NULL, 0);
+#endif
+  
+  if (wstring == NULL)
+    {
+      TrioWriteString(self, NULL, flags, width, precision);
+      return;
+    }
+  
+  if (NO_PRECISION == precision)
+    {
+      length = INT_MAX;
+    }
+  else
+    {
+      length = precision;
+      width -= length;
+    }
+
+  if (flags & FLAGS_QUOTE)
+    self->OutStream(self, CHAR_QUOTE);
+
+  if (! (flags & FLAGS_LEFTADJUST))
+    {
+      while (width-- > 0)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+
+  while (length > 0)
+    {
+      size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
+      if (size == 0)
+	break; /* while */
+      length -= size;
+    }
+
+  if (flags & FLAGS_LEFTADJUST)
+    {
+      while (width-- > 0)
+	self->OutStream(self, CHAR_ADJUST);
+    }
+  if (flags & FLAGS_QUOTE)
+    self->OutStream(self, CHAR_QUOTE);
+}
+#endif /* TRIO_WIDECHAR */
+
+/*************************************************************************
+ * TrioWriteDouble
+ *
+ * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
+ *
+ * "5.2.4.2.2 paragraph #4
+ *
+ *  The accuracy [...] is implementation defined, as is the accuracy
+ *  of the conversion between floating-point internal representations
+ *  and string representations performed by the libray routine in
+ *  <stdio.h>"
+ */
+/* FIXME: handle all instances of constant long-double number (L)
+ *   and *l() math functions.
+ */
+TRIO_PRIVATE void
+TrioWriteDouble
+TRIO_ARGS6((self, number, flags, width, precision, base),
+	   trio_class_t *self,
+	   trio_long_double_t number,
+	   trio_flags_t flags,
+	   int width,
+	   int precision,
+	   int base)
+{
+  trio_long_double_t integerNumber;
+  trio_long_double_t fractionNumber;
+  trio_long_double_t workNumber;
+  int integerDigits;
+  int fractionDigits;
+  int exponentDigits;
+  int baseDigits;
+  int integerThreshold;
+  int fractionThreshold;
+  int expectedWidth;
+  int exponent = 0;
+  unsigned int uExponent = 0;
+  int exponentBase;
+  trio_long_double_t dblBase;
+  trio_long_double_t dblIntegerBase;
+  trio_long_double_t dblFractionBase;
+  trio_long_double_t integerAdjust;
+  trio_long_double_t fractionAdjust;
+  BOOLEAN_T isNegative;
+  BOOLEAN_T isExponentNegative = FALSE;
+  BOOLEAN_T requireTwoDigitExponent;
+  BOOLEAN_T isHex;
+  TRIO_CONST char *digits;
+  char *groupingPointer;
+  int i;
+  int index;
+  BOOLEAN_T hasOnlyZeroes;
+  int zeroes = 0;
+  register int trailingZeroes;
+  BOOLEAN_T keepTrailingZeroes;
+  BOOLEAN_T keepDecimalPoint;
+  trio_long_double_t epsilon;
+  
+  assert(VALID(self));
+  assert(VALID(self->OutStream));
+  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
+
+  /* Determine sign and look for special quantities */
+  switch (trio_fpclassify_and_signbit(number, &isNegative))
+    {
+    case TRIO_FP_NAN:
+      TrioWriteString(self,
+		      (flags & FLAGS_UPPER)
+		      ? NAN_UPPER
+		      : NAN_LOWER,
+		      flags, width, precision);
+      return;
+      
+    case TRIO_FP_INFINITE:
+      if (isNegative)
+	{
+	  /* Negative infinity */
+	  TrioWriteString(self,
+			  (flags & FLAGS_UPPER)
+			  ? "-" INFINITE_UPPER
+			  : "-" INFINITE_LOWER,
+			  flags, width, precision);
+	  return;
+	}
+      else
+	{
+	  /* Positive infinity */
+	  TrioWriteString(self,
+			  (flags & FLAGS_UPPER)
+			  ? INFINITE_UPPER
+			  : INFINITE_LOWER,
+			  flags, width, precision);
+	  return;
+	}
+
+    default:
+      /* Finitude */
+      break;
+    }
+  
+  /* Normal numbers */
+  if (flags & FLAGS_LONGDOUBLE)
+    {
+      baseDigits = (base == 10)
+	? LDBL_DIG
+	: (int)floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
+      epsilon = LDBL_EPSILON;
+    }
+  else if (flags & FLAGS_SHORT)
+    {
+      baseDigits = (base == BASE_DECIMAL)
+	? FLT_DIG
+	: (int)floor(FLT_MANT_DIG / TrioLogarithmBase(base));
+      epsilon = FLT_EPSILON;
+    }
+  else
+    {
+      baseDigits = (base == BASE_DECIMAL)
+	? DBL_DIG
+	: (int)floor(DBL_MANT_DIG / TrioLogarithmBase(base));
+      epsilon = DBL_EPSILON;
+    }
+
+  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
+  isHex = (base == BASE_HEX);
+  if (base == NO_BASE)
+    base = BASE_DECIMAL;
+  dblBase = (trio_long_double_t)base;
+  keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
+			  ( (flags & FLAGS_FLOAT_G) &&
+			    !(flags & FLAGS_ALTERNATIVE) ) );
+
+  if (flags & FLAGS_ROUNDING)
+    precision = baseDigits;
+
+  if (precision == NO_PRECISION)
+    {
+      if (isHex)
+	{
+	  keepTrailingZeroes = FALSE;
+	  precision = FLT_MANT_DIG;
+	}
+      else
+	{
+	  precision = FLT_DIG;
+	}
+    }
+  
+  if (isNegative)
+    number = -number;
+
+  if (isHex)
+    flags |= FLAGS_FLOAT_E;
+  
+  if (flags & FLAGS_FLOAT_G)
+    {
+      if (precision == 0)
+	precision = 1;
+
+      if ((number < 1.0E-4) || (number > powl(base,
+					      (trio_long_double_t)precision)))
+	{
+	  /* Use scientific notation */
+	  flags |= FLAGS_FLOAT_E;
+	}
+      else if (number < 1.0)
+	{
+	  /*
+	   * Use normal notation. If the integer part of the number is
+	   * zero, then adjust the precision to include leading fractional
+	   * zeros.
+	   */
+	  workNumber = TrioLogarithm(number, base);
+	  workNumber = TRIO_FABS(workNumber);
+	  if (workNumber - floorl(workNumber) < 0.001)
+	    workNumber--;
+	  zeroes = (int)floorl(workNumber);
+	}
+    }
+
+  if (flags & FLAGS_FLOAT_E)
+    {
+      /* Scale the number */
+      workNumber = TrioLogarithm(number, base);
+      if (trio_isinf(workNumber) == -1)
+	{
+	  exponent = 0;
+	  /* Undo setting */
+	  if (flags & FLAGS_FLOAT_G)
+	    flags &= ~FLAGS_FLOAT_E;
+	}
+      else
+	{
+	  exponent = (int)floorl(workNumber);
+	  number /= powl(dblBase, (trio_long_double_t)exponent);
+	  isExponentNegative = (exponent < 0);
+	  uExponent = (isExponentNegative) ? -exponent : exponent;
+	  if (isHex)
+	    uExponent *= 4; /* log16(2) */
+	  /* No thousand separators */
+	  flags &= ~FLAGS_QUOTE;
+	}
+    }
+
+  integerNumber = floorl(number);
+  fractionNumber = number - integerNumber;
+  
+  /*
+   * Truncated number.
+   *
+   * Precision is number of significant digits for FLOAT_G
+   * and number of fractional digits for others.
+   */
+  integerDigits = (integerNumber > epsilon)
+    ? 1 + (int)TrioLogarithm(integerNumber, base)
+    : 1;
+  fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0))
+    ? precision - integerDigits
+    : zeroes + precision;
+
+  dblFractionBase = TrioPower(base, fractionDigits);
+  
+  workNumber = number + 0.5 / dblFractionBase;
+  if (floorl(number) != floorl(workNumber))
+    {
+      if (flags & FLAGS_FLOAT_E)
+	{
+	  /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
+	  exponent++;
+	  isExponentNegative = (exponent < 0);
+	  uExponent = (isExponentNegative) ? -exponent : exponent;
+	  if (isHex)
+	    uExponent *= 4; /* log16(2) */
+	  workNumber = (number + 0.5 / dblFractionBase) / dblBase;
+	  integerNumber = floorl(workNumber);
+	  fractionNumber = workNumber - integerNumber;
+	}
+      else
+	{
+	  /* Adjust if number was rounded up one digit (ie. 99 to 100) */
+	  integerNumber = floorl(number + 0.5);
+	  fractionNumber = 0.0;
+	  integerDigits = (integerNumber > epsilon)
+	    ? 1 + (int)TrioLogarithm(integerNumber, base)
+	    : 1;
+	}
+    }
+
+  /* Estimate accuracy */
+  integerAdjust = fractionAdjust = 0.5;
+  if (flags & FLAGS_ROUNDING)
+    {
+      if (integerDigits > baseDigits)
+	{
+	  integerThreshold = baseDigits;
+	  fractionDigits = 0;
+	  dblFractionBase = 1.0;
+	  fractionThreshold = 0;
+	  precision = 0; /* Disable decimal-point */
+	  integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
+	  fractionAdjust = 0.0;
+	}
+      else
+	{
+	  integerThreshold = integerDigits;
+	  fractionThreshold = fractionDigits - integerThreshold;
+	  fractionAdjust = 1.0;
+	}
+    }
+  else
+    {
+      integerThreshold = INT_MAX;
+      fractionThreshold = INT_MAX;
+    }
+  
+  /*
+   * Calculate expected width.
+   *  sign + integer part + thousands separators + decimal point
+   *  + fraction + exponent
+   */
+  fractionAdjust /= dblFractionBase;
+  hasOnlyZeroes = (floorl((fractionNumber + fractionAdjust) * dblFractionBase) < epsilon);
+  keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
+		       !((precision == 0) ||
+			 (!keepTrailingZeroes && hasOnlyZeroes)) );
+  if (flags & FLAGS_FLOAT_E)
+    {
+      exponentDigits = (uExponent == 0)
+	? 1
+	: (int)ceil(TrioLogarithm((double)(uExponent + 1),
+				  (isHex) ? 10.0 : base));
+    }
+  else
+    exponentDigits = 0;
+  requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
+
+  expectedWidth = integerDigits + fractionDigits
+    + (keepDecimalPoint
+       ? internalDecimalPointLength
+       : 0)
+    + ((flags & FLAGS_QUOTE)
+       ? TrioCalcThousandSeparatorLength(integerDigits)
+       : 0);
+  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
+    expectedWidth += sizeof("-") - 1;
+  if (exponentDigits > 0)
+    expectedWidth += exponentDigits +
+      ((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1);
+  if (isHex)
+    expectedWidth += sizeof("0X") - 1;
+  
+  /* Output prefixing */
+  if (flags & FLAGS_NILPADDING)
+    {
+      /* Leading zeros must be after sign */
+      if (isNegative)
+	self->OutStream(self, '-');
+      else if (flags & FLAGS_SHOWSIGN)
+	self->OutStream(self, '+');
+      else if (flags & FLAGS_SPACE)
+	self->OutStream(self, ' ');
+      if (isHex)
+	{
+	  self->OutStream(self, '0');
+	  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
+	}
+      if (!(flags & FLAGS_LEFTADJUST))
+	{
+	  for (i = expectedWidth; i < width; i++)
+	    {
+	      self->OutStream(self, '0');
+	    }
+	}
+    }
+  else
+    {
+      /* Leading spaces must be before sign */
+      if (!(flags & FLAGS_LEFTADJUST))
+	{
+	  for (i = expectedWidth; i < width; i++)
+	    {
+	      self->OutStream(self, CHAR_ADJUST);
+	    }
+	}
+      if (isNegative)
+	self->OutStream(self, '-');
+      else if (flags & FLAGS_SHOWSIGN)
+	self->OutStream(self, '+');
+      else if (flags & FLAGS_SPACE)
+	self->OutStream(self, ' ');
+      if (isHex)
+	{
+	  self->OutStream(self, '0');
+	  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
+	}
+    }
+  
+  /* Output the integer part and thousand separators */
+  dblIntegerBase = 1.0 / TrioPower(base, integerDigits - 1);
+  for (i = 0; i < integerDigits; i++)
+    {
+      workNumber = floorl(((integerNumber + integerAdjust) * dblIntegerBase));
+      if (i > integerThreshold)
+	{
+	  /* Beyond accuracy */
+	  self->OutStream(self, digits[0]);
+	}
+      else
+	{
+	  self->OutStream(self, digits[(int)fmodl(workNumber, dblBase)]);
+	}
+      dblIntegerBase *= dblBase;
+      
+      if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
+	  && TrioFollowedBySeparator(integerDigits - i))
+	{
+	  for (groupingPointer = internalThousandSeparator;
+	       *groupingPointer != NIL;
+	       groupingPointer++)
+	    {
+	      self->OutStream(self, *groupingPointer);
+	    }
+	}
+    }
+  
+  /* Insert decimal point and build the fraction part */
+  trailingZeroes = 0;
+
+  if (keepDecimalPoint)
+    {
+      if (internalDecimalPoint)
+	{
+	  self->OutStream(self, internalDecimalPoint);
+	}
+      else
+	{
+	  for (i = 0; i < internalDecimalPointLength; i++)
+	    {
+	      self->OutStream(self, internalDecimalPointString[i]);
+	    }
+	}
+    }
+
+  for (i = 0; i < fractionDigits; i++)
+    {
+      if ((integerDigits > integerThreshold) || (i > fractionThreshold))
+	{
+	  /* Beyond accuracy */
+	  trailingZeroes++;
+	}
+      else
+	{
+	  fractionNumber *= dblBase;
+	  fractionAdjust *= dblBase;
+	  workNumber = floorl(fractionNumber + fractionAdjust);
+	  fractionNumber -= workNumber;
+	  index = (int)fmodl(workNumber, dblBase);
+	  if (index == 0)
+	    {
+	      trailingZeroes++;
+	    }
+	  else
+	    {
+	      while (trailingZeroes > 0)
+		{
+		  /* Not trailing zeroes after all */
+		  self->OutStream(self, digits[0]);
+		  trailingZeroes--;
+		}
+	      self->OutStream(self, digits[index]);
+	    }
+	}
+    }
+  
+  if (keepTrailingZeroes)
+    {
+      while (trailingZeroes > 0)
+	{
+	  self->OutStream(self, digits[0]);
+	  trailingZeroes--;
+	}
+    }
+  
+  /* Output exponent */
+  if (exponentDigits > 0)
+    {
+      self->OutStream(self,
+		      isHex
+		      ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
+		      : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
+      self->OutStream(self, (isExponentNegative) ? '-' : '+');
+
+      /* The exponent must contain at least two digits */
+      if (requireTwoDigitExponent)
+        self->OutStream(self, '0');
+
+      if (isHex)
+	base = 10.0;
+      exponentBase = (int)TrioPower(base, exponentDigits - 1);
+      for (i = 0; i < exponentDigits; i++)
+	{
+	  self->OutStream(self, digits[(uExponent / exponentBase) % base]);
+	  exponentBase /= base;
+	}
+    }
+  /* Output trailing spaces */
+  if (flags & FLAGS_LEFTADJUST)
+    {
+      for (i = expectedWidth; i < width; i++)
+	{
+	  self->OutStream(self, CHAR_ADJUST);
+	}
+    }
+}
+
+/*************************************************************************
+ * TrioFormatProcess
+ *
+ * Description:
+ *  This is the main engine for formatting output
+ */
+TRIO_PRIVATE int
+TrioFormatProcess
+TRIO_ARGS3((data, format, parameters),
+	   trio_class_t *data,
+	   TRIO_CONST char *format,
+	   trio_parameter_t *parameters)
+{
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  int charlen;
+#endif
+  int i;
+  TRIO_CONST char *string;
+  trio_pointer_t pointer;
+  trio_flags_t flags;
+  int width;
+  int precision;
+  int base;
+  int index;
+  
+  index = 0;
+  i = 0;
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  (void)mblen(NULL, 0);
+#endif
+  
+  while (format[index])
+    {
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+      if (! isascii(format[index]))
+	{
+	  charlen = mblen(&format[index], MB_LEN_MAX);
+	  /*
+	   * Only valid multibyte characters are handled here. Invalid
+	   * multibyte characters (charlen == -1) are handled as normal
+	   * characters.
+	   */
+	  if (charlen != -1)
+	    {
+	      while (charlen-- > 0)
+		{
+		  data->OutStream(data, format[index++]);
+		}
+	      continue; /* while characters left in formatting string */
+	    }
+	}
+#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
+      if (CHAR_IDENTIFIER == format[index])
+	{
+	  if (CHAR_IDENTIFIER == format[index + 1])
+	    {
+	      data->OutStream(data, CHAR_IDENTIFIER);
+	      index += 2;
+	    }
+	  else
+	    {
+	      /* Skip the parameter entries */
+	      while (parameters[i].type == FORMAT_PARAMETER)
+		i++;
+	      
+	      flags = parameters[i].flags;
+
+	      /* Find width */
+	      width = parameters[i].width;
+	      if (flags & FLAGS_WIDTH_PARAMETER)
+		{
+		  /* Get width from parameter list */
+		  width = (int)parameters[width].data.number.as_signed;
+		  if (width < 0)
+		    {
+		      /*
+		       * A negative width is the same as the - flag and
+		       * a positive width.
+		       */
+		      flags |= FLAGS_LEFTADJUST;
+		      flags &= ~FLAGS_NILPADDING;
+		      width = -width;
+		    }
+		}
+	      
+	      /* Find precision */
+	      if (flags & FLAGS_PRECISION)
+		{
+		  precision = parameters[i].precision;
+		  if (flags & FLAGS_PRECISION_PARAMETER)
+		    {
+		      /* Get precision from parameter list */
+		      precision = (int)parameters[precision].data.number.as_signed;
+		      if (precision < 0)
+			{
+			  /*
+			   * A negative precision is the same as no
+			   * precision
+			   */
+			  precision = NO_PRECISION;
+			}
+		    }
+		}
+	      else
+		{
+		  precision = NO_PRECISION;
+		}
+
+	      /* Find base */
+	      base = parameters[i].base;
+	      if (flags & FLAGS_BASE_PARAMETER)
+		{
+		  /* Get base from parameter list */
+		  base = (int)parameters[base].data.number.as_signed;
+		}
+	      
+	      switch (parameters[i].type)
+		{
+		case FORMAT_CHAR:
+		  if (flags & FLAGS_QUOTE)
+		    data->OutStream(data, CHAR_QUOTE);
+		  if (! (flags & FLAGS_LEFTADJUST))
+		    {
+		      while (--width > 0)
+			data->OutStream(data, CHAR_ADJUST);
+		    }
+#if TRIO_WIDECHAR
+		  if (flags & FLAGS_WIDECHAR)
+		    {
+		      TrioWriteWideStringCharacter(data,
+						   (trio_wchar_t)parameters[i].data.number.as_signed,
+						   flags,
+						   NO_WIDTH);
+		    }
+		  else
+#endif
+		    {
+		      TrioWriteStringCharacter(data,
+					       (int)parameters[i].data.number.as_signed,
+					       flags);
+		    }
+
+		  if (flags & FLAGS_LEFTADJUST)
+		    {
+		      while(--width > 0)
+			data->OutStream(data, CHAR_ADJUST);
+		    }
+		  if (flags & FLAGS_QUOTE)
+		    data->OutStream(data, CHAR_QUOTE);
+
+		  break; /* FORMAT_CHAR */
+
+		case FORMAT_INT:
+		  TrioWriteNumber(data,
+				  parameters[i].data.number.as_unsigned,
+				  flags,
+				  width,
+				  precision,
+				  base);
+
+		  break; /* FORMAT_INT */
+
+		case FORMAT_DOUBLE:
+		  TrioWriteDouble(data,
+				  parameters[i].data.longdoubleNumber,
+				  flags,
+				  width,
+				  precision,
+				  base);
+		  break; /* FORMAT_DOUBLE */
+
+		case FORMAT_STRING:
+#if TRIO_WIDECHAR
+		  if (flags & FLAGS_WIDECHAR)
+		    {
+		      TrioWriteWideString(data,
+					  parameters[i].data.wstring,
+					  flags,
+					  width,
+					  precision);
+		    }
+		  else
+#endif
+		    {
+		      TrioWriteString(data,
+				      parameters[i].data.string,
+				      flags,
+				      width,
+				      precision);
+		    }
+		  break; /* FORMAT_STRING */
+
+		case FORMAT_POINTER:
+		  {
+		    trio_reference_t reference;
+		    
+		    reference.data = data;
+		    reference.parameter = &parameters[i];
+		    trio_print_pointer(&reference, parameters[i].data.pointer);
+		  }
+		  break; /* FORMAT_POINTER */
+
+		case FORMAT_COUNT:
+		  pointer = parameters[i].data.pointer;
+		  if (NULL != pointer)
+		    {
+		      /*
+		       * C99 paragraph 7.19.6.1.8 says "the number of
+		       * characters written to the output stream so far by
+		       * this call", which is data->committed
+		       */
+#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
+		      if (flags & FLAGS_SIZE_T)
+			*(size_t *)pointer = (size_t)data->committed;
+		      else
+#endif
+#if defined(QUALIFIER_PTRDIFF_T)
+		      if (flags & FLAGS_PTRDIFF_T)
+			*(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;
+		      else
+#endif
+#if defined(QUALIFIER_INTMAX_T)
+		      if (flags & FLAGS_INTMAX_T)
+			*(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;
+		      else
+#endif
+		      if (flags & FLAGS_QUAD)
+			{
+			  *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;
+			}
+		      else if (flags & FLAGS_LONG)
+			{
+			  *(long int *)pointer = (long int)data->committed;
+			}
+		      else if (flags & FLAGS_SHORT)
+			{
+			  *(short int *)pointer = (short int)data->committed;
+			}
+		      else
+			{
+			  *(int *)pointer = (int)data->committed;
+			}
+		    }
+		  break; /* FORMAT_COUNT */
+
+		case FORMAT_PARAMETER:
+		  break; /* FORMAT_PARAMETER */
+
+#if defined(FORMAT_ERRNO)
+		case FORMAT_ERRNO:
+		  string = trio_error(parameters[i].data.errorNumber);
+		  if (string)
+		    {
+		      TrioWriteString(data,
+				      string,
+				      flags,
+				      width,
+				      precision);
+		    }
+		  else
+		    {
+		      data->OutStream(data, '#');
+		      TrioWriteNumber(data,
+				      (trio_uintmax_t)parameters[i].data.errorNumber,
+				      flags,
+				      width,
+				      precision,
+				      BASE_DECIMAL);
+		    }
+		  break; /* FORMAT_ERRNO */
+#endif /* defined(FORMAT_ERRNO) */
+
+#if defined(FORMAT_USER_DEFINED)
+		case FORMAT_USER_DEFINED:
+		  {
+		    trio_reference_t reference;
+		    trio_userdef_t *def = NULL;
+
+		    if (parameters[i].user_name[0] == NIL)
+		      {
+			/* Use handle */
+			if ((i > 0) ||
+			    (parameters[i - 1].type == FORMAT_PARAMETER))
+			  def = (trio_userdef_t *)parameters[i - 1].data.pointer;
+		      }
+		    else
+		      {
+			/* Look up namespace */
+			def = TrioFindNamespace(parameters[i].user_name, NULL);
+		      }
+		    if (def) {
+		      reference.data = data;
+		      reference.parameter = &parameters[i];
+		      def->callback(&reference);
+		    }
+		  }
+		  break;
+#endif /* defined(FORMAT_USER_DEFINED) */
+		  
+		default:
+		  break;
+		} /* switch parameter type */
+
+	      /* Prepare for next */
+	      index = parameters[i].indexAfterSpecifier;
+	      i++;
+	    }
+	}
+      else /* not identifier */
+	{
+	  data->OutStream(data, format[index++]);
+	}
+    }
+  return data->processed;
+}
+
+/*************************************************************************
+ * TrioFormatRef
+ */
+TRIO_PRIVATE int
+TrioFormatRef
+TRIO_ARGS4((reference, format, arglist, argarray),
+	   trio_reference_t *reference,
+	   TRIO_CONST char *format,
+	   va_list *arglist,
+	   trio_pointer_t *argarray)
+{
+  int status;
+  trio_parameter_t parameters[MAX_PARAMETERS];
+
+  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
+  if (status < 0)
+    return status;
+
+  status = TrioFormatProcess(reference->data, format, parameters);
+  if (reference->data->error != 0)
+    {
+      status = reference->data->error;
+    }
+  return status;
+}
+
+/*************************************************************************
+ * TrioFormat
+ */
+TRIO_PRIVATE int
+TrioFormat
+TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
+	   trio_pointer_t destination,
+	   size_t destinationSize,
+	   void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
+	   TRIO_CONST char *format,
+	   va_list *arglist,
+	   trio_pointer_t *argarray)
+{
+  int status;
+  trio_class_t data;
+  trio_parameter_t parameters[MAX_PARAMETERS];
+
+  assert(VALID(OutStream));
+  assert(VALID(format));
+
+  memset(&data, 0, sizeof(data));
+  data.OutStream = OutStream;
+  data.location = destination;
+  data.max = destinationSize;
+  data.error = 0;
+
+#if defined(USE_LOCALE)
+  if (NULL == internalLocaleValues)
+    {
+      TrioSetLocale();
+    }
+#endif
+
+  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
+  if (status < 0)
+    return status;
+
+  status = TrioFormatProcess(&data, format, parameters);
+  if (data.error != 0)
+    {
+      status = data.error;
+    }
+  return status;
+}
+
+/*************************************************************************
+ * TrioOutStreamFile
+ */
+TRIO_PRIVATE void
+TrioOutStreamFile
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  FILE *file;
+
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  file = (FILE *)self->location;
+  self->processed++;
+  if (fputc(output, file) == EOF)
+    {
+      self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
+    }
+  else
+    {
+      self->committed++;
+    }
+}
+
+/*************************************************************************
+ * TrioOutStreamFileDescriptor
+ */
+TRIO_PRIVATE void
+TrioOutStreamFileDescriptor
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  int fd;
+  char ch;
+
+  assert(VALID(self));
+
+  fd = *((int *)self->location);
+  ch = (char)output;
+  self->processed++;
+  if (write(fd, &ch, sizeof(char)) == -1)
+    {
+      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
+    }
+  else
+    {
+      self->committed++;
+    }
+}
+
+/*************************************************************************
+ * TrioOutStreamCustom
+ */
+TRIO_PRIVATE void
+TrioOutStreamCustom
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  int status;
+  trio_custom_t *data;
+
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  data = (trio_custom_t *)self->location;
+  if (data->stream.out)
+    {
+      status = (data->stream.out)(data->closure, output);
+      if (status >= 0)
+	{
+	  self->committed++;
+	}
+      else
+	{
+	  if (self->error == 0)
+	    {
+	      self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
+	    }
+	}
+    }
+  self->processed++;
+}
+
+/*************************************************************************
+ * TrioOutStreamString
+ */
+TRIO_PRIVATE void
+TrioOutStreamString
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  char **buffer;
+
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  buffer = (char **)self->location;
+  **buffer = (char)output;
+  (*buffer)++;
+  self->processed++;
+  self->committed++;
+}
+
+/*************************************************************************
+ * TrioOutStreamStringMax
+ */
+TRIO_PRIVATE void
+TrioOutStreamStringMax
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  char **buffer;
+
+  assert(VALID(self));
+  assert(VALID(self->location));
+  
+  buffer = (char **)self->location;
+
+  if (self->processed < self->max)
+    {
+      **buffer = (char)output;
+      (*buffer)++;
+      self->committed++;
+    }
+  self->processed++;
+}
+
+/*************************************************************************
+ * TrioOutStreamStringDynamic
+ */
+TRIO_PRIVATE void
+TrioOutStreamStringDynamic
+TRIO_ARGS2((self, output),
+	   trio_class_t *self,
+	   int output)
+{
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  if (self->error == 0)
+    {
+      trio_xstring_append_char((trio_string_t *)self->location,
+			       (char)output);
+      self->committed++;
+    }
+  /* The processed variable must always be increased */
+  self->processed++;
+}
+
+/*************************************************************************
+ *
+ * Formatted printing functions
+ *
+ ************************************************************************/
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_printf.h"
+#endif
+/** @addtogroup Printf
+    @{
+*/
+
+/*************************************************************************
+ * printf
+ */
+
+/**
+   Print to standard output stream.
+
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_printf
+TRIO_VARGS2((format, va_alist),
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+/**
+   Print to standard output stream.
+
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_vprintf
+TRIO_ARGS2((format, args),
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(format));
+
+  return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+}
+
+/**
+   Print to standard output stream.
+
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_printfv
+TRIO_ARGS2((format, args),
+	   TRIO_CONST char *format,
+	   trio_pointer_t * args)
+{
+  assert(VALID(format));
+
+  return TrioFormat(stdout, 0, TrioOutStreamFile, format, NULL, args);
+}
+
+/*************************************************************************
+ * fprintf
+ */
+
+/**
+   Print to file.
+
+   @param file File pointer.
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_fprintf
+TRIO_VARGS3((file, format, va_alist),
+	    FILE *file,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+/**
+   Print to file.
+
+   @param file File pointer.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_vfprintf
+TRIO_ARGS3((file, format, args),
+	   FILE *file,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+}
+
+/**
+   Print to file.
+
+   @param file File pointer.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_fprintfv
+TRIO_ARGS3((file, format, args),
+	   FILE *file,
+	   TRIO_CONST char *format,
+	   trio_pointer_t * args)
+{
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args);
+}
+
+/*************************************************************************
+ * dprintf
+ */
+
+/**
+   Print to file descriptor.
+
+   @param fd File descriptor.
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_dprintf
+TRIO_VARGS3((fd, format, va_alist),
+	    int fd,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+/**
+   Print to file descriptor.
+
+   @param fd File descriptor.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_vdprintf
+TRIO_ARGS3((fd, format, args),
+	   int fd,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(format));
+  
+  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+}
+
+/**
+   Print to file descriptor.
+
+   @param fd File descriptor.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_dprintfv
+TRIO_ARGS3((fd, format, args),
+	   int fd,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  assert(VALID(format));
+  
+  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, NULL, args);
+}
+
+/*************************************************************************
+ * cprintf
+ */
+TRIO_PUBLIC int
+trio_cprintf
+TRIO_VARGS4((stream, closure, format, va_alist),
+	    trio_outstream_t stream,
+	    trio_pointer_t closure,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+  trio_custom_t data;
+
+  assert(VALID(stream));
+  assert(VALID(format));
+
+  TRIO_VA_START(args, format);
+  data.stream.out = stream;
+  data.closure = closure;
+  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vcprintf
+TRIO_ARGS4((stream, closure, format, args),
+	   trio_outstream_t stream,
+	   trio_pointer_t closure,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  trio_custom_t data;
+
+  assert(VALID(stream));
+  assert(VALID(format));
+
+  data.stream.out = stream;
+  data.closure = closure;
+  return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_cprintfv
+TRIO_ARGS4((stream, closure, format, args),
+	   trio_outstream_t stream,
+	   trio_pointer_t closure,
+	   TRIO_CONST char *format,
+	   void **args)
+{
+  trio_custom_t data;
+
+  assert(VALID(stream));
+  assert(VALID(format));
+
+  data.stream.out = stream;
+  data.closure = closure;
+  return TrioFormat(&data, 0, TrioOutStreamCustom, format, NULL, args);
+}
+
+/*************************************************************************
+ * sprintf
+ */
+
+/**
+   Print to string.
+
+   @param buffer Output string.
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_sprintf
+TRIO_VARGS3((buffer, format, va_alist),
+	    char *buffer,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  *buffer = NIL; /* Terminate with NIL character */
+  TRIO_VA_END(args);
+  return status;
+}
+
+/**
+   Print to string.
+
+   @param buffer Output string.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_vsprintf
+TRIO_ARGS3((buffer, format, args),
+	   char *buffer,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  int status;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  *buffer = NIL;
+  return status;
+}
+
+/**
+   Print to string.
+
+   @param buffer Output string.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_sprintfv
+TRIO_ARGS3((buffer, format, args),
+	   char *buffer,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  int status;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, NULL, args);
+  *buffer = NIL;
+  return status;
+}
+
+/*************************************************************************
+ * snprintf
+ */
+
+/**
+   Print at most @p max characters to string.
+
+   @param buffer Output string.
+   @param max Maximum number of characters to print.
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_snprintf
+TRIO_VARGS4((buffer, max, format, va_alist),
+	    char *buffer,
+	    size_t max,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  TRIO_VA_START(args, format);
+  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
+		      TrioOutStreamStringMax, format, &args, NULL);
+  if (max > 0)
+    *buffer = NIL;
+  TRIO_VA_END(args);
+  return status;
+}
+
+/**
+   Print at most @p max characters to string.
+
+   @param buffer Output string.
+   @param max Maximum number of characters to print.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_vsnprintf
+TRIO_ARGS4((buffer, max, format, args),
+	   char *buffer,
+	   size_t max,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  int status;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
+		      TrioOutStreamStringMax, format, &args, NULL);
+  if (max > 0)
+    *buffer = NIL;
+  return status;
+}
+
+/**
+   Print at most @p max characters to string.
+
+   @param buffer Output string.
+   @param max Maximum number of characters to print.
+   @param format Formatting string.
+   @param args Arguments.
+   @return Number of printed characters.
+ */
+TRIO_PUBLIC int
+trio_snprintfv
+TRIO_ARGS4((buffer, max, format, args),
+	   char *buffer,
+	   size_t max,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  int status;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
+		      TrioOutStreamStringMax, format, NULL, args);
+  if (max > 0)
+    *buffer = NIL;
+  return status;
+}
+
+/*************************************************************************
+ * snprintfcat
+ * Appends the new string to the buffer string overwriting the '\0'
+ * character at the end of buffer.
+ */
+TRIO_PUBLIC int
+trio_snprintfcat
+TRIO_VARGS4((buffer, max, format, va_alist),
+	    char *buffer,
+	    size_t max,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+  size_t buf_len;
+
+  TRIO_VA_START(args, format);
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  buf_len = trio_length(buffer);
+  buffer = &buffer[buf_len];
+
+  status = TrioFormat(&buffer, max - 1 - buf_len,
+		      TrioOutStreamStringMax, format, &args, NULL);
+  TRIO_VA_END(args);
+  *buffer = NIL;
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vsnprintfcat
+TRIO_ARGS4((buffer, max, format, args),
+	   char *buffer,
+	   size_t max,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  int status;
+  size_t buf_len;
+  
+  assert(VALID(buffer));
+  assert(VALID(format));
+
+  buf_len = trio_length(buffer);
+  buffer = &buffer[buf_len];
+  status = TrioFormat(&buffer, max - 1 - buf_len,
+		      TrioOutStreamStringMax, format, &args, NULL);
+  *buffer = NIL;
+  return status;
+}
+
+/*************************************************************************
+ * trio_aprintf
+ */
+
+/* Deprecated */
+TRIO_PUBLIC char *
+trio_aprintf
+TRIO_VARGS2((format, va_alist),
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  va_list args;
+  trio_string_t *info;
+  char *result = NULL;
+
+  assert(VALID(format));
+  
+  info = trio_xstring_duplicate("");
+  if (info)
+    {
+      TRIO_VA_START(args, format);
+      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
+		       format, &args, NULL);
+      TRIO_VA_END(args);
+
+      trio_string_terminate(info);
+      result = trio_string_extract(info);
+      trio_string_destroy(info);
+    }
+  return result;
+}
+
+/* Deprecated */
+TRIO_PUBLIC char *
+trio_vaprintf
+TRIO_ARGS2((format, args),
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  trio_string_t *info;
+  char *result = NULL;
+  
+  assert(VALID(format));
+  
+  info = trio_xstring_duplicate("");
+  if (info)
+    {
+      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
+		       format, &args, NULL);
+      trio_string_terminate(info);
+      result = trio_string_extract(info);
+      trio_string_destroy(info);
+    }
+  return result;
+}
+
+TRIO_PUBLIC int
+trio_asprintf
+TRIO_VARGS3((result, format, va_alist),
+	    char **result,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  va_list args;
+  int status;
+  trio_string_t *info;
+
+  assert(VALID(format));
+
+  *result = NULL;
+  
+  info = trio_xstring_duplicate("");
+  if (info == NULL)
+    {
+      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
+    }
+  else
+    {
+      TRIO_VA_START(args, format);
+      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
+			  format, &args, NULL);
+      TRIO_VA_END(args);
+      if (status >= 0)
+	{
+	  trio_string_terminate(info);
+	  *result = trio_string_extract(info);
+	}
+      trio_string_destroy(info);
+    }
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vasprintf
+TRIO_ARGS3((result, format, args),
+	   char **result,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  int status;
+  trio_string_t *info;
+  
+  assert(VALID(format));
+
+  *result = NULL;
+  
+  info = trio_xstring_duplicate("");
+  if (info == NULL)
+    {
+      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
+    }
+  else
+    {
+      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
+			  format, &args, NULL);
+      if (status >= 0)
+	{
+	  trio_string_terminate(info);
+	  *result = trio_string_extract(info);
+	}
+      trio_string_destroy(info);
+    }
+  return status;
+}
+
+/** @} End of Printf documentation module */
+
+/*************************************************************************
+ *
+ * CALLBACK
+ *
+ ************************************************************************/
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_register.h"
+#endif
+/**
+   @addtogroup UserDefined
+   @{
+*/
+
+#if TRIO_EXTENSION
+
+/*************************************************************************
+ * trio_register
+ */
+
+/**
+   Register new user-defined specifier.
+
+   @param callback
+   @param name
+   @return Handle.
+ */
+TRIO_PUBLIC trio_pointer_t 
+trio_register
+TRIO_ARGS2((callback, name),
+	   trio_callback_t callback,
+	   TRIO_CONST char *name)
+{
+  trio_userdef_t *def;
+  trio_userdef_t *prev = NULL;
+
+  if (callback == NULL)
+    return NULL;
+
+  if (name)
+    {
+      /* Handle built-in namespaces */
+      if (name[0] == ':')
+	{
+	  if (trio_equal(name, ":enter"))
+	    {
+	      internalEnterCriticalRegion = callback;
+	    }
+	  else if (trio_equal(name, ":leave"))
+	    {
+	      internalLeaveCriticalRegion = callback;
+	    }
+	  return NULL;
+	}
+      
+      /* Bail out if namespace is too long */
+      if (trio_length(name) >= MAX_USER_NAME)
+	return NULL;
+      
+      /* Bail out if namespace already is registered */
+      def = TrioFindNamespace(name, &prev);
+      if (def)
+	return NULL;
+    }
+  
+  def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
+  if (def)
+    {
+      if (internalEnterCriticalRegion)
+	(void)internalEnterCriticalRegion(NULL);
+      
+      if (name)
+	{
+	  /* Link into internal list */
+	  if (prev == NULL)
+	    internalUserDef = def;
+	  else
+	    prev->next = def;
+	}
+      /* Initialize */
+      def->callback = callback;
+      def->name = (name == NULL)
+	? NULL
+	: trio_duplicate(name);
+      def->next = NULL;
+
+      if (internalLeaveCriticalRegion)
+	(void)internalLeaveCriticalRegion(NULL);
+    }
+  return (trio_pointer_t)def;
+}
+
+/**
+   Unregister an existing user-defined specifier.
+
+   @param handle
+ */
+void
+trio_unregister
+TRIO_ARGS1((handle),
+	   trio_pointer_t handle)
+{
+  trio_userdef_t *self = (trio_userdef_t *)handle;
+  trio_userdef_t *def;
+  trio_userdef_t *prev = NULL;
+
+  assert(VALID(self));
+
+  if (self->name)
+    {
+      def = TrioFindNamespace(self->name, &prev);
+      if (def)
+	{
+	  if (internalEnterCriticalRegion)
+	    (void)internalEnterCriticalRegion(NULL);
+	  
+	  if (prev == NULL)
+	    internalUserDef = NULL;
+	  else
+	    prev->next = def->next;
+	  
+	  if (internalLeaveCriticalRegion)
+	    (void)internalLeaveCriticalRegion(NULL);
+	}
+      trio_destroy(self->name);
+    }
+  TRIO_FREE(self);
+}
+
+/*************************************************************************
+ * trio_get_format [public]
+ */
+TRIO_CONST char *
+trio_get_format
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+#if defined(FORMAT_USER_DEFINED)
+  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
+#endif
+  
+  return (((trio_reference_t *)ref)->parameter->user_data);
+}
+
+/*************************************************************************
+ * trio_get_argument [public]
+ */
+trio_pointer_t 
+trio_get_argument
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+#if defined(FORMAT_USER_DEFINED)
+  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
+#endif
+  
+  return ((trio_reference_t *)ref)->parameter->data.pointer;
+}
+
+/*************************************************************************
+ * trio_get_width / trio_set_width [public]
+ */
+int
+trio_get_width
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return ((trio_reference_t *)ref)->parameter->width;
+}
+
+void
+trio_set_width
+TRIO_ARGS2((ref, width),
+	   trio_pointer_t ref,
+	   int width)
+{
+  ((trio_reference_t *)ref)->parameter->width = width;
+}
+
+/*************************************************************************
+ * trio_get_precision / trio_set_precision [public]
+ */
+int
+trio_get_precision
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->precision);
+}
+
+void
+trio_set_precision
+TRIO_ARGS2((ref, precision),
+	   trio_pointer_t ref,
+	   int precision)
+{
+  ((trio_reference_t *)ref)->parameter->precision = precision;
+}
+
+/*************************************************************************
+ * trio_get_base / trio_set_base [public]
+ */
+int
+trio_get_base
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->base);
+}
+
+void
+trio_set_base
+TRIO_ARGS2((ref, base),
+	   trio_pointer_t ref,
+	   int base)
+{
+  ((trio_reference_t *)ref)->parameter->base = base;
+}
+
+/*************************************************************************
+ * trio_get_long / trio_set_long [public]
+ */
+int
+trio_get_long
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_long
+TRIO_ARGS2((ref, is_long),
+	   trio_pointer_t ref,
+	   int is_long)
+{
+  if (is_long)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
+}
+
+/*************************************************************************
+ * trio_get_longlong / trio_set_longlong [public]
+ */
+int
+trio_get_longlong
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_longlong
+TRIO_ARGS2((ref, is_longlong),
+	   trio_pointer_t ref,
+	   int is_longlong)
+{
+  if (is_longlong)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
+}
+
+/*************************************************************************
+ * trio_get_longdouble / trio_set_longdouble [public]
+ */
+int
+trio_get_longdouble
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_longdouble
+TRIO_ARGS2((ref, is_longdouble),
+	   trio_pointer_t ref,
+	   int is_longdouble)
+{
+  if (is_longdouble)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
+}
+
+/*************************************************************************
+ * trio_get_short / trio_set_short [public]
+ */
+int
+trio_get_short
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_short
+TRIO_ARGS2((ref, is_short),
+	   trio_pointer_t ref,
+	   int is_short)
+{
+  if (is_short)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
+}
+
+/*************************************************************************
+ * trio_get_shortshort / trio_set_shortshort [public]
+ */
+int
+trio_get_shortshort
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_shortshort
+TRIO_ARGS2((ref, is_shortshort),
+	   trio_pointer_t ref,
+	   int is_shortshort)
+{
+  if (is_shortshort)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
+}
+
+/*************************************************************************
+ * trio_get_alternative / trio_set_alternative [public]
+ */
+int
+trio_get_alternative
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_alternative
+TRIO_ARGS2((ref, is_alternative),
+	   trio_pointer_t ref,
+	   int is_alternative)
+{
+  if (is_alternative)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
+}
+
+/*************************************************************************
+ * trio_get_alignment / trio_set_alignment [public]
+ */
+int
+trio_get_alignment
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_alignment
+TRIO_ARGS2((ref, is_leftaligned),
+	   trio_pointer_t ref,
+	   int is_leftaligned)
+{
+  if (is_leftaligned)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
+}
+
+/*************************************************************************
+ * trio_get_spacing /trio_set_spacing [public]
+ */
+int
+trio_get_spacing
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_spacing
+TRIO_ARGS2((ref, is_space),
+	   trio_pointer_t ref,
+	   int is_space)
+{
+  if (is_space)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
+}
+
+/*************************************************************************
+ * trio_get_sign / trio_set_sign [public]
+ */
+int
+trio_get_sign
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_sign
+TRIO_ARGS2((ref, is_sign),
+	   trio_pointer_t ref,
+	   int is_sign)
+{
+  if (is_sign)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
+}
+
+/*************************************************************************
+ * trio_get_padding / trio_set_padding [public]
+ */
+int
+trio_get_padding
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_padding
+TRIO_ARGS2((ref, is_padding),
+	   trio_pointer_t ref,
+	   int is_padding)
+{
+  if (is_padding)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
+}
+
+/*************************************************************************
+ * trio_get_quote / trio_set_quote [public]
+ */
+int
+trio_get_quote
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_quote
+TRIO_ARGS2((ref, is_quote),
+	   trio_pointer_t ref,
+	   int is_quote)
+{
+  if (is_quote)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
+}
+
+/*************************************************************************
+ * trio_get_upper / trio_set_upper [public]
+ */
+int
+trio_get_upper
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_upper
+TRIO_ARGS2((ref, is_upper),
+	   trio_pointer_t ref,
+	   int is_upper)
+{
+  if (is_upper)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
+}
+
+/*************************************************************************
+ * trio_get_largest / trio_set_largest [public]
+ */
+#if TRIO_C99
+int
+trio_get_largest
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_largest
+TRIO_ARGS2((ref, is_largest),
+	   trio_pointer_t ref,
+	   int is_largest)
+{
+  if (is_largest)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
+}
+#endif
+
+/*************************************************************************
+ * trio_get_ptrdiff / trio_set_ptrdiff [public]
+ */
+int
+trio_get_ptrdiff
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_ptrdiff
+TRIO_ARGS2((ref, is_ptrdiff),
+	   trio_pointer_t ref,
+	   int is_ptrdiff)
+{
+  if (is_ptrdiff)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
+}
+
+/*************************************************************************
+ * trio_get_size / trio_set_size [public]
+ */
+#if TRIO_C99
+int
+trio_get_size
+TRIO_ARGS1((ref),
+	   trio_pointer_t ref)
+{
+  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)
+    ? TRUE
+    : FALSE;
+}
+
+void
+trio_set_size
+TRIO_ARGS2((ref, is_size),
+	   trio_pointer_t ref,
+	   int is_size)
+{
+  if (is_size)
+    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
+  else
+    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
+}
+#endif
+
+/*************************************************************************
+ * trio_print_int [public]
+ */
+void
+trio_print_int
+TRIO_ARGS2((ref, number),
+	   trio_pointer_t ref,
+	   int number)
+{
+  trio_reference_t *self = (trio_reference_t *)ref;
+
+  TrioWriteNumber(self->data,
+		  (trio_uintmax_t)number,
+		  self->parameter->flags,
+		  self->parameter->width,
+		  self->parameter->precision,
+		  self->parameter->base);
+}
+
+/*************************************************************************
+ * trio_print_uint [public]
+ */
+void
+trio_print_uint
+TRIO_ARGS2((ref, number),
+	   trio_pointer_t ref,
+	   unsigned int number)
+{
+  trio_reference_t *self = (trio_reference_t *)ref;
+
+  TrioWriteNumber(self->data,
+		  (trio_uintmax_t)number,
+		  self->parameter->flags | FLAGS_UNSIGNED,
+		  self->parameter->width,
+		  self->parameter->precision,
+		  self->parameter->base);
+}
+
+/*************************************************************************
+ * trio_print_double [public]
+ */
+void
+trio_print_double
+TRIO_ARGS2((ref, number),
+	   trio_pointer_t ref,
+	   double number)
+{
+  trio_reference_t *self = (trio_reference_t *)ref;
+
+  TrioWriteDouble(self->data,
+		  number,
+		  self->parameter->flags,
+		  self->parameter->width,
+		  self->parameter->precision,
+		  self->parameter->base);
+}
+
+/*************************************************************************
+ * trio_print_string [public]
+ */
+void
+trio_print_string
+TRIO_ARGS2((ref, string),
+	   trio_pointer_t ref,
+	   char *string)
+{
+  trio_reference_t *self = (trio_reference_t *)ref;
+
+  TrioWriteString(self->data,
+		  string,
+		  self->parameter->flags,
+		  self->parameter->width,
+		  self->parameter->precision);
+}
+
+/*************************************************************************
+ * trio_print_ref [public]
+ */
+int
+trio_print_ref
+TRIO_VARGS3((ref, format, va_alist),
+	    trio_pointer_t ref,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list arglist;
+
+  assert(VALID(format));
+  
+  TRIO_VA_START(arglist, format);
+  status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+  TRIO_VA_END(arglist);
+  return status;
+}
+
+/*************************************************************************
+ * trio_vprint_ref [public]
+ */
+int
+trio_vprint_ref
+TRIO_ARGS3((ref, format, arglist),
+	   trio_pointer_t ref,
+	   TRIO_CONST char *format,
+	   va_list arglist)
+{
+  assert(VALID(format));
+  
+  return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+}
+
+/*************************************************************************
+ * trio_printv_ref [public]
+ */
+int
+trio_printv_ref
+TRIO_ARGS3((ref, format, argarray),
+	   trio_pointer_t ref,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *argarray)
+{
+  assert(VALID(format));
+  
+  return TrioFormatRef((trio_reference_t *)ref, format, NULL, argarray);
+}
+
+#endif /* TRIO_EXTENSION */
+
+/*************************************************************************
+ * trio_print_pointer [public]
+ */
+void
+trio_print_pointer
+TRIO_ARGS2((ref, pointer),
+	   trio_pointer_t ref,
+	   trio_pointer_t pointer)
+{
+  trio_reference_t *self = (trio_reference_t *)ref;
+  trio_flags_t flags;
+  trio_uintmax_t number;
+
+  if (NULL == pointer)
+    {
+      TRIO_CONST char *string = internalNullString;
+      while (*string)
+	self->data->OutStream(self->data, *string++);
+    }
+  else
+    {
+      /*
+       * The subtraction of the null pointer is a workaround
+       * to avoid a compiler warning. The performance overhead
+       * is negligible (and likely to be removed by an
+       * optimizing compiler). The (char *) casting is done
+       * to please ANSI C++.
+       */
+      number = (trio_uintmax_t)((char *)pointer - (char *)0);
+      /* Shrink to size of pointer */
+      number &= (trio_uintmax_t)-1;
+      flags = self->parameter->flags;
+      flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
+	        FLAGS_NILPADDING);
+      TrioWriteNumber(self->data,
+		      number,
+		      flags,
+		      POINTER_WIDTH,
+		      NO_PRECISION,
+		      BASE_HEX);
+    }
+}
+
+/** @} End of UserDefined documentation module */
+
+/*************************************************************************
+ *
+ * LOCALES
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ * trio_locale_set_decimal_point
+ *
+ * Decimal point can only be one character. The input argument is a
+ * string to enable multibyte characters. At most MB_LEN_MAX characters
+ * will be used.
+ */
+TRIO_PUBLIC void
+trio_locale_set_decimal_point
+TRIO_ARGS1((decimalPoint),
+	   char *decimalPoint)
+{
+#if defined(USE_LOCALE)
+  if (NULL == internalLocaleValues)
+    {
+      TrioSetLocale();
+    }
+#endif
+  internalDecimalPointLength = trio_length(decimalPoint);
+  if (internalDecimalPointLength == 1)
+    {
+      internalDecimalPoint = *decimalPoint;
+    }
+  else
+    {
+      internalDecimalPoint = NIL;
+      trio_copy_max(internalDecimalPointString,
+		    sizeof(internalDecimalPointString),
+		    decimalPoint);
+    }
+}
+
+/*************************************************************************
+ * trio_locale_set_thousand_separator
+ *
+ * See trio_locale_set_decimal_point
+ */
+TRIO_PUBLIC void
+trio_locale_set_thousand_separator
+TRIO_ARGS1((thousandSeparator),
+	   char *thousandSeparator)
+{
+#if defined(USE_LOCALE)
+  if (NULL == internalLocaleValues)
+    {
+      TrioSetLocale();
+    }
+#endif
+  trio_copy_max(internalThousandSeparator,
+		sizeof(internalThousandSeparator),
+		thousandSeparator);
+  internalThousandSeparatorLength = trio_length(internalThousandSeparator);
+}
+
+/*************************************************************************
+ * trio_locale_set_grouping
+ *
+ * Array of bytes. Reversed order.
+ *
+ *  CHAR_MAX : No further grouping
+ *  0        : Repeat last group for the remaining digits (not necessary
+ *             as C strings are zero-terminated)
+ *  n        : Set current group to n
+ *
+ * Same order as the grouping attribute in LC_NUMERIC.
+ */
+TRIO_PUBLIC void
+trio_locale_set_grouping
+TRIO_ARGS1((grouping),
+	   char *grouping)
+{
+#if defined(USE_LOCALE)
+  if (NULL == internalLocaleValues)
+    {
+      TrioSetLocale();
+    }
+#endif
+  trio_copy_max(internalGrouping,
+		sizeof(internalGrouping),
+		grouping);
+}
+
+
+/*************************************************************************
+ *
+ * SCANNING
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ * TrioSkipWhitespaces
+ */
+TRIO_PRIVATE int
+TrioSkipWhitespaces
+TRIO_ARGS1((self),
+	   trio_class_t *self)
+{
+  int ch;
+
+  ch = self->current;
+  while (isspace(ch))
+    {
+      self->InStream(self, &ch);
+    }
+  return ch;
+}
+
+/*************************************************************************
+ * TrioGetCollation
+ */
+#if TRIO_EXTENSION
+TRIO_PRIVATE void
+TrioGetCollation(TRIO_NOARGS)
+{
+  int i;
+  int j;
+  int k;
+  char first[2];
+  char second[2];
+
+  /* This is computationally expensive */
+  first[1] = NIL;
+  second[1] = NIL;
+  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+    {
+      k = 0;
+      first[0] = (char)i;
+      for (j = 0; j < MAX_CHARACTER_CLASS; j++)
+	{
+	  second[0] = (char)j;
+	  if (trio_equal_locale(first, second))
+	    internalCollationArray[i][k++] = (char)j;
+	}
+      internalCollationArray[i][k] = NIL;
+    }
+}
+#endif
+
+/*************************************************************************
+ * TrioGetCharacterClass
+ *
+ * FIXME:
+ *  multibyte
+ */
+TRIO_PRIVATE int
+TrioGetCharacterClass
+TRIO_ARGS4((format, indexPointer, flagsPointer, characterclass),
+	   TRIO_CONST char *format,
+	   int *indexPointer,
+	   trio_flags_t *flagsPointer,
+	   int *characterclass)
+{
+  int index = *indexPointer;
+  int i;
+  char ch;
+  char range_begin;
+  char range_end;
+
+  *flagsPointer &= ~FLAGS_EXCLUDE;
+
+  if (format[index] == QUALIFIER_CIRCUMFLEX)
+    {
+      *flagsPointer |= FLAGS_EXCLUDE;
+      index++;
+    }
+  /*
+   * If the ungroup character is at the beginning of the scanlist,
+   * it will be part of the class, and a second ungroup character
+   * must follow to end the group.
+   */
+  if (format[index] == SPECIFIER_UNGROUP)
+    {
+      characterclass[(int)SPECIFIER_UNGROUP]++;
+      index++;
+    }
+  /*
+   * Minus is used to specify ranges. To include minus in the class,
+   * it must be at the beginning of the list
+   */
+  if (format[index] == QUALIFIER_MINUS)
+    {
+      characterclass[(int)QUALIFIER_MINUS]++;
+      index++;
+    }
+  /* Collect characters */
+  for (ch = format[index];
+       (ch != SPECIFIER_UNGROUP) && (ch != NIL);
+       ch = format[++index])
+    {
+      switch (ch)
+	{
+	case QUALIFIER_MINUS: /* Scanlist ranges */
+	  
+	  /*
+	   * Both C99 and UNIX98 describes ranges as implementation-
+	   * defined.
+	   *
+	   * We support the following behaviour (although this may
+	   * change as we become wiser)
+	   * - only increasing ranges, ie. [a-b] but not [b-a]
+	   * - transitive ranges, ie. [a-b-c] == [a-c]
+	   * - trailing minus, ie. [a-] is interpreted as an 'a'
+	   *   and a '-'
+	   * - duplicates (although we can easily convert these
+	   *   into errors)
+	   */
+	  range_begin = format[index - 1];
+	  range_end = format[++index];
+	  if (range_end == SPECIFIER_UNGROUP)
+	    {
+	      /* Trailing minus is included */
+	      characterclass[(int)ch]++;
+	      ch = range_end;
+	      break; /* for */
+	    }
+	  if (range_end == NIL)
+	    return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+	  if (range_begin > range_end)
+	    return TRIO_ERROR_RETURN(TRIO_ERANGE, index);
+	    
+	  for (i = (int)range_begin; i <= (int)range_end; i++)
+	    characterclass[i]++;
+	    
+	  ch = range_end;
+	  break;
+	  
+#if TRIO_EXTENSION
+
+	case SPECIFIER_GROUP:
+	  
+	  switch (format[index + 1])
+	    {
+	    case QUALIFIER_DOT: /* Collating symbol */
+	      /*
+	       * FIXME: This will be easier to implement when multibyte
+	       * characters have been implemented. Until now, we ignore
+	       * this feature.
+	       */
+	      for (i = index + 2; ; i++)
+		{
+		  if (format[i] == NIL)
+		    /* Error in syntax */
+		    return -1;
+		  else if (format[i] == QUALIFIER_DOT)
+		    break; /* for */
+		}
+	      if (format[++i] != SPECIFIER_UNGROUP)
+		return -1;
+	      
+	      index = i;
+	      break;
+	  
+	    case QUALIFIER_EQUAL: /* Equivalence class expressions */
+	      {
+		unsigned int j;
+		unsigned int k;
+	    
+		if (internalCollationUnconverted)
+		  {
+		    /* Lazy evaluation of collation array */
+		    TrioGetCollation();
+		    internalCollationUnconverted = FALSE;
+		  }
+		for (i = index + 2; ; i++)
+		  {
+		    if (format[i] == NIL)
+		      /* Error in syntax */
+		      return -1;
+		    else if (format[i] == QUALIFIER_EQUAL)
+		      break; /* for */
+		    else
+		      {
+			/* Mark any equivalent character */
+			k = (unsigned int)format[i];
+			for (j = 0; internalCollationArray[k][j] != NIL; j++)
+			  characterclass[(int)internalCollationArray[k][j]]++;
+		      }
+		  }
+		if (format[++i] != SPECIFIER_UNGROUP)
+		  return -1;
+		
+		index = i;
+	      }
+	      break;
+	  
+	    case QUALIFIER_COLON: /* Character class expressions */
+	  
+	      if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
+				 &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isalnum(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_ALNUM) - 1;
+		}
+	      else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isalpha(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_ALPHA) - 1;
+		}
+	      else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (iscntrl(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_CNTRL) - 1;
+		}
+	      else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isdigit(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_DIGIT) - 1;
+		}
+	      else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isgraph(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_GRAPH) - 1;
+		}
+	      else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (islower(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_LOWER) - 1;
+		}
+	      else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isprint(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_PRINT) - 1;
+		}
+	      else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (ispunct(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_PUNCT) - 1;
+		}
+	      else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isspace(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_SPACE) - 1;
+		}
+	      else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isupper(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_UPPER) - 1;
+		}
+	      else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
+				      &format[index]))
+		{
+		  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
+		    if (isxdigit(i))
+		      characterclass[i]++;
+		  index += sizeof(CLASS_XDIGIT) - 1;
+		}
+	      else
+		{
+		  characterclass[(int)ch]++;
+		}
+	      break;
+
+	    default:
+	      characterclass[(int)ch]++;
+	      break;
+	    }
+	  break;
+	  
+#endif /* TRIO_EXTENSION */
+	  
+	default:
+	  characterclass[(int)ch]++;
+	  break;
+	}
+    }
+  return 0;
+}
+
+/*************************************************************************
+ * TrioReadNumber
+ *
+ * We implement our own number conversion in preference of strtol and
+ * strtoul, because we must handle 'long long' and thousand separators.
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioReadNumber
+TRIO_ARGS5((self, target, flags, width, base),
+	   trio_class_t *self,
+	   trio_uintmax_t *target,
+	   trio_flags_t flags,
+	   int width,
+	   int base)
+{
+  trio_uintmax_t number = 0;
+  int digit;
+  int count;
+  BOOLEAN_T isNegative = FALSE;
+  BOOLEAN_T gotNumber = FALSE;
+  int j;
+
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+  assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
+
+  if (internalDigitsUnconverted)
+    {
+      /* Lazy evaluation of digits array */
+      memset(internalDigitArray, -1, sizeof(internalDigitArray));
+      for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
+	{
+	  internalDigitArray[(int)internalDigitsLower[j]] = j;
+	  internalDigitArray[(int)internalDigitsUpper[j]] = j;
+	}
+      internalDigitsUnconverted = FALSE;
+    }
+  
+  TrioSkipWhitespaces(self);
+  
+  if (!(flags & FLAGS_UNSIGNED))
+    {
+      /* Leading sign */
+      if (self->current == '+')
+	{
+	  self->InStream(self, NULL);
+	}
+      else if (self->current == '-')
+	{
+	  self->InStream(self, NULL);
+	  isNegative = TRUE;
+	}
+    }
+  
+  count = self->processed;
+  
+  if (flags & FLAGS_ALTERNATIVE)
+    {
+      switch (base)
+	{
+	case NO_BASE:
+	case BASE_OCTAL:
+	case BASE_HEX:
+	case BASE_BINARY:
+	  if (self->current == '0')
+	    {
+	      self->InStream(self, NULL);
+	      if (self->current)
+		{
+		  if ((base == BASE_HEX) &&
+		      (trio_to_upper(self->current) == 'X'))
+		    {
+		      self->InStream(self, NULL);
+		    }
+		  else if ((base == BASE_BINARY) &&
+			   (trio_to_upper(self->current) == 'B'))
+		    {
+		      self->InStream(self, NULL);
+		    }
+		}
+	    }
+	  else
+	    return FALSE;
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  while (((width == NO_WIDTH) || (self->processed - count < width)) &&
+	 (! ((self->current == EOF) || isspace(self->current))))
+    {
+      if (isascii(self->current))
+	{
+	  digit = internalDigitArray[self->current];
+	  /* Abort if digit is not allowed in the specified base */
+	  if ((digit == -1) || (digit >= base))
+	    break;
+	}
+      else if (flags & FLAGS_QUOTE)
+	{
+	  /* Compare with thousands separator */
+	  for (j = 0; internalThousandSeparator[j] && self->current; j++)
+	    {
+	      if (internalThousandSeparator[j] != self->current)
+		break;
+
+	      self->InStream(self, NULL);
+	    }
+	  if (internalThousandSeparator[j])
+	    break; /* Mismatch */
+	  else
+	    continue; /* Match */
+	}
+      else
+	break;
+            
+      number *= base;
+      number += digit;
+      gotNumber = TRUE; /* we need at least one digit */
+
+      self->InStream(self, NULL);
+    }
+
+  /* Was anything read at all? */
+  if (!gotNumber)
+    return FALSE;
+  
+  if (target)
+    *target = (isNegative) ? -((trio_intmax_t)number) : number;
+  return TRUE;
+}
+
+/*************************************************************************
+ * TrioReadChar
+ */
+TRIO_PRIVATE int
+TrioReadChar
+TRIO_ARGS4((self, target, flags, width),
+	   trio_class_t *self,
+	   char *target,
+	   trio_flags_t flags,
+	   int width)
+{
+  int i;
+  char ch;
+  trio_uintmax_t number;
+  
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+
+  for (i = 0;
+       (self->current != EOF) && (i < width);
+       i++)
+    {
+      ch = (char)self->current;
+      self->InStream(self, NULL);
+      if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
+	{
+	  switch (self->current)
+	    {
+	    case '\\': ch = '\\'; break;
+	    case 'a': ch = '\007'; break;
+	    case 'b': ch = '\b'; break;
+	    case 'f': ch = '\f'; break;
+	    case 'n': ch = '\n'; break;
+	    case 'r': ch = '\r'; break;
+	    case 't': ch = '\t'; break;
+	    case 'v': ch = '\v'; break;
+	    default:
+	      if (isdigit(self->current))
+		{
+		  /* Read octal number */
+		  if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
+		    return 0;
+		  ch = (char)number;
+		}
+	      else if (trio_to_upper(self->current) == 'X')
+		{
+		  /* Read hexadecimal number */
+		  self->InStream(self, NULL);
+		  if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
+		    return 0;
+		  ch = (char)number;
+		}
+	      else
+		{
+		  ch = (char)self->current;
+		}
+	      break;
+	    }
+	}
+      
+      if (target)
+	target[i] = ch;
+    }
+  return i + 1;
+}
+
+/*************************************************************************
+ * TrioReadString
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioReadString
+TRIO_ARGS4((self, target, flags, width),
+	   trio_class_t *self,
+	   char *target,
+	   trio_flags_t flags,
+	   int width)
+{
+  int i;
+  
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+
+  TrioSkipWhitespaces(self);
+    
+  /*
+   * Continue until end of string is reached, a whitespace is encountered,
+   * or width is exceeded
+   */
+  for (i = 0;
+       ((width == NO_WIDTH) || (i < width)) &&
+       (! ((self->current == EOF) || isspace(self->current)));
+       i++)
+    {
+      if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
+	break; /* for */
+    }
+  if (target)
+    target[i] = NIL;
+  return TRUE;
+}
+
+/*************************************************************************
+ * TrioReadWideChar
+ */
+#if TRIO_WIDECHAR
+TRIO_PRIVATE int
+TrioReadWideChar
+TRIO_ARGS4((self, target, flags, width),
+	   trio_class_t *self,
+	   trio_wchar_t *target,
+	   trio_flags_t flags,
+	   int width)
+{
+  int i;
+  int j;
+  int size;
+  int amount = 0;
+  trio_wchar_t wch;
+  char buffer[MB_LEN_MAX + 1];
+  
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+
+  for (i = 0;
+       (self->current != EOF) && (i < width);
+       i++)
+    {
+      if (isascii(self->current))
+	{
+	  if (TrioReadChar(self, buffer, flags, 1) == 0)
+	    return 0;
+	  buffer[1] = NIL;
+	}
+      else
+	{
+	  /*
+	   * Collect a multibyte character, by enlarging buffer until
+	   * it contains a fully legal multibyte character, or the
+	   * buffer is full.
+	   */
+	  j = 0;
+	  do
+	    {
+	      buffer[j++] = (char)self->current;
+	      buffer[j] = NIL;
+	      self->InStream(self, NULL);
+	    }
+	  while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
+	}
+      if (target)
+	{
+	  size = mbtowc(&wch, buffer, sizeof(buffer));
+	  if (size > 0)
+	    target[i] = wch;
+	}
+      amount += size;
+      self->InStream(self, NULL);
+    }
+  return amount;
+}
+#endif /* TRIO_WIDECHAR */
+
+/*************************************************************************
+ * TrioReadWideString
+ */
+#if TRIO_WIDECHAR
+TRIO_PRIVATE BOOLEAN_T
+TrioReadWideString
+TRIO_ARGS4((self, target, flags, width),
+	   trio_class_t *self,
+	   trio_wchar_t *target,
+	   trio_flags_t flags,
+	   int width)
+{
+  int i;
+  int size;
+  
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+
+  TrioSkipWhitespaces(self);
+
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  (void)mblen(NULL, 0);
+#endif
+  
+  /*
+   * Continue until end of string is reached, a whitespace is encountered,
+   * or width is exceeded
+   */
+  for (i = 0;
+       ((width == NO_WIDTH) || (i < width)) &&
+       (! ((self->current == EOF) || isspace(self->current)));
+       )
+    {
+      size = TrioReadWideChar(self, &target[i], flags, 1);
+      if (size == 0)
+	break; /* for */
+
+      i += size;
+    }
+  if (target)
+    target[i] = WCONST('\0');
+  return TRUE;
+}
+#endif /* TRIO_WIDECHAR */
+
+/*************************************************************************
+ * TrioReadGroup
+ *
+ * FIXME: characterclass does not work with multibyte characters
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioReadGroup
+TRIO_ARGS5((self, target, characterclass, flags, width),
+	   trio_class_t *self,
+	   char *target,
+	   int *characterclass,
+	   trio_flags_t flags,
+	   int width)
+{
+  int ch;
+  int i;
+  
+  assert(VALID(self));
+  assert(VALID(self->InStream));
+
+  ch = self->current;
+  for (i = 0;
+       ((width == NO_WIDTH) || (i < width)) &&
+       (! ((ch == EOF) ||
+	   (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
+       i++)
+    {
+      if (target)
+	target[i] = (char)ch;
+      self->InStream(self, &ch);
+    }
+  
+  if (target)
+    target[i] = NIL;
+  return TRUE;
+}
+
+/*************************************************************************
+ * TrioReadDouble
+ *
+ * FIXME:
+ *  add long double
+ *  handle base
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioReadDouble
+TRIO_ARGS4((self, target, flags, width),
+	   trio_class_t *self,
+	   trio_pointer_t target,
+	   trio_flags_t flags,
+	   int width)
+{
+  int ch;
+  char doubleString[512];
+  int index = 0;
+  int start;
+  int j;
+  BOOLEAN_T isHex = FALSE;
+
+  doubleString[0] = 0;
+  
+  if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
+    width = sizeof(doubleString) - 1;
+  
+  TrioSkipWhitespaces(self);
+  
+  /*
+   * Read entire double number from stream. trio_to_double requires
+   * a string as input, but InStream can be anything, so we have to
+   * collect all characters.
+   */
+  ch = self->current;
+  if ((ch == '+') || (ch == '-'))
+    {
+      doubleString[index++] = (char)ch;
+      self->InStream(self, &ch);
+      width--;
+    }
+
+  start = index;
+  switch (ch)
+    {
+    case 'n':
+    case 'N':
+      /* Not-a-number */
+      if (index != 0)
+	break;
+      /* FALLTHROUGH */
+    case 'i':
+    case 'I':
+      /* Infinity */
+      while (isalpha(ch) && (index - start < width))
+	{
+	  doubleString[index++] = (char)ch;
+	  self->InStream(self, &ch);
+	}
+      doubleString[index] = NIL;
+
+      /* Case insensitive string comparison */
+      if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
+	  trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
+	{
+	  if (flags & FLAGS_LONGDOUBLE)
+	    {
+	      if ((start == 1) && (doubleString[0] == '-'))
+		{
+		  *((trio_long_double_t *)target) = trio_ninf();
+		}
+	      else
+		{
+		  *((trio_long_double_t *)target) = trio_pinf();
+		}
+	    }
+	  else
+	    {
+	      if ((start == 1) && (doubleString[0] == '-'))
+		{
+		  *((double *)target) = trio_ninf();
+		}
+	      else
+		{
+		  *((double *)target) = trio_pinf();
+		}
+	    }
+	  return TRUE;
+	}
+      if (trio_equal(doubleString, NAN_UPPER))
+	{
+	  /* NaN must not have a preceeding + nor - */
+	  if (flags & FLAGS_LONGDOUBLE)
+	    {
+	      *((trio_long_double_t *)target) = trio_nan();
+	    }
+	  else
+	    {
+	      *((double *)target) = trio_nan();
+	    }
+	  return TRUE;
+	}
+      return FALSE;
+
+    case '0':
+      doubleString[index++] = (char)ch;
+      self->InStream(self, &ch);
+      if (trio_to_upper(ch) == 'X')
+	{
+	  isHex = TRUE;
+	  doubleString[index++] = (char)ch;
+	  self->InStream(self, &ch);
+	}
+      break;
+      
+    default:
+      break;
+    }
+  
+  while ((ch != EOF) && (index - start < width))
+    {
+      /* Integer part */
+      if (isHex ? isxdigit(ch) : isdigit(ch))
+	{
+	  doubleString[index++] = (char)ch;
+	  self->InStream(self, &ch);
+	}
+      else if (flags & FLAGS_QUOTE)
+	{
+	  /* Compare with thousands separator */
+	  for (j = 0; internalThousandSeparator[j] && self->current; j++)
+	    {
+	      if (internalThousandSeparator[j] != self->current)
+		break;
+
+	      self->InStream(self, &ch);
+	    }
+	  if (internalThousandSeparator[j])
+	    break; /* Mismatch */
+	  else
+	    continue; /* Match */
+	}
+      else
+	break; /* while */
+    }
+  if (ch == '.')
+    {
+      /* Decimal part */
+      doubleString[index++] = (char)ch;
+      self->InStream(self, &ch);
+      while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
+	     (index - start < width))
+	{
+	  doubleString[index++] = (char)ch;
+	  self->InStream(self, &ch);
+	}
+      if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))
+	{
+	  /* Exponent */
+	  doubleString[index++] = (char)ch;
+	  self->InStream(self, &ch);
+	  if ((ch == '+') || (ch == '-'))
+	    {
+	      doubleString[index++] = (char)ch;
+	      self->InStream(self, &ch);
+	    }
+	  while (isdigit(ch) && (index - start < width))
+	    {
+	      doubleString[index++] = (char)ch;
+	      self->InStream(self, &ch);
+	    }
+	}
+    }
+
+  if ((index == start) || (*doubleString == NIL))
+    return FALSE;
+
+  doubleString[index] = 0;
+  
+  if (flags & FLAGS_LONGDOUBLE)
+    {
+      *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
+    }
+  else
+    {
+      *((double *)target) = trio_to_double(doubleString, NULL);
+    }
+  return TRUE;
+}
+
+/*************************************************************************
+ * TrioReadPointer
+ */
+TRIO_PRIVATE BOOLEAN_T
+TrioReadPointer
+TRIO_ARGS3((self, target, flags),
+	   trio_class_t *self,
+	   trio_pointer_t *target,
+	   trio_flags_t flags)
+{
+  trio_uintmax_t number;
+  char buffer[sizeof(internalNullString)];
+
+  flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
+  
+  if (TrioReadNumber(self,
+		     &number,
+		     flags,
+		     POINTER_WIDTH,
+		     BASE_HEX))
+    {
+      /*
+       * The strange assignment of number is a workaround for a compiler
+       * warning
+       */
+      if (target)
+	*target = (char *)0 + number;
+      return TRUE;
+    }
+  else if (TrioReadString(self,
+			  (flags & FLAGS_IGNORE)
+			  ? NULL
+			  : buffer,
+			  0,
+			  sizeof(internalNullString) - 1))
+    {  
+      if (trio_equal_case(buffer, internalNullString))
+	{
+	  if (target)
+	    *target = NULL;
+	  return TRUE;
+	}
+    }
+  return FALSE;
+}
+
+/*************************************************************************
+ * TrioScanProcess
+ */
+TRIO_PRIVATE int
+TrioScanProcess
+TRIO_ARGS3((data, format, parameters),
+	   trio_class_t *data,
+	   TRIO_CONST char *format,
+	   trio_parameter_t *parameters)
+{
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  int charlen;
+  int cnt;
+#endif
+  int assignment;
+  int ch;
+  int index; /* Index of format string */
+  int i; /* Index of current parameter */
+  trio_flags_t flags;
+  int width;
+  int base;
+  trio_pointer_t pointer;
+
+  assignment = 0;
+  i = 0;
+  index = 0;
+  data->InStream(data, &ch);
+
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+  (void)mblen(NULL, 0);
+#endif
+
+  while (format[index])
+    {
+#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
+      if (! isascii(format[index]))
+	{
+	  charlen = mblen(&format[index], MB_LEN_MAX);
+	  if (charlen != -1)
+	    {
+	      /* Compare multibyte characters in format string */
+	      for (cnt = 0; cnt < charlen - 1; cnt++)
+		{
+		  if (ch != format[index + cnt])
+		    {
+		      return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+		    }
+		  data->InStream(data, &ch);
+		}
+	      continue; /* while characters left in formatting string */
+	    }
+	}
+#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
+      
+      if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
+	{
+	  return (assignment > 0) ? assignment : EOF;
+	}
+      
+      if (CHAR_IDENTIFIER == format[index])
+	{
+	  if (CHAR_IDENTIFIER == format[index + 1])
+	    {
+	      /* Two % in format matches one % in input stream */
+	      if (CHAR_IDENTIFIER == ch)
+		{
+		  data->InStream(data, &ch);
+		  index += 2;
+		  continue; /* while format chars left */
+		}
+	      else
+		return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+	    }
+
+	  /* Skip the parameter entries */
+	  while (parameters[i].type == FORMAT_PARAMETER)
+	    i++;
+	  
+	  flags = parameters[i].flags;
+	  /* Find width */
+	  width = parameters[i].width;
+	  if (flags & FLAGS_WIDTH_PARAMETER)
+	    {
+	      /* Get width from parameter list */
+	      width = (int)parameters[width].data.number.as_signed;
+	    }
+	  /* Find base */
+	  base = parameters[i].base;
+	  if (flags & FLAGS_BASE_PARAMETER)
+	    {
+	      /* Get base from parameter list */
+	      base = (int)parameters[base].data.number.as_signed;
+	    }
+	  
+	  switch (parameters[i].type)
+	    {
+	    case FORMAT_INT:
+	      {
+		trio_uintmax_t number;
+
+		if (0 == base)
+		  base = BASE_DECIMAL;
+
+		if (!TrioReadNumber(data,
+				    &number,
+				    flags,
+				    width,
+				    base))
+		  return assignment;
+
+		if (!(flags & FLAGS_IGNORE))
+		  {
+		    assignment++;
+
+		    pointer = parameters[i].data.pointer;
+#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
+		    if (flags & FLAGS_SIZE_T)
+		      *(size_t *)pointer = (size_t)number;
+		    else
+#endif
+#if defined(QUALIFIER_PTRDIFF_T)
+		    if (flags & FLAGS_PTRDIFF_T)
+		      *(ptrdiff_t *)pointer = (ptrdiff_t)number;
+		    else
+#endif
+#if defined(QUALIFIER_INTMAX_T)
+		    if (flags & FLAGS_INTMAX_T)
+		      *(trio_intmax_t *)pointer = (trio_intmax_t)number;
+		    else
+#endif
+		    if (flags & FLAGS_QUAD)
+		      *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
+		    else if (flags & FLAGS_LONG)
+		      *(long int *)pointer = (long int)number;
+		    else if (flags & FLAGS_SHORT)
+		      *(short int *)pointer = (short int)number;
+		    else
+		      *(int *)pointer = (int)number;
+		  }
+	      }
+	      break; /* FORMAT_INT */
+	      
+	    case FORMAT_STRING:
+#if TRIO_WIDECHAR
+	      if (flags & FLAGS_WIDECHAR)
+		{
+		  if (!TrioReadWideString(data,
+					  (flags & FLAGS_IGNORE)
+					  ? NULL
+					  : parameters[i].data.wstring,
+					  flags,
+					  width))
+		    return assignment;
+		}
+	      else
+#endif
+		{
+		  if (!TrioReadString(data,
+				      (flags & FLAGS_IGNORE)
+				      ? NULL
+				      : parameters[i].data.string,
+				      flags,
+				      width))
+		    return assignment;
+		}
+	      if (!(flags & FLAGS_IGNORE))
+		assignment++;
+	      break; /* FORMAT_STRING */
+
+	    case FORMAT_DOUBLE:
+	      {
+		trio_pointer_t pointer;
+
+		if (flags & FLAGS_IGNORE)
+		  {
+		    pointer = NULL;
+		  }
+		else
+		  {
+		    pointer = (flags & FLAGS_LONGDOUBLE)
+		      ? (trio_pointer_t)parameters[i].data.longdoublePointer
+		      : (trio_pointer_t)parameters[i].data.doublePointer;
+		  }
+		if (!TrioReadDouble(data, pointer, flags, width))
+		  {
+		    return assignment;
+		  }
+		if (!(flags & FLAGS_IGNORE))
+		  {
+		    assignment++;
+		  }
+		break; /* FORMAT_DOUBLE */
+	      }
+	    case FORMAT_GROUP:
+	      {
+		int characterclass[MAX_CHARACTER_CLASS + 1];
+		int rc;
+
+		/* Skip over modifiers */
+		while (format[index] != SPECIFIER_GROUP)
+		  {
+		    index++;
+		  }
+		/* Skip over group specifier */
+		index++;
+		
+		memset(characterclass, 0, sizeof(characterclass));
+		rc = TrioGetCharacterClass(format,
+					   &index,
+					   &flags,
+					   characterclass);
+		if (rc < 0)
+		  return rc;
+
+		if (!TrioReadGroup(data,
+				   (flags & FLAGS_IGNORE)
+				   ? NULL
+				   : parameters[i].data.string,
+				   characterclass,
+				   flags,
+				   parameters[i].width))
+		  return assignment;
+		if (!(flags & FLAGS_IGNORE))
+		  assignment++;
+	      }
+	      break; /* FORMAT_GROUP */
+
+	    case FORMAT_COUNT:
+	      pointer = parameters[i].data.pointer;
+	      if (NULL != pointer)
+		{
+		  int count = data->committed;
+		  if (ch != EOF)
+		    count--; /* a character is read, but is not consumed yet */
+#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
+		  if (flags & FLAGS_SIZE_T)
+		    *(size_t *)pointer = (size_t)count;
+		  else
+#endif
+#if defined(QUALIFIER_PTRDIFF_T)
+		  if (flags & FLAGS_PTRDIFF_T)
+		    *(ptrdiff_t *)pointer = (ptrdiff_t)count;
+		  else
+#endif
+#if defined(QUALIFIER_INTMAX_T)
+		  if (flags & FLAGS_INTMAX_T)
+		    *(trio_intmax_t *)pointer = (trio_intmax_t)count;
+		  else
+#endif
+		  if (flags & FLAGS_QUAD)
+		    {
+		      *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
+		    }
+		  else if (flags & FLAGS_LONG)
+		    {
+		      *(long int *)pointer = (long int)count;
+		    }
+		  else if (flags & FLAGS_SHORT)
+		    {
+		      *(short int *)pointer = (short int)count;
+		    }
+		  else
+		    {
+		      *(int *)pointer = (int)count;
+		    }
+		}
+	      break; /* FORMAT_COUNT */
+	      
+	    case FORMAT_CHAR:
+#if TRIO_WIDECHAR
+	      if (flags & FLAGS_WIDECHAR)
+		{
+		  if (TrioReadWideChar(data,
+				       (flags & FLAGS_IGNORE)
+				       ? NULL
+				       : parameters[i].data.wstring,
+				       flags,
+				       (width == NO_WIDTH) ? 1 : width) == 0)
+		    return assignment;
+		}
+	      else
+#endif
+		{
+		  if (TrioReadChar(data,
+				   (flags & FLAGS_IGNORE)
+				   ? NULL
+				   : parameters[i].data.string,
+				   flags,
+				   (width == NO_WIDTH) ? 1 : width) == 0)
+		    return assignment;
+		}
+	      if (!(flags & FLAGS_IGNORE))
+		assignment++;
+	      break; /* FORMAT_CHAR */
+
+	    case FORMAT_POINTER:
+	      if (!TrioReadPointer(data,
+				   (flags & FLAGS_IGNORE)
+				   ? NULL
+				   : (trio_pointer_t *)parameters[i].data.pointer,
+				   flags))
+		return assignment;
+	      if (!(flags & FLAGS_IGNORE))
+		assignment++;
+	      break; /* FORMAT_POINTER */
+
+	    case FORMAT_PARAMETER:
+	      break; /* FORMAT_PARAMETER */
+
+	    default:
+	      return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+	    }
+	  ch = data->current;
+	  index = parameters[i].indexAfterSpecifier;
+	  i++;
+	}
+      else /* Not an % identifier */
+	{
+	  if (isspace((int)format[index]))
+	    {
+	      /* Whitespaces may match any amount of whitespaces */
+	      ch = TrioSkipWhitespaces(data);
+	    }
+	  else if (ch == format[index])
+	    {
+	      data->InStream(data, &ch);
+	    }
+	  else
+	    return assignment;
+	  
+	  index++;
+	}
+    }
+  return assignment;
+}
+
+/*************************************************************************
+ * TrioScan
+ */
+TRIO_PRIVATE int
+TrioScan
+TRIO_ARGS6((source, sourceSize, InStream, format, arglist, argarray),
+	   trio_pointer_t source,
+	   size_t sourceSize,
+	   void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
+	   TRIO_CONST char *format,
+	   va_list *arglist,
+	   trio_pointer_t *argarray)
+{
+  int status;
+  trio_parameter_t parameters[MAX_PARAMETERS];
+  trio_class_t data;
+
+  assert(VALID(InStream));
+  assert(VALID(format));
+
+  memset(&data, 0, sizeof(data));
+  data.InStream = InStream;
+  data.location = (trio_pointer_t)source;
+  data.max = sourceSize;
+  data.error = 0;
+
+#if defined(USE_LOCALE)
+  if (NULL == internalLocaleValues)
+    {
+      TrioSetLocale();
+    }
+#endif
+  
+  status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
+  if (status < 0)
+    return status;
+
+  status = TrioScanProcess(&data, format, parameters);
+  if (data.error != 0)
+    {
+      status = data.error;
+    }
+  return status;
+}
+
+/*************************************************************************
+ * TrioInStreamFile
+ */
+TRIO_PRIVATE void
+TrioInStreamFile
+TRIO_ARGS2((self, intPointer),
+	   trio_class_t *self,
+	   int *intPointer)
+{
+  FILE *file = (FILE *)self->location;
+
+  assert(VALID(self));
+  assert(VALID(file));
+
+  self->current = fgetc(file);
+  if (self->current == EOF)
+    {
+      self->error = (ferror(file))
+	? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
+	: TRIO_ERROR_RETURN(TRIO_EOF, 0);
+    }
+  else
+    {
+      self->processed++;
+      self->committed++;
+    }
+  
+  if (VALID(intPointer))
+    {
+      *intPointer = self->current;
+    }
+}
+
+/*************************************************************************
+ * TrioInStreamFileDescriptor
+ */
+TRIO_PRIVATE void
+TrioInStreamFileDescriptor
+TRIO_ARGS2((self, intPointer),
+	   trio_class_t *self,
+	   int *intPointer)
+{
+  int fd = *((int *)self->location);
+  int size;
+  unsigned char input;
+
+  assert(VALID(self));
+
+  size = read(fd, &input, sizeof(char));
+  if (size == -1)
+    {
+      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
+      self->current = EOF;
+    }
+  else
+    {
+      self->current = (size == 0) ? EOF : input;
+    }
+  if (self->current != EOF)
+    {
+      self->committed++;
+      self->processed++;
+    }
+  
+  if (VALID(intPointer))
+    {
+      *intPointer = self->current;
+    }
+}
+
+/*************************************************************************
+ * TrioInStreamCustom
+ */
+TRIO_PRIVATE void
+TrioInStreamCustom
+TRIO_ARGS2((self, intPointer),
+	   trio_class_t *self,
+	   int *intPointer)
+{
+  trio_custom_t *data;
+  
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  data = (trio_custom_t *)self->location;
+
+  self->current = (data->stream.in == NULL)
+    ? NIL
+    : (data->stream.in)(data->closure);
+  
+  if (self->current == NIL)
+    {
+      self->current = EOF;
+    }
+  else
+    {
+      self->processed++;
+      self->committed++;
+    }
+  
+  if (VALID(intPointer))
+    {
+      *intPointer = self->current;
+    }
+}
+
+/*************************************************************************
+ * TrioInStreamString
+ */
+TRIO_PRIVATE void
+TrioInStreamString
+TRIO_ARGS2((self, intPointer),
+	   trio_class_t *self,
+	   int *intPointer)
+{
+  unsigned char **buffer;
+
+  assert(VALID(self));
+  assert(VALID(self->location));
+
+  buffer = (unsigned char **)self->location;
+  self->current = (*buffer)[0];
+  if (self->current == NIL)
+    {
+      self->current = EOF;
+    }
+  else
+    {
+      (*buffer)++;
+      self->processed++;
+      self->committed++;
+    }
+  
+  if (VALID(intPointer))
+    {
+      *intPointer = self->current;
+    }
+}
+
+/*************************************************************************
+ *
+ * Formatted scanning functions
+ *
+ ************************************************************************/
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_scanf.h"
+#endif
+/** @addtogroup Scanf
+    @{
+*/
+
+/*************************************************************************
+ * scanf
+ */
+
+/**
+   Scan characters from standard input stream.
+
+   @param format Formatting string.
+   @param ... Arguments.
+   @return Number of scanned characters.
+ */
+TRIO_PUBLIC int
+trio_scanf
+TRIO_VARGS2((format, va_alist),
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioScan((trio_pointer_t)stdin, 0,
+		    TrioInStreamFile,
+		    format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vscanf
+TRIO_ARGS2((format, args),
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)stdin, 0,
+		  TrioInStreamFile,
+		  format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_scanfv
+TRIO_ARGS2((format, args),
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)stdin, 0,
+		  TrioInStreamFile,
+		  format, NULL, args);
+}
+
+/*************************************************************************
+ * fscanf
+ */
+TRIO_PUBLIC int
+trio_fscanf
+TRIO_VARGS3((file, format, va_alist),
+	    FILE *file,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioScan((trio_pointer_t)file, 0,
+		    TrioInStreamFile,
+		    format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vfscanf
+TRIO_ARGS3((file, format, args),
+	   FILE *file,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)file, 0,
+		  TrioInStreamFile,
+		  format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_fscanfv
+TRIO_ARGS3((file, format, args),
+	   FILE *file,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  assert(VALID(file));
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)file, 0,
+		  TrioInStreamFile,
+		  format, NULL, args);
+}
+
+/*************************************************************************
+ * dscanf
+ */
+TRIO_PUBLIC int
+trio_dscanf
+TRIO_VARGS3((fd, format, va_alist),
+	    int fd,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioScan((trio_pointer_t)&fd, 0,
+		    TrioInStreamFileDescriptor,
+		    format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vdscanf
+TRIO_ARGS3((fd, format, args),
+	   int fd,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)&fd, 0,
+		  TrioInStreamFileDescriptor,
+		  format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_dscanfv
+TRIO_ARGS3((fd, format, args),
+	   int fd,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)&fd, 0,
+		  TrioInStreamFileDescriptor,
+		  format, NULL, args);
+}
+
+/*************************************************************************
+ * cscanf
+ */
+TRIO_PUBLIC int
+trio_cscanf
+TRIO_VARGS4((stream, closure, format, va_alist),
+	    trio_instream_t stream,
+	    trio_pointer_t closure,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+  trio_custom_t data;
+
+  assert(VALID(stream));
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  data.stream.in = stream;
+  data.closure = closure;
+  status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vcscanf
+TRIO_ARGS4((stream, closure, format, args),
+	   trio_instream_t stream,
+	   trio_pointer_t closure,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  trio_custom_t data;
+  
+  assert(VALID(stream));
+  assert(VALID(format));
+
+  data.stream.in = stream;
+  data.closure = closure;
+  return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_cscanfv
+TRIO_ARGS4((stream, closure, format, args),
+	   trio_instream_t stream,
+	   trio_pointer_t closure,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  trio_custom_t data;
+  
+  assert(VALID(stream));
+  assert(VALID(format));
+
+  data.stream.in = stream;
+  data.closure = closure;
+  return TrioScan(&data, 0, TrioInStreamCustom, format, NULL, args);
+}
+
+/*************************************************************************
+ * sscanf
+ */
+TRIO_PUBLIC int
+trio_sscanf
+TRIO_VARGS3((buffer, format, va_alist),
+	    TRIO_CONST char *buffer,
+	    TRIO_CONST char *format,
+	    TRIO_VA_DECL)
+{
+  int status;
+  va_list args;
+
+  assert(VALID(buffer));
+  assert(VALID(format));
+  
+  TRIO_VA_START(args, format);
+  status = TrioScan((trio_pointer_t)&buffer, 0,
+		    TrioInStreamString,
+		    format, &args, NULL);
+  TRIO_VA_END(args);
+  return status;
+}
+
+TRIO_PUBLIC int
+trio_vsscanf
+TRIO_ARGS3((buffer, format, args),
+	   TRIO_CONST char *buffer,
+	   TRIO_CONST char *format,
+	   va_list args)
+{
+  assert(VALID(buffer));
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)&buffer, 0,
+		  TrioInStreamString,
+		  format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_sscanfv
+TRIO_ARGS3((buffer, format, args),
+	   TRIO_CONST char *buffer,
+	   TRIO_CONST char *format,
+	   trio_pointer_t *args)
+{
+  assert(VALID(buffer));
+  assert(VALID(format));
+  
+  return TrioScan((trio_pointer_t)&buffer, 0,
+		  TrioInStreamString,
+		  format, NULL, args);
+}
+
+/** @} End of Scanf documentation module */
+
+/*************************************************************************
+ * trio_strerror
+ */
+TRIO_PUBLIC TRIO_CONST char *
+trio_strerror
+TRIO_ARGS1((errorcode),
+	   int errorcode)
+{
+  /* Textual versions of the error codes */
+  switch (TRIO_ERROR_CODE(errorcode))
+    {
+    case TRIO_EOF:
+      return "End of file";
+    case TRIO_EINVAL:
+      return "Invalid argument";
+    case TRIO_ETOOMANY:
+      return "Too many arguments";
+    case TRIO_EDBLREF:
+      return "Double reference";
+    case TRIO_EGAP:
+      return "Reference gap";
+    case TRIO_ENOMEM:
+      return "Out of memory";
+    case TRIO_ERANGE:
+      return "Invalid range";
+    case TRIO_ECUSTOM:
+      return "Custom error";
+    default:
+      return "Unknown";
+    }
+}
diff --git a/src/trio.h b/src/trio.h
new file mode 100644
index 0000000..eab1b6d
--- /dev/null
+++ b/src/trio.h
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ *************************************************************************
+ *
+ * http://ctrio.sourceforge.net/
+ *
+ ************************************************************************/
+
+#ifndef TRIO_TRIO_H
+#define TRIO_TRIO_H
+
+#if !defined(WITHOUT_TRIO)
+
+/*
+ * Use autoconf defines if present. Packages using trio must define
+ * HAVE_CONFIG_H as a compiler option themselves.
+ */
+#if defined(HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include "triodef.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Error codes.
+ *
+ * Remember to add a textual description to trio_strerror.
+ */
+enum {
+  TRIO_EOF      = 1,
+  TRIO_EINVAL   = 2,
+  TRIO_ETOOMANY = 3,
+  TRIO_EDBLREF  = 4,
+  TRIO_EGAP     = 5,
+  TRIO_ENOMEM   = 6,
+  TRIO_ERANGE   = 7,
+  TRIO_ERRNO    = 8,
+  TRIO_ECUSTOM  = 9
+};
+
+/* Error macros */
+#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
+#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
+#define TRIO_ERROR_NAME(x) trio_strerror(x)
+
+typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
+typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
+
+TRIO_CONST char *trio_strerror TRIO_PROTO((int));
+
+/*************************************************************************
+ * Print Functions
+ */
+
+int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
+int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
+int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
+
+int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
+int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
+int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
+
+int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
+int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
+int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
+
+int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+			     TRIO_CONST char *format, ...));
+int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+			      TRIO_CONST char *format, va_list args));
+int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+			      TRIO_CONST char *format, void **args));
+
+int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
+int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
+int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
+
+int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
+int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+		   va_list args));
+int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+		   void **args));
+
+int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
+int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+                      va_list args));
+
+char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
+char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
+
+int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
+int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
+
+/*************************************************************************
+ * Scan Functions
+ */
+int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
+int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
+int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
+
+int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
+int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
+int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
+
+int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
+int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
+int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
+
+int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+			    TRIO_CONST char *format, ...));
+int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+			     TRIO_CONST char *format, va_list args));
+int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+			     TRIO_CONST char *format, void **args));
+
+int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
+int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
+int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
+
+/*************************************************************************
+ * Locale Functions
+ */
+void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
+void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
+void trio_locale_set_grouping TRIO_PROTO((char *grouping));
+
+/*************************************************************************
+ * Renaming
+ */
+#ifdef TRIO_REPLACE_STDIO
+/* Replace the <stdio.h> functions */
+#ifndef HAVE_PRINTF
+# define printf trio_printf
+#endif
+#ifndef HAVE_VPRINTF
+# define vprintf trio_vprintf
+#endif
+#ifndef HAVE_FPRINTF
+# define fprintf trio_fprintf
+#endif
+#ifndef HAVE_VFPRINTF
+# define vfprintf trio_vfprintf
+#endif
+#ifndef HAVE_SPRINTF
+# define sprintf trio_sprintf
+#endif
+#ifndef HAVE_VSPRINTF
+# define vsprintf trio_vsprintf
+#endif
+#ifndef HAVE_SNPRINTF
+# define snprintf trio_snprintf
+#endif
+#ifndef HAVE_VSNPRINTF
+# define vsnprintf trio_vsnprintf
+#endif
+#ifndef HAVE_SCANF
+# define scanf trio_scanf
+#endif
+#ifndef HAVE_VSCANF
+# define vscanf trio_vscanf
+#endif
+#ifndef HAVE_FSCANF
+# define fscanf trio_fscanf
+#endif
+#ifndef HAVE_VFSCANF
+# define vfscanf trio_vfscanf
+#endif
+#ifndef HAVE_SSCANF
+# define sscanf trio_sscanf
+#endif
+#ifndef HAVE_VSSCANF
+# define vsscanf trio_vsscanf
+#endif
+/* These aren't stdio functions, but we make them look similar */
+#define dprintf trio_dprintf
+#define vdprintf trio_vdprintf
+#define aprintf trio_aprintf
+#define vaprintf trio_vaprintf
+#define asprintf trio_asprintf
+#define vasprintf trio_vasprintf
+#define dscanf trio_dscanf
+#define vdscanf trio_vdscanf
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* WITHOUT_TRIO */
+
+#endif /* TRIO_TRIO_H */
diff --git a/src/triodef.h b/src/triodef.h
new file mode 100644
index 0000000..fa89416
--- /dev/null
+++ b/src/triodef.h
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************/
+
+#ifndef TRIO_TRIODEF_H
+#define TRIO_TRIODEF_H
+
+/*************************************************************************
+ * Platform and compiler support detection
+ */
+#if defined(__GNUC__)
+# define TRIO_COMPILER_GCC
+#elif defined(__SUNPRO_C)
+# define TRIO_COMPILER_SUNPRO
+#elif defined(__SUNPRO_CC)
+# define TRIO_COMPILER_SUNPRO
+# define __SUNPRO_C __SUNPRO_CC
+#elif defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
+# define TRIO_COMPILER_XLC
+#elif defined(_AIX) && !defined(__GNUC__)
+# define TRIO_COMPILER_XLC /* Workaround for old xlc */
+#elif defined(__DECC) || defined(__DECCXX)
+# define TRIO_COMPILER_DECC
+#elif defined(__osf__) && defined(__LANGUAGE_C__)
+# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
+#elif defined(_MSC_VER)
+# define TRIO_COMPILER_MSVC
+#elif defined(__BORLANDC__)
+# define TRIO_COMPILER_BCB
+#endif
+
+#if defined(VMS) || defined(__VMS)
+/*
+ * VMS is placed first to avoid identifying the platform as Unix
+ * based on the DECC compiler later on.
+ */
+# define TRIO_PLATFORM_VMS
+#elif defined(unix) || defined(__unix) || defined(__unix__)
+# define TRIO_PLATFORM_UNIX
+#elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
+# define TRIO_PLATFORM_UNIX
+#elif defined(TRIO_COMPILER_DECC) || defined(__osf___)
+# define TRIO_PLATFORM_UNIX
+#elif defined(__NetBSD__)
+# define TRIO_PLATFORM_UNIX
+#elif defined(__Lynx__)
+# define TRIO_PLATFORM_UNIX
+#elif defined(__QNX__)
+# define TRIO_PLATFORM_UNIX
+# define TRIO_PLATFORM_QNX
+#elif defined(__CYGWIN__)
+# define TRIO_PLATFORM_UNIX
+#elif defined(AMIGA) && defined(TRIO_COMPILER_GCC)
+# define TRIO_PLATFORM_UNIX
+#elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
+# define TRIO_PLATFORM_WIN32
+#elif defined(mpeix) || defined(__mpexl)
+# define TRIO_PLATFORM_MPEIX
+#endif
+
+#if defined(_AIX)
+# define TRIO_PLATFORM_AIX
+#elif defined(__hpux)
+# define TRIO_PLATFORM_HPUX
+#elif defined(sun) || defined(__sun__)
+# if defined(__SVR4) || defined(__svr4__)
+#  define TRIO_PLATFORM_SOLARIS
+# else
+#  define TRIO_PLATFORM_SUNOS
+# endif
+#endif
+
+#if defined(__STDC__) || defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
+# define TRIO_COMPILER_SUPPORTS_C89
+# if defined(__STDC_VERSION__)
+#  define TRIO_COMPILER_SUPPORTS_C90
+#  if (__STDC_VERSION__ >= 199409L)
+#   define TRIO_COMPILER_SUPPORTS_C94
+#  endif
+#  if (__STDC_VERSION__ >= 199901L)
+#   define TRIO_COMPILER_SUPPORTS_C99
+#  endif
+# elif defined(TRIO_COMPILER_SUNPRO)
+#  if (__SUNPRO_C >= 0x420)
+#   define TRIO_COMPILER_SUPPORTS_C94
+#  endif
+# endif
+#endif
+
+#if defined(_XOPEN_SOURCE)
+# if defined(_XOPEN_SOURCE_EXTENDED)
+#  define TRIO_COMPILER_SUPPORTS_UNIX95
+# endif
+# if (_XOPEN_VERSION >= 500)
+#  define TRIO_COMPILER_SUPPORTS_UNIX98
+# endif
+# if (_XOPEN_VERSION >= 600)
+#  define TRIO_COMPILER_SUPPORTS_UNIX01
+# endif
+#endif
+
+/*************************************************************************
+ * Generic defines
+ */
+
+#if !defined(TRIO_PUBLIC)
+# define TRIO_PUBLIC
+#endif
+#if !defined(TRIO_PRIVATE)
+# define TRIO_PRIVATE static
+#endif
+
+#if !(defined(TRIO_COMPILER_SUPPORTS_C89) || defined(__cplusplus))
+# define TRIO_COMPILER_ANCIENT
+#endif
+
+#if defined(TRIO_COMPILER_ANCIENT)
+# define TRIO_CONST
+# define TRIO_VOLATILE
+# define TRIO_SIGNED
+typedef double trio_long_double_t;
+typedef char * trio_pointer_t;
+# define TRIO_SUFFIX_LONG(x) x
+# define TRIO_PROTO(x) ()
+# define TRIO_NOARGS
+# define TRIO_ARGS1(list,a1) list a1;
+# define TRIO_ARGS2(list,a1,a2) list a1; a2;
+# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
+# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
+# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
+# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
+# define TRIO_VARGS2(list,a1,a2) list a1; a2
+# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
+# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
+# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
+# define TRIO_VA_DECL va_dcl
+# define TRIO_VA_START(x,y) va_start(x)
+# define TRIO_VA_END(x) va_end(x)
+#else /* ANSI C */
+# define TRIO_CONST const
+# define TRIO_VOLATILE volatile
+# define TRIO_SIGNED signed
+typedef long double trio_long_double_t;
+typedef void * trio_pointer_t;
+# define TRIO_SUFFIX_LONG(x) x ## L
+# define TRIO_PROTO(x) x
+# define TRIO_NOARGS void
+# define TRIO_ARGS1(list,a1) (a1)
+# define TRIO_ARGS2(list,a1,a2) (a1,a2)
+# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
+# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
+# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
+# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
+# define TRIO_VARGS2 TRIO_ARGS2
+# define TRIO_VARGS3 TRIO_ARGS3
+# define TRIO_VARGS4 TRIO_ARGS4
+# define TRIO_VARGS5 TRIO_ARGS5
+# define TRIO_VA_DECL ...
+# define TRIO_VA_START(x,y) va_start(x,y)
+# define TRIO_VA_END(x) va_end(x)
+#endif
+
+#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus)
+# define TRIO_INLINE inline
+#elif defined(TRIO_COMPILER_GCC)
+# define TRIO_INLINE __inline__
+#elif defined(TRIO_COMPILER_MSVC)
+# define TRIO_INLINE _inline
+#elif defined(TRIO_COMPILER_BCB)
+# define TRIO_INLINE __inline
+#else
+# define TRIO_INLINE
+#endif
+
+/*************************************************************************
+ * Workarounds
+ */
+
+#if defined(TRIO_PLATFORM_VMS)
+/*
+ * Computations done with constants at compile time can trigger these
+ * even when compiling with IEEE enabled.
+ */
+# pragma message disable (UNDERFLOW, FLOATOVERFL)
+
+# if (__CRTL_VER < 80000000)
+/*
+ * Although the compiler supports C99 language constructs, the C
+ * run-time library does not contain all C99 functions.
+ *
+ * This was the case for 70300022. Update the 80000000 value when
+ * it has been accurately determined what version of the library
+ * supports C99.
+ */
+#  if defined(TRIO_COMPILER_SUPPORTS_C99)
+#   undef TRIO_COMPILER_SUPPORTS_C99
+#  endif
+# endif
+#endif
+
+/*
+ * Not all preprocessors supports the LL token.
+ */
+#if defined(TRIO_COMPILER_BCB)
+#else
+# define TRIO_COMPILER_SUPPORTS_LL
+#endif
+
+#endif /* TRIO_TRIODEF_H */
diff --git a/src/trionan.c b/src/trionan.c
new file mode 100644
index 0000000..95baae1
--- /dev/null
+++ b/src/trionan.c
@@ -0,0 +1,914 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************
+ *
+ * Functions to handle special quantities in floating-point numbers
+ * (that is, NaNs and infinity). They provide the capability to detect
+ * and fabricate special quantities.
+ *
+ * Although written to be as portable as possible, it can never be
+ * guaranteed to work on all platforms, as not all hardware supports
+ * special quantities.
+ *
+ * The approach used here (approximately) is to:
+ *
+ *   1. Use C99 functionality when available.
+ *   2. Use IEEE 754 bit-patterns if possible.
+ *   3. Use platform-specific techniques.
+ *
+ ************************************************************************/
+
+/*
+ * TODO:
+ *  o Put all the magic into trio_fpclassify_and_signbit(), and use this from
+ *    trio_isnan() etc.
+ */
+
+/*************************************************************************
+ * Include files
+ */
+#include "triodef.h"
+#include "trionan.h"
+
+#include <math.h>
+#include <string.h>
+#include <limits.h>
+#include <float.h>
+#if defined(TRIO_PLATFORM_UNIX)
+# include <signal.h>
+#endif
+#if defined(TRIO_COMPILER_DECC)
+#  if defined(__linux__)
+#   include <cpml.h>
+#  else
+#   include <fp_class.h>
+#  endif
+#endif
+#include <assert.h>
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_nan.h"
+#endif
+/** @addtogroup SpecialQuantities
+    @{
+*/
+
+/*************************************************************************
+ * Definitions
+ */
+
+#define TRIO_TRUE (1 == 1)
+#define TRIO_FALSE (0 == 1)
+
+/*
+ * We must enable IEEE floating-point on Alpha
+ */
+#if defined(__alpha) && !defined(_IEEE_FP)
+# if defined(TRIO_COMPILER_DECC)
+#  if defined(TRIO_PLATFORM_VMS)
+#   error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
+#  else
+#   if !defined(_CFE)
+#    error "Must be compiled with option -ieee"
+#   endif
+#  endif
+# elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
+#  error "Must be compiled with option -mieee"
+# endif
+#endif /* __alpha && ! _IEEE_FP */
+
+/*
+ * In ANSI/IEEE 754-1985 64-bits double format numbers have the
+ * following properties (amoungst others)
+ *
+ *   o FLT_RADIX == 2: binary encoding
+ *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
+ *     to indicate special numbers (e.g. NaN and Infinity), so the
+ *     maximum exponent is 10 bits wide (2^10 == 1024).
+ *   o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
+ *     numbers are normalized the initial binary 1 is represented
+ *     implicitly (the so-called "hidden bit"), which leaves us with
+ *     the ability to represent 53 bits wide mantissa.
+ */
+#if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53)
+# define USE_IEEE_754
+#endif
+
+
+/*************************************************************************
+ * Constants
+ */
+
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
+
+#if defined(USE_IEEE_754)
+
+/*
+ * Endian-agnostic indexing macro.
+ *
+ * The value of internalEndianMagic, when converted into a 64-bit
+ * integer, becomes 0x0706050403020100 (we could have used a 64-bit
+ * integer value instead of a double, but not all platforms supports
+ * that type). The value is automatically encoded with the correct
+ * endianess by the compiler, which means that we can support any
+ * kind of endianess. The individual bytes are then used as an index
+ * for the IEEE 754 bit-patterns and masks.
+ */
+#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
+
+#if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0590)
+static TRIO_CONST double internalEndianMagic = 7.949928895127362e-275;
+#else
+static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
+#endif
+
+/* Mask for the exponent */
+static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
+  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Mask for the mantissa */
+static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Mask for the sign bit */
+static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Bit-pattern for negative zero */
+static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Bit-pattern for infinity */
+static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
+  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Bit-pattern for quiet NaN */
+static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
+  0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+/*************************************************************************
+ * Functions
+ */
+
+/*
+ * trio_make_double
+ */
+TRIO_PRIVATE double
+trio_make_double
+TRIO_ARGS1((values),
+	   TRIO_CONST unsigned char *values)
+{
+  TRIO_VOLATILE double result;
+  int i;
+
+  for (i = 0; i < (int)sizeof(double); i++) {
+    ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
+  }
+  return result;
+}
+
+/*
+ * trio_is_special_quantity
+ */
+TRIO_PRIVATE int
+trio_is_special_quantity
+TRIO_ARGS2((number, has_mantissa),
+	   double number,
+	   int *has_mantissa)
+{
+  unsigned int i;
+  unsigned char current;
+  int is_special_quantity = TRIO_TRUE;
+
+  *has_mantissa = 0;
+
+  for (i = 0; i < (unsigned int)sizeof(double); i++) {
+    current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
+    is_special_quantity
+      &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
+    *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
+  }
+  return is_special_quantity;
+}
+
+/*
+ * trio_is_negative
+ */
+TRIO_PRIVATE int
+trio_is_negative
+TRIO_ARGS1((number),
+	   double number)
+{
+  unsigned int i;
+  int is_negative = TRIO_FALSE;
+
+  for (i = 0; i < (unsigned int)sizeof(double); i++) {
+    is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
+		    & ieee_754_sign_mask[i]);
+  }
+  return is_negative;
+}
+
+#endif /* USE_IEEE_754 */
+
+
+/**
+   Generate negative zero.
+
+   @return Floating-point representation of negative zero.
+*/
+TRIO_PUBLIC double
+trio_nzero(TRIO_NOARGS)
+{
+#if defined(USE_IEEE_754)
+  return trio_make_double(ieee_754_negzero_array);
+#else
+  TRIO_VOLATILE double zero = 0.0;
+
+  return -zero;
+#endif
+}
+
+/**
+   Generate positive infinity.
+
+   @return Floating-point representation of positive infinity.
+*/
+TRIO_PUBLIC double
+trio_pinf(TRIO_NOARGS)
+{
+  /* Cache the result */
+  static double result = 0.0;
+
+  if (result == 0.0) {
+    
+#if defined(INFINITY) && defined(__STDC_IEC_559__)
+    result = (double)INFINITY;
+
+#elif defined(USE_IEEE_754)
+    result = trio_make_double(ieee_754_infinity_array);
+
+#else
+    /*
+     * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
+     * as infinity. Otherwise we have to resort to an overflow
+     * operation to generate infinity.
+     */
+# if defined(TRIO_PLATFORM_UNIX)
+    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
+# endif
+
+    result = HUGE_VAL;
+    if (HUGE_VAL == DBL_MAX) {
+      /* Force overflow */
+      result += HUGE_VAL;
+    }
+    
+# if defined(TRIO_PLATFORM_UNIX)
+    signal(SIGFPE, signal_handler);
+# endif
+
+#endif
+  }
+  return result;
+}
+
+/**
+   Generate negative infinity.
+
+   @return Floating-point value of negative infinity.
+*/
+TRIO_PUBLIC double
+trio_ninf(TRIO_NOARGS)
+{
+  static double result = 0.0;
+
+  if (result == 0.0) {
+    /*
+     * Negative infinity is calculated by negating positive infinity,
+     * which can be done because it is legal to do calculations on
+     * infinity (for example,  1 / infinity == 0).
+     */
+    result = -trio_pinf();
+  }
+  return result;
+}
+
+/**
+   Generate NaN.
+
+   @return Floating-point representation of NaN.
+*/
+TRIO_PUBLIC double
+trio_nan(TRIO_NOARGS)
+{
+  /* Cache the result */
+  static double result = 0.0;
+
+  if (result == 0.0) {
+    
+#if defined(TRIO_COMPILER_SUPPORTS_C99)
+    result = nan("");
+
+#elif defined(NAN) && defined(__STDC_IEC_559__)
+    result = (double)NAN;
+  
+#elif defined(USE_IEEE_754)
+    result = trio_make_double(ieee_754_qnan_array);
+
+#else
+    /*
+     * There are several ways to generate NaN. The one used here is
+     * to divide infinity by infinity. I would have preferred to add
+     * negative infinity to positive infinity, but that yields wrong
+     * result (infinity) on FreeBSD.
+     *
+     * This may fail if the hardware does not support NaN, or if
+     * the Invalid Operation floating-point exception is unmasked.
+     */
+# if defined(TRIO_PLATFORM_UNIX)
+    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
+# endif
+    
+    result = trio_pinf() / trio_pinf();
+    
+# if defined(TRIO_PLATFORM_UNIX)
+    signal(SIGFPE, signal_handler);
+# endif
+    
+#endif
+  }
+  return result;
+}
+
+/**
+   Check for NaN.
+
+   @param number An arbitrary floating-point number.
+   @return Boolean value indicating whether or not the number is a NaN.
+*/
+TRIO_PUBLIC int
+trio_isnan
+TRIO_ARGS1((number),
+	   double number)
+{
+#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
+ || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
+  /*
+   * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
+   * function. This function was already present in XPG4, but this
+   * is a bit tricky to detect with compiler defines, so we choose
+   * the conservative approach and only use it for UNIX95.
+   */
+  return isnan(number);
+  
+#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
+  /*
+   * Microsoft Visual C++ and Borland C++ Builder have an _isnan()
+   * function.
+   */
+  return _isnan(number) ? TRIO_TRUE : TRIO_FALSE;
+
+#elif defined(USE_IEEE_754)
+  /*
+   * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
+   * pattern, and a non-empty mantissa.
+   */
+  int has_mantissa;
+  int is_special_quantity;
+
+  is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
+  
+  return (is_special_quantity && has_mantissa);
+  
+#else
+  /*
+   * Fallback solution
+   */
+  int status;
+  double integral, fraction;
+  
+# if defined(TRIO_PLATFORM_UNIX)
+  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
+# endif
+  
+  status = (/*
+	     * NaN is the only number which does not compare to itself
+	     */
+	    ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
+	    /*
+	     * Fallback solution if NaN compares to NaN
+	     */
+	    ((number != 0.0) &&
+	     (fraction = modf(number, &integral),
+	      integral == fraction)));
+  
+# if defined(TRIO_PLATFORM_UNIX)
+  signal(SIGFPE, signal_handler);
+# endif
+  
+  return status;
+  
+#endif
+}
+
+/**
+   Check for infinity.
+
+   @param number An arbitrary floating-point number.
+   @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
+*/
+TRIO_PUBLIC int
+trio_isinf
+TRIO_ARGS1((number),
+	   double number)
+{
+#if defined(TRIO_COMPILER_DECC) && !defined(__linux__)
+  /*
+   * DECC has an isinf() macro, but it works differently than that
+   * of C99, so we use the fp_class() function instead.
+   */
+  return ((fp_class(number) == FP_POS_INF)
+	  ? 1
+	  : ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
+
+#elif defined(isinf)
+  /*
+   * C99 defines isinf() as a macro.
+   */
+  return isinf(number)
+    ? ((number > 0.0) ? 1 : -1)
+    : 0;
+  
+#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
+  /*
+   * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
+   * function that can be used to detect infinity.
+   */
+  return ((_fpclass(number) == _FPCLASS_PINF)
+	  ? 1
+	  : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0));
+
+#elif defined(USE_IEEE_754)
+  /*
+   * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
+   * pattern, and an empty mantissa.
+   */
+  int has_mantissa;
+  int is_special_quantity;
+
+  is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
+  
+  return (is_special_quantity && !has_mantissa)
+    ? ((number < 0.0) ? -1 : 1)
+    : 0;
+
+#else
+  /*
+   * Fallback solution.
+   */
+  int status;
+  
+# if defined(TRIO_PLATFORM_UNIX)
+  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
+# endif
+  
+  double infinity = trio_pinf();
+  
+  status = ((number == infinity)
+	    ? 1
+	    : ((number == -infinity) ? -1 : 0));
+  
+# if defined(TRIO_PLATFORM_UNIX)
+  signal(SIGFPE, signal_handler);
+# endif
+  
+  return status;
+  
+#endif
+}
+
+#if 0
+	/* Temporary fix - this routine is not used anywhere */
+/**
+   Check for finity.
+
+   @param number An arbitrary floating-point number.
+   @return Boolean value indicating whether or not the number is a finite.
+*/
+TRIO_PUBLIC int
+trio_isfinite
+TRIO_ARGS1((number),
+	   double number)
+{
+#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
+  /*
+   * C99 defines isfinite() as a macro.
+   */
+  return isfinite(number);
+  
+#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
+  /*
+   * Microsoft Visual C++ and Borland C++ Builder use _finite().
+   */
+  return _finite(number);
+
+#elif defined(USE_IEEE_754)
+  /*
+   * Examine IEEE 754 bit-pattern. For finity we do not care about the
+   * mantissa.
+   */
+  int dummy;
+
+  return (! trio_is_special_quantity(number, &dummy));
+
+#else
+  /*
+   * Fallback solution.
+   */
+  return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
+  
+#endif
+}
+
+#endif
+
+/*
+ * The sign of NaN is always false
+ */
+TRIO_PUBLIC int
+trio_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+	   double number,
+	   int *is_negative)
+{
+#if defined(fpclassify) && defined(signbit)
+  /*
+   * C99 defines fpclassify() and signbit() as a macros
+   */
+  *is_negative = signbit(number);
+  switch (fpclassify(number)) {
+  case FP_NAN:
+    return TRIO_FP_NAN;
+  case FP_INFINITE:
+    return TRIO_FP_INFINITE;
+  case FP_SUBNORMAL:
+    return TRIO_FP_SUBNORMAL;
+  case FP_ZERO:
+    return TRIO_FP_ZERO;
+  default:
+    return TRIO_FP_NORMAL;
+  }
+
+#else
+# if defined(TRIO_COMPILER_DECC)
+  /*
+   * DECC has an fp_class() function.
+   */
+#  define TRIO_FPCLASSIFY(n) fp_class(n)
+#  define TRIO_QUIET_NAN FP_QNAN
+#  define TRIO_SIGNALLING_NAN FP_SNAN
+#  define TRIO_POSITIVE_INFINITY FP_POS_INF
+#  define TRIO_NEGATIVE_INFINITY FP_NEG_INF
+#  define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM
+#  define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM
+#  define TRIO_POSITIVE_ZERO FP_POS_ZERO
+#  define TRIO_NEGATIVE_ZERO FP_NEG_ZERO
+#  define TRIO_POSITIVE_NORMAL FP_POS_NORM
+#  define TRIO_NEGATIVE_NORMAL FP_NEG_NORM
+  
+# elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
+  /*
+   * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
+   * function.
+   */
+#  define TRIO_FPCLASSIFY(n) _fpclass(n)
+#  define TRIO_QUIET_NAN _FPCLASS_QNAN
+#  define TRIO_SIGNALLING_NAN _FPCLASS_SNAN
+#  define TRIO_POSITIVE_INFINITY _FPCLASS_PINF
+#  define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF
+#  define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD
+#  define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND
+#  define TRIO_POSITIVE_ZERO _FPCLASS_PZ
+#  define TRIO_NEGATIVE_ZERO _FPCLASS_NZ
+#  define TRIO_POSITIVE_NORMAL _FPCLASS_PN
+#  define TRIO_NEGATIVE_NORMAL _FPCLASS_NN
+  
+# elif defined(FP_PLUS_NORM)
+  /*
+   * HP-UX 9.x and 10.x have an fpclassify() function, that is different
+   * from the C99 fpclassify() macro supported on HP-UX 11.x.
+   *
+   * AIX has class() for C, and _class() for C++, which returns the
+   * same values as the HP-UX fpclassify() function.
+   */
+#  if defined(TRIO_PLATFORM_AIX)
+#   if defined(__cplusplus)
+#    define TRIO_FPCLASSIFY(n) _class(n)
+#   else
+#    define TRIO_FPCLASSIFY(n) class(n)
+#   endif
+#  else
+#   define TRIO_FPCLASSIFY(n) fpclassify(n)
+#  endif
+#  define TRIO_QUIET_NAN FP_QNAN
+#  define TRIO_SIGNALLING_NAN FP_SNAN
+#  define TRIO_POSITIVE_INFINITY FP_PLUS_INF
+#  define TRIO_NEGATIVE_INFINITY FP_MINUS_INF
+#  define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM
+#  define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM
+#  define TRIO_POSITIVE_ZERO FP_PLUS_ZERO
+#  define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO
+#  define TRIO_POSITIVE_NORMAL FP_PLUS_NORM
+#  define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM
+# endif
+
+# if defined(TRIO_FPCLASSIFY)
+  switch (TRIO_FPCLASSIFY(number)) {
+  case TRIO_QUIET_NAN:
+  case TRIO_SIGNALLING_NAN:
+    *is_negative = TRIO_FALSE; /* NaN has no sign */
+    return TRIO_FP_NAN;
+  case TRIO_POSITIVE_INFINITY:
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_INFINITE;
+  case TRIO_NEGATIVE_INFINITY:
+    *is_negative = TRIO_TRUE;
+    return TRIO_FP_INFINITE;
+  case TRIO_POSITIVE_SUBNORMAL:
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_SUBNORMAL;
+  case TRIO_NEGATIVE_SUBNORMAL:
+    *is_negative = TRIO_TRUE;
+    return TRIO_FP_SUBNORMAL;
+  case TRIO_POSITIVE_ZERO:
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_ZERO;
+  case TRIO_NEGATIVE_ZERO:
+    *is_negative = TRIO_TRUE;
+    return TRIO_FP_ZERO;
+  case TRIO_POSITIVE_NORMAL:
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_NORMAL;
+  case TRIO_NEGATIVE_NORMAL:
+    *is_negative = TRIO_TRUE;
+    return TRIO_FP_NORMAL;
+  default:
+    /* Just in case... */
+    *is_negative = (number < 0.0);
+    return TRIO_FP_NORMAL;
+  }
+  
+# else
+  /*
+   * Fallback solution.
+   */
+  int rc;
+  
+  if (number == 0.0) {
+    /*
+     * In IEEE 754 the sign of zero is ignored in comparisons, so we
+     * have to handle this as a special case by examining the sign bit
+     * directly.
+     */
+#  if defined(USE_IEEE_754)
+    *is_negative = trio_is_negative(number);
+#  else
+    *is_negative = TRIO_FALSE; /* FIXME */
+#  endif
+    return TRIO_FP_ZERO;
+  }
+  if (trio_isnan(number)) {
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_NAN;
+  }
+  if ((rc = trio_isinf(number))) {
+    *is_negative = (rc == -1);
+    return TRIO_FP_INFINITE;
+  }
+  if ((number > 0.0) && (number < DBL_MIN)) {
+    *is_negative = TRIO_FALSE;
+    return TRIO_FP_SUBNORMAL;
+  }
+  if ((number < 0.0) && (number > -DBL_MIN)) {
+    *is_negative = TRIO_TRUE;
+    return TRIO_FP_SUBNORMAL;
+  }
+  *is_negative = (number < 0.0);
+  return TRIO_FP_NORMAL;
+  
+# endif
+#endif
+}
+
+/**
+   Examine the sign of a number.
+
+   @param number An arbitrary floating-point number.
+   @return Boolean value indicating whether or not the number has the
+   sign bit set (i.e. is negative).
+*/
+TRIO_PUBLIC int
+trio_signbit
+TRIO_ARGS1((number),
+	   double number)
+{
+  int is_negative;
+  
+  (void)trio_fpclassify_and_signbit(number, &is_negative);
+  return is_negative;
+}
+
+#if 0
+	/* Temporary fix - this routine is not used in libxml */
+/**
+   Examine the class of a number.
+
+   @param number An arbitrary floating-point number.
+   @return Enumerable value indicating the class of @p number
+*/
+TRIO_PUBLIC int
+trio_fpclassify
+TRIO_ARGS1((number),
+	   double number)
+{
+  int dummy;
+  
+  return trio_fpclassify_and_signbit(number, &dummy);
+}
+
+#endif
+
+/** @} SpecialQuantities */
+
+/*************************************************************************
+ * For test purposes.
+ *
+ * Add the following compiler option to include this test code.
+ *
+ *  Unix : -DSTANDALONE
+ *  VMS  : /DEFINE=(STANDALONE)
+ */
+#if defined(STANDALONE)
+# include <stdio.h>
+
+static TRIO_CONST char *
+getClassification
+TRIO_ARGS1((type),
+	   int type)
+{
+  switch (type) {
+  case TRIO_FP_INFINITE:
+    return "FP_INFINITE";
+  case TRIO_FP_NAN:
+    return "FP_NAN";
+  case TRIO_FP_NORMAL:
+    return "FP_NORMAL";
+  case TRIO_FP_SUBNORMAL:
+    return "FP_SUBNORMAL";
+  case TRIO_FP_ZERO:
+    return "FP_ZERO";
+  default:
+    return "FP_UNKNOWN";
+  }
+}
+
+static void
+print_class
+TRIO_ARGS2((prefix, number),
+	   TRIO_CONST char *prefix,
+	   double number)
+{
+  printf("%-6s: %s %-15s %g\n",
+	 prefix,
+	 trio_signbit(number) ? "-" : "+",
+	 getClassification(TRIO_FPCLASSIFY(number)),
+	 number);
+}
+
+int main(TRIO_NOARGS)
+{
+  double my_nan;
+  double my_pinf;
+  double my_ninf;
+# if defined(TRIO_PLATFORM_UNIX)
+  void (*signal_handler) TRIO_PROTO((int));
+# endif
+
+  my_nan = trio_nan();
+  my_pinf = trio_pinf();
+  my_ninf = trio_ninf();
+
+  print_class("Nan", my_nan);
+  print_class("PInf", my_pinf);
+  print_class("NInf", my_ninf);
+  print_class("PZero", 0.0);
+  print_class("NZero", -0.0);
+  print_class("PNorm", 1.0);
+  print_class("NNorm", -1.0);
+  print_class("PSub", 1.01e-307 - 1.00e-307);
+  print_class("NSub", 1.00e-307 - 1.01e-307);
+  
+  printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_nan,
+	 ((unsigned char *)&my_nan)[0],
+	 ((unsigned char *)&my_nan)[1],
+	 ((unsigned char *)&my_nan)[2],
+	 ((unsigned char *)&my_nan)[3],
+	 ((unsigned char *)&my_nan)[4],
+	 ((unsigned char *)&my_nan)[5],
+	 ((unsigned char *)&my_nan)[6],
+	 ((unsigned char *)&my_nan)[7],
+	 trio_isnan(my_nan), trio_isinf(my_nan));
+  printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_pinf,
+	 ((unsigned char *)&my_pinf)[0],
+	 ((unsigned char *)&my_pinf)[1],
+	 ((unsigned char *)&my_pinf)[2],
+	 ((unsigned char *)&my_pinf)[3],
+	 ((unsigned char *)&my_pinf)[4],
+	 ((unsigned char *)&my_pinf)[5],
+	 ((unsigned char *)&my_pinf)[6],
+	 ((unsigned char *)&my_pinf)[7],
+	 trio_isnan(my_pinf), trio_isinf(my_pinf));
+  printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_ninf,
+	 ((unsigned char *)&my_ninf)[0],
+	 ((unsigned char *)&my_ninf)[1],
+	 ((unsigned char *)&my_ninf)[2],
+	 ((unsigned char *)&my_ninf)[3],
+	 ((unsigned char *)&my_ninf)[4],
+	 ((unsigned char *)&my_ninf)[5],
+	 ((unsigned char *)&my_ninf)[6],
+	 ((unsigned char *)&my_ninf)[7],
+	 trio_isnan(my_ninf), trio_isinf(my_ninf));
+  
+# if defined(TRIO_PLATFORM_UNIX)
+  signal_handler = signal(SIGFPE, SIG_IGN);
+# endif
+  
+  my_pinf = DBL_MAX + DBL_MAX;
+  my_ninf = -my_pinf;
+  my_nan = my_pinf / my_pinf;
+
+# if defined(TRIO_PLATFORM_UNIX)
+  signal(SIGFPE, signal_handler);
+# endif
+  
+  printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_nan,
+	 ((unsigned char *)&my_nan)[0],
+	 ((unsigned char *)&my_nan)[1],
+	 ((unsigned char *)&my_nan)[2],
+	 ((unsigned char *)&my_nan)[3],
+	 ((unsigned char *)&my_nan)[4],
+	 ((unsigned char *)&my_nan)[5],
+	 ((unsigned char *)&my_nan)[6],
+	 ((unsigned char *)&my_nan)[7],
+	 trio_isnan(my_nan), trio_isinf(my_nan));
+  printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_pinf,
+	 ((unsigned char *)&my_pinf)[0],
+	 ((unsigned char *)&my_pinf)[1],
+	 ((unsigned char *)&my_pinf)[2],
+	 ((unsigned char *)&my_pinf)[3],
+	 ((unsigned char *)&my_pinf)[4],
+	 ((unsigned char *)&my_pinf)[5],
+	 ((unsigned char *)&my_pinf)[6],
+	 ((unsigned char *)&my_pinf)[7],
+	 trio_isnan(my_pinf), trio_isinf(my_pinf));
+  printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+	 my_ninf,
+	 ((unsigned char *)&my_ninf)[0],
+	 ((unsigned char *)&my_ninf)[1],
+	 ((unsigned char *)&my_ninf)[2],
+	 ((unsigned char *)&my_ninf)[3],
+	 ((unsigned char *)&my_ninf)[4],
+	 ((unsigned char *)&my_ninf)[5],
+	 ((unsigned char *)&my_ninf)[6],
+	 ((unsigned char *)&my_ninf)[7],
+	 trio_isnan(my_ninf), trio_isinf(my_ninf));
+  
+  return 0;
+}
+#endif
diff --git a/src/trionan.h b/src/trionan.h
new file mode 100644
index 0000000..c5de32b
--- /dev/null
+++ b/src/trionan.h
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************/
+
+#ifndef TRIO_NAN_H
+#define TRIO_NAN_H
+
+#include "triodef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  TRIO_FP_INFINITE,
+  TRIO_FP_NAN,
+  TRIO_FP_NORMAL,
+  TRIO_FP_SUBNORMAL,
+  TRIO_FP_ZERO
+};
+
+/*
+ * Return NaN (Not-a-Number).
+ */
+TRIO_PUBLIC double trio_nan TRIO_PROTO((void));
+
+/*
+ * Return positive infinity.
+ */
+TRIO_PUBLIC double trio_pinf TRIO_PROTO((void));
+
+/*
+ * Return negative infinity.
+ */
+TRIO_PUBLIC double trio_ninf TRIO_PROTO((void));
+  
+/*
+ * Return negative zero.
+ */
+TRIO_PUBLIC double trio_nzero TRIO_PROTO((TRIO_NOARGS));
+
+/*
+ * If number is a NaN return non-zero, otherwise return zero.
+ */
+TRIO_PUBLIC int trio_isnan TRIO_PROTO((double number));
+
+/*
+ * If number is positive infinity return 1, if number is negative
+ * infinity return -1, otherwise return 0.
+ */
+TRIO_PUBLIC int trio_isinf TRIO_PROTO((double number));
+
+/*
+ * If number is finite return non-zero, otherwise return zero.
+ */
+#if 0
+	/* Temporary fix - these 2 routines not used in libxml */
+TRIO_PUBLIC int trio_isfinite TRIO_PROTO((double number));
+
+TRIO_PUBLIC int trio_fpclassify TRIO_PROTO((double number));
+#endif
+
+TRIO_PUBLIC int trio_signbit TRIO_PROTO((double number));
+
+TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_PROTO((double number, int *is_negative));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRIO_NAN_H */
diff --git a/src/triop.h b/src/triop.h
new file mode 100644
index 0000000..8462c56
--- /dev/null
+++ b/src/triop.h
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************
+ *
+ * Private functions, types, etc. used for callback functions.
+ *
+ * The ref pointer is an opaque type and should remain as such.
+ * Private data must only be accessible through the getter and
+ * setter functions.
+ *
+ ************************************************************************/
+
+#ifndef TRIO_TRIOP_H
+#define TRIO_TRIOP_H
+
+#include "triodef.h"
+
+#include <stdlib.h>
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TRIO_C99
+# define TRIO_C99 1
+#endif
+#ifndef TRIO_BSD
+# define TRIO_BSD 1
+#endif
+#ifndef TRIO_GNU
+# define TRIO_GNU 1
+#endif
+#ifndef TRIO_MISC
+# define TRIO_MISC 1
+#endif
+#ifndef TRIO_UNIX98
+# define TRIO_UNIX98 1
+#endif
+#ifndef TRIO_MICROSOFT
+# define TRIO_MICROSOFT 1
+#endif
+#ifndef TRIO_EXTENSION
+# define TRIO_EXTENSION 1
+#endif
+#ifndef TRIO_WIDECHAR /* Does not work yet. Do not enable */
+# define TRIO_WIDECHAR 0
+#endif
+#ifndef TRIO_ERRORS
+# define TRIO_ERRORS 1
+#endif
+
+#ifndef TRIO_MALLOC
+# define TRIO_MALLOC(n) malloc(n)
+#endif
+#ifndef TRIO_REALLOC
+# define TRIO_REALLOC(x,n) realloc((x),(n))
+#endif
+#ifndef TRIO_FREE
+# define TRIO_FREE(x) free(x)
+#endif
+
+
+/*************************************************************************
+ * User-defined specifiers
+ */
+
+typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
+
+trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
+void trio_unregister TRIO_PROTO((trio_pointer_t handle));
+
+TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
+trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
+
+/* Modifiers */
+int  trio_get_width TRIO_PROTO((trio_pointer_t ref));
+void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
+int  trio_get_precision TRIO_PROTO((trio_pointer_t ref));
+void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
+int  trio_get_base TRIO_PROTO((trio_pointer_t ref));
+void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
+int  trio_get_padding TRIO_PROTO((trio_pointer_t ref));
+void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
+int  trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
+void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
+int  trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
+void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
+int  trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
+void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
+int  trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
+void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
+int  trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
+void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
+int  trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
+void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
+int  trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
+void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
+int  trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /*  TRIO_PROTO((space) */
+void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
+int  trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
+void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
+int  trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
+void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
+int  trio_get_upper TRIO_PROTO((trio_pointer_t ref));
+void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
+#if TRIO_C99
+int  trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
+void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
+int  trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
+void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
+int  trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
+void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
+#endif
+
+/* Printing */
+int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
+int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
+int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
+
+void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
+void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
+/*  void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
+/*  void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
+void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
+void trio_print_string TRIO_PROTO((trio_pointer_t ref, char *string));
+void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* TRIO_TRIOP_H */
diff --git a/src/triostr.c b/src/triostr.c
new file mode 100644
index 0000000..30d13ac
--- /dev/null
+++ b/src/triostr.c
@@ -0,0 +1,2106 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ * Include files
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include "triodef.h"
+#include "triostr.h"
+
+/*************************************************************************
+ * Definitions
+ */
+
+#if !defined(TRIO_STRING_PUBLIC)
+# define TRIO_STRING_PUBLIC TRIO_PUBLIC
+#endif
+#if !defined(TRIO_STRING_PRIVATE)
+# define TRIO_STRING_PRIVATE TRIO_PRIVATE
+#endif
+
+#if !defined(NULL)
+# define NULL 0
+#endif
+#if !defined(NIL)
+# define NIL ((char)0)
+#endif
+#if !defined(FALSE)
+# define FALSE (1 == 0)
+# define TRUE (! FALSE)
+#endif
+#if !defined(BOOLEAN_T)
+# define BOOLEAN_T int
+#endif
+
+#if defined(TRIO_COMPILER_SUPPORTS_C99)
+# define USE_STRTOD
+# define USE_STRTOF
+#elif defined(TRIO_COMPILER_MSVC)
+# define USE_STRTOD
+#endif
+
+#if defined(TRIO_PLATFORM_UNIX)
+# define USE_STRCASECMP
+# define USE_STRNCASECMP
+# if defined(TRIO_PLATFORM_SUNOS)
+#  define USE_SYS_ERRLIST
+# else
+#  define USE_STRERROR
+# endif
+# if defined(TRIO_PLATFORM_QNX)
+#  define strcasecmp(x,y) stricmp(x,y)
+#  define strncasecmp(x,y,n) strnicmp(x,y,n)
+# endif
+#elif defined(TRIO_PLATFORM_WIN32)
+# define USE_STRCASECMP
+# if defined(_WIN32_WCE)
+#  define strcasecmp(x,y) _stricmp(x,y)
+# else
+#  define strcasecmp(x,y) strcmpi(x,y)
+# endif
+#endif
+
+#if !(defined(TRIO_PLATFORM_SUNOS))
+# define USE_TOLOWER
+# define USE_TOUPPER
+#endif
+
+/*************************************************************************
+ * Structures
+ */
+
+struct _trio_string_t
+{
+  char *content;
+  size_t length;
+  size_t allocated;
+};
+
+/*************************************************************************
+ * Constants
+ */
+
+#if !defined(TRIO_MINIMAL)
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
+#endif
+
+/*************************************************************************
+ * Static String Functions
+ */
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_static.h"
+#endif
+/** @addtogroup StaticStrings
+    @{
+*/
+
+/**
+   Create new string.
+
+   @param size Size of new string.
+   @return Pointer to string, or NULL if allocation failed.
+*/
+TRIO_STRING_PUBLIC char *
+trio_create
+TRIO_ARGS1((size),
+	   size_t size)
+{
+  return (char *)TRIO_MALLOC(size);
+}
+
+
+/**
+   Destroy string.
+
+   @param string String to be freed.
+*/
+TRIO_STRING_PUBLIC void
+trio_destroy
+TRIO_ARGS1((string),
+	   char *string)
+{
+  if (string)
+    {
+      TRIO_FREE(string);
+    }
+}
+
+
+/**
+   Count the number of characters in a string.
+
+   @param string String to measure.
+   @return Number of characters in @string.
+*/
+TRIO_STRING_PUBLIC size_t
+trio_length
+TRIO_ARGS1((string),
+	   TRIO_CONST char *string)
+{
+  return strlen(string);
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Append @p source at the end of @p target.
+   
+   @param target Target string.
+   @param source Source string.
+   @return Boolean value indicating success or failure.
+   
+   @pre @p target must point to a memory chunk with sufficient room to
+   contain the @p target string and @p source string.
+   @pre No boundary checking is performed, so insufficient memory will
+   result in a buffer overrun.
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC int
+trio_append
+TRIO_ARGS2((target, source),
+	   char *target,
+	   TRIO_CONST char *source)
+{
+  assert(target);
+  assert(source);
+  
+  return (strcat(target, source) != NULL);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Append at most @p max characters from @p source to @p target.
+   
+   @param target Target string.
+   @param max Maximum number of characters to append.
+   @param source Source string.
+   @return Boolean value indicating success or failure.
+   
+   @pre @p target must point to a memory chuck with sufficient room to
+   contain the @p target string and the @p source string (at most @p max
+   characters).
+   @pre No boundary checking is performed, so insufficient memory will
+   result in a buffer overrun.
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC int
+trio_append_max
+TRIO_ARGS3((target, max, source),
+	   char *target,
+	   size_t max,
+	   TRIO_CONST char *source)
+{
+  size_t length;
+  
+  assert(target);
+  assert(source);
+
+  length = trio_length(target);
+  
+  if (max > length)
+    {
+      strncat(target, source, max - length - 1);
+    }
+  return TRUE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Determine if a string contains a substring.
+
+   @param string String to be searched.
+   @param substring String to be found.
+   @return Boolean value indicating success or failure.
+*/
+TRIO_STRING_PUBLIC int
+trio_contains
+TRIO_ARGS2((string, substring),
+	   TRIO_CONST char *string,
+	   TRIO_CONST char *substring)
+{
+  assert(string);
+  assert(substring);
+  
+  return (0 != strstr(string, substring));
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Copy @p source to @p target.
+   
+   @param target Target string.
+   @param source Source string.
+   @return Boolean value indicating success or failure.
+   
+   @pre @p target must point to a memory chunk with sufficient room to
+   contain the @p source string.
+   @pre No boundary checking is performed, so insufficient memory will
+   result in a buffer overrun.
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC int
+trio_copy
+TRIO_ARGS2((target, source),
+	   char *target,
+	   TRIO_CONST char *source)
+{
+  assert(target);
+  assert(source);
+     
+  (void)strcpy(target, source);
+  return TRUE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Copy at most @p max characters from @p source to @p target.
+   
+   @param target Target string.
+   @param max Maximum number of characters to append.
+   @param source Source string.
+   @return Boolean value indicating success or failure.
+   
+   @pre @p target must point to a memory chunk with sufficient room to
+   contain the @p source string (at most @p max characters).
+   @pre No boundary checking is performed, so insufficient memory will
+   result in a buffer overrun.
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC int
+trio_copy_max
+TRIO_ARGS3((target, max, source),
+	   char *target,
+	   size_t max,
+	   TRIO_CONST char *source)
+{
+  assert(target);
+  assert(source);
+  assert(max > 0); /* Includes != 0 */
+
+  (void)strncpy(target, source, max - 1);
+  target[max - 1] = (char)0;
+  return TRUE;
+}
+
+
+/*
+ * TrioDuplicateMax
+ */
+TRIO_STRING_PRIVATE char *
+TrioDuplicateMax
+TRIO_ARGS2((source, size),
+	   TRIO_CONST char *source,
+	   size_t size)
+{
+  char *target;
+
+  assert(source);
+
+  /* Make room for string plus a terminating zero */
+  size++;
+  target = trio_create(size);
+  if (target)
+    {
+      trio_copy_max(target, size, source);
+    }
+  return target;
+}
+
+
+/**
+   Duplicate @p source.
+   
+   @param source Source string.
+   @return A copy of the @p source string.
+   
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC char *
+trio_duplicate
+TRIO_ARGS1((source),
+	   TRIO_CONST char *source)
+{
+  return TrioDuplicateMax(source, trio_length(source));
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Duplicate at most @p max characters of @p source.
+   
+   @param source Source string.
+   @param max Maximum number of characters to duplicate.
+   @return A copy of the @p source string.
+   
+   @post @p target will be zero terminated.
+*/
+TRIO_STRING_PUBLIC char *
+trio_duplicate_max TRIO_ARGS2((source, max),
+			      TRIO_CONST char *source,
+			      size_t max)
+{
+  size_t length;
+
+  assert(source);
+  assert(max > 0);
+
+  length = trio_length(source);
+  if (length > max)
+    {
+      length = max;
+    }
+  return TrioDuplicateMax(source, length);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Compare if two strings are equal.
+   
+   @param first First string.
+   @param second Second string.
+   @return Boolean indicating whether the two strings are equal or not.
+   
+   Case-insensitive comparison.
+*/
+TRIO_STRING_PUBLIC int
+trio_equal
+TRIO_ARGS2((first, second),
+	   TRIO_CONST char *first,
+	   TRIO_CONST char *second)
+{
+  assert(first);
+  assert(second);
+
+  if ((first != NULL) && (second != NULL))
+    {
+#if defined(USE_STRCASECMP)
+      return (0 == strcasecmp(first, second));
+#else
+      while ((*first != NIL) && (*second != NIL))
+	{
+	  if (trio_to_upper(*first) != trio_to_upper(*second))
+	    {
+	      break;
+	    }
+	  first++;
+	  second++;
+	}
+      return ((*first == NIL) && (*second == NIL));
+#endif
+    }
+  return FALSE;
+}
+
+
+/**
+   Compare if two strings are equal.
+   
+   @param first First string.
+   @param second Second string.
+   @return Boolean indicating whether the two strings are equal or not.
+   
+   Case-sensitive comparison.
+*/
+TRIO_STRING_PUBLIC int
+trio_equal_case
+TRIO_ARGS2((first, second),
+	   TRIO_CONST char *first,
+	   TRIO_CONST char *second)
+{
+  assert(first);
+  assert(second);
+
+  if ((first != NULL) && (second != NULL))
+    {
+      return (0 == strcmp(first, second));
+    }
+  return FALSE;
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Compare if two strings up until the first @p max characters are equal.
+   
+   @param first First string.
+   @param max Maximum number of characters to compare.
+   @param second Second string.
+   @return Boolean indicating whether the two strings are equal or not.
+   
+   Case-sensitive comparison.
+*/
+TRIO_STRING_PUBLIC int
+trio_equal_case_max
+TRIO_ARGS3((first, max, second),
+	   TRIO_CONST char *first,
+	   size_t max,
+	   TRIO_CONST char *second)
+{
+  assert(first);
+  assert(second);
+
+  if ((first != NULL) && (second != NULL))
+    {
+      return (0 == strncmp(first, second, max));
+    }
+  return FALSE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Compare if two strings are equal.
+   
+   @param first First string.
+   @param second Second string.
+   @return Boolean indicating whether the two strings are equal or not.
+
+   Collating characters are considered equal.
+*/
+TRIO_STRING_PUBLIC int
+trio_equal_locale
+TRIO_ARGS2((first, second),
+	   TRIO_CONST char *first,
+	   TRIO_CONST char *second)
+{
+  assert(first);
+  assert(second);
+
+#if defined(LC_COLLATE)
+  return (strcoll(first, second) == 0);
+#else
+  return trio_equal(first, second);
+#endif
+}
+
+
+/**
+   Compare if two strings up until the first @p max characters are equal.
+   
+   @param first First string.
+   @param max Maximum number of characters to compare.
+   @param second Second string.
+   @return Boolean indicating whether the two strings are equal or not.
+   
+   Case-insensitive comparison.
+*/
+TRIO_STRING_PUBLIC int
+trio_equal_max
+TRIO_ARGS3((first, max, second),
+	   TRIO_CONST char *first,
+	   size_t max,
+	   TRIO_CONST char *second)
+{
+  assert(first);
+  assert(second);
+
+  if ((first != NULL) && (second != NULL))
+    {
+#if defined(USE_STRNCASECMP)
+      return (0 == strncasecmp(first, second, max));
+#else
+      /* Not adequately tested yet */
+      size_t cnt = 0;
+      while ((*first != NIL) && (*second != NIL) && (cnt <= max))
+	{
+	  if (trio_to_upper(*first) != trio_to_upper(*second))
+	    {
+	      break;
+	    }
+	  first++;
+	  second++;
+	  cnt++;
+	}
+      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
+#endif
+    }
+  return FALSE;
+}
+
+
+/**
+   Provide a textual description of an error code (errno).
+
+   @param error_number Error number.
+   @return Textual description of @p error_number.
+*/
+TRIO_STRING_PUBLIC TRIO_CONST char *
+trio_error
+TRIO_ARGS1((error_number),
+	   int error_number)
+{
+#if defined(USE_STRERROR)
+  
+  return strerror(error_number);
+
+#elif defined(USE_SYS_ERRLIST)
+
+  extern char *sys_errlist[];
+  extern int sys_nerr;
+
+  return ((error_number < 0) || (error_number >= sys_nerr))
+    ? "unknown"
+    : sys_errlist[error_number];
+ 
+#else
+  
+  return "unknown";
+  
+#endif
+}
+
+
+#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
+/**
+   Format the date/time according to @p format.
+
+   @param target Target string.
+   @param max Maximum number of characters to format.
+   @param format Formatting string.
+   @param datetime Date/time structure.
+   @return Number of formatted characters.
+
+   The formatting string accepts the same specifiers as the standard C
+   function strftime.
+*/
+TRIO_STRING_PUBLIC size_t
+trio_format_date_max
+TRIO_ARGS4((target, max, format, datetime),
+	   char *target,
+	   size_t max,
+	   TRIO_CONST char *format,
+	   TRIO_CONST struct tm *datetime)
+{
+  assert(target);
+  assert(format);
+  assert(datetime);
+  assert(max > 0);
+  
+  return strftime(target, max, format, datetime);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Calculate a hash value for a string.
+
+   @param string String to be calculated on.
+   @param type Hash function.
+   @return Calculated hash value.
+
+   @p type can be one of the following
+   @li @c TRIO_HASH_PLAIN Plain hash function.
+*/
+TRIO_STRING_PUBLIC unsigned long
+trio_hash
+TRIO_ARGS2((string, type),
+	   TRIO_CONST char *string,
+	   int type)
+{
+  unsigned long value = 0L;
+  char ch;
+
+  assert(string);
+  
+  switch (type)
+    {
+    case TRIO_HASH_PLAIN:
+      while ( (ch = *string++) != NIL )
+	{
+	  value *= 31;
+	  value += (unsigned long)ch;
+	}
+      break;
+    default:
+      assert(FALSE);
+      break;
+    }
+  return value;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Find first occurrence of a character in a string.
+
+   @param string String to be searched.
+   @param character Character to be found.
+   @param A pointer to the found character, or NULL if character was not found.
+ */
+TRIO_STRING_PUBLIC char *
+trio_index
+TRIO_ARGS2((string, character),
+	   TRIO_CONST char *string,
+	   int character)
+{
+  assert(string);
+
+  return strchr(string, character);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Find last occurrence of a character in a string.
+
+   @param string String to be searched.
+   @param character Character to be found.
+   @param A pointer to the found character, or NULL if character was not found.
+ */
+TRIO_STRING_PUBLIC char *
+trio_index_last
+TRIO_ARGS2((string, character),
+	   TRIO_CONST char *string,
+	   int character)
+{
+  assert(string);
+
+  return strchr(string, character);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Convert the alphabetic letters in the string to lower-case.
+
+   @param target String to be converted.
+   @return Number of processed characters (converted or not).
+*/
+TRIO_STRING_PUBLIC int
+trio_lower
+TRIO_ARGS1((target),
+	   char *target)
+{
+  assert(target);
+
+  return trio_span_function(target, target, trio_to_lower);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Compare two strings using wildcards.
+
+   @param string String to be searched.
+   @param pattern Pattern, including wildcards, to search for.
+   @return Boolean value indicating success or failure.
+
+   Case-insensitive comparison.
+   
+   The following wildcards can be used
+   @li @c * Match any number of characters.
+   @li @c ? Match a single character.
+*/
+TRIO_STRING_PUBLIC int
+trio_match
+TRIO_ARGS2((string, pattern),
+	   TRIO_CONST char *string,
+	   TRIO_CONST char *pattern)
+{
+  assert(string);
+  assert(pattern);
+  
+  for (; ('*' != *pattern); ++pattern, ++string)
+    {
+      if (NIL == *string)
+	{
+	  return (NIL == *pattern);
+	}
+      if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
+	  && ('?' != *pattern))
+	{
+	  return FALSE;
+	}
+    }
+  /* two-line patch to prevent *too* much recursiveness: */
+  while ('*' == pattern[1])
+    pattern++;
+
+  do
+    {
+      if ( trio_match(string, &pattern[1]) )
+	{
+	  return TRUE;
+	}
+    }
+  while (*string++);
+  
+  return FALSE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Compare two strings using wildcards.
+
+   @param string String to be searched.
+   @param pattern Pattern, including wildcards, to search for.
+   @return Boolean value indicating success or failure.
+
+   Case-sensitive comparison.
+   
+   The following wildcards can be used
+   @li @c * Match any number of characters.
+   @li @c ? Match a single character.
+*/
+TRIO_STRING_PUBLIC int
+trio_match_case
+TRIO_ARGS2((string, pattern),
+	   TRIO_CONST char *string,
+	   TRIO_CONST char *pattern)
+{
+  assert(string);
+  assert(pattern);
+  
+  for (; ('*' != *pattern); ++pattern, ++string)
+    {
+      if (NIL == *string)
+	{
+	  return (NIL == *pattern);
+	}
+      if ((*string != *pattern)
+	  && ('?' != *pattern))
+	{
+	  return FALSE;
+	}
+    }
+  /* two-line patch to prevent *too* much recursiveness: */
+  while ('*' == pattern[1])
+    pattern++;
+
+  do
+    {
+      if ( trio_match_case(string, &pattern[1]) )
+	{
+	  return TRUE;
+	}
+    }
+  while (*string++);
+  
+  return FALSE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Execute a function on each character in string.
+
+   @param target Target string.
+   @param source Source string.
+   @param Function Function to be executed.
+   @return Number of processed characters.
+*/
+TRIO_STRING_PUBLIC size_t
+trio_span_function
+TRIO_ARGS3((target, source, Function),
+	   char *target,
+	   TRIO_CONST char *source,
+	   int (*Function) TRIO_PROTO((int)))
+{
+  size_t count = 0;
+
+  assert(target);
+  assert(source);
+  assert(Function);
+  
+  while (*source != NIL)
+    {
+      *target++ = Function(*source++);
+      count++;
+    }
+  return count;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Search for a substring in a string.
+
+   @param string String to be searched.
+   @param substring String to be found.
+   @return Pointer to first occurrence of @p substring in @p string, or NULL
+   if no match was found.
+*/
+TRIO_STRING_PUBLIC char *
+trio_substring
+TRIO_ARGS2((string, substring),
+	   TRIO_CONST char *string,
+	   TRIO_CONST char *substring)
+{
+  assert(string);
+  assert(substring);
+
+  return strstr(string, substring);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Search for a substring in the first @p max characters of a string.
+
+   @param string String to be searched.
+   @param max Maximum characters to be searched.
+   @param substring String to be found.
+   @return Pointer to first occurrence of @p substring in @p string, or NULL
+   if no match was found.
+*/
+TRIO_STRING_PUBLIC char *
+trio_substring_max
+TRIO_ARGS3((string, max, substring),
+	   TRIO_CONST char *string,
+	   size_t max,
+	   TRIO_CONST char *substring)
+{
+  size_t count;
+  size_t size;
+  char *result = NULL;
+
+  assert(string);
+  assert(substring);
+  
+  size = trio_length(substring);
+  if (size <= max)
+    {
+      for (count = 0; count <= max - size; count++)
+	{
+	  if (trio_equal_max(substring, size, &string[count]))
+	    {
+	      result = (char *)&string[count];
+	      break;
+	    }
+	}
+    }
+  return result;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Tokenize string.
+
+   @param string String to be tokenized.
+   @param tokens String containing list of delimiting characters.
+   @return Start of new token.
+
+   @warning @p string will be destroyed.
+*/
+TRIO_STRING_PUBLIC char *
+trio_tokenize
+TRIO_ARGS2((string, delimiters),
+	   char *string,
+	   TRIO_CONST char *delimiters)
+{
+  assert(delimiters);
+  
+  return strtok(string, delimiters);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Convert string to floating-point number.
+
+   @param source String to be converted.
+   @param endp Pointer to end of the converted string.
+   @return A floating-point number.
+
+   The following Extended Backus-Naur form is used
+   @verbatim
+   double        ::= [ <sign> ]
+                     ( <number> |
+                       <number> <decimal_point> <number> |
+                       <decimal_point> <number> )
+                     [ <exponential> [ <sign> ] <number> ]
+   number        ::= 1*( <digit> )
+   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
+   exponential   ::= ( 'e' | 'E' )
+   sign          ::= ( '-' | '+' )
+   decimal_point ::= '.'
+   @endverbatim
+*/
+/* FIXME: Add EBNF for hex-floats */
+TRIO_STRING_PUBLIC trio_long_double_t
+trio_to_long_double
+TRIO_ARGS2((source, endp),
+	   TRIO_CONST char *source,
+	   char **endp)
+{
+#if defined(USE_STRTOLD)
+  return strtold(source, endp);
+#else
+  int isNegative = FALSE;
+  int isExponentNegative = FALSE;
+  trio_long_double_t integer = 0.0;
+  trio_long_double_t fraction = 0.0;
+  unsigned long exponent = 0;
+  trio_long_double_t base;
+  trio_long_double_t fracdiv = 1.0;
+  trio_long_double_t value = 0.0;
+
+  /* First try hex-floats */
+  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
+    {
+      base = 16.0;
+      source += 2;
+      while (isxdigit((int)*source))
+	{
+	  integer *= base;
+	  integer += (isdigit((int)*source)
+		      ? (*source - '0')
+		      : 10 + (trio_to_upper((int)*source) - 'A'));
+	  source++;
+	}
+      if (*source == '.')
+	{
+	  source++;
+	  while (isxdigit((int)*source))
+	    {
+	      fracdiv /= base;
+	      fraction += fracdiv * (isdigit((int)*source)
+				     ? (*source - '0')
+				     : 10 + (trio_to_upper((int)*source) - 'A'));
+	      source++;
+	    }
+	  if ((*source == 'p') || (*source == 'P'))
+	    {
+	      source++;
+	      if ((*source == '+') || (*source == '-'))
+		{
+		  isExponentNegative = (*source == '-');
+		  source++;
+		}
+	      while (isdigit((int)*source))
+		{
+		  exponent *= 10;
+		  exponent += (*source - '0');
+		  source++;
+		}
+	    }
+	}
+      /* For later use with exponent */
+      base = 2.0;
+    }
+  else /* Then try normal decimal floats */
+    {
+      base = 10.0;
+      isNegative = (*source == '-');
+      /* Skip sign */
+      if ((*source == '+') || (*source == '-'))
+	source++;
+
+      /* Integer part */
+      while (isdigit((int)*source))
+	{
+	  integer *= base;
+	  integer += (*source - '0');
+	  source++;
+	}
+
+      if (*source == '.')
+	{
+	  source++; /* skip decimal point */
+	  while (isdigit((int)*source))
+	    {
+	      fracdiv /= base;
+	      fraction += (*source - '0') * fracdiv;
+	      source++;
+	    }
+	}
+      if ((*source == 'e')
+	  || (*source == 'E')
+#if TRIO_MICROSOFT
+	  || (*source == 'd')
+	  || (*source == 'D')
+#endif
+	  )
+	{
+	  source++; /* Skip exponential indicator */
+	  isExponentNegative = (*source == '-');
+	  if ((*source == '+') || (*source == '-'))
+	    source++;
+	  while (isdigit((int)*source))
+	    {
+	      exponent *= (int)base;
+	      exponent += (*source - '0');
+	      source++;
+	    }
+	}
+    }
+  
+  value = integer + fraction;
+  if (exponent != 0)
+    {
+      if (isExponentNegative)
+	value /= pow(base, (double)exponent);
+      else
+	value *= pow(base, (double)exponent);
+    }
+  if (isNegative)
+    value = -value;
+
+  if (endp)
+    *endp = (char *)source;
+  return value;
+#endif
+}
+
+
+/**
+   Convert string to floating-point number.
+
+   @param source String to be converted.
+   @param endp Pointer to end of the converted string.
+   @return A floating-point number.
+
+   See @ref trio_to_long_double.
+*/
+TRIO_STRING_PUBLIC double
+trio_to_double
+TRIO_ARGS2((source, endp),
+	   TRIO_CONST char *source,
+	   char **endp)
+{
+#if defined(USE_STRTOD)
+  return strtod(source, endp);
+#else
+  return (double)trio_to_long_double(source, endp);
+#endif
+}
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Convert string to floating-point number.
+
+   @param source String to be converted.
+   @param endp Pointer to end of the converted string.
+   @return A floating-point number.
+
+   See @ref trio_to_long_double.
+*/
+TRIO_STRING_PUBLIC float
+trio_to_float
+TRIO_ARGS2((source, endp),
+	   TRIO_CONST char *source,
+	   char **endp)
+{
+#if defined(USE_STRTOF)
+  return strtof(source, endp);
+#else
+  return (float)trio_to_long_double(source, endp);
+#endif
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Convert string to signed integer.
+
+   @param string String to be converted.
+   @param endp Pointer to end of converted string.
+   @param base Radix number of number.
+*/
+TRIO_STRING_PUBLIC long
+trio_to_long
+TRIO_ARGS3((string, endp, base),
+	   TRIO_CONST char *string,
+	   char **endp,
+	   int base)
+{
+  assert(string);
+  assert((base >= 2) && (base <= 36));
+  
+  return strtol(string, endp, base);
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Convert one alphabetic letter to lower-case.
+
+   @param source The letter to be converted.
+   @return The converted letter.
+*/
+TRIO_STRING_PUBLIC int
+trio_to_lower
+TRIO_ARGS1((source),
+	   int source)
+{
+#if defined(USE_TOLOWER)
+  
+  return tolower(source);
+  
+#else
+
+  /* Does not handle locales or non-contiguous alphabetic characters */
+  return ((source >= (int)'A') && (source <= (int)'Z'))
+    ? source - 'A' + 'a'
+    : source;
+  
+#endif
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Convert string to unsigned integer.
+
+   @param string String to be converted.
+   @param endp Pointer to end of converted string.
+   @param base Radix number of number.
+*/
+TRIO_STRING_PUBLIC unsigned long
+trio_to_unsigned_long
+TRIO_ARGS3((string, endp, base),
+	   TRIO_CONST char *string,
+	   char **endp,
+	   int base)
+{
+  assert(string);
+  assert((base >= 2) && (base <= 36));
+  
+  return strtoul(string, endp, base);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Convert one alphabetic letter to upper-case.
+
+   @param source The letter to be converted.
+   @return The converted letter.
+*/
+TRIO_STRING_PUBLIC int
+trio_to_upper
+TRIO_ARGS1((source),
+	   int source)
+{
+#if defined(USE_TOUPPER)
+  
+  return toupper(source);
+  
+#else
+
+  /* Does not handle locales or non-contiguous alphabetic characters */
+  return ((source >= (int)'a') && (source <= (int)'z'))
+    ? source - 'a' + 'A'
+    : source;
+  
+#endif
+}
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Convert the alphabetic letters in the string to upper-case.
+
+   @param target The string to be converted.
+   @return The number of processed characters (converted or not).
+*/
+TRIO_STRING_PUBLIC int
+trio_upper
+TRIO_ARGS1((target),
+	   char *target)
+{
+  assert(target);
+
+  return trio_span_function(target, target, trio_to_upper);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/** @} End of StaticStrings */
+
+
+/*************************************************************************
+ * Dynamic String Functions
+ */
+
+#if defined(TRIO_DOCUMENTATION)
+# include "doc/doc_dynamic.h"
+#endif
+/** @addtogroup DynamicStrings
+    @{
+*/
+
+/*
+ * TrioStringAlloc
+ */
+TRIO_STRING_PRIVATE trio_string_t *
+TrioStringAlloc(TRIO_NOARGS)
+{
+  trio_string_t *self;
+  
+  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
+  if (self)
+    {
+      self->content = NULL;
+      self->length = 0;
+      self->allocated = 0;
+    }
+  return self;
+}
+
+
+/*
+ * TrioStringGrow
+ *
+ * The size of the string will be increased by 'delta' characters. If
+ * 'delta' is zero, the size will be doubled.
+ */
+TRIO_STRING_PRIVATE BOOLEAN_T
+TrioStringGrow
+TRIO_ARGS2((self, delta),
+	   trio_string_t *self,
+	   size_t delta)
+{
+  BOOLEAN_T status = FALSE;
+  char *new_content;
+  size_t new_size;
+
+  new_size = (delta == 0)
+    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
+    : self->allocated + delta;
+  
+  new_content = (char *)TRIO_REALLOC(self->content, new_size);
+  if (new_content)
+    {
+      self->content = new_content;
+      self->allocated = new_size;
+      status = TRUE;
+    }
+  return status;
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * TrioStringGrowTo
+ *
+ * The size of the string will be increased to 'length' plus one characters.
+ * If 'length' is less than the original size, the original size will be
+ * used (that is, the size of the string is never decreased).
+ */
+TRIO_STRING_PRIVATE BOOLEAN_T
+TrioStringGrowTo
+TRIO_ARGS2((self, length),
+	   trio_string_t *self,
+	   size_t length)
+{
+  length++; /* Room for terminating zero */
+  return (self->allocated < length)
+    ? TrioStringGrow(self, length - self->allocated)
+    : TRUE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Create a new dynamic string.
+   
+   @param initial_size Initial size of the buffer.
+   @return Newly allocated dynamic string, or NULL if memory allocation failed.
+*/
+TRIO_STRING_PUBLIC trio_string_t *
+trio_string_create
+TRIO_ARGS1((initial_size),
+	   int initial_size)
+{
+  trio_string_t *self;
+
+  self = TrioStringAlloc();
+  if (self)
+    {
+      if (TrioStringGrow(self,
+			 (size_t)((initial_size > 0) ? initial_size : 1)))
+	{
+	  self->content[0] = (char)0;
+	  self->allocated = initial_size;
+	}
+      else
+	{
+	  trio_string_destroy(self);
+	  self = NULL;
+	}
+    }
+  return self;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Deallocate the dynamic string and its contents.
+   
+   @param self Dynamic string
+*/
+TRIO_STRING_PUBLIC void
+trio_string_destroy
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  assert(self);
+  
+  if (self)
+    {
+      trio_destroy(self->content);
+      TRIO_FREE(self);
+    }
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Get a pointer to the content.
+   
+   @param self Dynamic string.
+   @param offset Offset into content.
+   @return Pointer to the content.
+   
+   @p Offset can be zero, positive, or negative. If @p offset is zero,
+   then the start of the content will be returned. If @p offset is positive,
+   then a pointer to @p offset number of characters from the beginning of the
+   content is returned. If @p offset is negative, then a pointer to @p offset
+   number of characters from the ending of the string, starting at the
+   terminating zero, is returned.
+*/
+TRIO_STRING_PUBLIC char *
+trio_string_get
+TRIO_ARGS2((self, offset),
+	   trio_string_t *self,
+	   int offset)
+{
+  char *result = NULL;
+  
+  assert(self);
+
+  if (self->content != NULL)
+    {
+      if (self->length == 0)
+	{
+	  (void)trio_string_length(self);
+	}
+      if (offset >= 0)
+	{
+	  if (offset > (int)self->length)
+	    {
+	      offset = self->length;
+	    }
+	}
+      else
+	{
+	  offset += self->length + 1;
+	  if (offset < 0)
+	    {
+	      offset = 0;
+	    }
+	}
+      result = &(self->content[offset]);
+    }
+  return result;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/**
+   Extract the content.
+   
+   @param self Dynamic String
+   @return Content of dynamic string.
+   
+   The content is removed from the dynamic string. This enables destruction
+   of the dynamic string without deallocation of the content.
+*/
+TRIO_STRING_PUBLIC char *
+trio_string_extract
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  char *result;
+  
+  assert(self);
+
+  result = self->content;
+  /* FIXME: Allocate new empty buffer? */
+  self->content = NULL;
+  self->length = self->allocated = 0;
+  return result;
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Set the content of the dynamic string.
+   
+   @param self Dynamic String
+   @param buffer The new content.
+   
+   Sets the content of the dynamic string to a copy @p buffer.
+   An existing content will be deallocated first, if necessary.
+   
+   @remark
+   This function will make a copy of @p buffer.
+   You are responsible for deallocating @p buffer yourself.
+*/
+TRIO_STRING_PUBLIC void
+trio_xstring_set
+TRIO_ARGS2((self, buffer),
+	   trio_string_t *self,
+	   char *buffer)
+{
+  assert(self);
+
+  trio_destroy(self->content);
+  self->content = trio_duplicate(buffer);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/*
+ * trio_string_size
+ */
+TRIO_STRING_PUBLIC int
+trio_string_size
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  assert(self);
+
+  return self->allocated;
+}
+
+
+/*
+ * trio_string_terminate
+ */
+TRIO_STRING_PUBLIC void
+trio_string_terminate
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  trio_xstring_append_char(self, 0);
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Append the second string to the first.
+   
+   @param self Dynamic string to be modified.
+   @param other Dynamic string to copy from.
+   @return Boolean value indicating success or failure.
+*/
+TRIO_STRING_PUBLIC int
+trio_string_append
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  size_t length;
+  
+  assert(self);
+  assert(other);
+
+  length = self->length + other->length;
+  if (!TrioStringGrowTo(self, length))
+    goto error;
+  trio_copy(&self->content[self->length], other->content);
+  self->length = length;
+  return TRUE;
+  
+ error:
+  return FALSE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_append
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_append
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  size_t length;
+  
+  assert(self);
+  assert(other);
+
+  length = self->length + trio_length(other);
+  if (!TrioStringGrowTo(self, length))
+    goto error;
+  trio_copy(&self->content[self->length], other);
+  self->length = length;
+  return TRUE;
+  
+ error:
+  return FALSE;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/*
+ * trio_xstring_append_char
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_append_char
+TRIO_ARGS2((self, character),
+	   trio_string_t *self,
+	   char character)
+{
+  assert(self);
+
+  if ((int)self->length >= trio_string_size(self))
+    {
+      if (!TrioStringGrow(self, 0))
+	goto error;
+    }
+  self->content[self->length] = character;
+  self->length++;
+  return TRUE;
+  
+ error:
+  return FALSE;
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/**
+   Search for the first occurrence of second parameter in the first.
+   
+   @param self Dynamic string to be modified.
+   @param other Dynamic string to copy from.
+   @return Boolean value indicating success or failure.
+*/
+TRIO_STRING_PUBLIC int
+trio_string_contains
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_contains(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_contains
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_contains
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_contains(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_copy
+ */
+TRIO_STRING_PUBLIC int
+trio_string_copy
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  self->length = 0;
+  return trio_string_append(self, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_copy
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_copy
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  self->length = 0;
+  return trio_xstring_append(self, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_duplicate
+ */
+TRIO_STRING_PUBLIC trio_string_t *
+trio_string_duplicate
+TRIO_ARGS1((other),
+	   trio_string_t *other)
+{
+  trio_string_t *self;
+  
+  assert(other);
+
+  self = TrioStringAlloc();
+  if (self)
+    {
+      self->content = TrioDuplicateMax(other->content, other->length);
+      if (self->content)
+	{
+	  self->length = other->length;
+	  self->allocated = self->length + 1;
+	}
+      else
+	{
+	  self->length = self->allocated = 0;
+	}
+    }
+  return self;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+/*
+ * trio_xstring_duplicate
+ */
+TRIO_STRING_PUBLIC trio_string_t *
+trio_xstring_duplicate
+TRIO_ARGS1((other),
+	   TRIO_CONST char *other)
+{
+  trio_string_t *self;
+  
+  assert(other);
+
+  self = TrioStringAlloc();
+  if (self)
+    {
+      self->content = TrioDuplicateMax(other, trio_length(other));
+      if (self->content)
+	{
+	  self->length = trio_length(self->content);
+	  self->allocated = self->length + 1;
+	}
+      else
+	{
+	  self->length = self->allocated = 0;
+	}
+    }
+  return self;
+}
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_equal
+ */
+TRIO_STRING_PUBLIC int
+trio_string_equal
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_equal
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_equal
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_equal_max
+ */
+TRIO_STRING_PUBLIC int
+trio_string_equal_max
+TRIO_ARGS3((self, max, other),
+	   trio_string_t *self,
+	   size_t max,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_max(self->content, max, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_equal_max
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_max
+TRIO_ARGS3((self, max, other),
+	   trio_string_t *self,
+	   size_t max,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_max(self->content, max, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_equal_case
+ */
+TRIO_STRING_PUBLIC int
+trio_string_equal_case
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_case(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_equal_case
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_case
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_case(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_equal_case_max
+ */
+TRIO_STRING_PUBLIC int
+trio_string_equal_case_max
+TRIO_ARGS3((self, max, other),
+	   trio_string_t *self,
+	   size_t max,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_case_max(self->content, max, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_equal_case_max
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_case_max
+TRIO_ARGS3((self, max, other),
+	   trio_string_t *self,
+	   size_t max,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_equal_case_max(self->content, max, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
+/*
+ * trio_string_format_data_max
+ */
+TRIO_STRING_PUBLIC size_t
+trio_string_format_date_max
+TRIO_ARGS4((self, max, format, datetime),
+	   trio_string_t *self,
+	   size_t max,
+	   TRIO_CONST char *format,
+	   TRIO_CONST struct tm *datetime)
+{
+  assert(self);
+
+  return trio_format_date_max(self->content, max, format, datetime);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_index
+ */
+TRIO_STRING_PUBLIC char *
+trio_string_index
+TRIO_ARGS2((self, character),
+	   trio_string_t *self,
+	   int character)
+{
+  assert(self);
+
+  return trio_index(self->content, character);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_index_last
+ */
+TRIO_STRING_PUBLIC char *
+trio_string_index_last
+TRIO_ARGS2((self, character),
+	   trio_string_t *self,
+	   int character)
+{
+  assert(self);
+
+  return trio_index_last(self->content, character);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_length
+ */
+TRIO_STRING_PUBLIC int
+trio_string_length
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  assert(self);
+
+  if (self->length == 0)
+    {
+      self->length = trio_length(self->content);
+    }
+  return self->length;
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_lower
+ */
+TRIO_STRING_PUBLIC int
+trio_string_lower
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  assert(self);
+
+  return trio_lower(self->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_match
+ */
+TRIO_STRING_PUBLIC int
+trio_string_match
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_match(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_match
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_match
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_match(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_match_case
+ */
+TRIO_STRING_PUBLIC int
+trio_string_match_case
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_match_case(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_match_case
+ */
+TRIO_STRING_PUBLIC int
+trio_xstring_match_case
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_match_case(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_substring
+ */
+TRIO_STRING_PUBLIC char *
+trio_string_substring
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   trio_string_t *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_substring(self->content, other->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_xstring_substring
+ */
+TRIO_STRING_PUBLIC char *
+trio_xstring_substring
+TRIO_ARGS2((self, other),
+	   trio_string_t *self,
+	   TRIO_CONST char *other)
+{
+  assert(self);
+  assert(other);
+
+  return trio_substring(self->content, other);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+
+#if !defined(TRIO_MINIMAL)
+/*
+ * trio_string_upper
+ */
+TRIO_STRING_PUBLIC int
+trio_string_upper
+TRIO_ARGS1((self),
+	   trio_string_t *self)
+{
+  assert(self);
+
+  return trio_upper(self->content);
+}
+#endif /* !defined(TRIO_MINIMAL) */
+
+/** @} End of DynamicStrings */
diff --git a/src/triostr.h b/src/triostr.h
new file mode 100644
index 0000000..27f4ace
--- /dev/null
+++ b/src/triostr.h
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ ************************************************************************/
+
+#ifndef TRIO_TRIOSTR_H
+#define TRIO_TRIOSTR_H
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "triodef.h"
+#include "triop.h"
+
+enum {
+  TRIO_HASH_NONE = 0,
+  TRIO_HASH_PLAIN,
+  TRIO_HASH_TWOSIGNED
+};
+
+#if !defined(TRIO_STRING_PUBLIC)
+# if !defined(TRIO_PUBLIC)
+#  define TRIO_PUBLIC
+# endif
+# define TRIO_STRING_PUBLIC TRIO_PUBLIC
+#endif
+
+/*************************************************************************
+ * String functions
+ */
+
+TRIO_STRING_PUBLIC int trio_copy_max TRIO_PROTO((char *target, size_t max, const char *source));
+TRIO_STRING_PUBLIC char *trio_create TRIO_PROTO((size_t size));
+TRIO_STRING_PUBLIC void trio_destroy TRIO_PROTO((char *string));
+TRIO_STRING_PUBLIC char *trio_duplicate TRIO_PROTO((const char *source));
+TRIO_STRING_PUBLIC int trio_equal TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_case TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_locale TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_max TRIO_PROTO((const char *first, size_t max, const char *second));
+TRIO_STRING_PUBLIC TRIO_CONST char *trio_error TRIO_PROTO((int));
+TRIO_STRING_PUBLIC size_t trio_length TRIO_PROTO((const char *string));
+TRIO_STRING_PUBLIC double trio_to_double TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC long trio_to_long TRIO_PROTO((const char *source, char **endp, int base));
+TRIO_STRING_PUBLIC trio_long_double_t trio_to_long_double TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC int trio_to_upper TRIO_PROTO((int source));
+
+#if !defined(TRIO_MINIMAL)
+
+TRIO_STRING_PUBLIC int trio_append TRIO_PROTO((char *target, const char *source));
+TRIO_STRING_PUBLIC int trio_append_max TRIO_PROTO((char *target, size_t max, const char *source));
+TRIO_STRING_PUBLIC int trio_contains TRIO_PROTO((const char *string, const char *substring));
+TRIO_STRING_PUBLIC int trio_copy TRIO_PROTO((char *target, const char *source));
+TRIO_STRING_PUBLIC char *trio_duplicate_max TRIO_PROTO((const char *source, size_t max));
+TRIO_STRING_PUBLIC int trio_equal_case_max TRIO_PROTO((const char *first, size_t max, const char *second));
+#if !defined(_WIN32_WCE)
+TRIO_STRING_PUBLIC size_t trio_format_date_max TRIO_PROTO((char *target, size_t max, const char *format, const struct tm *datetime));
+#endif
+TRIO_STRING_PUBLIC unsigned long trio_hash TRIO_PROTO((const char *string, int type));
+TRIO_STRING_PUBLIC char *trio_index TRIO_PROTO((const char *string, int character));
+TRIO_STRING_PUBLIC char *trio_index_last TRIO_PROTO((const char *string, int character));
+TRIO_STRING_PUBLIC int trio_lower TRIO_PROTO((char *target));
+TRIO_STRING_PUBLIC int trio_match TRIO_PROTO((const char *string, const char *pattern));
+TRIO_STRING_PUBLIC int trio_match_case TRIO_PROTO((const char *string, const char *pattern));
+TRIO_STRING_PUBLIC size_t trio_span_function TRIO_PROTO((char *target, const char *source, int (*Function) TRIO_PROTO((int))));
+TRIO_STRING_PUBLIC char *trio_substring TRIO_PROTO((const char *string, const char *substring));
+TRIO_STRING_PUBLIC char *trio_substring_max TRIO_PROTO((const char *string, size_t max, const char *substring));
+TRIO_STRING_PUBLIC float trio_to_float TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC int trio_to_lower TRIO_PROTO((int source));
+TRIO_STRING_PUBLIC unsigned long trio_to_unsigned_long TRIO_PROTO((const char *source, char **endp, int base));
+TRIO_STRING_PUBLIC char *trio_tokenize TRIO_PROTO((char *string, const char *delimiters));
+TRIO_STRING_PUBLIC int trio_upper TRIO_PROTO((char *target));
+
+#endif /* !defined(TRIO_MINIMAL) */
+
+/*************************************************************************
+ * Dynamic string functions
+ */
+
+/*
+ * Opaque type for dynamic strings
+ */
+
+typedef struct _trio_string_t trio_string_t;
+
+TRIO_STRING_PUBLIC void trio_string_destroy TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC char *trio_string_extract TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_size TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC void trio_string_terminate TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_xstring_append_char TRIO_PROTO((trio_string_t *self, char character));
+TRIO_STRING_PUBLIC trio_string_t *trio_xstring_duplicate TRIO_PROTO((const char *other));
+
+#if !defined(TRIO_MINIMAL)
+
+TRIO_STRING_PUBLIC trio_string_t *trio_string_create TRIO_PROTO((int initial_size));
+TRIO_STRING_PUBLIC char *trio_string_get TRIO_PROTO((trio_string_t *self, int offset));
+TRIO_STRING_PUBLIC void trio_xstring_set TRIO_PROTO((trio_string_t *self, char *buffer));
+
+TRIO_STRING_PUBLIC int trio_string_append TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_contains TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_copy TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC trio_string_t *trio_string_duplicate TRIO_PROTO((trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
+TRIO_STRING_PUBLIC int trio_string_equal_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
+#if !defined(_WIN32_WCE)
+TRIO_STRING_PUBLIC size_t trio_string_format_date_max TRIO_PROTO((trio_string_t *self, size_t max, const char *format, const struct tm *datetime));
+#endif
+TRIO_STRING_PUBLIC char *trio_string_index TRIO_PROTO((trio_string_t *self, int character));
+TRIO_STRING_PUBLIC char *trio_string_index_last TRIO_PROTO((trio_string_t *self, int character));
+TRIO_STRING_PUBLIC int trio_string_length TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_lower TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_match TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_match_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC char *trio_string_substring TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_upper TRIO_PROTO((trio_string_t *self));
+
+TRIO_STRING_PUBLIC int trio_xstring_append TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_contains TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_copy TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_case TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_match TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_match_case TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC char *trio_xstring_substring TRIO_PROTO((trio_string_t *self, const char *other));
+
+#endif /* !defined(TRIO_MINIMAL) */
+
+#endif /* TRIO_TRIOSTR_H */
diff --git a/src/uri.c b/src/uri.c
new file mode 100644
index 0000000..950e177
--- /dev/null
+++ b/src/uri.c
@@ -0,0 +1,2633 @@
+/**
+ * uri.c: set of generic URI related routines 
+ *
+ * Reference: RFCs 3986, 2732 and 2373
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/uri.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+
+static void xmlCleanURI(xmlURIPtr uri);
+
+/*
+ * Old rule from 2396 used in legacy handling code
+ * alpha    = lowalpha | upalpha
+ */
+#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))
+
+
+/*
+ * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
+ *            "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
+ *            "u" | "v" | "w" | "x" | "y" | "z"
+ */
+
+#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
+
+/*
+ * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |
+ *           "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |
+ *           "U" | "V" | "W" | "X" | "Y" | "Z"
+ */
+#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))
+
+#ifdef IS_DIGIT
+#undef IS_DIGIT
+#endif
+/*
+ * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+ */
+#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
+
+/*
+ * alphanum = alpha | digit
+ */
+
+#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
+
+/*
+ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+ */
+
+#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') ||     \
+    ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') ||    \
+    ((x) == '(') || ((x) == ')'))
+
+/*
+ * unwise = "{" | "}" | "|" | "\" | "^" | "`"
+ */
+
+#define IS_UNWISE(p)                                                    \
+      (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) ||         \
+       ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) ||        \
+       ((*(p) == ']')) || ((*(p) == '`')))
+/*
+ * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," |
+ *            "[" | "]"
+ */
+
+#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
+        ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
+        ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \
+        ((x) == ']'))
+
+/*
+ * unreserved = alphanum | mark
+ */
+
+#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
+
+/*
+ * Skip to next pointer char, handle escaped sequences
+ */
+
+#define NEXT(p) ((*p == '%')? p += 3 : p++)
+
+/*
+ * Productions from the spec.
+ *
+ *    authority     = server | reg_name
+ *    reg_name      = 1*( unreserved | escaped | "$" | "," |
+ *                        ";" | ":" | "@" | "&" | "=" | "+" )
+ *
+ * path          = [ abs_path | opaque_part ]
+ */
+
+#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n))
+
+/************************************************************************
+ *									*
+ *                         RFC 3986 parser				*
+ *									*
+ ************************************************************************/
+
+#define ISA_DIGIT(p) ((*(p) >= '0') && (*(p) <= '9'))
+#define ISA_ALPHA(p) (((*(p) >= 'a') && (*(p) <= 'z')) ||		\
+                      ((*(p) >= 'A') && (*(p) <= 'Z')))
+#define ISA_HEXDIG(p)							\
+       (ISA_DIGIT(p) || ((*(p) >= 'a') && (*(p) <= 'f')) ||		\
+        ((*(p) >= 'A') && (*(p) <= 'F')))
+
+/*
+ *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+ *                     / "*" / "+" / "," / ";" / "="
+ */
+#define ISA_SUB_DELIM(p)						\
+      (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) ||		\
+       ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) ||		\
+       ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) ||		\
+       ((*(p) == '=')))
+
+/*
+ *    gen-delims    = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+ */
+#define ISA_GEN_DELIM(p)						\
+      (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) ||         \
+       ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) ||         \
+       ((*(p) == '@')))
+
+/*
+ *    reserved      = gen-delims / sub-delims
+ */
+#define ISA_RESERVED(p) (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p)))
+
+/*
+ *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ */
+#define ISA_UNRESERVED(p)						\
+      ((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) ||		\
+       ((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~')))
+
+/*
+ *    pct-encoded   = "%" HEXDIG HEXDIG
+ */
+#define ISA_PCT_ENCODED(p)						\
+     ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2)))
+
+/*
+ *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+ */
+#define ISA_PCHAR(p)							\
+     (ISA_UNRESERVED(p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) ||	\
+      ((*(p) == ':')) || ((*(p) == '@')))
+
+/**
+ * xmlParse3986Scheme:
+ * @uri:  pointer to an URI structure
+ * @str:  pointer to the string to analyze
+ *
+ * Parse an URI scheme
+ *
+ * ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Scheme(xmlURIPtr uri, const char **str) {
+    const char *cur;
+
+    if (str == NULL)
+	return(-1);
+
+    cur = *str;
+    if (!ISA_ALPHA(cur))
+	return(2);
+    cur++;
+    while (ISA_ALPHA(cur) || ISA_DIGIT(cur) ||
+           (*cur == '+') || (*cur == '-') || (*cur == '.')) cur++;
+    if (uri != NULL) {
+	if (uri->scheme != NULL) xmlFree(uri->scheme);
+	uri->scheme = STRNDUP(*str, cur - *str);
+    }
+    *str = cur;
+    return(0);
+}
+
+/**
+ * xmlParse3986Fragment:
+ * @uri:  pointer to an URI structure
+ * @str:  pointer to the string to analyze
+ *
+ * Parse the query part of an URI
+ *
+ * fragment      = *( pchar / "/" / "?" )
+ * NOTE: the strict syntax as defined by 3986 does not allow '[' and ']'
+ *       in the fragment identifier but this is used very broadly for
+ *       xpointer scheme selection, so we are allowing it here to not break
+ *       for example all the DocBook processing chains.
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Fragment(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+
+    if (str == NULL)
+        return (-1);
+
+    cur = *str;
+
+    while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
+           (*cur == '[') || (*cur == ']') ||
+           ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
+        NEXT(cur);
+    if (uri != NULL) {
+        if (uri->fragment != NULL)
+            xmlFree(uri->fragment);
+	if (uri->cleanup & 2)
+	    uri->fragment = STRNDUP(*str, cur - *str);
+	else
+	    uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
+    }
+    *str = cur;
+    return (0);
+}
+
+/**
+ * xmlParse3986Query:
+ * @uri:  pointer to an URI structure
+ * @str:  pointer to the string to analyze
+ *
+ * Parse the query part of an URI
+ *
+ * query = *uric
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Query(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+
+    if (str == NULL)
+        return (-1);
+
+    cur = *str;
+
+    while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
+           ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
+        NEXT(cur);
+    if (uri != NULL) {
+        if (uri->query != NULL)
+            xmlFree(uri->query);
+	if (uri->cleanup & 2)
+	    uri->query = STRNDUP(*str, cur - *str);
+	else
+	    uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
+
+	/* Save the raw bytes of the query as well.
+	 * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114
+	 */
+	if (uri->query_raw != NULL)
+	    xmlFree (uri->query_raw);
+	uri->query_raw = STRNDUP (*str, cur - *str);
+    }
+    *str = cur;
+    return (0);
+}
+
+/**
+ * xmlParse3986Port:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse a port  part and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * port          = *DIGIT
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Port(xmlURIPtr uri, const char **str)
+{
+    const char *cur = *str;
+
+    if (ISA_DIGIT(cur)) {
+	if (uri != NULL)
+	    uri->port = 0;
+	while (ISA_DIGIT(cur)) {
+	    if (uri != NULL)
+		uri->port = uri->port * 10 + (*cur - '0');
+	    cur++;
+	}
+	*str = cur;
+	return(0);
+    }
+    return(1);
+}
+
+/**
+ * xmlParse3986Userinfo:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an user informations part and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Userinfo(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+
+    cur = *str;
+    while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) ||
+           ISA_SUB_DELIM(cur) || (*cur == ':'))
+	NEXT(cur);
+    if (*cur == '@') {
+	if (uri != NULL) {
+	    if (uri->user != NULL) xmlFree(uri->user);
+	    if (uri->cleanup & 2)
+		uri->user = STRNDUP(*str, cur - *str);
+	    else
+		uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
+	}
+	*str = cur;
+	return(0);
+    }
+    return(1);
+}
+
+/**
+ * xmlParse3986DecOctet:
+ * @str:  the string to analyze
+ *
+ *    dec-octet     = DIGIT                 ; 0-9
+ *                  / %x31-39 DIGIT         ; 10-99
+ *                  / "1" 2DIGIT            ; 100-199
+ *                  / "2" %x30-34 DIGIT     ; 200-249
+ *                  / "25" %x30-35          ; 250-255
+ *
+ * Skip a dec-octet.
+ *
+ * Returns 0 if found and skipped, 1 otherwise
+ */
+static int
+xmlParse3986DecOctet(const char **str) {
+    const char *cur = *str;
+
+    if (!(ISA_DIGIT(cur)))
+        return(1);
+    if (!ISA_DIGIT(cur+1))
+	cur++;
+    else if ((*cur != '0') && (ISA_DIGIT(cur + 1)) && (!ISA_DIGIT(cur+2)))
+	cur += 2;
+    else if ((*cur == '1') && (ISA_DIGIT(cur + 1)) && (ISA_DIGIT(cur + 2)))
+	cur += 3;
+    else if ((*cur == '2') && (*(cur + 1) >= '0') &&
+	     (*(cur + 1) <= '4') && (ISA_DIGIT(cur + 2)))
+	cur += 3;
+    else if ((*cur == '2') && (*(cur + 1) == '5') &&
+	     (*(cur + 2) >= '0') && (*(cur + 1) <= '5'))
+	cur += 3;
+    else
+        return(1);
+    *str = cur;
+    return(0);
+}
+/**
+ * xmlParse3986Host:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an host part and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * host          = IP-literal / IPv4address / reg-name
+ * IP-literal    = "[" ( IPv6address / IPvFuture  ) "]"
+ * IPv4address   = dec-octet "." dec-octet "." dec-octet "." dec-octet
+ * reg-name      = *( unreserved / pct-encoded / sub-delims )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Host(xmlURIPtr uri, const char **str)
+{
+    const char *cur = *str;
+    const char *host;
+
+    host = cur;
+    /*
+     * IPv6 and future adressing scheme are enclosed between brackets
+     */
+    if (*cur == '[') {
+        cur++;
+	while ((*cur != ']') && (*cur != 0))
+	    cur++;
+	if (*cur != ']')
+	    return(1);
+	cur++;
+	goto found;
+    }
+    /*
+     * try to parse an IPv4
+     */
+    if (ISA_DIGIT(cur)) {
+        if (xmlParse3986DecOctet(&cur) != 0)
+	    goto not_ipv4;
+	if (*cur != '.')
+	    goto not_ipv4;
+	cur++;
+        if (xmlParse3986DecOctet(&cur) != 0)
+	    goto not_ipv4;
+	if (*cur != '.')
+	    goto not_ipv4;
+        if (xmlParse3986DecOctet(&cur) != 0)
+	    goto not_ipv4;
+	if (*cur != '.')
+	    goto not_ipv4;
+        if (xmlParse3986DecOctet(&cur) != 0)
+	    goto not_ipv4;
+	goto found;
+not_ipv4:
+        cur = *str;
+    }
+    /*
+     * then this should be a hostname which can be empty
+     */
+    while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur))
+        NEXT(cur);
+found:
+    if (uri != NULL) {
+	if (uri->authority != NULL) xmlFree(uri->authority);
+	uri->authority = NULL;
+	if (uri->server != NULL) xmlFree(uri->server);
+	if (cur != host) {
+	    if (uri->cleanup & 2)
+		uri->server = STRNDUP(host, cur - host);
+	    else
+		uri->server = xmlURIUnescapeString(host, cur - host, NULL);
+	} else
+	    uri->server = NULL;
+    }
+    *str = cur;
+    return(0);
+}
+
+/**
+ * xmlParse3986Authority:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an authority part and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * authority     = [ userinfo "@" ] host [ ":" port ]
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Authority(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+    /*
+     * try to parse an userinfo and check for the trailing @
+     */
+    ret = xmlParse3986Userinfo(uri, &cur);
+    if ((ret != 0) || (*cur != '@'))
+        cur = *str;
+    else
+        cur++;
+    ret = xmlParse3986Host(uri, &cur);
+    if (ret != 0) return(ret);
+    if (*cur == ':') {
+        cur++;
+        ret = xmlParse3986Port(uri, &cur);
+	if (ret != 0) return(ret);
+    }
+    *str = cur;
+    return(0);
+}
+
+/**
+ * xmlParse3986Segment:
+ * @str:  the string to analyze
+ * @forbid: an optional forbidden character
+ * @empty: allow an empty segment
+ *
+ * Parse a segment and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * segment       = *pchar
+ * segment-nz    = 1*pchar
+ * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+ *               ; non-zero-length segment without any colon ":"
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986Segment(const char **str, char forbid, int empty)
+{
+    const char *cur;
+
+    cur = *str;
+    if (!ISA_PCHAR(cur)) {
+        if (empty)
+	    return(0);
+	return(1);
+    }
+    while (ISA_PCHAR(cur) && (*cur != forbid))
+        NEXT(cur);
+    *str = cur;
+    return (0);
+}
+
+/**
+ * xmlParse3986PathAbEmpty:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an path absolute or empty and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * path-abempty  = *( "/" segment )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+
+    while (*cur == '/') {
+        cur++;
+	ret = xmlParse3986Segment(&cur, 0, 1);
+	if (ret != 0) return(ret);
+    }
+    if (uri != NULL) {
+	if (uri->path != NULL) xmlFree(uri->path);
+        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);
+}
+
+/**
+ * xmlParse3986PathAbsolute:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an path absolute and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * path-absolute = "/" [ segment-nz *( "/" segment ) ]
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986PathAbsolute(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+
+    if (*cur != '/')
+        return(1);
+    cur++;
+    ret = xmlParse3986Segment(&cur, 0, 0);
+    if (ret == 0) {
+	while (*cur == '/') {
+	    cur++;
+	    ret = xmlParse3986Segment(&cur, 0, 1);
+	    if (ret != 0) return(ret);
+	}
+    }
+    if (uri != NULL) {
+	if (uri->path != NULL) xmlFree(uri->path);
+        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);
+}
+
+/**
+ * xmlParse3986PathRootless:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an path without root and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * path-rootless = segment-nz *( "/" segment )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986PathRootless(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+
+    ret = xmlParse3986Segment(&cur, 0, 0);
+    if (ret != 0) return(ret);
+    while (*cur == '/') {
+        cur++;
+	ret = xmlParse3986Segment(&cur, 0, 1);
+	if (ret != 0) return(ret);
+    }
+    if (uri != NULL) {
+	if (uri->path != NULL) xmlFree(uri->path);
+        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);
+}
+
+/**
+ * xmlParse3986PathNoScheme:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an path which is not a scheme and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * path-noscheme = segment-nz-nc *( "/" segment )
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986PathNoScheme(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+
+    ret = xmlParse3986Segment(&cur, ':', 0);
+    if (ret != 0) return(ret);
+    while (*cur == '/') {
+        cur++;
+	ret = xmlParse3986Segment(&cur, 0, 1);
+	if (ret != 0) return(ret);
+    }
+    if (uri != NULL) {
+	if (uri->path != NULL) xmlFree(uri->path);
+        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);
+}
+
+/**
+ * xmlParse3986HierPart:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an hierarchical part and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * hier-part     = "//" authority path-abempty
+ *                / path-absolute
+ *                / path-rootless
+ *                / path-empty
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986HierPart(xmlURIPtr uri, const char **str)
+{
+    const char *cur;
+    int ret;
+
+    cur = *str;
+
+    if ((*cur == '/') && (*(cur + 1) == '/')) {
+        cur += 2;
+	ret = xmlParse3986Authority(uri, &cur);
+	if (ret != 0) return(ret);
+	ret = xmlParse3986PathAbEmpty(uri, &cur);
+	if (ret != 0) return(ret);
+	*str = cur;
+	return(0);
+    } else if (*cur == '/') {
+        ret = xmlParse3986PathAbsolute(uri, &cur);
+	if (ret != 0) return(ret);
+    } else if (ISA_PCHAR(cur)) {
+        ret = xmlParse3986PathRootless(uri, &cur);
+	if (ret != 0) return(ret);
+    } else {
+	/* path-empty is effectively empty */
+	if (uri != NULL) {
+	    if (uri->path != NULL) xmlFree(uri->path);
+	    uri->path = NULL;
+	}
+    }
+    *str = cur;
+    return (0);
+}
+
+/**
+ * xmlParse3986RelativeRef:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an URI string and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
+ * relative-part = "//" authority path-abempty
+ *               / path-absolute
+ *               / path-noscheme
+ *               / path-empty
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986RelativeRef(xmlURIPtr uri, const char *str) {
+    int ret;
+
+    if ((*str == '/') && (*(str + 1) == '/')) {
+        str += 2;
+	ret = xmlParse3986Authority(uri, &str);
+	if (ret != 0) return(ret);
+	ret = xmlParse3986PathAbEmpty(uri, &str);
+	if (ret != 0) return(ret);
+    } else if (*str == '/') {
+	ret = xmlParse3986PathAbsolute(uri, &str);
+	if (ret != 0) return(ret);
+    } else if (ISA_PCHAR(str)) {
+        ret = xmlParse3986PathNoScheme(uri, &str);
+	if (ret != 0) return(ret);
+    } else {
+	/* path-empty is effectively empty */
+	if (uri != NULL) {
+	    if (uri->path != NULL) xmlFree(uri->path);
+	    uri->path = NULL;
+	}
+    }
+
+    if (*str == '?') {
+	str++;
+	ret = xmlParse3986Query(uri, &str);
+	if (ret != 0) return(ret);
+    }
+    if (*str == '#') {
+	str++;
+	ret = xmlParse3986Fragment(uri, &str);
+	if (ret != 0) return(ret);
+    }
+    if (*str != 0) {
+	xmlCleanURI(uri);
+	return(1);
+    }
+    return(0);
+}
+
+
+/**
+ * xmlParse3986URI:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an URI string and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986URI(xmlURIPtr uri, const char *str) {
+    int ret;
+
+    ret = xmlParse3986Scheme(uri, &str);
+    if (ret != 0) return(ret);
+    if (*str != ':') {
+	return(1);
+    }
+    str++;
+    ret = xmlParse3986HierPart(uri, &str);
+    if (ret != 0) return(ret);
+    if (*str == '?') {
+	str++;
+	ret = xmlParse3986Query(uri, &str);
+	if (ret != 0) return(ret);
+    }
+    if (*str == '#') {
+	str++;
+	ret = xmlParse3986Fragment(uri, &str);
+	if (ret != 0) return(ret);
+    }
+    if (*str != 0) {
+	xmlCleanURI(uri);
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlParse3986URIReference:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an URI reference string and fills in the appropriate fields
+ * of the @uri structure
+ *
+ * URI-reference = URI / relative-ref
+ *
+ * Returns 0 or the error code
+ */
+static int
+xmlParse3986URIReference(xmlURIPtr uri, const char *str) {
+    int ret;
+
+    if (str == NULL)
+	return(-1);
+    xmlCleanURI(uri);
+
+    /*
+     * Try first to parse absolute refs, then fallback to relative if
+     * it fails.
+     */
+    ret = xmlParse3986URI(uri, str);
+    if (ret != 0) {
+	xmlCleanURI(uri);
+        ret = xmlParse3986RelativeRef(uri, str);
+	if (ret != 0) {
+	    xmlCleanURI(uri);
+	    return(ret);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlParseURI:
+ * @str:  the URI string to analyze
+ *
+ * Parse an URI based on RFC 3986
+ *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ *
+ * Returns a newly built xmlURIPtr or NULL in case of error
+ */
+xmlURIPtr
+xmlParseURI(const char *str) {
+    xmlURIPtr uri;
+    int ret;
+
+    if (str == NULL)
+	return(NULL);
+    uri = xmlCreateURI();
+    if (uri != NULL) {
+	ret = xmlParse3986URIReference(uri, str);
+        if (ret) {
+	    xmlFreeURI(uri);
+	    return(NULL);
+	}
+    }
+    return(uri);
+}
+
+/**
+ * xmlParseURIReference:
+ * @uri:  pointer to an URI structure
+ * @str:  the string to analyze
+ *
+ * Parse an URI reference string based on RFC 3986 and fills in the
+ * appropriate fields of the @uri structure
+ *
+ * URI-reference = URI / relative-ref
+ *
+ * Returns 0 or the error code
+ */
+int
+xmlParseURIReference(xmlURIPtr uri, const char *str) {
+    return(xmlParse3986URIReference(uri, str));
+}
+
+/**
+ * xmlParseURIRaw:
+ * @str:  the URI string to analyze
+ * @raw:  if 1 unescaping of URI pieces are disabled
+ *
+ * Parse an URI but allows to keep intact the original fragments.
+ *
+ * URI-reference = URI / relative-ref
+ *
+ * Returns a newly built xmlURIPtr or NULL in case of error
+ */
+xmlURIPtr
+xmlParseURIRaw(const char *str, int raw) {
+    xmlURIPtr uri;
+    int ret;
+
+    if (str == NULL)
+	return(NULL);
+    uri = xmlCreateURI();
+    if (uri != NULL) {
+        if (raw) {
+	    uri->cleanup |= 2;
+	}
+	ret = xmlParseURIReference(uri, str);
+        if (ret) {
+	    xmlFreeURI(uri);
+	    return(NULL);
+	}
+    }
+    return(uri);
+}
+
+/************************************************************************
+ *									*
+ *			Generic URI structure functions			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlCreateURI:
+ *
+ * Simply creates an empty xmlURI
+ *
+ * Returns the new structure or NULL in case of error
+ */
+xmlURIPtr
+xmlCreateURI(void) {
+    xmlURIPtr ret;
+
+    ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
+    if (ret == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlCreateURI: out of memory\n");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlURI));
+    return(ret);
+}
+
+/**
+ * xmlSaveUri:
+ * @uri:  pointer to an xmlURI
+ *
+ * Save the URI as an escaped string
+ *
+ * Returns a new string (to be deallocated by caller)
+ */
+xmlChar *
+xmlSaveUri(xmlURIPtr uri) {
+    xmlChar *ret = NULL;
+    xmlChar *temp;
+    const char *p;
+    int len;
+    int max;
+
+    if (uri == NULL) return(NULL);
+
+
+    max = 80;
+    ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlSaveUri: out of memory\n");
+	return(NULL);
+    }
+    len = 0;
+
+    if (uri->scheme != NULL) {
+	p = uri->scheme;
+	while (*p != 0) {
+	    if (len >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "xmlSaveUri: out of memory\n");
+		    xmlFree(ret);
+		    return(NULL);
+		}
+		ret = temp;
+	    }
+	    ret[len++] = *p++;
+	}
+	if (len >= max) {
+	    max *= 2;
+	    temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
+	    if (temp == NULL) {
+		xmlGenericError(xmlGenericErrorContext,
+			"xmlSaveUri: out of memory\n");
+		xmlFree(ret);
+		return(NULL);
+	    }
+	    ret = temp;
+	}
+	ret[len++] = ':';
+    }
+    if (uri->opaque != NULL) {
+	p = uri->opaque;
+	while (*p != 0) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "xmlSaveUri: out of memory\n");
+		    xmlFree(ret);
+		    return(NULL);
+		}
+		ret = temp;
+	    }
+	    if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p)))
+		ret[len++] = *p++;
+	    else {
+		int val = *(unsigned char *)p++;
+		int hi = val / 0x10, lo = val % 0x10;
+		ret[len++] = '%';
+		ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+		ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+	    }
+	}
+    } else {
+	if (uri->server != NULL) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "xmlSaveUri: out of memory\n");
+                  xmlFree(ret);  
+		    return(NULL);
+		}
+		ret = temp;
+	    }
+	    ret[len++] = '/';
+	    ret[len++] = '/';
+	    if (uri->user != NULL) {
+		p = uri->user;
+		while (*p != 0) {
+		    if (len + 3 >= max) {
+			max *= 2;
+			temp = (xmlChar *) xmlRealloc(ret,
+				(max + 1) * sizeof(xmlChar));
+			if (temp == NULL) {
+			    xmlGenericError(xmlGenericErrorContext,
+				    "xmlSaveUri: out of memory\n");
+			    xmlFree(ret);
+			    return(NULL);
+			}
+			ret = temp;
+		    }
+		    if ((IS_UNRESERVED(*(p))) ||
+			((*(p) == ';')) || ((*(p) == ':')) ||
+			((*(p) == '&')) || ((*(p) == '=')) ||
+			((*(p) == '+')) || ((*(p) == '$')) ||
+			((*(p) == ',')))
+			ret[len++] = *p++;
+		    else {
+			int val = *(unsigned char *)p++;
+			int hi = val / 0x10, lo = val % 0x10;
+			ret[len++] = '%';
+			ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+			ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+		    }
+		}
+		if (len + 3 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+			xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		ret[len++] = '@';
+	    }
+	    p = uri->server;
+	    while (*p != 0) {
+		if (len >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+			xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		ret[len++] = *p++;
+	    }
+	    if (uri->port > 0) {
+		if (len + 10 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
+	    }
+	} else if (uri->authority != NULL) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret,
+			(max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	    }
+	    ret[len++] = '/';
+	    ret[len++] = '/';
+	    p = uri->authority;
+	    while (*p != 0) {
+		if (len + 3 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		if ((IS_UNRESERVED(*(p))) ||
+                    ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
+                    ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
+                    ((*(p) == '=')) || ((*(p) == '+')))
+		    ret[len++] = *p++;
+		else {
+		    int val = *(unsigned char *)p++;
+		    int hi = val / 0x10, lo = val % 0x10;
+		    ret[len++] = '%';
+		    ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+		    ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+		}
+	    }
+	} else if (uri->scheme != NULL) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret,
+			(max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	    }
+	    ret[len++] = '/';
+	    ret[len++] = '/';
+	}
+	if (uri->path != NULL) {
+	    p = uri->path;
+	    /*
+	     * the colon in file:///d: should not be escaped or
+	     * Windows accesses fail later.
+	     */
+	    if ((uri->scheme != NULL) &&
+		(p[0] == '/') &&
+		(((p[1] >= 'a') && (p[1] <= 'z')) ||
+		 ((p[1] >= 'A') && (p[1] <= 'Z'))) &&
+		(p[2] == ':') &&
+	        (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
+		if (len + 3 >= max) {
+		    max *= 2;
+		    ret = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (ret == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+			return(NULL);
+		    }
+		}
+		ret[len++] = *p++;
+		ret[len++] = *p++;
+		ret[len++] = *p++;
+	    }
+	    while (*p != 0) {
+		if (len + 3 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
+                    ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
+	            ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
+	            ((*(p) == ',')))
+		    ret[len++] = *p++;
+		else {
+		    int val = *(unsigned char *)p++;
+		    int hi = val / 0x10, lo = val % 0x10;
+		    ret[len++] = '%';
+		    ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+		    ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+		}
+	    }
+	}
+	if (uri->query_raw != NULL) {
+	    if (len + 1 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret,
+			(max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	    }
+	    ret[len++] = '?';
+	    p = uri->query_raw;
+	    while (*p != 0) {
+		if (len + 1 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		ret[len++] = *p++;
+	    }
+	} else if (uri->query != NULL) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret,
+			(max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	    }
+	    ret[len++] = '?';
+	    p = uri->query;
+	    while (*p != 0) {
+		if (len + 3 >= max) {
+		    max *= 2;
+		    temp = (xmlChar *) xmlRealloc(ret,
+			    (max + 1) * sizeof(xmlChar));
+		    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+		}
+		if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 
+		    ret[len++] = *p++;
+		else {
+		    int val = *(unsigned char *)p++;
+		    int hi = val / 0x10, lo = val % 0x10;
+		    ret[len++] = '%';
+		    ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+		    ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+		}
+	    }
+	}
+    }
+    if (uri->fragment != NULL) {
+	if (len + 3 >= max) {
+	    max *= 2;
+	    temp = (xmlChar *) xmlRealloc(ret,
+		    (max + 1) * sizeof(xmlChar));
+	    if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	}
+	ret[len++] = '#';
+	p = uri->fragment;
+	while (*p != 0) {
+	    if (len + 3 >= max) {
+		max *= 2;
+		temp = (xmlChar *) xmlRealloc(ret,
+			(max + 1) * sizeof(xmlChar));
+		if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+	    }
+	    if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 
+		ret[len++] = *p++;
+	    else {
+		int val = *(unsigned char *)p++;
+		int hi = val / 0x10, lo = val % 0x10;
+		ret[len++] = '%';
+		ret[len++] = hi + (hi > 9? 'A'-10 : '0');
+		ret[len++] = lo + (lo > 9? 'A'-10 : '0');
+	    }
+	}
+    }
+    if (len >= max) {
+	max *= 2;
+	temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
+	if (temp == NULL) {
+			xmlGenericError(xmlGenericErrorContext,
+				"xmlSaveUri: out of memory\n");
+                     xmlFree(ret);
+			return(NULL);
+		    }
+		    ret = temp;
+    }
+    ret[len] = 0;
+    return(ret);
+}
+
+/**
+ * xmlPrintURI:
+ * @stream:  a FILE* for the output
+ * @uri:  pointer to an xmlURI
+ *
+ * Prints the URI in the stream @stream.
+ */
+void
+xmlPrintURI(FILE *stream, xmlURIPtr uri) {
+    xmlChar *out;
+
+    out = xmlSaveUri(uri);
+    if (out != NULL) {
+	fprintf(stream, "%s", (char *) out);
+	xmlFree(out);
+    }
+}
+
+/**
+ * xmlCleanURI:
+ * @uri:  pointer to an xmlURI
+ *
+ * Make sure the xmlURI struct is free of content
+ */
+static void
+xmlCleanURI(xmlURIPtr uri) {
+    if (uri == NULL) return;
+
+    if (uri->scheme != NULL) xmlFree(uri->scheme);
+    uri->scheme = NULL;
+    if (uri->server != NULL) xmlFree(uri->server);
+    uri->server = NULL;
+    if (uri->user != NULL) xmlFree(uri->user);
+    uri->user = NULL;
+    if (uri->path != NULL) xmlFree(uri->path);
+    uri->path = NULL;
+    if (uri->fragment != NULL) xmlFree(uri->fragment);
+    uri->fragment = NULL;
+    if (uri->opaque != NULL) xmlFree(uri->opaque);
+    uri->opaque = NULL;
+    if (uri->authority != NULL) xmlFree(uri->authority);
+    uri->authority = NULL;
+    if (uri->query != NULL) xmlFree(uri->query);
+    uri->query = NULL;
+    if (uri->query_raw != NULL) xmlFree(uri->query_raw);
+    uri->query_raw = NULL;
+}
+
+/**
+ * xmlFreeURI:
+ * @uri:  pointer to an xmlURI
+ *
+ * Free up the xmlURI struct
+ */
+void
+xmlFreeURI(xmlURIPtr uri) {
+    if (uri == NULL) return;
+
+    if (uri->scheme != NULL) xmlFree(uri->scheme);
+    if (uri->server != NULL) xmlFree(uri->server);
+    if (uri->user != NULL) xmlFree(uri->user);
+    if (uri->path != NULL) xmlFree(uri->path);
+    if (uri->fragment != NULL) xmlFree(uri->fragment);
+    if (uri->opaque != NULL) xmlFree(uri->opaque);
+    if (uri->authority != NULL) xmlFree(uri->authority);
+    if (uri->query != NULL) xmlFree(uri->query);
+    if (uri->query_raw != NULL) xmlFree(uri->query_raw);
+    xmlFree(uri);
+}
+
+/************************************************************************
+ *									*
+ *			Helper functions				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlNormalizeURIPath:
+ * @path:  pointer to the path string
+ *
+ * Applies the 5 normalization steps to a path string--that is, RFC 2396
+ * Section 5.2, steps 6.c through 6.g.
+ *
+ * Normalization occurs directly on the string, no new allocation is done
+ *
+ * Returns 0 or an error code
+ */
+int
+xmlNormalizeURIPath(char *path) {
+    char *cur, *out;
+
+    if (path == NULL)
+	return(-1);
+
+    /* Skip all initial "/" chars.  We want to get to the beginning of the
+     * first non-empty segment.
+     */
+    cur = path;
+    while (cur[0] == '/')
+      ++cur;
+    if (cur[0] == '\0')
+      return(0);
+
+    /* Keep everything we've seen so far.  */
+    out = cur;
+
+    /*
+     * Analyze each segment in sequence for cases (c) and (d).
+     */
+    while (cur[0] != '\0') {
+	/*
+	 * c) All occurrences of "./", where "." is a complete path segment,
+	 *    are removed from the buffer string.
+	 */
+	if ((cur[0] == '.') && (cur[1] == '/')) {
+	    cur += 2;
+	    /* '//' normalization should be done at this point too */
+	    while (cur[0] == '/')
+		cur++;
+	    continue;
+	}
+
+	/*
+	 * d) If the buffer string ends with "." as a complete path segment,
+	 *    that "." is removed.
+	 */
+	if ((cur[0] == '.') && (cur[1] == '\0'))
+	    break;
+
+	/* Otherwise keep the segment.  */
+	while (cur[0] != '/') {
+            if (cur[0] == '\0')
+              goto done_cd;
+	    (out++)[0] = (cur++)[0];
+	}
+	/* nomalize // */
+	while ((cur[0] == '/') && (cur[1] == '/'))
+	    cur++;
+
+        (out++)[0] = (cur++)[0];
+    }
+ done_cd:
+    out[0] = '\0';
+
+    /* Reset to the beginning of the first segment for the next sequence.  */
+    cur = path;
+    while (cur[0] == '/')
+      ++cur;
+    if (cur[0] == '\0')
+	return(0);
+
+    /*
+     * Analyze each segment in sequence for cases (e) and (f).
+     *
+     * e) All occurrences of "<segment>/../", where <segment> is a
+     *    complete path segment not equal to "..", are removed from the
+     *    buffer string.  Removal of these path segments is performed
+     *    iteratively, removing the leftmost matching pattern on each
+     *    iteration, until no matching pattern remains.
+     *
+     * f) If the buffer string ends with "<segment>/..", where <segment>
+     *    is a complete path segment not equal to "..", that
+     *    "<segment>/.." is removed.
+     *
+     * To satisfy the "iterative" clause in (e), we need to collapse the
+     * string every time we find something that needs to be removed.  Thus,
+     * we don't need to keep two pointers into the string: we only need a
+     * "current position" pointer.
+     */
+    while (1) {
+        char *segp, *tmp;
+
+        /* At the beginning of each iteration of this loop, "cur" points to
+         * the first character of the segment we want to examine.
+         */
+
+        /* Find the end of the current segment.  */
+        segp = cur;
+        while ((segp[0] != '/') && (segp[0] != '\0'))
+          ++segp;
+
+        /* If this is the last segment, we're done (we need at least two
+         * segments to meet the criteria for the (e) and (f) cases).
+         */
+        if (segp[0] == '\0')
+          break;
+
+        /* If the first segment is "..", or if the next segment _isn't_ "..",
+         * keep this segment and try the next one.
+         */
+        ++segp;
+        if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
+            || ((segp[0] != '.') || (segp[1] != '.')
+                || ((segp[2] != '/') && (segp[2] != '\0')))) {
+          cur = segp;
+          continue;
+        }
+
+        /* If we get here, remove this segment and the next one and back up
+         * to the previous segment (if there is one), to implement the
+         * "iteratively" clause.  It's pretty much impossible to back up
+         * while maintaining two pointers into the buffer, so just compact
+         * the whole buffer now.
+         */
+
+        /* If this is the end of the buffer, we're done.  */
+        if (segp[2] == '\0') {
+          cur[0] = '\0';
+          break;
+        }
+        /* Valgrind complained, strcpy(cur, segp + 3); */
+	/* string will overlap, do not use strcpy */
+	tmp = cur;
+	segp += 3;
+	while ((*tmp++ = *segp++) != 0);
+
+        /* If there are no previous segments, then keep going from here.  */
+        segp = cur;
+        while ((segp > path) && ((--segp)[0] == '/'))
+          ;
+        if (segp == path)
+          continue;
+
+        /* "segp" is pointing to the end of a previous segment; find it's
+         * start.  We need to back up to the previous segment and start
+         * over with that to handle things like "foo/bar/../..".  If we
+         * don't do this, then on the first pass we'll remove the "bar/..",
+         * but be pointing at the second ".." so we won't realize we can also
+         * remove the "foo/..".
+         */
+        cur = segp;
+        while ((cur > path) && (cur[-1] != '/'))
+          --cur;
+    }
+    out[0] = '\0';
+
+    /*
+     * g) If the resulting buffer string still begins with one or more
+     *    complete path segments of "..", then the reference is
+     *    considered to be in error. Implementations may handle this
+     *    error by retaining these components in the resolved path (i.e.,
+     *    treating them as part of the final URI), by removing them from
+     *    the resolved path (i.e., discarding relative levels above the
+     *    root), or by avoiding traversal of the reference.
+     *
+     * We discard them from the final path.
+     */
+    if (path[0] == '/') {
+      cur = path;
+      while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.')
+             && ((cur[3] == '/') || (cur[3] == '\0')))
+	cur += 3;
+
+      if (cur != path) {
+	out = path;
+	while (cur[0] != '\0')
+          (out++)[0] = (cur++)[0];
+	out[0] = 0;
+      }
+    }
+
+    return(0);
+}
+
+static int is_hex(char c) {
+    if (((c >= '0') && (c <= '9')) ||
+        ((c >= 'a') && (c <= 'f')) ||
+        ((c >= 'A') && (c <= 'F')))
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlURIUnescapeString:
+ * @str:  the string to unescape
+ * @len:   the length in bytes to unescape (or <= 0 to indicate full string)
+ * @target:  optional destination buffer
+ *
+ * Unescaping routine, but does not check that the string is an URI. The
+ * output is a direct unsigned char translation of %XX values (no encoding)
+ * Note that the length of the result can only be smaller or same size as
+ * the input string.
+ *
+ * Returns a copy of the string, but unescaped, will return NULL only in case
+ * of error
+ */
+char *
+xmlURIUnescapeString(const char *str, int len, char *target) {
+    char *ret, *out;
+    const char *in;
+
+    if (str == NULL)
+	return(NULL);
+    if (len <= 0) len = strlen(str);
+    if (len < 0) return(NULL);
+
+    if (target == NULL) {
+	ret = (char *) xmlMallocAtomic(len + 1);
+	if (ret == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "xmlURIUnescapeString: out of memory\n");
+	    return(NULL);
+	}
+    } else
+	ret = target;
+    in = str;
+    out = ret;
+    while(len > 0) {
+	if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {
+	    in++;
+	    if ((*in >= '0') && (*in <= '9')) 
+	        *out = (*in - '0');
+	    else if ((*in >= 'a') && (*in <= 'f'))
+	        *out = (*in - 'a') + 10;
+	    else if ((*in >= 'A') && (*in <= 'F'))
+	        *out = (*in - 'A') + 10;
+	    in++;
+	    if ((*in >= '0') && (*in <= '9')) 
+	        *out = *out * 16 + (*in - '0');
+	    else if ((*in >= 'a') && (*in <= 'f'))
+	        *out = *out * 16 + (*in - 'a') + 10;
+	    else if ((*in >= 'A') && (*in <= 'F'))
+	        *out = *out * 16 + (*in - 'A') + 10;
+	    in++;
+	    len -= 3;
+	    out++;
+	} else {
+	    *out++ = *in++;
+	    len--;
+	}
+    }
+    *out = 0;
+    return(ret);
+}
+
+/**
+ * xmlURIEscapeStr:
+ * @str:  string to escape
+ * @list: exception list string of chars not to escape
+ *
+ * This routine escapes a string to hex, ignoring reserved characters (a-z)
+ * and the characters in the exception list.
+ *
+ * Returns a new escaped string or NULL in case of error.
+ */
+xmlChar *
+xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
+    xmlChar *ret, ch;
+    xmlChar *temp;
+    const xmlChar *in;
+
+    unsigned int len, out;
+
+    if (str == NULL)
+	return(NULL);
+    if (str[0] == 0)
+	return(xmlStrdup(str));
+    len = xmlStrlen(str);
+    if (!(len > 0)) return(NULL);
+
+    len += 20;
+    ret = (xmlChar *) xmlMallocAtomic(len);
+    if (ret == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlURIEscapeStr: out of memory\n");
+	return(NULL);
+    }
+    in = (const xmlChar *) str;
+    out = 0;
+    while(*in != 0) {
+	if (len - out <= 3) {
+	    len += 20;
+	    temp = (xmlChar *) xmlRealloc(ret, len);
+	    if (temp == NULL) {
+		xmlGenericError(xmlGenericErrorContext,
+			"xmlURIEscapeStr: out of memory\n");
+		xmlFree(ret);
+		return(NULL);
+	    }
+	    ret = temp;
+	}
+
+	ch = *in;
+
+	if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {
+	    unsigned char val;
+	    ret[out++] = '%';
+	    val = ch >> 4;
+	    if (val <= 9)
+		ret[out++] = '0' + val;
+	    else
+		ret[out++] = 'A' + val - 0xA;
+	    val = ch & 0xF;
+	    if (val <= 9)
+		ret[out++] = '0' + val;
+	    else
+		ret[out++] = 'A' + val - 0xA;
+	    in++;
+	} else {
+	    ret[out++] = *in++;
+	}
+
+    }
+    ret[out] = 0;
+    return(ret);
+}
+
+/**
+ * xmlURIEscape:
+ * @str:  the string of the URI to escape
+ *
+ * Escaping routine, does not do validity checks !
+ * It will try to escape the chars needing this, but this is heuristic
+ * based it's impossible to be sure.
+ *
+ * Returns an copy of the string, but escaped
+ *
+ * 25 May 2001
+ * Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly
+ * according to RFC2396.
+ *   - Carl Douglas
+ */
+xmlChar *
+xmlURIEscape(const xmlChar * str)
+{
+    xmlChar *ret, *segment = NULL;
+    xmlURIPtr uri;
+    int ret2;
+
+#define NULLCHK(p) if(!p) { \
+                   xmlGenericError(xmlGenericErrorContext, \
+                        "xmlURIEscape: out of memory\n"); \
+                        xmlFreeURI(uri); \
+                        return NULL; } \
+
+    if (str == NULL)
+        return (NULL);
+
+    uri = xmlCreateURI();
+    if (uri != NULL) {
+	/*
+	 * Allow escaping errors in the unescaped form
+	 */
+        uri->cleanup = 1;
+        ret2 = xmlParseURIReference(uri, (const char *)str);
+        if (ret2) {
+            xmlFreeURI(uri);
+            return (NULL);
+        }
+    }
+
+    if (!uri)
+        return NULL;
+
+    ret = NULL;
+
+    if (uri->scheme) {
+        segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-.");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, segment);
+        ret = xmlStrcat(ret, BAD_CAST ":");
+        xmlFree(segment);
+    }
+
+    if (uri->authority) {
+        segment =
+            xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, BAD_CAST "//");
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    if (uri->user) {
+        segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,");
+        NULLCHK(segment)
+		ret = xmlStrcat(ret,BAD_CAST "//");	
+        ret = xmlStrcat(ret, segment);
+        ret = xmlStrcat(ret, BAD_CAST "@");
+        xmlFree(segment);
+    }
+
+    if (uri->server) {
+        segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@");
+        NULLCHK(segment)
+		if (uri->user == NULL)
+		ret = xmlStrcat(ret, BAD_CAST "//");
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    if (uri->port) {
+        xmlChar port[10];
+
+        snprintf((char *) port, 10, "%d", uri->port);
+        ret = xmlStrcat(ret, BAD_CAST ":");
+        ret = xmlStrcat(ret, port);
+    }
+
+    if (uri->path) {
+        segment =
+            xmlURIEscapeStr(BAD_CAST uri->path, BAD_CAST ":@&=+$,/?;");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    if (uri->query_raw) {
+        ret = xmlStrcat(ret, BAD_CAST "?");
+        ret = xmlStrcat(ret, BAD_CAST uri->query_raw);
+    }
+    else if (uri->query) {
+        segment =
+            xmlURIEscapeStr(BAD_CAST uri->query, BAD_CAST ";/?:@&=+,$");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, BAD_CAST "?");
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    if (uri->opaque) {
+        segment = xmlURIEscapeStr(BAD_CAST uri->opaque, BAD_CAST "");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    if (uri->fragment) {
+        segment = xmlURIEscapeStr(BAD_CAST uri->fragment, BAD_CAST "#");
+        NULLCHK(segment)
+        ret = xmlStrcat(ret, BAD_CAST "#");
+        ret = xmlStrcat(ret, segment);
+        xmlFree(segment);
+    }
+
+    xmlFreeURI(uri);
+#undef NULLCHK
+
+    return (ret);
+}
+
+/************************************************************************
+ *									*
+ *			Public functions				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlBuildURI:
+ * @URI:  the URI instance found in the document
+ * @base:  the base value
+ *
+ * Computes he final URI of the reference done by checking that
+ * the given URI is valid, and building the final URI using the
+ * base URI. This is processed according to section 5.2 of the 
+ * RFC 2396
+ *
+ * 5.2. Resolving Relative References to Absolute Form
+ *
+ * Returns a new URI string (to be freed by the caller) or NULL in case
+ *         of error.
+ */
+xmlChar *
+xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
+    xmlChar *val = NULL;
+    int ret, len, indx, cur, out;
+    xmlURIPtr ref = NULL;
+    xmlURIPtr bas = NULL;
+    xmlURIPtr res = NULL;
+
+    /*
+     * 1) The URI reference is parsed into the potential four components and
+     *    fragment identifier, as described in Section 4.3.
+     *
+     *    NOTE that a completely empty URI is treated by modern browsers
+     *    as a reference to "." rather than as a synonym for the current
+     *    URI.  Should we do that here?
+     */
+    if (URI == NULL) 
+	ret = -1;
+    else {
+	if (*URI) {
+	    ref = xmlCreateURI();
+	    if (ref == NULL)
+		goto done;
+	    ret = xmlParseURIReference(ref, (const char *) URI);
+	}
+	else
+	    ret = 0;
+    }
+    if (ret != 0)
+	goto done;
+    if ((ref != NULL) && (ref->scheme != NULL)) {
+	/*
+	 * The URI is absolute don't modify.
+	 */
+	val = xmlStrdup(URI);
+	goto done;
+    }
+    if (base == NULL)
+	ret = -1;
+    else {
+	bas = xmlCreateURI();
+	if (bas == NULL)
+	    goto done;
+	ret = xmlParseURIReference(bas, (const char *) base);
+    }
+    if (ret != 0) {
+	if (ref)
+	    val = xmlSaveUri(ref);
+	goto done;
+    }
+    if (ref == NULL) {
+	/*
+	 * the base fragment must be ignored
+	 */
+	if (bas->fragment != NULL) {
+	    xmlFree(bas->fragment);
+	    bas->fragment = NULL;
+	}
+	val = xmlSaveUri(bas);
+	goto done;
+    }
+
+    /*
+     * 2) If the path component is empty and the scheme, authority, and
+     *    query components are undefined, then it is a reference to the
+     *    current document and we are done.  Otherwise, the reference URI's
+     *    query and fragment components are defined as found (or not found)
+     *    within the URI reference and not inherited from the base URI.
+     *
+     *    NOTE that in modern browsers, the parsing differs from the above
+     *    in the following aspect:  the query component is allowed to be
+     *    defined while still treating this as a reference to the current
+     *    document.
+     */
+    res = xmlCreateURI();
+    if (res == NULL)
+	goto done;
+    if ((ref->scheme == NULL) && (ref->path == NULL) &&
+	((ref->authority == NULL) && (ref->server == NULL))) {
+	if (bas->scheme != NULL)
+	    res->scheme = xmlMemStrdup(bas->scheme);
+	if (bas->authority != NULL)
+	    res->authority = xmlMemStrdup(bas->authority);
+	else if (bas->server != NULL) {
+	    res->server = xmlMemStrdup(bas->server);
+	    if (bas->user != NULL)
+		res->user = xmlMemStrdup(bas->user);
+	    res->port = bas->port;		
+	}
+	if (bas->path != NULL)
+	    res->path = xmlMemStrdup(bas->path);
+	if (ref->query_raw != NULL)
+	    res->query_raw = xmlMemStrdup (ref->query_raw);
+	else if (ref->query != NULL)
+	    res->query = xmlMemStrdup(ref->query);
+	else if (bas->query_raw != NULL)
+	    res->query_raw = xmlMemStrdup(bas->query_raw);
+	else if (bas->query != NULL)
+	    res->query = xmlMemStrdup(bas->query);
+	if (ref->fragment != NULL)
+	    res->fragment = xmlMemStrdup(ref->fragment);
+	goto step_7;
+    }
+
+    /*
+     * 3) If the scheme component is defined, indicating that the reference
+     *    starts with a scheme name, then the reference is interpreted as an
+     *    absolute URI and we are done.  Otherwise, the reference URI's
+     *    scheme is inherited from the base URI's scheme component.
+     */
+    if (ref->scheme != NULL) {
+	val = xmlSaveUri(ref);
+	goto done;
+    }
+    if (bas->scheme != NULL)
+	res->scheme = xmlMemStrdup(bas->scheme);
+ 
+    if (ref->query_raw != NULL)
+	res->query_raw = xmlMemStrdup(ref->query_raw);
+    else if (ref->query != NULL)
+	res->query = xmlMemStrdup(ref->query);
+    if (ref->fragment != NULL)
+	res->fragment = xmlMemStrdup(ref->fragment);
+
+    /*
+     * 4) If the authority component is defined, then the reference is a
+     *    network-path and we skip to step 7.  Otherwise, the reference
+     *    URI's authority is inherited from the base URI's authority
+     *    component, which will also be undefined if the URI scheme does not
+     *    use an authority component.
+     */
+    if ((ref->authority != NULL) || (ref->server != NULL)) {
+	if (ref->authority != NULL)
+	    res->authority = xmlMemStrdup(ref->authority);
+	else {
+	    res->server = xmlMemStrdup(ref->server);
+	    if (ref->user != NULL)
+		res->user = xmlMemStrdup(ref->user);
+            res->port = ref->port;		
+	}
+	if (ref->path != NULL)
+	    res->path = xmlMemStrdup(ref->path);
+	goto step_7;
+    }
+    if (bas->authority != NULL)
+	res->authority = xmlMemStrdup(bas->authority);
+    else if (bas->server != NULL) {
+	res->server = xmlMemStrdup(bas->server);
+	if (bas->user != NULL)
+	    res->user = xmlMemStrdup(bas->user);
+	res->port = bas->port;		
+    }
+
+    /*
+     * 5) If the path component begins with a slash character ("/"), then
+     *    the reference is an absolute-path and we skip to step 7.
+     */
+    if ((ref->path != NULL) && (ref->path[0] == '/')) {
+	res->path = xmlMemStrdup(ref->path);
+	goto step_7;
+    }
+
+
+    /*
+     * 6) If this step is reached, then we are resolving a relative-path
+     *    reference.  The relative path needs to be merged with the base
+     *    URI's path.  Although there are many ways to do this, we will
+     *    describe a simple method using a separate string buffer.
+     *
+     * Allocate a buffer large enough for the result string.
+     */
+    len = 2; /* extra / and 0 */
+    if (ref->path != NULL)
+	len += strlen(ref->path);
+    if (bas->path != NULL)
+	len += strlen(bas->path);
+    res->path = (char *) xmlMallocAtomic(len);
+    if (res->path == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlBuildURI: out of memory\n");
+	goto done;
+    }
+    res->path[0] = 0;
+
+    /*
+     * a) All but the last segment of the base URI's path component is
+     *    copied to the buffer.  In other words, any characters after the
+     *    last (right-most) slash character, if any, are excluded.
+     */
+    cur = 0;
+    out = 0;
+    if (bas->path != NULL) {
+	while (bas->path[cur] != 0) {
+	    while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))
+		cur++;
+	    if (bas->path[cur] == 0)
+		break;
+
+	    cur++;
+	    while (out < cur) {
+		res->path[out] = bas->path[out];
+		out++;
+	    }
+	}
+    }
+    res->path[out] = 0;
+
+    /*
+     * b) The reference's path component is appended to the buffer
+     *    string.
+     */
+    if (ref->path != NULL && ref->path[0] != 0) {
+	indx = 0;
+	/*
+	 * Ensure the path includes a '/'
+	 */
+	if ((out == 0) && (bas->server != NULL))
+	    res->path[out++] = '/';
+	while (ref->path[indx] != 0) {
+	    res->path[out++] = ref->path[indx++];
+	}
+    }
+    res->path[out] = 0;
+
+    /*
+     * Steps c) to h) are really path normalization steps
+     */
+    xmlNormalizeURIPath(res->path);
+
+step_7:
+
+    /*
+     * 7) The resulting URI components, including any inherited from the
+     *    base URI, are recombined to give the absolute form of the URI
+     *    reference.
+     */
+    val = xmlSaveUri(res);
+
+done:
+    if (ref != NULL)
+	xmlFreeURI(ref);
+    if (bas != NULL)
+	xmlFreeURI(bas);
+    if (res != NULL)
+	xmlFreeURI(res);
+    return(val);
+}
+
+/**
+ * xmlBuildRelativeURI:
+ * @URI:  the URI reference under consideration
+ * @base:  the base value
+ *
+ * Expresses the URI of the reference in terms relative to the
+ * base.  Some examples of this operation include:
+ *     base = "http://site1.com/docs/book1.html"
+ *        URI input                        URI returned
+ *     docs/pic1.gif                    pic1.gif
+ *     docs/img/pic1.gif                img/pic1.gif
+ *     img/pic1.gif                     ../img/pic1.gif
+ *     http://site1.com/docs/pic1.gif   pic1.gif
+ *     http://site2.com/docs/pic1.gif   http://site2.com/docs/pic1.gif
+ *
+ *     base = "docs/book1.html"
+ *        URI input                        URI returned
+ *     docs/pic1.gif                    pic1.gif
+ *     docs/img/pic1.gif                img/pic1.gif
+ *     img/pic1.gif                     ../img/pic1.gif
+ *     http://site1.com/docs/pic1.gif   http://site1.com/docs/pic1.gif
+ *
+ *
+ * Note: if the URI reference is really wierd or complicated, it may be
+ *       worthwhile to first convert it into a "nice" one by calling
+ *       xmlBuildURI (using 'base') before calling this routine,
+ *       since this routine (for reasonable efficiency) assumes URI has
+ *       already been through some validation.
+ *
+ * Returns a new URI string (to be freed by the caller) or NULL in case
+ * error.
+ */
+xmlChar *
+xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
+{
+    xmlChar *val = NULL;
+    int ret;
+    int ix;
+    int pos = 0;
+    int nbslash = 0;
+    int len;
+    xmlURIPtr ref = NULL;
+    xmlURIPtr bas = NULL;
+    xmlChar *bptr, *uptr, *vptr;
+    int remove_path = 0;
+
+    if ((URI == NULL) || (*URI == 0))
+	return NULL;
+
+    /*
+     * First parse URI into a standard form
+     */
+    ref = xmlCreateURI ();
+    if (ref == NULL)
+	return NULL;
+    /* If URI not already in "relative" form */
+    if (URI[0] != '.') {
+	ret = xmlParseURIReference (ref, (const char *) URI);
+	if (ret != 0)
+	    goto done;		/* Error in URI, return NULL */
+    } else
+	ref->path = (char *)xmlStrdup(URI);
+
+    /*
+     * Next parse base into the same standard form
+     */
+    if ((base == NULL) || (*base == 0)) {
+	val = xmlStrdup (URI);
+	goto done;
+    }
+    bas = xmlCreateURI ();
+    if (bas == NULL)
+	goto done;
+    if (base[0] != '.') {
+	ret = xmlParseURIReference (bas, (const char *) base);
+	if (ret != 0)
+	    goto done;		/* Error in base, return NULL */
+    } else
+	bas->path = (char *)xmlStrdup(base);
+
+    /*
+     * If the scheme / server on the URI differs from the base,
+     * just return the URI
+     */
+    if ((ref->scheme != NULL) &&
+	((bas->scheme == NULL) ||
+	 (xmlStrcmp ((xmlChar *)bas->scheme, (xmlChar *)ref->scheme)) ||
+	 (xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)))) {
+	val = xmlStrdup (URI);
+	goto done;
+    }
+    if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) {
+	val = xmlStrdup(BAD_CAST "");
+	goto done;
+    }
+    if (bas->path == NULL) {
+	val = xmlStrdup((xmlChar *)ref->path);
+	goto done;
+    }
+    if (ref->path == NULL) {
+        ref->path = (char *) "/";
+	remove_path = 1;
+    }
+
+    /*
+     * At this point (at last!) we can compare the two paths
+     *
+     * First we take care of the special case where either of the
+     * two path components may be missing (bug 316224)
+     */
+    if (bas->path == NULL) {
+	if (ref->path != NULL) {
+	    uptr = (xmlChar *) ref->path;
+	    if (*uptr == '/')
+		uptr++;
+	    /* exception characters from xmlSaveUri */
+	    val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,");
+	}
+	goto done;
+    }
+    bptr = (xmlChar *)bas->path;
+    if (ref->path == NULL) {
+	for (ix = 0; bptr[ix] != 0; ix++) {
+	    if (bptr[ix] == '/')
+		nbslash++;
+	}
+	uptr = NULL;
+	len = 1;	/* this is for a string terminator only */
+    } else {
+    /*
+     * Next we compare the two strings and find where they first differ
+     */
+	if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/'))
+            pos += 2;
+	if ((*bptr == '.') && (bptr[1] == '/'))
+            bptr += 2;
+	else if ((*bptr == '/') && (ref->path[pos] != '/'))
+	    bptr++;
+	while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0))
+	    pos++;
+
+	if (bptr[pos] == ref->path[pos]) {
+	    val = xmlStrdup(BAD_CAST "");
+	    goto done;		/* (I can't imagine why anyone would do this) */
+	}
+
+	/*
+	 * In URI, "back up" to the last '/' encountered.  This will be the
+	 * beginning of the "unique" suffix of URI
+	 */
+	ix = pos;
+	if ((ref->path[ix] == '/') && (ix > 0))
+	    ix--;
+	else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/'))
+	    ix -= 2;
+	for (; ix > 0; ix--) {
+	    if (ref->path[ix] == '/')
+		break;
+	}
+	if (ix == 0) {
+	    uptr = (xmlChar *)ref->path;
+	} else {
+	    ix++;
+	    uptr = (xmlChar *)&ref->path[ix];
+	}
+
+	/*
+	 * In base, count the number of '/' from the differing point
+	 */
+	if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */
+	    for (; bptr[ix] != 0; ix++) {
+		if (bptr[ix] == '/')
+		    nbslash++;
+	    }
+	}
+	len = xmlStrlen (uptr) + 1;
+    }
+    
+    if (nbslash == 0) {
+	if (uptr != NULL)
+	    /* exception characters from xmlSaveUri */
+	    val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,");
+	goto done;
+    }
+
+    /*
+     * Allocate just enough space for the returned string -
+     * length of the remainder of the URI, plus enough space
+     * for the "../" groups, plus one for the terminator
+     */
+    val = (xmlChar *) xmlMalloc (len + 3 * nbslash);
+    if (val == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlBuildRelativeURI: out of memory\n");
+	goto done;
+    }
+    vptr = val;
+    /*
+     * Put in as many "../" as needed
+     */
+    for (; nbslash>0; nbslash--) {
+	*vptr++ = '.';
+	*vptr++ = '.';
+	*vptr++ = '/';
+    }
+    /*
+     * Finish up with the end of the URI
+     */
+    if (uptr != NULL) {
+        if ((vptr > val) && (len > 0) &&
+	    (uptr[0] == '/') && (vptr[-1] == '/')) {
+	    memcpy (vptr, uptr + 1, len - 1);
+	    vptr[len - 2] = 0;
+	} else {
+	    memcpy (vptr, uptr, len);
+	    vptr[len - 1] = 0;
+	}
+    } else {
+	vptr[len - 1] = 0;
+    }
+
+    /* escape the freshly-built path */
+    vptr = val;
+	/* exception characters from xmlSaveUri */
+    val = xmlURIEscapeStr(vptr, BAD_CAST "/;&=+$,");
+    xmlFree(vptr);
+
+done:
+    /*
+     * Free the working variables
+     */
+    if (remove_path != 0)
+        ref->path = NULL;
+    if (ref != NULL)
+	xmlFreeURI (ref);
+    if (bas != NULL)
+	xmlFreeURI (bas);
+
+    return val;
+}
+
+/**
+ * xmlCanonicPath:
+ * @path:  the resource locator in a filesystem notation
+ *
+ * Constructs a canonic path from the specified path. 
+ *
+ * Returns a new canonic path, or a duplicate of the path parameter if the 
+ * construction fails. The caller is responsible for freeing the memory occupied
+ * by the returned string. If there is insufficient memory available, or the 
+ * argument is NULL, the function returns NULL.
+ */
+#define IS_WINDOWS_PATH(p) 					\
+	((p != NULL) &&						\
+	 (((p[0] >= 'a') && (p[0] <= 'z')) ||			\
+	  ((p[0] >= 'A') && (p[0] <= 'Z'))) &&			\
+	 (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))
+xmlChar *
+xmlCanonicPath(const xmlChar *path)
+{
+/*
+ * For Windows implementations, additional work needs to be done to
+ * replace backslashes in pathnames with "forward slashes"
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)    
+    int len = 0;
+    int i = 0;
+    xmlChar *p = NULL;
+#endif
+    xmlURIPtr uri;
+    xmlChar *ret;
+    const xmlChar *absuri;
+
+    if (path == NULL)
+	return(NULL);
+
+    /* sanitize filename starting with // so it can be used as URI */
+    if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/'))
+        path++;
+
+    if ((uri = xmlParseURI((const char *) path)) != NULL) {
+	xmlFreeURI(uri);
+	return xmlStrdup(path);
+    }
+
+    /* Check if this is an "absolute uri" */
+    absuri = xmlStrstr(path, BAD_CAST "://");
+    if (absuri != NULL) {
+        int l, j;
+	unsigned char c;
+	xmlChar *escURI;
+
+        /*
+	 * this looks like an URI where some parts have not been
+	 * escaped leading to a parsing problem.  Check that the first
+	 * part matches a protocol.
+	 */
+	l = absuri - path;
+	/* Bypass if first part (part before the '://') is > 20 chars */
+	if ((l <= 0) || (l > 20))
+	    goto path_processing;
+	/* Bypass if any non-alpha characters are present in first part */
+	for (j = 0;j < l;j++) {
+	    c = path[j];
+	    if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))
+	        goto path_processing;
+	}
+
+	/* Escape all except the characters specified in the supplied path */
+        escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;=");
+	if (escURI != NULL) {
+	    /* Try parsing the escaped path */
+	    uri = xmlParseURI((const char *) escURI);
+	    /* If successful, return the escaped string */
+	    if (uri != NULL) {
+	        xmlFreeURI(uri);
+		return escURI;
+	    }
+	}
+    }
+
+path_processing:
+/* For Windows implementations, replace backslashes with 'forward slashes' */
+#if defined(_WIN32) && !defined(__CYGWIN__)    
+    /*
+     * Create a URI structure
+     */
+    uri = xmlCreateURI();
+    if (uri == NULL) {		/* Guard against 'out of memory' */
+        return(NULL);
+    }
+
+    len = xmlStrlen(path);
+    if ((len > 2) && IS_WINDOWS_PATH(path)) {
+        /* make the scheme 'file' */
+	uri->scheme = xmlStrdup(BAD_CAST "file");
+	/* allocate space for leading '/' + path + string terminator */
+	uri->path = xmlMallocAtomic(len + 2);
+	if (uri->path == NULL) {
+	    xmlFreeURI(uri);	/* Guard agains 'out of memory' */
+	    return(NULL);
+	}
+	/* Put in leading '/' plus path */
+	uri->path[0] = '/';
+	p = uri->path + 1;
+	strncpy(p, path, len + 1);
+    } else {
+	uri->path = xmlStrdup(path);
+	if (uri->path == NULL) {
+	    xmlFreeURI(uri);
+	    return(NULL);
+	}
+	p = uri->path;
+    }
+    /* Now change all occurences of '\' to '/' */
+    while (*p != '\0') {
+	if (*p == '\\')
+	    *p = '/';
+	p++;
+    }
+
+    if (uri->scheme == NULL) {
+	ret = xmlStrdup((const xmlChar *) uri->path);
+    } else {
+	ret = xmlSaveUri(uri);
+    }
+
+    xmlFreeURI(uri);
+#else
+    ret = xmlStrdup((const xmlChar *) path);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlPathToURI:
+ * @path:  the resource locator in a filesystem notation
+ *
+ * Constructs an URI expressing the existing path
+ *
+ * Returns a new URI, or a duplicate of the path parameter if the 
+ * construction fails. The caller is responsible for freeing the memory
+ * occupied by the returned string. If there is insufficient memory available,
+ * or the argument is NULL, the function returns NULL.
+ */
+xmlChar *
+xmlPathToURI(const xmlChar *path)
+{
+    xmlURIPtr uri;
+    xmlURI temp;
+    xmlChar *ret, *cal;
+
+    if (path == NULL)
+        return(NULL);
+
+    if ((uri = xmlParseURI((const char *) path)) != NULL) {
+	xmlFreeURI(uri);
+	return xmlStrdup(path);
+    }
+    cal = xmlCanonicPath(path);
+    if (cal == NULL)
+        return(NULL);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?) 
+       If 'cal' is a valid URI allready then we are done here, as continuing would make
+       it invalid. */
+    if ((uri = xmlParseURI((const char *) cal)) != NULL) {
+	xmlFreeURI(uri);
+	return cal;
+    }
+    /* 'cal' can contain a relative path with backslashes. If that is processed
+       by xmlSaveURI, they will be escaped and the external entity loader machinery
+       will fail. So convert them to slashes. Misuse 'ret' for walking. */
+    ret = cal;
+    while (*ret != '\0') {
+	if (*ret == '\\')
+	    *ret = '/';
+	ret++;
+    }
+#endif
+    memset(&temp, 0, sizeof(temp));
+    temp.path = (char *) cal;
+    ret = xmlSaveUri(&temp);
+    xmlFree(cal);
+    return(ret);
+}
+#define bottom_uri
+#include "elfgcchack.h"
diff --git a/src/valid.c b/src/valid.c
new file mode 100644
index 0000000..2cb32f3
--- /dev/null
+++ b/src/valid.c
@@ -0,0 +1,7041 @@
+/*
+ * valid.c : part of the code use to do the DTD handling and the validity
+ *           checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/hash.h>
+#include <libxml/uri.h>
+#include <libxml/valid.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/list.h>
+#include <libxml/globals.h>
+
+static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name,
+	                           int create);
+/* #define DEBUG_VALID_ALGO */
+/* #define DEBUG_REGEXP_ALGO */
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#ifdef LIBXML_VALID_ENABLED
+static int
+xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
+                                  const xmlChar *value);
+#endif
+/************************************************************************
+ *									*
+ *			Error handling routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlVErrMemory:
+ * @ctxt:  an XML validation parser context
+ * @extra:  extra informations
+ *
+ * Handle an out of memory error
+ */
+static void
+xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra)
+{
+    xmlGenericErrorFunc channel = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        channel = ctxt->error;
+        data = ctxt->userData;
+	/* Use the special values to detect if it is part of a parsing
+	   context */
+	if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+	    (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
+	    long delta = (char *) ctxt - (char *) ctxt->userData;
+	    if ((delta > 0) && (delta < 250))
+		pctxt = ctxt->userData;
+	}
+    }
+    if (extra)
+        __xmlRaiseError(NULL, channel, data,
+                        pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,
+                        XML_ERR_FATAL, NULL, 0, extra, NULL, NULL, 0, 0,
+                        "Memory allocation failed : %s\n", extra);
+    else
+        __xmlRaiseError(NULL, channel, data,
+                        pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,
+                        XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0,
+                        "Memory allocation failed\n");
+}
+
+/**
+ * xmlErrValid:
+ * @ctxt:  an XML validation parser context
+ * @error:  the error number
+ * @extra:  extra informations
+ *
+ * Handle a validation error
+ */
+static void
+xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
+            const char *msg, const char *extra)
+{
+    xmlGenericErrorFunc channel = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        channel = ctxt->error;
+        data = ctxt->userData;
+	/* Use the special values to detect if it is part of a parsing
+	   context */
+	if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+	    (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
+	    long delta = (char *) ctxt - (char *) ctxt->userData;
+	    if ((delta > 0) && (delta < 250))
+		pctxt = ctxt->userData;
+	}
+    }
+    if (extra)
+        __xmlRaiseError(NULL, channel, data,
+                        pctxt, NULL, XML_FROM_VALID, error,
+                        XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0,
+                        msg, extra);
+    else
+        __xmlRaiseError(NULL, channel, data,
+                        pctxt, NULL, XML_FROM_VALID, error,
+                        XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,
+                        "%s", msg);
+}
+
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlErrValidNode:
+ * @ctxt:  an XML validation parser context
+ * @node:  the node raising the error
+ * @error:  the error number
+ * @str1:  extra informations
+ * @str2:  extra informations
+ * @str3:  extra informations
+ *
+ * Handle a validation error, provide contextual informations
+ */
+static void
+xmlErrValidNode(xmlValidCtxtPtr ctxt,
+                xmlNodePtr node, xmlParserErrors error,
+                const char *msg, const xmlChar * str1,
+                const xmlChar * str2, const xmlChar * str3)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        channel = ctxt->error;
+        data = ctxt->userData;
+	/* Use the special values to detect if it is part of a parsing
+	   context */
+	if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+	    (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
+	    long delta = (char *) ctxt - (char *) ctxt->userData;
+	    if ((delta > 0) && (delta < 250))
+		pctxt = ctxt->userData;
+	}
+    }
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
+                    XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1,
+                    (const char *) str1,
+                    (const char *) str3, 0, 0, msg, str1, str2, str3);
+}
+#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+/**
+ * xmlErrValidNodeNr:
+ * @ctxt:  an XML validation parser context
+ * @node:  the node raising the error
+ * @error:  the error number
+ * @str1:  extra informations
+ * @int2:  extra informations
+ * @str3:  extra informations
+ *
+ * Handle a validation error, provide contextual informations
+ */
+static void
+xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
+                xmlNodePtr node, xmlParserErrors error,
+                const char *msg, const xmlChar * str1,
+                int int2, const xmlChar * str3)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        channel = ctxt->error;
+        data = ctxt->userData;
+	/* Use the special values to detect if it is part of a parsing
+	   context */
+	if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+	    (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
+	    long delta = (char *) ctxt - (char *) ctxt->userData;
+	    if ((delta > 0) && (delta < 250))
+		pctxt = ctxt->userData;
+	}
+    }
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
+                    XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1,
+                    (const char *) str3,
+                    NULL, int2, 0, msg, str1, int2, str3);
+}
+
+/**
+ * xmlErrValidWarning:
+ * @ctxt:  an XML validation parser context
+ * @node:  the node raising the error
+ * @error:  the error number
+ * @str1:  extra information
+ * @str2:  extra information
+ * @str3:  extra information
+ *
+ * Handle a validation error, provide contextual information
+ */
+static void
+xmlErrValidWarning(xmlValidCtxtPtr ctxt,
+                xmlNodePtr node, xmlParserErrors error,
+                const char *msg, const xmlChar * str1,
+                const xmlChar * str2, const xmlChar * str3)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        channel = ctxt->warning;
+        data = ctxt->userData;
+	/* Use the special values to detect if it is part of a parsing
+	   context */
+	if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+	    (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
+	    long delta = (char *) ctxt - (char *) ctxt->userData;
+	    if ((delta > 0) && (delta < 250))
+		pctxt = ctxt->userData;
+	}
+    }
+    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
+                    XML_ERR_WARNING, NULL, 0,
+                    (const char *) str1,
+                    (const char *) str1,
+                    (const char *) str3, 0, 0, msg, str1, str2, str3);
+}
+
+
+
+#ifdef LIBXML_REGEXP_ENABLED
+/*
+ * If regexp are enabled we can do continuous validation without the
+ * need of a tree to validate the content model. this is done in each
+ * callbacks.
+ * Each xmlValidState represent the validation state associated to the
+ * set of nodes currently open from the document root to the current element.
+ */
+
+
+typedef struct _xmlValidState {
+    xmlElementPtr	 elemDecl;	/* pointer to the content model */
+    xmlNodePtr           node;		/* pointer to the current node */
+    xmlRegExecCtxtPtr    exec;		/* regexp runtime */
+} _xmlValidState;
+
+
+static int
+vstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {
+    if ((ctxt->vstateMax == 0) || (ctxt->vstateTab == NULL)) {
+	ctxt->vstateMax = 10;
+	ctxt->vstateTab = (xmlValidState *) xmlMalloc(ctxt->vstateMax *
+		              sizeof(ctxt->vstateTab[0]));
+        if (ctxt->vstateTab == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+	    return(-1);
+	}
+    }
+
+    if (ctxt->vstateNr >= ctxt->vstateMax) {
+        xmlValidState *tmp;
+
+	tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,
+	             2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
+        if (tmp == NULL) {
+	    xmlVErrMemory(ctxt, "realloc failed");
+	    return(-1);
+	}
+	ctxt->vstateMax *= 2;
+	ctxt->vstateTab = tmp;
+    }
+    ctxt->vstate = &ctxt->vstateTab[ctxt->vstateNr];
+    ctxt->vstateTab[ctxt->vstateNr].elemDecl = elemDecl;
+    ctxt->vstateTab[ctxt->vstateNr].node = node;
+    if ((elemDecl != NULL) && (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)) {
+	if (elemDecl->contModel == NULL)
+	    xmlValidBuildContentModel(ctxt, elemDecl);
+	if (elemDecl->contModel != NULL) {
+	    ctxt->vstateTab[ctxt->vstateNr].exec = 
+		xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
+	} else {
+	    ctxt->vstateTab[ctxt->vstateNr].exec = NULL;
+	    xmlErrValidNode(ctxt, (xmlNodePtr) elemDecl,
+	                    XML_ERR_INTERNAL_ERROR,
+			    "Failed to build content model regexp for %s\n",
+			    node->name, NULL, NULL);
+	}
+    }
+    return(ctxt->vstateNr++);
+}
+
+static int
+vstateVPop(xmlValidCtxtPtr ctxt) {
+    xmlElementPtr elemDecl;
+
+    if (ctxt->vstateNr < 1) return(-1);
+    ctxt->vstateNr--;
+    elemDecl = ctxt->vstateTab[ctxt->vstateNr].elemDecl;
+    ctxt->vstateTab[ctxt->vstateNr].elemDecl = NULL;
+    ctxt->vstateTab[ctxt->vstateNr].node = NULL;
+    if ((elemDecl != NULL) && (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)) {
+	xmlRegFreeExecCtxt(ctxt->vstateTab[ctxt->vstateNr].exec);
+    }
+    ctxt->vstateTab[ctxt->vstateNr].exec = NULL;
+    if (ctxt->vstateNr >= 1)
+	ctxt->vstate = &ctxt->vstateTab[ctxt->vstateNr - 1];
+    else
+	ctxt->vstate = NULL;
+    return(ctxt->vstateNr);
+}
+
+#else /* not LIBXML_REGEXP_ENABLED */
+/*
+ * If regexp are not enabled, it uses a home made algorithm less
+ * complex and easier to
+ * debug/maintain than a generic NFA -> DFA state based algo. The
+ * only restriction is on the deepness of the tree limited by the
+ * size of the occurs bitfield
+ *
+ * this is the content of a saved state for rollbacks
+ */
+
+#define ROLLBACK_OR	0
+#define ROLLBACK_PARENT	1
+
+typedef struct _xmlValidState {
+    xmlElementContentPtr cont;	/* pointer to the content model subtree */
+    xmlNodePtr           node;	/* pointer to the current node in the list */
+    long                 occurs;/* bitfield for multiple occurrences */
+    unsigned char        depth; /* current depth in the overall tree */
+    unsigned char        state; /* ROLLBACK_XXX */
+} _xmlValidState;
+
+#define MAX_RECURSE 25000
+#define MAX_DEPTH ((sizeof(_xmlValidState.occurs)) * 8)
+#define CONT ctxt->vstate->cont
+#define NODE ctxt->vstate->node
+#define DEPTH ctxt->vstate->depth
+#define OCCURS ctxt->vstate->occurs
+#define STATE ctxt->vstate->state
+
+#define OCCURRENCE (ctxt->vstate->occurs & (1 << DEPTH))
+#define PARENT_OCCURRENCE (ctxt->vstate->occurs & ((1 << DEPTH) - 1))
+
+#define SET_OCCURRENCE ctxt->vstate->occurs |= (1 << DEPTH)
+#define RESET_OCCURRENCE ctxt->vstate->occurs &= ((1 << DEPTH) - 1)
+
+static int
+vstateVPush(xmlValidCtxtPtr ctxt, xmlElementContentPtr cont,
+	    xmlNodePtr node, unsigned char depth, long occurs,
+	    unsigned char state) {
+    int i = ctxt->vstateNr - 1;
+
+    if (ctxt->vstateNr > MAX_RECURSE) {
+	return(-1);
+    }
+    if (ctxt->vstateTab == NULL) {
+	ctxt->vstateMax = 8;
+	ctxt->vstateTab = (xmlValidState *) xmlMalloc(
+		     ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
+	if (ctxt->vstateTab == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+	    return(-1);
+	}
+    }
+    if (ctxt->vstateNr >= ctxt->vstateMax) {
+        xmlValidState *tmp;
+
+        tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,
+	             2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
+        if (tmp == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+	    return(-1);
+	}
+	ctxt->vstateMax *= 2;
+	ctxt->vstateTab = tmp;
+	ctxt->vstate = &ctxt->vstateTab[0];
+    }
+    /*
+     * Don't push on the stack a state already here
+     */
+    if ((i >= 0) && (ctxt->vstateTab[i].cont == cont) &&
+	(ctxt->vstateTab[i].node == node) &&
+	(ctxt->vstateTab[i].depth == depth) &&
+	(ctxt->vstateTab[i].occurs == occurs) &&
+	(ctxt->vstateTab[i].state == state))
+	return(ctxt->vstateNr);
+    ctxt->vstateTab[ctxt->vstateNr].cont = cont;
+    ctxt->vstateTab[ctxt->vstateNr].node = node;
+    ctxt->vstateTab[ctxt->vstateNr].depth = depth;
+    ctxt->vstateTab[ctxt->vstateNr].occurs = occurs;
+    ctxt->vstateTab[ctxt->vstateNr].state = state;
+    return(ctxt->vstateNr++);
+}
+
+static int
+vstateVPop(xmlValidCtxtPtr ctxt) {
+    if (ctxt->vstateNr <= 1) return(-1);
+    ctxt->vstateNr--;
+    ctxt->vstate = &ctxt->vstateTab[0];
+    ctxt->vstate->cont =  ctxt->vstateTab[ctxt->vstateNr].cont;
+    ctxt->vstate->node = ctxt->vstateTab[ctxt->vstateNr].node;
+    ctxt->vstate->depth = ctxt->vstateTab[ctxt->vstateNr].depth;
+    ctxt->vstate->occurs = ctxt->vstateTab[ctxt->vstateNr].occurs;
+    ctxt->vstate->state = ctxt->vstateTab[ctxt->vstateNr].state;
+    return(ctxt->vstateNr);
+}
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+static int
+nodeVPush(xmlValidCtxtPtr ctxt, xmlNodePtr value)
+{
+    if (ctxt->nodeMax <= 0) {
+        ctxt->nodeMax = 4;
+        ctxt->nodeTab =
+            (xmlNodePtr *) xmlMalloc(ctxt->nodeMax *
+                                     sizeof(ctxt->nodeTab[0]));
+        if (ctxt->nodeTab == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+            ctxt->nodeMax = 0;
+            return (0);
+        }
+    }
+    if (ctxt->nodeNr >= ctxt->nodeMax) {
+        xmlNodePtr *tmp;
+        tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
+			      ctxt->nodeMax * 2 * sizeof(ctxt->nodeTab[0]));
+        if (tmp == NULL) {
+	    xmlVErrMemory(ctxt, "realloc failed");
+            return (0);
+        }
+        ctxt->nodeMax *= 2;
+	ctxt->nodeTab = tmp;
+    }
+    ctxt->nodeTab[ctxt->nodeNr] = value;
+    ctxt->node = value;
+    return (ctxt->nodeNr++);
+}
+static xmlNodePtr
+nodeVPop(xmlValidCtxtPtr ctxt)
+{
+    xmlNodePtr ret;
+
+    if (ctxt->nodeNr <= 0)
+        return (NULL);
+    ctxt->nodeNr--;
+    if (ctxt->nodeNr > 0)
+        ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
+    else
+        ctxt->node = NULL;
+    ret = ctxt->nodeTab[ctxt->nodeNr];
+    ctxt->nodeTab[ctxt->nodeNr] = NULL;
+    return (ret);
+}
+
+#ifdef DEBUG_VALID_ALGO
+static void
+xmlValidPrintNode(xmlNodePtr cur) {
+    if (cur == NULL) {
+	xmlGenericError(xmlGenericErrorContext, "null");
+	return;
+    }
+    switch (cur->type) {
+	case XML_ELEMENT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "%s ", cur->name);
+	    break;
+	case XML_TEXT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "text ");
+	    break;
+	case XML_CDATA_SECTION_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "cdata ");
+	    break;
+	case XML_ENTITY_REF_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "&%s; ", cur->name);
+	    break;
+	case XML_PI_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "pi(%s) ", cur->name);
+	    break;
+	case XML_COMMENT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "comment ");
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?attr? ");
+	    break;
+	case XML_ENTITY_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?ent? ");
+	    break;
+	case XML_DOCUMENT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?doc? ");
+	    break;
+	case XML_DOCUMENT_TYPE_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?doctype? ");
+	    break;
+	case XML_DOCUMENT_FRAG_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?frag? ");
+	    break;
+	case XML_NOTATION_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?nota? ");
+	    break;
+	case XML_HTML_DOCUMENT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?html? ");
+	    break;
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?docb? ");
+	    break;
+#endif
+	case XML_DTD_NODE:
+	    xmlGenericError(xmlGenericErrorContext, "?dtd? ");
+	    break;
+	case XML_ELEMENT_DECL:
+	    xmlGenericError(xmlGenericErrorContext, "?edecl? ");
+	    break;
+	case XML_ATTRIBUTE_DECL:
+	    xmlGenericError(xmlGenericErrorContext, "?adecl? ");
+	    break;
+	case XML_ENTITY_DECL:
+	    xmlGenericError(xmlGenericErrorContext, "?entdecl? ");
+	    break;
+	case XML_NAMESPACE_DECL:
+	    xmlGenericError(xmlGenericErrorContext, "?nsdecl? ");
+	    break;
+	case XML_XINCLUDE_START:
+	    xmlGenericError(xmlGenericErrorContext, "incstart ");
+	    break;
+	case XML_XINCLUDE_END:
+	    xmlGenericError(xmlGenericErrorContext, "incend ");
+	    break;
+    }
+}
+
+static void
+xmlValidPrintNodeList(xmlNodePtr cur) {
+    if (cur == NULL)
+	xmlGenericError(xmlGenericErrorContext, "null ");
+    while (cur != NULL) {
+	xmlValidPrintNode(cur);
+	cur = cur->next;
+    }
+}
+
+static void
+xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) {
+    char expr[5000];
+
+    expr[0] = 0;
+    xmlGenericError(xmlGenericErrorContext, "valid: ");
+    xmlValidPrintNodeList(cur);
+    xmlGenericError(xmlGenericErrorContext, "against ");
+    xmlSnprintfElementContent(expr, 5000, cont, 1);
+    xmlGenericError(xmlGenericErrorContext, "%s\n", expr);
+}
+
+static void
+xmlValidDebugState(xmlValidStatePtr state) {
+    xmlGenericError(xmlGenericErrorContext, "(");
+    if (state->cont == NULL)
+	xmlGenericError(xmlGenericErrorContext, "null,");
+    else
+	switch (state->cont->type) {
+            case XML_ELEMENT_CONTENT_PCDATA:
+		xmlGenericError(xmlGenericErrorContext, "pcdata,");
+		break;
+            case XML_ELEMENT_CONTENT_ELEMENT:
+		xmlGenericError(xmlGenericErrorContext, "%s,",
+			        state->cont->name);
+		break;
+            case XML_ELEMENT_CONTENT_SEQ:
+		xmlGenericError(xmlGenericErrorContext, "seq,");
+		break;
+            case XML_ELEMENT_CONTENT_OR:
+		xmlGenericError(xmlGenericErrorContext, "or,");
+		break;
+	}
+    xmlValidPrintNode(state->node);
+    xmlGenericError(xmlGenericErrorContext, ",%d,%X,%d)",
+	    state->depth, state->occurs, state->state);
+}
+
+static void
+xmlValidStateDebug(xmlValidCtxtPtr ctxt) {
+    int i, j;
+
+    xmlGenericError(xmlGenericErrorContext, "state: ");
+    xmlValidDebugState(ctxt->vstate);
+    xmlGenericError(xmlGenericErrorContext, " stack: %d ",
+	    ctxt->vstateNr - 1);
+    for (i = 0, j = ctxt->vstateNr - 1;(i < 3) && (j > 0);i++,j--)
+	xmlValidDebugState(&ctxt->vstateTab[j]);
+    xmlGenericError(xmlGenericErrorContext, "\n");
+}
+
+/*****
+#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c);
+ *****/
+
+#define DEBUG_VALID_STATE(n,c) xmlValidStateDebug(ctxt);
+#define DEBUG_VALID_MSG(m)					\
+    xmlGenericError(xmlGenericErrorContext, "%s\n", m);
+        
+#else
+#define DEBUG_VALID_STATE(n,c)
+#define DEBUG_VALID_MSG(m)
+#endif
+
+/* TODO: use hash table for accesses to elem and attribute definitions */
+
+
+#define CHECK_DTD						\
+   if (doc == NULL) return(0);					\
+   else if ((doc->intSubset == NULL) &&				\
+	    (doc->extSubset == NULL)) return(0)
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+/************************************************************************
+ *									*
+ *		Content model validation based on the regexps		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlValidBuildAContentModel:
+ * @content:  the content model
+ * @ctxt:  the schema parser context
+ * @name:  the element name whose content is being built
+ *
+ * Generate the automata sequence needed for that type
+ *
+ * Returns 1 if successful or 0 in case of error.
+ */
+static int
+xmlValidBuildAContentModel(xmlElementContentPtr content,
+		           xmlValidCtxtPtr ctxt,
+		           const xmlChar *name) {
+    if (content == NULL) {
+	xmlErrValidNode(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
+			"Found NULL content in content model of %s\n",
+			name, NULL, NULL);
+	return(0);
+    }
+    switch (content->type) {
+	case XML_ELEMENT_CONTENT_PCDATA:
+	    xmlErrValidNode(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
+			    "Found PCDATA in content model of %s\n",
+		            name, NULL, NULL);
+	    return(0);
+	    break;
+	case XML_ELEMENT_CONTENT_ELEMENT: {
+	    xmlAutomataStatePtr oldstate = ctxt->state;
+	    xmlChar fn[50];
+	    xmlChar *fullname;
+	    
+	    fullname = xmlBuildQName(content->name, content->prefix, fn, 50);
+	    if (fullname == NULL) {
+	        xmlVErrMemory(ctxt, "Building content model");
+		return(0);
+	    }
+
+	    switch (content->ocur) {
+		case XML_ELEMENT_CONTENT_ONCE:
+		    ctxt->state = xmlAutomataNewTransition(ctxt->am,
+			    ctxt->state, NULL, fullname, NULL);
+		    break;
+		case XML_ELEMENT_CONTENT_OPT:
+		    ctxt->state = xmlAutomataNewTransition(ctxt->am,
+			    ctxt->state, NULL, fullname, NULL);
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    break;
+		case XML_ELEMENT_CONTENT_PLUS:
+		    ctxt->state = xmlAutomataNewTransition(ctxt->am,
+			    ctxt->state, NULL, fullname, NULL);
+		    xmlAutomataNewTransition(ctxt->am, ctxt->state,
+			                     ctxt->state, fullname, NULL);
+		    break;
+		case XML_ELEMENT_CONTENT_MULT:
+		    ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+		    			    ctxt->state, NULL);
+		    xmlAutomataNewTransition(ctxt->am,
+		    	    ctxt->state, ctxt->state, fullname, NULL);
+		    break;
+	    }
+	    if ((fullname != fn) && (fullname != content->name))
+		xmlFree(fullname);
+	    break;
+	}
+	case XML_ELEMENT_CONTENT_SEQ: {
+	    xmlAutomataStatePtr oldstate, oldend;
+	    xmlElementContentOccur ocur;
+
+	    /*
+	     * Simply iterate over the content
+	     */
+	    oldstate = ctxt->state;
+	    ocur = content->ocur;
+	    if (ocur != XML_ELEMENT_CONTENT_ONCE) {
+		ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
+		oldstate = ctxt->state;
+	    }
+	    do {
+		xmlValidBuildAContentModel(content->c1, ctxt, name);
+		content = content->c2;
+	    } while ((content->type == XML_ELEMENT_CONTENT_SEQ) &&
+		     (content->ocur == XML_ELEMENT_CONTENT_ONCE));
+	    xmlValidBuildAContentModel(content, ctxt, name);
+	    oldend = ctxt->state;
+	    ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
+	    switch (ocur) {
+		case XML_ELEMENT_CONTENT_ONCE:
+		    break;
+		case XML_ELEMENT_CONTENT_OPT:
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    break;
+		case XML_ELEMENT_CONTENT_MULT:
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
+		    break;
+		case XML_ELEMENT_CONTENT_PLUS:
+		    xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
+		    break;
+	    }
+	    break;
+	}
+	case XML_ELEMENT_CONTENT_OR: {
+	    xmlAutomataStatePtr oldstate, oldend;
+	    xmlElementContentOccur ocur;
+
+	    ocur = content->ocur;
+	    if ((ocur == XML_ELEMENT_CONTENT_PLUS) || 
+		(ocur == XML_ELEMENT_CONTENT_MULT)) {
+		ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+			ctxt->state, NULL);
+	    }
+	    oldstate = ctxt->state;
+	    oldend = xmlAutomataNewState(ctxt->am);
+
+	    /*
+	     * iterate over the subtypes and remerge the end with an
+	     * epsilon transition
+	     */
+	    do {
+		ctxt->state = oldstate;
+		xmlValidBuildAContentModel(content->c1, ctxt, name);
+		xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
+		content = content->c2;
+	    } while ((content->type == XML_ELEMENT_CONTENT_OR) &&
+		     (content->ocur == XML_ELEMENT_CONTENT_ONCE));
+	    ctxt->state = oldstate;
+	    xmlValidBuildAContentModel(content, ctxt, name);
+	    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
+	    ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
+	    switch (ocur) {
+		case XML_ELEMENT_CONTENT_ONCE:
+		    break;
+		case XML_ELEMENT_CONTENT_OPT:
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    break;
+		case XML_ELEMENT_CONTENT_MULT:
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
+		    break;
+		case XML_ELEMENT_CONTENT_PLUS:
+		    xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
+		    break;
+	    }
+	    break;
+	}
+	default:
+	    xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+	                "ContentModel broken for element %s\n",
+			(const char *) name);
+	    return(0);
+    }
+    return(1);
+}
+/**
+ * xmlValidBuildContentModel:
+ * @ctxt:  a validation context
+ * @elem:  an element declaration node
+ *
+ * (Re)Build the automata associated to the content model of this
+ * element
+ *
+ * Returns 1 in case of success, 0 in case of error
+ */
+int
+xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
+
+    if ((ctxt == NULL) || (elem == NULL))
+	return(0);
+    if (elem->type != XML_ELEMENT_DECL)
+	return(0);
+    if (elem->etype != XML_ELEMENT_TYPE_ELEMENT)
+	return(1);
+    /* TODO: should we rebuild in this case ? */
+    if (elem->contModel != NULL) {
+	if (!xmlRegexpIsDeterminist(elem->contModel)) {
+	    ctxt->valid = 0;
+	    return(0);
+	}
+	return(1);
+    }
+
+    ctxt->am = xmlNewAutomata();
+    if (ctxt->am == NULL) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) elem,
+	                XML_ERR_INTERNAL_ERROR,
+	                "Cannot create automata for element %s\n",
+		        elem->name, NULL, NULL);
+	return(0);
+    }
+    ctxt->state = xmlAutomataGetInitState(ctxt->am);
+    xmlValidBuildAContentModel(elem->content, ctxt, elem->name);
+    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
+    elem->contModel = xmlAutomataCompile(ctxt->am);
+    if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
+	char expr[5000];
+	expr[0] = 0;
+	xmlSnprintfElementContent(expr, 5000, elem->content, 1);
+	xmlErrValidNode(ctxt, (xmlNodePtr) elem,
+	                XML_DTD_CONTENT_NOT_DETERMINIST,
+	       "Content model of %s is not determinist: %s\n",
+	       elem->name, BAD_CAST expr, NULL);
+#ifdef DEBUG_REGEXP_ALGO
+        xmlRegexpPrint(stderr, elem->contModel);
+#endif
+        ctxt->valid = 0;
+	ctxt->state = NULL;
+	xmlFreeAutomata(ctxt->am);
+	ctxt->am = NULL;
+	return(0);
+    }
+    ctxt->state = NULL;
+    xmlFreeAutomata(ctxt->am);
+    ctxt->am = NULL;
+    return(1);
+}
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+/****************************************************************
+ *								*
+ *	Util functions for data allocation/deallocation		*
+ *								*
+ ****************************************************************/
+
+/**
+ * xmlNewValidCtxt:
+ *
+ * Allocate a validation context structure.
+ *
+ * Returns NULL if not, otherwise the new validation context structure
+ */
+xmlValidCtxtPtr xmlNewValidCtxt(void) {
+    xmlValidCtxtPtr ret;
+
+    if ((ret = xmlMalloc(sizeof (xmlValidCtxt))) == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return (NULL);
+    }
+
+    (void) memset(ret, 0, sizeof (xmlValidCtxt));
+
+    return (ret);
+}
+
+/**
+ * xmlFreeValidCtxt:
+ * @cur:  the validation context to free
+ *
+ * Free a validation context structure.
+ */
+void
+xmlFreeValidCtxt(xmlValidCtxtPtr cur) {
+    if (cur->vstateTab != NULL)
+        xmlFree(cur->vstateTab);
+    if (cur->nodeTab != NULL)
+        xmlFree(cur->nodeTab);
+    xmlFree(cur);
+}
+
+#endif /* LIBXML_VALID_ENABLED */
+
+/**
+ * xmlNewDocElementContent:
+ * @doc:  the document
+ * @name:  the subelement name or NULL
+ * @type:  the type of element content decl
+ *
+ * Allocate an element content structure for the document.
+ *
+ * Returns NULL if not, otherwise the new element content structure
+ */
+xmlElementContentPtr
+xmlNewDocElementContent(xmlDocPtr doc, const xmlChar *name,
+                        xmlElementContentType type) {
+    xmlElementContentPtr ret;
+    xmlDictPtr dict = NULL;
+
+    if (doc != NULL)
+        dict = doc->dict;
+
+    switch(type) {
+	case XML_ELEMENT_CONTENT_ELEMENT:
+	    if (name == NULL) {
+	        xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+			"xmlNewElementContent : name == NULL !\n",
+			NULL);
+	    }
+	    break;
+        case XML_ELEMENT_CONTENT_PCDATA:
+	case XML_ELEMENT_CONTENT_SEQ:
+	case XML_ELEMENT_CONTENT_OR:
+	    if (name != NULL) {
+	        xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+			"xmlNewElementContent : name != NULL !\n",
+			NULL);
+	    }
+	    break;
+	default:
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ELEMENT content corrupted invalid type\n",
+		    NULL);
+	    return(NULL);
+    }
+    ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
+    if (ret == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlElementContent));
+    ret->type = type;
+    ret->ocur = XML_ELEMENT_CONTENT_ONCE;
+    if (name != NULL) {
+        int l;
+	const xmlChar *tmp;
+
+	tmp = xmlSplitQName3(name, &l);
+	if (tmp == NULL) {
+	    if (dict == NULL)
+		ret->name = xmlStrdup(name);
+	    else
+	        ret->name = xmlDictLookup(dict, name, -1);
+	} else {
+	    if (dict == NULL) {
+		ret->prefix = xmlStrndup(name, l);
+		ret->name = xmlStrdup(tmp);
+	    } else {
+	        ret->prefix = xmlDictLookup(dict, name, l);
+		ret->name = xmlDictLookup(dict, tmp, -1);
+	    }
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlNewElementContent:
+ * @name:  the subelement name or NULL
+ * @type:  the type of element content decl
+ *
+ * Allocate an element content structure.
+ * Deprecated in favor of xmlNewDocElementContent
+ *
+ * Returns NULL if not, otherwise the new element content structure
+ */
+xmlElementContentPtr
+xmlNewElementContent(const xmlChar *name, xmlElementContentType type) {
+    return(xmlNewDocElementContent(NULL, name, type));
+}
+
+/**
+ * xmlCopyDocElementContent:
+ * @doc:  the document owning the element declaration
+ * @cur:  An element content pointer.
+ *
+ * Build a copy of an element content description.
+ * 
+ * Returns the new xmlElementContentPtr or NULL in case of error.
+ */
+xmlElementContentPtr
+xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
+    xmlElementContentPtr ret = NULL, prev = NULL, tmp;
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) return(NULL);
+
+    if (doc != NULL)
+        dict = doc->dict;
+
+    ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
+    if (ret == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlElementContent));
+    ret->type = cur->type;
+    ret->ocur = cur->ocur;
+    if (cur->name != NULL) {
+	if (dict)
+	    ret->name = xmlDictLookup(dict, cur->name, -1);
+	else
+	    ret->name = xmlStrdup(cur->name);
+    }
+    
+    if (cur->prefix != NULL) {
+	if (dict)
+	    ret->prefix = xmlDictLookup(dict, cur->prefix, -1);
+	else
+	    ret->prefix = xmlStrdup(cur->prefix);
+    }
+    if (cur->c1 != NULL)
+        ret->c1 = xmlCopyDocElementContent(doc, cur->c1);
+    if (ret->c1 != NULL)
+	ret->c1->parent = ret;
+    if (cur->c2 != NULL) {
+        prev = ret;
+	cur = cur->c2;
+	while (cur != NULL) {
+	    tmp = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
+	    if (tmp == NULL) {
+		xmlVErrMemory(NULL, "malloc failed");
+		return(ret);
+	    }
+	    memset(tmp, 0, sizeof(xmlElementContent));
+	    tmp->type = cur->type;
+	    tmp->ocur = cur->ocur;
+	    prev->c2 = tmp;
+	    if (cur->name != NULL) {
+		if (dict)
+		    tmp->name = xmlDictLookup(dict, cur->name, -1);
+		else
+		    tmp->name = xmlStrdup(cur->name);
+	    }
+	    
+	    if (cur->prefix != NULL) {
+		if (dict)
+		    tmp->prefix = xmlDictLookup(dict, cur->prefix, -1);
+		else
+		    tmp->prefix = xmlStrdup(cur->prefix);
+	    }
+	    if (cur->c1 != NULL)
+	        tmp->c1 = xmlCopyDocElementContent(doc,cur->c1);
+	    if (tmp->c1 != NULL)
+		tmp->c1->parent = ret;
+	    prev = tmp;
+	    cur = cur->c2;
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlCopyElementContent:
+ * @cur:  An element content pointer.
+ *
+ * Build a copy of an element content description.
+ * Deprecated, use xmlCopyDocElementContent instead
+ * 
+ * Returns the new xmlElementContentPtr or NULL in case of error.
+ */
+xmlElementContentPtr
+xmlCopyElementContent(xmlElementContentPtr cur) {
+    return(xmlCopyDocElementContent(NULL, cur));
+}
+
+/**
+ * xmlFreeDocElementContent:
+ * @doc: the document owning the element declaration
+ * @cur:  the element content tree to free
+ *
+ * Free an element content structure. The whole subtree is removed.
+ */
+void
+xmlFreeDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
+    xmlElementContentPtr next;
+    xmlDictPtr dict = NULL;
+
+    if (doc != NULL)
+        dict = doc->dict;
+
+    while (cur != NULL) {
+        next = cur->c2;
+	switch (cur->type) {
+	    case XML_ELEMENT_CONTENT_PCDATA:
+	    case XML_ELEMENT_CONTENT_ELEMENT:
+	    case XML_ELEMENT_CONTENT_SEQ:
+	    case XML_ELEMENT_CONTENT_OR:
+		break;
+	    default:
+		xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+			"Internal: ELEMENT content corrupted invalid type\n",
+			NULL);
+		return;
+	}
+	if (cur->c1 != NULL) xmlFreeDocElementContent(doc, cur->c1);
+	if (dict) {
+	    if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
+	        xmlFree((xmlChar *) cur->name);
+	    if ((cur->prefix != NULL) && (!xmlDictOwns(dict, cur->prefix)))
+	        xmlFree((xmlChar *) cur->prefix);
+	} else {
+	    if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
+	    if (cur->prefix != NULL) xmlFree((xmlChar *) cur->prefix);
+	}
+	xmlFree(cur);
+	cur = next;
+    }
+}
+
+/**
+ * xmlFreeElementContent:
+ * @cur:  the element content tree to free
+ *
+ * Free an element content structure. The whole subtree is removed.
+ * Deprecated, use xmlFreeDocElementContent instead
+ */
+void
+xmlFreeElementContent(xmlElementContentPtr cur) {
+    xmlFreeDocElementContent(NULL, cur);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlDumpElementContent:
+ * @buf:  An XML buffer
+ * @content:  An element table
+ * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
+ *
+ * This will dump the content of the element table as an XML DTD definition
+ */
+static void
+xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
+    if (content == NULL) return;
+
+    if (glob) xmlBufferWriteChar(buf, "(");
+    switch (content->type) {
+        case XML_ELEMENT_CONTENT_PCDATA:
+            xmlBufferWriteChar(buf, "#PCDATA");
+	    break;
+	case XML_ELEMENT_CONTENT_ELEMENT:
+	    if (content->prefix != NULL) {
+		xmlBufferWriteCHAR(buf, content->prefix);
+		xmlBufferWriteChar(buf, ":");
+	    }
+	    xmlBufferWriteCHAR(buf, content->name);
+	    break;
+	case XML_ELEMENT_CONTENT_SEQ:
+	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+		xmlDumpElementContent(buf, content->c1, 1);
+	    else
+		xmlDumpElementContent(buf, content->c1, 0);
+            xmlBufferWriteChar(buf, " , ");
+	    if ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
+	        ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
+		 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+		xmlDumpElementContent(buf, content->c2, 1);
+	    else
+		xmlDumpElementContent(buf, content->c2, 0);
+	    break;
+	case XML_ELEMENT_CONTENT_OR:
+	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+		xmlDumpElementContent(buf, content->c1, 1);
+	    else
+		xmlDumpElementContent(buf, content->c1, 0);
+            xmlBufferWriteChar(buf, " | ");
+	    if ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
+	        ((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
+		 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+		xmlDumpElementContent(buf, content->c2, 1);
+	    else
+		xmlDumpElementContent(buf, content->c2, 0);
+	    break;
+	default:
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ELEMENT content corrupted invalid type\n",
+		    NULL);
+    }
+    if (glob)
+        xmlBufferWriteChar(buf, ")");
+    switch (content->ocur) {
+        case XML_ELEMENT_CONTENT_ONCE:
+	    break;
+        case XML_ELEMENT_CONTENT_OPT:
+	    xmlBufferWriteChar(buf, "?");
+	    break;
+        case XML_ELEMENT_CONTENT_MULT:
+	    xmlBufferWriteChar(buf, "*");
+	    break;
+        case XML_ELEMENT_CONTENT_PLUS:
+	    xmlBufferWriteChar(buf, "+");
+	    break;
+    }
+}
+
+/**
+ * xmlSprintfElementContent:
+ * @buf:  an output buffer
+ * @content:  An element table
+ * @englob: 1 if one must print the englobing parenthesis, 0 otherwise
+ *
+ * Deprecated, unsafe, use xmlSnprintfElementContent
+ */
+void
+xmlSprintfElementContent(char *buf ATTRIBUTE_UNUSED,
+	                 xmlElementContentPtr content ATTRIBUTE_UNUSED,
+			 int englob ATTRIBUTE_UNUSED) {
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlSnprintfElementContent:
+ * @buf:  an output buffer
+ * @size:  the buffer size
+ * @content:  An element table
+ * @englob: 1 if one must print the englobing parenthesis, 0 otherwise
+ *
+ * This will dump the content of the element content definition
+ * Intended just for the debug routine
+ */
+void
+xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int englob) {
+    int len;
+
+    if (content == NULL) return;
+    len = strlen(buf);
+    if (size - len < 50) {
+	if ((size - len > 4) && (buf[len - 1] != '.'))
+	    strcat(buf, " ...");
+	return;
+    }
+    if (englob) strcat(buf, "(");
+    switch (content->type) {
+        case XML_ELEMENT_CONTENT_PCDATA:
+            strcat(buf, "#PCDATA");
+	    break;
+	case XML_ELEMENT_CONTENT_ELEMENT:
+	    if (content->prefix != NULL) {
+		if (size - len < xmlStrlen(content->prefix) + 10) {
+		    strcat(buf, " ...");
+		    return;
+		}
+		strcat(buf, (char *) content->prefix);
+		strcat(buf, ":");
+	    }
+	    if (size - len < xmlStrlen(content->name) + 10) {
+		strcat(buf, " ...");
+		return;
+	    }
+	    if (content->name != NULL)
+		strcat(buf, (char *) content->name);
+	    break;
+	case XML_ELEMENT_CONTENT_SEQ:
+	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+		xmlSnprintfElementContent(buf, size, content->c1, 1);
+	    else
+		xmlSnprintfElementContent(buf, size, content->c1, 0);
+	    len = strlen(buf);
+	    if (size - len < 50) {
+		if ((size - len > 4) && (buf[len - 1] != '.'))
+		    strcat(buf, " ...");
+		return;
+	    }
+            strcat(buf, " , ");
+	    if (((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
+		 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
+		(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
+		xmlSnprintfElementContent(buf, size, content->c2, 1);
+	    else
+		xmlSnprintfElementContent(buf, size, content->c2, 0);
+	    break;
+	case XML_ELEMENT_CONTENT_OR:
+	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+		xmlSnprintfElementContent(buf, size, content->c1, 1);
+	    else
+		xmlSnprintfElementContent(buf, size, content->c1, 0);
+	    len = strlen(buf);
+	    if (size - len < 50) {
+		if ((size - len > 4) && (buf[len - 1] != '.'))
+		    strcat(buf, " ...");
+		return;
+	    }
+            strcat(buf, " | ");
+	    if (((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
+		 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
+		(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
+		xmlSnprintfElementContent(buf, size, content->c2, 1);
+	    else
+		xmlSnprintfElementContent(buf, size, content->c2, 0);
+	    break;
+    }
+    if (englob)
+        strcat(buf, ")");
+    switch (content->ocur) {
+        case XML_ELEMENT_CONTENT_ONCE:
+	    break;
+        case XML_ELEMENT_CONTENT_OPT:
+	    strcat(buf, "?");
+	    break;
+        case XML_ELEMENT_CONTENT_MULT:
+	    strcat(buf, "*");
+	    break;
+        case XML_ELEMENT_CONTENT_PLUS:
+	    strcat(buf, "+");
+	    break;
+    }
+}
+
+/****************************************************************
+ *								*
+ *	Registration of DTD declarations			*
+ *								*
+ ****************************************************************/
+
+/**
+ * xmlFreeElement:
+ * @elem:  An element
+ *
+ * Deallocate the memory used by an element definition
+ */
+static void
+xmlFreeElement(xmlElementPtr elem) {
+    if (elem == NULL) return;
+    xmlUnlinkNode((xmlNodePtr) elem);
+    xmlFreeDocElementContent(elem->doc, elem->content);
+    if (elem->name != NULL)
+	xmlFree((xmlChar *) elem->name);
+    if (elem->prefix != NULL)
+	xmlFree((xmlChar *) elem->prefix);
+#ifdef LIBXML_REGEXP_ENABLED
+    if (elem->contModel != NULL)
+	xmlRegFreeRegexp(elem->contModel);
+#endif
+    xmlFree(elem);
+}
+
+
+/**
+ * xmlAddElementDecl:
+ * @ctxt:  the validation context
+ * @dtd:  pointer to the DTD
+ * @name:  the entity name
+ * @type:  the element type
+ * @content:  the element content tree or NULL
+ *
+ * Register a new element declaration
+ *
+ * Returns NULL if not, otherwise the entity
+ */
+xmlElementPtr
+xmlAddElementDecl(xmlValidCtxtPtr ctxt,
+                  xmlDtdPtr dtd, const xmlChar *name,
+                  xmlElementTypeVal type,
+		  xmlElementContentPtr content) {
+    xmlElementPtr ret;
+    xmlElementTablePtr table;
+    xmlAttributePtr oldAttributes = NULL;
+    xmlChar *ns, *uqname;
+
+    if (dtd == NULL) {
+	return(NULL);
+    }
+    if (name == NULL) {
+	return(NULL);
+    }
+
+    switch (type) {
+        case XML_ELEMENT_TYPE_EMPTY:
+	    if (content != NULL) {
+		xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		        "xmlAddElementDecl: content != NULL for EMPTY\n",
+			NULL);
+		return(NULL);
+	    }
+	    break;
+	case XML_ELEMENT_TYPE_ANY:
+	    if (content != NULL) {
+		xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		        "xmlAddElementDecl: content != NULL for ANY\n",
+			NULL);
+		return(NULL);
+	    }
+	    break;
+	case XML_ELEMENT_TYPE_MIXED:
+	    if (content == NULL) {
+		xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		        "xmlAddElementDecl: content == NULL for MIXED\n",
+			NULL);
+		return(NULL);
+	    }
+	    break;
+	case XML_ELEMENT_TYPE_ELEMENT:
+	    if (content == NULL) {
+		xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		        "xmlAddElementDecl: content == NULL for ELEMENT\n",
+			NULL);
+		return(NULL);
+	    }
+	    break;
+	default:
+	    xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ELEMENT decl corrupted invalid type\n",
+		    NULL);
+	    return(NULL);
+    }
+
+    /*
+     * check if name is a QName
+     */
+    uqname = xmlSplitQName2(name, &ns);
+    if (uqname != NULL)
+	name = uqname;
+
+    /*
+     * Create the Element table if needed.
+     */
+    table = (xmlElementTablePtr) dtd->elements;
+    if (table == NULL) {
+	xmlDictPtr dict = NULL;
+
+	if (dtd->doc != NULL)
+	    dict = dtd->doc->dict;
+        table = xmlHashCreateDict(0, dict);
+	dtd->elements = (void *) table;
+    }
+    if (table == NULL) {
+	xmlVErrMemory(ctxt,
+            "xmlAddElementDecl: Table creation failed!\n");
+	if (uqname != NULL)
+	    xmlFree(uqname);
+	if (ns != NULL)
+	    xmlFree(ns);
+        return(NULL);
+    }
+
+    /*
+     * lookup old attributes inserted on an undefined element in the
+     * internal subset.
+     */
+    if ((dtd->doc != NULL) && (dtd->doc->intSubset != NULL)) {
+	ret = xmlHashLookup2(dtd->doc->intSubset->elements, name, ns);
+	if ((ret != NULL) && (ret->etype == XML_ELEMENT_TYPE_UNDEFINED)) {
+	    oldAttributes = ret->attributes;
+	    ret->attributes = NULL;
+	    xmlHashRemoveEntry2(dtd->doc->intSubset->elements, name, ns, NULL);
+	    xmlFreeElement(ret);
+	}
+    }
+
+    /*
+     * The element may already be present if one of its attribute
+     * was registered first
+     */
+    ret = xmlHashLookup2(table, name, ns);
+    if (ret != NULL) {
+	if (ret->etype != XML_ELEMENT_TYPE_UNDEFINED) {
+#ifdef LIBXML_VALID_ENABLED
+	    /*
+	     * The element is already defined in this DTD.
+	     */
+	    xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ELEM_REDEFINED,
+	                    "Redefinition of element %s\n",
+			    name, NULL, NULL);
+#endif /* LIBXML_VALID_ENABLED */
+	    if (uqname != NULL)
+		xmlFree(uqname);
+            if (ns != NULL)
+	        xmlFree(ns);
+	    return(NULL);
+	}
+	if (ns != NULL) {
+	    xmlFree(ns);
+	    ns = NULL;
+	}
+    } else {
+	ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
+	if (ret == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+	    if (uqname != NULL)
+		xmlFree(uqname);
+            if (ns != NULL)
+	        xmlFree(ns);
+	    return(NULL);
+	}
+	memset(ret, 0, sizeof(xmlElement));
+	ret->type = XML_ELEMENT_DECL;
+
+	/*
+	 * fill the structure.
+	 */
+	ret->name = xmlStrdup(name);
+	if (ret->name == NULL) {
+	    xmlVErrMemory(ctxt, "malloc failed");
+	    if (uqname != NULL)
+		xmlFree(uqname);
+            if (ns != NULL)
+	        xmlFree(ns);
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	ret->prefix = ns;
+
+	/*
+	 * Validity Check:
+	 * Insertion must not fail
+	 */
+	if (xmlHashAddEntry2(table, name, ns, ret)) {
+#ifdef LIBXML_VALID_ENABLED
+	    /*
+	     * The element is already defined in this DTD.
+	     */
+	    xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ELEM_REDEFINED,
+	                    "Redefinition of element %s\n",
+			    name, NULL, NULL);
+#endif /* LIBXML_VALID_ENABLED */
+	    xmlFreeElement(ret);
+	    if (uqname != NULL)
+		xmlFree(uqname);
+	    return(NULL);
+	}
+	/*
+	 * For new element, may have attributes from earlier
+	 * definition in internal subset
+	 */
+	ret->attributes = oldAttributes;
+    }
+
+    /*
+     * Finish to fill the structure.
+     */
+    ret->etype = type;
+    /*
+     * Avoid a stupid copy when called by the parser
+     * and flag it by setting a special parent value
+     * so the parser doesn't unallocate it.
+     */
+    if ((ctxt != NULL) &&
+        ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
+         (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1))) {
+	ret->content = content;
+	if (content != NULL)
+	    content->parent = (xmlElementContentPtr) 1;
+    } else {
+	ret->content = xmlCopyDocElementContent(dtd->doc, content);
+    }
+
+    /*
+     * Link it to the DTD
+     */
+    ret->parent = dtd;
+    ret->doc = dtd->doc;
+    if (dtd->last == NULL) {
+	dtd->children = dtd->last = (xmlNodePtr) ret;
+    } else {
+        dtd->last->next = (xmlNodePtr) ret;
+	ret->prev = dtd->last;
+	dtd->last = (xmlNodePtr) ret;
+    }
+    if (uqname != NULL)
+	xmlFree(uqname);
+    return(ret);
+}
+
+/**
+ * xmlFreeElementTable:
+ * @table:  An element table
+ *
+ * Deallocate the memory used by an element hash table.
+ */
+void
+xmlFreeElementTable(xmlElementTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlCopyElement:
+ * @elem:  An element
+ *
+ * Build a copy of an element.
+ * 
+ * Returns the new xmlElementPtr or NULL in case of error.
+ */
+static xmlElementPtr
+xmlCopyElement(xmlElementPtr elem) {
+    xmlElementPtr cur;
+
+    cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
+    if (cur == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlElement));
+    cur->type = XML_ELEMENT_DECL;
+    cur->etype = elem->etype;
+    if (elem->name != NULL)
+	cur->name = xmlStrdup(elem->name);
+    else
+	cur->name = NULL;
+    if (elem->prefix != NULL)
+	cur->prefix = xmlStrdup(elem->prefix);
+    else
+	cur->prefix = NULL;
+    cur->content = xmlCopyElementContent(elem->content);
+    /* TODO : rebuild the attribute list on the copy */
+    cur->attributes = NULL;
+    return(cur);
+}
+
+/**
+ * xmlCopyElementTable:
+ * @table:  An element table
+ *
+ * Build a copy of an element table.
+ * 
+ * Returns the new xmlElementTablePtr or NULL in case of error.
+ */
+xmlElementTablePtr
+xmlCopyElementTable(xmlElementTablePtr table) {
+    return((xmlElementTablePtr) xmlHashCopy(table,
+		                            (xmlHashCopier) xmlCopyElement));
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlDumpElementDecl:
+ * @buf:  the XML buffer output
+ * @elem:  An element table
+ *
+ * This will dump the content of the element declaration as an XML
+ * DTD definition
+ */
+void
+xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
+    if ((buf == NULL) || (elem == NULL))
+        return;
+    switch (elem->etype) {
+	case XML_ELEMENT_TYPE_EMPTY:
+	    xmlBufferWriteChar(buf, "<!ELEMENT ");
+	    if (elem->prefix != NULL) {
+		xmlBufferWriteCHAR(buf, elem->prefix);
+		xmlBufferWriteChar(buf, ":");
+	    }
+	    xmlBufferWriteCHAR(buf, elem->name);
+	    xmlBufferWriteChar(buf, " EMPTY>\n");
+	    break;
+	case XML_ELEMENT_TYPE_ANY:
+	    xmlBufferWriteChar(buf, "<!ELEMENT ");
+	    if (elem->prefix != NULL) {
+		xmlBufferWriteCHAR(buf, elem->prefix);
+		xmlBufferWriteChar(buf, ":");
+	    }
+	    xmlBufferWriteCHAR(buf, elem->name);
+	    xmlBufferWriteChar(buf, " ANY>\n");
+	    break;
+	case XML_ELEMENT_TYPE_MIXED:
+	    xmlBufferWriteChar(buf, "<!ELEMENT ");
+	    if (elem->prefix != NULL) {
+		xmlBufferWriteCHAR(buf, elem->prefix);
+		xmlBufferWriteChar(buf, ":");
+	    }
+	    xmlBufferWriteCHAR(buf, elem->name);
+	    xmlBufferWriteChar(buf, " ");
+	    xmlDumpElementContent(buf, elem->content, 1);
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	case XML_ELEMENT_TYPE_ELEMENT:
+	    xmlBufferWriteChar(buf, "<!ELEMENT ");
+	    if (elem->prefix != NULL) {
+		xmlBufferWriteCHAR(buf, elem->prefix);
+		xmlBufferWriteChar(buf, ":");
+	    }
+	    xmlBufferWriteCHAR(buf, elem->name);
+	    xmlBufferWriteChar(buf, " ");
+	    xmlDumpElementContent(buf, elem->content, 1);
+	    xmlBufferWriteChar(buf, ">\n");
+	    break;
+	default:
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ELEMENT struct corrupted invalid type\n",
+		    NULL);
+    }
+}
+
+/**
+ * xmlDumpElementDeclScan:
+ * @elem:  An element table
+ * @buf:  the XML buffer output
+ *
+ * This routine is used by the hash scan function.  It just reverses
+ * the arguments.
+ */
+static void
+xmlDumpElementDeclScan(xmlElementPtr elem, xmlBufferPtr buf) {
+    xmlDumpElementDecl(buf, elem);
+}
+
+/**
+ * xmlDumpElementTable:
+ * @buf:  the XML buffer output
+ * @table:  An element table
+ *
+ * This will dump the content of the element table as an XML DTD definition
+ */
+void
+xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
+    if ((buf == NULL) || (table == NULL))
+        return;
+    xmlHashScan(table, (xmlHashScanner) xmlDumpElementDeclScan, buf);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlCreateEnumeration:
+ * @name:  the enumeration name or NULL
+ *
+ * create and initialize an enumeration attribute node.
+ *
+ * Returns the xmlEnumerationPtr just created or NULL in case
+ *                of error.
+ */
+xmlEnumerationPtr
+xmlCreateEnumeration(const xmlChar *name) {
+    xmlEnumerationPtr ret;
+
+    ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration));
+    if (ret == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+        return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlEnumeration));
+
+    if (name != NULL)
+        ret->name = xmlStrdup(name);
+    return(ret);
+}
+
+/**
+ * xmlFreeEnumeration:
+ * @cur:  the tree to free.
+ *
+ * free an enumeration attribute node (recursive).
+ */
+void
+xmlFreeEnumeration(xmlEnumerationPtr cur) {
+    if (cur == NULL) return;
+
+    if (cur->next != NULL) xmlFreeEnumeration(cur->next);
+
+    if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
+    xmlFree(cur);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlCopyEnumeration:
+ * @cur:  the tree to copy.
+ *
+ * Copy an enumeration attribute node (recursive).
+ *
+ * Returns the xmlEnumerationPtr just created or NULL in case
+ *                of error.
+ */
+xmlEnumerationPtr
+xmlCopyEnumeration(xmlEnumerationPtr cur) {
+    xmlEnumerationPtr ret;
+
+    if (cur == NULL) return(NULL);
+    ret = xmlCreateEnumeration((xmlChar *) cur->name);
+
+    if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
+    else ret->next = NULL;
+
+    return(ret);
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlDumpEnumeration:
+ * @buf:  the XML buffer output
+ * @enum:  An enumeration
+ *
+ * This will dump the content of the enumeration
+ */
+static void
+xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
+    if ((buf == NULL) || (cur == NULL))
+        return;
+    
+    xmlBufferWriteCHAR(buf, cur->name);
+    if (cur->next == NULL)
+	xmlBufferWriteChar(buf, ")");
+    else {
+	xmlBufferWriteChar(buf, " | ");
+	xmlDumpEnumeration(buf, cur->next);
+    }
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+/**
+ * xmlScanIDAttributeDecl:
+ * @ctxt:  the validation context
+ * @elem:  the element name
+ * @err: whether to raise errors here
+ *
+ * Verify that the element don't have too many ID attributes
+ * declared.
+ *
+ * Returns the number of ID attributes found.
+ */
+static int
+xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem, int err) {
+    xmlAttributePtr cur;
+    int ret = 0;
+
+    if (elem == NULL) return(0);
+    cur = elem->attributes;
+    while (cur != NULL) {
+        if (cur->atype == XML_ATTRIBUTE_ID) {
+	    ret ++;
+	    if ((ret > 1) && (err))
+		xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_MULTIPLE_ID,
+	       "Element %s has too many ID attributes defined : %s\n",
+		       elem->name, cur->name, NULL);
+	}
+	cur = cur->nexth;
+    }
+    return(ret);
+}
+#endif /* LIBXML_VALID_ENABLED */
+
+/**
+ * xmlFreeAttribute:
+ * @elem:  An attribute
+ *
+ * Deallocate the memory used by an attribute definition
+ */
+static void
+xmlFreeAttribute(xmlAttributePtr attr) {
+    xmlDictPtr dict;
+
+    if (attr == NULL) return;
+    if (attr->doc != NULL)
+	dict = attr->doc->dict;
+    else
+	dict = NULL;
+    xmlUnlinkNode((xmlNodePtr) attr);
+    if (attr->tree != NULL)
+        xmlFreeEnumeration(attr->tree);
+    if (dict) {
+        if ((attr->elem != NULL) && (!xmlDictOwns(dict, attr->elem)))
+	    xmlFree((xmlChar *) attr->elem);
+        if ((attr->name != NULL) && (!xmlDictOwns(dict, attr->name)))
+	    xmlFree((xmlChar *) attr->name);
+        if ((attr->prefix != NULL) && (!xmlDictOwns(dict, attr->prefix)))
+	    xmlFree((xmlChar *) attr->prefix);
+        if ((attr->defaultValue != NULL) &&
+	    (!xmlDictOwns(dict, attr->defaultValue)))
+	    xmlFree((xmlChar *) attr->defaultValue);
+    } else {
+	if (attr->elem != NULL)
+	    xmlFree((xmlChar *) attr->elem);
+	if (attr->name != NULL)
+	    xmlFree((xmlChar *) attr->name);
+	if (attr->defaultValue != NULL)
+	    xmlFree((xmlChar *) attr->defaultValue);
+	if (attr->prefix != NULL)
+	    xmlFree((xmlChar *) attr->prefix);
+    }
+    xmlFree(attr);
+}
+
+
+/**
+ * xmlAddAttributeDecl:
+ * @ctxt:  the validation context
+ * @dtd:  pointer to the DTD
+ * @elem:  the element name
+ * @name:  the attribute name
+ * @ns:  the attribute namespace prefix
+ * @type:  the attribute type
+ * @def:  the attribute default type
+ * @defaultValue:  the attribute default value
+ * @tree:  if it's an enumeration, the associated list
+ *
+ * Register a new attribute declaration
+ * Note that @tree becomes the ownership of the DTD
+ *
+ * Returns NULL if not new, otherwise the attribute decl
+ */
+xmlAttributePtr
+xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
+                    xmlDtdPtr dtd, const xmlChar *elem,
+                    const xmlChar *name, const xmlChar *ns,
+		    xmlAttributeType type, xmlAttributeDefault def,
+		    const xmlChar *defaultValue, xmlEnumerationPtr tree) {
+    xmlAttributePtr ret;
+    xmlAttributeTablePtr table;
+    xmlElementPtr elemDef;
+    xmlDictPtr dict = NULL;
+
+    if (dtd == NULL) {
+	xmlFreeEnumeration(tree);
+	return(NULL);
+    }
+    if (name == NULL) {
+	xmlFreeEnumeration(tree);
+	return(NULL);
+    }
+    if (elem == NULL) {
+	xmlFreeEnumeration(tree);
+	return(NULL);
+    }
+    if (dtd->doc != NULL)
+	dict = dtd->doc->dict;
+
+#ifdef LIBXML_VALID_ENABLED
+    /*
+     * Check the type and possibly the default value.
+     */
+    switch (type) {
+        case XML_ATTRIBUTE_CDATA:
+	    break;
+        case XML_ATTRIBUTE_ID:
+	    break;
+        case XML_ATTRIBUTE_IDREF:
+	    break;
+        case XML_ATTRIBUTE_IDREFS:
+	    break;
+        case XML_ATTRIBUTE_ENTITY:
+	    break;
+        case XML_ATTRIBUTE_ENTITIES:
+	    break;
+        case XML_ATTRIBUTE_NMTOKEN:
+	    break;
+        case XML_ATTRIBUTE_NMTOKENS:
+	    break;
+        case XML_ATTRIBUTE_ENUMERATION:
+	    break;
+        case XML_ATTRIBUTE_NOTATION:
+	    break;
+	default:
+	    xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ATTRIBUTE struct corrupted invalid type\n",
+		    NULL);
+	    xmlFreeEnumeration(tree);
+	    return(NULL);
+    }
+    if ((defaultValue != NULL) && 
+        (!xmlValidateAttributeValueInternal(dtd->doc, type, defaultValue))) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_DEFAULT,
+	                "Attribute %s of %s: invalid default value\n",
+	                elem, name, defaultValue);
+	defaultValue = NULL;
+	if (ctxt != NULL)
+	    ctxt->valid = 0;
+    }
+#endif /* LIBXML_VALID_ENABLED */
+
+    /*
+     * Check first that an attribute defined in the external subset wasn't
+     * already defined in the internal subset
+     */
+    if ((dtd->doc != NULL) && (dtd->doc->extSubset == dtd) &&
+	(dtd->doc->intSubset != NULL) &&
+	(dtd->doc->intSubset->attributes != NULL)) {
+        ret = xmlHashLookup3(dtd->doc->intSubset->attributes, name, ns, elem);
+	if (ret != NULL) {
+	    xmlFreeEnumeration(tree);
+	    return(NULL);
+	}
+    }
+
+    /*
+     * Create the Attribute table if needed.
+     */
+    table = (xmlAttributeTablePtr) dtd->attributes;
+    if (table == NULL) {
+        table = xmlHashCreateDict(0, dict);
+	dtd->attributes = (void *) table;
+    }
+    if (table == NULL) {
+	xmlVErrMemory(ctxt,
+            "xmlAddAttributeDecl: Table creation failed!\n");
+	xmlFreeEnumeration(tree);
+        return(NULL);
+    }
+
+
+    ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
+    if (ret == NULL) {
+	xmlVErrMemory(ctxt, "malloc failed");
+	xmlFreeEnumeration(tree);
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlAttribute));
+    ret->type = XML_ATTRIBUTE_DECL;
+
+    /*
+     * fill the structure.
+     */
+    ret->atype = type;
+    /*
+     * doc must be set before possible error causes call
+     * to xmlFreeAttribute (because it's used to check on
+     * dict use)
+     */
+    ret->doc = dtd->doc;
+    if (dict) {
+	ret->name = xmlDictLookup(dict, name, -1);
+	ret->prefix = xmlDictLookup(dict, ns, -1);
+	ret->elem = xmlDictLookup(dict, elem, -1);
+    } else {
+	ret->name = xmlStrdup(name);
+	ret->prefix = xmlStrdup(ns);
+	ret->elem = xmlStrdup(elem);
+    }
+    ret->def = def;
+    ret->tree = tree;
+    if (defaultValue != NULL) {
+        if (dict)
+	    ret->defaultValue = xmlDictLookup(dict, defaultValue, -1);
+	else
+	    ret->defaultValue = xmlStrdup(defaultValue);
+    }
+
+    /*
+     * Validity Check:
+     * Search the DTD for previous declarations of the ATTLIST
+     */
+    if (xmlHashAddEntry3(table, ret->name, ret->prefix, ret->elem, ret) < 0) {
+#ifdef LIBXML_VALID_ENABLED
+	/*
+	 * The attribute is already defined in this DTD.
+	 */
+	xmlErrValidWarning(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_REDEFINED,
+		 "Attribute %s of element %s: already defined\n",
+		 name, elem, NULL);
+#endif /* LIBXML_VALID_ENABLED */
+	xmlFreeAttribute(ret);
+	return(NULL);
+    }
+
+    /*
+     * Validity Check:
+     * Multiple ID per element
+     */
+    elemDef = xmlGetDtdElementDesc2(dtd, elem, 1);
+    if (elemDef != NULL) {
+
+#ifdef LIBXML_VALID_ENABLED
+        if ((type == XML_ATTRIBUTE_ID) &&
+	    (xmlScanIDAttributeDecl(NULL, elemDef, 1) != 0)) {
+	    xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_MULTIPLE_ID,
+	   "Element %s has too may ID attributes defined : %s\n",
+		   elem, name, NULL);
+	    if (ctxt != NULL)
+		ctxt->valid = 0;
+	}
+#endif /* LIBXML_VALID_ENABLED */
+
+	/*
+	 * Insert namespace default def first they need to be
+	 * processed first.
+	 */
+	if ((xmlStrEqual(ret->name, BAD_CAST "xmlns")) ||
+	    ((ret->prefix != NULL &&
+	     (xmlStrEqual(ret->prefix, BAD_CAST "xmlns"))))) {
+	    ret->nexth = elemDef->attributes;
+	    elemDef->attributes = ret;
+	} else {
+	    xmlAttributePtr tmp = elemDef->attributes;
+
+	    while ((tmp != NULL) &&
+		   ((xmlStrEqual(tmp->name, BAD_CAST "xmlns")) ||
+		    ((ret->prefix != NULL &&
+		     (xmlStrEqual(ret->prefix, BAD_CAST "xmlns")))))) {
+		if (tmp->nexth == NULL)
+		    break;
+		tmp = tmp->nexth;
+	    }
+	    if (tmp != NULL) {
+		ret->nexth = tmp->nexth;
+	        tmp->nexth = ret;
+	    } else {
+		ret->nexth = elemDef->attributes;
+		elemDef->attributes = ret;
+	    }
+	}
+    }
+
+    /*
+     * Link it to the DTD
+     */
+    ret->parent = dtd;
+    if (dtd->last == NULL) {
+	dtd->children = dtd->last = (xmlNodePtr) ret;
+    } else {
+        dtd->last->next = (xmlNodePtr) ret;
+	ret->prev = dtd->last;
+	dtd->last = (xmlNodePtr) ret;
+    }
+    return(ret);
+}
+
+/**
+ * xmlFreeAttributeTable:
+ * @table:  An attribute table
+ *
+ * Deallocate the memory used by an entities hash table.
+ */
+void
+xmlFreeAttributeTable(xmlAttributeTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlCopyAttribute:
+ * @attr:  An attribute
+ *
+ * Build a copy of an attribute.
+ * 
+ * Returns the new xmlAttributePtr or NULL in case of error.
+ */
+static xmlAttributePtr
+xmlCopyAttribute(xmlAttributePtr attr) {
+    xmlAttributePtr cur;
+
+    cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
+    if (cur == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlAttribute));
+    cur->type = XML_ATTRIBUTE_DECL;
+    cur->atype = attr->atype;
+    cur->def = attr->def;
+    cur->tree = xmlCopyEnumeration(attr->tree);
+    if (attr->elem != NULL)
+	cur->elem = xmlStrdup(attr->elem);
+    if (attr->name != NULL)
+	cur->name = xmlStrdup(attr->name);
+    if (attr->prefix != NULL)
+	cur->prefix = xmlStrdup(attr->prefix);
+    if (attr->defaultValue != NULL)
+	cur->defaultValue = xmlStrdup(attr->defaultValue);
+    return(cur);
+}
+
+/**
+ * xmlCopyAttributeTable:
+ * @table:  An attribute table
+ *
+ * Build a copy of an attribute table.
+ * 
+ * Returns the new xmlAttributeTablePtr or NULL in case of error.
+ */
+xmlAttributeTablePtr
+xmlCopyAttributeTable(xmlAttributeTablePtr table) {
+    return((xmlAttributeTablePtr) xmlHashCopy(table,
+				    (xmlHashCopier) xmlCopyAttribute));
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlDumpAttributeDecl:
+ * @buf:  the XML buffer output
+ * @attr:  An attribute declaration
+ *
+ * This will dump the content of the attribute declaration as an XML
+ * DTD definition
+ */
+void
+xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
+    if ((buf == NULL) || (attr == NULL))
+        return;
+    xmlBufferWriteChar(buf, "<!ATTLIST ");
+    xmlBufferWriteCHAR(buf, attr->elem);
+    xmlBufferWriteChar(buf, " ");
+    if (attr->prefix != NULL) {
+	xmlBufferWriteCHAR(buf, attr->prefix);
+	xmlBufferWriteChar(buf, ":");
+    }
+    xmlBufferWriteCHAR(buf, attr->name);
+    switch (attr->atype) {
+	case XML_ATTRIBUTE_CDATA:
+	    xmlBufferWriteChar(buf, " CDATA");
+	    break;
+	case XML_ATTRIBUTE_ID:
+	    xmlBufferWriteChar(buf, " ID");
+	    break;
+	case XML_ATTRIBUTE_IDREF:
+	    xmlBufferWriteChar(buf, " IDREF");
+	    break;
+	case XML_ATTRIBUTE_IDREFS:
+	    xmlBufferWriteChar(buf, " IDREFS");
+	    break;
+	case XML_ATTRIBUTE_ENTITY:
+	    xmlBufferWriteChar(buf, " ENTITY");
+	    break;
+	case XML_ATTRIBUTE_ENTITIES:
+	    xmlBufferWriteChar(buf, " ENTITIES");
+	    break;
+	case XML_ATTRIBUTE_NMTOKEN:
+	    xmlBufferWriteChar(buf, " NMTOKEN");
+	    break;
+	case XML_ATTRIBUTE_NMTOKENS:
+	    xmlBufferWriteChar(buf, " NMTOKENS");
+	    break;
+	case XML_ATTRIBUTE_ENUMERATION:
+	    xmlBufferWriteChar(buf, " (");
+	    xmlDumpEnumeration(buf, attr->tree);
+	    break;
+	case XML_ATTRIBUTE_NOTATION:
+	    xmlBufferWriteChar(buf, " NOTATION (");
+	    xmlDumpEnumeration(buf, attr->tree);
+	    break;
+	default:
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ATTRIBUTE struct corrupted invalid type\n",
+		    NULL);
+    }
+    switch (attr->def) {
+	case XML_ATTRIBUTE_NONE:
+	    break;
+	case XML_ATTRIBUTE_REQUIRED:
+	    xmlBufferWriteChar(buf, " #REQUIRED");
+	    break;
+	case XML_ATTRIBUTE_IMPLIED:
+	    xmlBufferWriteChar(buf, " #IMPLIED");
+	    break;
+	case XML_ATTRIBUTE_FIXED:
+	    xmlBufferWriteChar(buf, " #FIXED");
+	    break;
+	default:
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+		    "Internal: ATTRIBUTE struct corrupted invalid def\n",
+		    NULL);
+    }
+    if (attr->defaultValue != NULL) {
+	xmlBufferWriteChar(buf, " ");
+	xmlBufferWriteQuotedString(buf, attr->defaultValue);
+    }
+    xmlBufferWriteChar(buf, ">\n");
+}
+
+/**
+ * xmlDumpAttributeDeclScan:
+ * @attr:  An attribute declaration
+ * @buf:  the XML buffer output
+ *
+ * This is used with the hash scan function - just reverses arguments
+ */
+static void
+xmlDumpAttributeDeclScan(xmlAttributePtr attr, xmlBufferPtr buf) {
+    xmlDumpAttributeDecl(buf, attr);
+}
+
+/**
+ * xmlDumpAttributeTable:
+ * @buf:  the XML buffer output
+ * @table:  An attribute table
+ *
+ * This will dump the content of the attribute table as an XML DTD definition
+ */
+void
+xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
+    if ((buf == NULL) || (table == NULL))
+        return;
+    xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDeclScan, buf);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *				NOTATIONs				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlFreeNotation:
+ * @not:  A notation
+ *
+ * Deallocate the memory used by an notation definition
+ */
+static void
+xmlFreeNotation(xmlNotationPtr nota) {
+    if (nota == NULL) return;
+    if (nota->name != NULL)
+	xmlFree((xmlChar *) nota->name);
+    if (nota->PublicID != NULL)
+	xmlFree((xmlChar *) nota->PublicID);
+    if (nota->SystemID != NULL)
+	xmlFree((xmlChar *) nota->SystemID);
+    xmlFree(nota);
+}
+
+
+/**
+ * xmlAddNotationDecl:
+ * @dtd:  pointer to the DTD
+ * @ctxt:  the validation context
+ * @name:  the entity name
+ * @PublicID:  the public identifier or NULL
+ * @SystemID:  the system identifier or NULL
+ *
+ * Register a new notation declaration
+ *
+ * Returns NULL if not, otherwise the entity
+ */
+xmlNotationPtr
+xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd,
+	           const xmlChar *name,
+                   const xmlChar *PublicID, const xmlChar *SystemID) {
+    xmlNotationPtr ret;
+    xmlNotationTablePtr table;
+
+    if (dtd == NULL) {
+	return(NULL);
+    }
+    if (name == NULL) {
+	return(NULL);
+    }
+    if ((PublicID == NULL) && (SystemID == NULL)) {
+	return(NULL);
+    }
+
+    /*
+     * Create the Notation table if needed.
+     */
+    table = (xmlNotationTablePtr) dtd->notations;
+    if (table == NULL) {
+	xmlDictPtr dict = NULL;
+	if (dtd->doc != NULL)
+	    dict = dtd->doc->dict;
+
+        dtd->notations = table = xmlHashCreateDict(0, dict);
+    }
+    if (table == NULL) {
+	xmlVErrMemory(ctxt,
+		"xmlAddNotationDecl: Table creation failed!\n");
+        return(NULL);
+    }
+
+    ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
+    if (ret == NULL) {
+	xmlVErrMemory(ctxt, "malloc failed");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlNotation));
+
+    /*
+     * fill the structure.
+     */
+    ret->name = xmlStrdup(name);
+    if (SystemID != NULL)
+        ret->SystemID = xmlStrdup(SystemID);
+    if (PublicID != NULL)
+        ret->PublicID = xmlStrdup(PublicID);
+
+    /*
+     * Validity Check:
+     * Check the DTD for previous declarations of the ATTLIST
+     */
+    if (xmlHashAddEntry(table, name, ret)) {
+#ifdef LIBXML_VALID_ENABLED
+	xmlErrValid(NULL, XML_DTD_NOTATION_REDEFINED, 
+		    "xmlAddNotationDecl: %s already defined\n",
+		    (const char *) name);
+#endif /* LIBXML_VALID_ENABLED */
+	xmlFreeNotation(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlFreeNotationTable:
+ * @table:  An notation table
+ *
+ * Deallocate the memory used by an entities hash table.
+ */
+void
+xmlFreeNotationTable(xmlNotationTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation);
+}
+
+#ifdef LIBXML_TREE_ENABLED
+/**
+ * xmlCopyNotation:
+ * @nota:  A notation
+ *
+ * Build a copy of a notation.
+ * 
+ * Returns the new xmlNotationPtr or NULL in case of error.
+ */
+static xmlNotationPtr
+xmlCopyNotation(xmlNotationPtr nota) {
+    xmlNotationPtr cur;
+
+    cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
+    if (cur == NULL) {
+	xmlVErrMemory(NULL, "malloc failed");
+	return(NULL);
+    }
+    if (nota->name != NULL)
+	cur->name = xmlStrdup(nota->name);
+    else
+	cur->name = NULL;
+    if (nota->PublicID != NULL)
+	cur->PublicID = xmlStrdup(nota->PublicID);
+    else
+	cur->PublicID = NULL;
+    if (nota->SystemID != NULL)
+	cur->SystemID = xmlStrdup(nota->SystemID);
+    else
+	cur->SystemID = NULL;
+    return(cur);
+}
+
+/**
+ * xmlCopyNotationTable:
+ * @table:  A notation table
+ *
+ * Build a copy of a notation table.
+ * 
+ * Returns the new xmlNotationTablePtr or NULL in case of error.
+ */
+xmlNotationTablePtr
+xmlCopyNotationTable(xmlNotationTablePtr table) {
+    return((xmlNotationTablePtr) xmlHashCopy(table,
+				    (xmlHashCopier) xmlCopyNotation));
+}
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlDumpNotationDecl:
+ * @buf:  the XML buffer output
+ * @nota:  A notation declaration
+ *
+ * This will dump the content the notation declaration as an XML DTD definition
+ */
+void
+xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
+    if ((buf == NULL) || (nota == NULL))
+        return;
+    xmlBufferWriteChar(buf, "<!NOTATION ");
+    xmlBufferWriteCHAR(buf, nota->name);
+    if (nota->PublicID != NULL) {
+	xmlBufferWriteChar(buf, " PUBLIC ");
+	xmlBufferWriteQuotedString(buf, nota->PublicID);
+	if (nota->SystemID != NULL) {
+	    xmlBufferWriteChar(buf, " ");
+	    xmlBufferWriteQuotedString(buf, nota->SystemID);
+	}
+    } else {
+	xmlBufferWriteChar(buf, " SYSTEM ");
+	xmlBufferWriteQuotedString(buf, nota->SystemID);
+    }
+    xmlBufferWriteChar(buf, " >\n");
+}
+
+/**
+ * xmlDumpNotationDeclScan:
+ * @nota:  A notation declaration
+ * @buf:  the XML buffer output
+ *
+ * This is called with the hash scan function, and just reverses args
+ */
+static void
+xmlDumpNotationDeclScan(xmlNotationPtr nota, xmlBufferPtr buf) {
+    xmlDumpNotationDecl(buf, nota);
+}
+
+/**
+ * xmlDumpNotationTable:
+ * @buf:  the XML buffer output
+ * @table:  A notation table
+ *
+ * This will dump the content of the notation table as an XML DTD definition
+ */
+void
+xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
+    if ((buf == NULL) || (table == NULL))
+        return;
+    xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDeclScan, buf);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *				IDs					*
+ *									*
+ ************************************************************************/
+/**
+ * DICT_FREE:
+ * @str:  a string
+ *
+ * Free a string if it is not owned by the "dict" dictionnary in the
+ * current scope
+ */
+#define DICT_FREE(str)						\
+	if ((str) && ((!dict) || 				\
+	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
+	    xmlFree((char *)(str));
+
+/**
+ * xmlFreeID:
+ * @not:  A id
+ *
+ * Deallocate the memory used by an id definition
+ */
+static void
+xmlFreeID(xmlIDPtr id) {
+    xmlDictPtr dict = NULL;
+
+    if (id == NULL) return;
+
+    if (id->doc != NULL)
+        dict = id->doc->dict;
+
+    if (id->value != NULL)
+	DICT_FREE(id->value)
+    if (id->name != NULL)
+	DICT_FREE(id->name)
+    xmlFree(id);
+}
+
+
+/**
+ * xmlAddID:
+ * @ctxt:  the validation context
+ * @doc:  pointer to the document
+ * @value:  the value name
+ * @attr:  the attribute holding the ID
+ *
+ * Register a new id declaration
+ *
+ * Returns NULL if not, otherwise the new xmlIDPtr
+ */
+xmlIDPtr 
+xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
+         xmlAttrPtr attr) {
+    xmlIDPtr ret;
+    xmlIDTablePtr table;
+
+    if (doc == NULL) {
+	return(NULL);
+    }
+    if (value == NULL) {
+	return(NULL);
+    }
+    if (attr == NULL) {
+	return(NULL);
+    }
+
+    /*
+     * Create the ID table if needed.
+     */
+    table = (xmlIDTablePtr) doc->ids;
+    if (table == NULL)  {
+        doc->ids = table = xmlHashCreateDict(0, doc->dict);
+    }
+    if (table == NULL) {
+	xmlVErrMemory(ctxt,
+		"xmlAddID: Table creation failed!\n");
+        return(NULL);
+    }
+
+    ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
+    if (ret == NULL) {
+	xmlVErrMemory(ctxt, "malloc failed");
+	return(NULL);
+    }
+
+    /*
+     * fill the structure.
+     */
+    ret->value = xmlStrdup(value);
+    ret->doc = doc;
+    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+	/*
+	 * Operating in streaming mode, attr is gonna disapear
+	 */
+	if (doc->dict != NULL)
+	    ret->name = xmlDictLookup(doc->dict, attr->name, -1);
+	else
+	    ret->name = xmlStrdup(attr->name);
+	ret->attr = NULL;
+    } else {
+	ret->attr = attr;
+	ret->name = NULL;
+    }
+    ret->lineno = xmlGetLineNo(attr->parent);
+
+    if (xmlHashAddEntry(table, value, ret) < 0) {
+#ifdef LIBXML_VALID_ENABLED
+	/*
+	 * The id is already defined in this DTD.
+	 */
+	if ((ctxt != NULL) && (ctxt->error != NULL)) {
+	    xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
+	                    "ID %s already defined\n",
+			    value, NULL, NULL);
+	}
+#endif /* LIBXML_VALID_ENABLED */
+	xmlFreeID(ret);
+	return(NULL);
+    }
+    if (attr != NULL)
+	attr->atype = XML_ATTRIBUTE_ID;
+    return(ret);
+}
+
+/**
+ * xmlFreeIDTable:
+ * @table:  An id table
+ *
+ * Deallocate the memory used by an ID hash table.
+ */
+void
+xmlFreeIDTable(xmlIDTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
+}
+
+/**
+ * xmlIsID:
+ * @doc:  the document
+ * @elem:  the element carrying the attribute
+ * @attr:  the attribute
+ *
+ * Determine whether an attribute is of type ID. In case we have DTD(s)
+ * then this is done if DTD loading has been requested. In the case
+ * of HTML documents parsed with the HTML parser, then ID detection is
+ * done systematically.
+ *
+ * Returns 0 or 1 depending on the lookup result
+ */
+int
+xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
+    if ((attr == NULL) || (attr->name == NULL)) return(0);
+    if ((attr->ns != NULL) && (attr->ns->prefix != NULL) &&
+        (!strcmp((char *) attr->name, "id")) &&
+        (!strcmp((char *) attr->ns->prefix, "xml")))
+	return(1);
+    if (doc == NULL) return(0);
+    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)) ||
+	    ((xmlStrEqual(BAD_CAST "name", attr->name)) &&
+	    ((elem == NULL) || (xmlStrEqual(elem->name, BAD_CAST "a")))))
+	    return(1);
+	return(0);    
+    } else if (elem == NULL) {
+	return(0);
+    } else {
+	xmlAttributePtr attrDecl = NULL;
+
+	xmlChar felem[50], fattr[50];
+	xmlChar *fullelemname, *fullattrname;
+
+	fullelemname = (elem->ns != NULL && elem->ns->prefix != NULL) ?
+	    xmlBuildQName(elem->name, elem->ns->prefix, felem, 50) :
+	    (xmlChar *)elem->name;
+
+	fullattrname = (attr->ns != NULL && attr->ns->prefix != NULL) ?
+	    xmlBuildQName(attr->name, attr->ns->prefix, fattr, 50) :
+	    (xmlChar *)attr->name;
+
+	if (fullelemname != NULL && fullattrname != NULL) {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullelemname,
+		                         fullattrname);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullelemname,
+					     fullattrname);
+	}
+
+	if ((fullattrname != fattr) && (fullattrname != attr->name))
+	    xmlFree(fullattrname);
+	if ((fullelemname != felem) && (fullelemname != elem->name))
+	    xmlFree(fullelemname);
+
+        if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
+	    return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlRemoveID:
+ * @doc:  the document
+ * @attr:  the attribute
+ *
+ * Remove the given attribute from the ID table maintained internally.
+ *
+ * Returns -1 if the lookup failed and 0 otherwise
+ */
+int
+xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
+    xmlIDTablePtr table;
+    xmlIDPtr id;
+    xmlChar *ID;
+
+    if (doc == NULL) return(-1);
+    if (attr == NULL) return(-1);
+    table = (xmlIDTablePtr) doc->ids;
+    if (table == NULL) 
+        return(-1);
+
+    if (attr == NULL)
+	return(-1);
+    ID = xmlNodeListGetString(doc, attr->children, 1);
+    if (ID == NULL)
+	return(-1);
+    id = xmlHashLookup(table, ID);
+    if (id == NULL || id->attr != attr) {
+	xmlFree(ID);
+	return(-1);
+    }
+    xmlHashRemoveEntry(table, ID, (xmlHashDeallocator) xmlFreeID);
+    xmlFree(ID);
+	attr->atype = 0;
+    return(0);
+}
+
+/**
+ * xmlGetID:
+ * @doc:  pointer to the document
+ * @ID:  the ID value
+ *
+ * Search the attribute declaring the given ID
+ *
+ * Returns NULL if not found, otherwise the xmlAttrPtr defining the ID
+ */
+xmlAttrPtr 
+xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
+    xmlIDTablePtr table;
+    xmlIDPtr id;
+
+    if (doc == NULL) {
+	return(NULL);
+    }
+
+    if (ID == NULL) {
+	return(NULL);
+    }
+
+    table = (xmlIDTablePtr) doc->ids;
+    if (table == NULL) 
+        return(NULL);
+
+    id = xmlHashLookup(table, ID);
+    if (id == NULL)
+	return(NULL);
+    if (id->attr == NULL) {
+	/*
+	 * We are operating on a stream, return a well known reference
+	 * since the attribute node doesn't exist anymore
+	 */
+	return((xmlAttrPtr) doc);
+    }
+    return(id->attr);
+}
+
+/************************************************************************
+ *									*
+ *				Refs					*
+ *									*
+ ************************************************************************/
+typedef struct xmlRemoveMemo_t 
+{
+	xmlListPtr l;
+	xmlAttrPtr ap;
+} xmlRemoveMemo;
+
+typedef xmlRemoveMemo *xmlRemoveMemoPtr;
+
+typedef struct xmlValidateMemo_t 
+{
+    xmlValidCtxtPtr ctxt;
+    const xmlChar *name;
+} xmlValidateMemo;
+
+typedef xmlValidateMemo *xmlValidateMemoPtr;
+
+/**
+ * xmlFreeRef:
+ * @lk:  A list link
+ *
+ * Deallocate the memory used by a ref definition
+ */
+static void
+xmlFreeRef(xmlLinkPtr lk) {
+    xmlRefPtr ref = (xmlRefPtr)xmlLinkGetData(lk);
+    if (ref == NULL) return;
+    if (ref->value != NULL)
+        xmlFree((xmlChar *)ref->value);
+    if (ref->name != NULL)
+        xmlFree((xmlChar *)ref->name);
+    xmlFree(ref);
+}
+
+/**
+ * xmlFreeRefList:
+ * @list_ref:  A list of references.
+ *
+ * Deallocate the memory used by a list of references
+ */
+static void
+xmlFreeRefList(xmlListPtr list_ref) {
+    if (list_ref == NULL) return;
+    xmlListDelete(list_ref);
+}
+
+/**
+ * xmlWalkRemoveRef:
+ * @data:  Contents of current link
+ * @user:  Value supplied by the user
+ *
+ * Returns 0 to abort the walk or 1 to continue
+ */
+static int
+xmlWalkRemoveRef(const void *data, const void *user)
+{
+    xmlAttrPtr attr0 = ((xmlRefPtr)data)->attr;
+    xmlAttrPtr attr1 = ((xmlRemoveMemoPtr)user)->ap;
+    xmlListPtr ref_list = ((xmlRemoveMemoPtr)user)->l;
+
+    if (attr0 == attr1) { /* Matched: remove and terminate walk */
+        xmlListRemoveFirst(ref_list, (void *)data);
+        return 0;
+    }
+    return 1;
+}
+
+/**
+ * xmlDummyCompare
+ * @data0:  Value supplied by the user
+ * @data1:  Value supplied by the user
+ *
+ * Do nothing, return 0. Used to create unordered lists.
+ */
+static int
+xmlDummyCompare(const void *data0 ATTRIBUTE_UNUSED,
+                const void *data1 ATTRIBUTE_UNUSED)
+{
+    return (0);
+}
+
+/**
+ * xmlAddRef:
+ * @ctxt:  the validation context
+ * @doc:  pointer to the document
+ * @value:  the value name
+ * @attr:  the attribute holding the Ref
+ *
+ * Register a new ref declaration
+ *
+ * Returns NULL if not, otherwise the new xmlRefPtr
+ */
+xmlRefPtr 
+xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
+    xmlAttrPtr attr) {
+    xmlRefPtr ret;
+    xmlRefTablePtr table;
+    xmlListPtr ref_list;
+
+    if (doc == NULL) {
+        return(NULL);
+    }
+    if (value == NULL) {
+        return(NULL);
+    }
+    if (attr == NULL) {
+        return(NULL);
+    }
+
+    /*
+     * Create the Ref table if needed.
+     */
+    table = (xmlRefTablePtr) doc->refs;
+    if (table == NULL) {
+        doc->refs = table = xmlHashCreateDict(0, doc->dict);
+    }
+    if (table == NULL) {
+	xmlVErrMemory(ctxt,
+            "xmlAddRef: Table creation failed!\n");
+        return(NULL);
+    }
+
+    ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
+    if (ret == NULL) {
+	xmlVErrMemory(ctxt, "malloc failed");
+        return(NULL);
+    }
+
+    /*
+     * fill the structure.
+     */
+    ret->value = xmlStrdup(value);
+    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+	/*
+	 * Operating in streaming mode, attr is gonna disapear
+	 */
+	ret->name = xmlStrdup(attr->name);
+	ret->attr = NULL;
+    } else {
+	ret->name = NULL;
+	ret->attr = attr;
+    }
+    ret->lineno = xmlGetLineNo(attr->parent);
+
+    /* To add a reference :-
+     * References are maintained as a list of references,
+     * Lookup the entry, if no entry create new nodelist
+     * Add the owning node to the NodeList
+     * Return the ref
+     */
+
+    if (NULL == (ref_list = xmlHashLookup(table, value))) {
+        if (NULL == (ref_list = xmlListCreate(xmlFreeRef, xmlDummyCompare))) {
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+		    "xmlAddRef: Reference list creation failed!\n",
+		    NULL);
+	    goto failed;
+        }
+        if (xmlHashAddEntry(table, value, ref_list) < 0) {
+            xmlListDelete(ref_list);
+	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+		    "xmlAddRef: Reference list insertion failed!\n",
+		    NULL);
+	    goto failed;
+        }
+    }
+    if (xmlListAppend(ref_list, ret) != 0) {
+	xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+		    "xmlAddRef: Reference list insertion failed!\n",
+		    NULL);
+        goto failed;
+    }
+    return(ret);
+failed:
+    if (ret != NULL) {
+        if (ret->value != NULL)
+	    xmlFree((char *)ret->value);
+        if (ret->name != NULL)
+	    xmlFree((char *)ret->name);
+        xmlFree(ret);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlFreeRefTable:
+ * @table:  An ref table
+ *
+ * Deallocate the memory used by an Ref hash table.
+ */
+void
+xmlFreeRefTable(xmlRefTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeRefList);
+}
+
+/**
+ * xmlIsRef:
+ * @doc:  the document
+ * @elem:  the element carrying the attribute
+ * @attr:  the attribute
+ *
+ * Determine whether an attribute is of type Ref. In case we have DTD(s)
+ * then this is simple, otherwise we use an heuristic: name Ref (upper
+ * or lowercase).
+ *
+ * Returns 0 or 1 depending on the lookup result
+ */
+int
+xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
+    if (attr == NULL)
+        return(0);
+    if (doc == NULL) {
+        doc = attr->doc;
+	if (doc == NULL) return(0);
+    }
+
+    if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
+        return(0);
+    } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
+        /* TODO @@@ */
+        return(0);    
+    } else {
+        xmlAttributePtr attrDecl;
+
+        if (elem == NULL) return(0);
+        attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
+        if ((attrDecl == NULL) && (doc->extSubset != NULL))
+            attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+		                         elem->name, attr->name);
+
+	if ((attrDecl != NULL) &&
+	    (attrDecl->atype == XML_ATTRIBUTE_IDREF ||
+	     attrDecl->atype == XML_ATTRIBUTE_IDREFS))
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlRemoveRef:
+ * @doc:  the document
+ * @attr:  the attribute
+ *
+ * Remove the given attribute from the Ref table maintained internally.
+ *
+ * Returns -1 if the lookup failed and 0 otherwise
+ */
+int
+xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
+    xmlListPtr ref_list;
+    xmlRefTablePtr table;
+    xmlChar *ID;
+    xmlRemoveMemo target;
+
+    if (doc == NULL) return(-1);
+    if (attr == NULL) return(-1);
+    table = (xmlRefTablePtr) doc->refs;
+    if (table == NULL) 
+        return(-1);
+
+    if (attr == NULL)
+        return(-1);
+    ID = xmlNodeListGetString(doc, attr->children, 1);
+    if (ID == NULL)
+        return(-1);
+    ref_list = xmlHashLookup(table, ID);
+
+    if(ref_list == NULL) {
+        xmlFree(ID);
+        return (-1);
+    }
+    /* At this point, ref_list refers to a list of references which
+     * have the same key as the supplied attr. Our list of references
+     * is ordered by reference address and we don't have that information
+     * here to use when removing. We'll have to walk the list and
+     * check for a matching attribute, when we find one stop the walk
+     * and remove the entry.
+     * The list is ordered by reference, so that means we don't have the
+     * key. Passing the list and the reference to the walker means we
+     * will have enough data to be able to remove the entry.
+     */
+    target.l = ref_list;
+    target.ap = attr;
+    
+    /* Remove the supplied attr from our list */
+    xmlListWalk(ref_list, xmlWalkRemoveRef, &target);
+
+    /*If the list is empty then remove the list entry in the hash */
+    if (xmlListEmpty(ref_list))
+        xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator)
+        xmlFreeRefList);
+    xmlFree(ID);
+    return(0);
+}
+
+/**
+ * xmlGetRefs:
+ * @doc:  pointer to the document
+ * @ID:  the ID value
+ *
+ * Find the set of references for the supplied ID. 
+ *
+ * Returns NULL if not found, otherwise node set for the ID.
+ */
+xmlListPtr 
+xmlGetRefs(xmlDocPtr doc, const xmlChar *ID) {
+    xmlRefTablePtr table;
+
+    if (doc == NULL) {
+        return(NULL);
+    }
+
+    if (ID == NULL) {
+        return(NULL);
+    }
+
+    table = (xmlRefTablePtr) doc->refs;
+    if (table == NULL) 
+        return(NULL);
+
+    return (xmlHashLookup(table, ID));
+}
+
+/************************************************************************
+ *									*
+ *		Routines for validity checking				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlGetDtdElementDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @name:  the element name
+ *
+ * Search the DTD for the description of this element
+ *
+ * returns the xmlElementPtr if found or NULL
+ */
+
+xmlElementPtr
+xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
+    xmlElementTablePtr table;
+    xmlElementPtr cur;
+    xmlChar *uqname = NULL, *prefix = NULL;
+
+    if ((dtd == NULL) || (name == NULL)) return(NULL);
+    if (dtd->elements == NULL)
+	return(NULL);
+    table = (xmlElementTablePtr) dtd->elements;
+
+    uqname = xmlSplitQName2(name, &prefix);
+    if (uqname != NULL)
+        name = uqname;
+    cur = xmlHashLookup2(table, name, prefix);
+    if (prefix != NULL) xmlFree(prefix);
+    if (uqname != NULL) xmlFree(uqname);
+    return(cur);
+}
+/**
+ * xmlGetDtdElementDesc2:
+ * @dtd:  a pointer to the DtD to search
+ * @name:  the element name
+ * @create:  create an empty description if not found
+ *
+ * Search the DTD for the description of this element
+ *
+ * returns the xmlElementPtr if found or NULL
+ */
+
+static xmlElementPtr
+xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
+    xmlElementTablePtr table;
+    xmlElementPtr cur;
+    xmlChar *uqname = NULL, *prefix = NULL;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->elements == NULL) {
+	xmlDictPtr dict = NULL;
+
+	if (dtd->doc != NULL)
+	    dict = dtd->doc->dict;
+
+	if (!create) 
+	    return(NULL);
+	/*
+	 * Create the Element table if needed.
+	 */
+	table = (xmlElementTablePtr) dtd->elements;
+	if (table == NULL) {
+	    table = xmlHashCreateDict(0, dict);
+	    dtd->elements = (void *) table;
+	}
+	if (table == NULL) {
+	    xmlVErrMemory(NULL, "element table allocation failed");
+	    return(NULL);
+	}
+    }
+    table = (xmlElementTablePtr) dtd->elements;
+
+    uqname = xmlSplitQName2(name, &prefix);
+    if (uqname != NULL)
+        name = uqname;
+    cur = xmlHashLookup2(table, name, prefix);
+    if ((cur == NULL) && (create)) {
+	cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
+	if (cur == NULL) {
+	    xmlVErrMemory(NULL, "malloc failed");
+	    return(NULL);
+	}
+	memset(cur, 0, sizeof(xmlElement));
+	cur->type = XML_ELEMENT_DECL;
+
+	/*
+	 * fill the structure.
+	 */
+	cur->name = xmlStrdup(name);
+	cur->prefix = xmlStrdup(prefix);
+	cur->etype = XML_ELEMENT_TYPE_UNDEFINED;
+
+	xmlHashAddEntry2(table, name, prefix, cur);
+    }
+    if (prefix != NULL) xmlFree(prefix);
+    if (uqname != NULL) xmlFree(uqname);
+    return(cur);
+}
+
+/**
+ * xmlGetDtdQElementDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @name:  the element name
+ * @prefix:  the element namespace prefix
+ *
+ * Search the DTD for the description of this element
+ *
+ * returns the xmlElementPtr if found or NULL
+ */
+
+xmlElementPtr
+xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
+	              const xmlChar *prefix) {
+    xmlElementTablePtr table;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->elements == NULL) return(NULL);
+    table = (xmlElementTablePtr) dtd->elements;
+
+    return(xmlHashLookup2(table, name, prefix));
+}
+
+/**
+ * xmlGetDtdAttrDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @elem:  the element name
+ * @name:  the attribute name
+ *
+ * Search the DTD for the description of this attribute on
+ * this element.
+ *
+ * returns the xmlAttributePtr if found or NULL
+ */
+
+xmlAttributePtr
+xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
+    xmlAttributeTablePtr table;
+    xmlAttributePtr cur;
+    xmlChar *uqname = NULL, *prefix = NULL;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->attributes == NULL) return(NULL);
+
+    table = (xmlAttributeTablePtr) dtd->attributes;
+    if (table == NULL)
+	return(NULL);
+
+    uqname = xmlSplitQName2(name, &prefix);
+
+    if (uqname != NULL) {
+	cur = xmlHashLookup3(table, uqname, prefix, elem);
+	if (prefix != NULL) xmlFree(prefix);
+	if (uqname != NULL) xmlFree(uqname);
+    } else
+	cur = xmlHashLookup3(table, name, NULL, elem);
+    return(cur);
+}
+
+/**
+ * xmlGetDtdQAttrDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @elem:  the element name
+ * @name:  the attribute name
+ * @prefix:  the attribute namespace prefix
+ *
+ * Search the DTD for the description of this qualified attribute on
+ * this element.
+ *
+ * returns the xmlAttributePtr if found or NULL
+ */
+
+xmlAttributePtr
+xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
+	          const xmlChar *prefix) {
+    xmlAttributeTablePtr table;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->attributes == NULL) return(NULL);
+    table = (xmlAttributeTablePtr) dtd->attributes;
+
+    return(xmlHashLookup3(table, name, prefix, elem));
+}
+
+/**
+ * xmlGetDtdNotationDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @name:  the notation name
+ *
+ * Search the DTD for the description of this notation
+ *
+ * returns the xmlNotationPtr if found or NULL
+ */
+
+xmlNotationPtr
+xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
+    xmlNotationTablePtr table;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->notations == NULL) return(NULL);
+    table = (xmlNotationTablePtr) dtd->notations;
+
+    return(xmlHashLookup(table, name));
+}
+
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+/**
+ * xmlValidateNotationUse:
+ * @ctxt:  the validation context
+ * @doc:  the document
+ * @notationName:  the notation name to check
+ *
+ * Validate that the given name match a notation declaration.
+ * - [ VC: Notation Declared ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                       const xmlChar *notationName) {
+    xmlNotationPtr notaDecl;
+    if ((doc == NULL) || (doc->intSubset == NULL) ||
+        (notationName == NULL)) return(-1);
+
+    notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
+    if ((notaDecl == NULL) && (doc->extSubset != NULL))
+	notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName);
+
+    if ((notaDecl == NULL) && (ctxt != NULL)) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) doc, XML_DTD_UNKNOWN_NOTATION,
+	                "NOTATION %s is not declared\n",
+		        notationName, NULL, NULL);
+	return(0);
+    }
+    return(1);
+}
+#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */
+
+/**
+ * xmlIsMixedElement:
+ * @doc:  the document
+ * @name:  the element name
+ *
+ * Search in the DtDs whether an element accept Mixed content (or ANY)
+ * basically if it is supposed to accept text childs
+ *
+ * returns 0 if no, 1 if yes, and -1 if no element description is available
+ */
+
+int
+xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
+    xmlElementPtr elemDecl;
+
+    if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
+
+    elemDecl = xmlGetDtdElementDesc(doc->intSubset, name);
+    if ((elemDecl == NULL) && (doc->extSubset != NULL))
+	elemDecl = xmlGetDtdElementDesc(doc->extSubset, name);
+    if (elemDecl == NULL) return(-1);
+    switch (elemDecl->etype) {
+	case XML_ELEMENT_TYPE_UNDEFINED:
+	    return(-1);
+	case XML_ELEMENT_TYPE_ELEMENT:
+	    return(0);
+        case XML_ELEMENT_TYPE_EMPTY:
+	    /*
+	     * return 1 for EMPTY since we want VC error to pop up
+	     * on <empty>     </empty> for example
+	     */
+	case XML_ELEMENT_TYPE_ANY:
+	case XML_ELEMENT_TYPE_MIXED:
+	    return(1);
+    }
+    return(1);
+}
+
+#ifdef LIBXML_VALID_ENABLED
+
+static int
+xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
+    if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+        /*
+	 * Use the new checks of production [4] [4a] amd [5] of the
+	 * Update 5 of XML-1.0
+	 */
+	if (((c >= 'a') && (c <= 'z')) ||
+	    ((c >= 'A') && (c <= 'Z')) ||
+	    (c == '_') || (c == ':') ||
+	    ((c >= 0xC0) && (c <= 0xD6)) ||
+	    ((c >= 0xD8) && (c <= 0xF6)) ||
+	    ((c >= 0xF8) && (c <= 0x2FF)) ||
+	    ((c >= 0x370) && (c <= 0x37D)) ||
+	    ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	    ((c >= 0x200C) && (c <= 0x200D)) ||
+	    ((c >= 0x2070) && (c <= 0x218F)) ||
+	    ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	    ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	    ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	    ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	    ((c >= 0x10000) && (c <= 0xEFFFF)))
+	    return(1);
+    } else {
+        if (IS_LETTER(c) || (c == '_') || (c == ':'))
+	    return(1);
+    }
+    return(0);
+}
+
+static int
+xmlIsDocNameChar(xmlDocPtr doc, int c) {
+    if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+        /*
+	 * Use the new checks of production [4] [4a] amd [5] of the
+	 * Update 5 of XML-1.0
+	 */
+	if (((c >= 'a') && (c <= 'z')) ||
+	    ((c >= 'A') && (c <= 'Z')) ||
+	    ((c >= '0') && (c <= '9')) || /* !start */
+	    (c == '_') || (c == ':') ||
+	    (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
+	    ((c >= 0xC0) && (c <= 0xD6)) ||
+	    ((c >= 0xD8) && (c <= 0xF6)) ||
+	    ((c >= 0xF8) && (c <= 0x2FF)) ||
+	    ((c >= 0x300) && (c <= 0x36F)) || /* !start */
+	    ((c >= 0x370) && (c <= 0x37D)) ||
+	    ((c >= 0x37F) && (c <= 0x1FFF)) ||
+	    ((c >= 0x200C) && (c <= 0x200D)) ||
+	    ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
+	    ((c >= 0x2070) && (c <= 0x218F)) ||
+	    ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+	    ((c >= 0x3001) && (c <= 0xD7FF)) ||
+	    ((c >= 0xF900) && (c <= 0xFDCF)) ||
+	    ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+	    ((c >= 0x10000) && (c <= 0xEFFFF)))
+	     return(1);
+    } else {
+        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || (c == ':') ||
+	    (IS_COMBINING(c)) ||
+	    (IS_EXTENDER(c)))
+	    return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlValidateNameValue:
+ * @doc:  pointer to the document or NULL
+ * @value:  an Name value
+ *
+ * Validate that the given value match Name production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateNameValueInternal(xmlDocPtr doc, const xmlChar *value) {
+    const xmlChar *cur;
+    int val, len;
+
+    if (value == NULL) return(0);
+    cur = value;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+    if (!xmlIsDocNameStartChar(doc, val))
+	return(0);
+
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+    while (xmlIsDocNameChar(doc, val)) {
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+    }
+
+    if (val != 0) return(0);
+
+    return(1);
+}
+
+/**
+ * xmlValidateNameValue:
+ * @value:  an Name value
+ *
+ * Validate that the given value match Name production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNameValue(const xmlChar *value) {
+    return(xmlValidateNameValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNamesValueInternal:
+ * @doc:  pointer to the document or NULL
+ * @value:  an Names value
+ *
+ * Validate that the given value match Names production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateNamesValueInternal(xmlDocPtr doc, const xmlChar *value) {
+    const xmlChar *cur;
+    int val, len;
+
+    if (value == NULL) return(0);
+    cur = value;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+
+    if (!xmlIsDocNameStartChar(doc, val))
+	return(0);
+
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+    while (xmlIsDocNameChar(doc, val)) {
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+    }
+
+    /* Should not test IS_BLANK(val) here -- see erratum E20*/
+    while (val == 0x20) {
+	while (val == 0x20) {
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	    cur += len;
+	}
+
+	if (!xmlIsDocNameStartChar(doc, val))
+	    return(0);
+
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+
+	while (xmlIsDocNameChar(doc, val)) {
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	    cur += len;
+	}
+    }
+
+    if (val != 0) return(0);
+
+    return(1);
+}
+
+/**
+ * xmlValidateNamesValue:
+ * @value:  an Names value
+ *
+ * Validate that the given value match Names production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNamesValue(const xmlChar *value) {
+    return(xmlValidateNamesValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNmtokenValueInternal:
+ * @doc:  pointer to the document or NULL
+ * @value:  an Nmtoken value
+ *
+ * Validate that the given value match Nmtoken production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateNmtokenValueInternal(xmlDocPtr doc, const xmlChar *value) {
+    const xmlChar *cur;
+    int val, len;
+
+    if (value == NULL) return(0);
+    cur = value;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+
+    if (!xmlIsDocNameChar(doc, val))
+	return(0);
+
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+    while (xmlIsDocNameChar(doc, val)) {
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+    }
+
+    if (val != 0) return(0);
+
+    return(1);
+}
+
+/**
+ * xmlValidateNmtokenValue:
+ * @value:  an Nmtoken value
+ *
+ * Validate that the given value match Nmtoken production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNmtokenValue(const xmlChar *value) {
+    return(xmlValidateNmtokenValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNmtokensValueInternal:
+ * @doc:  pointer to the document or NULL
+ * @value:  an Nmtokens value
+ *
+ * Validate that the given value match Nmtokens production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateNmtokensValueInternal(xmlDocPtr doc, const xmlChar *value) {
+    const xmlChar *cur;
+    int val, len;
+
+    if (value == NULL) return(0);
+    cur = value;
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+
+    while (IS_BLANK(val)) {
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+    }
+
+    if (!xmlIsDocNameChar(doc, val))
+	return(0);
+
+    while (xmlIsDocNameChar(doc, val)) {
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+    }
+
+    /* Should not test IS_BLANK(val) here -- see erratum E20*/
+    while (val == 0x20) {
+	while (val == 0x20) {
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	    cur += len;
+	}
+	if (val == 0) return(1);
+
+	if (!xmlIsDocNameChar(doc, val))
+	    return(0);
+
+	val = xmlStringCurrentChar(NULL, cur, &len);
+	cur += len;
+
+	while (xmlIsDocNameChar(doc, val)) {
+	    val = xmlStringCurrentChar(NULL, cur, &len);
+	    cur += len;
+	}
+    }
+
+    if (val != 0) return(0);
+
+    return(1);
+}
+
+/**
+ * xmlValidateNmtokensValue:
+ * @value:  an Nmtokens value
+ *
+ * Validate that the given value match Nmtokens production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNmtokensValue(const xmlChar *value) {
+    return(xmlValidateNmtokensValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNotationDecl:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @nota:  a notation definition
+ *
+ * Try to validate a single notation definition
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - it seems that no validity constraint exists on notation declarations
+ * But this function get called anyway ...
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATTRIBUTE_UNUSED,
+                         xmlNotationPtr nota ATTRIBUTE_UNUSED) {
+    int ret = 1;
+
+    return(ret);
+}
+
+/**
+ * xmlValidateAttributeValueInternal:
+ * @doc: the document
+ * @type:  an attribute type
+ * @value:  an attribute value
+ *
+ * Validate that the given attribute value match  the proper production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
+                                  const xmlChar *value) {
+    switch (type) {
+	case XML_ATTRIBUTE_ENTITIES:
+	case XML_ATTRIBUTE_IDREFS:
+	    return(xmlValidateNamesValueInternal(doc, value));
+	case XML_ATTRIBUTE_ENTITY:
+	case XML_ATTRIBUTE_IDREF:
+	case XML_ATTRIBUTE_ID:
+	case XML_ATTRIBUTE_NOTATION:
+	    return(xmlValidateNameValueInternal(doc, value));
+	case XML_ATTRIBUTE_NMTOKENS:
+	case XML_ATTRIBUTE_ENUMERATION:
+	    return(xmlValidateNmtokensValueInternal(doc, value));
+	case XML_ATTRIBUTE_NMTOKEN:
+	    return(xmlValidateNmtokenValueInternal(doc, value));
+        case XML_ATTRIBUTE_CDATA:
+	    break;
+    }
+    return(1);
+}
+
+/**
+ * xmlValidateAttributeValue:
+ * @type:  an attribute type
+ * @value:  an attribute value
+ *
+ * Validate that the given attribute value match  the proper production
+ *
+ * [ VC: ID ]
+ * Values of type ID must match the Name production....
+ *
+ * [ VC: IDREF ]
+ * Values of type IDREF must match the Name production, and values
+ * of type IDREFS must match Names ...
+ *
+ * [ VC: Entity Name ]
+ * Values of type ENTITY must match the Name production, values
+ * of type ENTITIES must match Names ...
+ *
+ * [ VC: Name Token ]
+ * Values of type NMTOKEN must match the Nmtoken production; values
+ * of type NMTOKENS must match Nmtokens. 
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+int
+xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) {
+    return(xmlValidateAttributeValueInternal(NULL, type, value));
+}
+
+/**
+ * xmlValidateAttributeValue2:
+ * @ctxt:  the validation context
+ * @doc:  the document
+ * @name:  the attribute name (used for error reporting only)
+ * @type:  the attribute type
+ * @value:  the attribute value
+ *
+ * Validate that the given attribute value match a given type.
+ * This typically cannot be done before having finished parsing
+ * the subsets.
+ *
+ * [ VC: IDREF ]
+ * Values of type IDREF must match one of the declared IDs
+ * Values of type IDREFS must match a sequence of the declared IDs
+ * each Name must match the value of an ID attribute on some element
+ * in the XML document; i.e. IDREF values must match the value of
+ * some ID attribute
+ *
+ * [ VC: Entity Name ]
+ * Values of type ENTITY must match one declared entity
+ * Values of type ENTITIES must match a sequence of declared entities
+ *
+ * [ VC: Notation Attributes ]
+ * all notation names in the declaration must be declared.
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+      const xmlChar *name, xmlAttributeType type, const xmlChar *value) {
+    int ret = 1;
+    switch (type) {
+	case XML_ATTRIBUTE_IDREFS:
+	case XML_ATTRIBUTE_IDREF:
+	case XML_ATTRIBUTE_ID:
+	case XML_ATTRIBUTE_NMTOKENS:
+	case XML_ATTRIBUTE_ENUMERATION:
+	case XML_ATTRIBUTE_NMTOKEN:
+        case XML_ATTRIBUTE_CDATA:
+	    break;
+	case XML_ATTRIBUTE_ENTITY: {
+	    xmlEntityPtr ent;
+
+	    ent = xmlGetDocEntity(doc, value);
+	    /* yeah it's a bit messy... */
+	    if ((ent == NULL) && (doc->standalone == 1)) {
+		doc->standalone = 0;
+		ent = xmlGetDocEntity(doc, value);
+	    } 
+	    if (ent == NULL) {
+		xmlErrValidNode(ctxt, (xmlNodePtr) doc,
+				XML_DTD_UNKNOWN_ENTITY,
+   "ENTITY attribute %s reference an unknown entity \"%s\"\n",
+		       name, value, NULL);
+		ret = 0;
+	    } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+		xmlErrValidNode(ctxt, (xmlNodePtr) doc,
+				XML_DTD_ENTITY_TYPE,
+   "ENTITY attribute %s reference an entity \"%s\" of wrong type\n",
+		       name, value, NULL);
+		ret = 0;
+	    }
+	    break;
+        }
+	case XML_ATTRIBUTE_ENTITIES: {
+	    xmlChar *dup, *nam = NULL, *cur, save;
+	    xmlEntityPtr ent;
+
+	    dup = xmlStrdup(value);
+	    if (dup == NULL)
+		return(0);
+	    cur = dup;
+	    while (*cur != 0) {
+		nam = cur;
+		while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
+		save = *cur;
+		*cur = 0;
+		ent = xmlGetDocEntity(doc, nam);
+		if (ent == NULL) {
+		    xmlErrValidNode(ctxt, (xmlNodePtr) doc,
+				    XML_DTD_UNKNOWN_ENTITY,
+       "ENTITIES attribute %s reference an unknown entity \"%s\"\n",
+			   name, nam, NULL);
+		    ret = 0;
+		} else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+		    xmlErrValidNode(ctxt, (xmlNodePtr) doc,
+				    XML_DTD_ENTITY_TYPE,
+       "ENTITIES attribute %s reference an entity \"%s\" of wrong type\n",
+			   name, nam, NULL);
+		    ret = 0;
+		}
+		if (save == 0)
+		    break;
+		*cur = save;
+		while (IS_BLANK_CH(*cur)) cur++;
+	    }
+	    xmlFree(dup);
+	    break;
+	}
+	case XML_ATTRIBUTE_NOTATION: {
+	    xmlNotationPtr nota;
+
+	    nota = xmlGetDtdNotationDesc(doc->intSubset, value);
+	    if ((nota == NULL) && (doc->extSubset != NULL))
+		nota = xmlGetDtdNotationDesc(doc->extSubset, value);
+
+	    if (nota == NULL) {
+		xmlErrValidNode(ctxt, (xmlNodePtr) doc,
+		                XML_DTD_UNKNOWN_NOTATION,
+       "NOTATION attribute %s reference an unknown notation \"%s\"\n",
+		       name, value, NULL);
+		ret = 0;
+	    }
+	    break;
+        }
+    }
+    return(ret);
+}
+
+/**
+ * xmlValidCtxtNormalizeAttributeValue:
+ * @ctxt: the validation context
+ * @doc:  the document
+ * @elem:  the parent
+ * @name:  the attribute name
+ * @value:  the attribute value
+ * @ctxt:  the validation context or NULL
+ *
+ * Does the validation related extra step of the normalization of attribute
+ * values:
+ *
+ * If the declared value is not CDATA, then the XML processor must further
+ * process the normalized attribute value by discarding any leading and
+ * trailing space (#x20) characters, and by replacing sequences of space
+ * (#x20) characters by single space (#x20) character.
+ *
+ * Also  check VC: Standalone Document Declaration in P32, and update
+ *  ctxt->valid accordingly
+ *
+ * returns a new normalized string if normalization is needed, NULL otherwise
+ *      the caller must free the returned value.
+ */
+
+xmlChar *
+xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+	     xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
+    xmlChar *ret, *dst;
+    const xmlChar *src;
+    xmlAttributePtr attrDecl = NULL;
+    int extsubset = 0;
+
+    if (doc == NULL) return(NULL);
+    if (elem == NULL) return(NULL);
+    if (name == NULL) return(NULL);
+    if (value == NULL) return(NULL);
+
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+	xmlChar 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 (attrDecl != NULL)
+		extsubset = 1;
+	}
+	if ((fullname != fn) && (fullname != elem->name))
+	    xmlFree(fullname);
+    }
+    if ((attrDecl == NULL) && (doc->intSubset != NULL))
+	attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
+    if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
+	attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
+	if (attrDecl != NULL)
+	    extsubset = 1;
+    }
+
+    if (attrDecl == NULL)
+	return(NULL);
+    if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
+	return(NULL);
+
+    ret = xmlStrdup(value);
+    if (ret == NULL)
+	return(NULL);
+    src = value;
+    dst = ret;
+    while (*src == 0x20) src++;
+    while (*src != 0) {
+	if (*src == 0x20) {
+	    while (*src == 0x20) src++;
+	    if (*src != 0)
+		*dst++ = 0x20;
+	} else {
+	    *dst++ = *src++;
+	}
+    }
+    *dst = 0;
+    if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
+	xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
+"standalone: %s on %s value had to be normalized based on external subset declaration\n",
+	       name, elem->name, NULL);
+	ctxt->valid = 0;
+    }
+    return(ret);
+}
+
+/**
+ * xmlValidNormalizeAttributeValue:
+ * @doc:  the document
+ * @elem:  the parent
+ * @name:  the attribute name
+ * @value:  the attribute value
+ *
+ * Does the validation related extra step of the normalization of attribute
+ * values:
+ *
+ * If the declared value is not CDATA, then the XML processor must further
+ * process the normalized attribute value by discarding any leading and
+ * trailing space (#x20) characters, and by replacing sequences of space
+ * (#x20) characters by single space (#x20) character.
+ *
+ * Returns a new normalized string if normalization is needed, NULL otherwise
+ *      the caller must free the returned value.
+ */
+
+xmlChar *
+xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
+			        const xmlChar *name, const xmlChar *value) {
+    xmlChar *ret, *dst;
+    const xmlChar *src;
+    xmlAttributePtr attrDecl = NULL;
+
+    if (doc == NULL) return(NULL);
+    if (elem == NULL) return(NULL);
+    if (name == NULL) return(NULL);
+    if (value == NULL) return(NULL);
+
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+	xmlChar fn[50];
+	xmlChar *fullname;
+
+	fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
+	if (fullname == NULL)
+	    return(NULL);
+	if ((fullname != fn) && (fullname != elem->name))
+	    xmlFree(fullname);
+    }
+    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
+    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+	attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
+
+    if (attrDecl == NULL)
+	return(NULL);
+    if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
+	return(NULL);
+
+    ret = xmlStrdup(value);
+    if (ret == NULL)
+	return(NULL);
+    src = value;
+    dst = ret;
+    while (*src == 0x20) src++;
+    while (*src != 0) {
+	if (*src == 0x20) {
+	    while (*src == 0x20) src++;
+	    if (*src != 0)
+		*dst++ = 0x20;
+	} else {
+	    *dst++ = *src++;
+	}
+    }
+    *dst = 0;
+    return(ret);
+}
+
+static void
+xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
+	                       const xmlChar* name ATTRIBUTE_UNUSED) {
+    if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
+}
+
+/**
+ * xmlValidateAttributeDecl:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @attr:  an attribute definition
+ *
+ * Try to validate a single attribute definition
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: Attribute Default Legal ]
+ *  - [ VC: Enumeration ]
+ *  - [ VC: ID Attribute Default ]
+ *
+ * The ID/IDREF uniqueness and matching are done separately
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                         xmlAttributePtr attr) {
+    int ret = 1;
+    int val;
+    CHECK_DTD;
+    if(attr == NULL) return(1);
+
+    /* Attribute Default Legal */
+    /* Enumeration */
+    if (attr->defaultValue != NULL) {
+	val = xmlValidateAttributeValueInternal(doc, attr->atype,
+	                                        attr->defaultValue);
+	if (val == 0) {
+	    xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT,
+	       "Syntax of default value for attribute %s of %s is not valid\n",
+	           attr->name, attr->elem, NULL);
+	}
+        ret &= val;
+    }
+
+    /* ID Attribute Default */
+    if ((attr->atype == XML_ATTRIBUTE_ID)&&
+        (attr->def != XML_ATTRIBUTE_IMPLIED) &&
+	(attr->def != XML_ATTRIBUTE_REQUIRED)) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ID_FIXED,
+          "ID attribute %s of %s is not valid must be #IMPLIED or #REQUIRED\n",
+	       attr->name, attr->elem, NULL);
+	ret = 0;
+    }
+
+    /* One ID per Element Type */
+    if (attr->atype == XML_ATTRIBUTE_ID) {
+        int nbId;
+
+	/* the trick is that we parse DtD as their own internal subset */
+        xmlElementPtr elem = xmlGetDtdElementDesc(doc->intSubset,
+	                                          attr->elem);
+	if (elem != NULL) {
+	    nbId = xmlScanIDAttributeDecl(NULL, elem, 0);
+	} else {
+	    xmlAttributeTablePtr table;
+
+	    /*
+	     * The attribute may be declared in the internal subset and the
+	     * element in the external subset.
+	     */
+	    nbId = 0;
+	    if (doc->intSubset != NULL) {
+		table = (xmlAttributeTablePtr) doc->intSubset->attributes;
+		xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner)
+			     xmlValidateAttributeIdCallback, &nbId);
+	    }
+	}
+	if (nbId > 1) {
+	    
+	    xmlErrValidNodeNr(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
+       "Element %s has %d ID attribute defined in the internal subset : %s\n",
+		   attr->elem, nbId, attr->name);
+	} else if (doc->extSubset != NULL) {
+	    int extId = 0;
+	    elem = xmlGetDtdElementDesc(doc->extSubset, attr->elem);
+	    if (elem != NULL) {
+		extId = xmlScanIDAttributeDecl(NULL, elem, 0);
+	    }
+	    if (extId > 1) {
+		xmlErrValidNodeNr(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
+       "Element %s has %d ID attribute defined in the external subset : %s\n",
+		       attr->elem, extId, attr->name);
+	    } else if (extId + nbId > 1) {
+		xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
+"Element %s has ID attributes defined in the internal and external subset : %s\n",
+		       attr->elem, attr->name, NULL);
+	    }
+	}
+    }
+
+    /* Validity Constraint: Enumeration */
+    if ((attr->defaultValue != NULL) && (attr->tree != NULL)) {
+        xmlEnumerationPtr tree = attr->tree;
+	while (tree != NULL) {
+	    if (xmlStrEqual(tree->name, attr->defaultValue)) break;
+	    tree = tree->next;
+	}
+	if (tree == NULL) {
+	    xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_VALUE,
+"Default value \"%s\" for attribute %s of %s is not among the enumerated set\n",
+		   attr->defaultValue, attr->name, attr->elem);
+	    ret = 0;
+	}
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlValidateElementDecl:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element definition
+ *
+ * Try to validate a single element definition
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: One ID per Element Type ]
+ *  - [ VC: No Duplicate Types ]
+ *  - [ VC: Unique Element Type Declaration ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                       xmlElementPtr elem) {
+    int ret = 1;
+    xmlElementPtr tst;
+
+    CHECK_DTD;
+    
+    if (elem == NULL) return(1);
+
+#if 0
+#ifdef LIBXML_REGEXP_ENABLED
+    /* Build the regexp associated to the content model */
+    ret = xmlValidBuildContentModel(ctxt, elem);
+#endif
+#endif
+
+    /* No Duplicate Types */
+    if (elem->etype == XML_ELEMENT_TYPE_MIXED) {
+	xmlElementContentPtr cur, next;
+        const xmlChar *name;
+
+	cur = elem->content;
+	while (cur != NULL) {
+	    if (cur->type != XML_ELEMENT_CONTENT_OR) break;
+	    if (cur->c1 == NULL) break;
+	    if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
+		name = cur->c1->name;
+		next = cur->c2;
+		while (next != NULL) {
+		    if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
+		        if ((xmlStrEqual(next->name, name)) &&
+			    (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->c1->prefix, name);
+			    }
+			    ret = 0;
+			}
+			break;
+		    }
+		    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->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->c1->prefix, name);
+			}
+			ret = 0;
+		    }
+		    next = next->c2;
+		}
+	    }
+	    cur = cur->c2;
+	}
+    }
+
+    /* VC: Unique Element Type Declaration */
+    tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
+    if ((tst != NULL ) && (tst != elem) &&
+	((tst->prefix == elem->prefix) ||
+	 (xmlStrEqual(tst->prefix, elem->prefix))) &&
+	(tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
+	                "Redefinition of element %s\n",
+		       elem->name, NULL, NULL);
+	ret = 0;
+    }
+    tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
+    if ((tst != NULL ) && (tst != elem) &&
+	((tst->prefix == elem->prefix) ||
+	 (xmlStrEqual(tst->prefix, elem->prefix))) &&
+	(tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
+	xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_ELEM_REDEFINED,
+	                "Redefinition of element %s\n",
+		       elem->name, NULL, NULL);
+	ret = 0;
+    }
+    /* One ID per Element Type
+     * already done when registering the attribute
+    if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
+	ret = 0;
+    } */
+    return(ret);
+}
+
+/**
+ * xmlValidateOneAttribute:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ * @attr:  an attribute instance
+ * @value:  the attribute value (without entities processing)
+ *
+ * Try to validate a single attribute for an element
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: Attribute Value Type ]
+ *  - [ VC: Fixed Attribute Default ]
+ *  - [ VC: Entity Name ]
+ *  - [ VC: Name Token ]
+ *  - [ VC: ID ]
+ *  - [ VC: IDREF ]
+ *  - [ VC: Entity Name ]
+ *  - [ VC: Notation Attributes ]
+ *
+ * The ID/IDREF uniqueness and matching are done separately
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                        xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) 
+{
+    xmlAttributePtr attrDecl =  NULL;
+    int val;
+    int ret = 1;
+
+    CHECK_DTD;
+    if ((elem == NULL) || (elem->name == NULL)) return(0);
+    if ((attr == NULL) || (attr->name == NULL)) return(0);
+
+    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(0);
+	if (attr->ns != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
+		                          attr->name, attr->ns->prefix);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
+					      attr->name, attr->ns->prefix);
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, attr->name);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+					     fullname, attr->name);
+	}
+	if ((fullname != fn) && (fullname != elem->name))
+	    xmlFree(fullname);
+    }
+    if (attrDecl == NULL) {
+	if (attr->ns != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
+		                          attr->name, attr->ns->prefix);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
+					      attr->name, attr->ns->prefix);
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
+		                         elem->name, attr->name);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+					     elem->name, attr->name);
+	}
+    }
+
+
+    /* Validity Constraint: Attribute Value Type */
+    if (attrDecl == NULL) {
+	xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE,
+	       "No declaration for attribute %s of element %s\n",
+	       attr->name, elem->name, NULL);
+	return(0);
+    }
+    attr->atype = attrDecl->atype;
+
+    val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
+    if (val == 0) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
+	   "Syntax of value for attribute %s of %s is not valid\n",
+	       attr->name, elem->name, NULL);
+        ret = 0;
+    }
+
+    /* Validity constraint: Fixed Attribute Default */
+    if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
+	if (!xmlStrEqual(value, attrDecl->defaultValue)) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_DEFAULT,
+	   "Value for attribute %s of %s is different from default \"%s\"\n",
+		   attr->name, elem->name, attrDecl->defaultValue);
+	    ret = 0;
+	}
+    }
+
+    /* Validity Constraint: ID uniqueness */
+    if (attrDecl->atype == XML_ATTRIBUTE_ID) {
+        if (xmlAddID(ctxt, doc, value, attr) == NULL)
+	    ret = 0;
+    }
+
+    if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
+	(attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
+        if (xmlAddRef(ctxt, doc, value, attr) == NULL)
+	    ret = 0;
+    }
+
+    /* Validity Constraint: Notation Attributes */
+    if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
+        xmlEnumerationPtr tree = attrDecl->tree;
+        xmlNotationPtr nota;
+
+        /* First check that the given NOTATION was declared */
+	nota = xmlGetDtdNotationDesc(doc->intSubset, value);
+	if (nota == NULL)
+	    nota = xmlGetDtdNotationDesc(doc->extSubset, value);
+	
+	if (nota == NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_NOTATION,
+       "Value \"%s\" for attribute %s of %s is not a declared Notation\n",
+		   value, attr->name, elem->name);
+	    ret = 0;
+        }
+
+	/* Second, verify that it's among the list */
+	while (tree != NULL) {
+	    if (xmlStrEqual(tree->name, value)) break;
+	    tree = tree->next;
+	}
+	if (tree == NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_NOTATION_VALUE,
+"Value \"%s\" for attribute %s of %s is not among the enumerated notations\n",
+		   value, attr->name, elem->name);
+	    ret = 0;
+	}
+    }
+
+    /* Validity Constraint: Enumeration */
+    if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
+        xmlEnumerationPtr tree = attrDecl->tree;
+	while (tree != NULL) {
+	    if (xmlStrEqual(tree->name, value)) break;
+	    tree = tree->next;
+	}
+	if (tree == NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
+       "Value \"%s\" for attribute %s of %s is not among the enumerated set\n",
+		   value, attr->name, elem->name);
+	    ret = 0;
+	}
+    }
+
+    /* Fixed Attribute Default */
+    if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
+        (!xmlStrEqual(attrDecl->defaultValue, value))) {
+	xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
+	   "Value for attribute %s of %s must be \"%s\"\n",
+	       attr->name, elem->name, attrDecl->defaultValue);
+        ret = 0;
+    }
+
+    /* Extra check for the attribute value */
+    ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
+				      attrDecl->atype, value);
+
+    return(ret);
+}
+
+/**
+ * xmlValidateOneNamespace:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ * @prefix:  the namespace prefix
+ * @ns:  an namespace declaration instance
+ * @value:  the attribute value (without entities processing)
+ *
+ * Try to validate a single namespace declaration for an element
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: Attribute Value Type ]
+ *  - [ VC: Fixed Attribute Default ]
+ *  - [ VC: Entity Name ]
+ *  - [ VC: Name Token ]
+ *  - [ VC: ID ]
+ *  - [ VC: IDREF ]
+ *  - [ VC: Entity Name ]
+ *  - [ VC: Notation Attributes ]
+ *
+ * The ID/IDREF uniqueness and matching are done separately
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateOneNamespace(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
+    /* xmlElementPtr elemDecl; */
+    xmlAttributePtr attrDecl =  NULL;
+    int val;
+    int ret = 1;
+
+    CHECK_DTD;
+    if ((elem == NULL) || (elem->name == NULL)) return(0);
+    if ((ns == NULL) || (ns->href == NULL)) return(0);
+
+    if (prefix != NULL) {
+	xmlChar fn[50];
+	xmlChar *fullname;
+	
+	fullname = xmlBuildQName(elem->name, prefix, fn, 50);
+	if (fullname == NULL) {
+	    xmlVErrMemory(ctxt, "Validating namespace");
+	    return(0);
+	}
+	if (ns->prefix != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
+		                          ns->prefix, BAD_CAST "xmlns");
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
+					  ns->prefix, BAD_CAST "xmlns");
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname,
+		                         BAD_CAST "xmlns");
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname,
+			                 BAD_CAST "xmlns");
+	}
+	if ((fullname != fn) && (fullname != elem->name))
+	    xmlFree(fullname);
+    }
+    if (attrDecl == NULL) {
+	if (ns->prefix != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
+		                          ns->prefix, BAD_CAST "xmlns");
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
+					      ns->prefix, BAD_CAST "xmlns");
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
+		                         elem->name, BAD_CAST "xmlns");
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+					     elem->name, BAD_CAST "xmlns");
+	}
+    }
+
+
+    /* Validity Constraint: Attribute Value Type */
+    if (attrDecl == NULL) {
+	if (ns->prefix != NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE,
+		   "No declaration for attribute xmlns:%s of element %s\n",
+		   ns->prefix, elem->name, NULL);
+	} else {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE,
+		   "No declaration for attribute xmlns of element %s\n",
+		   elem->name, NULL, NULL);
+	}
+	return(0);
+    }
+
+    val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
+    if (val == 0) {
+	if (ns->prefix != NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT,
+	       "Syntax of value for attribute xmlns:%s of %s is not valid\n",
+		   ns->prefix, elem->name, NULL);
+	} else {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT,
+	       "Syntax of value for attribute xmlns of %s is not valid\n",
+		   elem->name, NULL, NULL);
+	}
+        ret = 0;
+    }
+
+    /* Validity constraint: Fixed Attribute Default */
+    if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
+	if (!xmlStrEqual(value, attrDecl->defaultValue)) {
+	    if (ns->prefix != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_DEFAULT,
+       "Value for attribute xmlns:%s of %s is different from default \"%s\"\n",
+		       ns->prefix, elem->name, attrDecl->defaultValue);
+	    } else {
+		xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_DEFAULT,
+       "Value for attribute xmlns of %s is different from default \"%s\"\n",
+		       elem->name, attrDecl->defaultValue, NULL);
+	    }
+	    ret = 0;
+	}
+    }
+
+    /* Validity Constraint: ID uniqueness */
+    if (attrDecl->atype == XML_ATTRIBUTE_ID) {
+        if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
+	    ret = 0;
+    }
+
+    if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
+	(attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
+        if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
+	    ret = 0;
+    }
+
+    /* Validity Constraint: Notation Attributes */
+    if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
+        xmlEnumerationPtr tree = attrDecl->tree;
+        xmlNotationPtr nota;
+
+        /* First check that the given NOTATION was declared */
+	nota = xmlGetDtdNotationDesc(doc->intSubset, value);
+	if (nota == NULL)
+	    nota = xmlGetDtdNotationDesc(doc->extSubset, value);
+	
+	if (nota == NULL) {
+	    if (ns->prefix != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_NOTATION,
+       "Value \"%s\" for attribute xmlns:%s of %s is not a declared Notation\n",
+		       value, ns->prefix, elem->name);
+	    } else {
+		xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_NOTATION,
+       "Value \"%s\" for attribute xmlns of %s is not a declared Notation\n",
+		       value, elem->name, NULL);
+	    }
+	    ret = 0;
+        }
+
+	/* Second, verify that it's among the list */
+	while (tree != NULL) {
+	    if (xmlStrEqual(tree->name, value)) break;
+	    tree = tree->next;
+	}
+	if (tree == NULL) {
+	    if (ns->prefix != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_DTD_NOTATION_VALUE,
+"Value \"%s\" for attribute xmlns:%s of %s is not among the enumerated notations\n",
+		       value, ns->prefix, elem->name);
+	    } else {
+		xmlErrValidNode(ctxt, elem, XML_DTD_NOTATION_VALUE,
+"Value \"%s\" for attribute xmlns of %s is not among the enumerated notations\n",
+		       value, elem->name, NULL);
+	    }
+	    ret = 0;
+	}
+    }
+
+    /* Validity Constraint: Enumeration */
+    if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
+        xmlEnumerationPtr tree = attrDecl->tree;
+	while (tree != NULL) {
+	    if (xmlStrEqual(tree->name, value)) break;
+	    tree = tree->next;
+	}
+	if (tree == NULL) {
+	    if (ns->prefix != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
+"Value \"%s\" for attribute xmlns:%s of %s is not among the enumerated set\n",
+		       value, ns->prefix, elem->name);
+	    } else {
+		xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
+"Value \"%s\" for attribute xmlns of %s is not among the enumerated set\n",
+		       value, elem->name, NULL);
+	    }
+	    ret = 0;
+	}
+    }
+
+    /* Fixed Attribute Default */
+    if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
+        (!xmlStrEqual(attrDecl->defaultValue, value))) {
+	if (ns->prefix != NULL) {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_ELEM_NAMESPACE,
+		   "Value for attribute xmlns:%s of %s must be \"%s\"\n",
+		   ns->prefix, elem->name, attrDecl->defaultValue);
+	} else {
+	    xmlErrValidNode(ctxt, elem, XML_DTD_ELEM_NAMESPACE,
+		   "Value for attribute xmlns of %s must be \"%s\"\n",
+		   elem->name, attrDecl->defaultValue, NULL);
+	}
+        ret = 0;
+    }
+
+    /* Extra check for the attribute value */
+    if (ns->prefix != NULL) {
+	ret &= xmlValidateAttributeValue2(ctxt, doc, ns->prefix,
+					  attrDecl->atype, value);
+    } else {
+	ret &= xmlValidateAttributeValue2(ctxt, doc, BAD_CAST "xmlns",
+					  attrDecl->atype, value);
+    }
+
+    return(ret);
+}
+
+#ifndef  LIBXML_REGEXP_ENABLED
+/**
+ * xmlValidateSkipIgnorable:
+ * @ctxt:  the validation context
+ * @child:  the child list
+ *
+ * Skip ignorable elements w.r.t. the validation process
+ *
+ * returns the first element to consider for validation of the content model
+ */
+
+static xmlNodePtr
+xmlValidateSkipIgnorable(xmlNodePtr child) {
+    while (child != NULL) {
+	switch (child->type) {
+	    /* These things are ignored (skipped) during validation.  */
+	    case XML_PI_NODE:
+	    case XML_COMMENT_NODE:
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		child = child->next;
+		break;
+	    case XML_TEXT_NODE:
+		if (xmlIsBlankNode(child))
+		    child = child->next;
+		else
+		    return(child);
+		break;
+	    /* keep current node */
+	    default:
+		return(child);
+	}
+    }
+    return(child);
+}
+
+/**
+ * xmlValidateElementType:
+ * @ctxt:  the validation context
+ *
+ * Try to validate the content model of an element internal function
+ *
+ * returns 1 if valid or 0 ,-1 in case of error, -2 if an entity
+ *           reference is found and -3 if the validation succeeded but
+ *           the content model is not determinist.
+ */
+
+static int
+xmlValidateElementType(xmlValidCtxtPtr ctxt) {
+    int ret = -1;
+    int determinist = 1;
+
+    NODE = xmlValidateSkipIgnorable(NODE);
+    if ((NODE == NULL) && (CONT == NULL))
+	return(1);
+    if ((NODE == NULL) && 
+	((CONT->ocur == XML_ELEMENT_CONTENT_MULT) ||
+	 (CONT->ocur == XML_ELEMENT_CONTENT_OPT))) {
+	return(1);
+    }
+    if (CONT == NULL) return(-1);
+    if ((NODE != NULL) && (NODE->type == XML_ENTITY_REF_NODE))
+	return(-2);
+
+    /*
+     * We arrive here when more states need to be examined
+     */
+cont:
+
+    /*
+     * We just recovered from a rollback generated by a possible
+     * epsilon transition, go directly to the analysis phase
+     */
+    if (STATE == ROLLBACK_PARENT) {
+	DEBUG_VALID_MSG("restored parent branch");
+	DEBUG_VALID_STATE(NODE, CONT)
+	ret = 1;
+	goto analyze;
+    }
+
+    DEBUG_VALID_STATE(NODE, CONT)
+    /*
+     * we may have to save a backup state here. This is the equivalent
+     * of handling epsilon transition in NFAs.
+     */
+    if ((CONT != NULL) &&
+	((CONT->parent == NULL) ||
+	 (CONT->parent->type != XML_ELEMENT_CONTENT_OR)) &&
+	((CONT->ocur == XML_ELEMENT_CONTENT_MULT) ||
+	 (CONT->ocur == XML_ELEMENT_CONTENT_OPT) ||
+	 ((CONT->ocur == XML_ELEMENT_CONTENT_PLUS) && (OCCURRENCE)))) {
+	DEBUG_VALID_MSG("saving parent branch");
+	if (vstateVPush(ctxt, CONT, NODE, DEPTH, OCCURS, ROLLBACK_PARENT) < 0)
+	    return(0);
+    }
+
+
+    /*
+     * Check first if the content matches
+     */
+    switch (CONT->type) {
+	case XML_ELEMENT_CONTENT_PCDATA:
+	    if (NODE == NULL) {
+		DEBUG_VALID_MSG("pcdata failed no node");
+		ret = 0;
+		break;
+	    }
+	    if (NODE->type == XML_TEXT_NODE) {
+		DEBUG_VALID_MSG("pcdata found, skip to next");
+		/*
+		 * go to next element in the content model
+		 * skipping ignorable elems
+		 */
+		do {
+		    NODE = NODE->next;
+		    NODE = xmlValidateSkipIgnorable(NODE);
+		    if ((NODE != NULL) &&
+			(NODE->type == XML_ENTITY_REF_NODE))
+			return(-2);
+		} while ((NODE != NULL) &&
+			 ((NODE->type != XML_ELEMENT_NODE) &&
+			  (NODE->type != XML_TEXT_NODE) &&
+			  (NODE->type != XML_CDATA_SECTION_NODE)));
+                ret = 1;
+		break;
+	    } else {
+		DEBUG_VALID_MSG("pcdata failed");
+		ret = 0;
+		break;
+	    }
+	    break;
+	case XML_ELEMENT_CONTENT_ELEMENT:
+	    if (NODE == NULL) {
+		DEBUG_VALID_MSG("element failed no node");
+		ret = 0;
+		break;
+	    }
+	    ret = ((NODE->type == XML_ELEMENT_NODE) &&
+		   (xmlStrEqual(NODE->name, CONT->name)));
+	    if (ret == 1) {
+		if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
+		    ret = (CONT->prefix == NULL);
+		} else if (CONT->prefix == NULL) {
+		    ret = 0;
+		} else {
+		    ret = xmlStrEqual(NODE->ns->prefix, CONT->prefix);
+		}
+	    }
+	    if (ret == 1) {
+		DEBUG_VALID_MSG("element found, skip to next");
+		/*
+		 * go to next element in the content model
+		 * skipping ignorable elems
+		 */
+		do {
+		    NODE = NODE->next;
+		    NODE = xmlValidateSkipIgnorable(NODE);
+		    if ((NODE != NULL) &&
+			(NODE->type == XML_ENTITY_REF_NODE))
+			return(-2);
+		} while ((NODE != NULL) &&
+			 ((NODE->type != XML_ELEMENT_NODE) &&
+			  (NODE->type != XML_TEXT_NODE) &&
+			  (NODE->type != XML_CDATA_SECTION_NODE)));
+	    } else {
+		DEBUG_VALID_MSG("element failed");
+		ret = 0;
+		break;
+	    }
+	    break;
+	case XML_ELEMENT_CONTENT_OR:
+	    /*
+	     * Small optimization.
+	     */
+	    if (CONT->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
+		if ((NODE == NULL) ||
+		    (!xmlStrEqual(NODE->name, CONT->c1->name))) {
+		    DEPTH++;
+		    CONT = CONT->c2;
+		    goto cont;
+		}
+		if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
+		    ret = (CONT->c1->prefix == NULL);
+		} else if (CONT->c1->prefix == NULL) {
+		    ret = 0;
+		} else {
+		    ret = xmlStrEqual(NODE->ns->prefix, CONT->c1->prefix);
+		}
+		if (ret == 0) {
+		    DEPTH++;
+		    CONT = CONT->c2;
+		    goto cont;
+		}
+	    }
+
+	    /*
+	     * save the second branch 'or' branch
+	     */
+	    DEBUG_VALID_MSG("saving 'or' branch");
+	    if (vstateVPush(ctxt, CONT->c2, NODE, (unsigned char)(DEPTH + 1),
+			    OCCURS, ROLLBACK_OR) < 0)
+		return(-1);
+	    DEPTH++;
+	    CONT = CONT->c1;
+	    goto cont;
+	case XML_ELEMENT_CONTENT_SEQ:
+	    /*
+	     * Small optimization.
+	     */
+	    if ((CONT->c1->type == XML_ELEMENT_CONTENT_ELEMENT) &&
+		((CONT->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
+		 (CONT->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
+		if ((NODE == NULL) ||
+		    (!xmlStrEqual(NODE->name, CONT->c1->name))) {
+		    DEPTH++;
+		    CONT = CONT->c2;
+		    goto cont;
+		}
+		if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
+		    ret = (CONT->c1->prefix == NULL);
+		} else if (CONT->c1->prefix == NULL) {
+		    ret = 0;
+		} else {
+		    ret = xmlStrEqual(NODE->ns->prefix, CONT->c1->prefix);
+		}
+		if (ret == 0) {
+		    DEPTH++;
+		    CONT = CONT->c2;
+		    goto cont;
+		}
+	    }
+	    DEPTH++;
+	    CONT = CONT->c1;
+	    goto cont;
+    }
+
+    /*
+     * At this point handle going up in the tree
+     */
+    if (ret == -1) {
+	DEBUG_VALID_MSG("error found returning");
+	return(ret);
+    }
+analyze:
+    while (CONT != NULL) {
+	/*
+	 * First do the analysis depending on the occurrence model at
+	 * this level.
+	 */
+	if (ret == 0) {
+	    switch (CONT->ocur) {
+		xmlNodePtr cur;
+
+		case XML_ELEMENT_CONTENT_ONCE:
+		    cur = ctxt->vstate->node;
+		    DEBUG_VALID_MSG("Once branch failed, rollback");
+		    if (vstateVPop(ctxt) < 0 ) {
+			DEBUG_VALID_MSG("exhaustion, failed");
+			return(0);
+		    }
+		    if (cur != ctxt->vstate->node)
+			determinist = -3;
+		    goto cont;
+		case XML_ELEMENT_CONTENT_PLUS:
+		    if (OCCURRENCE == 0) {
+			cur = ctxt->vstate->node;
+			DEBUG_VALID_MSG("Plus branch failed, rollback");
+			if (vstateVPop(ctxt) < 0 ) {
+			    DEBUG_VALID_MSG("exhaustion, failed");
+			    return(0);
+			}
+			if (cur != ctxt->vstate->node)
+			    determinist = -3;
+			goto cont;
+		    }
+		    DEBUG_VALID_MSG("Plus branch found");
+		    ret = 1;
+		    break;
+		case XML_ELEMENT_CONTENT_MULT:
+#ifdef DEBUG_VALID_ALGO
+		    if (OCCURRENCE == 0) {
+			DEBUG_VALID_MSG("Mult branch failed");
+		    } else {
+			DEBUG_VALID_MSG("Mult branch found");
+		    }
+#endif
+		    ret = 1;
+		    break;
+		case XML_ELEMENT_CONTENT_OPT:
+		    DEBUG_VALID_MSG("Option branch failed");
+		    ret = 1;
+		    break;
+	    }
+	} else {
+	    switch (CONT->ocur) {
+		case XML_ELEMENT_CONTENT_OPT:
+		    DEBUG_VALID_MSG("Option branch succeeded");
+		    ret = 1;
+		    break;
+		case XML_ELEMENT_CONTENT_ONCE:
+		    DEBUG_VALID_MSG("Once branch succeeded");
+		    ret = 1;
+		    break;
+		case XML_ELEMENT_CONTENT_PLUS:
+		    if (STATE == ROLLBACK_PARENT) {
+			DEBUG_VALID_MSG("Plus branch rollback");
+			ret = 1;
+			break;
+		    }
+		    if (NODE == NULL) {
+			DEBUG_VALID_MSG("Plus branch exhausted");
+			ret = 1;
+			break;
+		    }
+		    DEBUG_VALID_MSG("Plus branch succeeded, continuing");
+		    SET_OCCURRENCE;
+		    goto cont;
+		case XML_ELEMENT_CONTENT_MULT:
+		    if (STATE == ROLLBACK_PARENT) {
+			DEBUG_VALID_MSG("Mult branch rollback");
+			ret = 1;
+			break;
+		    }
+		    if (NODE == NULL) {
+			DEBUG_VALID_MSG("Mult branch exhausted");
+			ret = 1;
+			break;
+		    }
+		    DEBUG_VALID_MSG("Mult branch succeeded, continuing");
+		    /* SET_OCCURRENCE; */
+		    goto cont;
+	    }
+	}
+	STATE = 0;
+
+	/*
+	 * Then act accordingly at the parent level
+	 */
+	RESET_OCCURRENCE;
+	if (CONT->parent == NULL)
+	    break;
+
+	switch (CONT->parent->type) {
+	    case XML_ELEMENT_CONTENT_PCDATA:
+		DEBUG_VALID_MSG("Error: parent pcdata");
+		return(-1);
+	    case XML_ELEMENT_CONTENT_ELEMENT:
+		DEBUG_VALID_MSG("Error: parent element");
+		return(-1);
+	    case XML_ELEMENT_CONTENT_OR:
+		if (ret == 1) {
+		    DEBUG_VALID_MSG("Or succeeded");
+		    CONT = CONT->parent;
+		    DEPTH--;
+		} else {
+		    DEBUG_VALID_MSG("Or failed");
+		    CONT = CONT->parent;
+		    DEPTH--;
+		}
+		break;
+	    case XML_ELEMENT_CONTENT_SEQ:
+		if (ret == 0) {
+		    DEBUG_VALID_MSG("Sequence failed");
+		    CONT = CONT->parent;
+		    DEPTH--;
+		} else if (CONT == CONT->parent->c1) {
+		    DEBUG_VALID_MSG("Sequence testing 2nd branch");
+		    CONT = CONT->parent->c2;
+		    goto cont;
+		} else {
+		    DEBUG_VALID_MSG("Sequence succeeded");
+		    CONT = CONT->parent;
+		    DEPTH--;
+		}
+	}
+    }
+    if (NODE != NULL) {
+	xmlNodePtr cur;
+
+	cur = ctxt->vstate->node;
+	DEBUG_VALID_MSG("Failed, remaining input, rollback");
+	if (vstateVPop(ctxt) < 0 ) {
+	    DEBUG_VALID_MSG("exhaustion, failed");
+	    return(0);
+	}
+	if (cur != ctxt->vstate->node)
+	    determinist = -3;
+	goto cont;
+    }
+    if (ret == 0) {
+	xmlNodePtr cur;
+
+	cur = ctxt->vstate->node;
+	DEBUG_VALID_MSG("Failure, rollback");
+	if (vstateVPop(ctxt) < 0 ) {
+	    DEBUG_VALID_MSG("exhaustion, failed");
+	    return(0);
+	}
+	if (cur != ctxt->vstate->node)
+	    determinist = -3;
+	goto cont;
+    }
+    return(determinist);
+}
+#endif
+
+/**
+ * xmlSnprintfElements:
+ * @buf:  an output buffer
+ * @size:  the size of the buffer
+ * @content:  An element
+ * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
+ *
+ * This will dump the list of elements to the buffer
+ * Intended just for the debug routine
+ */
+static void
+xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
+    xmlNodePtr cur;
+    int len;
+
+    if (node == NULL) return;
+    if (glob) strcat(buf, "(");
+    cur = node;
+    while (cur != NULL) {
+	len = strlen(buf);
+	if (size - len < 50) {
+	    if ((size - len > 4) && (buf[len - 1] != '.'))
+		strcat(buf, " ...");
+	    return;
+	}
+        switch (cur->type) {
+            case XML_ELEMENT_NODE:
+		if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+		    if (size - len < xmlStrlen(cur->ns->prefix) + 10) {
+			if ((size - len > 4) && (buf[len - 1] != '.'))
+			    strcat(buf, " ...");
+			return;
+		    }
+		    strcat(buf, (char *) cur->ns->prefix);
+		    strcat(buf, ":");
+		}
+                if (size - len < xmlStrlen(cur->name) + 10) {
+		    if ((size - len > 4) && (buf[len - 1] != '.'))
+			strcat(buf, " ...");
+		    return;
+		}
+	        strcat(buf, (char *) cur->name);
+		if (cur->next != NULL)
+		    strcat(buf, " ");
+		break;
+            case XML_TEXT_NODE:
+		if (xmlIsBlankNode(cur))
+		    break;
+            case XML_CDATA_SECTION_NODE:
+            case XML_ENTITY_REF_NODE:
+	        strcat(buf, "CDATA");
+		if (cur->next != NULL)
+		    strcat(buf, " ");
+		break;
+            case XML_ATTRIBUTE_NODE:
+            case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    case XML_HTML_DOCUMENT_NODE:
+            case XML_DOCUMENT_TYPE_NODE:
+            case XML_DOCUMENT_FRAG_NODE:
+            case XML_NOTATION_NODE:
+	    case XML_NAMESPACE_DECL:
+	        strcat(buf, "???");
+		if (cur->next != NULL)
+		    strcat(buf, " ");
+		break;
+            case XML_ENTITY_NODE:
+            case XML_PI_NODE:
+            case XML_DTD_NODE:
+            case XML_COMMENT_NODE:
+	    case XML_ELEMENT_DECL:
+	    case XML_ATTRIBUTE_DECL:
+	    case XML_ENTITY_DECL:
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		break;
+	}
+	cur = cur->next;
+    }
+    if (glob) strcat(buf, ")");
+}
+
+/**
+ * xmlValidateElementContent:
+ * @ctxt:  the validation context
+ * @child:  the child list
+ * @elemDecl:  pointer to the element declaration
+ * @warn:  emit the error message
+ * @parent: the parent element (for error reporting)
+ *
+ * Try to validate the content model of an element
+ *
+ * returns 1 if valid or 0 if not and -1 in case of error
+ */
+
+static int
+xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
+       xmlElementPtr elemDecl, int warn, xmlNodePtr parent) {
+    int ret = 1;
+#ifndef  LIBXML_REGEXP_ENABLED
+    xmlNodePtr repl = NULL, last = NULL, tmp;
+#endif
+    xmlNodePtr cur;
+    xmlElementContentPtr cont;
+    const xmlChar *name;
+
+    if (elemDecl == NULL)
+	return(-1);
+    cont = elemDecl->content;
+    name = elemDecl->name;
+
+#ifdef LIBXML_REGEXP_ENABLED
+    /* Build the regexp associated to the content model */
+    if (elemDecl->contModel == NULL)
+	ret = xmlValidBuildContentModel(ctxt, elemDecl);
+    if (elemDecl->contModel == NULL) {
+	return(-1);
+    } else {
+	xmlRegExecCtxtPtr exec;
+
+	if (!xmlRegexpIsDeterminist(elemDecl->contModel)) {
+	    return(-1);
+	}
+	ctxt->nodeMax = 0;
+	ctxt->nodeNr = 0;
+	ctxt->nodeTab = NULL;
+	exec = xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
+	if (exec != NULL) {
+	    cur = child;
+	    while (cur != NULL) {
+		switch (cur->type) {
+		    case XML_ENTITY_REF_NODE:
+			/*
+			 * Push the current node to be able to roll back
+			 * and process within the entity
+			 */
+			if ((cur->children != NULL) &&
+			    (cur->children->children != NULL)) {
+			    nodeVPush(ctxt, cur);
+			    cur = cur->children->children;
+			    continue;
+			}
+			break;
+		    case XML_TEXT_NODE:
+			if (xmlIsBlankNode(cur))
+			    break;
+			ret = 0;
+			goto fail;
+		    case XML_CDATA_SECTION_NODE:
+			/* TODO */
+			ret = 0;
+			goto fail;
+		    case XML_ELEMENT_NODE:
+			if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+			    xmlChar fn[50];
+			    xmlChar *fullname;
+			    
+			    fullname = xmlBuildQName(cur->name,
+				                     cur->ns->prefix, fn, 50);
+			    if (fullname == NULL) {
+				ret = -1;
+				goto fail;
+			    }
+                            ret = xmlRegExecPushString(exec, fullname, NULL);
+			    if ((fullname != fn) && (fullname != cur->name))
+				xmlFree(fullname);
+			} else {
+			    ret = xmlRegExecPushString(exec, cur->name, NULL);
+			}
+			break;
+		    default:
+			break;
+		}
+		/*
+		 * Switch to next element
+		 */
+		cur = cur->next;
+		while (cur == NULL) {
+		    cur = nodeVPop(ctxt);
+		    if (cur == NULL)
+			break;
+		    cur = cur->next;
+		}
+	    }
+	    ret = xmlRegExecPushString(exec, NULL, NULL);
+fail:
+	    xmlRegFreeExecCtxt(exec);
+	}
+    }
+#else  /* LIBXML_REGEXP_ENABLED */
+    /*
+     * Allocate the stack
+     */
+    ctxt->vstateMax = 8;
+    ctxt->vstateTab = (xmlValidState *) xmlMalloc(
+		 ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
+    if (ctxt->vstateTab == NULL) {
+	xmlVErrMemory(ctxt, "malloc failed");
+	return(-1);
+    }
+    /*
+     * The first entry in the stack is reserved to the current state
+     */
+    ctxt->nodeMax = 0;
+    ctxt->nodeNr = 0;
+    ctxt->nodeTab = NULL;
+    ctxt->vstate = &ctxt->vstateTab[0];
+    ctxt->vstateNr = 1;
+    CONT = cont;
+    NODE = child;
+    DEPTH = 0;
+    OCCURS = 0;
+    STATE = 0;
+    ret = xmlValidateElementType(ctxt);
+    if ((ret == -3) && (warn)) {
+	xmlErrValidWarning(ctxt, child, XML_DTD_CONTENT_NOT_DETERMINIST,
+	       "Content model for Element %s is ambiguous\n",
+	                   name, NULL, NULL);
+    } else if (ret == -2) {
+	/*
+	 * An entities reference appeared at this level.
+	 * Buid a minimal representation of this node content
+	 * sufficient to run the validation process on it
+	 */
+	DEBUG_VALID_MSG("Found an entity reference, linearizing");
+	cur = child;
+	while (cur != NULL) {
+	    switch (cur->type) {
+		case XML_ENTITY_REF_NODE:
+		    /*
+		     * Push the current node to be able to roll back
+		     * and process within the entity
+		     */
+		    if ((cur->children != NULL) &&
+			(cur->children->children != NULL)) {
+			nodeVPush(ctxt, cur);
+			cur = cur->children->children;
+			continue;
+		    }
+		    break;
+		case XML_TEXT_NODE:
+		    if (xmlIsBlankNode(cur))
+			break;
+		    /* no break on purpose */
+		case XML_CDATA_SECTION_NODE:
+		    /* no break on purpose */
+		case XML_ELEMENT_NODE:
+		    /*
+		     * Allocate a new node and minimally fills in
+		     * what's required
+		     */
+		    tmp = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+		    if (tmp == NULL) {
+			xmlVErrMemory(ctxt, "malloc failed");
+			xmlFreeNodeList(repl);
+			ret = -1;
+			goto done;
+		    }
+		    tmp->type = cur->type;
+		    tmp->name = cur->name;
+		    tmp->ns = cur->ns;
+		    tmp->next = NULL;
+		    tmp->content = NULL;
+		    if (repl == NULL)
+			repl = last = tmp;
+		    else {
+			last->next = tmp;
+			last = tmp;
+		    }
+		    if (cur->type == XML_CDATA_SECTION_NODE) {
+			/* 
+			 * E59 spaces in CDATA does not match the
+			 * nonterminal S
+			 */
+			tmp->content = xmlStrdup(BAD_CAST "CDATA");
+		    }
+		    break;
+		default:
+		    break;
+	    }
+	    /*
+	     * Switch to next element
+	     */
+	    cur = cur->next;
+	    while (cur == NULL) {
+		cur = nodeVPop(ctxt);
+		if (cur == NULL)
+		    break;
+		cur = cur->next;
+	    }
+	}
+
+	/*
+	 * Relaunch the validation
+	 */
+	ctxt->vstate = &ctxt->vstateTab[0];
+	ctxt->vstateNr = 1;
+	CONT = cont;
+	NODE = repl;
+	DEPTH = 0;
+	OCCURS = 0;
+	STATE = 0;
+	ret = xmlValidateElementType(ctxt);
+    }
+#endif /* LIBXML_REGEXP_ENABLED */
+    if ((warn) && ((ret != 1) && (ret != -3))) {
+	if (ctxt != NULL) {
+	    char expr[5000];
+	    char list[5000];
+
+	    expr[0] = 0;
+	    xmlSnprintfElementContent(&expr[0], 5000, cont, 1);
+	    list[0] = 0;
+#ifndef LIBXML_REGEXP_ENABLED
+	    if (repl != NULL)
+		xmlSnprintfElements(&list[0], 5000, repl, 1);
+	    else
+#endif /* LIBXML_REGEXP_ENABLED */
+		xmlSnprintfElements(&list[0], 5000, child, 1);
+
+	    if (name != NULL) {
+		xmlErrValidNode(ctxt, parent, XML_DTD_CONTENT_MODEL,
+	   "Element %s content does not follow the DTD, expecting %s, got %s\n",
+		       name, BAD_CAST expr, BAD_CAST list);
+	    } else {
+		xmlErrValidNode(ctxt, parent, XML_DTD_CONTENT_MODEL,
+	   "Element content does not follow the DTD, expecting %s, got %s\n",
+		       BAD_CAST expr, BAD_CAST list, NULL);
+	    }
+	} else {
+	    if (name != NULL) {
+		xmlErrValidNode(ctxt, parent, XML_DTD_CONTENT_MODEL,
+		       "Element %s content does not follow the DTD\n",
+		       name, NULL, NULL);
+	    } else {
+		xmlErrValidNode(ctxt, parent, XML_DTD_CONTENT_MODEL,
+		       "Element content does not follow the DTD\n",
+		                NULL, NULL, NULL);
+	    }
+	}
+	ret = 0;
+    }
+    if (ret == -3)
+	ret = 1;
+
+#ifndef  LIBXML_REGEXP_ENABLED
+done:
+    /*
+     * Deallocate the copy if done, and free up the validation stack
+     */
+    while (repl != NULL) {
+	tmp = repl->next;
+	xmlFree(repl);
+	repl = tmp;
+    }
+    ctxt->vstateMax = 0;
+    if (ctxt->vstateTab != NULL) {
+	xmlFree(ctxt->vstateTab);
+	ctxt->vstateTab = NULL;
+    }
+#endif
+    ctxt->nodeMax = 0;
+    ctxt->nodeNr = 0;
+    if (ctxt->nodeTab != NULL) {
+	xmlFree(ctxt->nodeTab);
+	ctxt->nodeTab = NULL;
+    }
+    return(ret);
+
+}
+
+/**
+ * xmlValidateCdataElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Check that an element follows #CDATA
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+static int
+xmlValidateOneCdataElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                           xmlNodePtr elem) {
+    int ret = 1;
+    xmlNodePtr cur, child;
+
+    if ((ctxt == NULL) || (doc == NULL) || (elem == NULL))
+	return(0);
+
+    child = elem->children;
+
+    cur = child;
+    while (cur != NULL) {
+	switch (cur->type) {
+	    case XML_ENTITY_REF_NODE:
+		/*
+		 * Push the current node to be able to roll back
+		 * and process within the entity
+		 */
+		if ((cur->children != NULL) &&
+		    (cur->children->children != NULL)) {
+		    nodeVPush(ctxt, cur);
+		    cur = cur->children->children;
+		    continue;
+		}
+		break;
+	    case XML_COMMENT_NODE:
+	    case XML_PI_NODE:
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+		break;
+	    default:
+		ret = 0;
+		goto done;
+	}
+	/*
+	 * Switch to next element
+	 */
+	cur = cur->next;
+	while (cur == NULL) {
+	    cur = nodeVPop(ctxt);
+	    if (cur == NULL)
+		break;
+	    cur = cur->next;
+	}
+    }
+done:
+    ctxt->nodeMax = 0;
+    ctxt->nodeNr = 0;
+    if (ctxt->nodeTab != NULL) {
+	xmlFree(ctxt->nodeTab);
+	ctxt->nodeTab = NULL;
+    }
+    return(ret);
+}
+
+/**
+ * xmlValidateCheckMixed:
+ * @ctxt:  the validation context
+ * @cont:  the mixed content model
+ * @qname:  the qualified name as appearing in the serialization
+ *
+ * Check if the given node is part of the content model.
+ *
+ * Returns 1 if yes, 0 if no, -1 in case of error
+ */
+static int
+xmlValidateCheckMixed(xmlValidCtxtPtr ctxt,
+	              xmlElementContentPtr cont, const xmlChar *qname) {
+    const xmlChar *name;
+    int plen;
+    name = xmlSplitQName3(qname, &plen);
+
+    if (name == NULL) {
+	while (cont != NULL) {
+	    if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
+		if ((cont->prefix == NULL) && (xmlStrEqual(cont->name, qname)))
+		    return(1);
+	    } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
+	       (cont->c1 != NULL) &&
+	       (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
+		if ((cont->c1->prefix == NULL) &&
+		    (xmlStrEqual(cont->c1->name, qname)))
+		    return(1);
+	    } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
+		(cont->c1 == NULL) ||
+		(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
+		xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT, 
+			"Internal: MIXED struct corrupted\n",
+			NULL);
+		break;
+	    }
+	    cont = cont->c2;
+	}
+    } else {
+	while (cont != NULL) {
+	    if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
+		if ((cont->prefix != NULL) &&
+		    (xmlStrncmp(cont->prefix, qname, plen) == 0) &&
+		    (xmlStrEqual(cont->name, name)))
+		    return(1);
+	    } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
+	       (cont->c1 != NULL) &&
+	       (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
+		if ((cont->c1->prefix != NULL) &&
+		    (xmlStrncmp(cont->c1->prefix, qname, plen) == 0) &&
+		    (xmlStrEqual(cont->c1->name, name)))
+		    return(1);
+	    } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
+		(cont->c1 == NULL) ||
+		(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
+		xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT, 
+			"Internal: MIXED struct corrupted\n",
+			NULL);
+		break;
+	    }
+	    cont = cont->c2;
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlValidGetElemDecl:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ * @extsubset:  pointer, (out) indicate if the declaration was found
+ *              in the external subset.
+ *
+ * Finds a declaration associated to an element in the document.
+ *
+ * returns the pointer to the declaration or NULL if not found.
+ */
+static xmlElementPtr
+xmlValidGetElemDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+	            xmlNodePtr elem, int *extsubset) {
+    xmlElementPtr elemDecl = NULL;
+    const xmlChar *prefix = NULL;
+
+    if ((ctxt == NULL) || (doc == NULL) || 
+        (elem == NULL) || (elem->name == NULL))
+        return(NULL);
+    if (extsubset != NULL)
+	*extsubset = 0;
+
+    /*
+     * Fetch the declaration for the qualified name
+     */
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL))
+	prefix = elem->ns->prefix;
+
+    if (prefix != NULL) {
+	elemDecl = xmlGetDtdQElementDesc(doc->intSubset,
+		                         elem->name, prefix);
+	if ((elemDecl == NULL) && (doc->extSubset != NULL)) {
+	    elemDecl = xmlGetDtdQElementDesc(doc->extSubset,
+		                             elem->name, prefix);
+	    if ((elemDecl != NULL) && (extsubset != NULL))
+		*extsubset = 1;
+	}
+    }
+
+    /*
+     * Fetch the declaration for the non qualified name
+     * This is "non-strict" validation should be done on the
+     * full QName but in that case being flexible makes sense.
+     */
+    if (elemDecl == NULL) {
+	elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
+	if ((elemDecl == NULL) && (doc->extSubset != NULL)) {
+	    elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
+	    if ((elemDecl != NULL) && (extsubset != NULL))
+		*extsubset = 1;
+	}
+    }
+    if (elemDecl == NULL) {
+	xmlErrValidNode(ctxt, elem,
+			XML_DTD_UNKNOWN_ELEM,
+	       "No declaration for element %s\n",
+	       elem->name, NULL, NULL);
+    }
+    return(elemDecl);
+}
+
+#ifdef LIBXML_REGEXP_ENABLED
+/**
+ * xmlValidatePushElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ * @qname:  the qualified name as appearing in the serialization
+ *
+ * Push a new element start on the validation stack.
+ *
+ * returns 1 if no validation problem was found or 0 otherwise
+ */
+int
+xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                       xmlNodePtr elem, const xmlChar *qname) {
+    int ret = 1;
+    xmlElementPtr eDecl;
+    int extsubset = 0;
+
+    if (ctxt == NULL)
+        return(0);
+/* printf("PushElem %s\n", qname); */
+    if ((ctxt->vstateNr > 0) && (ctxt->vstate != NULL)) {
+	xmlValidStatePtr state = ctxt->vstate;
+	xmlElementPtr elemDecl;
+
+	/*
+	 * Check the new element agaisnt the content model of the new elem.
+	 */
+	if (state->elemDecl != NULL) {
+	    elemDecl = state->elemDecl;
+
+	    switch(elemDecl->etype) {
+		case XML_ELEMENT_TYPE_UNDEFINED:
+		    ret = 0;
+		    break;
+		case XML_ELEMENT_TYPE_EMPTY:
+		    xmlErrValidNode(ctxt, state->node,
+				    XML_DTD_NOT_EMPTY,
+	       "Element %s was declared EMPTY this one has content\n",
+			   state->node->name, NULL, NULL);
+		    ret = 0;
+		    break;
+		case XML_ELEMENT_TYPE_ANY:
+		    /* I don't think anything is required then */
+		    break;
+		case XML_ELEMENT_TYPE_MIXED:
+		    /* simple case of declared as #PCDATA */
+		    if ((elemDecl->content != NULL) &&
+			(elemDecl->content->type ==
+			 XML_ELEMENT_CONTENT_PCDATA)) {
+			xmlErrValidNode(ctxt, state->node,
+					XML_DTD_NOT_PCDATA,
+	       "Element %s was declared #PCDATA but contains non text nodes\n",
+				state->node->name, NULL, NULL);
+			ret = 0;
+		    } else {
+			ret = xmlValidateCheckMixed(ctxt, elemDecl->content,
+				                    qname);
+			if (ret != 1) {
+			    xmlErrValidNode(ctxt, state->node,
+					    XML_DTD_INVALID_CHILD,
+	       "Element %s is not declared in %s list of possible children\n",
+				    qname, state->node->name, NULL);
+			}
+		    }
+		    break;
+		case XML_ELEMENT_TYPE_ELEMENT:
+		    /*
+		     * TODO:
+		     * VC: Standalone Document Declaration
+		     *     - element types with element content, if white space
+		     *       occurs directly within any instance of those types.
+		     */
+		    if (state->exec != NULL) {
+			ret = xmlRegExecPushString(state->exec, qname, NULL);
+			if (ret < 0) {
+			    xmlErrValidNode(ctxt, state->node,
+					    XML_DTD_CONTENT_MODEL,
+	       "Element %s content does not follow the DTD, Misplaced %s\n",
+				   state->node->name, qname, NULL);
+			    ret = 0;
+			} else {
+			    ret = 1;
+			}
+		    }
+		    break;
+	    }
+	}
+    }
+    eDecl = xmlValidGetElemDecl(ctxt, doc, elem, &extsubset);
+    vstateVPush(ctxt, eDecl, elem);
+    return(ret);
+}
+
+/**
+ * xmlValidatePushCData:
+ * @ctxt:  the validation context
+ * @data:  some character data read
+ * @len:  the lenght of the data
+ *
+ * check the CData parsed for validation in the current stack
+ *
+ * returns 1 if no validation problem was found or 0 otherwise
+ */
+int
+xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) {
+    int ret = 1;
+
+/* printf("CDATA %s %d\n", data, len); */
+    if (ctxt == NULL)
+        return(0);
+    if (len <= 0)
+	return(ret);
+    if ((ctxt->vstateNr > 0) && (ctxt->vstate != NULL)) {
+	xmlValidStatePtr state = ctxt->vstate;
+	xmlElementPtr elemDecl;
+
+	/*
+	 * Check the new element agaisnt the content model of the new elem.
+	 */
+	if (state->elemDecl != NULL) {
+	    elemDecl = state->elemDecl;
+
+	    switch(elemDecl->etype) {
+		case XML_ELEMENT_TYPE_UNDEFINED:
+		    ret = 0;
+		    break;
+		case XML_ELEMENT_TYPE_EMPTY:
+		    xmlErrValidNode(ctxt, state->node,
+				    XML_DTD_NOT_EMPTY,
+	       "Element %s was declared EMPTY this one has content\n",
+			   state->node->name, NULL, NULL);
+		    ret = 0;
+		    break;
+		case XML_ELEMENT_TYPE_ANY:
+		    break;
+		case XML_ELEMENT_TYPE_MIXED:
+		    break;
+		case XML_ELEMENT_TYPE_ELEMENT:
+		    if (len > 0) {
+			int i;
+
+			for (i = 0;i < len;i++) {
+			    if (!IS_BLANK_CH(data[i])) {
+				xmlErrValidNode(ctxt, state->node,
+						XML_DTD_CONTENT_MODEL,
+	   "Element %s content does not follow the DTD, Text not allowed\n",
+				       state->node->name, NULL, NULL);
+				ret = 0;
+				goto done;
+			    }
+			}
+			/*
+			 * TODO:
+			 * VC: Standalone Document Declaration
+			 *  element types with element content, if white space
+			 *  occurs directly within any instance of those types.
+			 */
+		    }
+		    break;
+	    }
+	}
+    }
+done:
+    return(ret);
+}
+
+/**
+ * xmlValidatePopElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ * @qname:  the qualified name as appearing in the serialization
+ *
+ * Pop the element end from the validation stack.
+ *
+ * returns 1 if no validation problem was found or 0 otherwise
+ */
+int
+xmlValidatePopElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc ATTRIBUTE_UNUSED,
+                      xmlNodePtr elem ATTRIBUTE_UNUSED,
+		      const xmlChar *qname ATTRIBUTE_UNUSED) {
+    int ret = 1;
+
+    if (ctxt == NULL)
+        return(0);
+/* printf("PopElem %s\n", qname); */
+    if ((ctxt->vstateNr > 0) && (ctxt->vstate != NULL)) {
+	xmlValidStatePtr state = ctxt->vstate;
+	xmlElementPtr elemDecl;
+
+	/*
+	 * Check the new element agaisnt the content model of the new elem.
+	 */
+	if (state->elemDecl != NULL) {
+	    elemDecl = state->elemDecl;
+
+	    if (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT) {
+		if (state->exec != NULL) {
+		    ret = xmlRegExecPushString(state->exec, NULL, NULL);
+		    if (ret == 0) {
+			xmlErrValidNode(ctxt, state->node,
+			                XML_DTD_CONTENT_MODEL,
+	   "Element %s content does not follow the DTD, Expecting more child\n",
+			       state->node->name, NULL,NULL);
+		    } else {
+			/*
+			 * previous validation errors should not generate
+			 * a new one here
+			 */
+			ret = 1;
+		    }
+		}
+	    }
+	}
+	vstateVPop(ctxt);
+    }
+    return(ret);
+}
+#endif /* LIBXML_REGEXP_ENABLED */
+
+/**
+ * xmlValidateOneElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Try to validate a single element and it's attributes,
+ * basically it does the following checks as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: Element Valid ]
+ *  - [ VC: Required Attribute ]
+ * Then call xmlValidateOneAttribute() for each attribute present.
+ *
+ * The ID/IDREF checkings are done separately
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
+                      xmlNodePtr elem) {
+    xmlElementPtr elemDecl = NULL;
+    xmlElementContentPtr cont;
+    xmlAttributePtr attr;
+    xmlNodePtr child;
+    int ret = 1, tmp;
+    const xmlChar *name;
+    int extsubset = 0;
+
+    CHECK_DTD;
+
+    if (elem == NULL) return(0);
+    switch (elem->type) {
+        case XML_ATTRIBUTE_NODE:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "Attribute element not expected\n", NULL, NULL ,NULL);
+	    return(0);
+        case XML_TEXT_NODE:
+	    if (elem->children != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		                "Text element has children !\n",
+				NULL,NULL,NULL);
+		return(0);
+	    }
+	    if (elem->ns != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		                "Text element has namespace !\n",
+				NULL,NULL,NULL);
+		return(0);
+	    }
+	    if (elem->content == NULL) {
+		xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		                "Text element has no content !\n",
+				NULL,NULL,NULL);
+		return(0);
+	    }
+	    return(1);
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+            return(1);
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+	    return(1);
+        case XML_ENTITY_NODE:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "Entity element not expected\n", NULL, NULL ,NULL);
+	    return(0);
+        case XML_NOTATION_NODE:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "Notation element not expected\n", NULL, NULL ,NULL);
+	    return(0);
+        case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "Document element not expected\n", NULL, NULL ,NULL);
+	    return(0);
+        case XML_HTML_DOCUMENT_NODE:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "HTML Document not expected\n", NULL, NULL ,NULL);
+	    return(0);
+        case XML_ELEMENT_NODE:
+	    break;
+	default:
+	    xmlErrValidNode(ctxt, elem, XML_ERR_INTERNAL_ERROR,
+		   "unknown element type\n", NULL, NULL ,NULL);
+	    return(0);
+    }
+
+    /*
+     * Fetch the declaration
+     */
+    elemDecl = xmlValidGetElemDecl(ctxt, doc, elem, &extsubset);
+    if (elemDecl == NULL)
+	return(0);
+
+    /*
+     * If vstateNr is not zero that means continuous validation is 
+     * activated, do not try to check the content model at that level.
+     */
+    if (ctxt->vstateNr == 0) {
+    /* Check that the element content matches the definition */
+    switch (elemDecl->etype) {
+        case XML_ELEMENT_TYPE_UNDEFINED:
+	    xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ELEM,
+	                    "No declaration for element %s\n",
+		   elem->name, NULL, NULL);
+	    return(0);
+        case XML_ELEMENT_TYPE_EMPTY:
+	    if (elem->children != NULL) {
+		xmlErrValidNode(ctxt, elem, XML_DTD_NOT_EMPTY,
+	       "Element %s was declared EMPTY this one has content\n",
+	               elem->name, NULL, NULL);
+		ret = 0;
+	    }
+	    break;
+        case XML_ELEMENT_TYPE_ANY:
+	    /* I don't think anything is required then */
+	    break;
+        case XML_ELEMENT_TYPE_MIXED:
+
+	    /* simple case of declared as #PCDATA */
+	    if ((elemDecl->content != NULL) &&
+		(elemDecl->content->type == XML_ELEMENT_CONTENT_PCDATA)) {
+		ret = xmlValidateOneCdataElement(ctxt, doc, elem);
+		if (!ret) {
+		    xmlErrValidNode(ctxt, elem, XML_DTD_NOT_PCDATA,
+	       "Element %s was declared #PCDATA but contains non text nodes\n",
+			   elem->name, NULL, NULL);
+		}
+		break;
+	    }
+	    child = elem->children;
+	    /* Hum, this start to get messy */
+	    while (child != NULL) {
+	        if (child->type == XML_ELEMENT_NODE) {
+		    name = child->name;
+		    if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
+			xmlChar fn[50];
+			xmlChar *fullname;
+			
+			fullname = xmlBuildQName(child->name, child->ns->prefix,
+				                 fn, 50);
+			if (fullname == NULL)
+			    return(0);
+			cont = elemDecl->content;
+			while (cont != NULL) {
+			    if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
+				if (xmlStrEqual(cont->name, fullname))
+				    break;
+			    } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
+			       (cont->c1 != NULL) &&
+			       (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
+				if (xmlStrEqual(cont->c1->name, fullname))
+				    break;
+			    } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
+				(cont->c1 == NULL) ||
+				(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
+				xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT, 
+					"Internal: MIXED struct corrupted\n",
+					NULL);
+				break;
+			    }
+			    cont = cont->c2;
+			}
+			if ((fullname != fn) && (fullname != child->name))
+			    xmlFree(fullname);
+			if (cont != NULL)
+			    goto child_ok;
+		    }
+		    cont = elemDecl->content;
+		    while (cont != NULL) {
+		        if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
+			    if (xmlStrEqual(cont->name, name)) break;
+			} else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
+			   (cont->c1 != NULL) &&
+			   (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)) {
+			    if (xmlStrEqual(cont->c1->name, name)) break;
+			} else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
+			    (cont->c1 == NULL) ||
+			    (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
+			    xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT, 
+				    "Internal: MIXED struct corrupted\n",
+				    NULL);
+			    break;
+			}
+			cont = cont->c2;
+		    }
+		    if (cont == NULL) {
+			xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_CHILD,
+	       "Element %s is not declared in %s list of possible children\n",
+			       name, elem->name, NULL);
+			ret = 0;
+		    }
+		}
+child_ok:
+	        child = child->next;
+	    }
+	    break;
+        case XML_ELEMENT_TYPE_ELEMENT:
+	    if ((doc->standalone == 1) && (extsubset == 1)) {
+		/*
+		 * VC: Standalone Document Declaration
+		 *     - element types with element content, if white space
+		 *       occurs directly within any instance of those types.
+		 */
+		child = elem->children;
+		while (child != NULL) {
+		    if (child->type == XML_TEXT_NODE) {
+			const xmlChar *content = child->content;
+
+			while (IS_BLANK_CH(*content))
+			    content++;
+			if (*content == 0) {
+			    xmlErrValidNode(ctxt, elem,
+			                    XML_DTD_STANDALONE_WHITE_SPACE,
+"standalone: %s declared in the external subset contains white spaces nodes\n",
+				   elem->name, NULL, NULL);
+			    ret = 0;
+			    break;
+			}
+		    }
+		    child =child->next;
+		}
+	    }
+	    child = elem->children;
+	    cont = elemDecl->content;
+	    tmp = xmlValidateElementContent(ctxt, child, elemDecl, 1, elem);
+	    if (tmp <= 0)
+		ret = tmp;
+	    break;
+    }
+    } /* not continuous */
+
+    /* [ VC: Required Attribute ] */
+    attr = elemDecl->attributes;
+    while (attr != NULL) {
+	if (attr->def == XML_ATTRIBUTE_REQUIRED) {
+	    int qualified = -1;
+
+	    if ((attr->prefix == NULL) &&
+		(xmlStrEqual(attr->name, BAD_CAST "xmlns"))) {
+		xmlNsPtr ns;
+
+		ns = elem->nsDef;
+		while (ns != NULL) {
+		    if (ns->prefix == NULL)
+			goto found;
+		    ns = ns->next;
+		}
+	    } else if (xmlStrEqual(attr->prefix, BAD_CAST "xmlns")) {
+		xmlNsPtr ns;
+
+		ns = elem->nsDef;
+		while (ns != NULL) {
+		    if (xmlStrEqual(attr->name, ns->prefix))
+			goto found;
+		    ns = ns->next;
+		}
+	    } else {
+		xmlAttrPtr attrib;
+		
+		attrib = elem->properties;
+		while (attrib != NULL) {
+		    if (xmlStrEqual(attrib->name, attr->name)) {
+			if (attr->prefix != NULL) {
+			    xmlNsPtr nameSpace = attrib->ns;
+
+			    if (nameSpace == NULL)
+				nameSpace = elem->ns;
+			    /*
+			     * qualified names handling is problematic, having a
+			     * different prefix should be possible but DTDs don't
+			     * allow to define the URI instead of the prefix :-(
+			     */
+			    if (nameSpace == NULL) {
+				if (qualified < 0) 
+				    qualified = 0;
+			    } else if (!xmlStrEqual(nameSpace->prefix,
+						    attr->prefix)) {
+				if (qualified < 1) 
+				    qualified = 1;
+			    } else
+				goto found;
+			} else {
+			    /*
+			     * We should allow applications to define namespaces
+			     * for their application even if the DTD doesn't 
+			     * carry one, otherwise, basically we would always
+			     * break.
+			     */
+			    goto found;
+			}
+		    }
+		    attrib = attrib->next;
+		}
+	    }
+	    if (qualified == -1) {
+		if (attr->prefix == NULL) {
+		    xmlErrValidNode(ctxt, elem, XML_DTD_MISSING_ATTRIBUTE,
+		       "Element %s does not carry attribute %s\n",
+			   elem->name, attr->name, NULL);
+		    ret = 0;
+	        } else {
+		    xmlErrValidNode(ctxt, elem, XML_DTD_MISSING_ATTRIBUTE,
+		       "Element %s does not carry attribute %s:%s\n",
+			   elem->name, attr->prefix,attr->name);
+		    ret = 0;
+		}
+	    } else if (qualified == 0) {
+		xmlErrValidWarning(ctxt, elem, XML_DTD_NO_PREFIX,
+		   "Element %s required attribute %s:%s has no prefix\n",
+		       elem->name, attr->prefix, attr->name);
+	    } else if (qualified == 1) {
+		xmlErrValidWarning(ctxt, elem, XML_DTD_DIFFERENT_PREFIX,
+		   "Element %s required attribute %s:%s has different prefix\n",
+		       elem->name, attr->prefix, attr->name);
+	    }
+	} else if (attr->def == XML_ATTRIBUTE_FIXED) {
+	    /*
+	     * Special tests checking #FIXED namespace declarations
+	     * have the right value since this is not done as an
+	     * attribute checking
+	     */
+	    if ((attr->prefix == NULL) &&
+		(xmlStrEqual(attr->name, BAD_CAST "xmlns"))) {
+		xmlNsPtr ns;
+
+		ns = elem->nsDef;
+		while (ns != NULL) {
+		    if (ns->prefix == NULL) {
+			if (!xmlStrEqual(attr->defaultValue, ns->href)) {
+			    xmlErrValidNode(ctxt, elem,
+			           XML_DTD_ELEM_DEFAULT_NAMESPACE,
+   "Element %s namespace name for default namespace does not match the DTD\n",
+				   elem->name, NULL, NULL);
+			    ret = 0;
+			}
+			goto found;
+		    }
+		    ns = ns->next;
+		}
+	    } else if (xmlStrEqual(attr->prefix, BAD_CAST "xmlns")) {
+		xmlNsPtr ns;
+
+		ns = elem->nsDef;
+		while (ns != NULL) {
+		    if (xmlStrEqual(attr->name, ns->prefix)) {
+			if (!xmlStrEqual(attr->defaultValue, ns->href)) {
+			    xmlErrValidNode(ctxt, elem, XML_DTD_ELEM_NAMESPACE,
+		   "Element %s namespace name for %s does not match the DTD\n",
+				   elem->name, ns->prefix, NULL);
+			    ret = 0;
+			}
+			goto found;
+		    }
+		    ns = ns->next;
+		}
+	    }
+	}
+found:	    
+        attr = attr->nexth;
+    }
+    return(ret);
+}
+
+/**
+ * xmlValidateRoot:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ *
+ * Try to validate a the root element
+ * basically it does the following check as described by the
+ * XML-1.0 recommendation:
+ *  - [ VC: Root Element Type ]
+ * it doesn't try to recurse or apply other check to the element
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
+    xmlNodePtr root;
+    int ret;
+
+    if (doc == NULL) return(0);
+
+    root = xmlDocGetRootElement(doc);
+    if ((root == NULL) || (root->name == NULL)) {
+	xmlErrValid(ctxt, XML_DTD_NO_ROOT,
+	            "no root element\n", NULL);
+        return(0);
+    }
+
+    /*
+     * When doing post validation against a separate DTD, those may
+     * no internal subset has been generated
+     */
+    if ((doc->intSubset != NULL) &&
+	(doc->intSubset->name != NULL)) {
+	/*
+	 * Check first the document root against the NQName
+	 */
+	if (!xmlStrEqual(doc->intSubset->name, root->name)) {
+	    if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
+		xmlChar fn[50];
+		xmlChar *fullname;
+		
+		fullname = xmlBuildQName(root->name, root->ns->prefix, fn, 50);
+		if (fullname == NULL) {
+		    xmlVErrMemory(ctxt, NULL);
+		    return(0);
+		}
+		ret = xmlStrEqual(doc->intSubset->name, fullname);
+		if ((fullname != fn) && (fullname != root->name))
+		    xmlFree(fullname);
+		if (ret == 1)
+		    goto name_ok;
+	    } 
+	    if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
+		(xmlStrEqual(root->name, BAD_CAST "html")))
+		goto name_ok;
+	    xmlErrValidNode(ctxt, root, XML_DTD_ROOT_NAME,
+		   "root and DTD name do not match '%s' and '%s'\n",
+		   root->name, doc->intSubset->name, NULL);
+	    return(0);
+	}
+    }
+name_ok:
+    return(1);
+}
+
+
+/**
+ * xmlValidateElement:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @elem:  an element instance
+ *
+ * Try to validate the subtree under an element 
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
+    xmlNodePtr child;
+    xmlAttrPtr attr;
+    xmlNsPtr ns;
+    const xmlChar *value;
+    int ret = 1;
+
+    if (elem == NULL) return(0);
+
+    /*
+     * XInclude elements were added after parsing in the infoset,
+     * they don't really mean anything validation wise.
+     */
+    if ((elem->type == XML_XINCLUDE_START) ||
+	(elem->type == XML_XINCLUDE_END))
+	return(1);
+
+    CHECK_DTD;
+
+    /*
+     * Entities references have to be handled separately
+     */
+    if (elem->type == XML_ENTITY_REF_NODE) {
+	return(1);
+    }
+
+    ret &= xmlValidateOneElement(ctxt, doc, elem);
+    if (elem->type == XML_ELEMENT_NODE) {
+	attr = elem->properties;
+	while (attr != NULL) {
+	    value = xmlNodeListGetString(doc, attr->children, 0);
+	    ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
+	    if (value != NULL)
+		xmlFree((char *)value);
+	    attr= attr->next;
+	}
+	ns = elem->nsDef;
+	while (ns != NULL) {
+	    if (elem->ns == NULL)
+		ret &= xmlValidateOneNamespace(ctxt, doc, elem, NULL,
+					       ns, ns->href);
+	    else
+		ret &= xmlValidateOneNamespace(ctxt, doc, elem,
+		                               elem->ns->prefix, ns, ns->href);
+	    ns = ns->next;
+	}
+    }
+    child = elem->children;
+    while (child != NULL) {
+        ret &= xmlValidateElement(ctxt, doc, child);
+        child = child->next;
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlValidateRef:
+ * @ref:   A reference to be validated
+ * @ctxt:  Validation context
+ * @name:  Name of ID we are searching for
+ *
+ */
+static void
+xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
+	                   const xmlChar *name) {
+    xmlAttrPtr id;
+    xmlAttrPtr attr;
+
+    if (ref == NULL)
+	return;
+    if ((ref->attr == NULL) && (ref->name == NULL))
+	return;
+    attr = ref->attr;
+    if (attr == NULL) {
+	xmlChar *dup, *str = NULL, *cur, save;
+
+	dup = xmlStrdup(name);
+	if (dup == NULL) {
+	    ctxt->valid = 0;
+	    return;
+	}
+	cur = dup;
+	while (*cur != 0) {
+	    str = cur;
+	    while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
+	    save = *cur;
+	    *cur = 0;
+	    id = xmlGetID(ctxt->doc, str);
+	    if (id == NULL) {
+		xmlErrValidNodeNr(ctxt, NULL, XML_DTD_UNKNOWN_ID,
+	   "attribute %s line %d references an unknown ID \"%s\"\n",
+		       ref->name, ref->lineno, str);
+		ctxt->valid = 0;
+	    }
+	    if (save == 0)
+		break;
+	    *cur = save;
+	    while (IS_BLANK_CH(*cur)) cur++;
+	}
+	xmlFree(dup);
+    } else if (attr->atype == XML_ATTRIBUTE_IDREF) {
+	id = xmlGetID(ctxt->doc, name);
+	if (id == NULL) {
+	    xmlErrValidNode(ctxt, attr->parent, XML_DTD_UNKNOWN_ID,
+	   "IDREF attribute %s references an unknown ID \"%s\"\n",
+		   attr->name, name, NULL);
+	    ctxt->valid = 0;
+	}
+    } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
+	xmlChar *dup, *str = NULL, *cur, save;
+
+	dup = xmlStrdup(name);
+	if (dup == NULL) {
+	    xmlVErrMemory(ctxt, "IDREFS split");
+	    ctxt->valid = 0;
+	    return;
+	}
+	cur = dup;
+	while (*cur != 0) {
+	    str = cur;
+	    while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
+	    save = *cur;
+	    *cur = 0;
+	    id = xmlGetID(ctxt->doc, str);
+	    if (id == NULL) {
+		xmlErrValidNode(ctxt, attr->parent, XML_DTD_UNKNOWN_ID,
+	   "IDREFS attribute %s references an unknown ID \"%s\"\n",
+			     attr->name, str, NULL);
+		ctxt->valid = 0;
+	    }
+	    if (save == 0)
+		break;
+	    *cur = save;
+	    while (IS_BLANK_CH(*cur)) cur++;
+	}
+	xmlFree(dup);
+    }
+}
+
+/**
+ * xmlWalkValidateList:
+ * @data:  Contents of current link
+ * @user:  Value supplied by the user
+ *
+ * Returns 0 to abort the walk or 1 to continue
+ */
+static int
+xmlWalkValidateList(const void *data, const void *user)
+{
+	xmlValidateMemoPtr memo = (xmlValidateMemoPtr)user;
+	xmlValidateRef((xmlRefPtr)data, memo->ctxt, memo->name);
+	return 1;
+}
+
+/**
+ * xmlValidateCheckRefCallback:
+ * @ref_list:  List of references
+ * @ctxt:  Validation context
+ * @name:  Name of ID we are searching for
+ *
+ */
+static void
+xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt,
+	                   const xmlChar *name) {
+    xmlValidateMemo memo;
+
+    if (ref_list == NULL)
+	return;
+    memo.ctxt = ctxt;
+    memo.name = name;
+
+    xmlListWalk(ref_list, xmlWalkValidateList, &memo);
+    
+}
+
+/**
+ * xmlValidateDocumentFinal:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ *
+ * Does the final step for the document validation once all the
+ * incremental validation steps have been completed
+ *
+ * basically it does the following checks described by the XML Rec
+ * 
+ * Check all the IDREF/IDREFS attributes definition for validity
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
+    xmlRefTablePtr table;
+
+    if (ctxt == NULL)
+        return(0);
+    if (doc == NULL) {
+        xmlErrValid(ctxt, XML_DTD_NO_DOC, 
+		"xmlValidateDocumentFinal: doc == NULL\n", NULL);
+	return(0);
+    }
+
+    /*
+     * Check all the NOTATION/NOTATIONS attributes
+     */
+    /*
+     * Check all the ENTITY/ENTITIES attributes definition for validity
+     */
+    /*
+     * Check all the IDREF/IDREFS attributes definition for validity
+     */
+    table = (xmlRefTablePtr) doc->refs;
+    ctxt->doc = doc;
+    ctxt->valid = 1;
+    xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
+    return(ctxt->valid);
+}
+
+/**
+ * xmlValidateDtd:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ * @dtd:  a dtd instance
+ *
+ * Try to validate the document against the dtd instance
+ *
+ * Basically it does check all the definitions in the DtD.
+ * Note the the internal subset (if present) is de-coupled
+ * (i.e. not used), which could give problems if ID or IDREF
+ * is present.
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
+    int ret;
+    xmlDtdPtr oldExt, oldInt;
+    xmlNodePtr root;
+
+    if (dtd == NULL) return(0);
+    if (doc == NULL) return(0);
+    oldExt = doc->extSubset;
+    oldInt = doc->intSubset;
+    doc->extSubset = dtd;
+    doc->intSubset = NULL;
+    ret = xmlValidateRoot(ctxt, doc);
+    if (ret == 0) {
+	doc->extSubset = oldExt;
+	doc->intSubset = oldInt;
+	return(ret);
+    }
+    if (doc->ids != NULL) {
+          xmlFreeIDTable(doc->ids);
+          doc->ids = NULL;
+    }
+    if (doc->refs != NULL) {
+          xmlFreeRefTable(doc->refs);
+          doc->refs = NULL;
+    }
+    root = xmlDocGetRootElement(doc);
+    ret = xmlValidateElement(ctxt, doc, root);
+    ret &= xmlValidateDocumentFinal(ctxt, doc);
+    doc->extSubset = oldExt;
+    doc->intSubset = oldInt;
+    return(ret);
+}
+
+static void
+xmlValidateNotationCallback(xmlEntityPtr cur, xmlValidCtxtPtr ctxt,
+	                    const xmlChar *name ATTRIBUTE_UNUSED) {
+    if (cur == NULL)
+	return;
+    if (cur->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+	xmlChar *notation = cur->content;
+
+	if (notation != NULL) {
+	    int ret;
+
+	    ret = xmlValidateNotationUse(ctxt, cur->doc, notation);
+	    if (ret != 1) {
+		ctxt->valid = 0;
+	    }
+	}
+    }
+}
+
+static void
+xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
+	                    const xmlChar *name ATTRIBUTE_UNUSED) {
+    int ret;
+    xmlDocPtr doc;
+    xmlElementPtr elem = NULL;
+
+    if (cur == NULL)
+	return;
+    switch (cur->atype) {
+	case XML_ATTRIBUTE_CDATA:
+	case XML_ATTRIBUTE_ID:
+	case XML_ATTRIBUTE_IDREF	:
+	case XML_ATTRIBUTE_IDREFS:
+	case XML_ATTRIBUTE_NMTOKEN:
+	case XML_ATTRIBUTE_NMTOKENS:
+	case XML_ATTRIBUTE_ENUMERATION:
+	    break;
+	case XML_ATTRIBUTE_ENTITY:
+	case XML_ATTRIBUTE_ENTITIES:
+	case XML_ATTRIBUTE_NOTATION:
+	    if (cur->defaultValue != NULL) {
+		
+		ret = xmlValidateAttributeValue2(ctxt, ctxt->doc, cur->name,
+			                         cur->atype, cur->defaultValue);
+		if ((ret == 0) && (ctxt->valid == 1))
+		    ctxt->valid = 0;
+	    }
+	    if (cur->tree != NULL) {
+		xmlEnumerationPtr tree = cur->tree;
+		while (tree != NULL) {
+		    ret = xmlValidateAttributeValue2(ctxt, ctxt->doc,
+				    cur->name, cur->atype, tree->name);
+		    if ((ret == 0) && (ctxt->valid == 1))
+			ctxt->valid = 0;
+		    tree = tree->next;
+		}
+	    }
+    }
+    if (cur->atype == XML_ATTRIBUTE_NOTATION) {
+	doc = cur->doc;
+	if (cur->elem == NULL) {
+	    xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
+		   "xmlValidateAttributeCallback(%s): internal error\n",
+		   (const char *) cur->name);
+	    return;
+	}
+
+	if (doc != NULL)
+	    elem = xmlGetDtdElementDesc(doc->intSubset, cur->elem);
+	if ((elem == NULL) && (doc != NULL))
+	    elem = xmlGetDtdElementDesc(doc->extSubset, cur->elem);
+	if ((elem == NULL) && (cur->parent != NULL) &&
+	    (cur->parent->type == XML_DTD_NODE))
+	    elem = xmlGetDtdElementDesc((xmlDtdPtr) cur->parent, cur->elem);
+	if (elem == NULL) {
+	    xmlErrValidNode(ctxt, NULL, XML_DTD_UNKNOWN_ELEM,
+		   "attribute %s: could not find decl for element %s\n",
+		   cur->name, cur->elem, NULL);
+	    return;
+	}
+	if (elem->etype == XML_ELEMENT_TYPE_EMPTY) {
+	    xmlErrValidNode(ctxt, NULL, XML_DTD_EMPTY_NOTATION,
+		   "NOTATION attribute %s declared for EMPTY element %s\n",
+		   cur->name, cur->elem, NULL);
+	    ctxt->valid = 0;
+	}
+    }
+}
+
+/**
+ * xmlValidateDtdFinal:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ *
+ * Does the final step for the dtds validation once all the
+ * subsets have been parsed
+ *
+ * basically it does the following checks described by the XML Rec
+ * - check that ENTITY and ENTITIES type attributes default or 
+ *   possible values matches one of the defined entities.
+ * - check that NOTATION type attributes default or 
+ *   possible values matches one of the defined notations.
+ *
+ * returns 1 if valid or 0 if invalid and -1 if not well-formed
+ */
+
+int
+xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
+    xmlDtdPtr dtd;
+    xmlAttributeTablePtr table;
+    xmlEntitiesTablePtr entities;
+
+    if ((doc == NULL) || (ctxt == NULL)) return(0);
+    if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
+	return(0);
+    ctxt->doc = doc;
+    ctxt->valid = 1;
+    dtd = doc->intSubset;
+    if ((dtd != NULL) && (dtd->attributes != NULL)) {
+	table = (xmlAttributeTablePtr) dtd->attributes;
+	xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
+    }
+    if ((dtd != NULL) && (dtd->entities != NULL)) {
+	entities = (xmlEntitiesTablePtr) dtd->entities;
+	xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback,
+		    ctxt);
+    }
+    dtd = doc->extSubset;
+    if ((dtd != NULL) && (dtd->attributes != NULL)) {
+	table = (xmlAttributeTablePtr) dtd->attributes;
+	xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
+    }
+    if ((dtd != NULL) && (dtd->entities != NULL)) {
+	entities = (xmlEntitiesTablePtr) dtd->entities;
+	xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback,
+		    ctxt);
+    }
+    return(ctxt->valid);
+}
+
+/**
+ * xmlValidateDocument:
+ * @ctxt:  the validation context
+ * @doc:  a document instance
+ *
+ * Try to validate the document instance
+ *
+ * basically it does the all the checks described by the XML Rec
+ * i.e. validates the internal and external subset (if present)
+ * and validate the document tree.
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
+    int ret;
+    xmlNodePtr root;
+
+    if (doc == NULL)
+        return(0);
+    if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
+        xmlErrValid(ctxt, XML_DTD_NO_DTD,
+	            "no DTD found!\n", NULL);
+	return(0);
+    }
+    if ((doc->intSubset != NULL) && ((doc->intSubset->SystemID != NULL) ||
+	(doc->intSubset->ExternalID != NULL)) && (doc->extSubset == NULL)) {
+	xmlChar *sysID;
+	if (doc->intSubset->SystemID != NULL) {
+	    sysID = xmlBuildURI(doc->intSubset->SystemID,
+	    		doc->URL);
+	    if (sysID == NULL) {
+	        xmlErrValid(ctxt, XML_DTD_LOAD_ERROR,
+			"Could not build URI for external subset \"%s\"\n",
+			(const char *) doc->intSubset->SystemID);
+		return 0;
+	    }
+	} else
+	    sysID = NULL;
+        doc->extSubset = xmlParseDTD(doc->intSubset->ExternalID,
+			(const xmlChar *)sysID);
+	if (sysID != NULL)
+	    xmlFree(sysID);
+        if (doc->extSubset == NULL) {
+	    if (doc->intSubset->SystemID != NULL) {
+		xmlErrValid(ctxt, XML_DTD_LOAD_ERROR,
+		       "Could not load the external subset \"%s\"\n",
+		       (const char *) doc->intSubset->SystemID);
+	    } else {
+		xmlErrValid(ctxt, XML_DTD_LOAD_ERROR,
+		       "Could not load the external subset \"%s\"\n",
+		       (const char *) doc->intSubset->ExternalID);
+	    }
+	    return(0);
+	}
+    }
+
+    if (doc->ids != NULL) {
+          xmlFreeIDTable(doc->ids);
+          doc->ids = NULL;
+    }
+    if (doc->refs != NULL) {
+          xmlFreeRefTable(doc->refs);
+          doc->refs = NULL;
+    }
+    ret = xmlValidateDtdFinal(ctxt, doc);
+    if (!xmlValidateRoot(ctxt, doc)) return(0);
+
+    root = xmlDocGetRootElement(doc);
+    ret &= xmlValidateElement(ctxt, doc, root);
+    ret &= xmlValidateDocumentFinal(ctxt, doc);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		Routines for dynamic validation editing			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlValidGetPotentialChildren:
+ * @ctree:  an element content tree
+ * @names:  an array to store the list of child names
+ * @len:  a pointer to the number of element in the list
+ * @max:  the size of the array
+ *
+ * Build/extend a list of  potential children allowed by the content tree
+ *
+ * returns the number of element in the list, or -1 in case of error.
+ */
+
+int
+xmlValidGetPotentialChildren(xmlElementContent *ctree,
+                             const xmlChar **names,
+                             int *len, int max) {
+    int i;
+
+    if ((ctree == NULL) || (names == NULL) || (len == NULL))
+        return(-1);
+    if (*len >= max) return(*len);
+
+    switch (ctree->type) {
+	case XML_ELEMENT_CONTENT_PCDATA: 
+	    for (i = 0; i < *len;i++)
+		if (xmlStrEqual(BAD_CAST "#PCDATA", names[i])) return(*len);
+	    names[(*len)++] = BAD_CAST "#PCDATA";
+	    break;
+	case XML_ELEMENT_CONTENT_ELEMENT: 
+	    for (i = 0; i < *len;i++)
+		if (xmlStrEqual(ctree->name, names[i])) return(*len);
+	    names[(*len)++] = ctree->name;
+	    break;
+	case XML_ELEMENT_CONTENT_SEQ: 
+	    xmlValidGetPotentialChildren(ctree->c1, names, len, max);
+	    xmlValidGetPotentialChildren(ctree->c2, names, len, max);
+	    break;
+	case XML_ELEMENT_CONTENT_OR:
+	    xmlValidGetPotentialChildren(ctree->c1, names, len, max);
+	    xmlValidGetPotentialChildren(ctree->c2, names, len, max);
+	    break;
+   }
+   
+   return(*len);
+}
+
+/*
+ * Dummy function to suppress messages while we try out valid elements
+ */
+static void XMLCDECL xmlNoValidityErr(void *ctx ATTRIBUTE_UNUSED,
+                                const char *msg ATTRIBUTE_UNUSED, ...) {
+    return;
+}
+
+/**
+ * xmlValidGetValidElements:
+ * @prev:  an element to insert after
+ * @next:  an element to insert next
+ * @names:  an array to store the list of child names
+ * @max:  the size of the array
+ *
+ * This function returns the list of authorized children to insert
+ * within an existing tree while respecting the validity constraints
+ * forced by the Dtd. The insertion point is defined using @prev and
+ * @next in the following ways:
+ *  to insert before 'node': xmlValidGetValidElements(node->prev, node, ...
+ *  to insert next 'node': xmlValidGetValidElements(node, node->next, ...
+ *  to replace 'node': xmlValidGetValidElements(node->prev, node->next, ...
+ *  to prepend a child to 'node': xmlValidGetValidElements(NULL, node->childs,
+ *  to append a child to 'node': xmlValidGetValidElements(node->last, NULL, ...
+ *
+ * pointers to the element names are inserted at the beginning of the array
+ * and do not need to be freed.
+ *
+ * returns the number of element in the list, or -1 in case of error. If
+ *    the function returns the value @max the caller is invited to grow the
+ *    receiving array and retry.
+ */
+
+int
+xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **names,
+                         int max) {
+    xmlValidCtxt vctxt;
+    int nb_valid_elements = 0;
+    const xmlChar *elements[256];
+    int nb_elements = 0, i;
+    const xmlChar *name;
+    
+    xmlNode *ref_node;
+    xmlNode *parent;
+    xmlNode *test_node;
+    
+    xmlNode *prev_next;
+    xmlNode *next_prev;
+    xmlNode *parent_childs;
+    xmlNode *parent_last;
+    
+    xmlElement *element_desc;
+
+    if (prev == NULL && next == NULL)
+        return(-1);
+
+    if (names == NULL) return(-1);
+    if (max <= 0) return(-1);
+
+    memset(&vctxt, 0, sizeof (xmlValidCtxt));
+    vctxt.error = xmlNoValidityErr;	/* this suppresses err/warn output */
+
+    nb_valid_elements = 0;
+    ref_node = prev ? prev : next;
+    parent = ref_node->parent;
+
+    /*
+     * Retrieves the parent element declaration
+     */
+    element_desc = xmlGetDtdElementDesc(parent->doc->intSubset,
+                                         parent->name);
+    if ((element_desc == NULL) && (parent->doc->extSubset != NULL))
+        element_desc = xmlGetDtdElementDesc(parent->doc->extSubset,
+                                             parent->name);
+    if (element_desc == NULL) return(-1);
+	
+    /*
+     * Do a backup of the current tree structure
+     */
+    prev_next = prev ? prev->next : NULL;
+    next_prev = next ? next->prev : NULL;
+    parent_childs = parent->children;
+    parent_last = parent->last;
+
+    /*
+     * Creates a dummy node and insert it into the tree
+     */    
+    test_node = xmlNewDocNode (ref_node->doc, NULL, BAD_CAST "<!dummy?>", NULL);
+    test_node->parent = parent;
+    test_node->prev = prev;
+    test_node->next = next;
+    name = test_node->name;
+    
+    if (prev) prev->next = test_node;
+    else parent->children = test_node;
+		
+    if (next) next->prev = test_node;
+    else parent->last = test_node;
+
+    /*
+     * Insert each potential child node and check if the parent is
+     * still valid
+     */
+    nb_elements = xmlValidGetPotentialChildren(element_desc->content,
+		       elements, &nb_elements, 256);
+    
+    for (i = 0;i < nb_elements;i++) {
+	test_node->name = elements[i];
+	if (xmlValidateOneElement(&vctxt, parent->doc, parent)) {
+	    int j;
+
+	    for (j = 0; j < nb_valid_elements;j++)
+		if (xmlStrEqual(elements[i], names[j])) break;
+	    names[nb_valid_elements++] = elements[i];
+	    if (nb_valid_elements >= max) break;
+	}
+    }
+
+    /*
+     * Restore the tree structure
+     */
+    if (prev) prev->next = prev_next;
+    if (next) next->prev = next_prev;
+    parent->children = parent_childs;
+    parent->last = parent_last;
+
+    /*
+     * Free up the dummy node
+     */
+    test_node->name = name;
+    xmlFreeNode(test_node);
+
+    return(nb_valid_elements);
+}
+#endif /* LIBXML_VALID_ENABLED */
+
+#define bottom_valid
+#include "elfgcchack.h"
diff --git a/src/win32/Makefile b/src/win32/Makefile
new file mode 100644
index 0000000..e7947cc
--- /dev/null
+++ b/src/win32/Makefile
@@ -0,0 +1,465 @@
+# Makefile for libxml2, specific for Windows, MSVC and NMAKE.
+#
+# Take a look at the beginning and modify the variables to suit your 
+# environment. Having done that, you can do a
+#
+# nmake [all]     to build the libxml and the accompanying utilities.
+# nmake clean     to remove all compiler output files and return to a
+#                 clean state.
+# nmake rebuild   to rebuild everything from scratch. This basically does
+#                 a 'nmake clean' and then a 'nmake all'.
+# nmake install   to install the library and its header files.
+#
+# March 2002, Igor Zlatkovic <igor@zlatkovic.com>
+
+# There should never be a need to modify anything below this line.
+# ----------------------------------------------------------------
+
+AUTOCONF = .\config.msvc
+!include $(AUTOCONF)
+
+# Names of various input and output components.
+XML_NAME = xml2
+XML_BASENAME = lib$(XML_NAME)
+XML_SO = $(XML_BASENAME).dll
+XML_IMP = $(XML_BASENAME).lib
+XML_DEF = $(XML_BASENAME).def
+XML_A = $(XML_BASENAME)_a.lib
+XML_A_DLL = $(XML_BASENAME)_a_dll.lib
+
+# Place where we let the compiler put its output.
+BINDIR = bin.msvc
+XML_INTDIR = int.msvc
+XML_INTDIR_A = int.a.msvc
+XML_INTDIR_A_DLL = int.a.dll.msvc
+UTILS_INTDIR = int.utils.msvc
+
+# The preprocessor and its options.
+CPP = cl.exe /EP
+CPPFLAGS = /nologo /I$(XML_SRCDIR)\include
+!if "$(WITH_THREADS)" != "no"
+CPPFLAGS = $(CPPFLAGS) /D "_REENTRANT"
+!endif
+
+# The compiler and its options.
+CC = cl.exe
+CFLAGS = /nologo /D "WIN32" /D "_WINDOWS" /D "_MBCS" /W1 $(CRUNTIME)
+CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
+!if "$(WITH_THREADS)" != "no"
+CFLAGS = $(CFLAGS) /D "_REENTRANT"
+!endif
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
+CFLAGS = $(CFLAGS) /D "HAVE_WIN32_THREADS" /D "HAVE_COMPILER_TLS"
+!else if "$(WITH_THREADS)" == "native"
+CFLAGS = $(CFLAGS) /D "HAVE_WIN32_THREADS"
+!else if "$(WITH_THREADS)" == "posix"
+CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
+!endif
+!if "$(WITH_ZLIB)" == "1"
+CFLAGS = $(CFLAGS) /D "HAVE_ZLIB_H"
+!endif
+CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
+
+# The linker and its options.
+LD = link.exe
+LDFLAGS = /nologo /VERSION:$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION)
+LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX)
+LIBS =
+!if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
+LIBS = $(LIBS) wsock32.lib ws2_32.lib
+!endif 
+!if "$(WITH_ICONV)" == "1"
+LIBS = $(LIBS) iconv.lib
+!endif 
++!if "$(WITH_ICU)" == "1"
++LIBS = $(LIBS) icu.lib
++!endif
+!if "$(WITH_ZLIB)" == "1"
+LIBS = $(LIBS) zdll.lib
+!endif
+!if "$(WITH_THREADS)" == "posix"
+LIBS = $(LIBS) pthreadVC.lib
+!endif
+!if "$(WITH_MODULES)" == "1"
+LIBS = $(LIBS) kernel32.lib
+!endif
+
+# The archiver and its options.
+AR = lib.exe
+ARFLAGS = /nologo
+
+# Optimisation and debug symbols.
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) /D "_DEBUG" /Od /Z7
+LDFLAGS = $(LDFLAGS) /DEBUG
+!else
+CFLAGS = $(CFLAGS) /D "NDEBUG" /O2 
+LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
+!endif
+
+# Libxml object files.
+XML_OBJS = $(XML_INTDIR)\c14n.obj\
+	$(XML_INTDIR)\catalog.obj\
+	$(XML_INTDIR)\chvalid.obj\
+	$(XML_INTDIR)\debugXML.obj\
+	$(XML_INTDIR)\dict.obj\
+	$(XML_INTDIR)\DOCBparser.obj\
+	$(XML_INTDIR)\encoding.obj\
+	$(XML_INTDIR)\entities.obj\
+	$(XML_INTDIR)\error.obj\
+	$(XML_INTDIR)\globals.obj\
+	$(XML_INTDIR)\hash.obj\
+	$(XML_INTDIR)\HTMLparser.obj\
+	$(XML_INTDIR)\HTMLtree.obj\
+	$(XML_INTDIR)\legacy.obj\
+	$(XML_INTDIR)\list.obj\
+	$(XML_INTDIR)\nanoftp.obj\
+	$(XML_INTDIR)\nanohttp.obj\
+	$(XML_INTDIR)\parser.obj\
+	$(XML_INTDIR)\parserInternals.obj\
+	$(XML_INTDIR)\pattern.obj\
+	$(XML_INTDIR)\relaxng.obj\
+	$(XML_INTDIR)\SAX2.obj\
+	$(XML_INTDIR)\SAX.obj\
+	$(XML_INTDIR)\schematron.obj\
+	$(XML_INTDIR)\threads.obj\
+	$(XML_INTDIR)\tree.obj\
+	$(XML_INTDIR)\uri.obj\
+	$(XML_INTDIR)\valid.obj\
+	$(XML_INTDIR)\xinclude.obj\
+	$(XML_INTDIR)\xlink.obj\
+	$(XML_INTDIR)\xmlIO.obj\
+	$(XML_INTDIR)\xmlmemory.obj\
+	$(XML_INTDIR)\xmlreader.obj\
+	$(XML_INTDIR)\xmlregexp.obj\
+	$(XML_INTDIR)\xmlmodule.obj\
+	$(XML_INTDIR)\xmlsave.obj\
+	$(XML_INTDIR)\xmlschemas.obj\
+	$(XML_INTDIR)\xmlschemastypes.obj\
+	$(XML_INTDIR)\xmlunicode.obj\
+	$(XML_INTDIR)\xmlwriter.obj\
+	$(XML_INTDIR)\xpath.obj\
+	$(XML_INTDIR)\xpointer.obj\
+	$(XML_INTDIR)\xmlstring.obj
+
+# Static libxml object files.
+XML_OBJS_A = $(XML_INTDIR_A)\c14n.obj\
+	$(XML_INTDIR_A)\catalog.obj\
+	$(XML_INTDIR_A)\chvalid.obj\
+	$(XML_INTDIR_A)\debugXML.obj\
+	$(XML_INTDIR_A)\dict.obj\
+	$(XML_INTDIR_A)\DOCBparser.obj\
+	$(XML_INTDIR_A)\encoding.obj\
+	$(XML_INTDIR_A)\entities.obj\
+	$(XML_INTDIR_A)\error.obj\
+	$(XML_INTDIR_A)\globals.obj\
+	$(XML_INTDIR_A)\hash.obj\
+	$(XML_INTDIR_A)\HTMLparser.obj\
+	$(XML_INTDIR_A)\HTMLtree.obj\
+	$(XML_INTDIR_A)\legacy.obj\
+	$(XML_INTDIR_A)\list.obj\
+	$(XML_INTDIR_A)\nanoftp.obj\
+	$(XML_INTDIR_A)\nanohttp.obj\
+	$(XML_INTDIR_A)\parser.obj\
+	$(XML_INTDIR_A)\parserInternals.obj\
+	$(XML_INTDIR_A)\pattern.obj\
+	$(XML_INTDIR_A)\relaxng.obj\
+	$(XML_INTDIR_A)\SAX2.obj\
+	$(XML_INTDIR_A)\SAX.obj\
+	$(XML_INTDIR_A)\schematron.obj\
+	$(XML_INTDIR_A)\threads.obj\
+	$(XML_INTDIR_A)\tree.obj\
+	$(XML_INTDIR_A)\uri.obj\
+	$(XML_INTDIR_A)\valid.obj\
+	$(XML_INTDIR_A)\xinclude.obj\
+	$(XML_INTDIR_A)\xlink.obj\
+	$(XML_INTDIR_A)\xmlIO.obj\
+	$(XML_INTDIR_A)\xmlmemory.obj\
+	$(XML_INTDIR_A)\xmlreader.obj\
+	$(XML_INTDIR_A)\xmlregexp.obj\
+	$(XML_INTDIR_A)\xmlmodule.obj\
+	$(XML_INTDIR_A)\xmlsave.obj\
+	$(XML_INTDIR_A)\xmlschemas.obj\
+	$(XML_INTDIR_A)\xmlschemastypes.obj\
+	$(XML_INTDIR_A)\xmlunicode.obj\
+	$(XML_INTDIR_A)\xmlwriter.obj\
+	$(XML_INTDIR_A)\xpath.obj\
+	$(XML_INTDIR_A)\xpointer.obj\
+	$(XML_INTDIR_A)\xmlstring.obj
+
+# Static libxml object files.
+XML_OBJS_A_DLL = $(XML_INTDIR_A_DLL)\c14n.obj\
+	$(XML_INTDIR_A_DLL)\catalog.obj\
+	$(XML_INTDIR_A_DLL)\chvalid.obj\
+	$(XML_INTDIR_A_DLL)\debugXML.obj\
+	$(XML_INTDIR_A_DLL)\dict.obj\
+	$(XML_INTDIR_A_DLL)\DOCBparser.obj\
+	$(XML_INTDIR_A_DLL)\encoding.obj\
+	$(XML_INTDIR_A_DLL)\entities.obj\
+	$(XML_INTDIR_A_DLL)\error.obj\
+	$(XML_INTDIR_A_DLL)\globals.obj\
+	$(XML_INTDIR_A_DLL)\hash.obj\
+	$(XML_INTDIR_A_DLL)\HTMLparser.obj\
+	$(XML_INTDIR_A_DLL)\HTMLtree.obj\
+	$(XML_INTDIR_A_DLL)\legacy.obj\
+	$(XML_INTDIR_A_DLL)\list.obj\
+	$(XML_INTDIR_A_DLL)\nanoftp.obj\
+	$(XML_INTDIR_A_DLL)\nanohttp.obj\
+	$(XML_INTDIR_A_DLL)\parser.obj\
+	$(XML_INTDIR_A_DLL)\parserInternals.obj\
+	$(XML_INTDIR_A_DLL)\pattern.obj\
+	$(XML_INTDIR_A_DLL)\relaxng.obj\
+	$(XML_INTDIR_A_DLL)\SAX2.obj\
+	$(XML_INTDIR_A_DLL)\SAX.obj\
+	$(XML_INTDIR_A_DLL)\schematron.obj\
+	$(XML_INTDIR_A_DLL)\threads.obj\
+	$(XML_INTDIR_A_DLL)\tree.obj\
+	$(XML_INTDIR_A_DLL)\uri.obj\
+	$(XML_INTDIR_A_DLL)\valid.obj\
+	$(XML_INTDIR_A_DLL)\xinclude.obj\
+	$(XML_INTDIR_A_DLL)\xlink.obj\
+	$(XML_INTDIR_A_DLL)\xmlIO.obj\
+	$(XML_INTDIR_A_DLL)\xmlmemory.obj\
+	$(XML_INTDIR_A_DLL)\xmlreader.obj\
+	$(XML_INTDIR_A_DLL)\xmlregexp.obj\
+	$(XML_INTDIR_A_DLL)\xmlmodule.obj\
+	$(XML_INTDIR_A_DLL)\xmlsave.obj\
+	$(XML_INTDIR_A_DLL)\xmlschemas.obj\
+	$(XML_INTDIR_A_DLL)\xmlschemastypes.obj\
+	$(XML_INTDIR_A_DLL)\xmlunicode.obj\
+	$(XML_INTDIR_A_DLL)\xmlwriter.obj\
+	$(XML_INTDIR_A_DLL)\xpath.obj\
+	$(XML_INTDIR_A_DLL)\xpointer.obj\
+	$(XML_INTDIR_A_DLL)\xmlstring.obj
+
+# Xmllint and friends executables.
+UTILS = $(BINDIR)\xmllint.exe\
+	$(BINDIR)\xmlcatalog.exe\
+	$(BINDIR)\testAutomata.exe\
+	$(BINDIR)\testC14N.exe\
+	$(BINDIR)\testDocbook.exe\
+	$(BINDIR)\testHTML.exe\
+	$(BINDIR)\testReader.exe\
+	$(BINDIR)\testRelax.exe\
+	$(BINDIR)\testRegexp.exe\
+	$(BINDIR)\testModule.exe\
+	$(BINDIR)\testSAX.exe\
+	$(BINDIR)\testSchemas.exe\
+	$(BINDIR)\testURI.exe\
+	$(BINDIR)\testXPath.exe\
+	$(BINDIR)\runtest.exe\
+	$(BINDIR)\runsuite.exe\
+	$(BINDIR)\testapi.exe
+	
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls" || "$(WITH_THREADS)" == "native"
+UTILS = $(UTILS) $(BINDIR)\testThreadsWin32.exe
+!else if "$(WITH_THREADS)" == "posix"
+UTILS = $(UTILS) $(BINDIR)\testThreads.exe
+!endif
+
+!if "$(VCMANIFEST)" == "1"
+_VC_MANIFEST_EMBED_EXE= if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL= if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;2
+!else
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+!endif
+
+all : libxml libxmla libxmladll utils
+
+libxml : $(BINDIR)\$(XML_SO) 
+
+libxmla : $(BINDIR)\$(XML_A)
+
+libxmladll : $(BINDIR)\$(XML_A_DLL)
+
+utils : $(UTILS)
+
+clean :
+	if exist $(XML_INTDIR) rmdir /S /Q $(XML_INTDIR)
+	if exist $(XML_INTDIR_A) rmdir /S /Q $(XML_INTDIR_A)
+	if exist $(XML_INTDIR_A_DLL) rmdir /S /Q $(XML_INTDIR_A_DLL)
+	if exist $(UTILS_INTDIR) rmdir /S /Q $(UTILS_INTDIR)
+	if exist $(BINDIR) rmdir /S /Q $(BINDIR)
+
+distclean : clean
+	if exist config.* del config.*
+	if exist Makefile del Makefile
+
+rebuild : clean all
+
+install-libs : all
+	if not exist $(INCPREFIX)\libxml mkdir $(INCPREFIX)\libxml
+	if not exist $(BINPREFIX) mkdir $(BINPREFIX)
+	if not exist $(LIBPREFIX) mkdir $(LIBPREFIX)
+	if not exist $(SOPREFIX) mkdir $(SOPREFIX)
+	copy $(XML_SRCDIR)\include\libxml\*.h $(INCPREFIX)\libxml
+	copy $(BINDIR)\$(XML_SO) $(SOPREFIX)
+	copy $(BINDIR)\$(XML_A) $(LIBPREFIX)
+	copy $(BINDIR)\$(XML_A_DLL) $(LIBPREFIX)
+	copy $(BINDIR)\$(XML_IMP) $(LIBPREFIX)
+
+install : install-libs 
+	copy $(BINDIR)\*.exe $(BINPREFIX)
+	-copy $(BINDIR)\*.pdb $(BINPREFIX)
+
+install-dist : install-libs 
+	copy $(BINDIR)\xml*.exe $(BINPREFIX)
+	-copy $(BINDIR)\xml*.pdb $(BINPREFIX)
+
+# This is a target for me, to make a binary distribution. Not for the public use,
+# keep your hands off :-)
+BDVERSION = $(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION).$(LIBXML_MICRO_VERSION)
+BDPREFIX = $(XML_BASENAME)-$(BDVERSION).win32
+bindist : all
+	$(MAKE) /nologo PREFIX=$(BDPREFIX) SOPREFIX=$(BDPREFIX)\bin install-dist
+	cscript //NoLogo configure.js genreadme $(XML_BASENAME) $(BDVERSION) $(BDPREFIX)\readme.txt
+
+
+# Makes the output directory.
+$(BINDIR) :
+	if not exist $(BINDIR) mkdir $(BINDIR)
+
+
+# Makes the libxml intermediate directory.
+$(XML_INTDIR) :
+	if not exist $(XML_INTDIR) mkdir $(XML_INTDIR)
+
+# Makes the static libxml intermediate directory.
+$(XML_INTDIR_A) :
+	if not exist $(XML_INTDIR_A) mkdir $(XML_INTDIR_A)
+
+# Makes the static for dll libxml intermediate directory.
+$(XML_INTDIR_A_DLL) :
+	if not exist $(XML_INTDIR_A_DLL) mkdir $(XML_INTDIR_A_DLL)
+
+# An implicit rule for libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR)}.obj::
+	$(CC) $(CFLAGS) /Fo$(XML_INTDIR)\ /c $<
+
+# An implicit rule for static libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR_A)}.obj::
+	$(CC) $(CFLAGS) /D "LIBXML_STATIC" /Fo$(XML_INTDIR_A)\ /c $<
+
+# An implicit rule for static for dll libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR_A_DLL)}.obj::
+	$(CC) $(CFLAGS) /D "LIBXML_STATIC" /D "LIBXML_STATIC_FOR_DLL" /Fo$(XML_INTDIR_A_DLL)\ /c $<
+
+# Compiles libxml source. Uses the implicit rule for commands.
+$(XML_OBJS) : $(XML_INTDIR) 
+
+# Compiles static libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A) : $(XML_INTDIR_A) 
+
+# Compiles static for dll libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A_DLL) : $(XML_INTDIR_A_DLL) 
+
+# Creates the export definition file (DEF) for libxml.
+$(XML_INTDIR)\$(XML_DEF) : $(XML_INTDIR) $(XML_DEF).src
+	$(CPP) $(CPPFLAGS) $(XML_DEF).src > $(XML_INTDIR)\$(XML_DEF)
+
+# Creates the libxml shared object.
+$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF)
+	$(LD) $(LDFLAGS) /DLL \
+		/IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(LIBS)
+	@$(_VC_MANIFEST_EMBED_DLL)
+
+#$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF)
+#	$(LD) $(LDFLAGS) /DLL /DEF:$(XML_INTDIR)\$(XML_DEF) \
+#		/IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(LIBS)
+
+# Creates the libxml archive.
+$(BINDIR)\$(XML_A) : $(BINDIR) $(XML_OBJS_A)
+	$(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XML_A) $(XML_OBJS_A)
+
+# Creates the libxml static for dll archive.
+$(BINDIR)\$(XML_A_DLL) : $(BINDIR) $(XML_OBJS_A_DLL)
+	$(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XML_A_DLL) $(XML_OBJS_A_DLL)
+
+# Makes the utils intermediate directory.
+$(UTILS_INTDIR) :
+	if not exist $(UTILS_INTDIR) mkdir $(UTILS_INTDIR)
+
+# An implicit rule for xmllint and friends.
+!if "$(STATIC)" == "1"
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) /D "LIBXML_STATIC" $(CFLAGS) /Fo$(UTILS_INTDIR)\ /c $< 
+	$(LD) $(LDFLAGS) /OUT:$@ $(XML_A) $(LIBS) $(UTILS_INTDIR)\$(<B).obj
+	@$(_VC_MANIFEST_EMBED_EXE)
+!else
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) $(CFLAGS) /Fo$(UTILS_INTDIR)\ /c $< 
+	$(LD) $(LDFLAGS) /OUT:$@ $(XML_IMP) $(LIBS) $(UTILS_INTDIR)\$(<B).obj
+	@$(_VC_MANIFEST_EMBED_EXE)
+!endif
+
+# Builds xmllint and friends. Uses the implicit rule for commands.
+$(UTILS) : $(UTILS_INTDIR) $(BINDIR) libxml libxmla libxmladll
+
+# Source dependences should be autogenerated somehow here, but how to
+# do it? I have no clue.
+
+# TESTS
+
+tests :  XPathtests
+
+XPathtests : $(BINDIR)\testXPath.exe
+	@echo. 2> .memdump
+	@echo ## XPath regression tests
+	@-$(BINDIR)\testXPath.exe | find /C "support not compiled in" 1>nul
+	@if %ERRORLEVEL% NEQ 0 @( \
+		echo Skipping debug not compiled in\
+		@exit 0 \
+	)
+	@for %%I in ($(XML_SRCDIR)\test\XPath\expr\*.*) do @( \
+		@IF NOT EXIST $(XML_SRCDIR)\result\XPath\expr\%%~nxI ( \
+			@echo New test %%~nxI &&\
+			@echo %%~nxI &&\
+			$(BINDIR)\testXPath.exe -f --expr %%I > $(XML_SRCDIR)/result/XPath/expr/%%~nxI &&\
+			findstr /C:"MEMORY ALLOCATED : 0" \
+		) ELSE ( \
+			$(BINDIR)\testXPath.exe -f --expr %%I 2>&1 > result.%%~nxI &&\
+			fc $(XML_SRCDIR)\result\XPath\expr\%%~nxI result.%%~nxI >nul &\
+			iF ERRORLEVEL 1 exit 1 & \
+			findstr "MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" >nul &&\
+			del result.%%~nxI \
+		) \
+	)
+	@for %%I in ($(XML_SRCDIR)\test\XPath\docs\*.*) do @( \
+		for %%J in ($(XML_SRCDIR)\test\XPath\tests\%%~nxI*.*) do @( \
+			if not exist $(XML_SRCDIR)\result\XPath\tests\%%~nxJ ( \
+				$(BINDIR)\testXPath.exe -f -i %%I %%J > $(XML_SRCDIR)\result\XPath\tests\%%~nxJ &&\
+				findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > nul \
+			) ELSE ( \
+				$(BINDIR)\testXPAth.exe -f -i %%I %%J 2>&1 > result.%%~nxJ &&\
+				findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0">null &&\
+				fc $(XML_SRCDIR)\result\XPath\tests\%%~nxJ result.%%~nxJ >null & \
+				IF ERRORLEVEL 1 (echo Error: %%I %%J & exit 1) & \
+				del result.%%~nxJ \
+			)\
+		)\
+	)
+
+XMLtests : $(BINDIR)\xmllint.exe
+	@echo. 2> .memdump
+	@echo ## XML regression tests
+	-@for %%I in ($(XML_SRCDIR)\test\*) do @( \
+		if not exist $(XML_SRCDIR)\result\%%~nxI ( \
+			echo New test file %%~nxI &\
+			$(BINDIR)\xmllint.exe  %%I > $(XML_SRCDIR)\result\%%~nxI && \
+			findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > null \
+		) ELSE ( \
+			$(BINDIR)\xmllint.exe %%I 2>&1 > result.%%~nxI && \
+			findstr /C:"MEMORY ALLOC" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > null && \
+			fc $(XML_SRCDIR)\result\%%~nxI result.%%~nxI > null && \
+			$(BINDIR)\xmllint.exe result.%%~nxI 2>&1 > result2.%%~nxI | findstr /V /C:"failed to load external entity" && \
+			fc result.%%~nxI result2.%%~nxI & \
+			del result.%%~nxI result2.%%~nxI\
+		) \
+	)	
+
+				
+
+
+
+	
diff --git a/src/win32/Makefile.bcb b/src/win32/Makefile.bcb
new file mode 100644
index 0000000..0bc4dbb
--- /dev/null
+++ b/src/win32/Makefile.bcb
@@ -0,0 +1,345 @@
+# Makefile for libxml2, specific for Windows, BCB6 and Borland make.
+#
+# Take a look at the beginning and modify the variables to suit your 
+# environment. Having done that, you can do a
+#
+# make [all]     to build the libxml and the accompanying utilities.
+# make clean     to remove all compiler output files and return to a
+#                 clean state.
+# make rebuild   to rebuild everything from scratch. This basically does
+#                 a 'nmake clean' and then a 'nmake all'.
+# make install   to install the library and its header files.
+#
+# August 2003, Eric Zurcher <Eric.Zurcher@csiro.au>
+# based on the MSVC version of
+# March 2002, Igor Zlatkovic <igor@zlatkovic.com>
+#
+
+# There should never be a need to modify anything below this line.
+# ----------------------------------------------------------------
+
+AUTOCONF = .\config.bcb
+!include $(AUTOCONF)
+
+!if !$d(BCB)
+BCB = $(MAKEDIR)\..
+!endif
+.autodepend
+
+# Names of various input and output components.
+XML_NAME = xml2
+XML_BASENAME = lib$(XML_NAME)
+XML_SO = $(XML_BASENAME).dll
+XML_IMP = $(XML_BASENAME).lib
+XML_DEF = $(XML_BASENAME).def
+XML_A = $(XML_BASENAME)_a.lib
+DUMMY = dir.exists
+
+# Place where we let the compiler put its intermediate trash.
+BINDIR = bin.bcb
+XML_INTDIR = int.bcb
+XML_INTDIR_A = int.a.bcb
+UTILS_INTDIR = int.utils.bcb
+
+# The preprocessor and its options.
+CPP = cpp32.exe -P- -DWIN32
+CPPFLAGS = -I"$(XML_SRCDIR)\include"
+!if "$(WITH_THREADS)" != "no"
+CPPFLAGS = $(CPPFLAGS) -D_REENTRANT -D__MT__
+!endif
+
+# The compiler and its options.
+CC = bcc32.exe
+CFLAGS = -q -DWIN32 -D_NO_VCL -D_WINDOWS -D_MBCS -DEILSEQ=2 -w-
+CFLAGS = $(CFLAGS) -I"$(XML_SRCDIR)" -I"$(XML_SRCDIR)\include" -I"$(INCPREFIX)" -I"$(INCLUDE)"
+!if "$(WITH_THREADS)" != "no"
+CFLAGS = $(CFLAGS) -D_REENTRANT -tWM
+!endif
+!if "$(DYNRUNTIME)" == "1"
+CFLAGS = $(CFLAGS) -tWR
+!endif
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
+CFLAGS = $(CFLAGS) -DHAVE_WIN32_THREADS -DHAVE_COMPILER_TLS
+!else if "$(WITH_THREADS)" == "native"
+CFLAGS = $(CFLAGS) -DHAVE_WIN32_THREADS
+!else if "$(WITH_THREADS)" == "posix"
+CFLAGS = $(CFLAGS) -DHAVE_PTHREAD_H
+!endif
+!if "$(WITH_ZLIB)" == "1"
+CFLAGS = $(CFLAGS) -DHAVE_ZLIB_H
+!endif
+
+# The linker and its options.
+LD = ilink32.exe
+LDFLAGS = -q -U$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION)
+LDFLAGS = $(LDFLAGS) -L"$(BINDIR);$(LIBPREFIX);$(LIB);$(BCB)\lib;$(BCB)\lib\PSdk"
+LIBS = import32.lib
+!if "$(WITH_THREADS)" != "no" && "$(DYNRUNTIME)" == "1"
+LIBS = $(LIBS) cw32mti.lib
+!elif "$(WITH_THREADS)" != "no"
+LIBS = $(LIBS) cw32mt.lib
+!elif "$(DYNRUNTIME)" == "1"
+LIBS = $(LIBS) cw32i.lib
+!else
+LIBS = $(LIBS) cw32.lib
+!endif
+!if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
+LIBS = $(LIBS) wsock32.lib ws2_32.lib
+!endif 
+!if "$(WITH_ICONV)" == "1"
+LIBS = $(LIBS) iconvomf.lib
+!endif 
+!if "$(WITH_ZLIB)" == "1"
+LIBS = $(LIBS) zlibomf.lib
+!endif
+!if "$(WITH_THREADS)" == "posix"
+LIBS = $(LIBS) pthreadVC.lib
+!endif
+!if "$(WITH_MODULES)" == "1"
+LIBS = $(LIBS) kernel32.lib
+!endif
+
+# The archiver and its options.
+AR = tlib.exe
+ARFLAGS = /P64 /0
+
+# Optimisation and debug symbols.
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) -D_DEBUG -Od -v
+LDFLAGS = $(LDFLAGS) -v
+!else
+CFLAGS = $(CFLAGS) -DNDEBUG -O2 
+LDFLAGS = $(LDFLAGS)
+!endif
+
+# Libxml object files.
+XML_OBJS = $(XML_INTDIR)\c14n.obj\
+	$(XML_INTDIR)\catalog.obj\
+	$(XML_INTDIR)\chvalid.obj\
+	$(XML_INTDIR)\debugXML.obj\
+	$(XML_INTDIR)\dict.obj\
+	$(XML_INTDIR)\DOCBparser.obj\
+	$(XML_INTDIR)\encoding.obj\
+	$(XML_INTDIR)\entities.obj\
+	$(XML_INTDIR)\error.obj\
+	$(XML_INTDIR)\globals.obj\
+	$(XML_INTDIR)\hash.obj\
+	$(XML_INTDIR)\HTMLparser.obj\
+	$(XML_INTDIR)\HTMLtree.obj\
+	$(XML_INTDIR)\legacy.obj\
+	$(XML_INTDIR)\list.obj\
+	$(XML_INTDIR)\nanoftp.obj\
+	$(XML_INTDIR)\nanohttp.obj\
+	$(XML_INTDIR)\parser.obj\
+	$(XML_INTDIR)\parserInternals.obj\
+	$(XML_INTDIR)\pattern.obj\
+	$(XML_INTDIR)\relaxng.obj\
+	$(XML_INTDIR)\SAX.obj\
+	$(XML_INTDIR)\SAX2.obj\
+	$(XML_INTDIR)\schematron.obj\
+	$(XML_INTDIR)\threads.obj\
+	$(XML_INTDIR)\tree.obj\
+	$(XML_INTDIR)\uri.obj\
+	$(XML_INTDIR)\valid.obj\
+	$(XML_INTDIR)\xinclude.obj\
+	$(XML_INTDIR)\xlink.obj\
+	$(XML_INTDIR)\xmlIO.obj\
+	$(XML_INTDIR)\xmlmemory.obj\
+	$(XML_INTDIR)\xmlreader.obj\
+	$(XML_INTDIR)\xmlregexp.obj\
+	$(XML_INTDIR)\xmlmodule.obj\
+	$(XML_INTDIR)\xmlsave.obj\
+	$(XML_INTDIR)\xmlschemas.obj\
+	$(XML_INTDIR)\xmlschemastypes.obj\
+	$(XML_INTDIR)\xmlunicode.obj\
+	$(XML_INTDIR)\xmlwriter.obj\
+	$(XML_INTDIR)\xpath.obj\
+	$(XML_INTDIR)\xpointer.obj\
+	$(XML_INTDIR)\xmlstring.obj
+
+# Static libxml object files.
+XML_OBJS_A = $(XML_INTDIR_A)\c14n.obj\
+	$(XML_INTDIR_A)\catalog.obj\
+	$(XML_INTDIR_A)\chvalid.obj\
+	$(XML_INTDIR_A)\debugXML.obj\
+	$(XML_INTDIR_A)\dict.obj\
+	$(XML_INTDIR_A)\DOCBparser.obj\
+	$(XML_INTDIR_A)\encoding.obj\
+	$(XML_INTDIR_A)\entities.obj\
+	$(XML_INTDIR_A)\error.obj\
+	$(XML_INTDIR_A)\globals.obj\
+	$(XML_INTDIR_A)\hash.obj\
+	$(XML_INTDIR_A)\HTMLparser.obj\
+	$(XML_INTDIR_A)\HTMLtree.obj\
+	$(XML_INTDIR_A)\legacy.obj\
+	$(XML_INTDIR_A)\list.obj\
+	$(XML_INTDIR_A)\nanoftp.obj\
+	$(XML_INTDIR_A)\nanohttp.obj\
+	$(XML_INTDIR_A)\parser.obj\
+	$(XML_INTDIR_A)\parserInternals.obj\
+	$(XML_INTDIR_A)\pattern.obj\
+	$(XML_INTDIR_A)\relaxng.obj\
+	$(XML_INTDIR_A)\SAX.obj\
+	$(XML_INTDIR_A)\SAX2.obj\
+	$(XML_INTDIR_A)\schematron.obj\
+	$(XML_INTDIR_A)\threads.obj\
+	$(XML_INTDIR_A)\tree.obj\
+	$(XML_INTDIR_A)\uri.obj\
+	$(XML_INTDIR_A)\valid.obj\
+	$(XML_INTDIR_A)\xinclude.obj\
+	$(XML_INTDIR_A)\xlink.obj\
+	$(XML_INTDIR_A)\xmlIO.obj\
+	$(XML_INTDIR_A)\xmlmemory.obj\
+	$(XML_INTDIR_A)\xmlreader.obj\
+	$(XML_INTDIR_A)\xmlregexp.obj\
+	$(XML_INTDIR_A)\xmlmodule.obj\
+	$(XML_INTDIR_A)\xmlsave.obj\
+	$(XML_INTDIR_A)\xmlschemas.obj\
+	$(XML_INTDIR_A)\xmlschemastypes.obj\
+	$(XML_INTDIR_A)\xmlunicode.obj\
+	$(XML_INTDIR_A)\xmlwriter.obj\
+	$(XML_INTDIR_A)\xpath.obj\
+	$(XML_INTDIR_A)\xpointer.obj\
+	$(XML_INTDIR_A)\xmlstring.obj
+
+# Xmllint and friends executables.
+UTILS = $(BINDIR)\xmllint.exe\
+	$(BINDIR)\xmlcatalog.exe\
+	$(BINDIR)\testAutomata.exe\
+	$(BINDIR)\testC14N.exe\
+	$(BINDIR)\testDocbook.exe\
+	$(BINDIR)\testHTML.exe\
+	$(BINDIR)\testReader.exe\
+	$(BINDIR)\testRelax.exe\
+	$(BINDIR)\testRegexp.exe\
+	$(BINDIR)\testModule.exe\
+	$(BINDIR)\testSAX.exe\
+	$(BINDIR)\testSchemas.exe\
+	$(BINDIR)\testURI.exe\
+	$(BINDIR)\testXPath.exe\
+	$(BINDIR)\runtest.exe\
+	$(BINDIR)\runsuite.exe\
+	$(BINDIR)\testapi.exe
+
+
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls" || "$(WITH_THREADS)" == "native"
+UTILS = $(UTILS) $(BINDIR)\testThreadsWin32.exe
+!else if "$(WITH_THREADS)" == "posix"
+UTILS = $(UTILS) $(BINDIR)\testThreads.exe
+!endif
+
+
+all : libxml libxmla utils
+
+libxml : $(BINDIR)\$(XML_SO) 
+
+libxmla : $(BINDIR)\$(XML_A)
+
+utils : $(UTILS)
+
+clean :
+	if exist $(XML_INTDIR) rmdir /S /Q $(XML_INTDIR)
+	if exist $(XML_INTDIR_A) rmdir /S /Q $(XML_INTDIR_A)
+	if exist $(UTILS_INTDIR) rmdir /S /Q $(UTILS_INTDIR)
+	if exist $(BINDIR) rmdir /S /Q $(BINDIR)
+
+distclean : clean
+	if exist config.* del config.*
+	if exist Makefile del Makefile
+
+rebuild : clean all
+
+install-libs : all
+	if not exist "$(INCPREFIX)\libxml" mkdir "$(INCPREFIX)\libxml"
+	if not exist "$(BINPREFIX)" mkdir "$(BINPREFIX)"
+	if not exist "$(LIBPREFIX)" mkdir "$(LIBPREFIX)"
+	copy $(XML_SRCDIR)\include\libxml\*.h "$(INCPREFIX)\libxml"
+	copy $(BINDIR)\$(XML_SO) "$(SOPREFIX)"
+	copy $(BINDIR)\$(XML_A) "$(LIBPREFIX)"
+	copy $(BINDIR)\$(XML_IMP) "$(LIBPREFIX)"
+	copy $(BINDIR)\*.exe "$(BINPREFIX)"
+
+install : install-libs
+	copy $(BINDIR)\*.exe "$(BINPREFIX)"
+
+install-dist : install-libs
+	copy $(BINDIR)\xml*.exe "$(BINPREFIX)"
+
+# This is a target for me, to make a binary distribution. Not for the public use,
+# keep your hands off :-)
+BDVERSION = $(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION).$(LIBXML_MICRO_VERSION)
+BDPREFIX = $(XML_BASENAME)-$(BDVERSION).win32
+bindist : all
+	$(MAKE) /nologo PREFIX=$(BDPREFIX) SOPREFIX=$(BDPREFIX)\bin install-dist
+	cscript //NoLogo configure.js genreadme $(XML_BASENAME) $(BDVERSION) $(BDPREFIX)\readme.txt
+
+
+# Makes the output directory.
+$(BINDIR)\$(DUMMY) :
+	if not exist $(BINDIR) mkdir $(BINDIR)
+	touch $(BINDIR)\$(DUMMY)
+
+# Makes the libxml intermediate directory.
+$(XML_INTDIR)\$(DUMMY) :
+	if not exist $(XML_INTDIR) mkdir $(XML_INTDIR)
+	touch $(XML_INTDIR)\$(DUMMY)
+
+# Makes the static libxml intermediate directory.
+$(XML_INTDIR_A)\$(DUMMY) :
+	if not exist $(XML_INTDIR_A) mkdir $(XML_INTDIR_A)
+	touch $(XML_INTDIR_A)\$(DUMMY)
+
+# An implicit rule for libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR)}.obj:
+	$(CC) $(CFLAGS) -n$(XML_INTDIR) -c $<
+
+# An implicit rule for static libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR_A)}.obj:
+	$(CC) $(CFLAGS) -DLIBXML_STATIC -n$(XML_INTDIR_A)\ -c $<
+
+# Compiles libxml source. Uses the implicit rule for commands.
+$(XML_OBJS) : $(XML_INTDIR)\$(DUMMY)
+
+# Compiles static libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A) : $(XML_INTDIR_A)\$(DUMMY) 
+
+#def4bcb.exe : def4bcb.c
+
+# Creates the export definition file (DEF) for libxml.
+#$(XML_INTDIR)\$(XML_DEF) : $(XML_INTDIR)\$(DUMMY) $(XML_DEF).src def4bcb.exe
+#	$(CPP) $(CPPFLAGS) -o $(XML_INTDIR)\$(XML_DEF).tmp $(XML_DEF).src
+#	def4bcb -msnames < $(XML_INTDIR)\$(XML_DEF).tmp > $(XML_INTDIR)\$(XML_DEF)
+
+# Creates the libxml shared object.
+$(BINDIR)\$(XML_SO) : $(BINDIR)\$(DUMMY) $(XML_OBJS)
+	$(LD) $(LDFLAGS) -Tpd -Gi c0d32.obj $(XML_OBJS),$(BINDIR)\$(XML_SO),,$(LIBS)
+
+#$(BINDIR)\$(XML_SO) : $(BINDIR)\$(DUMMY) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF)
+#	$(LD) $(LDFLAGS) -Tpd -Gi c0d32.obj $(XML_OBJS),$(BINDIR)\$(XML_SO),,$(LIBS),$(XML_INTDIR)\$(XML_DEF)
+
+# Creates the libxml archive.
+$(BINDIR)\$(XML_A) : $(BINDIR)\$(DUMMY) $(XML_OBJS_A)
+	$(AR) $(BINDIR)\$(XML_A) $(ARFLAGS) /u $(XML_OBJS_A)
+
+# Makes the utils intermediate directory.
+$(UTILS_INTDIR)\$(DUMMY) :
+	if not exist $(UTILS_INTDIR) mkdir $(UTILS_INTDIR)
+	touch $(UTILS_INTDIR)\$(DUMMY)
+
+# An implicit rule for xmllint and friends.
+!if "$(STATIC)" == "1"
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) -DLIBXML_STATIC -w -tWC $(CFLAGS) -o$(UTILS_INTDIR)\$&.obj -c $< 
+	$(LD) $(LDFLAGS) c0x32.obj $(UTILS_INTDIR)\$&.obj,$@,,$(LIBS) $(XML_A)
+!else
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) $(CFLAGS) -tWC -o$(UTILS_INTDIR)\$&.obj -c $< 
+	$(LD) $(LDFLAGS) c0x32.obj $(UTILS_INTDIR)\$&.obj $(XML_IMP),$@,,$(LIBS) 
+!endif
+
+# Builds xmllint and friends. Uses the implicit rule for commands.
+$(UTILS) : $(UTILS_INTDIR)\$(DUMMY) $(BINDIR)\$(DUMMY) $(BINDIR)\$(XML_SO) $(BINDIR)\$(XML_A)
+
+# Source dependences should be autogenerated somehow here, but how to
+# do it? I have no clue.
+
diff --git a/src/win32/Makefile.mingw b/src/win32/Makefile.mingw
new file mode 100644
index 0000000..e79970e
--- /dev/null
+++ b/src/win32/Makefile.mingw
@@ -0,0 +1,340 @@
+# Makefile for libxml2, specific for Windows, GCC (mingw) and GNU make.
+#
+# Take a look at the beginning and modify the variables to suit your 
+# environment. Having done that, you can do a
+#
+# nmake [all]     to build the libxml and the accompanying utilities.
+# nmake clean     to remove all compiler output files and return to a
+#                 clean state.
+# nmake rebuild   to rebuild everything from scratch. This basically does
+#                 a 'nmake clean' and then a 'nmake all'.
+# nmake install   to install the library and its header files.
+#
+# November 2002, Igor Zlatkovic <igor@zlatkovic.com>
+
+# There should never be a need to modify anything below this line.
+# ----------------------------------------------------------------
+
+AUTOCONF = .\config.mingw
+include $(AUTOCONF)
+
+# Names of various input and output components.
+XML_NAME = xml2
+XML_BASENAME = lib$(XML_NAME)
+XML_SO = $(XML_BASENAME).dll
+XML_IMP = $(XML_BASENAME).lib
+XML_A = $(XML_BASENAME).a
+
+# Place where we let the compiler put its output.
+BINDIR = bin.mingw
+XML_INTDIR = int.mingw
+XML_INTDIR_A = int.a.mingw
+UTILS_INTDIR = int.utils.mingw
+
+# The preprocessor and its options.
+CPP = gcc.exe -E
+CPPFLAGS += -I$(XML_SRCDIR)/include
+ifeq ($(WITH_THREADS),1)
+CPPFLAGS += -D_REENTRANT
+endif
+
+# The compiler and its options.
+CC = gcc.exe
+CFLAGS += -DWIN32 -D_WINDOWS -D_MBCS
+CFLAGS += -I$(XML_SRCDIR) -I$(XML_SRCDIR)/include -I$(INCPREFIX)
+ifneq ($(WITH_THREADS),no)
+CFLAGS += -D_REENTRANT
+endif
+ifeq ($(WITH_THREADS),yes) 
+CFLAGS += -DHAVE_WIN32_THREADS -DHAVE_COMPILER_TLS
+endif
+ifeq ($(WITH_THREADS),ctls)
+CFLAGS += -DHAVE_WIN32_THREADS -DHAVE_COMPILER_TLS
+endif
+ifeq ($(WITH_THREADS),native)
+CFLAGS += -DHAVE_WIN32_THREADS
+endif
+ifeq ($(WITH_THREADS),posix)
+CFLAGS += -DHAVE_PTHREAD_H
+endif
+ifeq ($(WITH_ZLIB),1)
+CFLAGS += -DHAVE_ZLIB_H
+endif
+
+# The linker and its options.
+LD = gcc.exe
+LDFLAGS += -Wl,--major-image-version,$(LIBXML_MAJOR_VERSION)
+LDFLAGS += -Wl,--minor-image-version,$(LIBXML_MINOR_VERSION)
+LDFLAGS += -Wl,-L,$(BINDIR) -Wl,-L,$(LIBPREFIX)
+LIBS = 
+ifeq ($(WITH_FTP),1)
+CFLAGS += -D_WINSOCKAPI_
+LIBS += -lwsock32
+endif 
+ifeq ($(WITH_HTTP),1)
+CFLAGS += -D_WINSOCKAPI_
+LIBS += -lwsock32
+endif 
+ifeq ($(WITH_ICONV),1)
+LIBS += -liconv
+endif 
+ifeq ($(WITH_ZLIB),1)
+LIBS += -lzdll
+endif
+ifeq ($(WITH_THREADS),posix)
+LIBS += -lpthreadGC
+endif
+ifeq ($(WITH_MODULES),1)
+LIBS += -lkernel32
+endif
+
+# The archiver and its options.
+AR = ar.exe
+ARFLAGS = -r
+
+# Optimisation and debug symbols.
+ifeq ($(DEBUG),1)
+CFLAGS += -D_DEBUG -g
+LDFLAGS += 
+else
+CFLAGS += -DNDEBUG -O2 
+LDFLAGS += 
+endif
+
+
+# Libxml object files.
+XML_OBJS = $(XML_INTDIR)/c14n.o\
+	$(XML_INTDIR)/catalog.o\
+	$(XML_INTDIR)/chvalid.o\
+	$(XML_INTDIR)/debugXML.o\
+	$(XML_INTDIR)/dict.o\
+	$(XML_INTDIR)/DOCBparser.o\
+	$(XML_INTDIR)/encoding.o\
+	$(XML_INTDIR)/entities.o\
+	$(XML_INTDIR)/error.o\
+	$(XML_INTDIR)/globals.o\
+	$(XML_INTDIR)/hash.o\
+	$(XML_INTDIR)/HTMLparser.o\
+	$(XML_INTDIR)/HTMLtree.o\
+	$(XML_INTDIR)/legacy.o\
+	$(XML_INTDIR)/list.o\
+	$(XML_INTDIR)/nanoftp.o\
+	$(XML_INTDIR)/nanohttp.o\
+	$(XML_INTDIR)/parser.o\
+	$(XML_INTDIR)/parserInternals.o\
+	$(XML_INTDIR)/pattern.o\
+	$(XML_INTDIR)/relaxng.o\
+	$(XML_INTDIR)/SAX.o\
+	$(XML_INTDIR)/SAX2.o\
+	$(XML_INTDIR)/schematron.o\
+	$(XML_INTDIR)/threads.o\
+	$(XML_INTDIR)/tree.o\
+	$(XML_INTDIR)/uri.o\
+	$(XML_INTDIR)/valid.o\
+	$(XML_INTDIR)/xinclude.o\
+	$(XML_INTDIR)/xlink.o\
+	$(XML_INTDIR)/xmlIO.o\
+	$(XML_INTDIR)/xmlmemory.o\
+	$(XML_INTDIR)/xmlreader.o\
+	$(XML_INTDIR)/xmlregexp.o\
+	$(XML_INTDIR)/xmlmodule.o\
+	$(XML_INTDIR)/xmlsave.o\
+	$(XML_INTDIR)/xmlschemas.o\
+	$(XML_INTDIR)/xmlschemastypes.o\
+	$(XML_INTDIR)/xmlunicode.o\
+	$(XML_INTDIR)/xmlwriter.o\
+	$(XML_INTDIR)/xpath.o\
+	$(XML_INTDIR)/xpointer.o\
+	$(XML_INTDIR)/xmlstring.o
+
+XML_SRCS = $(subst .o,.c,$(subst $(XML_INTDIR)/,$(XML_SRCDIR)/,$(XML_OBJS)))
+
+# Static libxml object files.
+XML_OBJS_A = $(XML_INTDIR_A)/c14n.o\
+	$(XML_INTDIR_A)/catalog.o\
+	$(XML_INTDIR_A)/chvalid.o\
+	$(XML_INTDIR_A)/debugXML.o\
+	$(XML_INTDIR_A)/dict.o\
+	$(XML_INTDIR_A)/DOCBparser.o\
+	$(XML_INTDIR_A)/encoding.o\
+	$(XML_INTDIR_A)/entities.o\
+	$(XML_INTDIR_A)/error.o\
+	$(XML_INTDIR_A)/globals.o\
+	$(XML_INTDIR_A)/hash.o\
+	$(XML_INTDIR_A)/HTMLparser.o\
+	$(XML_INTDIR_A)/HTMLtree.o\
+	$(XML_INTDIR_A)/legacy.o\
+	$(XML_INTDIR_A)/list.o\
+	$(XML_INTDIR_A)/nanoftp.o\
+	$(XML_INTDIR_A)/nanohttp.o\
+	$(XML_INTDIR_A)/parser.o\
+	$(XML_INTDIR_A)/parserInternals.o\
+	$(XML_INTDIR_A)/pattern.o\
+	$(XML_INTDIR_A)/relaxng.o\
+	$(XML_INTDIR_A)/SAX.o\
+	$(XML_INTDIR_A)/SAX2.o\
+	$(XML_INTDIR_A)/schematron.o\
+	$(XML_INTDIR_A)/threads.o\
+	$(XML_INTDIR_A)/tree.o\
+	$(XML_INTDIR_A)/uri.o\
+	$(XML_INTDIR_A)/valid.o\
+	$(XML_INTDIR_A)/xinclude.o\
+	$(XML_INTDIR_A)/xlink.o\
+	$(XML_INTDIR_A)/xmlIO.o\
+	$(XML_INTDIR_A)/xmlmemory.o\
+	$(XML_INTDIR_A)/xmlreader.o\
+	$(XML_INTDIR_A)/xmlregexp.o\
+	$(XML_INTDIR_A)/xmlmodule.o\
+	$(XML_INTDIR_A)/xmlsave.o\
+	$(XML_INTDIR_A)/xmlschemas.o\
+	$(XML_INTDIR_A)/xmlschemastypes.o\
+	$(XML_INTDIR_A)/xmlunicode.o\
+	$(XML_INTDIR_A)/xmlwriter.o\
+	$(XML_INTDIR_A)/xpath.o\
+	$(XML_INTDIR_A)/xpointer.o\
+	$(XML_INTDIR_A)/xmlstring.o
+
+XML_SRCS_A = $(subst .o,.c,$(subst $(XML_INTDIR_A)/,$(XML_SRCDIR)/,$(XML_OBJS_A)))
+
+# Xmllint and friends executables.
+UTILS = $(BINDIR)/xmllint.exe\
+	$(BINDIR)/xmlcatalog.exe\
+	$(BINDIR)/testAutomata.exe\
+	$(BINDIR)/testC14N.exe\
+	$(BINDIR)/testDocbook.exe\
+	$(BINDIR)/testHTML.exe\
+	$(BINDIR)/testReader.exe\
+	$(BINDIR)/testRegexp.exe\
+	$(BINDIR)/testModule.exe\
+	$(BINDIR)/testRelax.exe\
+	$(BINDIR)/testSAX.exe\
+	$(BINDIR)/testSchemas.exe\
+	$(BINDIR)/testURI.exe\
+	$(BINDIR)/testXPath.exe\
+	$(BINDIR)/runtest.exe\
+	$(BINDIR)/runsuite.exe\
+	$(BINDIR)/testapi.exe
+
+ifeq ($(WITH_THREADS),yes)
+UTILS += $(BINDIR)/testThreadsWin32.exe
+endif
+ifeq ($(WITH_THREADS),ctls) 
+UTILS += $(BINDIR)/testThreadsWin32.exe
+endif
+ifeq ($(WITH_THREADS),native)
+UTILS += $(BINDIR)/testThreadsWin32.exe
+endif
+ifeq ($(WITH_THREADS),posix)
+UTILS += $(BINDIR)/testThreads.exe
+endif
+
+all : dep libxml libxmla utils
+
+libxml : $(BINDIR)/$(XML_SO) 
+
+libxmla : $(BINDIR)/$(XML_A)
+
+utils : $(UTILS)
+
+clean :
+	cmd.exe /C "if exist $(XML_INTDIR) rmdir /S /Q $(XML_INTDIR)"
+	cmd.exe /C "if exist $(XML_INTDIR_A) rmdir /S /Q $(XML_INTDIR_A)"
+	cmd.exe /C "if exist $(UTILS_INTDIR) rmdir /S /Q $(UTILS_INTDIR)"
+	cmd.exe /C "if exist $(BINDIR) rmdir /S /Q $(BINDIR)"
+	cmd.exe /C "if exist depends.mingw del depends.mingw"
+
+distclean : clean
+	cmd.exe /C "if exist config.* del config.*"
+	cmd.exe /C "if exist Makefile del Makefile"
+
+rebuild : clean all
+
+install-libs : all
+	cmd.exe /C "if not exist $(INCPREFIX)\libxml mkdir $(INCPREFIX)\libxml"
+	cmd.exe /C "if not exist $(BINPREFIX) mkdir $(BINPREFIX)"
+	cmd.exe /C "if not exist $(LIBPREFIX) mkdir $(LIBPREFIX)"
+	cmd.exe /C "copy $(XML_SRCDIR)\include\libxml\*.h $(INCPREFIX)\libxml"
+	cmd.exe /C "copy $(BINDIR)\$(XML_SO) $(SOPREFIX)"
+	cmd.exe /C "copy $(BINDIR)\$(XML_A) $(LIBPREFIX)"
+	cmd.exe /C "copy $(BINDIR)\$(XML_IMP) $(LIBPREFIX)"
+	cmd.exe /C "copy $(BINDIR)\xml*.exe $(BINPREFIX)"
+
+install : install-libs
+	cmd.exe /C "copy $(BINDIR)\*.exe $(BINPREFIX)"
+
+install-dist : install-libs
+	cmd.exe /C "copy $(BINDIR)\xml*.exe $(BINPREFIX)"
+
+# This is a target for me, to make a binary distribution. Not for the public use,
+# keep your hands off :-)
+BDVERSION = $(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION).$(LIBXML_MICRO_VERSION)
+BDPREFIX = $(XML_BASENAME)-$(BDVERSION).win32
+bindist : all
+	$(MAKE) PREFIX=$(BDPREFIX) SOPREFIX=$(BDPREFIX)/bin install-dist
+	cscript //NoLogo configure.js genreadme $(XML_BASENAME) $(BDVERSION) $(BDPREFIX)\readme.txt
+
+
+# Creates the dependency file
+dep :
+	$(CC) $(CFLAGS) -M $(XML_SRCS) > depends.mingw
+
+
+# Makes the output directory.
+$(BINDIR) :
+	cmd.exe /C if not exist $(BINDIR) mkdir $(BINDIR)
+
+
+# Makes the libxml intermediate directory.
+$(XML_INTDIR) :
+	cmd.exe /C if not exist $(XML_INTDIR) mkdir $(XML_INTDIR)
+
+# Makes the static libxml intermediate directory.
+$(XML_INTDIR_A) :
+	cmd.exe /C if not exist $(XML_INTDIR_A) mkdir $(XML_INTDIR_A)
+
+# An implicit rule for libxml compilation.
+$(XML_INTDIR)/%.o : $(XML_SRCDIR)/%.c
+	$(CC) $(CFLAGS) -o $@ -c $<
+
+# An implicit rule for static libxml compilation.
+$(XML_INTDIR_A)/%.o : $(XML_SRCDIR)/%.c
+	$(CC) $(CFLAGS) -DLIBXML_STATIC -o $@ -c $<
+
+
+# Compiles libxml source. Uses the implicit rule for commands.
+$(XML_OBJS) : $(XML_INTDIR)
+
+# Compiles static libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A) : $(XML_INTDIR_A) 
+
+# Creates the libxml shared object.
+XMLSO_LDFLAGS = $(LDFLAGS) -shared -Wl,--dll -Wl,--out-implib,$(BINDIR)/$(XML_IMP)
+$(BINDIR)/$(XML_SO) : $(BINDIR) $(XML_OBJS)
+	$(LD) $(XMLSO_LDFLAGS) -o $(BINDIR)/$(XML_SO) $(XML_OBJS) $(LIBS)
+
+# Creates the libxml archive.
+$(BINDIR)/$(XML_A) : $(BINDIR) $(XML_OBJS_A)
+	$(AR) $(ARFLAGS) $(BINDIR)\$(XML_A) $(XML_OBJS_A)
+
+
+# Makes the utils intermediate directory.
+$(UTILS_INTDIR) :
+	cmd.exe /C if not exist $(UTILS_INTDIR) mkdir $(UTILS_INTDIR)
+
+# An implicit rule for xmllint and friends.
+ifeq ($(STATIC),1)
+$(BINDIR)/%.exe : $(UTILS_SRCDIR)/%.c
+	$(CC) -DLIBXML_STATIC $(CFLAGS) -o $(subst .c,.o,$(UTILS_INTDIR)/$(<F)) -c $< 
+	$(LD) $(LDFLAGS) -o $@ $(subst .c,.o,$(UTILS_INTDIR)/$(<F)) -l$(XML_BASENAME) $(LIBS) 
+else
+$(BINDIR)/%.exe : $(UTILS_SRCDIR)/%.c
+	$(CC) $(CFLAGS) -o $(subst .c,.o,$(UTILS_INTDIR)/$(<F)) -c $< 
+	$(LD) $(LDFLAGS) -o $@ $(subst .c,.o,$(UTILS_INTDIR)/$(<F)) -l$(XML_BASENAME) $(LIBS) 
+endif
+
+# Builds xmllint and friends. Uses the implicit rule for commands.
+$(UTILS) : $(UTILS_INTDIR) $(BINDIR) libxml libxmla
+
+# Source dependencies
+#-include depends.mingw
+
diff --git a/src/win32/Makefile.msvc b/src/win32/Makefile.msvc
new file mode 100644
index 0000000..253c46e
--- /dev/null
+++ b/src/win32/Makefile.msvc
@@ -0,0 +1,465 @@
+# Makefile for libxml2, specific for Windows, MSVC and NMAKE.
+#
+# Take a look at the beginning and modify the variables to suit your 
+# environment. Having done that, you can do a
+#
+# nmake [all]     to build the libxml and the accompanying utilities.
+# nmake clean     to remove all compiler output files and return to a
+#                 clean state.
+# nmake rebuild   to rebuild everything from scratch. This basically does
+#                 a 'nmake clean' and then a 'nmake all'.
+# nmake install   to install the library and its header files.
+#
+# March 2002, Igor Zlatkovic <igor@zlatkovic.com>
+
+# There should never be a need to modify anything below this line.
+# ----------------------------------------------------------------
+
+AUTOCONF = .\config.msvc
+!include $(AUTOCONF)
+
+# Names of various input and output components.
+XML_NAME = xml2
+XML_BASENAME = lib$(XML_NAME)
+XML_SO = $(XML_BASENAME).dll
+XML_IMP = $(XML_BASENAME).lib
+XML_DEF = $(XML_BASENAME).def
+XML_A = $(XML_BASENAME)_a.lib
+XML_A_DLL = $(XML_BASENAME)_a_dll.lib
+
+# Place where we let the compiler put its output.
+BINDIR = bin.msvc
+XML_INTDIR = int.msvc
+XML_INTDIR_A = int.a.msvc
+XML_INTDIR_A_DLL = int.a.dll.msvc
+UTILS_INTDIR = int.utils.msvc
+
+# The preprocessor and its options.
+CPP = cl.exe /EP
+CPPFLAGS = /nologo /I$(XML_SRCDIR)\include
+!if "$(WITH_THREADS)" != "no"
+CPPFLAGS = $(CPPFLAGS) /D "_REENTRANT"
+!endif
+
+# The compiler and its options.
+CC = cl.exe
+CFLAGS = /nologo /D "WIN32" /D "_WINDOWS" /D "_MBCS" /W1 $(CRUNTIME)
+CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
+!if "$(WITH_THREADS)" != "no"
+CFLAGS = $(CFLAGS) /D "_REENTRANT"
+!endif
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
+CFLAGS = $(CFLAGS) /D "HAVE_WIN32_THREADS" /D "HAVE_COMPILER_TLS"
+!else if "$(WITH_THREADS)" == "native"
+CFLAGS = $(CFLAGS) /D "HAVE_WIN32_THREADS"
+!else if "$(WITH_THREADS)" == "posix"
+CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
+!endif
+!if "$(WITH_ZLIB)" == "1"
+CFLAGS = $(CFLAGS) /D "HAVE_ZLIB_H"
+!endif
+CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
+
+# The linker and its options.
+LD = link.exe
+LDFLAGS = /nologo /VERSION:$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION)
+LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX)
+LIBS =
+!if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
+LIBS = $(LIBS) wsock32.lib ws2_32.lib
+!endif 
+!if "$(WITH_ICONV)" == "1"
+LIBS = $(LIBS) iconv.lib
+!endif 
+!if "$(WITH_ICU)" == "1"
+LIBS = $(LIBS) icu.lib
+!endif
+!if "$(WITH_ZLIB)" == "1"
+LIBS = $(LIBS) zdll.lib
+!endif
+!if "$(WITH_THREADS)" == "posix"
+LIBS = $(LIBS) pthreadVC.lib
+!endif
+!if "$(WITH_MODULES)" == "1"
+LIBS = $(LIBS) kernel32.lib
+!endif
+
+# The archiver and its options.
+AR = lib.exe
+ARFLAGS = /nologo
+
+# Optimisation and debug symbols.
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) /D "_DEBUG" /Od /Z7
+LDFLAGS = $(LDFLAGS) /DEBUG
+!else
+CFLAGS = $(CFLAGS) /D "NDEBUG" /O2 
+LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
+!endif
+
+# Libxml object files.
+XML_OBJS = $(XML_INTDIR)\c14n.obj\
+	$(XML_INTDIR)\catalog.obj\
+	$(XML_INTDIR)\chvalid.obj\
+	$(XML_INTDIR)\debugXML.obj\
+	$(XML_INTDIR)\dict.obj\
+	$(XML_INTDIR)\DOCBparser.obj\
+	$(XML_INTDIR)\encoding.obj\
+	$(XML_INTDIR)\entities.obj\
+	$(XML_INTDIR)\error.obj\
+	$(XML_INTDIR)\globals.obj\
+	$(XML_INTDIR)\hash.obj\
+	$(XML_INTDIR)\HTMLparser.obj\
+	$(XML_INTDIR)\HTMLtree.obj\
+	$(XML_INTDIR)\legacy.obj\
+	$(XML_INTDIR)\list.obj\
+	$(XML_INTDIR)\nanoftp.obj\
+	$(XML_INTDIR)\nanohttp.obj\
+	$(XML_INTDIR)\parser.obj\
+	$(XML_INTDIR)\parserInternals.obj\
+	$(XML_INTDIR)\pattern.obj\
+	$(XML_INTDIR)\relaxng.obj\
+	$(XML_INTDIR)\SAX2.obj\
+	$(XML_INTDIR)\SAX.obj\
+	$(XML_INTDIR)\schematron.obj\
+	$(XML_INTDIR)\threads.obj\
+	$(XML_INTDIR)\tree.obj\
+	$(XML_INTDIR)\uri.obj\
+	$(XML_INTDIR)\valid.obj\
+	$(XML_INTDIR)\xinclude.obj\
+	$(XML_INTDIR)\xlink.obj\
+	$(XML_INTDIR)\xmlIO.obj\
+	$(XML_INTDIR)\xmlmemory.obj\
+	$(XML_INTDIR)\xmlreader.obj\
+	$(XML_INTDIR)\xmlregexp.obj\
+	$(XML_INTDIR)\xmlmodule.obj\
+	$(XML_INTDIR)\xmlsave.obj\
+	$(XML_INTDIR)\xmlschemas.obj\
+	$(XML_INTDIR)\xmlschemastypes.obj\
+	$(XML_INTDIR)\xmlunicode.obj\
+	$(XML_INTDIR)\xmlwriter.obj\
+	$(XML_INTDIR)\xpath.obj\
+	$(XML_INTDIR)\xpointer.obj\
+	$(XML_INTDIR)\xmlstring.obj
+
+# Static libxml object files.
+XML_OBJS_A = $(XML_INTDIR_A)\c14n.obj\
+	$(XML_INTDIR_A)\catalog.obj\
+	$(XML_INTDIR_A)\chvalid.obj\
+	$(XML_INTDIR_A)\debugXML.obj\
+	$(XML_INTDIR_A)\dict.obj\
+	$(XML_INTDIR_A)\DOCBparser.obj\
+	$(XML_INTDIR_A)\encoding.obj\
+	$(XML_INTDIR_A)\entities.obj\
+	$(XML_INTDIR_A)\error.obj\
+	$(XML_INTDIR_A)\globals.obj\
+	$(XML_INTDIR_A)\hash.obj\
+	$(XML_INTDIR_A)\HTMLparser.obj\
+	$(XML_INTDIR_A)\HTMLtree.obj\
+	$(XML_INTDIR_A)\legacy.obj\
+	$(XML_INTDIR_A)\list.obj\
+	$(XML_INTDIR_A)\nanoftp.obj\
+	$(XML_INTDIR_A)\nanohttp.obj\
+	$(XML_INTDIR_A)\parser.obj\
+	$(XML_INTDIR_A)\parserInternals.obj\
+	$(XML_INTDIR_A)\pattern.obj\
+	$(XML_INTDIR_A)\relaxng.obj\
+	$(XML_INTDIR_A)\SAX2.obj\
+	$(XML_INTDIR_A)\SAX.obj\
+	$(XML_INTDIR_A)\schematron.obj\
+	$(XML_INTDIR_A)\threads.obj\
+	$(XML_INTDIR_A)\tree.obj\
+	$(XML_INTDIR_A)\uri.obj\
+	$(XML_INTDIR_A)\valid.obj\
+	$(XML_INTDIR_A)\xinclude.obj\
+	$(XML_INTDIR_A)\xlink.obj\
+	$(XML_INTDIR_A)\xmlIO.obj\
+	$(XML_INTDIR_A)\xmlmemory.obj\
+	$(XML_INTDIR_A)\xmlreader.obj\
+	$(XML_INTDIR_A)\xmlregexp.obj\
+	$(XML_INTDIR_A)\xmlmodule.obj\
+	$(XML_INTDIR_A)\xmlsave.obj\
+	$(XML_INTDIR_A)\xmlschemas.obj\
+	$(XML_INTDIR_A)\xmlschemastypes.obj\
+	$(XML_INTDIR_A)\xmlunicode.obj\
+	$(XML_INTDIR_A)\xmlwriter.obj\
+	$(XML_INTDIR_A)\xpath.obj\
+	$(XML_INTDIR_A)\xpointer.obj\
+	$(XML_INTDIR_A)\xmlstring.obj
+
+# Static libxml object files.
+XML_OBJS_A_DLL = $(XML_INTDIR_A_DLL)\c14n.obj\
+	$(XML_INTDIR_A_DLL)\catalog.obj\
+	$(XML_INTDIR_A_DLL)\chvalid.obj\
+	$(XML_INTDIR_A_DLL)\debugXML.obj\
+	$(XML_INTDIR_A_DLL)\dict.obj\
+	$(XML_INTDIR_A_DLL)\DOCBparser.obj\
+	$(XML_INTDIR_A_DLL)\encoding.obj\
+	$(XML_INTDIR_A_DLL)\entities.obj\
+	$(XML_INTDIR_A_DLL)\error.obj\
+	$(XML_INTDIR_A_DLL)\globals.obj\
+	$(XML_INTDIR_A_DLL)\hash.obj\
+	$(XML_INTDIR_A_DLL)\HTMLparser.obj\
+	$(XML_INTDIR_A_DLL)\HTMLtree.obj\
+	$(XML_INTDIR_A_DLL)\legacy.obj\
+	$(XML_INTDIR_A_DLL)\list.obj\
+	$(XML_INTDIR_A_DLL)\nanoftp.obj\
+	$(XML_INTDIR_A_DLL)\nanohttp.obj\
+	$(XML_INTDIR_A_DLL)\parser.obj\
+	$(XML_INTDIR_A_DLL)\parserInternals.obj\
+	$(XML_INTDIR_A_DLL)\pattern.obj\
+	$(XML_INTDIR_A_DLL)\relaxng.obj\
+	$(XML_INTDIR_A_DLL)\SAX2.obj\
+	$(XML_INTDIR_A_DLL)\SAX.obj\
+	$(XML_INTDIR_A_DLL)\schematron.obj\
+	$(XML_INTDIR_A_DLL)\threads.obj\
+	$(XML_INTDIR_A_DLL)\tree.obj\
+	$(XML_INTDIR_A_DLL)\uri.obj\
+	$(XML_INTDIR_A_DLL)\valid.obj\
+	$(XML_INTDIR_A_DLL)\xinclude.obj\
+	$(XML_INTDIR_A_DLL)\xlink.obj\
+	$(XML_INTDIR_A_DLL)\xmlIO.obj\
+	$(XML_INTDIR_A_DLL)\xmlmemory.obj\
+	$(XML_INTDIR_A_DLL)\xmlreader.obj\
+	$(XML_INTDIR_A_DLL)\xmlregexp.obj\
+	$(XML_INTDIR_A_DLL)\xmlmodule.obj\
+	$(XML_INTDIR_A_DLL)\xmlsave.obj\
+	$(XML_INTDIR_A_DLL)\xmlschemas.obj\
+	$(XML_INTDIR_A_DLL)\xmlschemastypes.obj\
+	$(XML_INTDIR_A_DLL)\xmlunicode.obj\
+	$(XML_INTDIR_A_DLL)\xmlwriter.obj\
+	$(XML_INTDIR_A_DLL)\xpath.obj\
+	$(XML_INTDIR_A_DLL)\xpointer.obj\
+	$(XML_INTDIR_A_DLL)\xmlstring.obj
+
+# Xmllint and friends executables.
+UTILS = $(BINDIR)\xmllint.exe\
+	$(BINDIR)\xmlcatalog.exe\
+	$(BINDIR)\testAutomata.exe\
+	$(BINDIR)\testC14N.exe\
+	$(BINDIR)\testDocbook.exe\
+	$(BINDIR)\testHTML.exe\
+	$(BINDIR)\testReader.exe\
+	$(BINDIR)\testRelax.exe\
+	$(BINDIR)\testRegexp.exe\
+	$(BINDIR)\testModule.exe\
+	$(BINDIR)\testSAX.exe\
+	$(BINDIR)\testSchemas.exe\
+	$(BINDIR)\testURI.exe\
+	$(BINDIR)\testXPath.exe\
+	$(BINDIR)\runtest.exe\
+	$(BINDIR)\runsuite.exe\
+	$(BINDIR)\testapi.exe
+	
+!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls" || "$(WITH_THREADS)" == "native"
+UTILS = $(UTILS) $(BINDIR)\testThreadsWin32.exe
+!else if "$(WITH_THREADS)" == "posix"
+UTILS = $(UTILS) $(BINDIR)\testThreads.exe
+!endif
+
+!if "$(VCMANIFEST)" == "1"
+_VC_MANIFEST_EMBED_EXE= if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL= if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;2
+!else
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+!endif
+
+all : libxml libxmla libxmladll utils
+
+libxml : $(BINDIR)\$(XML_SO) 
+
+libxmla : $(BINDIR)\$(XML_A)
+
+libxmladll : $(BINDIR)\$(XML_A_DLL)
+
+utils : $(UTILS)
+
+clean :
+	if exist $(XML_INTDIR) rmdir /S /Q $(XML_INTDIR)
+	if exist $(XML_INTDIR_A) rmdir /S /Q $(XML_INTDIR_A)
+	if exist $(XML_INTDIR_A_DLL) rmdir /S /Q $(XML_INTDIR_A_DLL)
+	if exist $(UTILS_INTDIR) rmdir /S /Q $(UTILS_INTDIR)
+	if exist $(BINDIR) rmdir /S /Q $(BINDIR)
+
+distclean : clean
+	if exist config.* del config.*
+	if exist Makefile del Makefile
+
+rebuild : clean all
+
+install-libs : all
+	if not exist $(INCPREFIX)\libxml mkdir $(INCPREFIX)\libxml
+	if not exist $(BINPREFIX) mkdir $(BINPREFIX)
+	if not exist $(LIBPREFIX) mkdir $(LIBPREFIX)
+	if not exist $(SOPREFIX) mkdir $(SOPREFIX)
+	copy $(XML_SRCDIR)\include\libxml\*.h $(INCPREFIX)\libxml
+	copy $(BINDIR)\$(XML_SO) $(SOPREFIX)
+	copy $(BINDIR)\$(XML_A) $(LIBPREFIX)
+	copy $(BINDIR)\$(XML_A_DLL) $(LIBPREFIX)
+	copy $(BINDIR)\$(XML_IMP) $(LIBPREFIX)
+
+install : install-libs 
+	copy $(BINDIR)\*.exe $(BINPREFIX)
+	-copy $(BINDIR)\*.pdb $(BINPREFIX)
+
+install-dist : install-libs 
+	copy $(BINDIR)\xml*.exe $(BINPREFIX)
+	-copy $(BINDIR)\xml*.pdb $(BINPREFIX)
+
+# This is a target for me, to make a binary distribution. Not for the public use,
+# keep your hands off :-)
+BDVERSION = $(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION).$(LIBXML_MICRO_VERSION)
+BDPREFIX = $(XML_BASENAME)-$(BDVERSION).win32
+bindist : all
+	$(MAKE) /nologo PREFIX=$(BDPREFIX) SOPREFIX=$(BDPREFIX)\bin install-dist
+	cscript //NoLogo configure.js genreadme $(XML_BASENAME) $(BDVERSION) $(BDPREFIX)\readme.txt
+
+
+# Makes the output directory.
+$(BINDIR) :
+	if not exist $(BINDIR) mkdir $(BINDIR)
+
+
+# Makes the libxml intermediate directory.
+$(XML_INTDIR) :
+	if not exist $(XML_INTDIR) mkdir $(XML_INTDIR)
+
+# Makes the static libxml intermediate directory.
+$(XML_INTDIR_A) :
+	if not exist $(XML_INTDIR_A) mkdir $(XML_INTDIR_A)
+
+# Makes the static for dll libxml intermediate directory.
+$(XML_INTDIR_A_DLL) :
+	if not exist $(XML_INTDIR_A_DLL) mkdir $(XML_INTDIR_A_DLL)
+
+# An implicit rule for libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR)}.obj::
+	$(CC) $(CFLAGS) /Fo$(XML_INTDIR)\ /c $<
+
+# An implicit rule for static libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR_A)}.obj::
+	$(CC) $(CFLAGS) /D "LIBXML_STATIC" /Fo$(XML_INTDIR_A)\ /c $<
+
+# An implicit rule for static for dll libxml compilation.
+{$(XML_SRCDIR)}.c{$(XML_INTDIR_A_DLL)}.obj::
+	$(CC) $(CFLAGS) /D "LIBXML_STATIC" /D "LIBXML_STATIC_FOR_DLL" /Fo$(XML_INTDIR_A_DLL)\ /c $<
+
+# Compiles libxml source. Uses the implicit rule for commands.
+$(XML_OBJS) : $(XML_INTDIR) 
+
+# Compiles static libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A) : $(XML_INTDIR_A) 
+
+# Compiles static for dll libxml source. Uses the implicit rule for commands.
+$(XML_OBJS_A_DLL) : $(XML_INTDIR_A_DLL) 
+
+# Creates the export definition file (DEF) for libxml.
+$(XML_INTDIR)\$(XML_DEF) : $(XML_INTDIR) $(XML_DEF).src
+	$(CPP) $(CPPFLAGS) $(XML_DEF).src > $(XML_INTDIR)\$(XML_DEF)
+
+# Creates the libxml shared object.
+$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF)
+	$(LD) $(LDFLAGS) /DLL \
+		/IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(LIBS)
+	@$(_VC_MANIFEST_EMBED_DLL)
+
+#$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF)
+#	$(LD) $(LDFLAGS) /DLL /DEF:$(XML_INTDIR)\$(XML_DEF) \
+#		/IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(LIBS)
+
+# Creates the libxml archive.
+$(BINDIR)\$(XML_A) : $(BINDIR) $(XML_OBJS_A)
+	$(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XML_A) $(XML_OBJS_A)
+
+# Creates the libxml static for dll archive.
+$(BINDIR)\$(XML_A_DLL) : $(BINDIR) $(XML_OBJS_A_DLL)
+	$(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XML_A_DLL) $(XML_OBJS_A_DLL)
+
+# Makes the utils intermediate directory.
+$(UTILS_INTDIR) :
+	if not exist $(UTILS_INTDIR) mkdir $(UTILS_INTDIR)
+
+# An implicit rule for xmllint and friends.
+!if "$(STATIC)" == "1"
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) /D "LIBXML_STATIC" $(CFLAGS) /Fo$(UTILS_INTDIR)\ /c $< 
+	$(LD) $(LDFLAGS) /OUT:$@ $(XML_A) $(LIBS) $(UTILS_INTDIR)\$(<B).obj
+	@$(_VC_MANIFEST_EMBED_EXE)
+!else
+{$(UTILS_SRCDIR)}.c{$(BINDIR)}.exe:
+	$(CC) $(CFLAGS) /Fo$(UTILS_INTDIR)\ /c $< 
+	$(LD) $(LDFLAGS) /OUT:$@ $(XML_IMP) $(LIBS) $(UTILS_INTDIR)\$(<B).obj
+	@$(_VC_MANIFEST_EMBED_EXE)
+!endif
+
+# Builds xmllint and friends. Uses the implicit rule for commands.
+$(UTILS) : $(UTILS_INTDIR) $(BINDIR) libxml libxmla libxmladll
+
+# Source dependences should be autogenerated somehow here, but how to
+# do it? I have no clue.
+
+# TESTS
+
+tests :  XPathtests
+
+XPathtests : $(BINDIR)\testXPath.exe
+	@echo. 2> .memdump
+	@echo ## XPath regression tests
+	@-$(BINDIR)\testXPath.exe | find /C "support not compiled in" 1>nul
+	@if %ERRORLEVEL% NEQ 0 @( \
+		echo Skipping debug not compiled in\
+		@exit 0 \
+	)
+	@for %%I in ($(XML_SRCDIR)\test\XPath\expr\*.*) do @( \
+		@IF NOT EXIST $(XML_SRCDIR)\result\XPath\expr\%%~nxI ( \
+			@echo New test %%~nxI &&\
+			@echo %%~nxI &&\
+			$(BINDIR)\testXPath.exe -f --expr %%I > $(XML_SRCDIR)/result/XPath/expr/%%~nxI &&\
+			findstr /C:"MEMORY ALLOCATED : 0" \
+		) ELSE ( \
+			$(BINDIR)\testXPath.exe -f --expr %%I 2>&1 > result.%%~nxI &&\
+			fc $(XML_SRCDIR)\result\XPath\expr\%%~nxI result.%%~nxI >nul &\
+			iF ERRORLEVEL 1 exit 1 & \
+			findstr "MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" >nul &&\
+			del result.%%~nxI \
+		) \
+	)
+	@for %%I in ($(XML_SRCDIR)\test\XPath\docs\*.*) do @( \
+		for %%J in ($(XML_SRCDIR)\test\XPath\tests\%%~nxI*.*) do @( \
+			if not exist $(XML_SRCDIR)\result\XPath\tests\%%~nxJ ( \
+				$(BINDIR)\testXPath.exe -f -i %%I %%J > $(XML_SRCDIR)\result\XPath\tests\%%~nxJ &&\
+				findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > nul \
+			) ELSE ( \
+				$(BINDIR)\testXPAth.exe -f -i %%I %%J 2>&1 > result.%%~nxJ &&\
+				findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0">null &&\
+				fc $(XML_SRCDIR)\result\XPath\tests\%%~nxJ result.%%~nxJ >null & \
+				IF ERRORLEVEL 1 (echo Error: %%I %%J & exit 1) & \
+				del result.%%~nxJ \
+			)\
+		)\
+	)
+
+XMLtests : $(BINDIR)\xmllint.exe
+	@echo. 2> .memdump
+	@echo ## XML regression tests
+	-@for %%I in ($(XML_SRCDIR)\test\*) do @( \
+		if not exist $(XML_SRCDIR)\result\%%~nxI ( \
+			echo New test file %%~nxI &\
+			$(BINDIR)\xmllint.exe  %%I > $(XML_SRCDIR)\result\%%~nxI && \
+			findstr /C:"MEMORY ALLOCATED" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > null \
+		) ELSE ( \
+			$(BINDIR)\xmllint.exe %%I 2>&1 > result.%%~nxI && \
+			findstr /C:"MEMORY ALLOC" .memdump | findstr /C:"MEMORY ALLOCATED : 0" > null && \
+			fc $(XML_SRCDIR)\result\%%~nxI result.%%~nxI > null && \
+			$(BINDIR)\xmllint.exe result.%%~nxI 2>&1 > result2.%%~nxI | findstr /V /C:"failed to load external entity" && \
+			fc result.%%~nxI result2.%%~nxI & \
+			del result.%%~nxI result2.%%~nxI\
+		) \
+	)	
+
+				
+
+
+
+	
diff --git a/src/win32/Readme.txt b/src/win32/Readme.txt
new file mode 100644
index 0000000..6b3eddd
--- /dev/null
+++ b/src/win32/Readme.txt
@@ -0,0 +1,226 @@
+
+                             Windows port
+                             ============
+
+This directory contains the files required to build this software on the
+native Windows platform. This is not a place to look for help if you are
+using a POSIX emulator, such as Cygwin. Check the Unix instructions for 
+that.
+
+
+
+CONTENTS
+========
+
+1. General
+   1.1 Building From the Command-Line
+   1.2 Configuring The Source
+   1.3 Compiling
+   1.4 Installing
+
+2. Compiler Specifics
+   2.1 Microsoft Visual C/C++
+   2.1 GNU C/C++, Mingw Edition
+   2.2 Borland C++ Builder
+       2.2.1 Building with iconv support
+	   2.2.2 Compatability problems with MSVC (and probably CYGWIN)
+	   2.2.3 Other caveats
+
+
+
+
+1. General
+==========
+
+
+1.1 Building From The Command-Line
+----------------------------------
+
+This is the easiest, preferred and currently supported method. It can
+be that a subdirectory of the directory where this file resides 
+contains project files for some IDE. If you want to use that, please
+refer to the readme file within that subdirectory.
+
+In order to build from the command-line you need to make sure that
+your compiler works from the command line. This is not always the
+case, often the required environment variables are missing. If you are
+not sure, test if this works first. If it doesn't, you will first have
+to configure your compiler suite to run from the command-line - please
+refer to your compiler's documentation regarding that.
+
+The first thing you want to do is configure the source. You can have
+the configuration script do this automatically for you. The
+configuration script is written in JScript, a Microsoft's
+implementation of the ECMA scripting language. Almost every Windows
+machine can execute this through the Windows Scripting Host. If your
+system lacks the ability to execute JScript for some reason, you must
+perform the configuration manually and you are on your own with that.
+
+The second step is compiling the source and, optionally, installing it
+to the location of your choosing.
+
+
+1.2 Configuring The Source
+--------------------------
+
+The configuration script accepts numerous options. Some of these
+affect features which will be available in the compiled software,
+others affect the way the software is built and installed. To see a
+full list of options supported by the configuration script, run
+
+  cscript configure.js help
+
+from the win32 subdirectory. The configuration script will present you
+the options it accepts and give a biref explanation of these. In every
+case you will have two sets of options. The first set is specific to
+the software you are building and the second one is specific to the
+Windows port.
+
+Once you have decided which options suit you, run the script with that
+options. Here is an example:
+
+  cscript configure.js compiler=msvc prefix=c:\opt 
+    include=c:\opt\include lib=c:\opt\lib debug=yes
+
+The previous example will configure the process to use the Microsoft's
+compiler, install the library in c:\opt, use c:\opt\include and 
+c:\opt\lib as additional search paths for the compiler and the linker 
+and build executables with debug symbols.
+
+Note: Please do not use path names which contain spaces. This will
+fail. Allowing this would require me to put almost everything in the
+Makefile in quotas and that looks quite ugly with my
+syntax-highlighting engine. If you absolutely must use spaces in paths
+send me an email and tell me why. If there are enough of you out there
+who need this, or if a single one has a very good reason, I will
+modify the Makefile to allow spaces in paths.
+
+
+1.3 Compiling
+-------------
+
+After the configuration stage has been completed, you want to build
+the software. You will have to use the make tool which comes with
+your compiler. If you, for example, configured the source to build
+with Microsoft's MSVC compiler, you would use the NMAKE utility. If
+you configured it to build with GNU C compiler, mingw edition, you
+would use the GNU make. Assuming you use MSVC, type
+
+  nmake /f Makefile.msvc
+
+and if you use MinGW, you would type
+
+  make -f Makefile.mingw
+
+and if you use Borland's compiler, you would type
+
+  bmake -f Makefile.bcb
+
+in the win32 subdirectory. When the building completes, you will find
+the executable files in win32\bin.* directory, where * stands for the
+name of the compiler you have used.
+
+
+1.4 Installing
+--------------
+
+You can install the software into the directory you specified to the
+configure script during the configure stage by typing (with MSVC in
+this example)
+
+  nmake /f Makefile.msvc install
+
+That would be it, enjoy.
+
+
+
+
+
+2. Compiler Specifics
+=====================
+
+
+2.1 Microsoft Visual C/C++
+--------------------------
+
+If you use the compiler which comes with Visual Studio .NET, note that
+it will link to its own C-runtime named msvcr70.dll or msvcr71.dll. This 
+file is not available on any machine which doesn't have Visual Studio 
+.NET installed.
+
+
+2.2 GNU C/C++, Mingw edition
+----------------------------
+
+When specifying paths to configure.js, please use slashes instead of 
+backslashes for directory separation. Sometimes Mingw needs this. If
+this is the case, and you specify backslashes, then the compiler will 
+complain about not finding necessary header files.
+
+
+2.2 Borland C++ Builder
+-----------------------
+
+To compile libxml2 with the BCB6 compiler and associated tools, just follow
+the basic instructions found in this file file. Be sure to specify 
+the "compiler=bcb" option when running the configure script. To compile the
+library and test programs, just type
+
+  make -fMakefile.bcb
+
+That should be all that's required. But there are a few other things to note:
+
+2.2.1 Building with iconv support
+
+If you configure libxml2 to include iconv support, you will obviously need to
+obtain the iconv library and include files. To get them, just follow the links 
+at http://www.gnu.org/software/libiconv/ - there are pre-compiled Win32 
+versions available, but note that these where built with MSVC. Hence the 
+supplied import library is in COFF format rather than OMF format. You can 
+convert this library by using Borland's COFF2OMF utility, or use IMPLIB to 
+build a new import library from the DLL. Alternatively, it is possible to
+obtain the iconv source, and build the DLL using the Borland compiler.
+
+There is a minor problem with the header files for iconv - they expect a
+macro named "EILSEQ" in errno.h, but this is not defined in the Borland
+headers, and its absence can cause problems. To circumvent this problem, I
+define EILSEQ=2 in Makefile.bcb. The value "2" is the value for ENOFILE (file
+not found). This should not have any disastrous side effects beyond possibly
+displaying a misleading error message in certain situations.
+
+2.2.2 Compatability problems with MSVC (and probably CYGWIN)
+
+A libxml2 DLL generated by BCB is callable from MSVC programs, but there is a
+minor problem with the names of the symbols exported from the library. The
+Borland compiler, by default, prepends an underscore character to global 
+identifiers (functions and global variables) when generating object files.
+Hence the function "xmlAddChild" is added to the DLL with the name
+"_xmlAddChild". The MSVC compiler does not have this behaviour, and looks for
+the unadorned name. I currently circumvent this problem by writing a .def file
+which causes BOTH the adorned and unadorned names to be exported from the DLL.
+This behaviour may not be supported in the future.
+
+An even worse problem is that of generating an import library for the DLL. The
+Borland-generated DLL is in OMF format. MSVC expects libraries in COFF format,
+but they don't provide a "OMF2COFF" utility, or even the equivalent of
+Borland's IMPLIB utility. But it is possible to create an import lib from the
+.def file, using the command:
+  LIB /DEF:libxml2.def
+
+If you don't have the .def file, it's possible to create one manually. Use
+DUMPBIN /EXPORTS /OUT:libxml2.tmp libxml2.dll to get a list of the exported
+names, and edit this into .def file format.
+
+A similar problem is likely with Cygwin.
+
+2.2.3 Other caveats
+
+We have tested this only with BCB6, Professional Edition, and BCB 5.5 free
+command-line tools.
+
+
+
+Authors: Igor Zlatkovic <igor@zlatkovic.com>
+         Eric Zurcher <Eric.Zurcher@csiro.au>
+
+
diff --git a/src/win32/configure.js b/src/win32/configure.js
new file mode 100644
index 0000000..75def3f
--- /dev/null
+++ b/src/win32/configure.js
@@ -0,0 +1,698 @@
+/* Configure script for libxml, specific for Windows with Scripting Host.
+ * 
+ * This script will configure the libxml build process and create necessary files.
+ * Run it with an 'help', or an invalid option and it will tell you what options
+ * it accepts.
+ *
+ * March 2002, Igor Zlatkovic <igor@zlatkovic.com>
+ */
+
+/* The source directory, relative to the one where this file resides. */
+var srcDirXml = "..";
+var srcDirUtils = "..";
+/* Base name of what we are building. */
+var baseName = "libxml2";
+/* Configure file which contains the version and the output file where
+   we can store our build configuration. */
+var configFile = srcDirXml + "\\configure.in";
+var versionFile = ".\\config.msvc";
+/* Input and output files regarding the libxml features. */
+var optsFileIn = srcDirXml + "\\include\\libxml\\xmlversion.h.in";
+var optsFile = srcDirXml + "\\include\\libxml\\xmlversion.h";
+/* Version strings for the binary distribution. Will be filled later 
+   in the code. */
+var verMajor;
+var verMinor;
+var verMicro;
+var verMicroSuffix;
+var verCvs;
+var useCvsVer = true;
+/* Libxml features. */
+var withTrio = false;
+var withThreads = "native";
+var withFtp = true;
+var withHttp = true;
+var withHtml = true;
+var withC14n = true;
+var withCatalog = true;
+var withDocb = true;
+var withXpath = true;
+var withXptr = true;
+var withXinclude = true;
+var withIconv = true;
+var withIcu = false;
+var withIso8859x = false;
+var withZlib = false;
+var withDebug = true;
+var withMemDebug = false;
+var withRunDebug = false;
+var withSchemas = true;
+var withSchematron = true;
+var withRegExps = true;
+var withModules = true;
+var withTree = true;
+var withReader = true;
+var withWriter = true;
+var withWalker = true;
+var withPattern = true;
+var withPush = true;
+var withValid = true;
+var withSax1 = true;
+var withLegacy = true;
+var withOutput = true;
+var withPython = false;
+/* Win32 build options. */
+var dirSep = "\\";
+var compiler = "msvc";
+var cruntime = "/MD";
+var dynruntime = true;
+var vcmanifest = false;
+var buildDebug = 0;
+var buildStatic = 0;
+var buildPrefix = ".";
+var buildBinPrefix = "";
+var buildIncPrefix = "";
+var buildLibPrefix = "";
+var buildSoPrefix = "";
+var buildInclude = ".";
+var buildLib = ".";
+/* Local stuff */
+var error = 0;
+
+/* Helper function, transforms the option variable into the 'Enabled'
+   or 'Disabled' string. */
+function boolToStr(opt)
+{
+	if (opt == false)
+		return "no";
+	else if (opt == true)
+		return "yes";
+	error = 1;
+	return "*** undefined ***";
+}
+
+/* Helper function, transforms the argument string into a boolean
+   value. */
+function strToBool(opt)
+{
+	if (opt == 0 || opt == "no")
+		return false;
+	else if (opt == 1 || opt == "yes")
+		return true;
+	error = 1;
+	return false;
+}
+
+/* Displays the details about how to use this script. */
+function usage()
+{
+	var txt;
+	txt = "Usage:\n";
+	txt += "  cscript " + WScript.ScriptName + " <options>\n";
+	txt += "  cscript " + WScript.ScriptName + " help\n\n";
+	txt += "Options can be specified in the form <option>=<value>, where the value is\n";
+	txt += "either 'yes' or 'no', if not stated otherwise.\n\n";
+	txt += "\nXML processor options, default value given in parentheses:\n\n";
+	txt += "  trio:       Enable TRIO string manipulator (" + (withTrio? "yes" : "no")  + ")\n";
+	txt += "  threads:    Enable thread safety [no|ctls|native|posix] (" + (withThreads)  + ") \n";
+	txt += "  ftp:        Enable FTP client (" + (withFtp? "yes" : "no")  + ")\n";
+	txt += "  http:       Enable HTTP client (" + (withHttp? "yes" : "no")  + ")\n";
+	txt += "  html:       Enable HTML processor (" + (withHtml? "yes" : "no")  + ")\n";
+	txt += "  c14n:       Enable C14N support (" + (withC14n? "yes" : "no")  + ")\n";
+	txt += "  catalog:    Enable catalog support (" + (withCatalog? "yes" : "no")  + ")\n";
+	txt += "  docb:       Enable DocBook support (" + (withDocb? "yes" : "no")  + ")\n";
+	txt += "  xpath:      Enable XPath support (" + (withXpath? "yes" : "no")  + ")\n";
+	txt += "  xptr:       Enable XPointer support (" + (withXptr? "yes" : "no")  + ")\n";
+	txt += "  xinclude:   Enable XInclude support (" + (withXinclude? "yes" : "no")  + ")\n";
+	txt += "  iconv:      Enable iconv support (" + (withIconv? "yes" : "no")  + ")\n";
+	txt += "  icu:        Enable icu support (" + (withIcu? "yes" : "no")  + ")\n";
+	txt += "  iso8859x:   Enable ISO8859X support (" + (withIso8859x? "yes" : "no")  + ")\n";
+	txt += "  zlib:       Enable zlib support (" + (withZlib? "yes" : "no")  + ")\n";
+	txt += "  xml_debug:  Enable XML debbugging module (" + (withDebug? "yes" : "no")  + ")\n";
+	txt += "  mem_debug:  Enable memory debugger (" + (withMemDebug? "yes" : "no")  + ")\n";
+	txt += "  run_debug:  Enable memory debugger (" + (withRunDebug? "yes" : "no")  + ")\n";
+	txt += "  regexps:    Enable regular expressions (" + (withRegExps? "yes" : "no") + ")\n";
+	txt += "  modules:    Enable module support (" + (withModules? "yes" : "no") + ")\n";
+	txt += "  tree:       Enable tree api (" + (withTree? "yes" : "no") + ")\n";
+	txt += "  reader:     Enable xmlReader api (" + (withReader? "yes" : "no") + ")\n";
+	txt += "  writer:     Enable xmlWriter api (" + (withWriter? "yes" : "no") + ")\n";
+	txt += "  walker:     Enable xmlDocWalker api (" + (withWalker? "yes" : "no") + ")\n";
+	txt += "  pattern:    Enable xmlPattern api (" + (withPattern? "yes" : "no")  + ")\n";
+	txt += "  push:       Enable push api (" + (withPush? "yes" : "no") + ")\n";
+	txt += "  valid:      Enable DTD validation support (" + (withValid? "yes" : "no") + ")\n";
+	txt += "  sax1:       Enable SAX1 api (" + (withSax1? "yes" : "no") + ")\n";
+	txt += "  legacy:     Enable Deprecated api's (" + (withLegacy? "yes" : "no") + ")\n";
+	txt += "  output:     Enable serialization support (" + (withOutput? "yes" : "no") + ")\n";
+	txt += "  schemas:    Enable XML Schema support (" + (withSchemas? "yes" : "no")  + ")\n";
+	txt += "  schematron: Enable Schematron support (" + (withSchematron? "yes" : "no")  + ")\n";
+	txt += "  python:     Build Python bindings (" + (withPython? "yes" : "no")  + ")\n";
+	txt += "\nWin32 build options, default value given in parentheses:\n\n";
+	txt += "  compiler:   Compiler to be used [msvc|mingw|bcb] (" + compiler + ")\n";
+	txt += "  cruntime:   C-runtime compiler option (only msvc) (" + cruntime + ")\n";
+	txt += "  dynruntime: Use the dynamic RTL (only bcb) (" + dynruntime + ")\n";
+	txt += "  vcmanifest: Embed VC manifest (only msvc) (" + (vcmanifest? "yes" : "no") + ")\n";
+	txt += "  debug:      Build unoptimised debug executables (" + (buildDebug? "yes" : "no")  + ")\n";
+	txt += "  static:     Link xmllint statically to libxml2 (" + (buildStatic? "yes" : "no")  + ")\n";
+	txt += "              Note: automatically enabled if cruntime is not /MD or /MDd\n";
+	txt += "  prefix:     Base directory for the installation (" + buildPrefix + ")\n";
+	txt += "  bindir:     Directory where xmllint and friends should be installed\n";
+	txt += "              (" + buildBinPrefix + ")\n";
+	txt += "  incdir:     Directory where headers should be installed\n";
+	txt += "              (" + buildIncPrefix + ")\n";
+	txt += "  libdir:     Directory where static and import libraries should be\n";
+	txt += "              installed (" + buildLibPrefix + ")\n";
+	txt += "  sodir:      Directory where shared libraries should be installed\n"; 
+	txt += "              (" + buildSoPrefix + ")\n";
+	txt += "  include:    Additional search path for the compiler, particularily\n";
+	txt += "              where iconv headers can be found (" + buildInclude + ")\n";
+	txt += "  lib:        Additional search path for the linker, particularily\n";
+	txt += "              where iconv library can be found (" + buildLib + ")\n";
+	WScript.Echo(txt);
+}
+
+/* Discovers the version we are working with by reading the apropriate
+   configuration file. Despite its name, this also writes the configuration
+   file included by our makefile. */
+function discoverVersion()
+{
+	var fso, cf, vf, ln, s, iDot, iSlash;
+	fso = new ActiveXObject("Scripting.FileSystemObject");
+	verCvs = "";
+	if (useCvsVer && fso.FileExists("..\\CVS\\Entries")) {
+		cf = fso.OpenTextFile("..\\CVS\\Entries", 1);
+		while (cf.AtEndOfStream != true) {
+			ln = cf.ReadLine();
+			s = new String(ln);
+			if (s.search(/^\/ChangeLog\//) != -1) {
+				iDot = s.indexOf(".");
+				iSlash = s.indexOf("/", iDot);
+				verCvs = "CVS" + s.substring(iDot + 1, iSlash);
+				break;
+			}
+		}
+		cf.Close();
+	}
+	cf = fso.OpenTextFile(configFile, 1);
+	if (compiler == "msvc")
+		versionFile = ".\\config.msvc";
+	else if (compiler == "mingw")
+		versionFile = ".\\config.mingw";
+	else if (compiler == "bcb")
+		versionFile = ".\\config.bcb";
+	vf = fso.CreateTextFile(versionFile, true);
+	vf.WriteLine("# " + versionFile);
+	vf.WriteLine("# This file is generated automatically by " + WScript.ScriptName + ".");
+	vf.WriteBlankLines(1);
+	while (cf.AtEndOfStream != true) {
+		ln = cf.ReadLine();
+		s = new String(ln);
+		if (s.search(/^LIBXML_MAJOR_VERSION=/) != -1) {
+			vf.WriteLine(s);
+			verMajor = s.substring(s.indexOf("=") + 1, s.length)
+		} else if(s.search(/^LIBXML_MINOR_VERSION=/) != -1) {
+			vf.WriteLine(s);
+			verMinor = s.substring(s.indexOf("=") + 1, s.length)
+		} else if(s.search(/^LIBXML_MICRO_VERSION=/) != -1) {
+			vf.WriteLine(s);
+			verMicro = s.substring(s.indexOf("=") + 1, s.length)
+		} else if(s.search(/^LIBXML_MICRO_VERSION_SUFFIX=/) != -1) {
+			vf.WriteLine(s);
+			verMicroSuffix = s.substring(s.indexOf("=") + 1, s.length)
+		}
+	}
+	cf.Close();
+	vf.WriteLine("XML_SRCDIR=" + srcDirXml);
+	vf.WriteLine("UTILS_SRCDIR=" + srcDirUtils);
+	vf.WriteLine("WITH_TRIO=" + (withTrio? "1" : "0"));
+	vf.WriteLine("WITH_THREADS=" + withThreads);
+	vf.WriteLine("WITH_FTP=" + (withFtp? "1" : "0"));
+	vf.WriteLine("WITH_HTTP=" + (withHttp? "1" : "0"));
+	vf.WriteLine("WITH_HTML=" + (withHtml? "1" : "0"));
+	vf.WriteLine("WITH_C14N=" + (withC14n? "1" : "0"));
+	vf.WriteLine("WITH_CATALOG=" + (withCatalog? "1" : "0"));
+	vf.WriteLine("WITH_DOCB=" + (withDocb? "1" : "0"));
+	vf.WriteLine("WITH_XPATH=" + (withXpath? "1" : "0"));
+	vf.WriteLine("WITH_XPTR=" + (withXptr? "1" : "0"));
+	vf.WriteLine("WITH_XINCLUDE=" + (withXinclude? "1" : "0"));
+	vf.WriteLine("WITH_ICONV=" + (withIconv? "1" : "0"));
+	vf.WriteLine("WITH_ICU=" + (withIcu? "1" : "0"));
+	vf.WriteLine("WITH_ISO8859X=" + (withIso8859x? "1" : "0"));
+	vf.WriteLine("WITH_ZLIB=" + (withZlib? "1" : "0"));
+	vf.WriteLine("WITH_DEBUG=" + (withDebug? "1" : "0"));
+	vf.WriteLine("WITH_MEM_DEBUG=" + (withMemDebug? "1" : "0"));
+	vf.WriteLine("WITH_RUN_DEBUG=" + (withRunDebug? "1" : "0"));
+	vf.WriteLine("WITH_SCHEMAS=" + (withSchemas? "1" : "0"));
+	vf.WriteLine("WITH_SCHEMATRON=" + (withSchematron? "1" : "0"));
+	vf.WriteLine("WITH_REGEXPS=" + (withRegExps? "1" : "0"));
+	vf.WriteLine("WITH_MODULES=" + (withModules? "1" : "0"));
+	vf.WriteLine("WITH_TREE=" + (withTree? "1" : "0"));
+	vf.WriteLine("WITH_READER=" + (withReader? "1" : "0"));
+	vf.WriteLine("WITH_WRITER=" + (withWriter? "1" : "0"));
+	vf.WriteLine("WITH_WALKER=" + (withWalker? "1" : "0"));
+	vf.WriteLine("WITH_PATTERN=" + (withPattern? "1" : "0"));
+	vf.WriteLine("WITH_PUSH=" + (withPush? "1" : "0"));
+	vf.WriteLine("WITH_VALID=" + (withValid? "1" : "0"));
+	vf.WriteLine("WITH_SAX1=" + (withSax1? "1" : "0"));
+	vf.WriteLine("WITH_LEGACY=" + (withLegacy? "1" : "0"));
+	vf.WriteLine("WITH_OUTPUT=" + (withOutput? "1" : "0"));
+	vf.WriteLine("WITH_PYTHON=" + (withPython? "1" : "0"));
+	vf.WriteLine("DEBUG=" + (buildDebug? "1" : "0"));
+	vf.WriteLine("STATIC=" + (buildStatic? "1" : "0"));
+	vf.WriteLine("PREFIX=" + buildPrefix);
+	vf.WriteLine("BINPREFIX=" + buildBinPrefix);
+	vf.WriteLine("INCPREFIX=" + buildIncPrefix);
+	vf.WriteLine("LIBPREFIX=" + buildLibPrefix);
+	vf.WriteLine("SOPREFIX=" + buildSoPrefix);
+	if (compiler == "msvc") {
+		vf.WriteLine("INCLUDE=$(INCLUDE);" + buildInclude);
+		vf.WriteLine("LIB=$(LIB);" + buildLib);
+		vf.WriteLine("CRUNTIME=" + cruntime);
+		vf.WriteLine("VCMANIFEST=" + (vcmanifest? "1" : "0"));
+	} else if (compiler == "mingw") {
+		vf.WriteLine("INCLUDE+=;" + buildInclude);
+		vf.WriteLine("LIB+=;" + buildLib);
+	} else if (compiler == "bcb") {
+		vf.WriteLine("INCLUDE=" + buildInclude);
+		vf.WriteLine("LIB=" + buildLib);
+		vf.WriteLine("DYNRUNTIME=" + (dynruntime? "1" : "0"));
+	}
+	vf.Close();
+}
+
+/* Configures libxml. This one will generate xmlversion.h from xmlversion.h.in
+   taking what the user passed on the command line into account. */
+function configureLibxml()
+{
+	var fso, ofi, of, ln, s;
+	fso = new ActiveXObject("Scripting.FileSystemObject");
+	ofi = fso.OpenTextFile(optsFileIn, 1);
+	of = fso.CreateTextFile(optsFile, true);
+	while (ofi.AtEndOfStream != true) {
+		ln = ofi.ReadLine();
+		s = new String(ln);
+		if (s.search(/\@VERSION\@/) != -1) {
+			of.WriteLine(s.replace(/\@VERSION\@/, 
+				verMajor + "." + verMinor + "." + verMicro + verMicroSuffix));
+		} else if (s.search(/\@LIBXML_VERSION_NUMBER\@/) != -1) {
+			of.WriteLine(s.replace(/\@LIBXML_VERSION_NUMBER\@/, 
+				verMajor*10000 + verMinor*100 + verMicro*1));
+		} else if (s.search(/\@LIBXML_VERSION_EXTRA\@/) != -1) {
+			of.WriteLine(s.replace(/\@LIBXML_VERSION_EXTRA\@/, verCvs));
+		} else if (s.search(/\@WITH_TRIO\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_TRIO\@/, withTrio? "1" : "0"));
+		} else if (s.search(/\@WITH_THREADS\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_THREADS\@/, withThreads == "no"? "0" : "1"));
+		} else if (s.search(/\@WITH_FTP\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_FTP\@/, withFtp? "1" : "0"));
+		} else if (s.search(/\@WITH_HTTP\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_HTTP\@/, withHttp? "1" : "0"));
+		} else if (s.search(/\@WITH_HTML\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_HTML\@/, withHtml? "1" : "0"));
+		} else if (s.search(/\@WITH_C14N\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_C14N\@/, withC14n? "1" : "0"));
+		} else if (s.search(/\@WITH_CATALOG\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_CATALOG\@/, withCatalog? "1" : "0"));
+		} else if (s.search(/\@WITH_DOCB\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_DOCB\@/, withDocb? "1" : "0"));
+		} else if (s.search(/\@WITH_XPATH\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_XPATH\@/, withXpath? "1" : "0"));
+		} else if (s.search(/\@WITH_XPTR\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_XPTR\@/, withXptr? "1" : "0"));
+		} else if (s.search(/\@WITH_XINCLUDE\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_XINCLUDE\@/, withXinclude? "1" : "0"));
+		} else if (s.search(/\@WITH_ICONV\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_ICONV\@/, withIconv? "1" : "0"));
+		} else if (s.search(/\@WITH_ICU\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_ICU\@/, withIcu? "1" : "0"));
+		} else if (s.search(/\@WITH_ISO8859X\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_ISO8859X\@/, withIso8859x? "1" : "0"));
+		} else if (s.search(/\@WITH_ZLIB\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_ZLIB\@/, withZlib? "1" : "0"));
+		} else if (s.search(/\@WITH_DEBUG\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_DEBUG\@/, withDebug? "1" : "0"));
+		} else if (s.search(/\@WITH_MEM_DEBUG\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_MEM_DEBUG\@/, withMemDebug? "1" : "0"));
+		} else if (s.search(/\@WITH_RUN_DEBUG\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_RUN_DEBUG\@/, withRunDebug? "1" : "0"));
+		} else if (s.search(/\@WITH_SCHEMAS\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_SCHEMAS\@/, withSchemas? "1" : "0"));
+		} else if (s.search(/\@WITH_SCHEMATRON\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_SCHEMATRON\@/, withSchematron? "1" : "0"));
+		} else if (s.search(/\@WITH_REGEXPS\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_REGEXPS\@/, withRegExps? "1" : "0"));
+		} else if (s.search(/\@WITH_MODULES\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_MODULES\@/, withModules? "1" : "0"));
+		} else if (s.search(/\@MODULE_EXTENSION\@/) != -1) {
+			of.WriteLine(s.replace(/\@MODULE_EXTENSION\@/, ".dll"));
+		} else if (s.search(/\@WITH_TREE\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_TREE\@/, withTree? "1" : "0"));
+		} else if (s.search(/\@WITH_READER\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_READER\@/, withReader? "1" : "0"));
+		} else if (s.search(/\@WITH_WRITER\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_WRITER\@/, withWriter? "1" : "0"));
+		} else if (s.search(/\@WITH_WALKER\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_WALKER\@/, withWalker? "1" : "0"));
+		} else if (s.search(/\@WITH_PATTERN\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_PATTERN\@/, withPattern? "1" : "0"));
+		} else if (s.search(/\@WITH_PUSH\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_PUSH\@/, withPush? "1" : "0"));
+		} else if (s.search(/\@WITH_VALID\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_VALID\@/, withValid? "1" : "0"));
+		} else if (s.search(/\@WITH_SAX1\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_SAX1\@/, withSax1? "1" : "0"));
+		} else if (s.search(/\@WITH_LEGACY\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_LEGACY\@/, withLegacy? "1" : "0"));
+		} else if (s.search(/\@WITH_OUTPUT\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_OUTPUT\@/, withOutput? "1" : "0"));
+		} else
+			of.WriteLine(ln);
+	}
+	ofi.Close();
+	of.Close();
+}
+/* Configures Python bindings. Otherwise identical to the above */
+function configureLibxmlPy()
+{
+	var pyOptsFileIn = srcDirXml + "\\python\\setup.py.in";
+	var pyOptsFile = srcDirXml + "\\python\\setup.py";
+	var fso, ofi, of, ln, s;
+	fso = new ActiveXObject("Scripting.FileSystemObject");
+	ofi = fso.OpenTextFile(pyOptsFileIn, 1);
+	of = fso.CreateTextFile(pyOptsFile, true);
+	while (ofi.AtEndOfStream != true) {
+		ln = ofi.ReadLine();
+		s = new String(ln);
+		if (s.search(/\@LIBXML_VERSION\@/) != -1) {
+			of.WriteLine(s.replace(/\@LIBXML_VERSION\@/, 
+				verMajor + "." + verMinor + "." + verMicro));
+		} else if (s.search(/\@prefix\@/) != -1) {
+			of.WriteLine(s.replace(/\@prefix\@/, buildPrefix));
+		} else if (s.search(/\@WITH_THREADS\@/) != -1) {
+			of.WriteLine(s.replace(/\@WITH_THREADS\@/, withThreads == "no"? "0" : "1"));
+		} else
+			of.WriteLine(ln);
+	}
+	ofi.Close();
+	of.Close();
+}
+
+/* Creates the readme file for the binary distribution of 'bname', for the
+   version 'ver' in the file 'file'. This one is called from the Makefile when
+   generating a binary distribution. The parameters are passed by make. */
+function genReadme(bname, ver, file)
+{
+	var fso, f;
+	fso = new ActiveXObject("Scripting.FileSystemObject");
+	f = fso.CreateTextFile(file, true);
+	f.WriteLine("  " + bname + " " + ver);
+	f.WriteLine("  --------------");
+	f.WriteBlankLines(1);
+	f.WriteLine("  This is " + bname + ", version " + ver + ", binary package for the native Win32/IA32");
+	f.WriteLine("platform.");
+	f.WriteBlankLines(1);
+	f.WriteLine("  The files in this package do not require any special installation");
+	f.WriteLine("steps. Extract the contents of the archive whereever you wish and");
+	f.WriteLine("make sure that your tools which use " + bname + " can find it.");
+	f.WriteBlankLines(1);
+	f.WriteLine("  For example, if you want to run the supplied utilities from the command");
+	f.WriteLine("line, you can, if you wish, add the 'bin' subdirectory to the PATH");
+	f.WriteLine("environment variable.");
+	f.WriteLine("  If you want to make programmes in C which use " + bname + ", you'll");
+	f.WriteLine("likely know how to use the contents of this package. If you don't, please");
+	f.WriteLine("refer to your compiler's documentation."); 
+	f.WriteBlankLines(1);
+	f.WriteLine("  If there is something you cannot keep for yourself, such as a problem,");
+	f.WriteLine("a cheer of joy, a comment or a suggestion, feel free to contact me using");
+	f.WriteLine("the address below.");
+	f.WriteBlankLines(1);
+	f.WriteLine("                              Igor Zlatkovic (igor@zlatkovic.com)");
+	f.Close();
+}
+
+
+/*
+ * main(),
+ * Execution begins here.
+ */
+
+// Parse the command-line arguments.
+for (i = 0; (i < WScript.Arguments.length) && (error == 0); i++) {
+	var arg, opt;
+	arg = WScript.Arguments(i);
+	opt = arg.substring(0, arg.indexOf("="));
+	if (opt.length == 0)
+		opt = arg.substring(0, arg.indexOf(":"));
+	if (opt.length > 0) {
+		if (opt == "trio")
+			withTrio = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "threads")
+			withThreads = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "ftp")
+			withFtp = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "http")
+			withHttp = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "html")
+			withHtml = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "c14n")
+			withC14n = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "catalog")
+			withCatalog = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "docb")
+			withDocb = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "xpath")
+			withXpath = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "xptr")
+			withXptr = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "xinclude")
+			withXinclude = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "iconv")
+			withIconv = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "icu")
+			withIcu = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "iso8859x")
+			withIso8859x = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "zlib")
+			withZlib = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "xml_debug")
+			withDebug = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "mem_debug")
+			withMemDebug = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "run_debug")
+			withRunDebug = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "schemas")
+			withSchemas = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "schematron")
+			withSchematron = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "regexps")
+			withRegExps = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "modules")
+			withModules = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "tree")
+			withTree = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "reader")
+			withReader = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "writer")
+			withWriter = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "walker")
+			withWalker = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "pattern")
+			withPattern = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "push")
+			withPush = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "valid")
+			withValid = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "sax1")
+			withSax1 = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "legacy")
+			withLegacy = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "output")
+			withOutput = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "python")
+			withPython = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "compiler")
+			compiler = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "cruntime")
+			cruntime = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "dynruntime")
+			dynruntime = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "vcmanifest")
+			vcmanifest = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "debug")
+			buildDebug = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "static")
+			buildStatic = strToBool(arg.substring(opt.length + 1, arg.length));
+		else if (opt == "prefix")
+			buildPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "incdir")
+			buildIncPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "bindir")
+			buildBinPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "libdir")
+			buildLibPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "sodir")
+			buildSoPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "incdir")
+			buildIncPrefix = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "include")
+			buildInclude = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "lib")
+			buildLib = arg.substring(opt.length + 1, arg.length);
+		else if (opt == "release")
+			useCvsVer = false;
+		else
+			error = 1;
+	} else if (i == 0) {
+		if (arg == "genreadme") {
+			// This command comes from the Makefile and will not be checked
+			// for errors, because Makefile will always supply right the parameters.
+			genReadme(WScript.Arguments(1), WScript.Arguments(2), WScript.Arguments(3));
+			WScript.Quit(0);
+		} else if (arg == "help") {
+			usage();
+			WScript.Quit(0);
+		}
+
+	} else {
+		error = 1;
+	}
+}
+
+
+// If we fail here, it is because the user supplied an unrecognised argument.
+if (error != 0) {
+	usage();
+	WScript.Quit(error);
+}
+
+// if user choses to link the c-runtime library statically into libxml2
+// with /MT and friends, then we need to enable static linking for xmllint
+if (cruntime == "/MT" || cruntime == "/MTd" ||
+		cruntime == "/ML" || cruntime == "/MLd") {
+	buildStatic = 1;
+}
+
+dirSep = "\\";
+if (buildBinPrefix == "")
+	buildBinPrefix = "$(PREFIX)" + dirSep + "bin";
+if (buildIncPrefix == "")
+	buildIncPrefix = "$(PREFIX)" + dirSep + "include";
+if (buildLibPrefix == "")
+	buildLibPrefix = "$(PREFIX)" + dirSep + "lib";
+if (buildSoPrefix == "")
+	buildSoPrefix = "$(PREFIX)" + dirSep + "lib";
+
+// Discover the version.
+discoverVersion();
+if (error != 0) {
+	WScript.Echo("Version discovery failed, aborting.");
+	WScript.Quit(error);
+}
+
+var outVerString = baseName + " version: " + verMajor + "." + verMinor + "." + verMicro;
+if (verMicroSuffix && verMicroSuffix != "")
+	outVerString += "-" + verMicroSuffix;
+if (verCvs && verCvs != "")
+	outVerString += "-" + verCvs;
+WScript.Echo(outVerString);
+
+// Configure libxml.
+configureLibxml();
+if (error != 0) {
+	WScript.Echo("Configuration failed, aborting.");
+	WScript.Quit(error);
+}
+
+if (withPython == true) {
+	configureLibxmlPy();
+	if (error != 0) {
+		WScript.Echo("Configuration failed, aborting.");
+		WScript.Quit(error);
+	}
+
+}
+
+// Create the makefile.
+var fso = new ActiveXObject("Scripting.FileSystemObject");
+var makefile = ".\\Makefile.msvc";
+if (compiler == "mingw")
+	makefile = ".\\Makefile.mingw";
+else if (compiler == "bcb")
+	makefile = ".\\Makefile.bcb";
+var new_makefile = ".\\Makefile";
+var f = fso.FileExists(new_makefile);
+if (f) {
+       var t = fso.GetFile(new_makefile);
+       t.Attributes = 0;
+}
+fso.CopyFile(makefile, new_makefile, true);
+WScript.Echo("Created Makefile.");
+// Create the config.h.
+var confighsrc = "..\\include\\win32config.h";
+var configh = "..\\config.h";
+var f = fso.FileExists(configh);
+if (f) {
+	var t = fso.GetFile(configh);
+	t.Attributes =0;
+}
+fso.CopyFile(confighsrc, configh, true);
+WScript.Echo("Created config.h.");
+
+
+// Display the final configuration. 
+var txtOut = "\nXML processor configuration\n";
+txtOut += "---------------------------\n";
+txtOut += "              Trio: " + boolToStr(withTrio) + "\n";
+txtOut += "     Thread safety: " + withThreads + "\n";
+txtOut += "        FTP client: " + boolToStr(withFtp) + "\n";
+txtOut += "       HTTP client: " + boolToStr(withHttp) + "\n";
+txtOut += "    HTML processor: " + boolToStr(withHtml) + "\n";
+txtOut += "      C14N support: " + boolToStr(withC14n) + "\n";
+txtOut += "   Catalog support: " + boolToStr(withCatalog) + "\n";
+txtOut += "   DocBook support: " + boolToStr(withDocb) + "\n";
+txtOut += "     XPath support: " + boolToStr(withXpath) + "\n";
+txtOut += "  XPointer support: " + boolToStr(withXptr) + "\n";
+txtOut += "  XInclude support: " + boolToStr(withXinclude) + "\n";
+txtOut += "     iconv support: " + boolToStr(withIconv) + "\n";
+txtOut += "     icu   support: " + boolToStr(withIcu) + "\n";
+txtOut += "  iso8859x support: " + boolToStr(withIso8859x) + "\n";
+txtOut += "      zlib support: " + boolToStr(withZlib) + "\n";
+txtOut += "  Debugging module: " + boolToStr(withDebug) + "\n";
+txtOut += "  Memory debugging: " + boolToStr(withMemDebug) + "\n";
+txtOut += " Runtime debugging: " + boolToStr(withRunDebug) + "\n";
+txtOut += "    Regexp support: " + boolToStr(withRegExps) + "\n";
+txtOut += "    Module support: " + boolToStr(withModules) + "\n";
+txtOut += "      Tree support: " + boolToStr(withTree) + "\n";
+txtOut += "    Reader support: " + boolToStr(withReader) + "\n";
+txtOut += "    Writer support: " + boolToStr(withWriter) + "\n";
+txtOut += "    Walker support: " + boolToStr(withWalker) + "\n";
+txtOut += "   Pattern support: " + boolToStr(withPattern) + "\n";
+txtOut += "      Push support: " + boolToStr(withPush) + "\n";
+txtOut += "Validation support: " + boolToStr(withValid) + "\n";
+txtOut += "      SAX1 support: " + boolToStr(withSax1) + "\n";
+txtOut += "    Legacy support: " + boolToStr(withLegacy) + "\n";
+txtOut += "    Output support: " + boolToStr(withOutput) + "\n";
+txtOut += "XML Schema support: " + boolToStr(withSchemas) + "\n";
+txtOut += "Schematron support: " + boolToStr(withSchematron) + "\n";
+txtOut += "   Python bindings: " + boolToStr(withPython) + "\n";
+txtOut += "\n";
+txtOut += "Win32 build configuration\n";
+txtOut += "-------------------------\n";
+txtOut += "          Compiler: " + compiler + "\n";
+if (compiler == "msvc") {
+	txtOut += "  C-Runtime option: " + cruntime + "\n";
+	txtOut += "    Embed Manifest: " + boolToStr(vcmanifest) + "\n";
+} else if (compiler == "bcb")
+	txtOut += "   Use dynamic RTL: " + dynruntime + "\n";
+txtOut += "     Debug symbols: " + boolToStr(buildDebug) + "\n";
+txtOut += "    Static xmllint: " + boolToStr(buildStatic) + "\n";
+txtOut += "    Install prefix: " + buildPrefix + "\n";
+txtOut += "      Put tools in: " + buildBinPrefix + "\n";
+txtOut += "    Put headers in: " + buildIncPrefix + "\n";
+txtOut += "Put static libs in: " + buildLibPrefix + "\n";
+txtOut += "Put shared libs in: " + buildSoPrefix + "\n";
+txtOut += "      Include path: " + buildInclude + "\n";
+txtOut += "          Lib path: " + buildLib + "\n";
+WScript.Echo(txtOut);
+
+//
+
diff --git a/src/win32/defgen.xsl b/src/win32/defgen.xsl
new file mode 100644
index 0000000..a598ff1
--- /dev/null
+++ b/src/win32/defgen.xsl
@@ -0,0 +1,288 @@
+<?xml version="1.0"?>
+<!-- 
+	win32/defgen.xsl
+	This stylesheet is used to transform doc/libxml2-api.xml into a pseudo-source,
+	which can then be preprocessed to get the .DEF file for the Microsoft's linker.
+	
+	Use any XSLT processor to produce a file called libxml2.def.src in the win32
+	subdirectory, for example, run xsltproc from the win32 subdirectory:
+	
+	  xsltproc -o libxml2.def.src defgen.xsl ../doc/libxml2-api.xml
+	  
+	Once that finishes, rest assured, the Makefile will know what to do with the
+	generated file. 
+
+	April 2003, Igor Zlatkovic <igor@zlatkovic.com>
+-->
+<!DOCTYPE xsl:stylesheet [ <!ENTITY nl '&#xd;&#xa;'> ]>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+	<xsl:strip-space elements="*"/>
+	<xsl:output method="text"/>
+	<xsl:template match="/">
+		<xsl:text>#define LIBXML2_COMPILING_MSCCDEF&nl;</xsl:text>
+		<xsl:text>#include "../include/libxml/xmlversion.h"&nl;</xsl:text>
+		<xsl:text>LIBRARY libxml2&nl;</xsl:text>
+		<xsl:text>EXPORTS&nl;</xsl:text>
+		<xsl:for-each select="/api/symbols/*[self::variable or self::function]">
+			<!-- Basic tests -->
+			<xsl:if test="@file = 'c14n'">
+				<xsl:text>#ifdef LIBXML_C14N_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'catalog'">
+				<xsl:text>#ifdef LIBXML_CATALOG_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'debugXML'">
+				<xsl:text>#ifdef LIBXML_DEBUG_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'DOCBparser'">
+				<xsl:text>#ifdef LIBXML_DOCB_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'HTMLparser') 
+					or (@file = 'HTMLtree')">
+				<xsl:text>#ifdef LIBXML_HTML_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'nanohttp'">
+				<xsl:text>#ifdef LIBXML_HTTP_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'nanoftp'">
+				<xsl:text>#ifdef LIBXML_FTP_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'relaxng') 
+					or (@file = 'xmlschemas') 
+					or (@file = 'xmlschemastypes')">
+				<xsl:text>#ifdef LIBXML_SCHEMAS_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xinclude'">
+				<xsl:text>#ifdef LIBXML_XINCLUDE_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xlink'">
+				<xsl:text>#ifdef LIBXML_XLINK_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xmlautomata'">
+				<xsl:text>#ifdef LIBXML_AUTOMATA_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'xmlregexp') 
+					or (@file = 'xmlunicode')">
+				<xsl:text>#ifdef LIBXML_REGEXP_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'xpath') 
+					or (@file = 'xpathInternals')">
+				<xsl:text>#ifdef LIBXML_XPATH_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xpointer'">
+				<xsl:text>#ifdef LIBXML_XPTR_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<!-- Extended tests -->
+			<xsl:if test="(@name = 'htmlDefaultSAXHandlerInit') 
+					or (@name = 'htmlInitAutoClose') 
+					or (@name = 'htmlCreateFileParserCtxt') 
+					or (@name = 'inithtmlDefaultSAXHandler')
+					or (@name = 'xmlIsXHTML') 
+					or (@name = 'xmlIOHTTPOpenW') 
+					or (@name = 'xmlRegisterHTTPPostCallbacks') 
+					or (@name = 'xmlIOHTTPMatch')
+					or (@name = 'xmlIOHTTPOpen') 
+					or (@name = 'xmlIOHTTPRead') 
+					or (@name = 'xmlIOHTTPClose')">
+				<xsl:text>#ifdef LIBXML_HTML_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'docbDefaultSAXHandlerInit') 
+					or (@name = 'initdocbDefaultSAXHandler')">
+				<xsl:text>#ifdef LIBXML_DOCB_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@name = 'xmlValidBuildContentModel'">
+				<xsl:text>#ifdef LIBXML_REGEXP_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlIOFTPMatch') 
+					or (@name = 'xmlIOFTPOpen') 
+					or (@name = 'xmlIOFTPRead') 
+					or (@name = 'xmlIOFTPClose')">
+				<xsl:text>#ifdef LIBXML_FTP_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlTextReaderRelaxNGValidate') 
+					or (@name = 'xmlTextReaderRelaxNGSetSchema')">
+				<xsl:text>#ifdef LIBXML_SCHEMAS_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlXPathDebugDumpObject') 
+					or (@name = 'xmlXPathDebugDumpCompExpr')">
+				<xsl:text>#ifdef LIBXML_DEBUG_ENABLED&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlMallocLoc') 
+					or (@name = 'xmlMallocAtomicLoc') 
+					or (@name = 'xmlReallocLoc') 
+					or (@name = 'xmlMemStrdupLoc')">
+				<xsl:text>#ifdef DEBUG_MEMORY_LOCATION&nl;</xsl:text>
+			</xsl:if>
+			<!-- Symbol -->
+			<xsl:choose>
+				<xsl:when test="(@name = 'xmlMalloc') 
+						or (@name = 'xmlMallocAtomic') 
+						or (@name = 'xmlRealloc') 
+						or (@name = 'xmlFree') 
+						or (@name = 'xmlMemStrdup')">
+					<xsl:text>#ifdef LIBXML_THREAD_ALLOC_ENABLED&nl;</xsl:text>
+					<xsl:text>__</xsl:text>
+					<xsl:value-of select="@name"/>
+					<xsl:text>&nl;</xsl:text>
+					<xsl:text>#else&nl;</xsl:text>
+					<xsl:value-of select="@name"/>
+					<xsl:text> DATA&nl;</xsl:text>
+					<xsl:text>#endif&nl;</xsl:text>
+				</xsl:when>
+				<xsl:when test="(@name = 'docbDefaultSAXHandler') 
+						or (@name = 'htmlDefaultSAXHandler') 
+						or (@name = 'oldXMLWDcompatibility') 
+						or (@name = 'xmlBufferAllocScheme') 
+						or (@name = 'xmlDefaultBufferSize') 
+						or (@name = 'xmlDefaultSAXHandler') 
+						or (@name = 'xmlDefaultSAXLocator') 
+						or (@name = 'xmlDoValidityCheckingDefaultValue') 
+						or (@name = 'xmlGenericError') 
+						or (@name = 'xmlGenericErrorContext') 
+						or (@name = 'xmlGetWarningsDefaultValue') 
+						or (@name = 'xmlIndentTreeOutput') 
+						or (@name = 'xmlTreeIndentString') 
+						or (@name = 'xmlKeepBlanksDefaultValue') 
+						or (@name = 'xmlLineNumbersDefaultValue') 
+						or (@name = 'xmlLoadExtDtdDefaultValue') 
+						or (@name = 'xmlParserDebugEntities') 
+						or (@name = 'xmlParserVersion') 
+						or (@name = 'xmlPedanticParserDefaultValue') 
+						or (@name = 'xmlSaveNoEmptyTags') 
+						or (@name = 'xmlSubstituteEntitiesDefaultValue') 
+						or (@name = 'xmlRegisterNodeDefaultValue') 
+						or (@name = 'xmlDeregisterNodeDefaultValue')">
+					<xsl:text>#ifdef LIBXML_THREAD_ENABLED&nl;</xsl:text>
+					<xsl:if test="@name = 'docbDefaultSAXHandler'">
+						<xsl:text>#ifdef LIBXML_DOCB_ENABLED&nl;</xsl:text>
+					</xsl:if>
+					<xsl:if test="@name = 'htmlDefaultSAXHandler'">
+						<xsl:text>#ifdef LIBXML_HTML_ENABLED&nl;</xsl:text>
+					</xsl:if>
+					<xsl:text>__</xsl:text>
+					<xsl:value-of select="@name"/>
+					<xsl:text>&nl;</xsl:text>
+					<xsl:if test="@name = 'docbDefaultSAXHandler'">
+						<xsl:text>#endif&nl;</xsl:text>
+					</xsl:if>
+					<xsl:if test="@name = 'htmlDefaultSAXHandler'">
+						<xsl:text>#endif&nl;</xsl:text>
+					</xsl:if>
+					<xsl:text>#else&nl;</xsl:text>
+					<xsl:if test="@name = 'docbDefaultSAXHandler'">
+						<xsl:text>#ifdef LIBXML_DOCB_ENABLED&nl;</xsl:text>
+					</xsl:if>
+					<xsl:if test="@name = 'htmlDefaultSAXHandler'">
+						<xsl:text>#ifdef LIBXML_HTML_ENABLED&nl;</xsl:text>
+					</xsl:if>
+					<xsl:value-of select="@name"/>
+					<xsl:text> DATA&nl;</xsl:text>
+					<xsl:if test="@name = 'docbDefaultSAXHandler'">
+						<xsl:text>#endif&nl;</xsl:text>
+					</xsl:if>
+					<xsl:if test="@name = 'htmlDefaultSAXHandler'">
+						<xsl:text>#endif&nl;</xsl:text>
+					</xsl:if>
+					<xsl:text>#endif&nl;</xsl:text>
+				</xsl:when>
+				<xsl:otherwise>
+					<xsl:value-of select="@name"/>
+					<xsl:if test="self::variable">
+						<xsl:text> DATA</xsl:text>
+					</xsl:if>
+					<xsl:text>&nl;</xsl:text>
+				</xsl:otherwise>
+			</xsl:choose>
+			<!-- Basic tests (close) -->
+			<xsl:if test="@file = 'c14n'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'catalog'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'debugXML'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'DOCBparser'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'HTMLparser') 
+					or (@file = 'HTMLtree')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'nanohttp'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'nanoftp'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'relaxng') 
+					or (@file = 'xmlschemas') 
+					or (@file = 'xmlschemastypes')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xinclude'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xlink'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xmlautomata'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'xmlregexp') 
+					or (@file = 'xmlunicode')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@file = 'xpath') 
+					or (@file = 'xpathInternals')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@file = 'xpointer'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<!-- Extended tests (close) -->
+			<xsl:if test="(@name = 'htmlDefaultSAXHandlerInit') 
+					or (@name = 'htmlInitAutoClose') 
+					or (@name = 'htmlCreateFileParserCtxt') 
+					or (@name = 'inithtmlDefaultSAXHandler')
+					or (@name = 'xmlIsXHTML') 
+					or (@name = 'xmlIOHTTPOpenW') 
+					or (@name = 'xmlRegisterHTTPPostCallbacks') 
+					or (@name = 'xmlIOHTTPMatch')
+					or (@name = 'xmlIOHTTPOpen') 
+					or (@name = 'xmlIOHTTPRead') 
+					or (@name = 'xmlIOHTTPClose')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'docbDefaultSAXHandlerInit') 
+					or (@name = 'initdocbDefaultSAXHandler')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="@name = 'xmlValidBuildContentModel'">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlIOFTPMatch') 
+					or (@name = 'xmlIOFTPOpen') 
+					or (@name = 'xmlIOFTPRead') 
+					or (@name = 'xmlIOFTPClose')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlTextReaderRelaxNGValidate') 
+					or (@name = 'xmlTextReaderRelaxNGSetSchema')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlXPathDebugDumpObject') 
+					or (@name = 'xmlXPathDebugDumpCompExpr')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+			<xsl:if test="(@name = 'xmlMallocLoc') 
+					or (@name = 'xmlMallocAtomicLoc') 
+					or (@name = 'xmlReallocLoc') 
+					or (@name = 'xmlMemStrdupLoc')">
+				<xsl:text>#endif&nl;</xsl:text>
+			</xsl:if>
+		</xsl:for-each>
+	</xsl:template>
+</xsl:stylesheet>
+
diff --git a/src/win32/libxml2.def.src b/src/win32/libxml2.def.src
new file mode 100644
index 0000000..ce3f24a
--- /dev/null
+++ b/src/win32/libxml2.def.src
@@ -0,0 +1,3164 @@
+#define LIBXML2_COMPILING_MSCCDEF
+#include "../include/libxml/xmlversion.h"
+LIBRARY libxml2
+EXPORTS
+#ifdef LIBXML_THREAD_ENABLED
+#ifdef LIBXML_DOCB_ENABLED
+__docbDefaultSAXHandler
+#endif
+#else
+#ifdef LIBXML_DOCB_ENABLED
+docbDefaultSAXHandler DATA
+#endif
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+emptyExp DATA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+forbiddenExp DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+#ifdef LIBXML_HTML_ENABLED
+__htmlDefaultSAXHandler
+#endif
+#else
+#ifdef LIBXML_HTML_ENABLED
+htmlDefaultSAXHandler DATA
+#endif
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__oldXMLWDcompatibility
+#else
+oldXMLWDcompatibility DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlBufferAllocScheme
+#else
+xmlBufferAllocScheme DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlDefaultBufferSize
+#else
+xmlDefaultBufferSize DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlDefaultSAXHandler
+#else
+xmlDefaultSAXHandler DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlDefaultSAXLocator
+#else
+xmlDefaultSAXLocator DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlDeregisterNodeDefaultValue
+#else
+xmlDeregisterNodeDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlDoValidityCheckingDefaultValue
+#else
+xmlDoValidityCheckingDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+__xmlFree
+#else
+xmlFree DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlGenericError
+#else
+xmlGenericError DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlGenericErrorContext
+#else
+xmlGenericErrorContext DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlGetWarningsDefaultValue
+#else
+xmlGetWarningsDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlIndentTreeOutput
+#else
+xmlIndentTreeOutput DATA
+#endif
+xmlIsBaseCharGroup DATA
+xmlIsCharGroup DATA
+xmlIsCombiningGroup DATA
+xmlIsDigitGroup DATA
+xmlIsExtenderGroup DATA
+xmlIsIdeographicGroup DATA
+xmlIsPubidChar_tab DATA
+#ifdef LIBXML_THREAD_ENABLED
+__xmlKeepBlanksDefaultValue
+#else
+xmlKeepBlanksDefaultValue DATA
+#endif
+xmlLastError DATA
+#ifdef LIBXML_THREAD_ENABLED
+__xmlLineNumbersDefaultValue
+#else
+xmlLineNumbersDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlLoadExtDtdDefaultValue
+#else
+xmlLoadExtDtdDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+__xmlMalloc
+#else
+xmlMalloc DATA
+#endif
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+__xmlMallocAtomic
+#else
+xmlMallocAtomic DATA
+#endif
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+__xmlMemStrdup
+#else
+xmlMemStrdup DATA
+#endif
+xmlOutputBufferCreateFilenameValue DATA
+#ifdef LIBXML_THREAD_ENABLED
+__xmlParserDebugEntities
+#else
+xmlParserDebugEntities DATA
+#endif
+xmlParserInputBufferCreateFilenameValue DATA
+xmlParserMaxDepth DATA
+#ifdef LIBXML_THREAD_ENABLED
+__xmlParserVersion
+#else
+xmlParserVersion DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlPedanticParserDefaultValue
+#else
+xmlPedanticParserDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+__xmlRealloc
+#else
+xmlRealloc DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlRegisterNodeDefaultValue
+#else
+xmlRegisterNodeDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlSaveNoEmptyTags
+#else
+xmlSaveNoEmptyTags DATA
+#endif
+xmlStringComment DATA
+xmlStringText DATA
+xmlStringTextNoenc DATA
+xmlStructuredError DATA
+xmlStructuredErrorContext DATA
+#ifdef LIBXML_THREAD_ENABLED
+__xmlSubstituteEntitiesDefaultValue
+#else
+xmlSubstituteEntitiesDefaultValue DATA
+#endif
+#ifdef LIBXML_THREAD_ENABLED
+__xmlTreeIndentString
+#else
+xmlTreeIndentString DATA
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNAN DATA
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNINF DATA
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPINF DATA
+#endif
+#ifdef LIBXML_HTML_ENABLED
+UTF8ToHtml
+#endif
+UTF8Toisolat1
+attribute
+attributeDecl
+cdataBlock
+characters
+checkNamespace
+comment
+#ifdef LIBXML_DOCB_ENABLED
+docbCreateFileParserCtxt
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbCreatePushParserCtxt
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbDefaultSAXHandlerInit
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbEncodeEntities
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbFreeParserCtxt
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbParseChunk
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbParseDoc
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbParseDocument
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbParseFile
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbSAXParseDoc
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+docbSAXParseFile
+#endif
+elementDecl
+endDocument
+endElement
+entityDecl
+externalSubset
+getColumnNumber
+getEntity
+getLineNumber
+getNamespace
+getParameterEntity
+getPublicId
+getSystemId
+globalNamespace
+hasExternalSubset
+hasInternalSubset
+#ifdef LIBXML_HTML_ENABLED
+htmlAttrAllowed
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlAutoCloseTag
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCreateFileParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCreateMemoryParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCreatePushParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReadDoc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReadFd
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReadFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReadIO
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReadMemory
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtReset
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlCtxtUseOptions
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDefaultSAXHandlerInit
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDocContentDumpFormatOutput
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDocContentDumpOutput
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDocDump
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDocDumpMemory
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlDocDumpMemoryFormat
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlElementAllowedHere
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlElementStatusHere
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlEncodeEntities
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlEntityLookup
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlEntityValueLookup
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlFreeParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlGetMetaEncoding
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlHandleOmittedElem
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlInitAutoClose
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlIsAutoClosed
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlIsBooleanAttr
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlIsScriptAttribute
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNewDoc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNewDocNoDtD
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNewParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeDump
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeDumpFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeDumpFileFormat
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeDumpFormatOutput
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeDumpOutput
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlNodeStatus
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseCharRef
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseChunk
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseDoc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseDocument
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseElement
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseEntityRef
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlParseFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlReadDoc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlReadFd
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlReadFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlReadIO
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlReadMemory
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSAXParseDoc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSAXParseFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSaveFile
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSaveFileEnc
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSaveFileFormat
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlSetMetaEncoding
+#endif
+#ifdef LIBXML_HTML_ENABLED
+htmlTagLookup
+#endif
+ignorableWhitespace
+initGenericErrorDefaultFunc
+#ifdef LIBXML_DOCB_ENABLED
+initdocbDefaultSAXHandler
+#endif
+#ifdef LIBXML_HTML_ENABLED
+inithtmlDefaultSAXHandler
+#endif
+initxmlDefaultSAXHandler
+inputPop
+inputPush
+internalSubset
+isStandalone
+isolat1ToUTF8
+namePop
+namePush
+namespaceDecl
+nodePop
+nodePush
+notationDecl
+processingInstruction
+reference
+resolveEntity
+setDocumentLocator
+setNamespace
+startDocument
+startElement
+unparsedEntityDecl
+#ifdef LIBXML_XPATH_ENABLED
+valuePop
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+valuePush
+#endif
+#ifdef LIBXML_XLINK_ENABLED
+xlinkGetDefaultDetect
+#endif
+#ifdef LIBXML_XLINK_ENABLED
+xlinkGetDefaultHandler
+#endif
+#ifdef LIBXML_XLINK_ENABLED
+xlinkIsLink
+#endif
+#ifdef LIBXML_XLINK_ENABLED
+xlinkSetDefaultDetect
+#endif
+#ifdef LIBXML_XLINK_ENABLED
+xlinkSetDefaultHandler
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogAdd
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogDump
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogRemove
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogResolve
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogResolvePublic
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogResolveSystem
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlACatalogResolveURI
+#endif
+xmlAddAttributeDecl
+xmlAddChild
+xmlAddChildList
+xmlAddDocEntity
+xmlAddDtdEntity
+xmlAddElementDecl
+xmlAddEncodingAlias
+xmlAddID
+xmlAddNextSibling
+xmlAddNotationDecl
+xmlAddPrevSibling
+xmlAddRef
+xmlAddSibling
+xmlAllocOutputBuffer
+xmlAllocParserInputBuffer
+xmlAttrSerializeTxtContent
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataCompile
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataGetInitState
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataIsDeterminist
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewAllTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewCountTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewCountTrans2
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewCountedTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewCounter
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewCounterTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewEpsilon
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewNegTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewOnceTrans
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewOnceTrans2
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewState
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewTransition
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataNewTransition2
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlAutomataSetFinalState
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlBoolToText
+#endif
+xmlBufferAdd
+xmlBufferAddHead
+xmlBufferCCat
+xmlBufferCat
+xmlBufferContent
+xmlBufferCreate
+xmlBufferCreateSize
+xmlBufferCreateStatic
+xmlBufferDump
+xmlBufferEmpty
+xmlBufferFree
+xmlBufferGrow
+xmlBufferLength
+xmlBufferResize
+xmlBufferSetAllocationScheme
+xmlBufferShrink
+xmlBufferWriteCHAR
+xmlBufferWriteChar
+xmlBufferWriteQuotedString
+xmlBuildQName
+xmlBuildRelativeURI
+xmlBuildURI
+xmlByteConsumed
+#ifdef LIBXML_C14N_ENABLED
+xmlC14NDocDumpMemory
+#endif
+#ifdef LIBXML_C14N_ENABLED
+xmlC14NDocSave
+#endif
+#ifdef LIBXML_C14N_ENABLED
+xmlC14NDocSaveTo
+#endif
+#ifdef LIBXML_C14N_ENABLED
+xmlC14NExecute
+#endif
+xmlCanonicPath
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogAdd
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogAddLocal
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogCleanup
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogConvert
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogDump
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogFreeLocal
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogGetDefaults
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogGetPublic
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogGetSystem
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogIsEmpty
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogLocalResolve
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogLocalResolveURI
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogRemove
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogResolve
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogResolvePublic
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogResolveSystem
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogResolveURI
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogSetDebug
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogSetDefaultPrefer
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlCatalogSetDefaults
+#endif
+xmlCharEncCloseFunc
+xmlCharEncFirstLine
+xmlCharEncInFunc
+xmlCharEncOutFunc
+xmlCharInRange
+xmlCharStrdup
+xmlCharStrndup
+xmlCheckFilename
+xmlCheckHTTPInput
+xmlCheckLanguageID
+xmlCheckUTF8
+xmlCheckVersion
+xmlChildElementCount
+xmlCleanupCharEncodingHandlers
+xmlCleanupEncodingAliases
+xmlCleanupGlobals
+xmlCleanupInputCallbacks
+xmlCleanupMemory
+xmlCleanupOutputCallbacks
+xmlCleanupParser
+xmlCleanupPredefinedEntities
+xmlCleanupThreads
+xmlClearNodeInfoSeq
+xmlClearParserCtxt
+#ifdef LIBXML_CATALOG_ENABLED
+xmlConvertSGMLCatalog
+#endif
+xmlCopyAttributeTable
+xmlCopyChar
+xmlCopyCharMultiByte
+xmlCopyDoc
+xmlCopyDocElementContent
+xmlCopyDtd
+xmlCopyElementContent
+xmlCopyElementTable
+xmlCopyEntitiesTable
+xmlCopyEnumeration
+xmlCopyError
+xmlCopyNamespace
+xmlCopyNamespaceList
+xmlCopyNode
+xmlCopyNodeList
+xmlCopyNotationTable
+xmlCopyProp
+xmlCopyPropList
+xmlCreateDocParserCtxt
+xmlCreateEntitiesTable
+xmlCreateEntityParserCtxt
+xmlCreateEnumeration
+xmlCreateFileParserCtxt
+xmlCreateIOParserCtxt
+xmlCreateIntSubset
+xmlCreateMemoryParserCtxt
+xmlCreatePushParserCtxt
+xmlCreateURI
+xmlCreateURLParserCtxt
+xmlCtxtGetLastError
+xmlCtxtReadDoc
+xmlCtxtReadFd
+xmlCtxtReadFile
+xmlCtxtReadIO
+xmlCtxtReadMemory
+xmlCtxtReset
+xmlCtxtResetLastError
+xmlCtxtResetPush
+xmlCtxtUseOptions
+xmlCurrentChar
+xmlDOMWrapAdoptNode
+xmlDOMWrapCloneNode
+xmlDOMWrapFreeCtxt
+xmlDOMWrapNewCtxt
+xmlDOMWrapReconcileNamespaces
+xmlDOMWrapRemoveNode
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugCheckDocument
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpAttr
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpAttrList
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpDTD
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpDocument
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpDocumentHead
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpEntities
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpNode
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpNodeList
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpOneNode
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlDebugDumpString
+#endif
+xmlDecodeEntities
+xmlDefaultSAXHandlerInit
+xmlDelEncodingAlias
+xmlDeregisterNodeDefault
+xmlDetectCharEncoding
+xmlDictCleanup
+xmlDictCreate
+xmlDictCreateSub
+xmlDictExists
+xmlDictFree
+xmlDictLookup
+xmlDictOwns
+xmlDictQLookup
+xmlDictReference
+xmlDictSize
+xmlDllMain
+xmlDocCopyNode
+xmlDocCopyNodeList
+xmlDocDump
+xmlDocDumpFormatMemory
+xmlDocDumpFormatMemoryEnc
+xmlDocDumpMemory
+xmlDocDumpMemoryEnc
+xmlDocFormatDump
+xmlDocGetRootElement
+xmlDocSetRootElement
+xmlDumpAttributeDecl
+xmlDumpAttributeTable
+xmlDumpElementDecl
+xmlDumpElementTable
+xmlDumpEntitiesTable
+xmlDumpEntityDecl
+xmlDumpNotationDecl
+xmlDumpNotationTable
+xmlElemDump
+xmlEncodeEntities
+xmlEncodeEntitiesReentrant
+xmlEncodeSpecialChars
+xmlErrMemory
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpCtxtNbCons
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpCtxtNbNodes
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpDump
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpExpDerive
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpFree
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpFreeCtxt
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpGetLanguage
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpGetStart
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpIsNillable
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpMaxToken
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpNewAtom
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpNewCtxt
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpNewOr
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpNewRange
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpNewSeq
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpParse
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpRef
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpStringDerive
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlExpSubsume
+#endif
+xmlFileClose
+xmlFileMatch
+xmlFileOpen
+xmlFileRead
+xmlFindCharEncodingHandler
+xmlFirstElementChild
+xmlFreeAttributeTable
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlFreeAutomata
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlFreeCatalog
+#endif
+xmlFreeDoc
+xmlFreeDocElementContent
+xmlFreeDtd
+xmlFreeElementContent
+xmlFreeElementTable
+xmlFreeEntitiesTable
+xmlFreeEnumeration
+xmlFreeIDTable
+xmlFreeInputStream
+xmlFreeMutex
+xmlFreeNode
+xmlFreeNodeList
+xmlFreeNotationTable
+xmlFreeNs
+xmlFreeNsList
+xmlFreeParserCtxt
+xmlFreeParserInputBuffer
+xmlFreePattern
+xmlFreePatternList
+xmlFreeProp
+xmlFreePropList
+xmlFreeRMutex
+xmlFreeRefTable
+xmlFreeStreamCtxt
+xmlFreeTextReader
+xmlFreeTextWriter
+xmlFreeURI
+xmlFreeValidCtxt
+xmlGcMemGet
+xmlGcMemSetup
+xmlGetBufferAllocationScheme
+xmlGetCharEncodingHandler
+xmlGetCharEncodingName
+xmlGetCompressMode
+xmlGetDocCompressMode
+xmlGetDocEntity
+xmlGetDtdAttrDesc
+xmlGetDtdElementDesc
+xmlGetDtdEntity
+xmlGetDtdNotationDesc
+xmlGetDtdQAttrDesc
+xmlGetDtdQElementDesc
+xmlGetEncodingAlias
+xmlGetExternalEntityLoader
+xmlGetFeature
+xmlGetFeaturesList
+xmlGetGlobalState
+xmlGetID
+xmlGetIntSubset
+xmlGetLastChild
+xmlGetLastError
+xmlGetLineNo
+xmlGetNoNsProp
+xmlGetNodePath
+xmlGetNsList
+xmlGetNsProp
+xmlGetParameterEntity
+xmlGetPredefinedEntity
+xmlGetProp
+xmlGetRefs
+xmlGetThreadId
+xmlGetUTF8Char
+xmlHandleEntity
+xmlHasFeature
+xmlHasNsProp
+xmlHasProp
+xmlHashAddEntry
+xmlHashAddEntry2
+xmlHashAddEntry3
+xmlHashCopy
+xmlHashCreate
+xmlHashCreateDict
+xmlHashFree
+xmlHashLookup
+xmlHashLookup2
+xmlHashLookup3
+xmlHashQLookup
+xmlHashQLookup2
+xmlHashQLookup3
+xmlHashRemoveEntry
+xmlHashRemoveEntry2
+xmlHashRemoveEntry3
+xmlHashScan
+xmlHashScan3
+xmlHashScanFull
+xmlHashScanFull3
+xmlHashSize
+xmlHashUpdateEntry
+xmlHashUpdateEntry2
+xmlHashUpdateEntry3
+#ifdef LIBXML_FTP_ENABLED
+xmlIOFTPClose
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlIOFTPMatch
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlIOFTPOpen
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlIOFTPRead
+#endif
+#ifdef LIBXML_HTML_ENABLED
+xmlIOHTTPClose
+#endif
+#ifdef LIBXML_HTML_ENABLED
+xmlIOHTTPMatch
+#endif
+#ifdef LIBXML_HTML_ENABLED
+xmlIOHTTPOpen
+#endif
+#ifdef LIBXML_HTML_ENABLED
+xmlIOHTTPOpenW
+#endif
+#ifdef LIBXML_HTML_ENABLED
+xmlIOHTTPRead
+#endif
+xmlIOParseDTD
+xmlInitCharEncodingHandlers
+xmlInitGlobals
+xmlInitMemory
+xmlInitNodeInfoSeq
+xmlInitParser
+xmlInitParserCtxt
+xmlInitThreads
+#ifdef LIBXML_CATALOG_ENABLED
+xmlInitializeCatalog
+#endif
+xmlInitializeGlobalState
+xmlInitializePredefinedEntities
+xmlIsBaseChar
+xmlIsBlank
+xmlIsBlankNode
+xmlIsChar
+xmlIsCombining
+xmlIsDigit
+xmlIsExtender
+xmlIsID
+xmlIsIdeographic
+xmlIsLetter
+xmlIsMainThread
+xmlIsMixedElement
+xmlIsPubidChar
+xmlIsRef
+#ifdef LIBXML_HTML_ENABLED
+xmlIsXHTML
+#endif
+xmlKeepBlanksDefault
+xmlLastElementChild
+xmlLineNumbersDefault
+xmlLinkGetData
+xmlListAppend
+xmlListClear
+xmlListCopy
+xmlListCreate
+xmlListDelete
+xmlListDup
+xmlListEmpty
+xmlListEnd
+xmlListFront
+xmlListInsert
+xmlListMerge
+xmlListPopBack
+xmlListPopFront
+xmlListPushBack
+xmlListPushFront
+xmlListRemoveAll
+xmlListRemoveFirst
+xmlListRemoveLast
+xmlListReverse
+xmlListReverseSearch
+xmlListReverseWalk
+xmlListSearch
+xmlListSize
+xmlListSort
+xmlListWalk
+#ifdef LIBXML_CATALOG_ENABLED
+xmlLoadACatalog
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlLoadCatalog
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+xmlLoadCatalogs
+#endif
+xmlLoadExternalEntity
+#ifdef LIBXML_CATALOG_ENABLED
+xmlLoadSGMLSuperCatalog
+#endif
+xmlLockLibrary
+#ifdef LIBXML_DEBUG_ENABLED
+xmlLsCountNode
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlLsOneNode
+#endif
+#ifdef DEBUG_MEMORY_LOCATION
+xmlMallocAtomicLoc
+#endif
+#ifdef DEBUG_MEMORY_LOCATION
+xmlMallocLoc
+#endif
+xmlMemBlocks
+xmlMemDisplay
+xmlMemDisplayLast
+xmlMemFree
+xmlMemGet
+xmlMemMalloc
+xmlMemRealloc
+xmlMemSetup
+xmlMemShow
+#ifdef DEBUG_MEMORY_LOCATION
+xmlMemStrdupLoc
+#endif
+xmlMemUsed
+xmlMemoryDump
+xmlMemoryStrdup
+xmlModuleClose
+xmlModuleFree
+xmlModuleOpen
+xmlModuleSymbol
+xmlMutexLock
+xmlMutexUnlock
+xmlNamespaceParseNCName
+xmlNamespaceParseNSDef
+xmlNamespaceParseQName
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPCheckResponse
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPCleanup
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPClose
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPCloseConnection
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPConnect
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPConnectTo
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPCwd
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPDele
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPFreeCtxt
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPGet
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPGetConnection
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPGetResponse
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPGetSocket
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPInit
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPList
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPNewCtxt
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPOpen
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPProxy
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPQuit
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPRead
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPScanProxy
+#endif
+#ifdef LIBXML_FTP_ENABLED
+xmlNanoFTPUpdateURL
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPAuthHeader
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPCleanup
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPClose
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPContentLength
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPEncoding
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPFetch
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPInit
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPMethod
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPMethodRedir
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPMimeType
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPOpen
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPOpenRedir
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPRead
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPRedir
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPReturnCode
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPSave
+#endif
+#ifdef LIBXML_HTTP_ENABLED
+xmlNanoHTTPScanProxy
+#endif
+#ifdef LIBXML_AUTOMATA_ENABLED
+xmlNewAutomata
+#endif
+xmlNewCDataBlock
+#ifdef LIBXML_CATALOG_ENABLED
+xmlNewCatalog
+#endif
+xmlNewCharEncodingHandler
+xmlNewCharRef
+xmlNewChild
+xmlNewComment
+xmlNewDoc
+xmlNewDocComment
+xmlNewDocElementContent
+xmlNewDocFragment
+xmlNewDocNode
+xmlNewDocNodeEatName
+xmlNewDocPI
+xmlNewDocProp
+xmlNewDocRawNode
+xmlNewDocText
+xmlNewDocTextLen
+xmlNewDtd
+xmlNewElementContent
+xmlNewEntity
+xmlNewEntityInputStream
+xmlNewGlobalNs
+xmlNewIOInputStream
+xmlNewInputFromFile
+xmlNewInputStream
+xmlNewMutex
+xmlNewNode
+xmlNewNodeEatName
+xmlNewNs
+xmlNewNsProp
+xmlNewNsPropEatName
+xmlNewPI
+xmlNewParserCtxt
+xmlNewProp
+xmlNewRMutex
+xmlNewReference
+xmlNewStringInputStream
+xmlNewText
+xmlNewTextChild
+xmlNewTextLen
+xmlNewTextReader
+xmlNewTextReaderFilename
+xmlNewTextWriter
+xmlNewTextWriterDoc
+xmlNewTextWriterFilename
+xmlNewTextWriterMemory
+xmlNewTextWriterPushParser
+xmlNewTextWriterTree
+xmlNewValidCtxt
+xmlNextChar
+xmlNextElementSibling
+xmlNoNetExternalEntityLoader
+xmlNodeAddContent
+xmlNodeAddContentLen
+xmlNodeBufGetContent
+xmlNodeDump
+xmlNodeDumpOutput
+xmlNodeGetBase
+xmlNodeGetContent
+xmlNodeGetLang
+xmlNodeGetSpacePreserve
+xmlNodeIsText
+xmlNodeListGetRawString
+xmlNodeListGetString
+xmlNodeSetBase
+xmlNodeSetContent
+xmlNodeSetContentLen
+xmlNodeSetLang
+xmlNodeSetName
+xmlNodeSetSpacePreserve
+xmlNormalizeURIPath
+xmlNormalizeWindowsPath
+xmlOutputBufferClose
+xmlOutputBufferCreateBuffer
+xmlOutputBufferCreateFd
+xmlOutputBufferCreateFile
+xmlOutputBufferCreateFilename
+xmlOutputBufferCreateFilenameDefault
+xmlOutputBufferCreateIO
+xmlOutputBufferFlush
+xmlOutputBufferWrite
+xmlOutputBufferWriteEscape
+xmlOutputBufferWriteString
+xmlParseAttValue
+xmlParseAttribute
+xmlParseAttributeListDecl
+xmlParseAttributeType
+xmlParseBalancedChunkMemory
+xmlParseBalancedChunkMemoryRecover
+xmlParseCDSect
+#ifdef LIBXML_CATALOG_ENABLED
+xmlParseCatalogFile
+#endif
+xmlParseCharData
+xmlParseCharEncoding
+xmlParseCharRef
+xmlParseChunk
+xmlParseComment
+xmlParseContent
+xmlParseCtxtExternalEntity
+xmlParseDTD
+xmlParseDefaultDecl
+xmlParseDoc
+xmlParseDocTypeDecl
+xmlParseDocument
+xmlParseElement
+xmlParseElementChildrenContentDecl
+xmlParseElementContentDecl
+xmlParseElementDecl
+xmlParseElementMixedContentDecl
+xmlParseEncName
+xmlParseEncodingDecl
+xmlParseEndTag
+xmlParseEntity
+xmlParseEntityDecl
+xmlParseEntityRef
+xmlParseEntityValue
+xmlParseEnumeratedType
+xmlParseEnumerationType
+xmlParseExtParsedEnt
+xmlParseExternalEntity
+xmlParseExternalID
+xmlParseExternalSubset
+xmlParseFile
+xmlParseInNodeContext
+xmlParseMarkupDecl
+xmlParseMemory
+xmlParseMisc
+xmlParseName
+xmlParseNamespace
+xmlParseNmtoken
+xmlParseNotationDecl
+xmlParseNotationType
+xmlParsePEReference
+xmlParsePI
+xmlParsePITarget
+xmlParsePubidLiteral
+xmlParseQuotedString
+xmlParseReference
+xmlParseSDDecl
+xmlParseStartTag
+xmlParseSystemLiteral
+xmlParseTextDecl
+xmlParseURI
+xmlParseURIRaw
+xmlParseURIReference
+xmlParseVersionInfo
+xmlParseVersionNum
+xmlParseXMLDecl
+xmlParserAddNodeInfo
+xmlParserError
+xmlParserFindNodeInfo
+xmlParserFindNodeInfoIndex
+xmlParserGetDirectory
+xmlParserHandlePEReference
+xmlParserHandleReference
+xmlParserInputBufferCreateFd
+xmlParserInputBufferCreateFile
+xmlParserInputBufferCreateFilename
+xmlParserInputBufferCreateFilenameDefault
+xmlParserInputBufferCreateIO
+xmlParserInputBufferCreateMem
+xmlParserInputBufferCreateStatic
+xmlParserInputBufferGrow
+xmlParserInputBufferPush
+xmlParserInputBufferRead
+xmlParserInputGrow
+xmlParserInputRead
+xmlParserInputShrink
+xmlParserPrintFileContext
+xmlParserPrintFileInfo
+xmlParserValidityError
+xmlParserValidityWarning
+xmlParserWarning
+xmlPathToURI
+xmlPatternFromRoot
+xmlPatternGetStreamCtxt
+xmlPatternMatch
+xmlPatternMaxDepth
+xmlPatternMinDepth
+xmlPatternStreamable
+xmlPatterncompile
+xmlPedanticParserDefault
+xmlPopInput
+xmlPopInputCallbacks
+xmlPreviousElementSibling
+xmlPrintURI
+xmlPushInput
+xmlRMutexLock
+xmlRMutexUnlock
+xmlReadDoc
+xmlReadFd
+xmlReadFile
+xmlReadIO
+xmlReadMemory
+xmlReaderForDoc
+xmlReaderForFd
+xmlReaderForFile
+xmlReaderForIO
+xmlReaderForMemory
+xmlReaderNewDoc
+xmlReaderNewFd
+xmlReaderNewFile
+xmlReaderNewIO
+xmlReaderNewMemory
+xmlReaderNewWalker
+xmlReaderWalker
+#ifdef DEBUG_MEMORY_LOCATION
+xmlReallocLoc
+#endif
+xmlReconciliateNs
+xmlRecoverDoc
+xmlRecoverFile
+xmlRecoverMemory
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegExecErrInfo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegExecNextValues
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegExecPushString
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegExecPushString2
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegFreeExecCtxt
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegFreeRegexp
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegNewExecCtxt
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegexpCompile
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegexpExec
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegexpIsDeterminist
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlRegexpPrint
+#endif
+xmlRegisterCharEncodingHandler
+xmlRegisterDefaultInputCallbacks
+xmlRegisterDefaultOutputCallbacks
+#ifdef LIBXML_HTML_ENABLED
+xmlRegisterHTTPPostCallbacks
+#endif
+xmlRegisterInputCallbacks
+xmlRegisterNodeDefault
+xmlRegisterOutputCallbacks
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGCleanupTypes
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGDump
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGDumpTree
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGFree
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGFreeParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGFreeValidCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGGetParserErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGGetValidErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGInitTypes
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGNewDocParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGNewMemParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGNewParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGNewValidCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGParse
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGSetParserErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGSetParserStructuredErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGSetValidErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGSetValidStructuredErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGValidateDoc
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGValidateFullElement
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGValidatePopElement
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGValidatePushCData
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxNGValidatePushElement
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlRelaxParserSetFlag
+#endif
+xmlRemoveID
+xmlRemoveProp
+xmlRemoveRef
+xmlReplaceNode
+xmlResetError
+xmlResetLastError
+xmlSAX2AttributeDecl
+xmlSAX2CDataBlock
+xmlSAX2Characters
+xmlSAX2Comment
+xmlSAX2ElementDecl
+xmlSAX2EndDocument
+xmlSAX2EndElement
+xmlSAX2EndElementNs
+xmlSAX2EntityDecl
+xmlSAX2ExternalSubset
+xmlSAX2GetColumnNumber
+xmlSAX2GetEntity
+xmlSAX2GetLineNumber
+xmlSAX2GetParameterEntity
+xmlSAX2GetPublicId
+xmlSAX2GetSystemId
+xmlSAX2HasExternalSubset
+xmlSAX2HasInternalSubset
+xmlSAX2IgnorableWhitespace
+xmlSAX2InitDefaultSAXHandler
+xmlSAX2InitDocbDefaultSAXHandler
+xmlSAX2InitHtmlDefaultSAXHandler
+xmlSAX2InternalSubset
+xmlSAX2IsStandalone
+xmlSAX2NotationDecl
+xmlSAX2ProcessingInstruction
+xmlSAX2Reference
+xmlSAX2ResolveEntity
+xmlSAX2SetDocumentLocator
+xmlSAX2StartDocument
+xmlSAX2StartElement
+xmlSAX2StartElementNs
+xmlSAX2UnparsedEntityDecl
+xmlSAXDefaultVersion
+xmlSAXParseDTD
+xmlSAXParseDoc
+xmlSAXParseEntity
+xmlSAXParseFile
+xmlSAXParseFileWithData
+xmlSAXParseMemory
+xmlSAXParseMemoryWithData
+xmlSAXUserParseFile
+xmlSAXUserParseMemory
+xmlSAXVersion
+xmlSaveClose
+xmlSaveDoc
+xmlSaveFile
+xmlSaveFileEnc
+xmlSaveFileTo
+xmlSaveFlush
+xmlSaveFormatFile
+xmlSaveFormatFileEnc
+xmlSaveFormatFileTo
+xmlSaveSetAttrEscape
+xmlSaveSetEscape
+xmlSaveToBuffer
+xmlSaveToFd
+xmlSaveToFilename
+xmlSaveToIO
+xmlSaveTree
+xmlSaveUri
+xmlScanName
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCheckFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCleanupTypes
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCollapseString
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCompareValues
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCompareValuesWhtsp
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaCopyValue
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaDump
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaFree
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaFreeFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaFreeParserCtxt
+#endif
+xmlSchemaFreeType
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaFreeValidCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaFreeValue
+#endif
+xmlSchemaFreeWildcard
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetBuiltInListSimpleTypeItemType
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetBuiltInType
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetCanonValue
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetCanonValueWhtsp
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetFacetValueAsULong
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetParserErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetPredefinedType
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetValType
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaGetValidErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaInitTypes
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaIsBuiltInTypeFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaIsValid
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewDocParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewMemParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewNOTATIONValue
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewQNameValue
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewStringValue
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaNewValidCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaParse
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSAXPlug
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSAXUnplug
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSetParserErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSetParserStructuredErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSetValidErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSetValidOptions
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaSetValidStructuredErrors
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValPredefTypeNode
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValPredefTypeNodeNoNorm
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidCtxtGetOptions
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidCtxtGetParserCtxt
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateDoc
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateFacetWhtsp
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateFile
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateLengthFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateLengthFacetWhtsp
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateListSimpleTypeFacet
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateOneElement
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidatePredefinedType
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValidateStream
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValueAppend
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValueGetAsBoolean
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValueGetAsString
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaValueGetNext
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlSchemaWhiteSpaceReplace
+#endif
+xmlSchematronFree
+xmlSchematronFreeParserCtxt
+xmlSchematronFreeValidCtxt
+xmlSchematronNewDocParserCtxt
+xmlSchematronNewMemParserCtxt
+xmlSchematronNewParserCtxt
+xmlSchematronNewValidCtxt
+xmlSchematronParse
+xmlSchematronSetValidStructuredErrors
+xmlSchematronValidateDoc
+xmlSearchNs
+xmlSearchNsByHref
+xmlSetBufferAllocationScheme
+xmlSetCompressMode
+xmlSetDocCompressMode
+xmlSetEntityReferenceFunc
+xmlSetExternalEntityLoader
+xmlSetFeature
+xmlSetGenericErrorFunc
+xmlSetListDoc
+xmlSetNs
+xmlSetNsProp
+xmlSetProp
+xmlSetStructuredErrorFunc
+xmlSetTreeDoc
+xmlSetupParserForBuffer
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShell
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellBase
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellCat
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellDir
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellDu
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellList
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellLoad
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellPrintNode
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellPrintXPathError
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellPrintXPathResult
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellPwd
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellSave
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellValidate
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+xmlShellWrite
+#endif
+xmlSkipBlankChars
+xmlSnprintfElementContent
+xmlSplitQName
+xmlSplitQName2
+xmlSplitQName3
+xmlSprintfElementContent
+xmlStopParser
+xmlStrEqual
+xmlStrPrintf
+xmlStrQEqual
+xmlStrVPrintf
+xmlStrcasecmp
+xmlStrcasestr
+xmlStrcat
+xmlStrchr
+xmlStrcmp
+xmlStrdup
+xmlStreamPop
+xmlStreamPush
+xmlStreamPushAttr
+xmlStreamPushNode
+xmlStreamWantsAnyNode
+xmlStringCurrentChar
+xmlStringDecodeEntities
+xmlStringGetNodeList
+xmlStringLenDecodeEntities
+xmlStringLenGetNodeList
+xmlStrlen
+xmlStrncasecmp
+xmlStrncat
+xmlStrncatNew
+xmlStrncmp
+xmlStrndup
+xmlStrstr
+xmlStrsub
+xmlSubstituteEntitiesDefault
+xmlSwitchEncoding
+xmlSwitchInputEncoding
+xmlSwitchToEncoding
+xmlTextConcat
+xmlTextMerge
+xmlTextReaderAttributeCount
+xmlTextReaderBaseUri
+xmlTextReaderByteConsumed
+xmlTextReaderClose
+xmlTextReaderConstBaseUri
+xmlTextReaderConstEncoding
+xmlTextReaderConstLocalName
+xmlTextReaderConstName
+xmlTextReaderConstNamespaceUri
+xmlTextReaderConstPrefix
+xmlTextReaderConstString
+xmlTextReaderConstValue
+xmlTextReaderConstXmlLang
+xmlTextReaderConstXmlVersion
+xmlTextReaderCurrentDoc
+xmlTextReaderCurrentNode
+xmlTextReaderDepth
+xmlTextReaderExpand
+xmlTextReaderGetAttribute
+xmlTextReaderGetAttributeNo
+xmlTextReaderGetAttributeNs
+xmlTextReaderGetErrorHandler
+xmlTextReaderGetParserColumnNumber
+xmlTextReaderGetParserLineNumber
+xmlTextReaderGetParserProp
+xmlTextReaderGetRemainder
+xmlTextReaderHasAttributes
+xmlTextReaderHasValue
+xmlTextReaderIsDefault
+xmlTextReaderIsEmptyElement
+xmlTextReaderIsNamespaceDecl
+xmlTextReaderIsValid
+xmlTextReaderLocalName
+xmlTextReaderLocatorBaseURI
+xmlTextReaderLocatorLineNumber
+xmlTextReaderLookupNamespace
+xmlTextReaderMoveToAttribute
+xmlTextReaderMoveToAttributeNo
+xmlTextReaderMoveToAttributeNs
+xmlTextReaderMoveToElement
+xmlTextReaderMoveToFirstAttribute
+xmlTextReaderMoveToNextAttribute
+xmlTextReaderName
+xmlTextReaderNamespaceUri
+xmlTextReaderNext
+xmlTextReaderNextSibling
+xmlTextReaderNodeType
+xmlTextReaderNormalization
+xmlTextReaderPrefix
+xmlTextReaderPreserve
+xmlTextReaderPreservePattern
+xmlTextReaderQuoteChar
+xmlTextReaderRead
+xmlTextReaderReadAttributeValue
+xmlTextReaderReadInnerXml
+xmlTextReaderReadOuterXml
+xmlTextReaderReadState
+xmlTextReaderReadString
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlTextReaderRelaxNGSetSchema
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+xmlTextReaderRelaxNGValidate
+#endif
+xmlTextReaderSchemaValidate
+xmlTextReaderSchemaValidateCtxt
+xmlTextReaderSetErrorHandler
+xmlTextReaderSetParserProp
+xmlTextReaderSetSchema
+xmlTextReaderSetStructuredErrorHandler
+xmlTextReaderSetup
+xmlTextReaderStandalone
+xmlTextReaderValue
+xmlTextReaderXmlLang
+xmlTextWriterEndAttribute
+xmlTextWriterEndCDATA
+xmlTextWriterEndComment
+xmlTextWriterEndDTD
+xmlTextWriterEndDTDAttlist
+xmlTextWriterEndDTDElement
+xmlTextWriterEndDTDEntity
+xmlTextWriterEndDocument
+xmlTextWriterEndElement
+xmlTextWriterEndPI
+xmlTextWriterFlush
+xmlTextWriterFullEndElement
+xmlTextWriterSetIndent
+xmlTextWriterSetIndentString
+xmlTextWriterStartAttribute
+xmlTextWriterStartAttributeNS
+xmlTextWriterStartCDATA
+xmlTextWriterStartComment
+xmlTextWriterStartDTD
+xmlTextWriterStartDTDAttlist
+xmlTextWriterStartDTDElement
+xmlTextWriterStartDTDEntity
+xmlTextWriterStartDocument
+xmlTextWriterStartElement
+xmlTextWriterStartElementNS
+xmlTextWriterStartPI
+xmlTextWriterWriteAttribute
+xmlTextWriterWriteAttributeNS
+xmlTextWriterWriteBase64
+xmlTextWriterWriteBinHex
+xmlTextWriterWriteCDATA
+xmlTextWriterWriteComment
+xmlTextWriterWriteDTD
+xmlTextWriterWriteDTDAttlist
+xmlTextWriterWriteDTDElement
+xmlTextWriterWriteDTDEntity
+xmlTextWriterWriteDTDExternalEntity
+xmlTextWriterWriteDTDExternalEntityContents
+xmlTextWriterWriteDTDInternalEntity
+xmlTextWriterWriteDTDNotation
+xmlTextWriterWriteElement
+xmlTextWriterWriteElementNS
+xmlTextWriterWriteFormatAttribute
+xmlTextWriterWriteFormatAttributeNS
+xmlTextWriterWriteFormatCDATA
+xmlTextWriterWriteFormatComment
+xmlTextWriterWriteFormatDTD
+xmlTextWriterWriteFormatDTDAttlist
+xmlTextWriterWriteFormatDTDElement
+xmlTextWriterWriteFormatDTDInternalEntity
+xmlTextWriterWriteFormatElement
+xmlTextWriterWriteFormatElementNS
+xmlTextWriterWriteFormatPI
+xmlTextWriterWriteFormatRaw
+xmlTextWriterWriteFormatString
+xmlTextWriterWritePI
+xmlTextWriterWriteRaw
+xmlTextWriterWriteRawLen
+xmlTextWriterWriteString
+xmlTextWriterWriteVFormatAttribute
+xmlTextWriterWriteVFormatAttributeNS
+xmlTextWriterWriteVFormatCDATA
+xmlTextWriterWriteVFormatComment
+xmlTextWriterWriteVFormatDTD
+xmlTextWriterWriteVFormatDTDAttlist
+xmlTextWriterWriteVFormatDTDElement
+xmlTextWriterWriteVFormatDTDInternalEntity
+xmlTextWriterWriteVFormatElement
+xmlTextWriterWriteVFormatElementNS
+xmlTextWriterWriteVFormatPI
+xmlTextWriterWriteVFormatRaw
+xmlTextWriterWriteVFormatString
+xmlThrDefBufferAllocScheme
+xmlThrDefDefaultBufferSize
+xmlThrDefDeregisterNodeDefault
+xmlThrDefDoValidityCheckingDefaultValue
+xmlThrDefGetWarningsDefaultValue
+xmlThrDefIndentTreeOutput
+xmlThrDefKeepBlanksDefaultValue
+xmlThrDefLineNumbersDefaultValue
+xmlThrDefLoadExtDtdDefaultValue
+xmlThrDefOutputBufferCreateFilenameDefault
+xmlThrDefParserDebugEntities
+xmlThrDefParserInputBufferCreateFilenameDefault
+xmlThrDefPedanticParserDefaultValue
+xmlThrDefRegisterNodeDefault
+xmlThrDefSaveNoEmptyTags
+xmlThrDefSetGenericErrorFunc
+xmlThrDefSetStructuredErrorFunc
+xmlThrDefSubstituteEntitiesDefaultValue
+xmlThrDefTreeIndentString
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsAegeanNumbers
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsAlphabeticPresentationForms
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsArabic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsArabicPresentationFormsA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsArabicPresentationFormsB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsArmenian
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsArrows
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBasicLatin
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBengali
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBlock
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBlockElements
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBopomofo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBopomofoExtended
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBoxDrawing
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBraillePatterns
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsBuhid
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsByzantineMusicalSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKCompatibility
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKCompatibilityForms
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKCompatibilityIdeographs
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKCompatibilityIdeographsSupplement
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKRadicalsSupplement
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKSymbolsandPunctuation
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKUnifiedIdeographs
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKUnifiedIdeographsExtensionA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCJKUnifiedIdeographsExtensionB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCat
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatC
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatCc
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatCf
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatCo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatCs
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatL
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatLl
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatLm
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatLo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatLt
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatLu
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatM
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatMc
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatMe
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatMn
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatN
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatNd
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatNl
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatNo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatP
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPc
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPd
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPe
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPf
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPi
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatPs
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatS
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatSc
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatSk
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatSm
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatSo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatZ
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatZl
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatZp
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCatZs
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCherokee
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCombiningDiacriticalMarks
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCombiningDiacriticalMarksforSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCombiningHalfMarks
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCombiningMarksforSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsControlPictures
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCurrencySymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCypriotSyllabary
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCyrillic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsCyrillicSupplement
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsDeseret
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsDevanagari
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsDingbats
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsEnclosedAlphanumerics
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsEnclosedCJKLettersandMonths
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsEthiopic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGeneralPunctuation
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGeometricShapes
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGeorgian
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGothic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGreek
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGreekExtended
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGreekandCoptic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGujarati
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsGurmukhi
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHalfwidthandFullwidthForms
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHangulCompatibilityJamo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHangulJamo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHangulSyllables
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHanunoo
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHebrew
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHighPrivateUseSurrogates
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHighSurrogates
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsHiragana
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsIPAExtensions
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsIdeographicDescriptionCharacters
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKanbun
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKangxiRadicals
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKannada
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKatakana
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKatakanaPhoneticExtensions
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKhmer
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsKhmerSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLao
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLatin1Supplement
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLatinExtendedA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLatinExtendedAdditional
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLatinExtendedB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLetterlikeSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLimbu
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLinearBIdeograms
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLinearBSyllabary
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsLowSurrogates
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMalayalam
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMathematicalAlphanumericSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMathematicalOperators
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMiscellaneousMathematicalSymbolsA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMiscellaneousMathematicalSymbolsB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMiscellaneousSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMiscellaneousSymbolsandArrows
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMiscellaneousTechnical
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMongolian
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMusicalSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsMyanmar
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsNumberForms
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsOgham
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsOldItalic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsOpticalCharacterRecognition
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsOriya
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsOsmanya
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsPhoneticExtensions
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsPrivateUse
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsPrivateUseArea
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsRunic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsShavian
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSinhala
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSmallFormVariants
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSpacingModifierLetters
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSpecials
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSuperscriptsandSubscripts
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSupplementalArrowsA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSupplementalArrowsB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSupplementalMathematicalOperators
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSupplementaryPrivateUseAreaA
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSupplementaryPrivateUseAreaB
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsSyriac
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTagalog
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTagbanwa
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTags
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTaiLe
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTaiXuanJingSymbols
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTamil
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTelugu
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsThaana
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsThai
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsTibetan
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsUgaritic
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsUnifiedCanadianAboriginalSyllabics
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsVariationSelectors
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsVariationSelectorsSupplement
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsYiRadicals
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsYiSyllables
+#endif
+#ifdef LIBXML_REGEXP_ENABLED
+xmlUCSIsYijingHexagramSymbols
+#endif
+xmlURIEscape
+xmlURIEscapeStr
+xmlURIUnescapeString
+xmlUTF8Charcmp
+xmlUTF8Size
+xmlUTF8Strlen
+xmlUTF8Strloc
+xmlUTF8Strndup
+xmlUTF8Strpos
+xmlUTF8Strsize
+xmlUTF8Strsub
+xmlUnlinkNode
+xmlUnlockLibrary
+xmlUnsetNsProp
+xmlUnsetProp
+#ifdef LIBXML_REGEXP_ENABLED
+xmlValidBuildContentModel
+#endif
+xmlValidCtxtNormalizeAttributeValue
+xmlValidGetPotentialChildren
+xmlValidGetValidElements
+xmlValidNormalizeAttributeValue
+xmlValidateAttributeDecl
+xmlValidateAttributeValue
+xmlValidateDocument
+xmlValidateDocumentFinal
+xmlValidateDtd
+xmlValidateDtdFinal
+xmlValidateElement
+xmlValidateElementDecl
+xmlValidateNCName
+xmlValidateNMToken
+xmlValidateName
+xmlValidateNameValue
+xmlValidateNamesValue
+xmlValidateNmtokenValue
+xmlValidateNmtokensValue
+xmlValidateNotationDecl
+xmlValidateNotationUse
+xmlValidateOneAttribute
+xmlValidateOneElement
+xmlValidateOneNamespace
+xmlValidatePopElement
+xmlValidatePushCData
+xmlValidatePushElement
+xmlValidateQName
+xmlValidateRoot
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeFreeContext
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeNewContext
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcess
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessFlags
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessFlagsData
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessNode
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessTree
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessTreeFlags
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeProcessTreeFlagsData
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+xmlXIncludeSetFlags
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathAddValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathBooleanFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastBooleanToNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastBooleanToString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNodeSetToBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNodeSetToNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNodeSetToString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNodeToNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNodeToString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNumberToBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastNumberToString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastStringToBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastStringToNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastToBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastToNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCastToString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCeilingFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCmpNodes
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCompareValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCompile
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCompiledEval
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCompiledEvalToBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathConcatFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathContainsFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathContextSetCache
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathConvertBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathConvertNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathConvertString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCountFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathCtxtCompile
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+xmlXPathDebugDumpCompExpr
+#endif
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+#ifdef LIBXML_DEBUG_ENABLED
+xmlXPathDebugDumpObject
+#endif
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathDifference
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathDistinct
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathDistinctSorted
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathDivValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEqualValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathErr
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEval
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEvalExpr
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEvalExpression
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEvalPredicate
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathEvaluatePredicateResult
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFalseFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFloorFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeCompExpr
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeContext
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeNodeSet
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeNodeSetList
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeObject
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFreeParserContext
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFunctionLookup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathFunctionLookupNS
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathHasSameNodes
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathIdFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathInit
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathIntersection
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathIsInf
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathIsNaN
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathIsNodeType
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathLangFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathLastFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathLeading
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathLeadingSorted
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathLocalNameFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathModValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathMultValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNamespaceURIFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewCString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewContext
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewFloat
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewNodeSet
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewNodeSetList
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewParserContext
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNewValueTree
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextAncestor
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextAncestorOrSelf
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextAttribute
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextChild
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextDescendant
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextDescendantOrSelf
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextFollowing
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextFollowingSibling
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextNamespace
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextParent
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextPreceding
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextPrecedingSibling
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNextSelf
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeLeading
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeLeadingSorted
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetAdd
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetAddNs
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetAddUnique
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetContains
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetCreate
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetDel
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetFreeNs
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetMerge
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetRemove
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeSetSort
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeTrailing
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNodeTrailingSorted
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNormalizeFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNotEqualValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNotFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNsLookup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathNumberFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathObjectCopy
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathOrderDocElems
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathParseNCName
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathParseName
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPopBoolean
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPopExternal
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPopNodeSet
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPopNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPopString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathPositionFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterAllFunctions
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterFunc
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterFuncLookup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterFuncNS
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterNs
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterVariable
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterVariableLookup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisterVariableNS
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisteredFuncsCleanup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisteredNsCleanup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRegisteredVariablesCleanup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRoot
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathRoundFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathStartsWithFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathStringEvalNumber
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathStringFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathStringLengthFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathSubValues
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathSubstringAfterFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathSubstringBeforeFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathSubstringFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathSumFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathTrailing
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathTrailingSorted
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathTranslateFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathTrueFunction
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathValueFlipSign
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathVariableLookup
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathVariableLookupNS
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathWrapCString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathWrapExternal
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathWrapNodeSet
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPathWrapString
+#endif
+#ifdef LIBXML_XPATH_ENABLED
+xmlXPatherror
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrBuildNodeList
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrEval
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrEvalRangePredicate
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrFreeLocationSet
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrLocationSetAdd
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrLocationSetCreate
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrLocationSetDel
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrLocationSetMerge
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrLocationSetRemove
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewCollapsedRange
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewContext
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewLocationSetNodeSet
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewLocationSetNodes
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRange
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRangeNodeObject
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRangeNodePoint
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRangeNodes
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRangePointNode
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrNewRangePoints
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrRangeToFunction
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+xmlXPtrWrapLocationSet
+#endif
diff --git a/src/xinclude.c b/src/xinclude.c
new file mode 100644
index 0000000..2916ffa
--- /dev/null
+++ b/src/xinclude.c
@@ -0,0 +1,2591 @@
+/*
+ * xinclude.c : Code to implement XInclude processing
+ *
+ * World Wide Web Consortium W3C Last Call Working Draft 10 November 2003
+ * http://www.w3.org/TR/2003/WD-xinclude-20031110
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/uri.h>
+#include <libxml/xpointer.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/encoding.h>
+#include <libxml/globals.h>
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+
+
+#define XINCLUDE_MAX_DEPTH 40
+
+/* #define DEBUG_XINCLUDE */
+#ifdef DEBUG_XINCLUDE
+#ifdef LIBXML_DEBUG_ENABLED
+#include <libxml/debugXML.h>
+#endif
+#endif
+
+/************************************************************************
+ *									*
+ *			XInclude context handling			*
+ *									*
+ ************************************************************************/
+
+/*
+ * An XInclude context
+ */
+typedef xmlChar *xmlURL;
+
+typedef struct _xmlXIncludeRef xmlXIncludeRef;
+typedef xmlXIncludeRef *xmlXIncludeRefPtr;
+struct _xmlXIncludeRef {
+    xmlChar              *URI; /* the fully resolved resource URL */
+    xmlChar         *fragment; /* the fragment in the URI */
+    xmlDocPtr		  doc; /* the parsed document */
+    xmlNodePtr            ref; /* the node making the reference in the source */
+    xmlNodePtr            inc; /* the included copy */
+    int                   xml; /* xml or txt */
+    int                 count; /* how many refs use that specific doc */
+    xmlXPathObjectPtr    xptr; /* the xpointer if needed */
+    int		      emptyFb; /* flag to show fallback empty */
+};
+
+struct _xmlXIncludeCtxt {
+    xmlDocPtr             doc; /* the source document */
+    int               incBase; /* the first include for this document */
+    int                 incNr; /* number of includes */
+    int                incMax; /* size of includes tab */
+    xmlXIncludeRefPtr *incTab; /* array of included references */
+
+    int                 txtNr; /* number of unparsed documents */
+    int                txtMax; /* size of unparsed documents tab */
+    xmlNodePtr        *txtTab; /* array of unparsed text nodes */
+    xmlURL         *txturlTab; /* array of unparsed text URLs */
+
+    xmlChar *             url; /* the current URL processed */
+    int                 urlNr; /* number of URLs stacked */
+    int                urlMax; /* size of URL stack */
+    xmlChar *         *urlTab; /* URL stack */
+
+    int              nbErrors; /* the number of errors detected */
+    int                legacy; /* using XINCLUDE_OLD_NS */
+    int            parseFlags; /* the flags used for parsing XML documents */
+    xmlChar *		 base; /* the current xml:base */
+
+    void            *_private; /* application data */
+};
+
+static int
+xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree);
+
+
+/************************************************************************
+ *									*
+ * 			XInclude error handler				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXIncludeErrMemory:
+ * @extra:  extra information
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
+                     const char *extra)
+{
+    if (ctxt != NULL)
+	ctxt->nbErrors++;
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
+                    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
+		    extra, NULL, NULL, 0, 0,
+		    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlXIncludeErr:
+ * @ctxt: the XInclude context
+ * @node: the context node
+ * @msg:  the error message
+ * @extra:  extra information
+ *
+ * Handle an XInclude error
+ */
+static void
+xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
+               const char *msg, const xmlChar *extra)
+{
+    if (ctxt != NULL)
+	ctxt->nbErrors++;
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
+                    error, XML_ERR_ERROR, NULL, 0,
+		    (const char *) extra, NULL, NULL, 0, 0,
+		    msg, (const char *) extra);
+}
+
+#if 0
+/**
+ * xmlXIncludeWarn:
+ * @ctxt: the XInclude context
+ * @node: the context node
+ * @msg:  the error message
+ * @extra:  extra information
+ *
+ * Emit an XInclude warning.
+ */
+static void
+xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
+               const char *msg, const xmlChar *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
+                    error, XML_ERR_WARNING, NULL, 0,
+		    (const char *) extra, NULL, NULL, 0, 0,
+		    msg, (const char *) extra);
+}
+#endif
+
+/**
+ * xmlXIncludeGetProp:
+ * @ctxt:  the XInclude context
+ * @cur:  the node
+ * @name:  the attribute name
+ *
+ * Get an XInclude attribute
+ *
+ * Returns the value (to be freed) or NULL if not found
+ */
+static xmlChar *
+xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
+                   const xmlChar *name) {
+    xmlChar *ret;
+
+    ret = xmlGetNsProp(cur, XINCLUDE_NS, name);
+    if (ret != NULL)
+        return(ret);
+    if (ctxt->legacy != 0) {
+	ret = xmlGetNsProp(cur, XINCLUDE_OLD_NS, name);
+	if (ret != NULL)
+	    return(ret);
+    }
+    ret = xmlGetProp(cur, name);
+    return(ret);
+}
+/**
+ * xmlXIncludeFreeRef:
+ * @ref: the XInclude reference
+ *
+ * Free an XInclude reference
+ */
+static void
+xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
+    if (ref == NULL)
+	return;
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Freeing ref\n");
+#endif
+    if (ref->doc != NULL) {
+#ifdef DEBUG_XINCLUDE
+	xmlGenericError(xmlGenericErrorContext, "Freeing doc %s\n", ref->URI);
+#endif
+	xmlFreeDoc(ref->doc);
+    }
+    if (ref->URI != NULL)
+	xmlFree(ref->URI);
+    if (ref->fragment != NULL)
+	xmlFree(ref->fragment);
+    if (ref->xptr != NULL)
+	xmlXPathFreeObject(ref->xptr);
+    xmlFree(ref);
+}
+
+/**
+ * xmlXIncludeNewRef:
+ * @ctxt: the XInclude context
+ * @URI:  the resource URI
+ *
+ * Creates a new reference within an XInclude context
+ *
+ * Returns the new set
+ */
+static xmlXIncludeRefPtr
+xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
+	          xmlNodePtr ref) {
+    xmlXIncludeRefPtr ret;
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "New ref %s\n", URI);
+#endif
+    ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
+    if (ret == NULL) {
+        xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlXIncludeRef));
+    if (URI == NULL)
+	ret->URI = NULL;
+    else
+	ret->URI = xmlStrdup(URI);
+    ret->fragment = NULL;
+    ret->ref = ref;
+    ret->doc = NULL;
+    ret->count = 0;
+    ret->xml = 0;
+    ret->inc = NULL;
+    if (ctxt->incMax == 0) {
+	ctxt->incMax = 4;
+        ctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(ctxt->incMax *
+					      sizeof(ctxt->incTab[0]));
+        if (ctxt->incTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
+	    xmlXIncludeFreeRef(ret);
+	    return(NULL);
+	}
+    }
+    if (ctxt->incNr >= ctxt->incMax) {
+	ctxt->incMax *= 2;
+        ctxt->incTab = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
+	             ctxt->incMax * sizeof(ctxt->incTab[0]));
+        if (ctxt->incTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
+	    xmlXIncludeFreeRef(ret);
+	    return(NULL);
+	}
+    }
+    ctxt->incTab[ctxt->incNr++] = ret;
+    return(ret);
+}
+
+/**
+ * xmlXIncludeNewContext:
+ * @doc:  an XML Document
+ *
+ * Creates a new XInclude context
+ *
+ * Returns the new set
+ */
+xmlXIncludeCtxtPtr
+xmlXIncludeNewContext(xmlDocPtr doc) {
+    xmlXIncludeCtxtPtr ret;
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "New context\n");
+#endif
+    if (doc == NULL)
+	return(NULL);
+    ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
+    if (ret == NULL) {
+	xmlXIncludeErrMemory(NULL, (xmlNodePtr) doc,
+	                     "creating XInclude context");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlXIncludeCtxt));
+    ret->doc = doc;
+    ret->incNr = 0;
+    ret->incBase = 0;
+    ret->incMax = 0;
+    ret->incTab = NULL;
+    ret->nbErrors = 0;
+    return(ret);
+}
+
+/**
+ * xmlXIncludeURLPush:
+ * @ctxt:  the parser context
+ * @value:  the url
+ *
+ * Pushes a new url on top of the url stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+static int
+xmlXIncludeURLPush(xmlXIncludeCtxtPtr ctxt,
+	           const xmlChar *value)
+{
+    if (ctxt->urlNr > XINCLUDE_MAX_DEPTH) {
+	xmlXIncludeErr(ctxt, NULL, XML_XINCLUDE_RECURSION,
+	               "detected a recursion in %s\n", value);
+	return(-1);
+    }
+    if (ctxt->urlTab == NULL) {
+	ctxt->urlMax = 4;
+	ctxt->urlNr = 0;
+	ctxt->urlTab = (xmlChar * *) xmlMalloc(
+		        ctxt->urlMax * sizeof(ctxt->urlTab[0]));
+        if (ctxt->urlTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "adding URL");
+            return (-1);
+        }
+    }
+    if (ctxt->urlNr >= ctxt->urlMax) {
+        ctxt->urlMax *= 2;
+        ctxt->urlTab =
+            (xmlChar * *) xmlRealloc(ctxt->urlTab,
+                                      ctxt->urlMax *
+                                      sizeof(ctxt->urlTab[0]));
+        if (ctxt->urlTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "adding URL");
+            return (-1);
+        }
+    }
+    ctxt->url = ctxt->urlTab[ctxt->urlNr] = xmlStrdup(value);
+    return (ctxt->urlNr++);
+}
+
+/**
+ * xmlXIncludeURLPop:
+ * @ctxt: the parser context
+ *
+ * Pops the top URL from the URL stack
+ */
+static void
+xmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt)
+{
+    xmlChar * ret;
+
+    if (ctxt->urlNr <= 0)
+        return;
+    ctxt->urlNr--;
+    if (ctxt->urlNr > 0)
+        ctxt->url = ctxt->urlTab[ctxt->urlNr - 1];
+    else
+        ctxt->url = NULL;
+    ret = ctxt->urlTab[ctxt->urlNr];
+    ctxt->urlTab[ctxt->urlNr] = NULL;
+    if (ret != NULL)
+	xmlFree(ret);
+}
+
+/**
+ * xmlXIncludeFreeContext:
+ * @ctxt: the XInclude context
+ *
+ * Free an XInclude context
+ */
+void
+xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
+    int i;
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Freeing context\n");
+#endif
+    if (ctxt == NULL)
+	return;
+    while (ctxt->urlNr > 0)
+	xmlXIncludeURLPop(ctxt);
+    if (ctxt->urlTab != NULL)
+	xmlFree(ctxt->urlTab);
+    for (i = 0;i < ctxt->incNr;i++) {
+	if (ctxt->incTab[i] != NULL)
+	    xmlXIncludeFreeRef(ctxt->incTab[i]);
+    }
+    if (ctxt->txturlTab != NULL) {
+	for (i = 0;i < ctxt->txtNr;i++) {
+	    if (ctxt->txturlTab[i] != NULL)
+		xmlFree(ctxt->txturlTab[i]);
+	}
+    }
+    if (ctxt->incTab != NULL)
+	xmlFree(ctxt->incTab);
+    if (ctxt->txtTab != NULL)
+	xmlFree(ctxt->txtTab);
+    if (ctxt->txturlTab != NULL)
+	xmlFree(ctxt->txturlTab);
+    if (ctxt->base != NULL) {
+        xmlFree(ctxt->base);
+    }
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlXIncludeParseFile:
+ * @ctxt:  the XInclude context
+ * @URL:  the URL or file path
+ * 
+ * parse a document for XInclude
+ */
+static xmlDocPtr
+xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr pctxt;
+    xmlParserInputPtr inputStream;
+
+    xmlInitParser();
+
+    pctxt = xmlNewParserCtxt();
+    if (pctxt == NULL) {
+	xmlXIncludeErrMemory(ctxt, NULL, "cannot allocate parser context");
+	return(NULL);
+    }
+
+    /*
+     * pass in the application data to the parser context.
+     */
+    pctxt->_private = ctxt->_private;
+    
+    /*
+     * 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)) {
+       if (pctxt->dict != NULL)
+            xmlDictFree(pctxt->dict);
+	pctxt->dict = ctxt->doc->dict;
+	xmlDictReference(pctxt->dict);
+    }
+
+    xmlCtxtUseOptions(pctxt, ctxt->parseFlags | XML_PARSE_DTDLOAD);
+    
+    inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
+    if (inputStream == NULL) {
+	xmlFreeParserCtxt(pctxt);
+	return(NULL);
+    }
+
+    inputPush(pctxt, inputStream);
+
+    if (pctxt->directory == NULL)
+        pctxt->directory = xmlParserGetDirectory(URL);
+
+    pctxt->loadsubset |= XML_DETECT_IDS;
+
+    xmlParseDocument(pctxt);
+
+    if (pctxt->wellFormed) {
+        ret = pctxt->myDoc;
+    }
+    else {
+        ret = NULL;
+	if (pctxt->myDoc != NULL)
+	    xmlFreeDoc(pctxt->myDoc);
+        pctxt->myDoc = NULL;
+    }
+    xmlFreeParserCtxt(pctxt);
+    
+    return(ret);
+}
+
+/**
+ * xmlXIncludeAddNode:
+ * @ctxt:  the XInclude context
+ * @cur:  the new node
+ * 
+ * Add a new node to process to an XInclude context
+ */
+static int
+xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
+    xmlXIncludeRefPtr ref;
+    xmlURIPtr uri;
+    xmlChar *URL;
+    xmlChar *fragment = NULL;
+    xmlChar *href;
+    xmlChar *parse;
+    xmlChar *base;
+    xmlChar *URI;
+    int xml = 1, i; /* default Issue 64 */
+    int local = 0;
+
+
+    if (ctxt == NULL)
+	return(-1);
+    if (cur == NULL)
+	return(-1);
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Add node\n");
+#endif
+    /*
+     * read the attributes
+     */
+    href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
+    if (href == NULL) {
+	href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
+	if (href == NULL) 
+	    return(-1);
+    }
+    if ((href[0] == '#') || (href[0] == 0))
+	local = 1;
+    parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
+    if (parse != NULL) {
+	if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
+	    xml = 1;
+	else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
+	    xml = 0;
+	else {
+	    xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
+	                   "invalid value %s for 'parse'\n", parse);
+	    if (href != NULL)
+		xmlFree(href);
+	    if (parse != NULL)
+		xmlFree(parse);
+	    return(-1);
+	}
+    }
+
+    /*
+     * compute the URI
+     */
+    base = xmlNodeGetBase(ctxt->doc, cur);
+    if (base == NULL) {
+	URI = xmlBuildURI(href, ctxt->doc->URL);
+    } else {
+	URI = xmlBuildURI(href, base);
+    }
+    if (URI == NULL) {
+	xmlChar *escbase;
+	xmlChar *eschref;
+	/*
+	 * Some escaping may be needed
+	 */
+	escbase = xmlURIEscape(base);
+	eschref = xmlURIEscape(href);
+	URI = xmlBuildURI(eschref, escbase);
+	if (escbase != NULL)
+	    xmlFree(escbase);
+	if (eschref != NULL)
+	    xmlFree(eschref);
+    }
+    if (parse != NULL)
+	xmlFree(parse);
+    if (href != NULL)
+	xmlFree(href);
+    if (base != NULL)
+	xmlFree(base);
+    if (URI == NULL) {
+	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
+	               "failed build URL\n", NULL);
+	return(-1);
+    }
+    fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
+
+    /*
+     * Check the URL and remove any fragment identifier
+     */
+    uri = xmlParseURI((const char *)URI);
+    if (uri == NULL) {
+	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
+	               "invalid value URI %s\n", URI);
+	if (fragment != NULL)
+	    xmlFree(fragment);
+	xmlFree(URI);
+	return(-1);
+    }
+
+    if (uri->fragment != NULL) {
+        if (ctxt->legacy != 0) {
+	    if (fragment == NULL) {
+		fragment = (xmlChar *) uri->fragment;
+	    } else {
+		xmlFree(uri->fragment);
+	    }
+	} else {
+	    xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_FRAGMENT_ID,
+       "Invalid fragment identifier in URI %s use the xpointer attribute\n",
+                           URI);
+	    if (fragment != NULL)
+	        xmlFree(fragment);
+	    xmlFreeURI(uri);
+	    xmlFree(URI);
+	    return(-1);
+	}
+	uri->fragment = NULL;
+    }
+    URL = xmlSaveUri(uri);
+    xmlFreeURI(uri);
+    xmlFree(URI);
+    if (URL == NULL) {
+	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
+	               "invalid value URI %s\n", URI);
+	if (fragment != NULL)
+	    xmlFree(fragment);
+	return(-1);
+    }
+
+    /*
+     * If local and xml then we need a fragment
+     */
+    if ((local == 1) && (xml == 1) &&
+        ((fragment == NULL) || (fragment[0] == 0))) {
+	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
+	               "detected a local recursion with no xpointer in %s\n",
+		       URL);
+	if (fragment != NULL)
+	    xmlFree(fragment);
+	return(-1);
+    }
+
+    /*
+     * Check the URL against the stack for recursions
+     */
+    if ((!local) && (xml == 1)) {
+	for (i = 0;i < ctxt->urlNr;i++) {
+	    if (xmlStrEqual(URL, ctxt->urlTab[i])) {
+		xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
+		               "detected a recursion in %s\n", URL);
+		return(-1);
+	    }
+	}
+    }
+
+    ref = xmlXIncludeNewRef(ctxt, URL, cur);
+    if (ref == NULL) {
+	return(-1);
+    }
+    ref->fragment = fragment;
+    ref->doc = NULL;
+    ref->xml = xml;
+    ref->count = 1;
+    xmlFree(URL);
+    return(0);
+}
+
+/**
+ * xmlXIncludeRecurseDoc:
+ * @ctxt:  the XInclude context
+ * @doc:  the new document
+ * @url:  the associated URL
+ * 
+ * The XInclude recursive nature is handled at this point.
+ */
+static void
+xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
+	              const xmlURL url ATTRIBUTE_UNUSED) {
+    xmlXIncludeCtxtPtr newctxt;
+    int i;
+
+    /*
+     * Avoid recursion in already substitued resources
+    for (i = 0;i < ctxt->urlNr;i++) {
+	if (xmlStrEqual(doc->URL, ctxt->urlTab[i]))
+	    return;
+    }
+     */
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL);
+#endif
+    /*
+     * Handle recursion here.
+     */
+
+    newctxt = xmlXIncludeNewContext(doc);
+    if (newctxt != NULL) {
+	/*
+	 * Copy the private user data
+	 */
+	newctxt->_private = ctxt->_private;	
+	/*
+	 * Copy the existing document set
+	 */
+	newctxt->incMax = ctxt->incMax;
+	newctxt->incNr = ctxt->incNr;
+        newctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(newctxt->incMax *
+		                          sizeof(newctxt->incTab[0]));
+        if (newctxt->incTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, (xmlNodePtr) doc, "processing doc");
+	    xmlFree(newctxt);
+	    return;
+	}
+	/*
+	 * copy the urlTab
+	 */
+	newctxt->urlMax = ctxt->urlMax;
+	newctxt->urlNr = ctxt->urlNr;
+	newctxt->urlTab = ctxt->urlTab;
+
+	/*
+	 * Inherit the existing base
+	 */
+	newctxt->base = xmlStrdup(ctxt->base);
+
+	/*
+	 * Inherit the documents already in use by other includes
+	 */
+	newctxt->incBase = ctxt->incNr;
+	for (i = 0;i < ctxt->incNr;i++) {
+	    newctxt->incTab[i] = ctxt->incTab[i];
+	    newctxt->incTab[i]->count++; /* prevent the recursion from
+					    freeing it */
+	}
+	/*
+	 * The new context should also inherit the Parse Flags
+	 * (bug 132597)
+	 */
+	newctxt->parseFlags = ctxt->parseFlags;
+	xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc));
+	for (i = 0;i < ctxt->incNr;i++) {
+	    newctxt->incTab[i]->count--;
+	    newctxt->incTab[i] = NULL;
+	}
+
+	/* urlTab may have been reallocated */
+	ctxt->urlTab = newctxt->urlTab;
+	ctxt->urlMax = newctxt->urlMax;
+
+	newctxt->urlMax = 0;
+	newctxt->urlNr = 0;
+	newctxt->urlTab = NULL;
+
+	xmlXIncludeFreeContext(newctxt);
+    }
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Done recursing in doc %s\n", url);
+#endif
+}
+
+/**
+ * xmlXIncludeAddTxt:
+ * @ctxt:  the XInclude context
+ * @txt:  the new text node
+ * @url:  the associated URL
+ * 
+ * Add a new txtument to the list
+ */
+static void
+xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) {
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url);
+#endif
+    if (ctxt->txtMax == 0) {
+	ctxt->txtMax = 4;
+        ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
+		                          sizeof(ctxt->txtTab[0]));
+        if (ctxt->txtTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "processing text");
+	    return;
+	}
+        ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax *
+		                          sizeof(ctxt->txturlTab[0]));
+        if (ctxt->txturlTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "processing text");
+	    return;
+	}
+    }
+    if (ctxt->txtNr >= ctxt->txtMax) {
+	ctxt->txtMax *= 2;
+        ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
+	             ctxt->txtMax * sizeof(ctxt->txtTab[0]));
+        if (ctxt->txtTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "processing text");
+	    return;
+	}
+        ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab,
+	             ctxt->txtMax * sizeof(ctxt->txturlTab[0]));
+        if (ctxt->txturlTab == NULL) {
+	    xmlXIncludeErrMemory(ctxt, NULL, "processing text");
+	    return;
+	}
+    }
+    ctxt->txtTab[ctxt->txtNr] = txt;
+    ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
+    ctxt->txtNr++;
+}
+
+/************************************************************************
+ *									*
+ *			Node copy with specific semantic		*
+ *									*
+ ************************************************************************/
+
+static xmlNodePtr
+xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	                xmlDocPtr source, xmlNodePtr elem);
+
+/**
+ * xmlXIncludeCopyNode:
+ * @ctxt:  the XInclude context
+ * @target:  the document target
+ * @source:  the document source
+ * @elem:  the element
+ * 
+ * Make a copy of the node while preserving the XInclude semantic
+ * of the Infoset copy
+ */
+static xmlNodePtr
+xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	            xmlDocPtr source, xmlNodePtr elem) {
+    xmlNodePtr result = NULL;
+
+    if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
+	(elem == NULL))
+	return(NULL);
+    if (elem->type == XML_DTD_NODE)
+	return(NULL);
+    if (elem->type == XML_DOCUMENT_NODE)
+	result = xmlXIncludeCopyNodeList(ctxt, target, source, elem->children);
+    else
+        result = xmlDocCopyNode(elem, target, 1);
+    return(result);
+}
+
+/**
+ * xmlXIncludeCopyNodeList:
+ * @ctxt:  the XInclude context
+ * @target:  the document target
+ * @source:  the document source
+ * @elem:  the element list
+ * 
+ * Make a copy of the node list while preserving the XInclude semantic
+ * of the Infoset copy
+ */
+static xmlNodePtr
+xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	                xmlDocPtr source, xmlNodePtr elem) {
+    xmlNodePtr cur, res, result = NULL, last = NULL;
+
+    if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
+	(elem == NULL))
+	return(NULL);
+    cur = elem;
+    while (cur != NULL) {
+	res = xmlXIncludeCopyNode(ctxt, target, source, cur);
+	if (res != NULL) {
+	    if (result == NULL) {
+		result = last = res;
+	    } else {
+		last->next = res;
+		res->prev = last;
+		last = res;
+	    }
+	}
+	cur = cur->next;
+    }
+    return(result);
+}
+
+/**
+ * xmlXIncludeGetNthChild:
+ * @cur:  the node
+ * @no:  the child number
+ *
+ * Returns the @n'th element child of @cur or NULL
+ */
+static xmlNodePtr
+xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
+    int i;
+    if (cur == NULL) 
+	return(cur);
+    cur = cur->children;
+    for (i = 0;i <= no;cur = cur->next) {
+	if (cur == NULL) 
+	    return(cur);
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_DOCUMENT_NODE) ||
+	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	    i++;
+	    if (i == no)
+		break;
+	}
+    }
+    return(cur);
+}
+
+xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); /* in xpointer.c */
+/**
+ * xmlXIncludeCopyRange:
+ * @ctxt:  the XInclude context
+ * @target:  the document target
+ * @source:  the document source
+ * @obj:  the XPointer result from the evaluation.
+ *
+ * Build a node list tree copy of the XPointer result.
+ *
+ * Returns an xmlNodePtr list or NULL.
+ *         The caller has to free the node tree.
+ */
+static xmlNodePtr
+xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	                xmlDocPtr source, xmlXPathObjectPtr range) {
+    /* pointers to generated nodes */
+    xmlNodePtr list = NULL, last = NULL, listParent = NULL;
+    xmlNodePtr tmp, tmp2;
+    /* pointers to traversal nodes */
+    xmlNodePtr start, cur, end;
+    int index1, index2;
+    int level = 0, lastLevel = 0, endLevel = 0, endFlag = 0;
+
+    if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
+	(range == NULL))
+	return(NULL);
+    if (range->type != XPATH_RANGE)
+	return(NULL);
+    start = (xmlNodePtr) range->user;
+
+    if (start == NULL)
+	return(NULL);
+    end = range->user2;
+    if (end == NULL)
+	return(xmlDocCopyNode(start, target, 1));
+
+    cur = start;
+    index1 = range->index;
+    index2 = range->index2;
+    /*
+     * level is depth of the current node under consideration
+     * list is the pointer to the root of the output tree
+     * listParent is a pointer to the parent of output tree (within
+       the included file) in case we need to add another level
+     * last is a pointer to the last node added to the output tree
+     * lastLevel is the depth of last (relative to the root)
+     */
+    while (cur != NULL) {
+	/*
+	 * Check if our output tree needs a parent
+	 */
+	if (level < 0) {
+	    while (level < 0) {
+	        /* copy must include namespaces and properties */
+	        tmp2 = xmlDocCopyNode(listParent, target, 2);
+	        xmlAddChild(tmp2, list);
+	        list = tmp2;
+	        listParent = listParent->parent;
+	        level++;
+	    }
+	    last = list;
+	    lastLevel = 0;
+	}
+	/*
+	 * Check whether we need to change our insertion point
+	 */
+	while (level < lastLevel) {
+	    last = last->parent;
+	    lastLevel --;
+	}
+	if (cur == end) {	/* Are we at the end of the range? */
+	    if (cur->type == XML_TEXT_NODE) {
+		const xmlChar *content = cur->content;
+		int len;
+
+		if (content == NULL) {
+		    tmp = xmlNewTextLen(NULL, 0);
+		} else {
+		    len = index2;
+		    if ((cur == start) && (index1 > 1)) {
+			content += (index1 - 1);
+			len -= (index1 - 1);
+		    } else {
+			len = index2;
+		    }
+		    tmp = xmlNewTextLen(content, len);
+		}
+		/* single sub text node selection */
+		if (list == NULL)
+		    return(tmp);
+		/* prune and return full set */
+		if (level == lastLevel)
+		    xmlAddNextSibling(last, tmp);
+		else 
+		    xmlAddChild(last, tmp);
+		return(list);
+	    } else {	/* ending node not a text node */
+	        endLevel = level;	/* remember the level of the end node */
+		endFlag = 1;
+		/* last node - need to take care of properties + namespaces */
+		tmp = xmlDocCopyNode(cur, target, 2);
+		if (list == NULL) {
+		    list = tmp;
+		    listParent = cur->parent;
+		} else {
+		    if (level == lastLevel)
+			xmlAddNextSibling(last, tmp);
+		    else {
+			xmlAddChild(last, tmp);
+			lastLevel = level;
+		    }
+		}
+		last = tmp;
+
+		if (index2 > 1) {
+		    end = xmlXIncludeGetNthChild(cur, index2 - 1);
+		    index2 = 0;
+		}
+		if ((cur == start) && (index1 > 1)) {
+		    cur = xmlXIncludeGetNthChild(cur, index1 - 1);
+		    index1 = 0;
+		}  else {
+		    cur = cur->children;
+		}
+		level++;	/* increment level to show change */
+		/*
+		 * Now gather the remaining nodes from cur to end
+		 */
+		continue;	/* while */
+	    }
+	} else if (cur == start) {	/* Not at the end, are we at start? */
+	    if ((cur->type == XML_TEXT_NODE) ||
+		(cur->type == XML_CDATA_SECTION_NODE)) {
+		const xmlChar *content = cur->content;
+
+		if (content == NULL) {
+		    tmp = xmlNewTextLen(NULL, 0);
+		} else {
+		    if (index1 > 1) {
+			content += (index1 - 1);
+			index1 = 0;
+		    }
+		    tmp = xmlNewText(content);
+		}
+		last = list = tmp;
+		listParent = cur->parent;
+	    } else {		/* Not text node */
+	        /*
+		 * start of the range - need to take care of
+		 * properties and namespaces
+		 */
+		tmp = xmlDocCopyNode(cur, target, 2);
+		list = last = tmp;
+		listParent = cur->parent;
+		if (index1 > 1) {	/* Do we need to position? */
+		    cur = xmlXIncludeGetNthChild(cur, index1 - 1);
+		    level = lastLevel = 1;
+		    index1 = 0;
+		    /*
+		     * Now gather the remaining nodes from cur to end
+		     */
+		    continue; /* while */
+		}
+	    }
+	} else {
+	    tmp = NULL;
+	    switch (cur->type) {
+		case XML_DTD_NODE:
+		case XML_ELEMENT_DECL:
+		case XML_ATTRIBUTE_DECL:
+		case XML_ENTITY_NODE:
+		    /* Do not copy DTD informations */
+		    break;
+		case XML_ENTITY_DECL:
+		    /* handle crossing entities -> stack needed */
+		    break;
+		case XML_XINCLUDE_START:
+		case XML_XINCLUDE_END:
+		    /* don't consider it part of the tree content */
+		    break;
+		case XML_ATTRIBUTE_NODE:
+		    /* Humm, should not happen ! */
+		    break;
+		default:
+		    /*
+		     * Middle of the range - need to take care of
+		     * properties and namespaces
+		     */
+		    tmp = xmlDocCopyNode(cur, target, 2);
+		    break;
+	    }
+	    if (tmp != NULL) {
+		if (level == lastLevel)
+		    xmlAddNextSibling(last, tmp);
+		else {
+		    xmlAddChild(last, tmp);
+		    lastLevel = level;
+		}
+		last = tmp;
+	    }
+	}
+	/*
+	 * Skip to next node in document order
+	 */
+	cur = xmlXPtrAdvanceNode(cur, &level);
+	if (endFlag && (level >= endLevel))
+	    break;
+    }
+    return(list);
+}
+
+/**
+ * xmlXIncludeBuildNodeList:
+ * @ctxt:  the XInclude context
+ * @target:  the document target
+ * @source:  the document source
+ * @obj:  the XPointer result from the evaluation.
+ *
+ * Build a node list tree copy of the XPointer result.
+ * This will drop Attributes and Namespace declarations.
+ *
+ * Returns an xmlNodePtr list or NULL.
+ *         the caller has to free the node tree.
+ */
+static xmlNodePtr
+xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	                xmlDocPtr source, xmlXPathObjectPtr obj) {
+    xmlNodePtr list = NULL, last = NULL;
+    int i;
+
+    if (source == NULL)
+	source = ctxt->doc;
+    if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
+	(obj == NULL))
+	return(NULL);
+    switch (obj->type) {
+        case XPATH_NODESET: {
+	    xmlNodeSetPtr set = obj->nodesetval;
+	    if (set == NULL)
+		return(NULL);
+	    for (i = 0;i < set->nodeNr;i++) {
+		if (set->nodeTab[i] == NULL)
+		    continue;
+		switch (set->nodeTab[i]->type) {
+		    case XML_TEXT_NODE:
+		    case XML_CDATA_SECTION_NODE:
+		    case XML_ELEMENT_NODE:
+		    case XML_ENTITY_REF_NODE:
+		    case XML_ENTITY_NODE:
+		    case XML_PI_NODE:
+		    case XML_COMMENT_NODE:
+		    case XML_DOCUMENT_NODE:
+		    case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+		    case XML_DOCB_DOCUMENT_NODE:
+#endif
+		    case XML_XINCLUDE_END:
+			break;
+		    case XML_XINCLUDE_START: {
+	                xmlNodePtr tmp, cur = set->nodeTab[i];
+
+			cur = cur->next;
+			while (cur != NULL) {
+			    switch(cur->type) {
+				case XML_TEXT_NODE:
+				case XML_CDATA_SECTION_NODE:
+				case XML_ELEMENT_NODE:
+				case XML_ENTITY_REF_NODE:
+				case XML_ENTITY_NODE:
+				case XML_PI_NODE:
+				case XML_COMMENT_NODE:
+				    tmp = xmlXIncludeCopyNode(ctxt, target,
+							      source, cur);
+				    if (last == NULL) {
+					list = last = tmp;
+				    } else {
+					xmlAddNextSibling(last, tmp);
+					last = tmp;
+				    }
+				    cur = cur->next;
+				    continue;
+				default:
+				    break;
+			    }
+			    break;
+			}
+			continue;
+		    }
+		    case XML_ATTRIBUTE_NODE:
+		    case XML_NAMESPACE_DECL:
+		    case XML_DOCUMENT_TYPE_NODE:
+		    case XML_DOCUMENT_FRAG_NODE:
+		    case XML_NOTATION_NODE:
+		    case XML_DTD_NODE:
+		    case XML_ELEMENT_DECL:
+		    case XML_ATTRIBUTE_DECL:
+		    case XML_ENTITY_DECL:
+			continue; /* for */
+		}
+		if (last == NULL)
+		    list = last = xmlXIncludeCopyNode(ctxt, target, source,
+			                              set->nodeTab[i]);
+		else {
+		    xmlAddNextSibling(last,
+			    xmlXIncludeCopyNode(ctxt, target, source,
+				                set->nodeTab[i]));
+		    if (last->next != NULL)
+			last = last->next;
+		}
+	    }
+	    break;
+	}
+	case XPATH_LOCATIONSET: {
+	    xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
+	    if (set == NULL)
+		return(NULL);
+	    for (i = 0;i < set->locNr;i++) {
+		if (last == NULL)
+		    list = last = xmlXIncludeCopyXPointer(ctxt, target, source,
+			                                  set->locTab[i]);
+		else
+		    xmlAddNextSibling(last,
+			    xmlXIncludeCopyXPointer(ctxt, target, source,
+				                    set->locTab[i]));
+		if (last != NULL) {
+		    while (last->next != NULL)
+			last = last->next;
+		}
+	    }
+	    break;
+	}
+#ifdef LIBXML_XPTR_ENABLED
+	case XPATH_RANGE:
+	    return(xmlXIncludeCopyRange(ctxt, target, source, obj));
+#endif
+	case XPATH_POINT:
+	    /* points are ignored in XInclude */
+	    break;
+	default:
+	    break;
+    }
+    return(list);
+}
+/************************************************************************
+ *									*
+ *			XInclude I/O handling				*
+ *									*
+ ************************************************************************/
+
+typedef struct _xmlXIncludeMergeData xmlXIncludeMergeData;
+typedef xmlXIncludeMergeData *xmlXIncludeMergeDataPtr;
+struct _xmlXIncludeMergeData {
+    xmlDocPtr doc;
+    xmlXIncludeCtxtPtr ctxt;
+};
+
+/**
+ * xmlXIncludeMergeOneEntity:
+ * @ent: the entity
+ * @doc:  the including doc
+ * @nr: the entity name
+ *
+ * Inplements the merge of one entity
+ */
+static void
+xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data,
+	               xmlChar *name ATTRIBUTE_UNUSED) {
+    xmlEntityPtr ret, prev;
+    xmlDocPtr doc;
+    xmlXIncludeCtxtPtr ctxt;
+
+    if ((ent == NULL) || (data == NULL))
+	return;
+    ctxt = data->ctxt;
+    doc = data->doc;
+    if ((ctxt == NULL) || (doc == NULL))
+	return;
+    switch (ent->etype) {
+        case XML_INTERNAL_PARAMETER_ENTITY:
+        case XML_EXTERNAL_PARAMETER_ENTITY:
+        case XML_INTERNAL_PREDEFINED_ENTITY:
+	    return;
+        case XML_INTERNAL_GENERAL_ENTITY:
+        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	    break;
+    }
+    ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
+			  ent->SystemID, ent->content);
+    if (ret != NULL) {
+	if (ent->URI != NULL)
+	    ret->URI = xmlStrdup(ent->URI);
+    } else {
+	prev = xmlGetDocEntity(doc, ent->name);
+	if (prev != NULL) {
+	    if (ent->etype != prev->etype)
+		goto error;
+	
+	    if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
+		if (!xmlStrEqual(ent->SystemID, prev->SystemID))
+		    goto error;
+	    } else if ((ent->ExternalID != NULL) &&
+		       (prev->ExternalID != NULL)) {
+		if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
+		    goto error;
+	    } else if ((ent->content != NULL) && (prev->content != NULL)) {
+		if (!xmlStrEqual(ent->content, prev->content))
+		    goto error;
+	    } else {
+		goto error;
+	    }
+
+	}
+    }
+    return;
+error:
+    switch (ent->etype) {
+        case XML_INTERNAL_PARAMETER_ENTITY:
+        case XML_EXTERNAL_PARAMETER_ENTITY:
+        case XML_INTERNAL_PREDEFINED_ENTITY:
+        case XML_INTERNAL_GENERAL_ENTITY:
+        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+	    return;
+        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	    break;
+    }
+    xmlXIncludeErr(ctxt, (xmlNodePtr) ent, XML_XINCLUDE_ENTITY_DEF_MISMATCH,
+                   "mismatch in redefinition of entity %s\n",
+		   ent->name);
+}
+
+/**
+ * xmlXIncludeMergeEntities:
+ * @ctxt: an XInclude context
+ * @doc:  the including doc
+ * @from:  the included doc
+ *
+ * Inplements the entity merge
+ *
+ * Returns 0 if merge succeeded, -1 if some processing failed
+ */
+static int
+xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
+	                 xmlDocPtr from) {
+    xmlNodePtr cur;
+    xmlDtdPtr target, source;
+
+    if (ctxt == NULL)
+	return(-1);
+
+    if ((from == NULL) || (from->intSubset == NULL))
+	return(0);
+
+    target = doc->intSubset;
+    if (target == NULL) {
+	cur = xmlDocGetRootElement(doc);
+	if (cur == NULL)
+	    return(-1);
+        target = xmlCreateIntSubset(doc, cur->name, NULL, NULL);
+	if (target == NULL)
+	    return(-1);
+    }
+
+    source = from->intSubset;
+    if ((source != NULL) && (source->entities != NULL)) {
+	xmlXIncludeMergeData data;
+
+	data.ctxt = ctxt;
+	data.doc = doc;
+
+	xmlHashScan((xmlHashTablePtr) source->entities,
+		    (xmlHashScanner) xmlXIncludeMergeEntity, &data);
+    }
+    source = from->extSubset;
+    if ((source != NULL) && (source->entities != NULL)) {
+	xmlXIncludeMergeData data;
+
+	data.ctxt = ctxt;
+	data.doc = doc;
+
+	/*
+	 * don't duplicate existing stuff when external subsets are the same
+	 */
+	if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) &&
+	    (!xmlStrEqual(target->SystemID, source->SystemID))) {
+	    xmlHashScan((xmlHashTablePtr) source->entities,
+			(xmlHashScanner) xmlXIncludeMergeEntity, &data);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlXIncludeLoadDoc:
+ * @ctxt:  the XInclude context
+ * @url:  the associated URL
+ * @nr:  the xinclude node number
+ * 
+ * Load the document, and store the result in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
+    xmlDocPtr doc;
+    xmlURIPtr uri;
+    xmlChar *URL;
+    xmlChar *fragment = NULL;
+    int i = 0;
+#ifdef LIBXML_XPTR_ENABLED
+    int saveFlags;
+#endif
+
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "Loading doc %s:%d\n", url, nr);
+#endif
+    /*
+     * Check the URL and remove any fragment identifier
+     */
+    uri = xmlParseURI((const char *)url);
+    if (uri == NULL) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	               XML_XINCLUDE_HREF_URI,
+		       "invalid value URI %s\n", url);
+	return(-1);
+    }
+    if (uri->fragment != NULL) {
+	fragment = (xmlChar *) uri->fragment;
+	uri->fragment = NULL;
+    }
+    if ((ctxt->incTab != NULL) && (ctxt->incTab[nr] != NULL) &&
+        (ctxt->incTab[nr]->fragment != NULL)) {
+	if (fragment != NULL) xmlFree(fragment);
+	fragment = xmlStrdup(ctxt->incTab[nr]->fragment);
+    }
+    URL = xmlSaveUri(uri);
+    xmlFreeURI(uri);
+    if (URL == NULL) {
+        if (ctxt->incTab != NULL)
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+			   XML_XINCLUDE_HREF_URI,
+			   "invalid value URI %s\n", url);
+	else
+	    xmlXIncludeErr(ctxt, NULL,
+			   XML_XINCLUDE_HREF_URI,
+			   "invalid value URI %s\n", url);
+	if (fragment != NULL)
+	    xmlFree(fragment);
+	return(-1);
+    }
+
+    /*
+     * Handling of references to the local document are done
+     * directly through ctxt->doc.
+     */
+    if ((URL[0] == 0) || (URL[0] == '#') ||
+	((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) {
+	doc = NULL;
+        goto loaded;
+    }
+
+    /*
+     * Prevent reloading twice the document.
+     */
+    for (i = 0; i < ctxt->incNr; i++) {
+	if ((xmlStrEqual(URL, ctxt->incTab[i]->URI)) &&
+	    (ctxt->incTab[i]->doc != NULL)) {
+	    doc = ctxt->incTab[i]->doc;
+#ifdef DEBUG_XINCLUDE
+	    printf("Already loaded %s\n", URL);
+#endif
+	    goto loaded;
+	}
+    }
+
+    /*
+     * Load it.
+     */
+#ifdef DEBUG_XINCLUDE
+    printf("loading %s\n", URL);
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+    /*
+     * If this is an XPointer evaluation, we want to assure that
+     * all entities have been resolved prior to processing the
+     * referenced document
+     */
+    saveFlags = ctxt->parseFlags;
+    if (fragment != NULL) {	/* if this is an XPointer eval */
+	ctxt->parseFlags |= XML_PARSE_NOENT;
+    }
+#endif
+
+    doc = xmlXIncludeParseFile(ctxt, (const char *)URL);
+#ifdef LIBXML_XPTR_ENABLED
+    ctxt->parseFlags = saveFlags;
+#endif
+    if (doc == NULL) {
+	xmlFree(URL);
+	if (fragment != NULL)
+	    xmlFree(fragment);
+	return(-1);
+    }
+    ctxt->incTab[nr]->doc = doc;
+    /*
+     * It's possible that the requested URL has been mapped to a
+     * completely different location (e.g. through a catalog entry).
+     * To check for this, we compare the URL with that of the doc
+     * and change it if they disagree (bug 146988).
+     */
+   if (!xmlStrEqual(URL, doc->URL)) {
+       xmlFree(URL);
+       URL = xmlStrdup(doc->URL);
+   }
+    for (i = nr + 1; i < ctxt->incNr; i++) {
+	if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) {
+	    ctxt->incTab[nr]->count++;
+#ifdef DEBUG_XINCLUDE
+	    printf("Increasing %s count since reused\n", URL);
+#endif
+            break;
+	}
+    }
+
+    /*
+     * Make sure we have all entities fixed up
+     */
+    xmlXIncludeMergeEntities(ctxt, ctxt->doc, doc);
+
+    /*
+     * We don't need the DTD anymore, free up space
+    if (doc->intSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) doc->intSubset);
+	xmlFreeNode((xmlNodePtr) doc->intSubset);
+	doc->intSubset = NULL;
+    }
+    if (doc->extSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) doc->extSubset);
+	xmlFreeNode((xmlNodePtr) doc->extSubset);
+	doc->extSubset = NULL;
+    }
+     */
+    xmlXIncludeRecurseDoc(ctxt, doc, URL);
+
+loaded:
+    if (fragment == NULL) {
+	/*
+	 * Add the top children list as the replacement copy.
+	 */
+	if (doc == NULL)
+	{
+	    /* Hopefully a DTD declaration won't be copied from
+	     * the same document */
+	    ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children);
+	} else {
+	    ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
+		                                       doc, doc->children);
+	}
+    } 
+#ifdef LIBXML_XPTR_ENABLED
+    else {
+	/*
+	 * Computes the XPointer expression and make a copy used
+	 * as the replacement copy.
+	 */
+	xmlXPathObjectPtr xptr;
+	xmlXPathContextPtr xptrctxt;
+	xmlNodeSetPtr set;
+
+	if (doc == NULL) {
+	    xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref,
+		                         NULL);
+	} else {
+	    xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
+	}
+	if (xptrctxt == NULL) {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	                   XML_XINCLUDE_XPTR_FAILED,
+			   "could not create XPointer context\n", NULL);
+	    xmlFree(URL);
+	    xmlFree(fragment);
+	    return(-1);
+	}
+	xptr = xmlXPtrEval(fragment, xptrctxt);
+	if (xptr == NULL) {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+	                   XML_XINCLUDE_XPTR_FAILED,
+			   "XPointer evaluation failed: #%s\n",
+			   fragment);
+	    xmlXPathFreeContext(xptrctxt);
+	    xmlFree(URL);
+	    xmlFree(fragment);
+	    return(-1);
+	}
+	switch (xptr->type) {
+	    case XPATH_UNDEFINED:
+	    case XPATH_BOOLEAN:
+	    case XPATH_NUMBER:
+	    case XPATH_STRING:
+	    case XPATH_POINT:
+	    case XPATH_USERS:
+	    case XPATH_XSLT_TREE:
+		xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+		               XML_XINCLUDE_XPTR_RESULT,
+			       "XPointer is not a range: #%s\n",
+			       fragment);
+		xmlXPathFreeContext(xptrctxt);
+		xmlFree(URL);
+		xmlFree(fragment);
+		return(-1);
+	    case XPATH_NODESET:
+	        if ((xptr->nodesetval == NULL) ||
+		    (xptr->nodesetval->nodeNr <= 0)) {
+		    xmlXPathFreeContext(xptrctxt);
+		    xmlFree(URL);
+		    xmlFree(fragment);
+		    return(-1);
+		}
+
+	    case XPATH_RANGE:
+	    case XPATH_LOCATIONSET:
+		break;
+	}
+	set = xptr->nodesetval;
+	if (set != NULL) {
+	    for (i = 0;i < set->nodeNr;i++) {
+		if (set->nodeTab[i] == NULL)
+		    continue;
+		switch (set->nodeTab[i]->type) {
+		    case XML_ELEMENT_NODE:
+		    case XML_TEXT_NODE:
+		    case XML_CDATA_SECTION_NODE:
+		    case XML_ENTITY_REF_NODE:
+		    case XML_ENTITY_NODE:
+		    case XML_PI_NODE:
+		    case XML_COMMENT_NODE:
+		    case XML_DOCUMENT_NODE:
+		    case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+		    case XML_DOCB_DOCUMENT_NODE:
+#endif
+			continue;
+
+		    case XML_ATTRIBUTE_NODE:
+			xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+			               XML_XINCLUDE_XPTR_RESULT,
+				       "XPointer selects an attribute: #%s\n",
+				       fragment);
+			set->nodeTab[i] = NULL;
+			continue;
+		    case XML_NAMESPACE_DECL:
+			xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+			               XML_XINCLUDE_XPTR_RESULT,
+				       "XPointer selects a namespace: #%s\n",
+				       fragment);
+			set->nodeTab[i] = NULL;
+			continue;
+		    case XML_DOCUMENT_TYPE_NODE:
+		    case XML_DOCUMENT_FRAG_NODE:
+		    case XML_NOTATION_NODE:
+		    case XML_DTD_NODE:
+		    case XML_ELEMENT_DECL:
+		    case XML_ATTRIBUTE_DECL:
+		    case XML_ENTITY_DECL:
+		    case XML_XINCLUDE_START:
+		    case XML_XINCLUDE_END:
+			xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+			               XML_XINCLUDE_XPTR_RESULT,
+				   "XPointer selects unexpected nodes: #%s\n",
+				       fragment);
+			set->nodeTab[i] = NULL;
+			set->nodeTab[i] = NULL;
+			continue; /* for */
+		}
+	    }
+	}
+	if (doc == NULL) {
+	    ctxt->incTab[nr]->xptr = xptr;
+	    ctxt->incTab[nr]->inc = NULL;
+	} else {
+	    ctxt->incTab[nr]->inc =
+		xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
+	    xmlXPathFreeObject(xptr);
+	}
+	xmlXPathFreeContext(xptrctxt);
+	xmlFree(fragment);
+    }
+#endif
+
+    /*
+     * Do the xml:base fixup if needed
+     */
+    if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/')) &&
+        (!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) &&
+	(!(doc->parseFlags & XML_PARSE_NOBASEFIX))) {
+	xmlNodePtr node;
+	xmlChar *base;
+	xmlChar *curBase;
+
+	/*
+	 * The base is only adjusted if "necessary", i.e. if the xinclude node
+	 * has a base specified, or the URL is relative
+	 */
+	base = xmlGetNsProp(ctxt->incTab[nr]->ref, BAD_CAST "base",
+			XML_XML_NAMESPACE);
+	if (base == NULL) {
+	    /*
+	     * No xml:base on the xinclude node, so we check whether the
+	     * URI base is different than (relative to) the context base
+	     */
+	    curBase = xmlBuildRelativeURI(URL, ctxt->base);
+	    if (curBase == NULL) {	/* Error return */
+	        xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	               XML_XINCLUDE_HREF_URI,
+		       "trying to build relative URI from %s\n", URL);
+	    } else {
+		/* If the URI doesn't contain a slash, it's not relative */
+	        if (!xmlStrchr(curBase, (xmlChar) '/'))
+		    xmlFree(curBase);
+		else
+		    base = curBase;
+	    }
+	}
+	if (base != NULL) {	/* Adjustment may be needed */
+	    node = ctxt->incTab[nr]->inc;
+	    while (node != NULL) {
+		/* Only work on element nodes */
+		if (node->type == XML_ELEMENT_NODE) {
+		    curBase = xmlNodeGetBase(node->doc, node);
+		    /* If no current base, set it */
+		    if (curBase == NULL) {
+			xmlNodeSetBase(node, base);
+		    } else {
+			/*
+			 * If the current base is the same as the
+			 * URL of the document, then reset it to be
+			 * the specified xml:base or the relative URI
+			 */
+			if (xmlStrEqual(curBase, node->doc->URL)) {
+			    xmlNodeSetBase(node, base);
+			} else {
+			    /*
+			     * If the element already has an xml:base
+			     * set, then relativise it if necessary
+			     */
+			    xmlChar *xmlBase;
+			    xmlBase = xmlGetNsProp(node,
+					    BAD_CAST "base",
+					    XML_XML_NAMESPACE);
+			    if (xmlBase != NULL) {
+				xmlChar *relBase;
+				relBase = xmlBuildURI(xmlBase, base);
+				if (relBase == NULL) { /* error */
+				    xmlXIncludeErr(ctxt, 
+						ctxt->incTab[nr]->ref,
+						XML_XINCLUDE_HREF_URI,
+					"trying to rebuild base from %s\n",
+						xmlBase);
+				} else {
+				    xmlNodeSetBase(node, relBase);
+				    xmlFree(relBase);
+				}
+				xmlFree(xmlBase);
+			    }
+			}
+			xmlFree(curBase);
+		    }
+		}
+	        node = node->next;
+	    }
+	    xmlFree(base);
+	}
+    }
+    if ((nr < ctxt->incNr) && (ctxt->incTab[nr]->doc != NULL) &&
+	(ctxt->incTab[nr]->count <= 1)) {
+#ifdef DEBUG_XINCLUDE
+        printf("freeing %s\n", ctxt->incTab[nr]->doc->URL);
+#endif
+	xmlFreeDoc(ctxt->incTab[nr]->doc);
+	ctxt->incTab[nr]->doc = NULL;
+    }
+    xmlFree(URL);
+    return(0);
+}
+
+/**
+ * xmlXIncludeLoadTxt:
+ * @ctxt:  the XInclude context
+ * @url:  the associated URL
+ * @nr:  the xinclude node number
+ * 
+ * Load the content, and store the result in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
+    xmlParserInputBufferPtr buf;
+    xmlNodePtr node;
+    xmlURIPtr uri;
+    xmlChar *URL;
+    int i;
+    xmlChar *encoding = NULL;
+    xmlCharEncoding enc = (xmlCharEncoding) 0;
+
+    /*
+     * Check the URL and remove any fragment identifier
+     */
+    uri = xmlParseURI((const char *)url);
+    if (uri == NULL) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
+	               "invalid value URI %s\n", url);
+	return(-1);
+    }
+    if (uri->fragment != NULL) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT,
+	               "fragment identifier forbidden for text: %s\n",
+		       (const xmlChar *) uri->fragment);
+	xmlFreeURI(uri);
+	return(-1);
+    }
+    URL = xmlSaveUri(uri);
+    xmlFreeURI(uri);
+    if (URL == NULL) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
+	               "invalid value URI %s\n", url);
+	return(-1);
+    }
+
+    /*
+     * Handling of references to the local document are done
+     * directly through ctxt->doc.
+     */
+    if (URL[0] == 0) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	               XML_XINCLUDE_TEXT_DOCUMENT,
+		       "text serialization of document not available\n", NULL);
+	xmlFree(URL);
+	return(-1);
+    }
+
+    /*
+     * Prevent reloading twice the document.
+     */
+    for (i = 0; i < ctxt->txtNr; i++) {
+	if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
+	    node = xmlCopyNode(ctxt->txtTab[i], 1);
+	    goto loaded;
+	}
+    }
+    /*
+     * Try to get the encoding if available
+     */
+    if ((ctxt->incTab[nr] != NULL) && (ctxt->incTab[nr]->ref != NULL)) {
+	encoding = xmlGetProp(ctxt->incTab[nr]->ref, XINCLUDE_PARSE_ENCODING);
+    }
+    if (encoding != NULL) {
+	/*
+	 * TODO: we should not have to remap to the xmlCharEncoding
+	 *       predefined set, a better interface than
+	 *       xmlParserInputBufferCreateFilename should allow any
+	 *       encoding supported by iconv
+	 */
+        enc = xmlParseCharEncoding((const char *) encoding);
+	if (enc == XML_CHAR_ENCODING_ERROR) {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+	                   XML_XINCLUDE_UNKNOWN_ENCODING,
+			   "encoding %s not supported\n", encoding);
+	    xmlFree(encoding);
+	    xmlFree(URL);
+	    return(-1);
+	}
+	xmlFree(encoding);
+    }
+
+    /*
+     * Load it.
+     */
+    buf = xmlParserInputBufferCreateFilename((const char *)URL, enc);
+    if (buf == NULL) {
+	xmlFree(URL);
+	return(-1);
+    }
+    node = xmlNewText(NULL);
+
+    /*
+     * Scan all chars from the resource and add the to the node
+     */
+    while (xmlParserInputBufferRead(buf, 128) > 0) {
+	int len;
+	const xmlChar *content;
+
+	content = xmlBufferContent(buf->buffer);
+	len = xmlBufferLength(buf->buffer);
+	for (i = 0;i < len;) {
+	    int cur;
+	    int l;
+
+	    cur = xmlStringCurrentChar(NULL, &content[i], &l);
+	    if (!IS_CHAR(cur)) {
+		xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+		               XML_XINCLUDE_INVALID_CHAR,
+			       "%s contains invalid char\n", URL);
+		xmlFreeParserInputBuffer(buf);
+		xmlFree(URL);
+		return(-1);
+	    } else {
+		xmlNodeAddContentLen(node, &content[i], l);
+	    }
+	    i += l;
+	}
+	xmlBufferShrink(buf->buffer, len);
+    }
+    xmlFreeParserInputBuffer(buf);
+    xmlXIncludeAddTxt(ctxt, node, URL);
+
+loaded:
+    /*
+     * Add the element as the replacement copy.
+     */
+    ctxt->incTab[nr]->inc = node;
+    xmlFree(URL);
+    return(0);
+}
+
+/**
+ * xmlXIncludeLoadFallback:
+ * @ctxt:  the XInclude context
+ * @fallback:  the fallback node
+ * @nr:  the xinclude node number
+ * 
+ * Load the content of the fallback node, and store the result
+ * in the XInclude context
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
+    xmlXIncludeCtxtPtr newctxt;
+    int ret = 0;
+    
+    if ((fallback == NULL) || (ctxt == NULL))
+	return(-1);
+    if (fallback->children != NULL) {
+	/*
+	 * It's possible that the fallback also has 'includes'
+	 * (Bug 129969), so we re-process the fallback just in case
+	 */
+	newctxt = xmlXIncludeNewContext(ctxt->doc);
+	if (newctxt == NULL)
+	    return (-1);
+	newctxt->_private = ctxt->_private;
+	newctxt->base = xmlStrdup(ctxt->base);	/* Inherit the base from the existing context */
+	xmlXIncludeSetFlags(newctxt, ctxt->parseFlags);
+	ret = xmlXIncludeDoProcess(newctxt, ctxt->doc, fallback->children);
+	if (ctxt->nbErrors > 0)
+	    ret = -1;
+	else if (ret > 0)
+	    ret = 0;	/* xmlXIncludeDoProcess can return +ve number */
+	xmlXIncludeFreeContext(newctxt);
+
+	ctxt->incTab[nr]->inc = xmlDocCopyNodeList(ctxt->doc,
+	                                           fallback->children);
+    } else {
+        ctxt->incTab[nr]->inc = NULL;
+	ctxt->incTab[nr]->emptyFb = 1;	/* flag empty callback */
+    }
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *			XInclude Processing				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXIncludePreProcessNode:
+ * @ctxt: an XInclude context
+ * @node: an XInclude node
+ *
+ * Implement the XInclude preprocessing, currently just adding the element
+ * for further processing.
+ *
+ * Returns the result list or NULL in case of error
+ */
+static xmlNodePtr
+xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
+    xmlXIncludeAddNode(ctxt, node);
+    return(NULL);
+}
+
+/**
+ * xmlXIncludeLoadNode:
+ * @ctxt: an XInclude context
+ * @nr: the node number
+ *
+ * Find and load the infoset replacement for the given node.
+ *
+ * Returns 0 if substitution succeeded, -1 if some processing failed
+ */
+static int
+xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
+    xmlNodePtr cur;
+    xmlChar *href;
+    xmlChar *parse;
+    xmlChar *base;
+    xmlChar *oldBase;
+    xmlChar *URI;
+    int xml = 1; /* default Issue 64 */
+    int ret;
+
+    if (ctxt == NULL)
+	return(-1);
+    if ((nr < 0) || (nr >= ctxt->incNr))
+	return(-1);
+    cur = ctxt->incTab[nr]->ref;
+    if (cur == NULL)
+	return(-1);
+
+    /*
+     * read the attributes
+     */
+    href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
+    if (href == NULL) {
+	href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
+	if (href == NULL) 
+	    return(-1);
+    }
+    parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
+    if (parse != NULL) {
+	if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
+	    xml = 1;
+	else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
+	    xml = 0;
+	else {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+	                   XML_XINCLUDE_PARSE_VALUE,
+			   "invalid value %s for 'parse'\n", parse);
+	    if (href != NULL)
+		xmlFree(href);
+	    if (parse != NULL)
+		xmlFree(parse);
+	    return(-1);
+	}
+    }
+
+    /*
+     * compute the URI
+     */
+    base = xmlNodeGetBase(ctxt->doc, cur);
+    if (base == NULL) {
+	URI = xmlBuildURI(href, ctxt->doc->URL);
+    } else {
+	URI = xmlBuildURI(href, base);
+    }
+    if (URI == NULL) {
+	xmlChar *escbase;
+	xmlChar *eschref;
+	/*
+	 * Some escaping may be needed
+	 */
+	escbase = xmlURIEscape(base);
+	eschref = xmlURIEscape(href);
+	URI = xmlBuildURI(eschref, escbase);
+	if (escbase != NULL)
+	    xmlFree(escbase);
+	if (eschref != NULL)
+	    xmlFree(eschref);
+    }
+    if (URI == NULL) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	               XML_XINCLUDE_HREF_URI, "failed build URL\n", NULL);
+	if (parse != NULL)
+	    xmlFree(parse);
+	if (href != NULL)
+	    xmlFree(href);
+	if (base != NULL)
+	    xmlFree(base);
+	return(-1);
+    }
+#ifdef DEBUG_XINCLUDE
+    xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
+	    xml ? "xml": "text");
+    xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
+#endif
+
+    /*
+     * Save the base for this include (saving the current one)
+     */
+    oldBase = ctxt->base;
+    ctxt->base = base;
+
+    if (xml) {
+	ret = xmlXIncludeLoadDoc(ctxt, URI, nr);
+	/* xmlXIncludeGetFragment(ctxt, cur, URI); */
+    } else {
+	ret = xmlXIncludeLoadTxt(ctxt, URI, nr);
+    }
+
+    /*
+     * Restore the original base before checking for fallback
+     */
+    ctxt->base = oldBase;
+    
+    if (ret < 0) {
+	xmlNodePtr children;
+
+	/*
+	 * Time to try a fallback if availble
+	 */
+#ifdef DEBUG_XINCLUDE
+	xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");
+#endif
+	children = cur->children;
+	while (children != NULL) {
+	    if ((children->type == XML_ELEMENT_NODE) &&
+		(children->ns != NULL) &&
+		(xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&
+		((xmlStrEqual(children->ns->href, XINCLUDE_NS)) ||
+		 (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) {
+		ret = xmlXIncludeLoadFallback(ctxt, children, nr);
+		if (ret == 0) 
+		    break;
+	    }
+	    children = children->next;
+	}
+    }
+    if (ret < 0) {
+	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	               XML_XINCLUDE_NO_FALLBACK,
+		       "could not load %s, and no fallback was found\n",
+		       URI);
+    }
+
+    /*
+     * Cleanup
+     */
+    if (URI != NULL)
+	xmlFree(URI);
+    if (parse != NULL)
+	xmlFree(parse);
+    if (href != NULL)
+	xmlFree(href);
+    if (base != NULL)
+	xmlFree(base);
+    return(0);
+}
+
+/**
+ * xmlXIncludeIncludeNode:
+ * @ctxt: an XInclude context
+ * @nr: the node number
+ *
+ * Inplement the infoset replacement for the given node
+ *
+ * Returns 0 if substitution succeeded, -1 if some processing failed
+ */
+static int
+xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
+    xmlNodePtr cur, end, list, tmp;
+
+    if (ctxt == NULL)
+	return(-1);
+    if ((nr < 0) || (nr >= ctxt->incNr))
+	return(-1);
+    cur = ctxt->incTab[nr]->ref;
+    if (cur == NULL)
+	return(-1);
+
+    /*
+     * If we stored an XPointer a late computation may be needed
+     */
+    if ((ctxt->incTab[nr]->inc == NULL) &&
+	(ctxt->incTab[nr]->xptr != NULL)) {
+	ctxt->incTab[nr]->inc =
+	    xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc,
+		                    ctxt->incTab[nr]->xptr);
+	xmlXPathFreeObject(ctxt->incTab[nr]->xptr);
+	ctxt->incTab[nr]->xptr = NULL;
+    }
+    list = ctxt->incTab[nr]->inc;
+    ctxt->incTab[nr]->inc = NULL;
+
+    /*
+     * Check against the risk of generating a multi-rooted document
+     */
+    if ((cur->parent != NULL) &&
+	(cur->parent->type != XML_ELEMENT_NODE)) {
+	int nb_elem = 0;
+
+	tmp = list;
+	while (tmp != NULL) {
+	    if (tmp->type == XML_ELEMENT_NODE)
+		nb_elem++;
+	    tmp = tmp->next;
+	}
+	if (nb_elem > 1) {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 
+	                   XML_XINCLUDE_MULTIPLE_ROOT,
+		       "XInclude error: would result in multiple root nodes\n",
+			   NULL);
+	    return(-1);
+	}
+    }
+
+    if (ctxt->parseFlags & XML_PARSE_NOXINCNODE) {
+	/*
+	 * Add the list of nodes
+	 */
+	while (list != NULL) {
+	    end = list;
+	    list = list->next;
+
+	    xmlAddPrevSibling(cur, end);
+	}
+	xmlUnlinkNode(cur);
+	xmlFreeNode(cur);
+    } else {
+	/*
+	 * Change the current node as an XInclude start one, and add an
+	 * XInclude end one
+	 */
+	cur->type = XML_XINCLUDE_START;
+	end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
+	if (end == NULL) {
+	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+	                   XML_XINCLUDE_BUILD_FAILED,
+			   "failed to build node\n", NULL);
+	    return(-1);
+	}
+	end->type = XML_XINCLUDE_END;
+	xmlAddNextSibling(cur, end);
+
+	/*
+	 * Add the list of nodes
+	 */
+	while (list != NULL) {
+	    cur = list;
+	    list = list->next;
+
+	    xmlAddPrevSibling(end, cur);
+	}
+    }
+
+    
+    return(0);
+}
+
+/**
+ * xmlXIncludeTestNode:
+ * @ctxt: the XInclude processing context
+ * @node: an XInclude node
+ *
+ * test if the node is an XInclude node
+ *
+ * Returns 1 true, 0 otherwise
+ */
+static int
+xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
+    if (node == NULL)
+	return(0);
+    if (node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (node->ns == NULL)
+	return(0);
+    if ((xmlStrEqual(node->ns->href, XINCLUDE_NS)) ||
+        (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS))) {
+	if (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS)) {
+	    if (ctxt->legacy == 0) {
+#if 0 /* wait for the XML Core Working Group to get something stable ! */
+		xmlXIncludeWarn(ctxt, node, XML_XINCLUDE_DEPRECATED_NS,
+	               "Deprecated XInclude namespace found, use %s",
+		                XINCLUDE_NS);
+#endif
+	        ctxt->legacy = 1;
+	    }
+	}
+	if (xmlStrEqual(node->name, XINCLUDE_NODE)) {
+	    xmlNodePtr child = node->children;
+	    int nb_fallback = 0;
+
+	    while (child != NULL) {
+		if ((child->type == XML_ELEMENT_NODE) &&
+		    (child->ns != NULL) &&
+		    ((xmlStrEqual(child->ns->href, XINCLUDE_NS)) ||
+		     (xmlStrEqual(child->ns->href, XINCLUDE_OLD_NS)))) {
+		    if (xmlStrEqual(child->name, XINCLUDE_NODE)) {
+			xmlXIncludeErr(ctxt, node,
+			               XML_XINCLUDE_INCLUDE_IN_INCLUDE,
+				       "%s has an 'include' child\n",
+				       XINCLUDE_NODE);
+			return(0);
+		    }
+		    if (xmlStrEqual(child->name, XINCLUDE_FALLBACK)) {
+			nb_fallback++;
+		    }
+		}
+		child = child->next;
+	    }
+	    if (nb_fallback > 1) {
+		xmlXIncludeErr(ctxt, node, XML_XINCLUDE_FALLBACKS_IN_INCLUDE,
+			       "%s has multiple fallback children\n",
+		               XINCLUDE_NODE);
+		return(0);
+	    }
+	    return(1);
+	}
+	if (xmlStrEqual(node->name, XINCLUDE_FALLBACK)) {
+	    if ((node->parent == NULL) ||
+		(node->parent->type != XML_ELEMENT_NODE) ||
+		(node->parent->ns == NULL) ||
+		((!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) &&
+		 (!xmlStrEqual(node->parent->ns->href, XINCLUDE_OLD_NS))) ||
+		(!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {
+		xmlXIncludeErr(ctxt, node,
+		               XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE,
+			       "%s is not the child of an 'include'\n",
+			       XINCLUDE_FALLBACK);
+	    }
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlXIncludeDoProcess:
+ * @ctxt: the XInclude processing context
+ * @doc: an XML document
+ * @tree: the top of the tree to process
+ *
+ * Implement the XInclude substitution on the XML document @doc
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+static int
+xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
+    xmlNodePtr cur;
+    int ret = 0;
+    int i, start;
+
+    if ((doc == NULL) || (tree == NULL))
+	return(-1);
+    if (ctxt == NULL)
+	return(-1);
+
+    if (doc->URL != NULL) {
+	ret = xmlXIncludeURLPush(ctxt, doc->URL);
+	if (ret < 0)
+	    return(-1);
+    }
+    start = ctxt->incNr;
+
+    /*
+     * First phase: lookup the elements in the document
+     */
+    cur = tree;
+    if (xmlXIncludeTestNode(ctxt, cur) == 1)
+	xmlXIncludePreProcessNode(ctxt, cur);
+    while ((cur != NULL) && (cur != tree->parent)) {
+	/* TODO: need to work on entities -> stack */
+	if ((cur->children != NULL) &&
+	    (cur->children->type != XML_ENTITY_DECL) &&
+	    (cur->children->type != XML_XINCLUDE_START) &&
+	    (cur->children->type != XML_XINCLUDE_END)) {
+	    cur = cur->children;
+	    if (xmlXIncludeTestNode(ctxt, cur))
+		xmlXIncludePreProcessNode(ctxt, cur);
+	} else if (cur->next != NULL) {
+	    cur = cur->next;
+	    if (xmlXIncludeTestNode(ctxt, cur))
+		xmlXIncludePreProcessNode(ctxt, cur);
+	} else {
+	    if (cur == tree)
+	        break;
+	    do {
+		cur = cur->parent;
+		if ((cur == NULL) || (cur == tree->parent))
+		    break; /* do */
+		if (cur->next != NULL) {
+		    cur = cur->next;
+		    if (xmlXIncludeTestNode(ctxt, cur))
+			xmlXIncludePreProcessNode(ctxt, cur);
+		    break; /* do */
+		}
+	    } while (cur != NULL);
+	}
+    }
+
+    /*
+     * Second Phase : collect the infosets fragments
+     */
+    for (i = start;i < ctxt->incNr; i++) {
+        xmlXIncludeLoadNode(ctxt, i);
+	ret++;
+    }
+
+    /*
+     * Third phase: extend the original document infoset.
+     *
+     * Originally we bypassed the inclusion if there were any errors
+     * encountered on any of the XIncludes.  A bug was raised (bug
+     * 132588) requesting that we output the XIncludes without error,
+     * so the check for inc!=NULL || xptr!=NULL was put in.  This may
+     * give some other problems in the future, but for now it seems to
+     * work ok.
+     *
+     */
+    for (i = ctxt->incBase;i < ctxt->incNr; i++) {
+	if ((ctxt->incTab[i]->inc != NULL) ||
+		(ctxt->incTab[i]->xptr != NULL) ||
+		(ctxt->incTab[i]->emptyFb != 0))	/* (empty fallback) */
+	    xmlXIncludeIncludeNode(ctxt, i);
+    }
+
+    if (doc->URL != NULL)
+	xmlXIncludeURLPop(ctxt);
+    return(ret);
+}
+
+/**
+ * xmlXIncludeSetFlags:
+ * @ctxt:  an XInclude processing context
+ * @flags: a set of xmlParserOption used for parsing XML includes
+ *
+ * Set the flags used for further processing of XML resources.
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xmlXIncludeSetFlags(xmlXIncludeCtxtPtr ctxt, int flags) {
+    if (ctxt == NULL)
+        return(-1);
+    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
+ * @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 document @doc
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {
+    xmlNodePtr tree;
+
+    if (doc == NULL)
+	return(-1);
+    tree = xmlDocGetRootElement(doc);
+    if (tree == NULL)
+	return(-1);
+    return(xmlXIncludeProcessTreeFlagsData(tree, flags, data));
+}
+
+/**
+ * xmlXIncludeProcessFlags:
+ * @doc: an XML document
+ * @flags: a set of xmlParserOption used for parsing XML includes
+ *
+ * Implement the XInclude substitution on the XML document @doc
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {
+    return xmlXIncludeProcessFlagsData(doc, flags, NULL);
+}
+
+/**
+ * xmlXIncludeProcess:
+ * @doc: an XML document
+ *
+ * Implement the XInclude substitution on the XML document @doc
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcess(xmlDocPtr doc) {
+    return(xmlXIncludeProcessFlags(doc, 0));
+}
+
+/**
+ * xmlXIncludeProcessTreeFlags:
+ * @tree: a node in an XML document
+ * @flags: a set of xmlParserOption used for parsing XML includes
+ *
+ * Implement the XInclude substitution for the given subtree
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
+    xmlXIncludeCtxtPtr ctxt;
+    int ret = 0;
+
+    if ((tree == NULL) || (tree->doc == NULL))
+	return(-1);
+    ctxt = xmlXIncludeNewContext(tree->doc);
+    if (ctxt == NULL)
+	return(-1);
+    ctxt->base = xmlNodeGetBase(tree->doc, tree);
+    xmlXIncludeSetFlags(ctxt, flags);
+    ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
+    if ((ret >= 0) && (ctxt->nbErrors > 0))
+	ret = -1;
+
+    xmlXIncludeFreeContext(ctxt);
+    return(ret);
+}
+
+/**
+ * xmlXIncludeProcessTree:
+ * @tree: a node in an XML document
+ *
+ * Implement the XInclude substitution for the given subtree
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessTree(xmlNodePtr tree) {
+    return(xmlXIncludeProcessTreeFlags(tree, 0));
+}
+
+/**
+ * xmlXIncludeProcessNode:
+ * @ctxt: an existing XInclude context
+ * @node: a node in an XML document
+ *
+ * Implement the XInclude substitution for the given subtree reusing
+ * the informations and data coming from the given context.
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
+    int ret = 0;
+
+    if ((node == NULL) || (node->doc == NULL) || (ctxt == NULL))
+	return(-1);
+    ret = xmlXIncludeDoProcess(ctxt, node->doc, node);
+    if ((ret >= 0) && (ctxt->nbErrors > 0))
+	ret = -1;
+    return(ret);
+}
+
+#else /* !LIBXML_XINCLUDE_ENABLED */
+#endif
+#define bottom_xinclude
+#include "elfgcchack.h"
diff --git a/src/xlink.c b/src/xlink.c
new file mode 100644
index 0000000..0d9be73
--- /dev/null
+++ b/src/xlink.c
@@ -0,0 +1,183 @@
+/*
+ * xlink.c : implementation of the hyperlinks detection module
+ *           This version supports both XML XLinks and HTML simple links
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_XPTR_ENABLED
+#include <string.h> /* for memset() only */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/valid.h>
+#include <libxml/xlink.h>
+#include <libxml/globals.h>
+
+#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
+#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
+
+/****************************************************************
+ *								*
+ *           Default setting and related functions		*
+ *								*
+ ****************************************************************/
+ 
+static xlinkHandlerPtr xlinkDefaultHandler = NULL;
+static xlinkNodeDetectFunc	xlinkDefaultDetect = NULL;
+
+/**
+ * xlinkGetDefaultHandler:
+ *
+ * Get the default xlink handler.
+ *
+ * Returns the current xlinkHandlerPtr value.
+ */
+xlinkHandlerPtr
+xlinkGetDefaultHandler(void) {
+    return(xlinkDefaultHandler);
+}
+
+
+/**
+ * xlinkSetDefaultHandler:
+ * @handler:  the new value for the xlink handler block
+ *
+ * Set the default xlink handlers
+ */
+void
+xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
+    xlinkDefaultHandler = handler;
+}
+
+/**
+ * xlinkGetDefaultDetect:
+ *
+ * Get the default xlink detection routine
+ *
+ * Returns the current function or NULL;
+ */
+xlinkNodeDetectFunc
+xlinkGetDefaultDetect	(void) {
+    return(xlinkDefaultDetect);
+}
+
+/**
+ * xlinkSetDefaultDetect:
+ * @func: pointer to the new detection routine.
+ *
+ * Set the default xlink detection routine
+ */
+void 
+xlinkSetDefaultDetect	(xlinkNodeDetectFunc func) {
+    xlinkDefaultDetect = func;
+}
+
+/****************************************************************
+ *								*
+ *                  The detection routines			*
+ *								*
+ ****************************************************************/
+
+ 
+/**
+ * xlinkIsLink:
+ * @doc:  the document containing the node
+ * @node:  the node pointer itself
+ *
+ * Check whether the given node carries the attributes needed
+ * to be a link element (or is one of the linking elements issued
+ * from the (X)HTML DtDs).
+ * This routine don't try to do full checking of the link validity
+ * but tries to detect and return the appropriate link type.
+ *
+ * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
+ *         link detected.
+ */
+xlinkType 
+xlinkIsLink	(xmlDocPtr doc, xmlNodePtr node) {
+    xmlChar *type = NULL, *role = NULL;
+    xlinkType ret = XLINK_TYPE_NONE;
+
+    if (node == NULL) return(XLINK_TYPE_NONE);
+    if (doc == NULL) doc = node->doc;
+    if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
+        /*
+	 * This is an HTML document.
+	 */
+    } else if ((node->ns != NULL) &&
+               (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
+	/*
+	 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
+	 */
+        /*
+	 * This is an XHTML element within an XML document
+	 * Check whether it's one of the element able to carry links
+	 * and in that case if it holds the attributes.
+	 */
+    }
+
+    /*
+     * We don't prevent a-priori having XML Linking constructs on
+     * XHTML elements
+     */
+    type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
+    if (type != NULL) {
+	if (xmlStrEqual(type, BAD_CAST "simple")) {
+            ret = XLINK_TYPE_SIMPLE;
+	} if (xmlStrEqual(type, BAD_CAST "extended")) {
+	    role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
+	    if (role != NULL) {
+		xmlNsPtr xlink;
+		xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
+		if (xlink == NULL) {
+		    /* Humm, fallback method */
+		    if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset")) 
+			ret = XLINK_TYPE_EXTENDED_SET;
+		} else {
+		    xmlChar buf[200];
+		    snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
+			     (char *) xlink->prefix);
+                    buf[sizeof(buf) - 1] = 0;
+		    if (xmlStrEqual(role, buf))
+			ret = XLINK_TYPE_EXTENDED_SET;
+
+		}
+
+	    }
+	    ret = XLINK_TYPE_EXTENDED;
+	}
+    }
+
+    if (type != NULL) xmlFree(type);
+    if (role != NULL) xmlFree(role);
+    return(ret);
+}
+#endif /* LIBXML_XPTR_ENABLED */
+#define bottom_xlink
+#include "elfgcchack.h"
diff --git a/src/xml2-config.1 b/src/xml2-config.1
new file mode 100644
index 0000000..8a25962
--- /dev/null
+++ b/src/xml2-config.1
@@ -0,0 +1,31 @@
+.TH GNOME-XML 1 "3 July 1999" Version 1.1.0
+.SH NAME
+xml-config - script to get information about the installed version of GNOME-XML
+.SH SYNOPSIS
+.B xml-config
+[\-\-prefix\fI[=DIR]\fP] [\-\-libs] [\-\-cflags] [\-\-version] [\-\-help]
+.SH DESCRIPTION
+\fIxml-config\fP is a tool that is used to determine the compile and
+linker flags that should be used to compile and link programs that use
+\fIGNOME-XML\fP.
+.SH OPTIONS
+.l
+\fIxml-config\fP accepts the following options:
+.TP 8
+.B  \-\-version
+Print the currently installed version of \fIGNOME-XML\fP on the standard output.
+.TP 8
+.B  \-\-libs
+Print the linker flags that are necessary to link a \fIGNOME-XML\fP program.
+.TP 8
+.B  \-\-cflags
+Print the compiler flags that are necessary to compile a \fIGNOME-XML\fP program.
+.TP 8
+.B  \-\-prefix=PREFIX
+If specified, use PREFIX instead of the installation prefix that
+\fIGNOME-XML\fP was built with when computing the output for the
+\-\-cflags and \-\-libs options. This option must be specified before
+any \-\-libs or \-\-cflags options.
+.SH AUTHOR
+This manual page was written by Fredrik Hallenberg <hallon@lysator.liu.se>,
+for the Debian GNU/linux system (but may be used by others).
diff --git a/src/xml2-config.in b/src/xml2-config.in
new file mode 100755
index 0000000..2989325
--- /dev/null
+++ b/src/xml2-config.in
@@ -0,0 +1,106 @@
+#! /bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+
+usage()
+{
+    cat <<EOF
+Usage: xml2-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix=DIR		change libxml prefix [default $prefix]
+  --exec-prefix=DIR	change libxml exec prefix [default $exec_prefix]
+  --libs		print library linking information
+  --cflags		print pre-processor and compiler flags
+  --modules		module support enabled
+  --help		display this help and exit
+  --version		output version information
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+cflags=false
+libs=false
+
+while test $# -gt 0; do
+    case "$1" in
+    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) optarg= ;;
+    esac
+
+    case "$1" in
+    --prefix=*)
+	prefix=$optarg
+	includedir=$prefix/include
+	libdir=$prefix/lib
+	;;
+
+    --prefix)
+	echo $prefix
+	;;
+
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      libdir=$exec_prefix/lib
+      ;;
+
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+
+    --version)
+	echo @VERSION@
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+       	echo @XML_INCLUDEDIR@ @XML_CFLAGS@
+       	;;
+
+    --libtool-libs)
+	if [ -r ${libdir}/@XML_LIBTOOLLIBS@ ]
+	then
+	    echo ${libdir}/@XML_LIBTOOLLIBS@
+	fi
+        ;;
+
+    --modules)
+       	echo @WITH_MODULES@
+       	;;
+
+    --libs)
+        if [ "`uname`" = "Linux" ]
+	then
+	    if [ "@XML_LIBDIR@" = "-L/usr/lib" -o "@XML_LIBDIR@" = "-L/usr/lib64" ]
+	    then
+		echo @XML_LIBS@ 
+	    else
+		echo @XML_LIBDIR@ @XML_LIBS@ 
+	    fi
+	else
+	    echo @XML_LIBDIR@ @XML_LIBS@ @WIN32_EXTRA_LIBADD@
+	fi
+       	;;
+
+    *)
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+
+exit 0
diff --git a/src/xml2Conf.sh.in b/src/xml2Conf.sh.in
new file mode 100644
index 0000000..08cb233
--- /dev/null
+++ b/src/xml2Conf.sh.in
@@ -0,0 +1,8 @@
+#
+# Configuration file for using the XML library in GNOME applications
+#
+XML2_LIBDIR="@XML_LIBDIR@"
+XML2_LIBS="@XML_LIBS@"
+XML2_INCLUDEDIR="@XML_INCLUDEDIR@"
+MODULE_VERSION="xml2-@VERSION@"
+
diff --git a/src/xmlIO.c b/src/xmlIO.c
new file mode 100644
index 0000000..29623dc
--- /dev/null
+++ b/src/xmlIO.c
@@ -0,0 +1,3992 @@
+/*
+ * xmlIO.c : implementation of the I/O interfaces used by the parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+#include <windows.h>
+#endif
+
+#if defined(_WIN32_WCE)
+#include <winnls.h> /* for CP_UTF8 */
+#endif
+
+/* Figure a portable way to know if a file is a directory. */
+#ifndef HAVE_STAT
+#  ifdef HAVE__STAT
+     /* MS C library seems to define stat and _stat. The definition
+        is identical. Still, mapping them to each other causes a warning. */
+#    ifndef _MSC_VER
+#      define stat(x,y) _stat(x,y)
+#    endif
+#    define HAVE_STAT
+#  endif
+#else
+#  ifdef HAVE__STAT
+#    if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+#      define stat _stat
+#    endif
+#  endif
+#endif
+#ifdef HAVE_STAT
+#  ifndef S_ISDIR
+#    ifdef _S_ISDIR
+#      define S_ISDIR(x) _S_ISDIR(x)
+#    else
+#      ifdef S_IFDIR
+#        ifndef S_IFMT
+#          ifdef _S_IFMT
+#            define S_IFMT _S_IFMT
+#          endif
+#        endif
+#        ifdef S_IFMT
+#          define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlIO.h>
+#include <libxml/uri.h>
+#include <libxml/xmlerror.h>
+#ifdef LIBXML_CATALOG_ENABLED
+#include <libxml/catalog.h>
+#endif
+#include <libxml/globals.h>
+
+/* #define VERBOSE_FAILURE */
+/* #define DEBUG_EXTERNAL_ENTITIES */
+/* #define DEBUG_INPUT */
+
+#ifdef DEBUG_INPUT
+#define MINLEN 40
+#else
+#define MINLEN 4000
+#endif
+
+/*
+ * Input I/O callback sets
+ */
+typedef struct _xmlInputCallback {
+    xmlInputMatchCallback matchcallback;
+    xmlInputOpenCallback opencallback;
+    xmlInputReadCallback readcallback;
+    xmlInputCloseCallback closecallback;
+} xmlInputCallback;
+
+#define MAX_INPUT_CALLBACK 15
+
+static xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];
+static int xmlInputCallbackNr = 0;
+static int xmlInputCallbackInitialized = 0;
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Output I/O callback sets
+ */
+typedef struct _xmlOutputCallback {
+    xmlOutputMatchCallback matchcallback;
+    xmlOutputOpenCallback opencallback;
+    xmlOutputWriteCallback writecallback;
+    xmlOutputCloseCallback closecallback;
+} xmlOutputCallback;
+
+#define MAX_OUTPUT_CALLBACK 15
+
+static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
+static int xmlOutputCallbackNr = 0;
+static int xmlOutputCallbackInitialized = 0;
+
+xmlOutputBufferPtr
+xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Tree memory error handler				*
+ *									*
+ ************************************************************************/
+
+static const char *IOerr[] = {
+    "Unknown IO error",         /* UNKNOWN */
+    "Permission denied",	/* EACCES */
+    "Resource temporarily unavailable",/* EAGAIN */
+    "Bad file descriptor",	/* EBADF */
+    "Bad message",		/* EBADMSG */
+    "Resource busy",		/* EBUSY */
+    "Operation canceled",	/* ECANCELED */
+    "No child processes",	/* ECHILD */
+    "Resource deadlock avoided",/* EDEADLK */
+    "Domain error",		/* EDOM */
+    "File exists",		/* EEXIST */
+    "Bad address",		/* EFAULT */
+    "File too large",		/* EFBIG */
+    "Operation in progress",	/* EINPROGRESS */
+    "Interrupted function call",/* EINTR */
+    "Invalid argument",		/* EINVAL */
+    "Input/output error",	/* EIO */
+    "Is a directory",		/* EISDIR */
+    "Too many open files",	/* EMFILE */
+    "Too many links",		/* EMLINK */
+    "Inappropriate message buffer length",/* EMSGSIZE */
+    "Filename too long",	/* ENAMETOOLONG */
+    "Too many open files in system",/* ENFILE */
+    "No such device",		/* ENODEV */
+    "No such file or directory",/* ENOENT */
+    "Exec format error",	/* ENOEXEC */
+    "No locks available",	/* ENOLCK */
+    "Not enough space",		/* ENOMEM */
+    "No space left on device",	/* ENOSPC */
+    "Function not implemented",	/* ENOSYS */
+    "Not a directory",		/* ENOTDIR */
+    "Directory not empty",	/* ENOTEMPTY */
+    "Not supported",		/* ENOTSUP */
+    "Inappropriate I/O control operation",/* ENOTTY */
+    "No such device or address",/* ENXIO */
+    "Operation not permitted",	/* EPERM */
+    "Broken pipe",		/* EPIPE */
+    "Result too large",		/* ERANGE */
+    "Read-only file system",	/* EROFS */
+    "Invalid seek",		/* ESPIPE */
+    "No such process",		/* ESRCH */
+    "Operation timed out",	/* ETIMEDOUT */
+    "Improper link",		/* EXDEV */
+    "Attempt to load network entity %s", /* XML_IO_NETWORK_ATTEMPT */
+    "encoder error",		/* XML_IO_ENCODER */
+    "flush error",
+    "write error",
+    "no input",
+    "buffer full",
+    "loading error",
+    "not a socket",		/* ENOTSOCK */
+    "already connected",	/* EISCONN */
+    "connection refused",	/* ECONNREFUSED */
+    "unreachable network",	/* ENETUNREACH */
+    "adddress in use",		/* EADDRINUSE */
+    "already in use",		/* EALREADY */
+    "unknown address familly",	/* EAFNOSUPPORT */
+};
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+/**
+ * __xmlIOWin32UTF8ToWChar:
+ * @u8String:  uft-8 string
+ *
+ * Convert a string from utf-8 to wchar (WINDOWS ONLY!)
+ */
+static wchar_t *
+__xmlIOWin32UTF8ToWChar(const char *u8String)
+{
+    wchar_t *wString = NULL;
+
+    if (u8String) {
+        int wLen =
+            MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u8String,
+                                -1, NULL, 0);
+        if (wLen) {
+            wString = xmlMalloc(wLen * sizeof(wchar_t));
+            if (wString) {
+                if (MultiByteToWideChar
+                    (CP_UTF8, 0, u8String, -1, wString, wLen) == 0) {
+                    xmlFree(wString);
+                    wString = NULL;
+                }
+            }
+        }
+    }
+
+    return wString;
+}
+#endif
+
+/**
+ * xmlIOErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlIOErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_IO, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * __xmlIOErr:
+ * @code:  the error number
+ * @
+ * @extra:  extra informations
+ *
+ * Handle an I/O error
+ */
+void
+__xmlIOErr(int domain, int code, const char *extra)
+{
+    unsigned int idx;
+
+    if (code == 0) {
+#ifdef HAVE_ERRNO_H
+	if (errno == 0) code = 0;
+#ifdef EACCES
+        else if (errno == EACCES) code = XML_IO_EACCES;
+#endif
+#ifdef EAGAIN
+        else if (errno == EAGAIN) code = XML_IO_EAGAIN;
+#endif
+#ifdef EBADF
+        else if (errno == EBADF) code = XML_IO_EBADF;
+#endif
+#ifdef EBADMSG
+        else if (errno == EBADMSG) code = XML_IO_EBADMSG;
+#endif
+#ifdef EBUSY
+        else if (errno == EBUSY) code = XML_IO_EBUSY;
+#endif
+#ifdef ECANCELED
+        else if (errno == ECANCELED) code = XML_IO_ECANCELED;
+#endif
+#ifdef ECHILD
+        else if (errno == ECHILD) code = XML_IO_ECHILD;
+#endif
+#ifdef EDEADLK
+        else if (errno == EDEADLK) code = XML_IO_EDEADLK;
+#endif
+#ifdef EDOM
+        else if (errno == EDOM) code = XML_IO_EDOM;
+#endif
+#ifdef EEXIST
+        else if (errno == EEXIST) code = XML_IO_EEXIST;
+#endif
+#ifdef EFAULT
+        else if (errno == EFAULT) code = XML_IO_EFAULT;
+#endif
+#ifdef EFBIG
+        else if (errno == EFBIG) code = XML_IO_EFBIG;
+#endif
+#ifdef EINPROGRESS
+        else if (errno == EINPROGRESS) code = XML_IO_EINPROGRESS;
+#endif
+#ifdef EINTR
+        else if (errno == EINTR) code = XML_IO_EINTR;
+#endif
+#ifdef EINVAL
+        else if (errno == EINVAL) code = XML_IO_EINVAL;
+#endif
+#ifdef EIO
+        else if (errno == EIO) code = XML_IO_EIO;
+#endif
+#ifdef EISDIR
+        else if (errno == EISDIR) code = XML_IO_EISDIR;
+#endif
+#ifdef EMFILE
+        else if (errno == EMFILE) code = XML_IO_EMFILE;
+#endif
+#ifdef EMLINK
+        else if (errno == EMLINK) code = XML_IO_EMLINK;
+#endif
+#ifdef EMSGSIZE
+        else if (errno == EMSGSIZE) code = XML_IO_EMSGSIZE;
+#endif
+#ifdef ENAMETOOLONG
+        else if (errno == ENAMETOOLONG) code = XML_IO_ENAMETOOLONG;
+#endif
+#ifdef ENFILE
+        else if (errno == ENFILE) code = XML_IO_ENFILE;
+#endif
+#ifdef ENODEV
+        else if (errno == ENODEV) code = XML_IO_ENODEV;
+#endif
+#ifdef ENOENT
+        else if (errno == ENOENT) code = XML_IO_ENOENT;
+#endif
+#ifdef ENOEXEC
+        else if (errno == ENOEXEC) code = XML_IO_ENOEXEC;
+#endif
+#ifdef ENOLCK
+        else if (errno == ENOLCK) code = XML_IO_ENOLCK;
+#endif
+#ifdef ENOMEM
+        else if (errno == ENOMEM) code = XML_IO_ENOMEM;
+#endif
+#ifdef ENOSPC
+        else if (errno == ENOSPC) code = XML_IO_ENOSPC;
+#endif
+#ifdef ENOSYS
+        else if (errno == ENOSYS) code = XML_IO_ENOSYS;
+#endif
+#ifdef ENOTDIR
+        else if (errno == ENOTDIR) code = XML_IO_ENOTDIR;
+#endif
+#ifdef ENOTEMPTY
+        else if (errno == ENOTEMPTY) code = XML_IO_ENOTEMPTY;
+#endif
+#ifdef ENOTSUP
+        else if (errno == ENOTSUP) code = XML_IO_ENOTSUP;
+#endif
+#ifdef ENOTTY
+        else if (errno == ENOTTY) code = XML_IO_ENOTTY;
+#endif
+#ifdef ENXIO
+        else if (errno == ENXIO) code = XML_IO_ENXIO;
+#endif
+#ifdef EPERM
+        else if (errno == EPERM) code = XML_IO_EPERM;
+#endif
+#ifdef EPIPE
+        else if (errno == EPIPE) code = XML_IO_EPIPE;
+#endif
+#ifdef ERANGE
+        else if (errno == ERANGE) code = XML_IO_ERANGE;
+#endif
+#ifdef EROFS
+        else if (errno == EROFS) code = XML_IO_EROFS;
+#endif
+#ifdef ESPIPE
+        else if (errno == ESPIPE) code = XML_IO_ESPIPE;
+#endif
+#ifdef ESRCH
+        else if (errno == ESRCH) code = XML_IO_ESRCH;
+#endif
+#ifdef ETIMEDOUT
+        else if (errno == ETIMEDOUT) code = XML_IO_ETIMEDOUT;
+#endif
+#ifdef EXDEV
+        else if (errno == EXDEV) code = XML_IO_EXDEV;
+#endif
+#ifdef ENOTSOCK
+        else if (errno == ENOTSOCK) code = XML_IO_ENOTSOCK;
+#endif
+#ifdef EISCONN
+        else if (errno == EISCONN) code = XML_IO_EISCONN;
+#endif
+#ifdef ECONNREFUSED
+        else if (errno == ECONNREFUSED) code = XML_IO_ECONNREFUSED;
+#endif
+#ifdef ETIMEDOUT
+        else if (errno == ETIMEDOUT) code = XML_IO_ETIMEDOUT;
+#endif
+#ifdef ENETUNREACH
+        else if (errno == ENETUNREACH) code = XML_IO_ENETUNREACH;
+#endif
+#ifdef EADDRINUSE
+        else if (errno == EADDRINUSE) code = XML_IO_EADDRINUSE;
+#endif
+#ifdef EINPROGRESS
+        else if (errno == EINPROGRESS) code = XML_IO_EINPROGRESS;
+#endif
+#ifdef EALREADY
+        else if (errno == EALREADY) code = XML_IO_EALREADY;
+#endif
+#ifdef EAFNOSUPPORT
+        else if (errno == EAFNOSUPPORT) code = XML_IO_EAFNOSUPPORT;
+#endif
+        else code = XML_IO_UNKNOWN;
+#endif /* HAVE_ERRNO_H */
+    }
+    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);
+}
+
+/**
+ * xmlIOErr:
+ * @code:  the error number
+ * @extra:  extra informations
+ *
+ * Handle an I/O error
+ */
+static void
+xmlIOErr(int code, const char *extra)
+{
+    __xmlIOErr(XML_FROM_IO, code, extra);
+}
+
+/**
+ * __xmlLoaderErr:
+ * @ctx: the parser context
+ * @extra:  extra informations
+ *
+ * Handle a resource access error
+ */
+void
+__xmlLoaderErr(void *ctx, const char *msg, const char *filename)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+    xmlErrorLevel level = XML_ERR_ERROR;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+	return;
+    if ((ctxt != NULL) && (ctxt->sax != NULL)) {
+        if (ctxt->validate) {
+	    channel = ctxt->sax->error;
+	    level = XML_ERR_ERROR;
+	} else {
+	    channel = ctxt->sax->warning;
+	    level = XML_ERR_WARNING;
+	}
+	if (ctxt->sax->initialized == XML_SAX2_MAGIC)
+	    schannel = ctxt->sax->serror;
+	data = ctxt->userData;
+    }
+    __xmlRaiseError(schannel, channel, data, ctxt, NULL, XML_FROM_IO,
+                    XML_IO_LOAD_ERROR, level, NULL, 0,
+		    filename, NULL, NULL, 0, 0,
+		    msg, filename);
+
+}
+
+/************************************************************************
+ *									*
+ *		Tree memory error handler				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlNormalizeWindowsPath:
+ * @path: the input file path
+ *
+ * This function is obsolete. Please see xmlURIFromPath in uri.c for
+ * a better solution.
+ *
+ * Returns a canonicalized version of the path
+ */
+xmlChar *
+xmlNormalizeWindowsPath(const xmlChar *path)
+{
+    return xmlCanonicPath(path);
+}
+
+/**
+ * xmlCleanupInputCallbacks:
+ *
+ * clears the entire input callback table. this includes the
+ * compiled-in I/O.
+ */
+void
+xmlCleanupInputCallbacks(void)
+{
+    int i;
+
+    if (!xmlInputCallbackInitialized)
+        return;
+
+    for (i = xmlInputCallbackNr - 1; i >= 0; i--) {
+        xmlInputCallbackTable[i].matchcallback = NULL;
+        xmlInputCallbackTable[i].opencallback = NULL;
+        xmlInputCallbackTable[i].readcallback = NULL;
+        xmlInputCallbackTable[i].closecallback = NULL;
+    }
+
+    xmlInputCallbackNr = 0;
+    xmlInputCallbackInitialized = 0;
+}
+
+/**
+ * xmlPopInputCallbacks:
+ *
+ * Clear the top input callback from the input stack. this includes the
+ * compiled-in I/O.
+ *
+ * Returns the number of input callback registered or -1 in case of error.
+ */
+int
+xmlPopInputCallbacks(void)
+{
+    if (!xmlInputCallbackInitialized)
+        return(-1);
+
+    if (xmlInputCallbackNr <= 0)
+        return(-1);
+
+    xmlInputCallbackNr--;
+    xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL;
+    xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL;
+    xmlInputCallbackTable[xmlInputCallbackNr].readcallback = NULL;
+    xmlInputCallbackTable[xmlInputCallbackNr].closecallback = NULL;
+
+    return(xmlInputCallbackNr);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlCleanupOutputCallbacks:
+ *
+ * clears the entire output callback table. this includes the
+ * compiled-in I/O callbacks.
+ */
+void
+xmlCleanupOutputCallbacks(void)
+{
+    int i;
+
+    if (!xmlOutputCallbackInitialized)
+        return;
+
+    for (i = xmlOutputCallbackNr - 1; i >= 0; i--) {
+        xmlOutputCallbackTable[i].matchcallback = NULL;
+        xmlOutputCallbackTable[i].opencallback = NULL;
+        xmlOutputCallbackTable[i].writecallback = NULL;
+        xmlOutputCallbackTable[i].closecallback = NULL;
+    }
+
+    xmlOutputCallbackNr = 0;
+    xmlOutputCallbackInitialized = 0;
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ *		Standard I/O for file accesses				*
+ *									*
+ ************************************************************************/
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+
+/**
+ *  xmlWrapOpenUtf8:
+ * @path:  the path in utf-8 encoding
+ * @mode:  type of access (0 - read, 1 - write)
+ *
+ * function opens the file specified by @path
+ *
+ */
+static FILE*
+xmlWrapOpenUtf8(const char *path,int mode)
+{
+    FILE *fd = NULL;
+    wchar_t *wPath;
+
+    wPath = __xmlIOWin32UTF8ToWChar(path);
+    if(wPath)
+    {
+       fd = _wfopen(wPath, mode ? L"wb" : L"rb");
+       xmlFree(wPath);
+    }
+    /* maybe path in native encoding */
+    if(fd == NULL)
+       fd = fopen(path, mode ? "wb" : "rb");
+
+    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
+ * @info:  structure that stores results
+ *
+ * function obtains information about the file or directory
+ *
+ */
+static int
+xmlWrapStatUtf8(const char *path,struct stat *info)
+{
+#ifdef HAVE_STAT
+    int retval = -1;
+    wchar_t *wPath;
+
+    wPath = __xmlIOWin32UTF8ToWChar(path);
+    if (wPath)
+    {
+       retval = _wstat(wPath,info);
+       xmlFree(wPath);
+    }
+    /* maybe path in native encoding */
+    if(retval < 0)
+       retval = stat(path,info);
+    return retval;
+#else
+    return -1;
+#endif
+}
+
+/**
+ *  xmlWrapOpenNative:
+ * @path:  the path
+ * @mode:  type of access (0 - read, 1 - write)
+ *
+ * function opens the file specified by @path
+ *
+ */
+static FILE*
+xmlWrapOpenNative(const char *path,int mode)
+{
+    return fopen(path,mode ? "wb" : "rb");
+}
+
+/**
+ *  xmlWrapStatNative:
+ * @path:  the path
+ * @info:  structure that stores results
+ *
+ * function obtains information about the file or directory
+ *
+ */
+static int
+xmlWrapStatNative(const char *path,struct stat *info)
+{
+#ifdef HAVE_STAT
+    return stat(path,info);
+#else
+    return -1;
+#endif
+}
+
+typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s);
+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:
+ *
+ * Initialize platform specific features.
+ */
+static void
+xmlInitPlatformSpecificIo(void)
+{
+    static int xmlPlatformIoInitialized = 0;
+    OSVERSIONINFO osvi;
+
+    if(xmlPlatformIoInitialized)
+      return;
+
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+
+    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;
+    return;
+}
+
+#endif
+
+/**
+ * xmlCheckFilename:
+ * @path:  the path to check
+ *
+ * function checks to see if @path is a valid source
+ * (file, socket...) for XML.
+ *
+ * if stat is not available on the target machine,
+ * returns 1.  if stat fails, returns 0 (if calling
+ * stat on the filename fails, it can't be right).
+ * if stat succeeds and the file is a directory,
+ * returns 2.  otherwise returns 1.
+ */
+
+int
+xmlCheckFilename (const char *path)
+{
+#ifdef HAVE_STAT
+	struct stat stat_buffer;
+#endif
+	if (path == NULL)
+		return(0);
+
+#ifdef HAVE_STAT
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    if (xmlWrapStat(path, &stat_buffer) == -1)
+        return 0;
+#else
+    if (stat(path, &stat_buffer) == -1)
+        return 0;
+#endif
+#ifdef S_ISDIR
+    if (S_ISDIR(stat_buffer.st_mode))
+        return 2;
+#endif
+#endif /* HAVE_STAT */
+    return 1;
+}
+
+static int
+xmlNop(void) {
+    return(0);
+}
+
+/**
+ * xmlFdRead:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to read
+ *
+ * Read @len bytes to @buffer from the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlFdRead (void * context, char * buffer, int len) {
+    int ret;
+
+    ret = read((int) (long) context, &buffer[0], len);
+    if (ret < 0) xmlIOErr(0, "read()");
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlFdWrite:
+ * @context:  the I/O context
+ * @buffer:  where to get data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlFdWrite (void * context, const char * buffer, int len) {
+    int ret = 0;
+
+    if (len > 0) {
+	ret = write((int) (long) context, &buffer[0], len);
+	if (ret < 0) xmlIOErr(0, "write()");
+    }
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlFdClose:
+ * @context:  the I/O context
+ *
+ * Close an I/O channel
+ *
+ * Returns 0 in case of success and error code otherwise
+ */
+static int
+xmlFdClose (void * context) {
+    int ret;
+    ret = close((int) (long) context);
+    if (ret < 0) xmlIOErr(0, "close()");
+    return(ret);
+}
+
+/**
+ * xmlFileMatch:
+ * @filename:  the URI for matching
+ *
+ * input from FILE *
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+int
+xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) {
+    return(1);
+}
+
+/**
+ * xmlFileOpen_real:
+ * @filename:  the URI for matching
+ *
+ * input from FILE *, supports compressed input
+ * if @filename is " " then the standard input is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+static void *
+xmlFileOpen_real (const char *filename) {
+    const char *path = NULL;
+    FILE *fd;
+
+    if (filename == NULL)
+        return(NULL);
+
+    if (!strcmp(filename, "-")) {
+	fd = stdin;
+	return((void *) fd);
+    }
+
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
+	path = &filename[16];
+#endif
+    } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[8];
+#else
+	path = &filename[7];
+#endif
+    } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) {
+        /* lots of generators seems to lazy to read RFC 1738 */
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[6];
+#else
+	path = &filename[5];
+#endif
+    } else
+	path = filename;
+
+    if (path == NULL)
+	return(NULL);
+    if (!xmlCheckFilename(path))
+        return(NULL);
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    fd = xmlWrapOpen(path, 0);
+#else
+    fd = fopen(path, "r");
+#endif /* WIN32 */
+    if (fd == NULL) xmlIOErr(0, path);
+    return((void *) fd);
+}
+
+/**
+ * xmlFileOpen:
+ * @filename:  the URI for matching
+ *
+ * Wrapper around xmlFileOpen_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
+ */
+void *
+xmlFileOpen (const char *filename) {
+    char *unescaped;
+    void *retval;
+
+    retval = xmlFileOpen_real(filename);
+    if (retval == NULL) {
+	unescaped = xmlURIUnescapeString(filename, 0, NULL);
+	if (unescaped != NULL) {
+	    retval = xmlFileOpen_real(unescaped);
+	    xmlFree(unescaped);
+	}
+    }
+
+    return retval;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlFileOpenW:
+ * @filename:  the URI for matching
+ *
+ * output to from FILE *,
+ * if @filename is "-" then the standard output is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+static void *
+xmlFileOpenW (const char *filename) {
+    const char *path = NULL;
+    FILE *fd;
+
+    if (!strcmp(filename, "-")) {
+	fd = stdout;
+	return((void *) fd);
+    }
+
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
+	path = &filename[16];
+#endif
+    else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[8];
+#else
+	path = &filename[7];
+#endif
+    } else
+	path = filename;
+
+    if (path == NULL)
+	return(NULL);
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    fd = xmlWrapOpen(path, 1);
+#else
+ 	   fd = fopen(path, "wb");
+#endif /* WIN32 */
+
+	 if (fd == NULL) xmlIOErr(0, path);
+    return((void *) fd);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlFileRead:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Read @len bytes to @buffer from the I/O channel.
+ *
+ * Returns the number of bytes written or < 0 in case of failure
+ */
+int
+xmlFileRead (void * context, char * buffer, int len) {
+    int ret;
+    if ((context == NULL) || (buffer == NULL))
+        return(-1);
+    ret = fread(&buffer[0], 1,  len, (FILE *) context);
+    if (ret < 0) xmlIOErr(0, "fread()");
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlFileWrite:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlFileWrite (void * context, const char * buffer, int len) {
+    int items;
+
+    if ((context == NULL) || (buffer == NULL))
+        return(-1);
+    items = fwrite(&buffer[0], len, 1, (FILE *) context);
+    if ((items == 0) && (ferror((FILE *) context))) {
+        xmlIOErr(0, "fwrite()");
+	return(-1);
+    }
+    return(items * len);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlFileClose:
+ * @context:  the I/O context
+ *
+ * Close an I/O channel
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlFileClose (void * context) {
+    FILE *fil;
+    int ret;
+
+    if (context == NULL)
+        return(-1);
+    fil = (FILE *) context;
+    if ((fil == stdout) || (fil == stderr)) {
+        ret = fflush(fil);
+	if (ret < 0)
+	    xmlIOErr(0, "fflush()");
+	return(0);
+    }
+    if (fil == stdin)
+	return(0);
+    ret = ( fclose((FILE *) context) == EOF ) ? -1 : 0;
+    if (ret < 0)
+        xmlIOErr(0, "fclose()");
+    return(ret);
+}
+
+/**
+ * xmlFileFlush:
+ * @context:  the I/O context
+ *
+ * Flush an I/O channel
+ */
+static int
+xmlFileFlush (void * context) {
+    int ret;
+
+    if (context == NULL)
+        return(-1);
+    ret = ( fflush((FILE *) context) == EOF ) ? -1 : 0;
+    if (ret < 0)
+        xmlIOErr(0, "fflush()");
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlBufferWrite:
+ * @context:  the xmlBuffer
+ * @buffer:  the data to write
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the xml buffer
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlBufferWrite (void * context, const char * buffer, int len) {
+    int ret;
+
+    ret = xmlBufferAdd((xmlBufferPtr) context, (const xmlChar *) buffer, len);
+    if (ret != 0)
+        return(-1);
+    return(len);
+}
+#endif
+
+#ifdef HAVE_ZLIB_H
+/************************************************************************
+ *									*
+ *		I/O for compressed file accesses			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlGzfileMatch:
+ * @filename:  the URI for matching
+ *
+ * input from compressed file test
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+static int
+xmlGzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
+    return(1);
+}
+
+/**
+ * xmlGzfileOpen_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 *
+xmlGzfileOpen_real (const char *filename) {
+    const char *path = NULL;
+    gzFile fd;
+
+    if (!strcmp(filename, "-")) {
+        fd = gzdopen(dup(0), "rb");
+	return((void *) fd);
+    }
+
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
+	path = &filename[16];
+#endif
+    else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[8];
+#else
+	path = &filename[7];
+#endif
+    } else
+	path = filename;
+
+    if (path == NULL)
+	return(NULL);
+    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);
+}
+
+/**
+ * xmlGzfileOpen:
+ * @filename:  the URI for matching
+ *
+ * Wrapper around xmlGzfileOpen if the open fais, it will
+ * try to unescape @filename
+ */
+static void *
+xmlGzfileOpen (const char *filename) {
+    char *unescaped;
+    void *retval;
+
+    retval = xmlGzfileOpen_real(filename);
+    if (retval == NULL) {
+	unescaped = xmlURIUnescapeString(filename, 0, NULL);
+	if (unescaped != NULL) {
+	    retval = xmlGzfileOpen_real(unescaped);
+	}
+	xmlFree(unescaped);
+    }
+    return retval;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlGzfileOpenW:
+ * @filename:  the URI for matching
+ * @compression:  the compression factor (0 - 9 included)
+ *
+ * input from compressed file open
+ * if @filename is " " then the standard input is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+static void *
+xmlGzfileOpenW (const char *filename, int compression) {
+    const char *path = NULL;
+    char mode[15];
+    gzFile fd;
+
+    snprintf(mode, sizeof(mode), "wb%d", compression);
+    if (!strcmp(filename, "-")) {
+        fd = gzdopen(dup(1), mode);
+	return((void *) fd);
+    }
+
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
+	path = &filename[16];
+#endif
+    else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &filename[8];
+#else
+	path = &filename[7];
+#endif
+    } 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 */
+
+/**
+ * xmlGzfileRead:
+ * @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
+xmlGzfileRead (void * context, char * buffer, int len) {
+    int ret;
+
+    ret = gzread((gzFile) context, &buffer[0], len);
+    if (ret < 0) xmlIOErr(0, "gzread()");
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlGzfileWrite:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the compressed I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlGzfileWrite (void * context, const char * buffer, int len) {
+    int ret;
+
+    ret = gzwrite((gzFile) context, (char *) &buffer[0], len);
+    if (ret < 0) xmlIOErr(0, "gzwrite()");
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlGzfileClose:
+ * @context:  the I/O context
+ *
+ * Close a compressed I/O channel
+ */
+static int
+xmlGzfileClose (void * context) {
+    int ret;
+
+    ret =  (gzclose((gzFile) context) == Z_OK ) ? 0 : -1;
+    if (ret < 0) xmlIOErr(0, "gzclose()");
+    return(ret);
+}
+#endif /* HAVE_ZLIB_H */
+
+#ifdef LIBXML_HTTP_ENABLED
+/************************************************************************
+ *									*
+ *			I/O for HTTP file accesses			*
+ *									*
+ ************************************************************************/
+
+#ifdef LIBXML_OUTPUT_ENABLED
+typedef struct xmlIOHTTPWriteCtxt_
+{
+    int			compression;
+
+    char *		uri;
+
+    void *		doc_buff;
+
+} xmlIOHTTPWriteCtxt, *xmlIOHTTPWriteCtxtPtr;
+
+#ifdef HAVE_ZLIB_H
+
+#define DFLT_WBITS		( -15 )
+#define DFLT_MEM_LVL		( 8 )
+#define GZ_MAGIC1		( 0x1f )
+#define GZ_MAGIC2		( 0x8b )
+#define LXML_ZLIB_OS_CODE	( 0x03 )
+#define INIT_HTTP_BUFF_SIZE	( 32768 )
+#define DFLT_ZLIB_RATIO		( 5 )
+
+/*
+**  Data structure and functions to work with sending compressed data
+**  via HTTP.
+*/
+
+typedef struct xmlZMemBuff_
+{
+   unsigned long	size;
+   unsigned long	crc;
+
+   unsigned char *	zbuff;
+   z_stream		zctrl;
+
+} xmlZMemBuff, *xmlZMemBuffPtr;
+
+/**
+ * append_reverse_ulong
+ * @buff:  Compressed memory buffer
+ * @data:  Unsigned long to append
+ *
+ * Append a unsigned long in reverse byte order to the end of the
+ * memory buffer.
+ */
+static void
+append_reverse_ulong( xmlZMemBuff * buff, unsigned long data ) {
+
+    int		idx;
+
+    if ( buff == NULL )
+	return;
+
+    /*
+    **  This is plagiarized from putLong in gzio.c (zlib source) where
+    **  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.
+    */
+
+    for ( idx = 0; idx < 4; idx++ ) {
+	*buff->zctrl.next_out = ( data & 0xff );
+	data >>= 8;
+	buff->zctrl.next_out++;
+    }
+
+    return;
+}
+
+/**
+ *
+ * xmlFreeZMemBuff
+ * @buff:  The memory buffer context to clear
+ *
+ * Release all the resources associated with the compressed memory buffer.
+ */
+static void
+xmlFreeZMemBuff( xmlZMemBuffPtr buff ) {
+
+#ifdef DEBUG_HTTP
+    int z_err;
+#endif
+
+    if ( buff == NULL )
+	return;
+
+    xmlFree( buff->zbuff );
+#ifdef DEBUG_HTTP
+    z_err = deflateEnd( &buff->zctrl );
+    if ( z_err != Z_OK )
+	xmlGenericError( xmlGenericErrorContext,
+			"xmlFreeZMemBuff:  Error releasing zlib context:  %d\n",
+			z_err );
+#else
+    deflateEnd( &buff->zctrl );
+#endif
+
+    xmlFree( buff );
+    return;
+}
+
+/**
+ * xmlCreateZMemBuff
+ *@compression:	Compression value to use
+ *
+ * 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
+ * write the document to disk.  The code for the header/trailer data to
+ * the compression is plagiarized from the zlib source files.
+ */
+static void *
+xmlCreateZMemBuff( int compression ) {
+
+    int			z_err;
+    int			hdr_lgth;
+    xmlZMemBuffPtr	buff = NULL;
+
+    if ( ( compression < 1 ) || ( compression > 9 ) )
+	return ( NULL );
+
+    /*  Create the control and data areas  */
+
+    buff = xmlMalloc( sizeof( xmlZMemBuff ) );
+    if ( buff == NULL ) {
+	xmlIOErrMemory("creating buffer context");
+	return ( NULL );
+    }
+
+    (void)memset( buff, 0, sizeof( xmlZMemBuff ) );
+    buff->size = INIT_HTTP_BUFF_SIZE;
+    buff->zbuff = xmlMalloc( buff->size );
+    if ( buff->zbuff == NULL ) {
+	xmlFreeZMemBuff( buff );
+	xmlIOErrMemory("creating buffer");
+	return ( NULL );
+    }
+
+    z_err = deflateInit2( &buff->zctrl, compression, Z_DEFLATED,
+			    DFLT_WBITS, DFLT_MEM_LVL, Z_DEFAULT_STRATEGY );
+    if ( z_err != Z_OK ) {
+	xmlChar msg[500];
+	xmlFreeZMemBuff( buff );
+	buff = NULL;
+	xmlStrPrintf(msg, 500,
+		    (const xmlChar *) "xmlCreateZMemBuff:  %s %d\n",
+		    "Error initializing compression context.  ZLIB error:",
+		    z_err );
+	xmlIOErr(XML_IO_WRITE, (const char *) msg);
+	return ( NULL );
+    }
+
+    /*  Set the header data.  The CRC will be needed for the trailer  */
+    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,
+			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;
+
+    return ( buff );
+}
+
+/**
+ * xmlZMemBuffExtend
+ * @buff:  Buffer used to compress and consolidate data.
+ * @ext_amt:   Number of bytes to extend the buffer.
+ *
+ * Extend the internal buffer used to store the compressed data by the
+ * specified amount.
+ *
+ * Returns 0 on success or -1 on failure to extend the buffer.  On failure
+ * the original buffer still exists at the original size.
+ */
+static int
+xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) {
+
+    int			rc = -1;
+    size_t		new_size;
+    size_t		cur_used;
+
+    unsigned char *	tmp_ptr = NULL;
+
+    if ( buff == NULL )
+	return ( -1 );
+
+    else if ( ext_amt == 0 )
+	return ( 0 );
+
+    cur_used = buff->zctrl.next_out - buff->zbuff;
+    new_size = buff->size + ext_amt;
+
+#ifdef DEBUG_HTTP
+    if ( cur_used > new_size )
+	xmlGenericError( xmlGenericErrorContext,
+			"xmlZMemBuffExtend:  %s\n%s %d bytes.\n",
+			"Buffer overwrite detected during compressed memory",
+			"buffer extension.  Overflowed by",
+			(cur_used - new_size ) );
+#endif
+
+    tmp_ptr = xmlRealloc( buff->zbuff, new_size );
+    if ( tmp_ptr != NULL ) {
+	rc = 0;
+	buff->size  = new_size;
+	buff->zbuff = tmp_ptr;
+	buff->zctrl.next_out  = tmp_ptr + cur_used;
+	buff->zctrl.avail_out = new_size - cur_used;
+    }
+    else {
+	xmlChar msg[500];
+	xmlStrPrintf(msg, 500,
+		    (const xmlChar *) "xmlZMemBuffExtend:  %s %lu bytes.\n",
+		    "Allocation failure extending output buffer to",
+		    new_size );
+	xmlIOErr(XML_IO_WRITE, (const char *) msg);
+    }
+
+    return ( rc );
+}
+
+/**
+ * xmlZMemBuffAppend
+ * @buff:  Buffer used to compress and consolidate data
+ * @src:   Uncompressed source content to append to buffer
+ * @len:   Length of source data to append to buffer
+ *
+ * Compress and append data to the internal buffer.  The data buffer
+ * will be expanded if needed to store the additional data.
+ *
+ * Returns the number of bytes appended to the buffer or -1 on error.
+ */
+static int
+xmlZMemBuffAppend( xmlZMemBuffPtr buff, const char * src, int len ) {
+
+    int		z_err;
+    size_t	min_accept;
+
+    if ( ( buff == NULL ) || ( src == NULL ) )
+	return ( -1 );
+
+    buff->zctrl.avail_in = len;
+    buff->zctrl.next_in  = (unsigned char *)src;
+    while ( buff->zctrl.avail_in > 0 ) {
+	/*
+	**  Extend the buffer prior to deflate call if a reasonable amount
+	**  of output buffer space is not available.
+	*/
+	min_accept = buff->zctrl.avail_in / DFLT_ZLIB_RATIO;
+	if ( buff->zctrl.avail_out <= min_accept ) {
+	    if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
+		return ( -1 );
+	}
+
+	z_err = deflate( &buff->zctrl, Z_NO_FLUSH );
+	if ( z_err != Z_OK ) {
+	    xmlChar msg[500];
+	    xmlStrPrintf(msg, 500,
+			(const xmlChar *) "xmlZMemBuffAppend:  %s %d %s - %d",
+			"Compression error while appending",
+			len, "bytes to buffer.  ZLIB error", z_err );
+	    xmlIOErr(XML_IO_WRITE, (const char *) msg);
+	    return ( -1 );
+	}
+    }
+
+    buff->crc = crc32( buff->crc, (unsigned char *)src, len );
+
+    return ( len );
+}
+
+/**
+ * xmlZMemBuffGetContent
+ * @buff:  Compressed memory content buffer
+ * @data_ref:  Pointer reference to point to compressed content
+ *
+ * Flushes the compression buffers, appends gzip file trailers and
+ * returns the compressed content and length of the compressed data.
+ * NOTE:  The gzip trailer code here is plagiarized from zlib source.
+ *
+ * Returns the length of the compressed data or -1 on error.
+ */
+static int
+xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) {
+
+    int		zlgth = -1;
+    int		z_err;
+
+    if ( ( buff == NULL ) || ( data_ref == NULL ) )
+	return ( -1 );
+
+    /*  Need to loop until compression output buffers are flushed  */
+
+    do
+    {
+	z_err = deflate( &buff->zctrl, Z_FINISH );
+	if ( z_err == Z_OK ) {
+	    /*  In this case Z_OK means more buffer space needed  */
+
+	    if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
+		return ( -1 );
+	}
+    }
+    while ( z_err == Z_OK );
+
+    /*  If the compression state is not Z_STREAM_END, some error occurred  */
+
+    if ( z_err == Z_STREAM_END ) {
+
+	/*  Need to append the gzip data trailer  */
+
+	if ( buff->zctrl.avail_out < ( 2 * sizeof( unsigned long ) ) ) {
+	    if ( xmlZMemBuffExtend(buff, (2 * sizeof(unsigned long))) == -1 )
+		return ( -1 );
+	}
+
+	/*
+	**  For whatever reason, the CRC and length data are pushed out
+	**  in reverse byte order.  So a memcpy can't be used here.
+	*/
+
+	append_reverse_ulong( buff, buff->crc );
+	append_reverse_ulong( buff, buff->zctrl.total_in );
+
+	zlgth = buff->zctrl.next_out - buff->zbuff;
+	*data_ref = (char *)buff->zbuff;
+    }
+
+    else {
+	xmlChar msg[500];
+	xmlStrPrintf(msg, 500,
+		    (const xmlChar *) "xmlZMemBuffGetContent:  %s - %d\n",
+		    "Error flushing zlib buffers.  Error code", z_err );
+	xmlIOErr(XML_IO_WRITE, (const char *) msg);
+    }
+
+    return ( zlgth );
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+#endif  /*  HAVE_ZLIB_H  */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlFreeHTTPWriteCtxt
+ * @ctxt:  Context to cleanup
+ *
+ * Free allocated memory and reclaim system resources.
+ *
+ * No return value.
+ */
+static void
+xmlFreeHTTPWriteCtxt( xmlIOHTTPWriteCtxtPtr ctxt )
+{
+    if ( ctxt->uri != NULL )
+	xmlFree( ctxt->uri );
+
+    if ( ctxt->doc_buff != NULL ) {
+
+#ifdef HAVE_ZLIB_H
+	if ( ctxt->compression > 0 ) {
+	    xmlFreeZMemBuff( ctxt->doc_buff );
+	}
+	else
+#endif
+	{
+	    xmlOutputBufferClose( ctxt->doc_buff );
+	}
+    }
+
+    xmlFree( ctxt );
+    return;
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+
+/**
+ * xmlIOHTTPMatch:
+ * @filename:  the URI for matching
+ *
+ * check if the URI matches an HTTP one
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+int
+xmlIOHTTPMatch (const char *filename) {
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "http://", 7))
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlIOHTTPOpen:
+ * @filename:  the URI for matching
+ *
+ * open an HTTP I/O channel
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+void *
+xmlIOHTTPOpen (const char *filename) {
+    return(xmlNanoHTTPOpen(filename, NULL));
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlIOHTTPOpenW:
+ * @post_uri:  The destination URI for the document
+ * @compression:  The compression desired for the document.
+ *
+ * Open a temporary buffer to collect the document for a subsequent HTTP POST
+ * request.  Non-static as is called from the output buffer creation routine.
+ *
+ * Returns an I/O context or NULL in case of error.
+ */
+
+void *
+xmlIOHTTPOpenW(const char *post_uri, int compression)
+{
+
+    xmlIOHTTPWriteCtxtPtr ctxt = NULL;
+
+    if (post_uri == NULL)
+        return (NULL);
+
+    ctxt = xmlMalloc(sizeof(xmlIOHTTPWriteCtxt));
+    if (ctxt == NULL) {
+	xmlIOErrMemory("creating HTTP output context");
+        return (NULL);
+    }
+
+    (void) memset(ctxt, 0, sizeof(xmlIOHTTPWriteCtxt));
+
+    ctxt->uri = (char *) xmlStrdup((const xmlChar *)post_uri);
+    if (ctxt->uri == NULL) {
+	xmlIOErrMemory("copying URI");
+        xmlFreeHTTPWriteCtxt(ctxt);
+        return (NULL);
+    }
+
+    /*
+     * **  Since the document length is required for an HTTP post,
+     * **  need to put the document into a buffer.  A memory buffer
+     * **  is being used to avoid pushing the data to disk and back.
+     */
+
+#ifdef HAVE_ZLIB_H
+    if ((compression > 0) && (compression <= 9)) {
+
+        ctxt->compression = compression;
+        ctxt->doc_buff = xmlCreateZMemBuff(compression);
+    } else
+#endif
+    {
+        /*  Any character conversions should have been done before this  */
+
+        ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL);
+    }
+
+    if (ctxt->doc_buff == NULL) {
+        xmlFreeHTTPWriteCtxt(ctxt);
+        ctxt = NULL;
+    }
+
+    return (ctxt);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlIOHTTPDfltOpenW
+ * @post_uri:  The destination URI for this document.
+ *
+ * Calls xmlIOHTTPOpenW with no compression to set up for a subsequent
+ * HTTP post command.  This function should generally not be used as
+ * the open callback is short circuited in xmlOutputBufferCreateFile.
+ *
+ * Returns a pointer to the new IO context.
+ */
+static void *
+xmlIOHTTPDfltOpenW( const char * post_uri ) {
+    return ( xmlIOHTTPOpenW( post_uri, 0 ) );
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlIOHTTPRead:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Read @len bytes to @buffer from the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+int
+xmlIOHTTPRead(void * context, char * buffer, int len) {
+    if ((buffer == NULL) || (len < 0)) return(-1);
+    return(xmlNanoHTTPRead(context, &buffer[0], len));
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlIOHTTPWrite
+ * @context:  previously opened writing context
+ * @buffer:   data to output to temporary buffer
+ * @len:      bytes to output
+ *
+ * Collect data from memory buffer into a temporary file for later
+ * processing.
+ *
+ * Returns number of bytes written.
+ */
+
+static int
+xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
+
+    xmlIOHTTPWriteCtxtPtr	ctxt = context;
+
+    if ( ( ctxt == NULL ) || ( ctxt->doc_buff == NULL ) || ( buffer == NULL ) )
+	return ( -1 );
+
+    if ( len > 0 ) {
+
+	/*  Use gzwrite or fwrite as previously setup in the open call  */
+
+#ifdef HAVE_ZLIB_H
+	if ( ctxt->compression > 0 )
+	    len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len );
+
+	else
+#endif
+	    len = xmlOutputBufferWrite( ctxt->doc_buff, len, buffer );
+
+	if ( len < 0 ) {
+	    xmlChar msg[500];
+	    xmlStrPrintf(msg, 500,
+			(const xmlChar *) "xmlIOHTTPWrite:  %s\n%s '%s'.\n",
+			"Error appending to internal buffer.",
+			"Error sending document to URI",
+			ctxt->uri );
+	    xmlIOErr(XML_IO_WRITE, (const char *) msg);
+	}
+    }
+
+    return ( len );
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+
+/**
+ * xmlIOHTTPClose:
+ * @context:  the I/O context
+ *
+ * Close an HTTP I/O channel
+ *
+ * Returns 0
+ */
+int
+xmlIOHTTPClose (void * context) {
+    xmlNanoHTTPClose(context);
+    return 0;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlIOHTTCloseWrite
+ * @context:  The I/O context
+ * @http_mthd: The HTTP method to be used when sending the data
+ *
+ * Close the transmit HTTP I/O channel and actually send the data.
+ */
+static int
+xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) {
+
+    int				close_rc = -1;
+    int				http_rtn = 0;
+    int				content_lgth = 0;
+    xmlIOHTTPWriteCtxtPtr	ctxt = context;
+
+    char *			http_content = NULL;
+    char *			content_encoding = NULL;
+    char *			content_type = (char *) "text/xml";
+    void *			http_ctxt = NULL;
+
+    if ( ( ctxt == NULL ) || ( http_mthd == NULL ) )
+	return ( -1 );
+
+    /*  Retrieve the content from the appropriate buffer  */
+
+#ifdef HAVE_ZLIB_H
+
+    if ( ctxt->compression > 0 ) {
+	content_lgth = xmlZMemBuffGetContent( ctxt->doc_buff, &http_content );
+	content_encoding = (char *) "Content-Encoding: gzip";
+    }
+    else
+#endif
+    {
+	/*  Pull the data out of the memory output buffer  */
+
+	xmlOutputBufferPtr	dctxt = ctxt->doc_buff;
+	http_content = (char *)dctxt->buffer->content;
+	content_lgth = dctxt->buffer->use;
+    }
+
+    if ( http_content == NULL ) {
+	xmlChar msg[500];
+	xmlStrPrintf(msg, 500,
+		     (const xmlChar *) "xmlIOHTTPCloseWrite:  %s '%s' %s '%s'.\n",
+		     "Error retrieving content.\nUnable to",
+		     http_mthd, "data to URI", ctxt->uri );
+	xmlIOErr(XML_IO_WRITE, (const char *) msg);
+    }
+
+    else {
+
+	http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
+					&content_type, content_encoding,
+					content_lgth );
+
+	if ( http_ctxt != NULL ) {
+#ifdef DEBUG_HTTP
+	    /*  If testing/debugging - dump reply with request content  */
+
+	    FILE *	tst_file = NULL;
+	    char	buffer[ 4096 ];
+	    char *	dump_name = NULL;
+	    int		avail;
+
+	    xmlGenericError( xmlGenericErrorContext,
+			"xmlNanoHTTPCloseWrite:  HTTP %s to\n%s returned %d.\n",
+			http_mthd, ctxt->uri,
+			xmlNanoHTTPReturnCode( http_ctxt ) );
+
+	    /*
+	    **  Since either content or reply may be gzipped,
+	    **  dump them to separate files instead of the
+	    **  standard error context.
+	    */
+
+	    dump_name = tempnam( NULL, "lxml" );
+	    if ( dump_name != NULL ) {
+		(void)snprintf( buffer, sizeof(buffer), "%s.content", dump_name );
+
+		tst_file = fopen( buffer, "wb" );
+		if ( tst_file != NULL ) {
+		    xmlGenericError( xmlGenericErrorContext,
+			"Transmitted content saved in file:  %s\n", buffer );
+
+		    fwrite( http_content, sizeof( char ),
+					content_lgth, tst_file );
+		    fclose( tst_file );
+		}
+
+		(void)snprintf( buffer, sizeof(buffer), "%s.reply", dump_name );
+		tst_file = fopen( buffer, "wb" );
+		if ( tst_file != NULL ) {
+		    xmlGenericError( xmlGenericErrorContext,
+			"Reply content saved in file:  %s\n", buffer );
+
+
+		    while ( (avail = xmlNanoHTTPRead( http_ctxt,
+					buffer, sizeof( buffer ) )) > 0 ) {
+
+			fwrite( buffer, sizeof( char ), avail, tst_file );
+		    }
+
+		    fclose( tst_file );
+		}
+
+		free( dump_name );
+	    }
+#endif  /*  DEBUG_HTTP  */
+
+	    http_rtn = xmlNanoHTTPReturnCode( http_ctxt );
+	    if ( ( http_rtn >= 200 ) && ( http_rtn < 300 ) )
+		close_rc = 0;
+	    else {
+                xmlChar msg[500];
+                xmlStrPrintf(msg, 500,
+    (const xmlChar *) "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
+			    http_mthd, content_lgth,
+			    "bytes to URI", ctxt->uri,
+			    "failed.  HTTP return code:", http_rtn );
+		xmlIOErr(XML_IO_WRITE, (const char *) msg);
+            }
+
+	    xmlNanoHTTPClose( http_ctxt );
+	    xmlFree( content_type );
+	}
+    }
+
+    /*  Final cleanups  */
+
+    xmlFreeHTTPWriteCtxt( ctxt );
+
+    return ( close_rc );
+}
+
+/**
+ * xmlIOHTTPClosePut
+ *
+ * @context:  The I/O context
+ *
+ * Close the transmit HTTP I/O channel and actually send data using a PUT
+ * HTTP method.
+ */
+static int
+xmlIOHTTPClosePut( void * ctxt ) {
+    return ( xmlIOHTTPCloseWrite( ctxt, "PUT" ) );
+}
+
+
+/**
+ * xmlIOHTTPClosePost
+ *
+ * @context:  The I/O context
+ *
+ * Close the transmit HTTP I/O channel and actually send data using a POST
+ * HTTP method.
+ */
+static int
+xmlIOHTTPClosePost( void * ctxt ) {
+    return ( xmlIOHTTPCloseWrite( ctxt, "POST" ) );
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#endif /* LIBXML_HTTP_ENABLED */
+
+#ifdef LIBXML_FTP_ENABLED
+/************************************************************************
+ *									*
+ *			I/O for FTP file accesses			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlIOFTPMatch:
+ * @filename:  the URI for matching
+ *
+ * check if the URI matches an FTP one
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+int
+xmlIOFTPMatch (const char *filename) {
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "ftp://", 6))
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlIOFTPOpen:
+ * @filename:  the URI for matching
+ *
+ * open an FTP I/O channel
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+void *
+xmlIOFTPOpen (const char *filename) {
+    return(xmlNanoFTPOpen(filename));
+}
+
+/**
+ * xmlIOFTPRead:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Read @len bytes to @buffer from the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+int
+xmlIOFTPRead(void * context, char * buffer, int len) {
+    if ((buffer == NULL) || (len < 0)) return(-1);
+    return(xmlNanoFTPRead(context, &buffer[0], len));
+}
+
+/**
+ * xmlIOFTPClose:
+ * @context:  the I/O context
+ *
+ * Close an FTP I/O channel
+ *
+ * Returns 0
+ */
+int
+xmlIOFTPClose (void * context) {
+    return ( xmlNanoFTPClose(context) );
+}
+#endif /* LIBXML_FTP_ENABLED */
+
+
+/**
+ * xmlRegisterInputCallbacks:
+ * @matchFunc:  the xmlInputMatchCallback
+ * @openFunc:  the xmlInputOpenCallback
+ * @readFunc:  the xmlInputReadCallback
+ * @closeFunc:  the xmlInputCloseCallback
+ *
+ * Register a new set of I/O callback for handling parser input.
+ *
+ * Returns the registered handler number or -1 in case of error
+ */
+int
+xmlRegisterInputCallbacks(xmlInputMatchCallback matchFunc,
+	xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc,
+	xmlInputCloseCallback closeFunc) {
+    if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
+	return(-1);
+    }
+    xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = matchFunc;
+    xmlInputCallbackTable[xmlInputCallbackNr].opencallback = openFunc;
+    xmlInputCallbackTable[xmlInputCallbackNr].readcallback = readFunc;
+    xmlInputCallbackTable[xmlInputCallbackNr].closecallback = closeFunc;
+    xmlInputCallbackInitialized = 1;
+    return(xmlInputCallbackNr++);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlRegisterOutputCallbacks:
+ * @matchFunc:  the xmlOutputMatchCallback
+ * @openFunc:  the xmlOutputOpenCallback
+ * @writeFunc:  the xmlOutputWriteCallback
+ * @closeFunc:  the xmlOutputCloseCallback
+ *
+ * Register a new set of I/O callback for handling output.
+ *
+ * Returns the registered handler number or -1 in case of error
+ */
+int
+xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
+	xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
+	xmlOutputCloseCallback closeFunc) {
+    if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) {
+	return(-1);
+    }
+    xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = openFunc;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = writeFunc;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = closeFunc;
+    xmlOutputCallbackInitialized = 1;
+    return(xmlOutputCallbackNr++);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlRegisterDefaultInputCallbacks:
+ *
+ * Registers the default compiled-in I/O handlers.
+ */
+void
+xmlRegisterDefaultInputCallbacks(void) {
+    if (xmlInputCallbackInitialized)
+	return;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    xmlInitPlatformSpecificIo();
+#endif
+
+    xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
+	                      xmlFileRead, xmlFileClose);
+#ifdef HAVE_ZLIB_H
+    xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
+	                      xmlGzfileRead, xmlGzfileClose);
+#endif /* HAVE_ZLIB_H */
+
+#ifdef LIBXML_HTTP_ENABLED
+    xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
+	                      xmlIOHTTPRead, xmlIOHTTPClose);
+#endif /* LIBXML_HTTP_ENABLED */
+
+#ifdef LIBXML_FTP_ENABLED
+    xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
+	                      xmlIOFTPRead, xmlIOFTPClose);
+#endif /* LIBXML_FTP_ENABLED */
+    xmlInputCallbackInitialized = 1;
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlRegisterDefaultOutputCallbacks:
+ *
+ * Registers the default compiled-in I/O handlers.
+ */
+void
+xmlRegisterDefaultOutputCallbacks (void) {
+    if (xmlOutputCallbackInitialized)
+	return;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    xmlInitPlatformSpecificIo();
+#endif
+
+    xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
+	                      xmlFileWrite, xmlFileClose);
+
+#ifdef LIBXML_HTTP_ENABLED
+    xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
+	                       xmlIOHTTPWrite, xmlIOHTTPClosePut);
+#endif
+
+/*********************************
+ No way a-priori to distinguish between gzipped files from
+ uncompressed ones except opening if existing then closing
+ and saving with same compression ratio ... a pain.
+
+#ifdef HAVE_ZLIB_H
+    xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
+	                       xmlGzfileWrite, xmlGzfileClose);
+#endif
+
+ Nor FTP PUT ....
+#ifdef LIBXML_FTP_ENABLED
+    xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
+	                       xmlIOFTPWrite, xmlIOFTPClose);
+#endif
+ **********************************/
+    xmlOutputCallbackInitialized = 1;
+}
+
+#ifdef LIBXML_HTTP_ENABLED
+/**
+ * xmlRegisterHTTPPostCallbacks:
+ *
+ * By default, libxml submits HTTP output requests using the "PUT" method.
+ * Calling this method changes the HTTP output method to use the "POST"
+ * method instead.
+ *
+ */
+void
+xmlRegisterHTTPPostCallbacks( void ) {
+
+    /*  Register defaults if not done previously  */
+
+    if ( xmlOutputCallbackInitialized == 0 )
+	xmlRegisterDefaultOutputCallbacks( );
+
+    xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
+	                       xmlIOHTTPWrite, xmlIOHTTPClosePost);
+    return;
+}
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlAllocParserInputBuffer:
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for progressive parsing
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlAllocParserInputBuffer(xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+
+    ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
+    if (ret == NULL) {
+	xmlIOErrMemory("creating input buffer");
+	return(NULL);
+    }
+    memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
+    ret->buffer = xmlBufferCreateSize(2 * xmlDefaultBufferSize);
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+	return(NULL);
+    }
+    ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
+    ret->encoder = xmlGetCharEncodingHandler(enc);
+    if (ret->encoder != NULL)
+        ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize);
+    else
+        ret->raw = NULL;
+    ret->readcallback = NULL;
+    ret->closecallback = NULL;
+    ret->context = NULL;
+    ret->compressed = -1;
+    ret->rawconsumed = 0;
+
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlAllocOutputBuffer:
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered parser output
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
+    if (ret == NULL) {
+	xmlIOErrMemory("creating output buffer");
+	return(NULL);
+    }
+    memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
+    ret->buffer = xmlBufferCreate();
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+	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);
+	if (ret->conv == NULL) {
+	    xmlFree(ret);
+	    return(NULL);
+	}
+
+	/*
+	 * This call is designed to initiate the encoder state
+	 */
+	xmlCharEncOutFunc(encoder, ret->conv, NULL);
+    } else
+        ret->conv = NULL;
+    ret->writecallback = NULL;
+    ret->closecallback = NULL;
+    ret->context = NULL;
+    ret->written = 0;
+
+    return(ret);
+}
+
+/**
+ * xmlAllocOutputBufferInternal:
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered parser output
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
+    if (ret == NULL) {
+	xmlIOErrMemory("creating output buffer");
+	return(NULL);
+    }
+    memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
+    ret->buffer = xmlBufferCreate();
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+	return(NULL);
+    }
+
+
+    /*
+     * For conversion buffers we use the special IO handling
+     * We don't do that from the exported API to avoid confusing
+     * user's code.
+     */
+    ret->buffer->alloc = XML_BUFFER_ALLOC_IO;
+    ret->buffer->contentIO = ret->buffer->content;
+
+    ret->encoder = encoder;
+    if (encoder != NULL) {
+        ret->conv = xmlBufferCreateSize(4000);
+	if (ret->conv == NULL) {
+	    xmlFree(ret);
+	    return(NULL);
+	}
+
+	/*
+	 * This call is designed to initiate the encoder state
+	 */
+	xmlCharEncOutFunc(encoder, ret->conv, NULL);
+    } else
+        ret->conv = NULL;
+    ret->writecallback = NULL;
+    ret->closecallback = NULL;
+    ret->context = NULL;
+    ret->written = 0;
+
+    return(ret);
+}
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlFreeParserInputBuffer:
+ * @in:  a buffered parser input
+ *
+ * Free up the memory used by a buffered parser input
+ */
+void
+xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
+    if (in == NULL) return;
+
+    if (in->raw) {
+        xmlBufferFree(in->raw);
+	in->raw = NULL;
+    }
+    if (in->encoder != NULL) {
+        xmlCharEncCloseFunc(in->encoder);
+    }
+    if (in->closecallback != NULL) {
+	in->closecallback(in->context);
+    }
+    if (in->buffer != NULL) {
+        xmlBufferFree(in->buffer);
+	in->buffer = NULL;
+    }
+
+    xmlFree(in);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlOutputBufferClose:
+ * @out:  a buffered output
+ *
+ * flushes and close the output I/O channel
+ * and free up all the associated resources
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlOutputBufferClose(xmlOutputBufferPtr out)
+{
+    int written;
+    int err_rc = 0;
+
+    if (out == NULL)
+        return (-1);
+    if (out->writecallback != NULL)
+        xmlOutputBufferFlush(out);
+    if (out->closecallback != NULL) {
+        err_rc = out->closecallback(out->context);
+    }
+    written = out->written;
+    if (out->conv) {
+        xmlBufferFree(out->conv);
+        out->conv = NULL;
+    }
+    if (out->encoder != NULL) {
+        xmlCharEncCloseFunc(out->encoder);
+    }
+    if (out->buffer != NULL) {
+        xmlBufferFree(out->buffer);
+        out->buffer = NULL;
+    }
+
+    if (out->error)
+        err_rc = -1;
+    xmlFree(out);
+    return ((err_rc == 0) ? written : err_rc);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+xmlParserInputBufferPtr
+__xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+    int i = 0;
+    void *context = NULL;
+
+    if (xmlInputCallbackInitialized == 0)
+	xmlRegisterDefaultInputCallbacks();
+
+    if (URI == NULL) return(NULL);
+
+    /*
+     * Try to find one of the input accept method accepting that scheme
+     * Go in reverse to give precedence to user defined handlers.
+     */
+    if (context == NULL) {
+	for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
+	    if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
+		(xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
+		context = xmlInputCallbackTable[i].opencallback(URI);
+		if (context != NULL) {
+		    break;
+		}
+	    }
+	}
+    }
+    if (context == NULL) {
+	return(NULL);
+    }
+
+    /*
+     * Allocate the Input buffer front-end.
+     */
+    ret = xmlAllocParserInputBuffer(enc);
+    if (ret != NULL) {
+	ret->context = context;
+	ret->readcallback = xmlInputCallbackTable[i].readcallback;
+	ret->closecallback = xmlInputCallbackTable[i].closecallback;
+#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;
+		if (gzread(context, buff4, 4) == 4) {
+		    if (strncmp(buff4, cptr, 4) == 0)
+		        ret->compressed = 0;
+		    else
+		        ret->compressed = 1;
+		    gzrewind(context);
+		}
+	    }
+#endif
+	}
+#endif
+    }
+    else
+      xmlInputCallbackTable[i].closecallback (context);
+
+    return(ret);
+}
+
+/**
+ * xmlParserInputBufferCreateFilename:
+ * @URI:  a C string containing the URI or filename
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing of a file
+ * If filename is "-' then we use stdin as the input.
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
+    if ((xmlParserInputBufferCreateFilenameValue)) {
+		return xmlParserInputBufferCreateFilenameValue(URI, enc);
+	}
+	return __xmlParserInputBufferCreateFilename(URI, enc);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+xmlOutputBufferPtr
+__xmlOutputBufferCreateFilename(const char *URI,
+                              xmlCharEncodingHandlerPtr encoder,
+                              int compression ATTRIBUTE_UNUSED) {
+    xmlOutputBufferPtr ret;
+    xmlURIPtr puri;
+    int i = 0;
+    void *context = NULL;
+    char *unescaped = NULL;
+#ifdef HAVE_ZLIB_H
+    int is_file_uri = 1;
+#endif
+
+    if (xmlOutputCallbackInitialized == 0)
+	xmlRegisterDefaultOutputCallbacks();
+
+    if (URI == NULL) return(NULL);
+
+    puri = xmlParseURI(URI);
+    if (puri != NULL) {
+#ifdef HAVE_ZLIB_H
+        if ((puri->scheme != NULL) &&
+	    (!xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file")))
+	    is_file_uri = 0;
+#endif
+	/*
+	 * try to limit the damages of the URI unescaping code.
+	 */
+	if ((puri->scheme == NULL) ||
+	    (xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file")))
+	    unescaped = xmlURIUnescapeString(URI, 0, NULL);
+	xmlFreeURI(puri);
+    }
+
+    /*
+     * Try to find one of the output accept method accepting that scheme
+     * Go in reverse to give precedence to user defined handlers.
+     * try with an unescaped version of the URI
+     */
+    if (unescaped != NULL) {
+#ifdef HAVE_ZLIB_H
+	if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
+	    context = xmlGzfileOpenW(unescaped, compression);
+	    if (context != NULL) {
+		ret = xmlAllocOutputBufferInternal(encoder);
+		if (ret != NULL) {
+		    ret->context = context;
+		    ret->writecallback = xmlGzfileWrite;
+		    ret->closecallback = xmlGzfileClose;
+		}
+		xmlFree(unescaped);
+		return(ret);
+	    }
+	}
+#endif
+	for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
+	    if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
+		(xmlOutputCallbackTable[i].matchcallback(unescaped) != 0)) {
+#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H)
+		/*  Need to pass compression parameter into HTTP open calls  */
+		if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
+		    context = xmlIOHTTPOpenW(unescaped, compression);
+		else
+#endif
+		    context = xmlOutputCallbackTable[i].opencallback(unescaped);
+		if (context != NULL)
+		    break;
+	    }
+	}
+	xmlFree(unescaped);
+    }
+
+    /*
+     * If this failed try with a non-escaped URI this may be a strange
+     * filename
+     */
+    if (context == NULL) {
+#ifdef HAVE_ZLIB_H
+	if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
+	    context = xmlGzfileOpenW(URI, compression);
+	    if (context != NULL) {
+		ret = xmlAllocOutputBufferInternal(encoder);
+		if (ret != NULL) {
+		    ret->context = context;
+		    ret->writecallback = xmlGzfileWrite;
+		    ret->closecallback = xmlGzfileClose;
+		}
+		return(ret);
+	    }
+	}
+#endif
+	for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
+	    if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
+		(xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
+#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H)
+		/*  Need to pass compression parameter into HTTP open calls  */
+		if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
+		    context = xmlIOHTTPOpenW(URI, compression);
+		else
+#endif
+		    context = xmlOutputCallbackTable[i].opencallback(URI);
+		if (context != NULL)
+		    break;
+	    }
+	}
+    }
+
+    if (context == NULL) {
+	return(NULL);
+    }
+
+    /*
+     * Allocate the Output buffer front-end.
+     */
+    ret = xmlAllocOutputBufferInternal(encoder);
+    if (ret != NULL) {
+	ret->context = context;
+	ret->writecallback = xmlOutputCallbackTable[i].writecallback;
+	ret->closecallback = xmlOutputCallbackTable[i].closecallback;
+    }
+    return(ret);
+}
+
+/**
+ * xmlOutputBufferCreateFilename:
+ * @URI:  a C string containing the URI or filename
+ * @encoder:  the encoding converter or NULL
+ * @compression:  the compression ration (0 none, 9 max).
+ *
+ * Create a buffered  output for the progressive saving of a file
+ * If filename is "-' then we use stdout as the output.
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ * TODO: currently if compression is set, the library only support
+ *       writing to a local file.
+ *
+ * Returns the new output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFilename(const char *URI,
+                              xmlCharEncodingHandlerPtr encoder,
+                              int compression ATTRIBUTE_UNUSED) {
+    if ((xmlOutputBufferCreateFilenameValue)) {
+		return xmlOutputBufferCreateFilenameValue(URI, encoder, compression);
+	}
+	return __xmlOutputBufferCreateFilename(URI, encoder, compression);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlParserInputBufferCreateFile:
+ * @file:  a FILE*
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing of a FILE *
+ * buffered C I/O
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+
+    if (xmlInputCallbackInitialized == 0)
+	xmlRegisterDefaultInputCallbacks();
+
+    if (file == NULL) return(NULL);
+
+    ret = xmlAllocParserInputBuffer(enc);
+    if (ret != NULL) {
+        ret->context = file;
+	ret->readcallback = xmlFileRead;
+	ret->closecallback = xmlFileFlush;
+    }
+
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlOutputBufferCreateFile:
+ * @file:  a FILE*
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving to a FILE *
+ * buffered C I/O
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (xmlOutputCallbackInitialized == 0)
+	xmlRegisterDefaultOutputCallbacks();
+
+    if (file == NULL) return(NULL);
+
+    ret = xmlAllocOutputBufferInternal(encoder);
+    if (ret != NULL) {
+        ret->context = file;
+	ret->writecallback = xmlFileWrite;
+	ret->closecallback = xmlFileFlush;
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlOutputBufferCreateBuffer:
+ * @buffer:  a xmlBufferPtr
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving to a xmlBuffer
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateBuffer(xmlBufferPtr buffer,
+                            xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (buffer == NULL) return(NULL);
+
+    ret = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
+                                  xmlBufferWrite,
+                                  (xmlOutputCloseCallback)
+                                  NULL, (void *) buffer, encoder);
+
+    return(ret);
+}
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlParserInputBufferCreateFd:
+ * @fd:  a file descriptor number
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing for the input
+ * from a file descriptor
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+
+    if (fd < 0) return(NULL);
+
+    ret = xmlAllocParserInputBuffer(enc);
+    if (ret != NULL) {
+        ret->context = (void *) (long) fd;
+	ret->readcallback = xmlFdRead;
+	ret->closecallback = xmlFdClose;
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlParserInputBufferCreateMem:
+ * @mem:  the memory input
+ * @size:  the length of the memory block
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing for the input
+ * from a memory area.
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+    int errcode;
+
+    if (size <= 0) return(NULL);
+    if (mem == NULL) return(NULL);
+
+    ret = xmlAllocParserInputBuffer(enc);
+    if (ret != NULL) {
+        ret->context = (void *) mem;
+	ret->readcallback = (xmlInputReadCallback) xmlNop;
+	ret->closecallback = NULL;
+	errcode = xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
+	if (errcode != 0) {
+	    xmlFree(ret);
+	    return(NULL);
+	}
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlParserInputBufferCreateStatic:
+ * @mem:  the memory input
+ * @size:  the length of the memory block
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing for the input
+ * from an immutable memory area. This will not copy the memory area to
+ * the buffer, but the memory is expected to be available until the end of
+ * the parsing, this is useful for example when using mmap'ed file.
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateStatic(const char *mem, int size,
+                                 xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+
+    if (size <= 0) return(NULL);
+    if (mem == NULL) return(NULL);
+
+    ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
+    if (ret == NULL) {
+	xmlIOErrMemory("creating input buffer");
+	return(NULL);
+    }
+    memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
+    ret->buffer = xmlBufferCreateStatic((void *)mem, (size_t) size);
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+	return(NULL);
+    }
+    ret->encoder = xmlGetCharEncodingHandler(enc);
+    if (ret->encoder != NULL)
+        ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize);
+    else
+        ret->raw = NULL;
+    ret->compressed = -1;
+    ret->context = (void *) mem;
+    ret->readcallback = NULL;
+    ret->closecallback = NULL;
+
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlOutputBufferCreateFd:
+ * @fd:  a file descriptor number
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving
+ * to a file descriptor
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (fd < 0) return(NULL);
+
+    ret = xmlAllocOutputBufferInternal(encoder);
+    if (ret != NULL) {
+        ret->context = (void *) (long) fd;
+	ret->writecallback = xmlFdWrite;
+	ret->closecallback = NULL;
+    }
+
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlParserInputBufferCreateIO:
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered parser input for the progressive parsing for the input
+ * from an I/O handler
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateIO(xmlInputReadCallback   ioread,
+	 xmlInputCloseCallback  ioclose, void *ioctx, xmlCharEncoding enc) {
+    xmlParserInputBufferPtr ret;
+
+    if (ioread == NULL) return(NULL);
+
+    ret = xmlAllocParserInputBuffer(enc);
+    if (ret != NULL) {
+        ret->context = (void *) ioctx;
+	ret->readcallback = ioread;
+	ret->closecallback = ioclose;
+    }
+
+    return(ret);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlOutputBufferCreateIO:
+ * @iowrite:  an I/O write function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @encoder:  the charset encoding if known
+ *
+ * Create a buffered output for the progressive saving
+ * to an I/O handler
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateIO(xmlOutputWriteCallback   iowrite,
+	 xmlOutputCloseCallback  ioclose, void *ioctx,
+	 xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (iowrite == NULL) return(NULL);
+
+    ret = xmlAllocOutputBufferInternal(encoder);
+    if (ret != NULL) {
+        ret->context = (void *) ioctx;
+	ret->writecallback = iowrite;
+	ret->closecallback = ioclose;
+    }
+
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlParserInputBufferCreateFilenameDefault:
+ * @func: function pointer to the new ParserInputBufferCreateFilenameFunc
+ *
+ * Registers a callback for URI input file handling
+ *
+ * Returns the old value of the registration function
+ */
+xmlParserInputBufferCreateFilenameFunc
+xmlParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func)
+{
+    xmlParserInputBufferCreateFilenameFunc old = xmlParserInputBufferCreateFilenameValue;
+    if (old == NULL) {
+		old = __xmlParserInputBufferCreateFilename;
+	}
+
+    xmlParserInputBufferCreateFilenameValue = func;
+    return(old);
+}
+
+/**
+ * xmlOutputBufferCreateFilenameDefault:
+ * @func: function pointer to the new OutputBufferCreateFilenameFunc
+ *
+ * Registers a callback for URI output file handling
+ *
+ * Returns the old value of the registration function
+ */
+xmlOutputBufferCreateFilenameFunc
+xmlOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func)
+{
+    xmlOutputBufferCreateFilenameFunc old = xmlOutputBufferCreateFilenameValue;
+#ifdef LIBXML_OUTPUT_ENABLED
+    if (old == NULL) {
+		old = __xmlOutputBufferCreateFilename;
+	}
+#endif
+    xmlOutputBufferCreateFilenameValue = func;
+    return(old);
+}
+
+/**
+ * xmlParserInputBufferPush:
+ * @in:  a buffered parser input
+ * @len:  the size in bytes of the array.
+ * @buf:  an char array
+ *
+ * Push the content of the arry in the input buffer
+ * This routine handle the I18N transcoding to internal UTF-8
+ * This is used when operating the parser in progressive (push) mode.
+ *
+ * Returns the number of chars read and stored in the buffer, or -1
+ *         in case of error.
+ */
+int
+xmlParserInputBufferPush(xmlParserInputBufferPtr in,
+	                 int len, const char *buf) {
+    int nbchars = 0;
+    int ret;
+
+    if (len < 0) return(0);
+    if ((in == NULL) || (in->error)) return(-1);
+    if (in->encoder != NULL) {
+        unsigned int use;
+
+        /*
+	 * Store the data in the incoming raw buffer
+	 */
+        if (in->raw == NULL) {
+	    in->raw = xmlBufferCreate();
+	}
+	ret = xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
+	if (ret != 0)
+	    return(-1);
+
+	/*
+	 * convert as much as possible to the parser reading buffer.
+	 */
+	use = in->raw->use;
+	nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
+	if (nbchars < 0) {
+	    xmlIOErr(XML_IO_ENCODER, NULL);
+	    in->error = XML_IO_ENCODER;
+	    return(-1);
+	}
+	in->rawconsumed += (use - in->raw->use);
+    } else {
+	nbchars = len;
+        ret = xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
+	if (ret != 0)
+	    return(-1);
+    }
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext,
+	    "I/O: pushed %d chars, buffer %d/%d\n",
+            nbchars, in->buffer->use, in->buffer->size);
+#endif
+    return(nbchars);
+}
+
+/**
+ * endOfInput:
+ *
+ * When reading from an Input channel indicated end of file or error
+ * don't reread from it again.
+ */
+static int
+endOfInput (void * context ATTRIBUTE_UNUSED,
+	    char * buffer ATTRIBUTE_UNUSED,
+	    int len ATTRIBUTE_UNUSED) {
+    return(0);
+}
+
+/**
+ * xmlParserInputBufferGrow:
+ * @in:  a buffered parser input
+ * @len:  indicative value of the amount of chars to read
+ *
+ * Grow up the content of the input buffer, the old data are preserved
+ * This routine handle the I18N transcoding to internal UTF-8
+ * This routine is used when operating the parser in normal (pull) mode
+ *
+ * TODO: one should be able to remove one extra copy by copying directly
+ *       onto in->buffer or in->raw
+ *
+ * Returns the number of chars read and stored in the buffer, or -1
+ *         in case of error.
+ */
+int
+xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
+    char *buffer = NULL;
+    int res = 0;
+    int nbchars = 0;
+    int buffree;
+    unsigned int needSize;
+
+    if ((in == NULL) || (in->error)) return(-1);
+    if ((len <= MINLEN) && (len != 4))
+        len = MINLEN;
+
+    buffree = in->buffer->size - in->buffer->use;
+    if (buffree <= 0) {
+	xmlIOErr(XML_IO_BUFFER_FULL, NULL);
+	in->error = XML_IO_BUFFER_FULL;
+	return(-1);
+    }
+
+    needSize = in->buffer->use + len + 1;
+    if (needSize > in->buffer->size){
+        if (!xmlBufferResize(in->buffer, needSize)){
+	    xmlIOErrMemory("growing input buffer");
+	    in->error = XML_ERR_NO_MEMORY;
+            return(-1);
+        }
+    }
+    buffer = (char *)&in->buffer->content[in->buffer->use];
+
+    /*
+     * Call the read method for this I/O type.
+     */
+    if (in->readcallback != NULL) {
+	res = in->readcallback(in->context, &buffer[0], len);
+	if (res <= 0)
+	    in->readcallback = endOfInput;
+    } else {
+	xmlIOErr(XML_IO_NO_INPUT, NULL);
+	in->error = XML_IO_NO_INPUT;
+	return(-1);
+    }
+    if (res < 0) {
+	return(-1);
+    }
+    len = res;
+    if (in->encoder != NULL) {
+        unsigned int use;
+
+        /*
+	 * Store the data in the incoming raw buffer
+	 */
+        if (in->raw == NULL) {
+	    in->raw = xmlBufferCreate();
+	}
+	res = xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
+	if (res != 0)
+	    return(-1);
+
+	/*
+	 * convert as much as possible to the parser reading buffer.
+	 */
+	use = in->raw->use;
+	nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
+	if (nbchars < 0) {
+	    xmlIOErr(XML_IO_ENCODER, NULL);
+	    in->error = XML_IO_ENCODER;
+	    return(-1);
+	}
+	in->rawconsumed += (use - in->raw->use);
+    } else {
+	nbchars = len;
+   	in->buffer->use += nbchars;
+	buffer[nbchars] = 0;
+    }
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext,
+	    "I/O: read %d chars, buffer %d/%d\n",
+            nbchars, in->buffer->use, in->buffer->size);
+#endif
+    return(nbchars);
+}
+
+/**
+ * xmlParserInputBufferRead:
+ * @in:  a buffered parser input
+ * @len:  indicative value of the amount of chars to read
+ *
+ * Refresh the content of the input buffer, the old data are considered
+ * consumed
+ * This routine handle the I18N transcoding to internal UTF-8
+ *
+ * Returns the number of chars read and stored in the buffer, or -1
+ *         in case of error.
+ */
+int
+xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
+    if ((in == NULL) || (in->error)) return(-1);
+    if (in->readcallback != NULL)
+	return(xmlParserInputBufferGrow(in, len));
+    else if ((in->buffer != NULL) &&
+             (in->buffer->alloc == XML_BUFFER_ALLOC_IMMUTABLE))
+	return(0);
+    else
+        return(-1);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * xmlOutputBufferWrite:
+ * @out:  a buffered parser output
+ * @len:  the size in bytes of the array.
+ * @buf:  an char array
+ *
+ * Write the content of the array in the output I/O buffer
+ * This routine handle the I18N transcoding from internal UTF-8
+ * The buffer is lossless, i.e. will store in case of partial
+ * or delayed writes.
+ *
+ * Returns the number of chars immediately written, or -1
+ *         in case of error.
+ */
+int
+xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
+    int nbchars = 0; /* number of chars to output to I/O */
+    int ret;         /* return from function call */
+    int written = 0; /* number of char written to I/O so far */
+    int chunk;       /* number of byte curreent processed from buf */
+
+    if ((out == NULL) || (out->error)) return(-1);
+    if (len < 0) return(0);
+    if (out->error) return(-1);
+
+    do {
+	chunk = len;
+	if (chunk > 4 * MINLEN)
+	    chunk = 4 * MINLEN;
+
+	/*
+	 * first handle encoding stuff.
+	 */
+	if (out->encoder != NULL) {
+	    /*
+	     * Store the data in the incoming raw buffer
+	     */
+	    if (out->conv == NULL) {
+		out->conv = xmlBufferCreate();
+	    }
+	    ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+	    if (ret != 0)
+	        return(-1);
+
+	    if ((out->buffer->use < MINLEN) && (chunk == len))
+		goto done;
+
+	    /*
+	     * convert as much as possible to the parser reading buffer.
+	     */
+	    ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
+	    if ((ret < 0) && (ret != -3)) {
+		xmlIOErr(XML_IO_ENCODER, NULL);
+		out->error = XML_IO_ENCODER;
+		return(-1);
+	    }
+	    nbchars = out->conv->use;
+	} else {
+	    ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
+	    if (ret != 0)
+	        return(-1);
+	    nbchars = out->buffer->use;
+	}
+	buf += chunk;
+	len -= chunk;
+
+	if ((nbchars < MINLEN) && (len <= 0))
+	    goto done;
+
+	if (out->writecallback) {
+	    /*
+	     * second write the stuff to the I/O channel
+	     */
+	    if (out->encoder != NULL) {
+		ret = out->writecallback(out->context,
+				 (const char *)out->conv->content, nbchars);
+		if (ret >= 0)
+		    xmlBufferShrink(out->conv, ret);
+	    } else {
+		ret = out->writecallback(out->context,
+				 (const char *)out->buffer->content, nbchars);
+		if (ret >= 0)
+		    xmlBufferShrink(out->buffer, ret);
+	    }
+	    if (ret < 0) {
+		xmlIOErr(XML_IO_WRITE, NULL);
+		out->error = XML_IO_WRITE;
+		return(ret);
+	    }
+	    out->written += ret;
+	}
+	written += nbchars;
+    } while (len > 0);
+
+done:
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext,
+	    "I/O: wrote %d chars\n", written);
+#endif
+    return(written);
+}
+
+/**
+ * xmlEscapeContent:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of unescaped UTF-8 bytes
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and escape them.
+ * Returns 0 if success, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+static int
+xmlEscapeContent(unsigned char* out, int *outlen,
+                 const xmlChar* in, int *inlen) {
+    unsigned char* outstart = out;
+    const unsigned char* base = in;
+    unsigned char* outend = out + *outlen;
+    const unsigned char* inend;
+
+    inend = in + (*inlen);
+
+    while ((in < inend) && (out < outend)) {
+   	if (*in == '<') {
+	    if (outend - out < 4) break;
+	    *out++ = '&';
+	    *out++ = 'l';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*in == '>') {
+	    if (outend - out < 4) break;
+	    *out++ = '&';
+	    *out++ = 'g';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*in == '&') {
+	    if (outend - out < 5) break;
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'm';
+	    *out++ = 'p';
+	    *out++ = ';';
+	} else if (*in == '\r') {
+	    if (outend - out < 5) break;
+	    *out++ = '&';
+	    *out++ = '#';
+	    *out++ = '1';
+	    *out++ = '3';
+	    *out++ = ';';
+	} else {
+	    *out++ = (unsigned char) *in;
+	}
+	++in;
+    }
+    *outlen = out - outstart;
+    *inlen = in - base;
+    return(0);
+}
+
+/**
+ * xmlOutputBufferWriteEscape:
+ * @out:  a buffered parser output
+ * @str:  a zero terminated UTF-8 string
+ * @escaping:  an optional escaping function (or NULL)
+ *
+ * Write the content of the string in the output I/O buffer
+ * This routine escapes the caracters and then handle the I18N
+ * transcoding from internal UTF-8
+ * The buffer is lossless, i.e. will store in case of partial
+ * or delayed writes.
+ *
+ * Returns the number of chars immediately written, or -1
+ *         in case of error.
+ */
+int
+xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
+                           xmlCharEncodingOutputFunc escaping) {
+    int nbchars = 0; /* number of chars to output to I/O */
+    int ret;         /* return from function call */
+    int written = 0; /* number of char written to I/O so far */
+    int oldwritten=0;/* loop guard */
+    int chunk;       /* number of byte currently processed from str */
+    int len;         /* number of bytes in str */
+    int cons;        /* byte from str consumed */
+
+    if ((out == NULL) || (out->error) || (str == NULL) ||
+        (out->buffer == NULL) ||
+	(out->buffer->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) return(-1);
+    len = strlen((const char *)str);
+    if (len < 0) return(0);
+    if (out->error) return(-1);
+    if (escaping == NULL) escaping = xmlEscapeContent;
+
+    do {
+        oldwritten = written;
+
+        /*
+	 * how many bytes to consume and how many bytes to store.
+	 */
+	cons = len;
+	chunk = (out->buffer->size - out->buffer->use) - 1;
+
+        /*
+	 * make sure we have enough room to save first, if this is
+	 * not the case force a flush, but make sure we stay in the loop
+	 */
+	if (chunk < 40) {
+	    if (xmlBufferGrow(out->buffer, out->buffer->size + 100) < 0)
+	        return(-1);
+            oldwritten = -1;
+	    continue;
+	}
+
+	/*
+	 * first handle encoding stuff.
+	 */
+	if (out->encoder != NULL) {
+	    /*
+	     * Store the data in the incoming raw buffer
+	     */
+	    if (out->conv == NULL) {
+		out->conv = xmlBufferCreate();
+	    }
+	    ret = escaping(out->buffer->content + out->buffer->use ,
+	                   &chunk, str, &cons);
+	    if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
+	        return(-1);
+	    out->buffer->use += chunk;
+	    out->buffer->content[out->buffer->use] = 0;
+
+	    if ((out->buffer->use < MINLEN) && (cons == len))
+		goto done;
+
+	    /*
+	     * convert as much as possible to the output buffer.
+	     */
+	    ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
+	    if ((ret < 0) && (ret != -3)) {
+		xmlIOErr(XML_IO_ENCODER, NULL);
+		out->error = XML_IO_ENCODER;
+		return(-1);
+	    }
+	    nbchars = out->conv->use;
+	} else {
+	    ret = escaping(out->buffer->content + out->buffer->use ,
+	                   &chunk, str, &cons);
+	    if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
+	        return(-1);
+	    out->buffer->use += chunk;
+	    out->buffer->content[out->buffer->use] = 0;
+	    nbchars = out->buffer->use;
+	}
+	str += cons;
+	len -= cons;
+
+	if ((nbchars < MINLEN) && (len <= 0))
+	    goto done;
+
+	if (out->writecallback) {
+	    /*
+	     * second write the stuff to the I/O channel
+	     */
+	    if (out->encoder != NULL) {
+		ret = out->writecallback(out->context,
+				 (const char *)out->conv->content, nbchars);
+		if (ret >= 0)
+		    xmlBufferShrink(out->conv, ret);
+	    } else {
+		ret = out->writecallback(out->context,
+				 (const char *)out->buffer->content, nbchars);
+		if (ret >= 0)
+		    xmlBufferShrink(out->buffer, ret);
+	    }
+	    if (ret < 0) {
+		xmlIOErr(XML_IO_WRITE, NULL);
+		out->error = XML_IO_WRITE;
+		return(ret);
+	    }
+	    out->written += ret;
+	} else if (out->buffer->size - out->buffer->use < MINLEN) {
+	    xmlBufferResize(out->buffer, out->buffer->size + MINLEN);
+	}
+	written += nbchars;
+    } while ((len > 0) && (oldwritten != written));
+
+done:
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext,
+	    "I/O: wrote %d chars\n", written);
+#endif
+    return(written);
+}
+
+/**
+ * xmlOutputBufferWriteString:
+ * @out:  a buffered parser output
+ * @str:  a zero terminated C string
+ *
+ * Write the content of the string in the output I/O buffer
+ * This routine handle the I18N transcoding from internal UTF-8
+ * The buffer is lossless, i.e. will store in case of partial
+ * or delayed writes.
+ *
+ * Returns the number of chars immediately written, or -1
+ *         in case of error.
+ */
+int
+xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
+    int len;
+
+    if ((out == NULL) || (out->error)) return(-1);
+    if (str == NULL)
+        return(-1);
+    len = strlen(str);
+
+    if (len > 0)
+	return(xmlOutputBufferWrite(out, len, str));
+    return(len);
+}
+
+/**
+ * xmlOutputBufferFlush:
+ * @out:  a buffered output
+ *
+ * flushes the output I/O channel
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlOutputBufferFlush(xmlOutputBufferPtr out) {
+    int nbchars = 0, ret = 0;
+
+    if ((out == NULL) || (out->error)) return(-1);
+    /*
+     * first handle encoding stuff.
+     */
+    if ((out->conv != NULL) && (out->encoder != NULL)) {
+	/*
+	 * convert as much as possible to the parser reading buffer.
+	 */
+	nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
+	if (nbchars < 0) {
+	    xmlIOErr(XML_IO_ENCODER, NULL);
+	    out->error = XML_IO_ENCODER;
+	    return(-1);
+	}
+    }
+
+    /*
+     * second flush the stuff to the I/O channel
+     */
+    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 if (out->writecallback != NULL) {
+	ret = out->writecallback(out->context,
+	           (const char *)out->buffer->content, out->buffer->use);
+	if (ret >= 0)
+	    xmlBufferShrink(out->buffer, ret);
+    }
+    if (ret < 0) {
+	xmlIOErr(XML_IO_FLUSH, NULL);
+	out->error = XML_IO_FLUSH;
+	return(ret);
+    }
+    out->written += ret;
+
+#ifdef DEBUG_INPUT
+    xmlGenericError(xmlGenericErrorContext,
+	    "I/O: flushed %d chars\n", ret);
+#endif
+    return(ret);
+}
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * xmlParserGetDirectory:
+ * @filename:  the path to a file
+ *
+ * lookup the directory for that file
+ *
+ * Returns a new allocated string containing the directory, or NULL.
+ */
+char *
+xmlParserGetDirectory(const char *filename) {
+    char *ret = NULL;
+    char dir[1024];
+    char *cur;
+
+#ifdef _WIN32_WCE  /* easy way by now ... wince does not have dirs! */
+    return NULL;
+#endif
+
+    if (xmlInputCallbackInitialized == 0)
+	xmlRegisterDefaultInputCallbacks();
+
+    if (filename == NULL) return(NULL);
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#   define IS_XMLPGD_SEP(ch) ((ch=='/')||(ch=='\\'))
+#else
+#   define IS_XMLPGD_SEP(ch) (ch=='/')
+#endif
+
+    strncpy(dir, filename, 1023);
+    dir[1023] = 0;
+    cur = &dir[strlen(dir)];
+    while (cur > dir) {
+         if (IS_XMLPGD_SEP(*cur)) break;
+	 cur --;
+    }
+    if (IS_XMLPGD_SEP(*cur)) {
+        if (cur == dir) dir[1] = 0;
+	else *cur = 0;
+	ret = xmlMemStrdup(dir);
+    } else {
+        if (getcwd(dir, 1024) != NULL) {
+	    dir[1023] = 0;
+	    ret = xmlMemStrdup(dir);
+	}
+    }
+    return(ret);
+#undef IS_XMLPGD_SEP
+}
+
+/****************************************************************
+ *								*
+ *		External entities loading			*
+ *								*
+ ****************************************************************/
+
+/**
+ * xmlCheckHTTPInput:
+ * @ctxt: an XML parser context
+ * @ret: an XML parser input
+ *
+ * Check an input in case it was created from an HTTP stream, in that
+ * case it will handle encoding and update of the base URL in case of
+ * redirection. It also checks for HTTP errors in which case the input
+ * is cleanly freed up and an appropriate error is raised in context
+ *
+ * Returns the input or NULL in case of HTTP error.
+ */
+xmlParserInputPtr
+xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
+#ifdef LIBXML_HTTP_ENABLED
+    if ((ret != NULL) && (ret->buf != NULL) &&
+        (ret->buf->readcallback == xmlIOHTTPRead) &&
+        (ret->buf->context != NULL)) {
+        const char *encoding;
+        const char *redir;
+        const char *mime;
+        int code;
+
+        code = xmlNanoHTTPReturnCode(ret->buf->context);
+        if (code >= 400) {
+            /* fatal error */
+	    if (ret->filename != NULL)
+		__xmlLoaderErr(ctxt, "failed to load HTTP resource \"%s\"\n",
+                         (const char *) ret->filename);
+	    else
+		__xmlLoaderErr(ctxt, "failed to load HTTP resource\n", NULL);
+            xmlFreeInputStream(ret);
+            ret = NULL;
+        } else {
+
+            mime = xmlNanoHTTPMimeType(ret->buf->context);
+            if ((xmlStrstr(BAD_CAST mime, BAD_CAST "/xml")) ||
+                (xmlStrstr(BAD_CAST mime, BAD_CAST "+xml"))) {
+                encoding = xmlNanoHTTPEncoding(ret->buf->context);
+                if (encoding != NULL) {
+                    xmlCharEncodingHandlerPtr handler;
+
+                    handler = xmlFindCharEncodingHandler(encoding);
+                    if (handler != NULL) {
+                        xmlSwitchInputEncoding(ctxt, ret, handler);
+                    } else {
+                        __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
+                                         "Unknown encoding %s",
+                                         BAD_CAST encoding, NULL);
+                    }
+                    if (ret->encoding == NULL)
+                        ret->encoding = xmlStrdup(BAD_CAST encoding);
+                }
+#if 0
+            } else if (xmlStrstr(BAD_CAST mime, BAD_CAST "html")) {
+#endif
+            }
+            redir = xmlNanoHTTPRedir(ret->buf->context);
+            if (redir != NULL) {
+                if (ret->filename != NULL)
+                    xmlFree((xmlChar *) ret->filename);
+                if (ret->directory != NULL) {
+                    xmlFree((xmlChar *) ret->directory);
+                    ret->directory = NULL;
+                }
+                ret->filename =
+                    (char *) xmlStrdup((const xmlChar *) redir);
+            }
+        }
+    }
+#endif
+    return(ret);
+}
+
+static int xmlNoNetExists(const char *URL) {
+    const char *path;
+
+    if (URL == NULL)
+	return(0);
+
+    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &URL[17];
+#else
+	path = &URL[16];
+#endif
+    else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
+#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
+	path = &URL[8];
+#else
+	path = &URL[7];
+#endif
+    } else
+	path = URL;
+
+    return xmlCheckFilename(path);
+}
+
+#ifdef LIBXML_CATALOG_ENABLED
+
+/**
+ * xmlResolveResourceFromCatalog:
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @ctxt:  the context in which the entity is called or NULL
+ *
+ * Resolves the URL and ID against the appropriate catalog.
+ * This function is used by xmlDefaultExternalEntityLoader and
+ * xmlNoNetExternalEntityLoader.
+ *
+ * Returns a new allocated URL, or NULL.
+ */
+static xmlChar *
+xmlResolveResourceFromCatalog(const char *URL, const char *ID,
+                              xmlParserCtxtPtr ctxt) {
+    xmlChar *resource = NULL;
+    xmlCatalogAllow pref;
+
+    /*
+     * If the resource doesn't exists as a file,
+     * try to load it from the resource pointed in the catalogs
+     */
+    pref = xmlCatalogGetDefaults();
+
+    if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
+	/*
+	 * Do a local lookup
+	 */
+	if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+	    ((pref == XML_CATA_ALLOW_ALL) ||
+	     (pref == XML_CATA_ALLOW_DOCUMENT))) {
+	    resource = xmlCatalogLocalResolve(ctxt->catalogs,
+					      (const xmlChar *)ID,
+					      (const xmlChar *)URL);
+        }
+	/*
+	 * Try a global lookup
+	 */
+	if ((resource == NULL) &&
+	    ((pref == XML_CATA_ALLOW_ALL) ||
+	     (pref == XML_CATA_ALLOW_GLOBAL))) {
+	    resource = xmlCatalogResolve((const xmlChar *)ID,
+					 (const xmlChar *)URL);
+	}
+	if ((resource == NULL) && (URL != NULL))
+	    resource = xmlStrdup((const xmlChar *) URL);
+
+	/*
+	 * TODO: do an URI lookup on the reference
+	 */
+	if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
+	    xmlChar *tmp = NULL;
+
+	    if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+		((pref == XML_CATA_ALLOW_ALL) ||
+		 (pref == XML_CATA_ALLOW_DOCUMENT))) {
+		tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
+	    }
+	    if ((tmp == NULL) &&
+		((pref == XML_CATA_ALLOW_ALL) ||
+	         (pref == XML_CATA_ALLOW_GLOBAL))) {
+		tmp = xmlCatalogResolveURI(resource);
+	    }
+
+	    if (tmp != NULL) {
+		xmlFree(resource);
+		resource = tmp;
+	    }
+	}
+    }
+
+    return resource;
+}
+
+#endif
+
+/**
+ * xmlDefaultExternalEntityLoader:
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @ctxt:  the context in which the entity is called or NULL
+ *
+ * By default we don't load external entitites, yet.
+ *
+ * Returns a new allocated xmlParserInputPtr, or NULL.
+ */
+static xmlParserInputPtr
+xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
+                               xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr ret = NULL;
+    xmlChar *resource = NULL;
+
+#ifdef DEBUG_EXTERNAL_ENTITIES
+    xmlGenericError(xmlGenericErrorContext,
+                    "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
+#endif
+    if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
+        int options = ctxt->options;
+
+	ctxt->options -= XML_PARSE_NONET;
+        ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+	ctxt->options = options;
+	return(ret);
+    }
+#ifdef LIBXML_CATALOG_ENABLED
+    resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
+#endif
+
+    if (resource == NULL)
+        resource = (xmlChar *) URL;
+
+    if (resource == NULL) {
+        if (ID == NULL)
+            ID = "NULL";
+        __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n", ID);
+        return (NULL);
+    }
+    ret = xmlNewInputFromFile(ctxt, (const char *) resource);
+    if ((resource != NULL) && (resource != (xmlChar *) URL))
+        xmlFree(resource);
+    return (ret);
+}
+
+static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
+       xmlDefaultExternalEntityLoader;
+
+/**
+ * xmlSetExternalEntityLoader:
+ * @f:  the new entity resolver function
+ *
+ * Changes the defaultexternal entity resolver function for the application
+ */
+void
+xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
+    xmlCurrentExternalEntityLoader = f;
+}
+
+/**
+ * xmlGetExternalEntityLoader:
+ *
+ * Get the default external entity resolver function for the application
+ *
+ * Returns the xmlExternalEntityLoader function pointer
+ */
+xmlExternalEntityLoader
+xmlGetExternalEntityLoader(void) {
+    return(xmlCurrentExternalEntityLoader);
+}
+
+/**
+ * xmlLoadExternalEntity:
+ * @URL:  the URL for the entity to load
+ * @ID:  the Public ID for the entity to load
+ * @ctxt:  the context in which the entity is called or NULL
+ *
+ * Load an external entity, note that the use of this function for
+ * unparsed entities may generate problems
+ *
+ * Returns the xmlParserInputPtr or NULL
+ */
+xmlParserInputPtr
+xmlLoadExternalEntity(const char *URL, const char *ID,
+                      xmlParserCtxtPtr ctxt) {
+    if ((URL != NULL) && (xmlNoNetExists(URL) == 0)) {
+	char *canonicFilename;
+	xmlParserInputPtr ret;
+
+	canonicFilename = (char *) xmlCanonicPath((const xmlChar *) URL);
+	if (canonicFilename == NULL) {
+            xmlIOErrMemory("building canonical path\n");
+	    return(NULL);
+	}
+
+	ret = xmlCurrentExternalEntityLoader(canonicFilename, ID, ctxt);
+	xmlFree(canonicFilename);
+	return(ret);
+    }
+    return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
+}
+
+/************************************************************************
+ *									*
+ *		Disabling Network access				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlNoNetExternalEntityLoader:
+ * @URL:  the URL for the entity to load
+ * @ID:  the System ID for the entity to load
+ * @ctxt:  the context in which the entity is called or NULL
+ *
+ * A specific entity loader disabling network accesses, though still
+ * allowing local catalog accesses for resolution.
+ *
+ * Returns a new allocated xmlParserInputPtr, or NULL.
+ */
+xmlParserInputPtr
+xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
+                             xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr input = NULL;
+    xmlChar *resource = NULL;
+
+#ifdef LIBXML_CATALOG_ENABLED
+    resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
+#endif
+
+    if (resource == NULL)
+	resource = (xmlChar *) URL;
+
+    if (resource != NULL) {
+        if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) ||
+            (!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) {
+            xmlIOErr(XML_IO_NETWORK_ATTEMPT, (const char *) resource);
+	    if (resource != (xmlChar *) URL)
+		xmlFree(resource);
+	    return(NULL);
+	}
+    }
+    input = xmlDefaultExternalEntityLoader((const char *) resource, ID, ctxt);
+    if (resource != (xmlChar *) URL)
+	xmlFree(resource);
+    return(input);
+}
+
+#define bottom_xmlIO
+#include "elfgcchack.h"
diff --git a/src/xmlcatalog.c b/src/xmlcatalog.c
new file mode 100644
index 0000000..489509f
--- /dev/null
+++ b/src/xmlcatalog.c
@@ -0,0 +1,614 @@
+/*
+ * xmlcatalog.c : a small utility program to handle XML catalogs
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_LIBREADLINE
+#include <readline/readline.h>
+#ifdef HAVE_LIBHISTORY
+#include <readline/history.h>
+#endif
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/uri.h>
+#include <libxml/catalog.h>
+#include <libxml/parser.h>
+#include <libxml/globals.h>
+
+#if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+static int shell = 0;
+static int sgml = 0;
+static int noout = 0;
+static int create = 0;
+static int add = 0;
+static int del = 0;
+static int convert = 0;
+static int no_super_update = 0;
+static int verbose = 0;
+static char *filename = NULL;
+
+
+#ifndef XML_SGML_DEFAULT_CATALOG
+#define XML_SGML_DEFAULT_CATALOG "/etc/sgml/catalog"
+#endif
+
+/************************************************************************
+ * 									*
+ * 			Shell Interface					*
+ * 									*
+ ************************************************************************/
+/**
+ * xmlShellReadline:
+ * @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.
+ */
+static char *
+xmlShellReadline(const char *prompt) {
+#ifdef HAVE_LIBREADLINE
+    char *line_read;
+
+    /* Get a line from the user. */
+    line_read = readline (prompt);
+
+    /* If the line has any text in it, save it on the history. */
+    if (line_read && *line_read)
+	add_history (line_read);
+
+    return (line_read);
+#else
+    char line_read[501];
+    char *ret;
+    int len;
+
+    if (prompt != NULL)
+	fprintf(stdout, "%s", prompt);
+    if (!fgets(line_read, 500, stdin))
+        return(NULL);
+    line_read[500] = 0;
+    len = strlen(line_read);
+    ret = (char *) malloc(len + 1);
+    if (ret != NULL) {
+	memcpy (ret, line_read, len + 1);
+    }
+    return(ret);
+#endif
+}
+
+static void usershell(void) {
+    char *cmdline = NULL, *cur;
+    int nbargs;
+    char command[100];
+    char arg[400];
+    char *argv[20];
+    int i, ret;
+    xmlChar *ans;
+
+    while (1) {
+	cmdline = xmlShellReadline("> ");
+	if (cmdline == NULL)
+	    return;
+
+	/*
+	 * Parse the command itself
+	 */
+	cur = cmdline;
+	nbargs = 0;
+	while ((*cur == ' ') || (*cur == '\t')) cur++;
+	i = 0;
+	while ((*cur != ' ') && (*cur != '\t') &&
+	       (*cur != '\n') && (*cur != '\r')) {
+	    if (*cur == 0)
+		break;
+	    command[i++] = *cur++;
+	}
+	command[i] = 0;
+	if (i == 0) {
+	    free(cmdline);
+	    continue;
+	}
+
+	/*
+	 * Parse the argument string
+	 */
+	memset(arg, 0, sizeof(arg));
+	while ((*cur == ' ') || (*cur == '\t')) cur++;
+	i = 0;
+	while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
+	    if (*cur == 0)
+		break;
+	    arg[i++] = *cur++;
+	}
+	arg[i] = 0;
+
+	/*
+	 * Parse the arguments
+	 */
+	i = 0;
+	nbargs = 0;
+	cur = arg;
+	memset(argv, 0, sizeof(argv));
+	while (*cur != 0) {
+	    while ((*cur == ' ') || (*cur == '\t')) cur++;
+	    if (*cur == '\'') {
+		cur++;
+		argv[i] = cur;
+		while ((*cur != 0) && (*cur != '\'')) cur++;
+		if (*cur == '\'') {
+		    *cur = 0;
+		    nbargs++;
+		    i++;
+		    cur++;
+		}
+	    } else if (*cur == '"') { 
+		cur++;
+		argv[i] = cur;
+		while ((*cur != 0) && (*cur != '"')) cur++;
+		if (*cur == '"') {
+		    *cur = 0;
+		    nbargs++;
+		    i++;
+		    cur++;
+		}
+	    } else {
+		argv[i] = cur;
+		while ((*cur != 0) && (*cur != ' ') && (*cur != '\t'))
+		    cur++;
+		*cur = 0;
+		nbargs++;
+		i++;
+		cur++;
+	    }
+	}
+
+	/*
+	 * start interpreting the command
+	 */
+        if (!strcmp(command, "exit"))
+	    break;
+        if (!strcmp(command, "quit"))
+	    break;
+        if (!strcmp(command, "bye"))
+	    break;
+	if (!strcmp(command, "public")) {
+	    if (nbargs != 1) {
+		printf("public requires 1 arguments\n");
+	    } else {
+		ans = xmlCatalogResolvePublic((const xmlChar *) argv[0]);
+		if (ans == NULL) {
+		    printf("No entry for PUBLIC %s\n", argv[0]);
+		} else {
+		    printf("%s\n", (char *) ans);
+		    xmlFree(ans);
+		}
+	    }
+	} else if (!strcmp(command, "system")) {
+	    if (nbargs != 1) {
+		printf("system requires 1 arguments\n");
+	    } else {
+		ans = xmlCatalogResolveSystem((const xmlChar *) argv[0]);
+		if (ans == NULL) {
+		    printf("No entry for SYSTEM %s\n", argv[0]);
+		} else {
+		    printf("%s\n", (char *) ans);
+		    xmlFree(ans);
+		}
+	    }
+	} else if (!strcmp(command, "add")) {
+	    if (sgml) {
+		if ((nbargs != 3) && (nbargs != 2)) {
+		    printf("add requires 2 or 3 arguments\n");
+		} else {
+		    if (argv[2] == NULL)
+			ret = xmlCatalogAdd(BAD_CAST argv[0], NULL,
+					    BAD_CAST argv[1]);
+		    else
+			ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1],
+					    BAD_CAST argv[2]);
+		    if (ret != 0)
+			printf("add command failed\n");
+		}
+	    } else {
+		if ((nbargs != 3) && (nbargs != 2)) {
+		    printf("add requires 2 or 3 arguments\n");
+		} else {
+		    if (argv[2] == NULL)
+			ret = xmlCatalogAdd(BAD_CAST argv[0], NULL,
+					    BAD_CAST argv[1]);
+		    else
+			ret = xmlCatalogAdd(BAD_CAST argv[0], BAD_CAST argv[1],
+					    BAD_CAST argv[2]);
+		    if (ret != 0)
+			printf("add command failed\n");
+		}
+	    }
+	} else if (!strcmp(command, "del")) {
+	    if (nbargs != 1) {
+		printf("del requires 1\n");
+	    } else {
+		ret = xmlCatalogRemove(BAD_CAST argv[0]);
+		if (ret <= 0)
+		    printf("del command failed\n");
+
+	    }
+	} else if (!strcmp(command, "resolve")) {
+	    if (nbargs != 2) {
+		printf("resolve requires 2 arguments\n");
+	    } else {
+		ans = xmlCatalogResolve(BAD_CAST argv[0],
+			                BAD_CAST argv[1]);
+		if (ans == NULL) {
+		    printf("Resolver failed to find an answer\n");
+		} else {
+		    printf("%s\n", (char *) ans);
+		    xmlFree(ans);
+		}
+	    }
+	} else if (!strcmp(command, "dump")) {
+	    if (nbargs != 0) {
+		printf("dump has no arguments\n");
+	    } else {
+		xmlCatalogDump(stdout);
+	    }
+	} else if (!strcmp(command, "debug")) {
+	    if (nbargs != 0) {
+		printf("debug has no arguments\n");
+	    } else {
+		verbose++;
+		xmlCatalogSetDebug(verbose);
+	    }
+	} else if (!strcmp(command, "quiet")) {
+	    if (nbargs != 0) {
+		printf("quiet has no arguments\n");
+	    } else {
+		if (verbose > 0)
+		    verbose--;
+		xmlCatalogSetDebug(verbose);
+	    }
+	} else {
+	    if (strcmp(command, "help")) {
+		printf("Unrecognized command %s\n", command);
+	    }
+	    printf("Commands available:\n");
+	    printf("\tpublic PublicID: make a PUBLIC identifier lookup\n");
+	    printf("\tsystem SystemID: make a SYSTEM identifier lookup\n");
+	    printf("\tresolve PublicID SystemID: do a full resolver lookup\n");
+	    printf("\tadd 'type' 'orig' 'replace' : add an entry\n");
+	    printf("\tdel 'values' : remove values\n");
+	    printf("\tdump: print the current catalog state\n");
+	    printf("\tdebug: increase the verbosity level\n");
+	    printf("\tquiet: decrease the verbosity level\n");
+	    printf("\texit:  quit the shell\n");
+	} 
+	free(cmdline); /* not xmlFree here ! */
+    }
+}
+
+/************************************************************************
+ * 									*
+ * 			Main						*
+ * 									*
+ ************************************************************************/
+static void usage(const char *name) {
+    /* split into 2 printf's to avoid overly long string (gcc warning) */
+    printf("\
+Usage : %s [options] catalogfile entities...\n\
+\tParse the catalog file and query it for the entities\n\
+\t--sgml : handle SGML Super catalogs for --add and --del\n\
+\t--shell : run a shell allowing interactive queries\n\
+\t--create : create a new catalog\n\
+\t--add 'type' 'orig' 'replace' : add an XML entry\n\
+\t--add 'entry' : add an SGML entry\n", name);
+    printf("\
+\t--del 'values' : remove values\n\
+\t--noout: avoid dumping the result on stdout\n\
+\t         used with --add or --del, it saves the catalog changes\n\
+\t         and with --sgml it automatically updates the super catalog\n\
+\t--no-super-update: do not update the SGML super catalog\n\
+\t-v --verbose : provide debug informations\n");
+}
+int main(int argc, char **argv) {
+    int i;
+    int ret;
+    int exit_value = 0;
+
+
+    if (argc <= 1) {
+	usage(argv[0]);
+	return(1);
+    }
+
+    LIBXML_TEST_VERSION
+    for (i = 1; i < argc ; i++) {
+	if (!strcmp(argv[i], "-"))
+	    break;
+
+	if (argv[i][0] != '-')
+	    break;
+	if ((!strcmp(argv[i], "-verbose")) ||
+	    (!strcmp(argv[i], "-v")) ||
+	    (!strcmp(argv[i], "--verbose"))) {
+	    verbose++;
+	    xmlCatalogSetDebug(verbose);
+	} else if ((!strcmp(argv[i], "-noout")) ||
+	    (!strcmp(argv[i], "--noout"))) {
+            noout = 1;
+	} else if ((!strcmp(argv[i], "-shell")) ||
+	    (!strcmp(argv[i], "--shell"))) {
+	    shell++;
+            noout = 1;
+	} else if ((!strcmp(argv[i], "-sgml")) ||
+	    (!strcmp(argv[i], "--sgml"))) {
+	    sgml++;
+	} else if ((!strcmp(argv[i], "-create")) ||
+	    (!strcmp(argv[i], "--create"))) {
+	    create++;
+	} else if ((!strcmp(argv[i], "-convert")) ||
+	    (!strcmp(argv[i], "--convert"))) {
+	    convert++;
+	} else if ((!strcmp(argv[i], "-no-super-update")) ||
+	    (!strcmp(argv[i], "--no-super-update"))) {
+	    no_super_update++;
+	} else if ((!strcmp(argv[i], "-add")) ||
+	    (!strcmp(argv[i], "--add"))) {
+	    if (sgml)
+		i += 2;
+	    else
+		i += 3;
+	    add++;
+	} else if ((!strcmp(argv[i], "-del")) ||
+	    (!strcmp(argv[i], "--del"))) {
+	    i += 1;
+	    del++;
+	} else {
+	    fprintf(stderr, "Unknown option %s\n", argv[i]);
+	    usage(argv[0]);
+	    return(1);
+	}
+    }
+
+    for (i = 1; i < argc; i++) {
+	if ((!strcmp(argv[i], "-add")) ||
+	    (!strcmp(argv[i], "--add"))) {
+	    if (sgml)
+		i += 2;
+	    else
+		i += 3;
+	    continue;
+	} else if ((!strcmp(argv[i], "-del")) ||
+	    (!strcmp(argv[i], "--del"))) {
+	    i += 1;
+
+	    /* No catalog entry specified */
+	    if (i == argc || (sgml && i + 1 == argc)) {
+		fprintf(stderr, "No catalog entry specified to remove from\n");
+		usage (argv[0]);
+		return(1);
+	    }
+
+	    continue;
+	} else if (argv[i][0] == '-')
+	    continue;
+	filename = argv[i];
+	    ret = xmlLoadCatalog(argv[i]);
+	    if ((ret < 0) && (create)) {
+		xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);
+	    }
+	break;
+    }
+
+    if (convert)
+        ret = xmlCatalogConvert();
+
+    if ((add) || (del)) {
+	for (i = 1; i < argc ; i++) {
+	    if (!strcmp(argv[i], "-"))
+		break;
+
+	    if (argv[i][0] != '-')
+		continue;
+	    if (strcmp(argv[i], "-add") && strcmp(argv[i], "--add") &&
+		strcmp(argv[i], "-del") && strcmp(argv[i], "--del"))
+		continue;
+
+	    if (sgml) {
+		/*
+		 * Maintenance of SGML catalogs.
+		 */
+		xmlCatalogPtr catal = NULL;
+		xmlCatalogPtr super = NULL;
+
+		catal = xmlLoadSGMLSuperCatalog(argv[i + 1]);
+
+		if ((!strcmp(argv[i], "-add")) ||
+		    (!strcmp(argv[i], "--add"))) {
+		    if (catal == NULL)
+			catal = xmlNewCatalog(1);
+		    xmlACatalogAdd(catal, BAD_CAST "CATALOG",
+					 BAD_CAST argv[i + 2], NULL);
+
+		    if (!no_super_update) {
+			super = xmlLoadSGMLSuperCatalog(XML_SGML_DEFAULT_CATALOG);
+			if (super == NULL)
+			    super = xmlNewCatalog(1);
+
+			xmlACatalogAdd(super, BAD_CAST "CATALOG",
+					     BAD_CAST argv[i + 1], NULL);
+		    }
+		} else {
+		    if (catal != NULL)
+			ret = xmlACatalogRemove(catal, BAD_CAST argv[i + 2]);
+		    else
+			ret = -1;
+		    if (ret < 0) {
+			fprintf(stderr, "Failed to remove entry from %s\n",
+				argv[i + 1]);
+			exit_value = 1;
+		    }
+		    if ((!no_super_update) && (noout) && (catal != NULL) &&
+			(xmlCatalogIsEmpty(catal))) {
+			super = xmlLoadSGMLSuperCatalog(
+				   XML_SGML_DEFAULT_CATALOG);
+			if (super != NULL) {
+			    ret = xmlACatalogRemove(super,
+				    BAD_CAST argv[i + 1]);
+			    if (ret < 0) {
+				fprintf(stderr,
+					"Failed to remove entry from %s\n",
+					XML_SGML_DEFAULT_CATALOG);
+				exit_value = 1;
+			    }
+			}
+		    }
+		}
+		if (noout) {
+		    FILE *out;
+
+		    if (xmlCatalogIsEmpty(catal)) {
+			remove(argv[i + 1]);
+		    } else {
+			out = fopen(argv[i + 1], "w");
+			if (out == NULL) {
+			    fprintf(stderr, "could not open %s for saving\n",
+				    argv[i + 1]);
+			    exit_value = 2;
+			    noout = 0;
+			} else {
+			    xmlACatalogDump(catal, out);
+			    fclose(out);
+			}
+		    }
+		    if (!no_super_update && super != NULL) {
+			if (xmlCatalogIsEmpty(super)) {
+			    remove(XML_SGML_DEFAULT_CATALOG);
+			} else {
+			    out = fopen(XML_SGML_DEFAULT_CATALOG, "w");
+			    if (out == NULL) {
+				fprintf(stderr,
+					"could not open %s for saving\n",
+					XML_SGML_DEFAULT_CATALOG);
+				exit_value = 2;
+				noout = 0;
+			    } else {
+				
+				xmlACatalogDump(super, out);
+				fclose(out);
+			    }
+			}
+		    }
+		} else {
+		    xmlACatalogDump(catal, stdout);
+		}
+		i += 2;
+	    } else {
+		if ((!strcmp(argv[i], "-add")) ||
+		    (!strcmp(argv[i], "--add"))) {
+			if ((argv[i + 3] == NULL) || (argv[i + 3][0] == 0))
+			    ret = xmlCatalogAdd(BAD_CAST argv[i + 1], NULL,
+						BAD_CAST argv[i + 2]);
+			else
+			    ret = xmlCatalogAdd(BAD_CAST argv[i + 1],
+						BAD_CAST argv[i + 2],
+						BAD_CAST argv[i + 3]);
+			if (ret != 0) {
+			    printf("add command failed\n");
+			    exit_value = 3;
+			}
+			i += 3;
+		} else if ((!strcmp(argv[i], "-del")) ||
+		    (!strcmp(argv[i], "--del"))) {
+		    ret = xmlCatalogRemove(BAD_CAST argv[i + 1]);
+		    if (ret < 0) {
+			fprintf(stderr, "Failed to remove entry %s\n",
+				argv[i + 1]);
+			exit_value = 1;
+		    }
+		    i += 1;
+		}
+	    }
+	}
+	
+    } else if (shell) {
+	usershell();
+    } else {
+	for (i++; i < argc; i++) {
+	    xmlURIPtr uri;
+	    xmlChar *ans;
+	    
+	    uri = xmlParseURI(argv[i]);
+	    if (uri == NULL) {
+		ans = xmlCatalogResolvePublic((const xmlChar *) argv[i]);
+		if (ans == NULL) {
+		    printf("No entry for PUBLIC %s\n", argv[i]);
+		    exit_value = 4;
+		} else {
+		    printf("%s\n", (char *) ans);
+		    xmlFree(ans);
+		}
+	    } else {
+                xmlFreeURI(uri);
+		ans = xmlCatalogResolveSystem((const xmlChar *) argv[i]);
+		if (ans == NULL) {
+		    printf("No entry for SYSTEM %s\n", argv[i]);
+		    ans = xmlCatalogResolveURI ((const xmlChar *) argv[i]);
+		    if (ans == NULL) {
+			printf ("No entry for URI %s\n", argv[i]);
+		        exit_value = 4;
+		    } else {
+		        printf("%s\n", (char *) ans);
+			xmlFree (ans);
+		    }
+		} else {
+		    printf("%s\n", (char *) ans);
+		    xmlFree(ans);
+		}
+	    }
+	}
+    }
+    if ((!sgml) && ((add) || (del) || (create) || (convert))) {
+	if (noout && filename && *filename) {
+	    FILE *out;
+
+	    out = fopen(filename, "w");
+	    if (out == NULL) {
+		fprintf(stderr, "could not open %s for saving\n", filename);
+		exit_value = 2;
+		noout = 0;
+	    } else {
+		xmlCatalogDump(out);
+	    }
+	} else {
+	    xmlCatalogDump(stdout);
+	}
+    }
+
+    /*
+     * Cleanup and check for memory leaks
+     */
+    xmlCleanupParser();
+    xmlMemoryDump();
+    return(exit_value);
+}
+#else
+int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    fprintf(stderr, "libxml was not compiled with catalog and output support\n");
+    return(1);
+}
+#endif
diff --git a/src/xmllint.c b/src/xmllint.c
new file mode 100644
index 0000000..2a75e3b
--- /dev/null
+++ b/src/xmllint.c
@@ -0,0 +1,3722 @@
+/*
+ * xmllint.c : a small tester program for XML input.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined (_WIN32) && !defined(__CYGWIN__)
+#if defined (_MSC_VER) || defined(__BORLANDC__)
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+#define gettimeofday(p1,p2)
+#endif /* _MSC_VER */
+#endif /* _WIN32 */
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef __MINGW32__
+#define _WINSOCKAPI_
+#include <wsockcompat.h>
+#include <winsock2.h>
+#undef XML_SOCKLEN_T
+#define XML_SOCKLEN_T unsigned int
+#endif
+
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+/* seems needed for Solaris */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_LIBREADLINE
+#include <readline/readline.h>
+#ifdef HAVE_LIBHISTORY
+#include <readline/history.h>
+#endif
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlerror.h>
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+#endif
+#ifdef LIBXML_CATALOG_ENABLED
+#include <libxml/catalog.h>
+#endif
+#include <libxml/globals.h>
+#include <libxml/xmlreader.h>
+#ifdef LIBXML_SCHEMATRON_ENABLED
+#include <libxml/schematron.h>
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
+#ifdef LIBXML_C14N_ENABLED
+#include <libxml/c14n.h>
+#endif
+#ifdef LIBXML_OUTPUT_ENABLED
+#include <libxml/xmlsave.h>
+#endif
+
+#ifndef XML_XML_DEFAULT_CATALOG
+#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
+#endif
+
+typedef enum {
+    XMLLINT_RETURN_OK = 0,	/* No 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;
+static int debugent = 0;
+#endif
+static int debug = 0;
+static int maxmem = 0;
+#ifdef LIBXML_TREE_ENABLED
+static int copy = 0;
+#endif /* LIBXML_TREE_ENABLED */
+static int recovery = 0;
+static int noent = 0;
+static int noblanks = 0;
+static int noout = 0;
+static int nowrap = 0;
+#ifdef LIBXML_OUTPUT_ENABLED
+static int format = 0;
+static const char *output = NULL;
+static int compress = 0;
+static int oldout = 0;
+#endif /* LIBXML_OUTPUT_ENABLED */
+#ifdef LIBXML_VALID_ENABLED
+static int valid = 0;
+static int postvalid = 0;
+static char * dtdvalid = NULL;
+static char * dtdvalidfpi = NULL;
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+static char * relaxng = NULL;
+static xmlRelaxNGPtr relaxngschemas = NULL;
+static char * schema = NULL;
+static xmlSchemaPtr wxschemas = NULL;
+#endif
+#ifdef LIBXML_SCHEMATRON_ENABLED
+static char * schematron = NULL;
+static xmlSchematronPtr wxschematron = NULL;
+#endif
+static int repeat = 0;
+static int insert = 0;
+#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+static int html = 0;
+static int xmlout = 0;
+#endif
+static int htmlout = 0;
+#ifdef LIBXML_PUSH_ENABLED
+static int push = 0;
+#endif /* LIBXML_PUSH_ENABLED */
+#ifdef HAVE_SYS_MMAN_H
+static int memory = 0;
+#endif
+static int testIO = 0;
+static char *encoding = NULL;
+#ifdef LIBXML_XINCLUDE_ENABLED
+static int xinclude = 0;
+#endif
+static int dtdattrs = 0;
+static int loaddtd = 0;
+static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
+static int timing = 0;
+static int generate = 0;
+static int dropdtd = 0;
+#ifdef LIBXML_CATALOG_ENABLED
+static int catalogs = 0;
+static int nocatalogs = 0;
+#endif
+#ifdef LIBXML_C14N_ENABLED
+static int canonical = 0;
+static int canonical_11 = 0;
+static int exc_canonical = 0;
+#endif
+#ifdef LIBXML_READER_ENABLED
+static int stream = 0;
+static int walker = 0;
+#endif /* LIBXML_READER_ENABLED */
+static int chkregister = 0;
+static int nbregister = 0;
+#ifdef LIBXML_SAX1_ENABLED
+static int sax1 = 0;
+#endif /* LIBXML_SAX1_ENABLED */
+#ifdef LIBXML_PATTERN_ENABLED
+static const char *pattern = NULL;
+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;
+
+/************************************************************************
+ *									*
+ *		 Entity loading control and customization.		*
+ *									*
+ ************************************************************************/
+#define MAX_PATHS 64
+#ifdef _WIN32
+# define PATH_SEPARATOR ';'
+#else
+# define PATH_SEPARATOR ':'
+#endif
+static xmlChar *paths[MAX_PATHS + 1];
+static int nbpaths = 0;
+static int load_trace = 0;
+
+static
+void parsePath(const xmlChar *path) {
+    const xmlChar *cur;
+
+    if (path == NULL)
+	return;
+    while (*path != 0) {
+	if (nbpaths >= MAX_PATHS) {
+	    fprintf(stderr, "MAX_PATHS reached: too many paths\n");
+	    return;
+	}
+	cur = path;
+	while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
+	    cur++;
+	path = cur;
+	while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
+	    cur++;
+	if (cur != path) {
+	    paths[nbpaths] = xmlStrndup(path, cur - path);
+	    if (paths[nbpaths] != NULL)
+		nbpaths++;
+	    path = cur;
+	}
+    }
+}
+
+static xmlExternalEntityLoader defaultEntityLoader = NULL;
+
+static xmlParserInputPtr
+xmllintExternalEntityLoader(const char *URL, const char *ID,
+			     xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr ret;
+    warningSAXFunc warning = NULL;
+    errorSAXFunc err = NULL;
+
+    int i;
+    const char *lastsegment = URL;
+    const char *iter = URL;
+
+    if ((nbpaths > 0) && (iter != NULL)) {
+	while (*iter != 0) {
+	    if (*iter == '/')
+		lastsegment = iter + 1;
+	    iter++;
+	}
+    }
+
+    if ((ctxt != NULL) && (ctxt->sax != NULL)) {
+	warning = ctxt->sax->warning;
+	err = ctxt->sax->error;
+	ctxt->sax->warning = NULL;
+	ctxt->sax->error = NULL;
+    }
+
+    if (defaultEntityLoader != NULL) {
+	ret = defaultEntityLoader(URL, ID, ctxt);
+	if (ret != NULL) {
+	    if (warning != NULL)
+		ctxt->sax->warning = warning;
+	    if (err != NULL)
+		ctxt->sax->error = err;
+	    if (load_trace) {
+		fprintf \
+			(stderr,
+			 "Loaded URL=\"%s\" ID=\"%s\"\n",
+			 URL ? URL : "(null)",
+			 ID ? ID : "(null)");
+	    }
+	    return(ret);
+	}
+    }
+    for (i = 0;i < nbpaths;i++) {
+	xmlChar *newURL;
+
+	newURL = xmlStrdup((const xmlChar *) paths[i]);
+	newURL = xmlStrcat(newURL, (const xmlChar *) "/");
+	newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
+	if (newURL != NULL) {
+	    ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
+	    if (ret != NULL) {
+		if (warning != NULL)
+		    ctxt->sax->warning = warning;
+		if (err != NULL)
+		    ctxt->sax->error = err;
+		if (load_trace) {
+		    fprintf \
+			(stderr,
+			 "Loaded URL=\"%s\" ID=\"%s\"\n",
+			 newURL,
+			 ID ? ID : "(null)");
+		}
+		xmlFree(newURL);
+		return(ret);
+	    }
+	    xmlFree(newURL);
+	}
+    }
+    if (err != NULL)
+        ctxt->sax->error = err;
+    if (warning != NULL) {
+	ctxt->sax->warning = warning;
+	if (URL != NULL)
+	    warning(ctxt, "failed to load external entity \"%s\"\n", URL);
+	else if (ID != NULL)
+	    warning(ctxt, "failed to load external entity \"%s\"\n", ID);
+    }
+    return(NULL);
+}
+/************************************************************************
+ *									*
+ * Memory allocation consumption debugging				*
+ *									*
+ ************************************************************************/
+
+static void
+OOM(void)
+{
+    fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
+    progresult = XMLLINT_ERR_MEM;
+}
+
+static void
+myFreeFunc(void *mem)
+{
+    xmlMemFree(mem);
+}
+static void *
+myMallocFunc(size_t size)
+{
+    void *ret;
+
+    ret = xmlMemMalloc(size);
+    if (ret != NULL) {
+        if (xmlMemUsed() > maxmem) {
+            OOM();
+            xmlMemFree(ret);
+            return (NULL);
+        }
+    }
+    return (ret);
+}
+static void *
+myReallocFunc(void *mem, size_t size)
+{
+    void *ret;
+
+    ret = xmlMemRealloc(mem, size);
+    if (ret != NULL) {
+        if (xmlMemUsed() > maxmem) {
+            OOM();
+            xmlMemFree(ret);
+            return (NULL);
+        }
+    }
+    return (ret);
+}
+static char *
+myStrdupFunc(const char *str)
+{
+    char *ret;
+
+    ret = xmlMemoryStrdup(str);
+    if (ret != NULL) {
+        if (xmlMemUsed() > maxmem) {
+            OOM();
+            xmlFree(ret);
+            return (NULL);
+        }
+    }
+    return (ret);
+}
+/************************************************************************
+ *									*
+ * Internal timing routines to remove the necessity to have		*
+ * unix-specific function calls.					*
+ *									*
+ ************************************************************************/
+
+#ifndef HAVE_GETTIMEOFDAY
+#ifdef HAVE_SYS_TIMEB_H
+#ifdef HAVE_SYS_TIME_H
+#ifdef HAVE_FTIME
+
+static int
+my_gettimeofday(struct timeval *tvp, void *tzp)
+{
+	struct timeb timebuffer;
+
+	ftime(&timebuffer);
+	if (tvp) {
+		tvp->tv_sec = timebuffer.time;
+		tvp->tv_usec = timebuffer.millitm * 1000L;
+	}
+	return (0);
+}
+#define HAVE_GETTIMEOFDAY 1
+#define gettimeofday my_gettimeofday
+
+#endif /* HAVE_FTIME */
+#endif /* HAVE_SYS_TIME_H */
+#endif /* HAVE_SYS_TIMEB_H */
+#endif /* !HAVE_GETTIMEOFDAY */
+
+#if defined(HAVE_GETTIMEOFDAY)
+static struct timeval begin, end;
+
+/*
+ * startTimer: call where you want to start timing
+ */
+static void
+startTimer(void)
+{
+    gettimeofday(&begin, NULL);
+}
+
+/*
+ * endTimer: call where you want to stop timing and to print out a
+ *           message about the timing performed; format is a printf
+ *           type argument
+ */
+static void XMLCDECL
+endTimer(const char *fmt, ...)
+{
+    long msec;
+    va_list ap;
+
+    gettimeofday(&end, NULL);
+    msec = end.tv_sec - begin.tv_sec;
+    msec *= 1000;
+    msec += (end.tv_usec - begin.tv_usec) / 1000;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+
+    fprintf(stderr, " took %ld ms\n", msec);
+}
+#elif defined(HAVE_TIME_H)
+/*
+ * No gettimeofday function, so we have to make do with calling clock.
+ * This is obviously less accurate, but there's little we can do about
+ * that.
+ */
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 100
+#endif
+
+static clock_t begin, end;
+static void
+startTimer(void)
+{
+    begin = clock();
+}
+static void XMLCDECL
+endTimer(const char *fmt, ...)
+{
+    long msec;
+    va_list ap;
+
+    end = clock();
+    msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, " took %ld ms\n", msec);
+}
+#else
+
+/*
+ * We don't have a gettimeofday or time.h, so we just don't do timing
+ */
+static void
+startTimer(void)
+{
+    /*
+     * Do nothing
+     */
+}
+static void XMLCDECL
+endTimer(char *format, ...)
+{
+    /*
+     * We cannot do anything because we don't have a timing function
+     */
+#ifdef HAVE_STDARG_H
+    va_start(ap, format);
+    vfprintf(stderr, format, ap);
+    va_end(ap);
+    fprintf(stderr, " was not timed\n", msec);
+#else
+    /* We don't have gettimeofday, time or stdarg.h, what crazy world is
+     * this ?!
+     */
+#endif
+}
+#endif
+/************************************************************************
+ *									*
+ *			HTML ouput					*
+ *									*
+ ************************************************************************/
+static char buffer[50000];
+
+static void
+xmlHTMLEncodeSend(void) {
+    char *result;
+
+    result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
+    if (result) {
+	xmlGenericError(xmlGenericErrorContext, "%s", result);
+	xmlFree(result);
+    }
+    buffer[0] = 0;
+}
+
+/**
+ * xmlHTMLPrintFileInfo:
+ * @input:  an xmlParserInputPtr input
+ *
+ * Displays the associated file and line informations for the current input
+ */
+
+static void
+xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
+    int len;
+    xmlGenericError(xmlGenericErrorContext, "<p>");
+
+    len = strlen(buffer);
+    if (input != NULL) {
+	if (input->filename) {
+	    snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
+		    input->line);
+	} else {
+	    snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
+	}
+    }
+    xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLPrintFileContext:
+ * @input:  an xmlParserInputPtr input
+ *
+ * Displays current context within the input content for error tracking
+ */
+
+static void
+xmlHTMLPrintFileContext(xmlParserInputPtr input) {
+    const xmlChar *cur, *base;
+    int len;
+    int n;
+
+    if (input == NULL) return;
+    xmlGenericError(xmlGenericErrorContext, "<pre>\n");
+    cur = input->cur;
+    base = input->base;
+    while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
+	cur--;
+    }
+    n = 0;
+    while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
+        cur--;
+    if ((*cur == '\n') || (*cur == '\r')) cur++;
+    base = cur;
+    n = 0;
+    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+	len = strlen(buffer);
+        snprintf(&buffer[len], sizeof(buffer) - len, "%c",
+		    (unsigned char) *cur++);
+	n++;
+    }
+    len = strlen(buffer);
+    snprintf(&buffer[len], sizeof(buffer) - len, "\n");
+    cur = input->cur;
+    while ((*cur == '\n') || (*cur == '\r'))
+	cur--;
+    n = 0;
+    while ((cur != base) && (n++ < 80)) {
+	len = strlen(buffer);
+        snprintf(&buffer[len], sizeof(buffer) - len, " ");
+        base++;
+    }
+    len = strlen(buffer);
+    snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
+    xmlHTMLEncodeSend();
+    xmlGenericError(xmlGenericErrorContext, "</pre>");
+}
+
+/**
+ * xmlHTMLError:
+ * @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.
+ */
+static void XMLCDECL
+xmlHTMLError(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input;
+    va_list args;
+    int len;
+
+    buffer[0] = 0;
+    input = ctxt->input;
+    if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
+        input = ctxt->inputTab[ctxt->inputNr - 2];
+    }
+
+    xmlHTMLPrintFileInfo(input);
+
+    xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
+    va_start(args, msg);
+    len = strlen(buffer);
+    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
+    va_end(args);
+    xmlHTMLEncodeSend();
+    xmlGenericError(xmlGenericErrorContext, "</p>\n");
+
+    xmlHTMLPrintFileContext(input);
+    xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLWarning:
+ * @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.
+ */
+static void XMLCDECL
+xmlHTMLWarning(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input;
+    va_list args;
+    int len;
+
+    buffer[0] = 0;
+    input = ctxt->input;
+    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);
+    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
+    va_end(args);
+    xmlHTMLEncodeSend();
+    xmlGenericError(xmlGenericErrorContext, "</p>\n");
+
+    xmlHTMLPrintFileContext(input);
+    xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLValidityError:
+ * @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.
+ */
+static void XMLCDECL
+xmlHTMLValidityError(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input;
+    va_list args;
+    int len;
+
+    buffer[0] = 0;
+    input = ctxt->input;
+    if ((input->filename == NULL) && (ctxt->inputNr > 1))
+        input = ctxt->inputTab[ctxt->inputNr - 2];
+
+    xmlHTMLPrintFileInfo(input);
+
+    xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
+    len = strlen(buffer);
+    va_start(args, msg);
+    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
+    va_end(args);
+    xmlHTMLEncodeSend();
+    xmlGenericError(xmlGenericErrorContext, "</p>\n");
+
+    xmlHTMLPrintFileContext(input);
+    xmlHTMLEncodeSend();
+    progresult = XMLLINT_ERR_VALID;
+}
+
+/**
+ * xmlHTMLValidityWarning:
+ * @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.
+ */
+static void XMLCDECL
+xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr input;
+    va_list args;
+    int len;
+
+    buffer[0] = 0;
+    input = ctxt->input;
+    if ((input->filename == NULL) && (ctxt->inputNr > 1))
+        input = ctxt->inputTab[ctxt->inputNr - 2];
+
+    xmlHTMLPrintFileInfo(input);
+
+    xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
+    va_start(args, msg);
+    len = strlen(buffer);
+    vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
+    va_end(args);
+    xmlHTMLEncodeSend();
+    xmlGenericError(xmlGenericErrorContext, "</p>\n");
+
+    xmlHTMLPrintFileContext(input);
+    xmlHTMLEncodeSend();
+}
+
+/************************************************************************
+ *									*
+ *			Shell Interface					*
+ *									*
+ ************************************************************************/
+#ifdef LIBXML_DEBUG_ENABLED
+#ifdef LIBXML_XPATH_ENABLED
+/**
+ * xmlShellReadline:
+ * @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.
+ */
+static char *
+xmlShellReadline(char *prompt) {
+#ifdef HAVE_LIBREADLINE
+    char *line_read;
+
+    /* Get a line from the user. */
+    line_read = readline (prompt);
+
+    /* If the line has any text in it, save it on the history. */
+    if (line_read && *line_read)
+	add_history (line_read);
+
+    return (line_read);
+#else
+    char line_read[501];
+    char *ret;
+    int len;
+
+    if (prompt != NULL)
+	fprintf(stdout, "%s", prompt);
+    if (!fgets(line_read, 500, stdin))
+        return(NULL);
+    line_read[500] = 0;
+    len = strlen(line_read);
+    ret = (char *) malloc(len + 1);
+    if (ret != NULL) {
+	memcpy (ret, line_read, len + 1);
+    }
+    return(ret);
+#endif
+}
+#endif /* LIBXML_XPATH_ENABLED */
+#endif /* LIBXML_DEBUG_ENABLED */
+
+/************************************************************************
+ *									*
+ *			I/O Interfaces					*
+ *									*
+ ************************************************************************/
+
+static int myRead(FILE *f, char * buf, int len) {
+    return(fread(buf, 1, len, f));
+}
+static void myClose(FILE *f) {
+  if (f != stdin) {
+    fclose(f);
+  }
+}
+
+/************************************************************************
+ *									*
+ *			SAX based tests					*
+ *									*
+ ************************************************************************/
+
+/*
+ * empty SAX block
+ */
+static xmlSAXHandler emptySAXHandlerStruct = {
+    NULL, /* internalSubset */
+    NULL, /* isStandalone */
+    NULL, /* hasInternalSubset */
+    NULL, /* hasExternalSubset */
+    NULL, /* resolveEntity */
+    NULL, /* getEntity */
+    NULL, /* entityDecl */
+    NULL, /* notationDecl */
+    NULL, /* attributeDecl */
+    NULL, /* elementDecl */
+    NULL, /* unparsedEntityDecl */
+    NULL, /* setDocumentLocator */
+    NULL, /* startDocument */
+    NULL, /* endDocument */
+    NULL, /* startElement */
+    NULL, /* endElement */
+    NULL, /* reference */
+    NULL, /* characters */
+    NULL, /* ignorableWhitespace */
+    NULL, /* processingInstruction */
+    NULL, /* comment */
+    NULL, /* xmlParserWarning */
+    NULL, /* xmlParserError */
+    NULL, /* xmlParserError */
+    NULL, /* getParameterEntity */
+    NULL, /* cdataBlock; */
+    NULL, /* externalSubset; */
+    XML_SAX2_MAGIC,
+    NULL,
+    NULL, /* startElementNs */
+    NULL, /* endElementNs */
+    NULL  /* xmlStructuredErrorFunc */
+};
+
+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
+extern xmlSAXHandlerPtr debugSAXHandler;
+static int callbacks;
+
+/**
+ * isStandaloneDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return(0);
+    fprintf(stdout, "SAX.isStandalone()\n");
+    return(0);
+}
+
+/**
+ * hasInternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return(0);
+    fprintf(stdout, "SAX.hasInternalSubset()\n");
+    return(0);
+}
+
+/**
+ * hasExternalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return(0);
+    fprintf(stdout, "SAX.hasExternalSubset()\n");
+    return(0);
+}
+
+/**
+ * internalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.internalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(stdout, " ,");
+    else
+	fprintf(stdout, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(stdout, " )\n");
+    else
+	fprintf(stdout, " %s)\n", SystemID);
+}
+
+/**
+ * externalSubsetDebug:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.externalSubset(%s,", name);
+    if (ExternalID == NULL)
+	fprintf(stdout, " ,");
+    else
+	fprintf(stdout, " %s,", ExternalID);
+    if (SystemID == NULL)
+	fprintf(stdout, " )\n");
+    else
+	fprintf(stdout, " %s)\n", SystemID);
+}
+
+/**
+ * resolveEntityDebug:
+ * @ctxt:  An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (noout)
+	return(NULL);
+    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+
+
+    fprintf(stdout, "SAX.resolveEntity(");
+    if (publicId != NULL)
+	fprintf(stdout, "%s", (char *)publicId);
+    else
+	fprintf(stdout, " ");
+    if (systemId != NULL)
+	fprintf(stdout, ", %s)\n", (char *)systemId);
+    else
+	fprintf(stdout, ", )\n");
+    return(NULL);
+}
+
+/**
+ * getEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (noout)
+	return(NULL);
+    fprintf(stdout, "SAX.getEntity(%s)\n", name);
+    return(NULL);
+}
+
+/**
+ * getParameterEntityDebug:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (noout)
+	return(NULL);
+    fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
+    return(NULL);
+}
+
+
+/**
+ * entityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @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).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+    /* not all libraries handle printing null pointers nicely */
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (content == NULL)
+        content = (xmlChar *)nullstr;
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
+            name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the attribute name
+ * @type:  the attribute type
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
+                   const xmlChar * name, int type, int def,
+                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
+{
+    callbacks++;
+    if (noout)
+        return;
+    if (defaultValue == NULL)
+        fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
+                elem, name, type, def);
+    else
+        fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
+                elem, name, type, def, defaultValue);
+    xmlFreeEnumeration(tree);
+}
+
+/**
+ * elementDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name:  the element name
+ * @type:  the element type
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
+            name, type);
+}
+
+/**
+ * notationDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId);
+}
+
+/**
+ * unparsedEntityDeclDebug:
+ * @ctxt:  An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+const xmlChar *nullstr = BAD_CAST "(null)";
+
+    if (publicId == NULL)
+        publicId = nullstr;
+    if (systemId == NULL)
+        systemId = nullstr;
+    if (notationName == NULL)
+        notationName = nullstr;
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+            (char *) name, (char *) publicId, (char *) systemId,
+	    (char *) notationName);
+}
+
+/**
+ * setDocumentLocatorDebug:
+ * @ctxt:  An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.setDocumentLocator()\n");
+}
+
+/**
+ * startDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.startDocument()\n");
+}
+
+/**
+ * endDocumentDebug:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.endDocument()\n");
+}
+
+/**
+ * startElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+	    fprintf(stdout, ", %s='", atts[i++]);
+	    if (atts[i] != NULL)
+	        fprintf(stdout, "%s'", atts[i]);
+	}
+    }
+    fprintf(stdout, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
+}
+
+/**
+ * charactersDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char out[40];
+    int i;
+
+    callbacks++;
+    if (noout)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	out[i] = ch[i];
+    out[i] = 0;
+
+    fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
+}
+
+/**
+ * referenceDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected.
+ */
+static void
+referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.reference(%s)\n", name);
+}
+
+/**
+ * ignorableWhitespaceDebug:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+{
+    char out[40];
+    int i;
+
+    callbacks++;
+    if (noout)
+	return;
+    for (i = 0;(i<len) && (i < 30);i++)
+	out[i] = ch[i];
+    out[i] = 0;
+    fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
+}
+
+/**
+ * processingInstructionDebug:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+                      const xmlChar *data)
+{
+    callbacks++;
+    if (noout)
+	return;
+    if (data != NULL)
+	fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
+		(char *) target, (char *) data);
+    else
+	fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
+		(char *) target);
+}
+
+/**
+ * cdataBlockDebug:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
+	    (char *) value, len);
+}
+
+/**
+ * commentDebug:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.comment(%s)\n", value);
+}
+
+/**
+ * warningDebug:
+ * @ctxt:  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.
+ */
+static void XMLCDECL
+warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (noout)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.warning: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * errorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (noout)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.error: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+/**
+ * fatalErrorDebug:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+    va_list args;
+
+    callbacks++;
+    if (noout)
+	return;
+    va_start(args, msg);
+    fprintf(stdout, "SAX.fatalError: ");
+    vfprintf(stdout, msg, args);
+    va_end(args);
+}
+
+static xmlSAXHandler debugSAXHandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    startElementDebug,
+    endElementDebug,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    1,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
+
+/*
+ * SAX2 specific callbacks
+ */
+/**
+ * startElementNsDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                    const xmlChar *localname,
+                    const xmlChar *prefix,
+                    const xmlChar *URI,
+		    int nb_namespaces,
+		    const xmlChar **namespaces,
+		    int nb_attributes,
+		    int nb_defaulted,
+		    const xmlChar **attributes)
+{
+    int i;
+
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(stdout, ", NULL");
+    else
+	fprintf(stdout, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(stdout, ", NULL");
+    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");
+	    if (namespaces[i] != NULL)
+	        fprintf(stdout, ":%s", namespaces[i]);
+	    i++;
+	    fprintf(stdout, "='%s'", namespaces[i]);
+	}
+    }
+    fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
+    if (attributes != NULL) {
+        for (i = 0;i < nb_attributes * 5;i += 5) {
+	    if (attributes[i + 1] != NULL)
+		fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
+	    else
+		fprintf(stdout, ", %s='", attributes[i]);
+	    fprintf(stdout, "%.4s...', %d", attributes[i + 3],
+		    (int)(attributes[i + 4] - attributes[i + 3]));
+	}
+    }
+    fprintf(stdout, ")\n");
+}
+
+/**
+ * endElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+                  const xmlChar *localname,
+                  const xmlChar *prefix,
+                  const xmlChar *URI)
+{
+    callbacks++;
+    if (noout)
+	return;
+    fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
+    if (prefix == NULL)
+	fprintf(stdout, ", NULL");
+    else
+	fprintf(stdout, ", %s", (char *) prefix);
+    if (URI == NULL)
+	fprintf(stdout, ", NULL)\n");
+    else
+	fprintf(stdout, ", '%s')\n", (char *) URI);
+}
+
+static xmlSAXHandler debugSAX2HandlerStruct = {
+    internalSubsetDebug,
+    isStandaloneDebug,
+    hasInternalSubsetDebug,
+    hasExternalSubsetDebug,
+    resolveEntityDebug,
+    getEntityDebug,
+    entityDeclDebug,
+    notationDeclDebug,
+    attributeDeclDebug,
+    elementDeclDebug,
+    unparsedEntityDeclDebug,
+    setDocumentLocatorDebug,
+    startDocumentDebug,
+    endDocumentDebug,
+    NULL,
+    NULL,
+    referenceDebug,
+    charactersDebug,
+    ignorableWhitespaceDebug,
+    processingInstructionDebug,
+    commentDebug,
+    warningDebug,
+    errorDebug,
+    fatalErrorDebug,
+    getParameterEntityDebug,
+    cdataBlockDebug,
+    externalSubsetDebug,
+    XML_SAX2_MAGIC,
+    NULL,
+    startElementNsDebug,
+    endElementNsDebug,
+    NULL
+};
+
+static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
+
+static void
+testSAX(const char *filename) {
+    xmlSAXHandlerPtr handler;
+    const char *user_data = "user_data"; /* mostly for debugging */
+    xmlParserInputBufferPtr buf = NULL;
+    xmlParserInputPtr inputStream;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlSAXHandlerPtr old_sax = NULL;
+
+    callbacks = 0;
+
+    if (noout) {
+        handler = emptySAXHandler;
+#ifdef LIBXML_SAX1_ENABLED
+    } else if (sax1) {
+        handler = debugSAXHandler;
+#endif
+    } else {
+        handler = debugSAX2Handler;
+    }
+
+    /*
+     * it's not the simplest code but the most generic in term of I/O
+     */
+    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) {
+        goto error;
+    }
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (wxschemas != NULL) {
+        int ret;
+	xmlSchemaValidCtxtPtr vctxt;
+
+	vctxt = xmlSchemaNewValidCtxt(wxschemas);
+	xmlSchemaSetValidErrors(vctxt,
+		(xmlSchemaValidityErrorFunc) fprintf,
+		(xmlSchemaValidityWarningFunc) fprintf,
+		stderr);
+
+	ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
+	                              (void *)user_data);
+	if (repeat == 0) {
+	    if (ret == 0) {
+		fprintf(stderr, "%s validates\n", filename);
+	    } else if (ret > 0) {
+		fprintf(stderr, "%s fails to validate\n", filename);
+		progresult = XMLLINT_ERR_VALID;
+	    } else {
+		fprintf(stderr, "%s validation generated an internal error\n",
+		       filename);
+		progresult = XMLLINT_ERR_VALID;
+	    }
+	}
+	xmlSchemaFreeValidCtxt(vctxt);
+    } else
+#endif
+    {
+	/*
+	 * Create the parser context amd hook the input
+	 */
+	ctxt = xmlNewParserCtxt();
+	if (ctxt == NULL) {
+	    xmlFreeParserInputBuffer(buf);
+	    goto error;
+	}
+	old_sax = ctxt->sax;
+	ctxt->sax = handler;
+	ctxt->userData = (void *) user_data;
+	inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
+	if (inputStream == NULL) {
+	    xmlFreeParserInputBuffer(buf);
+	    goto error;
+	}
+	inputPush(ctxt, inputStream);
+
+	/* do the parsing */
+	xmlParseDocument(ctxt);
+
+	if (ctxt->myDoc != NULL) {
+	    fprintf(stderr, "SAX generated a doc !\n");
+	    xmlFreeDoc(ctxt->myDoc);
+	    ctxt->myDoc = NULL;
+	}
+    }
+
+error:
+    if (ctxt != NULL) {
+        ctxt->sax = old_sax;
+        xmlFreeParserCtxt(ctxt);
+    }
+}
+
+/************************************************************************
+ *									*
+ *			Stream Test processing				*
+ *									*
+ ************************************************************************/
+#ifdef LIBXML_READER_ENABLED
+static void processNode(xmlTextReaderPtr reader) {
+    const xmlChar *name, *value;
+    int type, empty;
+
+    type = xmlTextReaderNodeType(reader);
+    empty = xmlTextReaderIsEmptyElement(reader);
+
+    if (debug) {
+	name = xmlTextReaderConstName(reader);
+	if (name == NULL)
+	    name = BAD_CAST "--";
+
+	value = xmlTextReaderConstValue(reader);
+
+
+	printf("%d %d %s %d %d",
+		xmlTextReaderDepth(reader),
+		type,
+		name,
+		empty,
+		xmlTextReaderHasValue(reader));
+	if (value == NULL)
+	    printf("\n");
+	else {
+	    printf(" %s\n", value);
+	}
+    }
+#ifdef LIBXML_PATTERN_ENABLED
+    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) {
+	    int ret;
+
+	    if (type == XML_READER_TYPE_ELEMENT) {
+		ret = xmlStreamPush(patstream,
+		                    xmlTextReaderConstLocalName(reader),
+				    xmlTextReaderConstNamespaceUri(reader));
+		if (ret < 0) {
+		    fprintf(stderr, "xmlStreamPush() failure\n");
+                    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");
+                    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);
+		if (ret < 0) {
+		    fprintf(stderr, "xmlStreamPop() failure\n");
+                    xmlFreeStreamCtxt(patstream);
+		    patstream = NULL;
+		}
+	    }
+	}
+	if (path != NULL)
+	    xmlFree(path);
+    }
+#endif
+}
+
+static void streamFile(char *filename) {
+    xmlTextReaderPtr reader;
+    int ret;
+#ifdef HAVE_SYS_MMAN_H
+    int fd = -1;
+    struct stat info;
+    const char *base = NULL;
+    xmlParserInputBufferPtr input = NULL;
+
+    if (memory) {
+	if (stat(filename, &info) < 0)
+	    return;
+	if ((fd = open(filename, O_RDONLY)) < 0)
+	    return;
+	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
+	if (base == (void *) MAP_FAILED)
+	    return;
+
+	reader = xmlReaderForMemory(base, info.st_size, filename,
+	                            NULL, options);
+    } else
+#endif
+	reader = xmlReaderForFile(filename, NULL, options);
+#ifdef LIBXML_PATTERN_ENABLED
+    if (pattern != NULL) {
+        patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
+	if (patternc == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Pattern %s failed to compile\n", pattern);
+            progresult = XMLLINT_ERR_SCHEMAPAT;
+	    pattern = NULL;
+	}
+    }
+    if (patternc != NULL) {
+        patstream = xmlPatternGetStreamCtxt(patternc);
+	if (patstream != NULL) {
+	    ret = xmlStreamPush(patstream, NULL, NULL);
+	    if (ret < 0) {
+		fprintf(stderr, "xmlStreamPush() failure\n");
+		xmlFreeStreamCtxt(patstream);
+		patstream = NULL;
+            }
+	}
+    }
+#endif
+
+
+    if (reader != NULL) {
+#ifdef LIBXML_VALID_ENABLED
+	if (valid)
+	    xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
+	else
+#endif /* LIBXML_VALID_ENABLED */
+	    xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
+#ifdef LIBXML_SCHEMAS_ENABLED
+	if (relaxng != NULL) {
+	    if ((timing) && (!repeat)) {
+		startTimer();
+	    }
+	    ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
+	    if (ret < 0) {
+		xmlGenericError(xmlGenericErrorContext,
+			"Relax-NG schema %s failed to compile\n", relaxng);
+		progresult = XMLLINT_ERR_SCHEMACOMP;
+		relaxng = NULL;
+	    }
+	    if ((timing) && (!repeat)) {
+		endTimer("Compiling the schemas");
+	    }
+	}
+	if (schema != NULL) {
+	    if ((timing) && (!repeat)) {
+		startTimer();
+	    }
+	    ret = xmlTextReaderSchemaValidate(reader, schema);
+	    if (ret < 0) {
+		xmlGenericError(xmlGenericErrorContext,
+			"XSD schema %s failed to compile\n", schema);
+		progresult = XMLLINT_ERR_SCHEMACOMP;
+		schema = NULL;
+	    }
+	    if ((timing) && (!repeat)) {
+		endTimer("Compiling the schemas");
+	    }
+	}
+#endif
+
+	/*
+	 * Process all nodes in sequence
+	 */
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+	ret = xmlTextReaderRead(reader);
+	while (ret == 1) {
+	    if ((debug)
+#ifdef LIBXML_PATTERN_ENABLED
+	        || (patternc)
+#endif
+	       )
+		processNode(reader);
+	    ret = xmlTextReaderRead(reader);
+	}
+	if ((timing) && (!repeat)) {
+#ifdef LIBXML_SCHEMAS_ENABLED
+	    if (relaxng != NULL)
+		endTimer("Parsing and validating");
+	    else
+#endif
+#ifdef LIBXML_VALID_ENABLED
+	    if (valid)
+		endTimer("Parsing and validating");
+	    else
+#endif
+	    endTimer("Parsing");
+	}
+
+#ifdef LIBXML_VALID_ENABLED
+	if (valid) {
+	    if (xmlTextReaderIsValid(reader) != 1) {
+		xmlGenericError(xmlGenericErrorContext,
+			"Document %s does not validate\n", filename);
+		progresult = XMLLINT_ERR_VALID;
+	    }
+	}
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+	if ((relaxng != NULL) || (schema != NULL)) {
+	    if (xmlTextReaderIsValid(reader) != 1) {
+		fprintf(stderr, "%s fails to validate\n", filename);
+		progresult = XMLLINT_ERR_VALID;
+	    } else {
+		fprintf(stderr, "%s validates\n", filename);
+	    }
+	}
+#endif
+	/*
+	 * Done, cleanup and status
+	 */
+	xmlFreeTextReader(reader);
+	if (ret != 0) {
+	    fprintf(stderr, "%s : failed to parse\n", filename);
+	    progresult = XMLLINT_ERR_UNCLASS;
+	}
+    } else {
+	fprintf(stderr, "Unable to open %s\n", filename);
+	progresult = XMLLINT_ERR_UNCLASS;
+    }
+#ifdef LIBXML_PATTERN_ENABLED
+    if (patstream != NULL) {
+	xmlFreeStreamCtxt(patstream);
+	patstream = NULL;
+    }
+#endif
+#ifdef HAVE_SYS_MMAN_H
+    if (memory) {
+        xmlFreeParserInputBuffer(input);
+	munmap((char *) base, info.st_size);
+	close(fd);
+    }
+#endif
+}
+
+static void walkDoc(xmlDocPtr doc) {
+    xmlTextReaderPtr reader;
+    int ret;
+
+#ifdef LIBXML_PATTERN_ENABLED
+    xmlNodePtr root;
+    const xmlChar *namespaces[22];
+    int i;
+    xmlNsPtr ns;
+
+    root = xmlDocGetRootElement(doc);
+    for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
+        namespaces[i++] = ns->href;
+        namespaces[i++] = ns->prefix;
+    }
+    namespaces[i++] = NULL;
+    namespaces[i] = NULL;
+
+    if (pattern != NULL) {
+        patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
+	                             0, &namespaces[0]);
+	if (patternc == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Pattern %s failed to compile\n", pattern);
+            progresult = XMLLINT_ERR_SCHEMAPAT;
+	    pattern = NULL;
+	}
+    }
+    if (patternc != NULL) {
+        patstream = xmlPatternGetStreamCtxt(patternc);
+	if (patstream != NULL) {
+	    ret = xmlStreamPush(patstream, NULL, NULL);
+	    if (ret < 0) {
+		fprintf(stderr, "xmlStreamPush() failure\n");
+		xmlFreeStreamCtxt(patstream);
+		patstream = NULL;
+            }
+	}
+    }
+#endif /* LIBXML_PATTERN_ENABLED */
+    reader = xmlReaderWalker(doc);
+    if (reader != NULL) {
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+	ret = xmlTextReaderRead(reader);
+	while (ret == 1) {
+	    if ((debug)
+#ifdef LIBXML_PATTERN_ENABLED
+	        || (patternc)
+#endif
+	       )
+		processNode(reader);
+	    ret = xmlTextReaderRead(reader);
+	}
+	if ((timing) && (!repeat)) {
+	    endTimer("walking through the doc");
+	}
+	xmlFreeTextReader(reader);
+	if (ret != 0) {
+	    fprintf(stderr, "failed to walk through the doc\n");
+	    progresult = XMLLINT_ERR_UNCLASS;
+	}
+    } else {
+	fprintf(stderr, "Failed to crate a reader from the document\n");
+	progresult = XMLLINT_ERR_UNCLASS;
+    }
+#ifdef LIBXML_PATTERN_ENABLED
+    if (patstream != NULL) {
+	xmlFreeStreamCtxt(patstream);
+	patstream = NULL;
+    }
+#endif
+}
+#endif /* LIBXML_READER_ENABLED */
+
+#ifdef LIBXML_XPATH_ENABLED
+/************************************************************************
+ *									*
+ *			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;
+#ifdef LIBXML_TREE_ENABLED
+    xmlDocPtr tmp;
+#endif /* LIBXML_TREE_ENABLED */
+
+    if ((timing) && (!repeat))
+	startTimer();
+
+
+#ifdef LIBXML_TREE_ENABLED
+    if (filename == NULL) {
+	if (generate) {
+	    xmlNodePtr n;
+
+	    doc = xmlNewDoc(BAD_CAST "1.0");
+	    n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
+	    xmlNodeSetContent(n, BAD_CAST "abc");
+	    xmlDocSetRootElement(doc, n);
+	}
+    }
+#endif /* LIBXML_TREE_ENABLED */
+#ifdef LIBXML_HTML_ENABLED
+#ifdef LIBXML_PUSH_ENABLED
+    else if ((html) && (push)) {
+        FILE *f;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+	f = fopen(filename, "rb");
+#else
+	f = fopen(filename, "r");
+#endif
+        if (f != NULL) {
+            int res, size = 3;
+            char chars[4096];
+            htmlParserCtxtPtr ctxt;
+
+            /* if (repeat) */
+                size = 4096;
+            res = fread(chars, 1, 4, f);
+            if (res > 0) {
+                ctxt = htmlCreatePushParserCtxt(NULL, NULL,
+                            chars, res, filename, XML_CHAR_ENCODING_NONE);
+                while ((res = fread(chars, 1, size, f)) > 0) {
+                    htmlParseChunk(ctxt, chars, res, 0);
+                }
+                htmlParseChunk(ctxt, chars, 0, 1);
+                doc = ctxt->myDoc;
+                htmlFreeParserCtxt(ctxt);
+            }
+            fclose(f);
+        }
+    }
+#endif /* LIBXML_PUSH_ENABLED */
+#ifdef HAVE_SYS_MMAN_H
+    else if ((html) && (memory)) {
+	int fd;
+	struct stat info;
+	const char *base;
+	if (stat(filename, &info) < 0)
+	    return;
+	if ((fd = open(filename, O_RDONLY)) < 0)
+	    return;
+	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
+	if (base == (void *) MAP_FAILED)
+	    return;
+
+	doc = htmlReadMemory((char *) base, info.st_size, filename,
+	                     NULL, options);
+
+	munmap((char *) base, info.st_size);
+	close(fd);
+    }
+#endif
+    else if (html) {
+	doc = htmlReadFile(filename, NULL, options);
+    }
+#endif /* LIBXML_HTML_ENABLED */
+    else {
+#ifdef LIBXML_PUSH_ENABLED
+	/*
+	 * build an XML tree from a string;
+	 */
+	if (push) {
+	    FILE *f;
+
+	    /* '-' Usually means stdin -<sven@zen.org> */
+	    if ((filename[0] == '-') && (filename[1] == 0)) {
+	      f = stdin;
+	    } else {
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+		f = fopen(filename, "rb");
+#else
+		f = fopen(filename, "r");
+#endif
+	    }
+	    if (f != NULL) {
+		int ret;
+	        int res, size = 1024;
+	        char chars[1024];
+                xmlParserCtxtPtr ctxt;
+
+		/* if (repeat) size = 1024; */
+		res = fread(chars, 1, 4, f);
+		if (res > 0) {
+		    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
+		                chars, res, filename);
+		    xmlCtxtUseOptions(ctxt, options);
+		    while ((res = fread(chars, 1, size, f)) > 0) {
+			xmlParseChunk(ctxt, chars, res, 0);
+		    }
+		    xmlParseChunk(ctxt, chars, 0, 1);
+		    doc = ctxt->myDoc;
+		    ret = ctxt->wellFormed;
+		    xmlFreeParserCtxt(ctxt);
+		    if (!ret) {
+			xmlFreeDoc(doc);
+			doc = NULL;
+		    }
+	        }
+                if (f != stdin)
+                    fclose(f);
+	    }
+	} else
+#endif /* LIBXML_PUSH_ENABLED */
+        if (testIO) {
+	    if ((filename[0] == '-') && (filename[1] == 0)) {
+	        doc = xmlReadFd(0, NULL, NULL, options);
+	    } else {
+	        FILE *f;
+
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+		f = fopen(filename, "rb");
+#else
+		f = fopen(filename, "r");
+#endif
+		if (f != NULL) {
+		    if (rectxt == NULL)
+			doc = xmlReadIO((xmlInputReadCallback) myRead,
+					(xmlInputCloseCallback) myClose, f,
+					filename, NULL, options);
+		    else
+			doc = xmlCtxtReadIO(rectxt,
+			                (xmlInputReadCallback) myRead,
+					(xmlInputCloseCallback) myClose, f,
+					filename, NULL, options);
+		} else
+		    doc = NULL;
+	    }
+	} else if (htmlout) {
+	    xmlParserCtxtPtr ctxt;
+
+	    if (rectxt == NULL)
+		ctxt = xmlNewParserCtxt();
+	    else
+	        ctxt = rectxt;
+	    if (ctxt == NULL) {
+	        doc = NULL;
+	    } else {
+	        ctxt->sax->error = xmlHTMLError;
+	        ctxt->sax->warning = xmlHTMLWarning;
+	        ctxt->vctxt.error = xmlHTMLValidityError;
+	        ctxt->vctxt.warning = xmlHTMLValidityWarning;
+
+		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+
+		if (rectxt == NULL)
+		    xmlFreeParserCtxt(ctxt);
+	    }
+#ifdef HAVE_SYS_MMAN_H
+	} else if (memory) {
+	    int fd;
+	    struct stat info;
+	    const char *base;
+	    if (stat(filename, &info) < 0)
+		return;
+	    if ((fd = open(filename, O_RDONLY)) < 0)
+		return;
+	    base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
+	    if (base == (void *) MAP_FAILED)
+	        return;
+
+	    if (rectxt == NULL)
+		doc = xmlReadMemory((char *) base, info.st_size,
+		                    filename, NULL, options);
+	    else
+		doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
+			                filename, NULL, options);
+
+	    munmap((char *) base, info.st_size);
+	    close(fd);
+#endif
+#ifdef LIBXML_VALID_ENABLED
+	} else if (valid) {
+	    xmlParserCtxtPtr ctxt = NULL;
+
+	    if (rectxt == NULL)
+		ctxt = xmlNewParserCtxt();
+	    else
+	        ctxt = rectxt;
+	    if (ctxt == NULL) {
+	        doc = NULL;
+	    } else {
+		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+
+		if (ctxt->valid == 0)
+		    progresult = XMLLINT_ERR_RDFILE;
+		if (rectxt == NULL)
+		    xmlFreeParserCtxt(ctxt);
+	    }
+#endif /* LIBXML_VALID_ENABLED */
+	} else {
+	    if (rectxt != NULL)
+	        doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
+	    else {
+#ifdef LIBXML_SAX1_ENABLED
+                if (sax1)
+		    doc = xmlParseFile(filename);
+		else
+#endif /* LIBXML_SAX1_ENABLED */
+		doc = xmlReadFile(filename, NULL, options);
+	    }
+	}
+    }
+
+    /*
+     * If we don't have a document we might as well give up.  Do we
+     * want an error message here?  <sven@zen.org> */
+    if (doc == NULL) {
+	progresult = XMLLINT_ERR_UNCLASS;
+	return;
+    }
+
+    if ((timing) && (!repeat)) {
+	endTimer("Parsing");
+    }
+
+    /*
+     * Remove DOCTYPE nodes
+     */
+    if (dropdtd) {
+	xmlDtdPtr dtd;
+
+	dtd = xmlGetIntSubset(doc);
+	if (dtd != NULL) {
+	    xmlUnlinkNode((xmlNodePtr)dtd);
+	    xmlFreeDtd(dtd);
+	}
+    }
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+    if (xinclude) {
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+	if (xmlXIncludeProcessFlags(doc, options) < 0)
+	    progresult = XMLLINT_ERR_UNCLASS;
+	if ((timing) && (!repeat)) {
+	    endTimer("Xinclude processing");
+	}
+    }
+#endif
+
+#ifdef LIBXML_XPATH_ENABLED
+    if (xpathquery != NULL) {
+        doXPathQuery(doc, xpathquery);
+    }
+#endif
+
+#ifdef LIBXML_DEBUG_ENABLED
+#ifdef LIBXML_XPATH_ENABLED
+    /*
+     * shell interaction
+     */
+    if (shell) {
+        xmlXPathOrderDocElems(doc);
+        xmlShell(doc, filename, xmlShellReadline, stdout);
+    }
+#endif
+#endif
+
+#ifdef LIBXML_TREE_ENABLED
+    /*
+     * test intermediate copy if needed.
+     */
+    if (copy) {
+        tmp = doc;
+	if (timing) {
+	    startTimer();
+	}
+	doc = xmlCopyDoc(doc, 1);
+	if (timing) {
+	    endTimer("Copying");
+	}
+	if (timing) {
+	    startTimer();
+	}
+	xmlFreeDoc(tmp);
+	if (timing) {
+	    endTimer("Freeing original");
+	}
+    }
+#endif /* LIBXML_TREE_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+    if ((insert) && (!html)) {
+        const xmlChar* list[256];
+	int nb, i;
+	xmlNodePtr node;
+
+	if (doc->children != NULL) {
+	    node = doc->children;
+	    while ((node != NULL) && (node->last == NULL)) node = node->next;
+	    if (node != NULL) {
+		nb = xmlValidGetValidElements(node->last, NULL, list, 256);
+		if (nb < 0) {
+		    fprintf(stderr, "could not get valid list of elements\n");
+		} else if (nb == 0) {
+		    fprintf(stderr, "No element can be inserted under root\n");
+		} else {
+		    fprintf(stderr, "%d element types can be inserted under root:\n",
+		           nb);
+		    for (i = 0;i < nb;i++) {
+			 fprintf(stderr, "%s\n", (char *) list[i]);
+		    }
+		}
+	    }
+	}
+    }else
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_READER_ENABLED
+    if (walker) {
+        walkDoc(doc);
+    }
+#endif /* LIBXML_READER_ENABLED */
+#ifdef LIBXML_OUTPUT_ENABLED
+    if (noout == 0) {
+        int ret;
+
+	/*
+	 * print it.
+	 */
+#ifdef LIBXML_DEBUG_ENABLED
+	if (!debug) {
+#endif
+	    if ((timing) && (!repeat)) {
+		startTimer();
+	    }
+#ifdef LIBXML_HTML_ENABLED
+            if ((html) && (!xmlout)) {
+		if (compress) {
+		    htmlSaveFile(output ? output : "-", doc);
+		}
+		else if (encoding != NULL) {
+		    if ( format ) {
+			htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
+		    }
+		    else {
+			htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
+		    }
+		}
+		else if (format) {
+		    htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
+		}
+		else {
+		    FILE *out;
+		    if (output == NULL)
+			out = stdout;
+		    else {
+			out = fopen(output,"wb");
+		    }
+		    if (out != NULL) {
+			if (htmlDocDump(out, doc) < 0)
+			    progresult = XMLLINT_ERR_OUT;
+
+			if (output != NULL)
+			    fclose(out);
+		    } else {
+			fprintf(stderr, "failed to open %s\n", output);
+			progresult = XMLLINT_ERR_OUT;
+		    }
+		}
+		if ((timing) && (!repeat)) {
+		    endTimer("Saving");
+		}
+	    } else
+#endif
+#ifdef LIBXML_C14N_ENABLED
+            if (canonical) {
+	        xmlChar *result = NULL;
+		int size;
+
+		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
+		if (size >= 0) {
+		    write(1, result, size);
+		    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) {
+		    write(1, result, size);
+		    xmlFree(result);
+		} else {
+		    fprintf(stderr, "Failed to canonicalize\n");
+		    progresult = XMLLINT_ERR_OUT;
+		}
+	    } else
+            if (exc_canonical) {
+	        xmlChar *result = NULL;
+		int size;
+
+		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
+		if (size >= 0) {
+		    write(1, result, size);
+		    xmlFree(result);
+		} else {
+		    fprintf(stderr, "Failed to canonicalize\n");
+		    progresult = XMLLINT_ERR_OUT;
+		}
+	    } else
+#endif
+#ifdef HAVE_SYS_MMAN_H
+	    if (memory) {
+		xmlChar *result;
+		int len;
+
+		if (encoding != NULL) {
+		    if ( format ) {
+		        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
+		    } else {
+			xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
+		    }
+		} else {
+		    if (format)
+			xmlDocDumpFormatMemory(doc, &result, &len, 1);
+		    else
+			xmlDocDumpMemory(doc, &result, &len);
+		}
+		if (result == NULL) {
+		    fprintf(stderr, "Failed to save\n");
+		    progresult = XMLLINT_ERR_OUT;
+		} else {
+		    write(1, result, len);
+		    xmlFree(result);
+		}
+
+	    } else
+#endif /* HAVE_SYS_MMAN_H */
+	    if (compress) {
+		xmlSaveFile(output ? output : "-", doc);
+	    } else if (oldout) {
+	        if (encoding != NULL) {
+		    if ( format ) {
+			ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
+						   encoding, 1);
+		    }
+		    else {
+			ret = xmlSaveFileEnc(output ? output : "-", doc,
+			                     encoding);
+		    }
+		    if (ret < 0) {
+			fprintf(stderr, "failed save to %s\n",
+				output ? output : "-");
+			progresult = XMLLINT_ERR_OUT;
+		    }
+		} else if (format) {
+		    ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
+		    if (ret < 0) {
+			fprintf(stderr, "failed save to %s\n",
+				output ? output : "-");
+			progresult = XMLLINT_ERR_OUT;
+		    }
+		} else {
+		    FILE *out;
+		    if (output == NULL)
+			out = stdout;
+		    else {
+			out = fopen(output,"wb");
+		    }
+		    if (out != NULL) {
+			if (xmlDocDump(out, doc) < 0)
+			    progresult = XMLLINT_ERR_OUT;
+
+			if (output != NULL)
+			    fclose(out);
+		    } else {
+			fprintf(stderr, "failed to open %s\n", output);
+			progresult = XMLLINT_ERR_OUT;
+		    }
+		}
+	    } else {
+	        xmlSaveCtxtPtr ctxt;
+		int saveOpts = 0;
+
+                if (format)
+		    saveOpts |= XML_SAVE_FORMAT;
+
+#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);
+		else
+		    ctxt = xmlSaveToFilename(output, encoding, saveOpts);
+
+		if (ctxt != NULL) {
+		    if (xmlSaveDoc(ctxt, doc) < 0) {
+			fprintf(stderr, "failed save to %s\n",
+				output ? output : "-");
+			progresult = XMLLINT_ERR_OUT;
+		    }
+		    xmlSaveClose(ctxt);
+		} else {
+		    progresult = XMLLINT_ERR_OUT;
+		}
+	    }
+	    if ((timing) && (!repeat)) {
+		endTimer("Saving");
+	    }
+#ifdef LIBXML_DEBUG_ENABLED
+	} else {
+	    FILE *out;
+	    if (output == NULL)
+	        out = stdout;
+	    else {
+		out = fopen(output,"wb");
+	    }
+	    if (out != NULL) {
+		xmlDebugDumpDocument(out, doc);
+
+		if (output != NULL)
+		    fclose(out);
+	    } else {
+		fprintf(stderr, "failed to open %s\n", output);
+		progresult = XMLLINT_ERR_OUT;
+	    }
+	}
+#endif
+    }
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+    /*
+     * A posteriori validation test
+     */
+    if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
+	xmlDtdPtr dtd;
+
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+	if (dtdvalid != NULL)
+	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
+	else
+	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
+	if ((timing) && (!repeat)) {
+	    endTimer("Parsing DTD");
+	}
+	if (dtd == NULL) {
+	    if (dtdvalid != NULL)
+		xmlGenericError(xmlGenericErrorContext,
+			"Could not parse DTD %s\n", dtdvalid);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+			"Could not parse DTD %s\n", dtdvalidfpi);
+	    progresult = XMLLINT_ERR_DTD;
+	} else {
+	    xmlValidCtxtPtr cvp;
+
+	    if ((cvp = xmlNewValidCtxt()) == NULL) {
+		xmlGenericError(xmlGenericErrorContext,
+			"Couldn't allocate validation context\n");
+		exit(-1);
+	    }
+	    cvp->userData = (void *) stderr;
+	    cvp->error    = (xmlValidityErrorFunc) fprintf;
+	    cvp->warning  = (xmlValidityWarningFunc) fprintf;
+
+	    if ((timing) && (!repeat)) {
+		startTimer();
+	    }
+	    if (!xmlValidateDtd(cvp, doc, dtd)) {
+		if (dtdvalid != NULL)
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Document %s does not validate against %s\n",
+			    filename, dtdvalid);
+		else
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Document %s does not validate against %s\n",
+			    filename, dtdvalidfpi);
+		progresult = XMLLINT_ERR_VALID;
+	    }
+	    if ((timing) && (!repeat)) {
+		endTimer("Validating against DTD");
+	    }
+	    xmlFreeValidCtxt(cvp);
+	    xmlFreeDtd(dtd);
+	}
+    } else if (postvalid) {
+	xmlValidCtxtPtr cvp;
+
+	if ((cvp = xmlNewValidCtxt()) == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Couldn't allocate validation context\n");
+	    exit(-1);
+	}
+
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+	cvp->userData = (void *) stderr;
+	cvp->error    = (xmlValidityErrorFunc) fprintf;
+	cvp->warning  = (xmlValidityWarningFunc) fprintf;
+	if (!xmlValidateDocument(cvp, doc)) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Document %s does not validate\n", filename);
+	    progresult = XMLLINT_ERR_VALID;
+	}
+	if ((timing) && (!repeat)) {
+	    endTimer("Validating");
+	}
+	xmlFreeValidCtxt(cvp);
+    }
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMATRON_ENABLED
+    if (wxschematron != NULL) {
+	xmlSchematronValidCtxtPtr ctxt;
+	int ret;
+	int flag;
+
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+
+	if (debug)
+	    flag = XML_SCHEMATRON_OUT_XML;
+	else
+	    flag = XML_SCHEMATRON_OUT_TEXT;
+	if (noout)
+	    flag |= XML_SCHEMATRON_OUT_QUIET;
+	ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
+#if 0
+	xmlSchematronSetValidErrors(ctxt,
+		(xmlSchematronValidityErrorFunc) fprintf,
+		(xmlSchematronValidityWarningFunc) fprintf,
+		stderr);
+#endif
+	ret = xmlSchematronValidateDoc(ctxt, doc);
+	if (ret == 0) {
+	    fprintf(stderr, "%s validates\n", filename);
+	} else if (ret > 0) {
+	    fprintf(stderr, "%s fails to validate\n", filename);
+	    progresult = XMLLINT_ERR_VALID;
+	} else {
+	    fprintf(stderr, "%s validation generated an internal error\n",
+		   filename);
+	    progresult = XMLLINT_ERR_VALID;
+	}
+	xmlSchematronFreeValidCtxt(ctxt);
+	if ((timing) && (!repeat)) {
+	    endTimer("Validating");
+	}
+    }
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (relaxngschemas != NULL) {
+	xmlRelaxNGValidCtxtPtr ctxt;
+	int ret;
+
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+
+	ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
+	xmlRelaxNGSetValidErrors(ctxt,
+		(xmlRelaxNGValidityErrorFunc) fprintf,
+		(xmlRelaxNGValidityWarningFunc) fprintf,
+		stderr);
+	ret = xmlRelaxNGValidateDoc(ctxt, doc);
+	if (ret == 0) {
+	    fprintf(stderr, "%s validates\n", filename);
+	} else if (ret > 0) {
+	    fprintf(stderr, "%s fails to validate\n", filename);
+	    progresult = XMLLINT_ERR_VALID;
+	} else {
+	    fprintf(stderr, "%s validation generated an internal error\n",
+		   filename);
+	    progresult = XMLLINT_ERR_VALID;
+	}
+	xmlRelaxNGFreeValidCtxt(ctxt);
+	if ((timing) && (!repeat)) {
+	    endTimer("Validating");
+	}
+    } else if (wxschemas != NULL) {
+	xmlSchemaValidCtxtPtr ctxt;
+	int ret;
+
+	if ((timing) && (!repeat)) {
+	    startTimer();
+	}
+
+	ctxt = xmlSchemaNewValidCtxt(wxschemas);
+	xmlSchemaSetValidErrors(ctxt,
+		(xmlSchemaValidityErrorFunc) fprintf,
+		(xmlSchemaValidityWarningFunc) fprintf,
+		stderr);
+	ret = xmlSchemaValidateDoc(ctxt, doc);
+	if (ret == 0) {
+	    fprintf(stderr, "%s validates\n", filename);
+	} else if (ret > 0) {
+	    fprintf(stderr, "%s fails to validate\n", filename);
+	    progresult = XMLLINT_ERR_VALID;
+	} else {
+	    fprintf(stderr, "%s validation generated an internal error\n",
+		   filename);
+	    progresult = XMLLINT_ERR_VALID;
+	}
+	xmlSchemaFreeValidCtxt(ctxt);
+	if ((timing) && (!repeat)) {
+	    endTimer("Validating");
+	}
+    }
+#endif
+
+#ifdef LIBXML_DEBUG_ENABLED
+#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+    if ((debugent) && (!html))
+	xmlDebugDumpEntities(stderr, doc);
+#endif
+#endif
+
+    /*
+     * free it.
+     */
+    if ((timing) && (!repeat)) {
+	startTimer();
+    }
+    xmlFreeDoc(doc);
+    if ((timing) && (!repeat)) {
+	endTimer("Freeing");
+    }
+}
+
+/************************************************************************
+ *									*
+ *			Usage and Main					*
+ *									*
+ ************************************************************************/
+
+static void showVersion(const char *name) {
+    fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
+    fprintf(stderr, "   compiled with: ");
+    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
+    if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
+    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
+    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
+    if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
+    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_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_ZLIB)) fprintf(stderr, "Zlib ");
+    fprintf(stderr, "\n");
+}
+
+static void usage(const char *name) {
+    printf("Usage : %s [options] XMLfiles ...\n", name);
+#ifdef LIBXML_OUTPUT_ENABLED
+    printf("\tParse the XML files and output the result of the parsing\n");
+#else
+    printf("\tParse the XML files\n");
+#endif /* LIBXML_OUTPUT_ENABLED */
+    printf("\t--version : display the version of the XML library used\n");
+#ifdef LIBXML_DEBUG_ENABLED
+    printf("\t--debug : dump a debug tree of the in-memory document\n");
+    printf("\t--shell : run a navigating shell\n");
+    printf("\t--debugent : debug the entities defined in the document\n");
+#else
+#ifdef LIBXML_READER_ENABLED
+    printf("\t--debug : dump the nodes content when using --stream\n");
+#endif /* LIBXML_READER_ENABLED */
+#endif
+#ifdef LIBXML_TREE_ENABLED
+    printf("\t--copy : used to test the internal copy implementation\n");
+#endif /* LIBXML_TREE_ENABLED */
+    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--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");
+    printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
+    printf("\t--nocompact : do not generate compact text nodes\n");
+    printf("\t--htmlout : output results as HTML\n");
+    printf("\t--nowrap : do not put HTML doc wrapper\n");
+#ifdef LIBXML_VALID_ENABLED
+    printf("\t--valid : validate the document in addition to std well-formed check\n");
+    printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
+    printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
+    printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
+#endif /* LIBXML_VALID_ENABLED */
+    printf("\t--timing : print some timings\n");
+    printf("\t--output file or -o file: save to a given file\n");
+    printf("\t--repeat : repeat 100 times, for timing or profiling\n");
+    printf("\t--insert : ad-hoc test for valid insertions\n");
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef HAVE_ZLIB_H
+    printf("\t--compress : turn on gzip compression of output\n");
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
+#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");
+#endif
+#ifdef LIBXML_PUSH_ENABLED
+    printf("\t--push : use the push mode of the parser\n");
+#endif /* LIBXML_PUSH_ENABLED */
+#ifdef HAVE_SYS_MMAN_H
+    printf("\t--memory : parse from memory\n");
+#endif
+    printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
+    printf("\t--nowarning : do not emit warnings from parser/validator\n");
+    printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
+    printf("\t--nocdata : replace cdata section with text nodes\n");
+#ifdef LIBXML_OUTPUT_ENABLED
+    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");
+#endif /* LIBXML_OUTPUT_ENABLED */
+    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 */
+    printf("\t--nsclean : remove redundant namespace declarations\n");
+    printf("\t--testIO : test user I/O support\n");
+#ifdef LIBXML_CATALOG_ENABLED
+    printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
+    printf("\t             otherwise XML Catalogs starting from \n");
+    printf("\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
+    printf("\t--nocatalogs: deactivate all catalogs\n");
+#endif
+    printf("\t--auto : generate a small doc on the fly\n");
+#ifdef LIBXML_XINCLUDE_ENABLED
+    printf("\t--xinclude : do XInclude processing\n");
+    printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
+    printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
+#endif
+    printf("\t--loaddtd : fetch external DTD\n");
+    printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
+#ifdef LIBXML_READER_ENABLED
+    printf("\t--stream : use the streaming interface to process very large files\n");
+    printf("\t--walker : create a reader and walk though the resulting doc\n");
+#endif /* LIBXML_READER_ENABLED */
+#ifdef LIBXML_PATTERN_ENABLED
+    printf("\t--pattern pattern_value : test the pattern support\n");
+#endif
+    printf("\t--chkregister : verify the node registration code\n");
+#ifdef LIBXML_SCHEMAS_ENABLED
+    printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
+    printf("\t--schema schema : do validation against the WXS schema\n");
+#endif
+#ifdef LIBXML_SCHEMATRON_ENABLED
+    printf("\t--schematron schema : do validation against a schematron\n");
+#endif
+#ifdef LIBXML_SAX1_ENABLED
+    printf("\t--sax1: use the old SAX1 interfaces for processing\n");
+#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");
+}
+
+static void registerNode(xmlNodePtr node)
+{
+    node->_private = malloc(sizeof(long));
+    *(long*)node->_private = (long) 0x81726354;
+    nbregister++;
+}
+
+static void deregisterNode(xmlNodePtr node)
+{
+    assert(node->_private != NULL);
+    assert(*(long*)node->_private == (long) 0x81726354);
+    free(node->_private);
+    nbregister--;
+}
+
+int
+main(int argc, char **argv) {
+    int i, acount;
+    int files = 0;
+    int version = 0;
+    const char* indent;
+
+    if (argc <= 1) {
+	usage(argv[0]);
+	return(1);
+    }
+    LIBXML_TEST_VERSION
+    for (i = 1; i < argc ; i++) {
+	if (!strcmp(argv[i], "-"))
+	    break;
+
+	if (argv[i][0] != '-')
+	    continue;
+	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+	    debug++;
+	else
+#ifdef LIBXML_DEBUG_ENABLED
+	if ((!strcmp(argv[i], "-shell")) ||
+	         (!strcmp(argv[i], "--shell"))) {
+	    shell++;
+            noout = 1;
+        } else
+#endif
+#ifdef LIBXML_TREE_ENABLED
+	if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
+	    copy++;
+	else
+#endif /* LIBXML_TREE_ENABLED */
+	if ((!strcmp(argv[i], "-recover")) ||
+	         (!strcmp(argv[i], "--recover"))) {
+	    recovery++;
+	    options |= XML_PARSE_RECOVER;
+	} else if ((!strcmp(argv[i], "-huge")) ||
+	         (!strcmp(argv[i], "--huge"))) {
+	    options |= XML_PARSE_HUGE;
+	} else if ((!strcmp(argv[i], "-noent")) ||
+	         (!strcmp(argv[i], "--noent"))) {
+	    noent++;
+	    options |= XML_PARSE_NOENT;
+	} else if ((!strcmp(argv[i], "-nsclean")) ||
+	         (!strcmp(argv[i], "--nsclean"))) {
+	    options |= XML_PARSE_NSCLEAN;
+	} else if ((!strcmp(argv[i], "-nocdata")) ||
+	         (!strcmp(argv[i], "--nocdata"))) {
+	    options |= XML_PARSE_NOCDATA;
+	} else if ((!strcmp(argv[i], "-nodict")) ||
+	         (!strcmp(argv[i], "--nodict"))) {
+	    options |= XML_PARSE_NODICT;
+	} else if ((!strcmp(argv[i], "-version")) ||
+	         (!strcmp(argv[i], "--version"))) {
+	    showVersion(argv[0]);
+	    version = 1;
+	} else if ((!strcmp(argv[i], "-noout")) ||
+	         (!strcmp(argv[i], "--noout")))
+	    noout++;
+#ifdef LIBXML_OUTPUT_ENABLED
+	else if ((!strcmp(argv[i], "-o")) ||
+	         (!strcmp(argv[i], "-output")) ||
+	         (!strcmp(argv[i], "--output"))) {
+	    i++;
+	    output = argv[i];
+	}
+#endif /* LIBXML_OUTPUT_ENABLED */
+	else if ((!strcmp(argv[i], "-htmlout")) ||
+	         (!strcmp(argv[i], "--htmlout")))
+	    htmlout++;
+	else if ((!strcmp(argv[i], "-nowrap")) ||
+	         (!strcmp(argv[i], "--nowrap")))
+	    nowrap++;
+#ifdef LIBXML_HTML_ENABLED
+	else if ((!strcmp(argv[i], "-html")) ||
+	         (!strcmp(argv[i], "--html"))) {
+	    html++;
+        }
+	else if ((!strcmp(argv[i], "-xmlout")) ||
+	         (!strcmp(argv[i], "--xmlout"))) {
+	    xmlout++;
+        }
+#endif /* LIBXML_HTML_ENABLED */
+	else if ((!strcmp(argv[i], "-loaddtd")) ||
+	         (!strcmp(argv[i], "--loaddtd"))) {
+	    loaddtd++;
+	    options |= XML_PARSE_DTDLOAD;
+	} else if ((!strcmp(argv[i], "-dtdattr")) ||
+	         (!strcmp(argv[i], "--dtdattr"))) {
+	    loaddtd++;
+	    dtdattrs++;
+	    options |= XML_PARSE_DTDATTR;
+	}
+#ifdef LIBXML_VALID_ENABLED
+	else if ((!strcmp(argv[i], "-valid")) ||
+	         (!strcmp(argv[i], "--valid"))) {
+	    valid++;
+	    options |= XML_PARSE_DTDVALID;
+	} else if ((!strcmp(argv[i], "-postvalid")) ||
+	         (!strcmp(argv[i], "--postvalid"))) {
+	    postvalid++;
+	    loaddtd++;
+	    options |= XML_PARSE_DTDLOAD;
+	} else if ((!strcmp(argv[i], "-dtdvalid")) ||
+	         (!strcmp(argv[i], "--dtdvalid"))) {
+	    i++;
+	    dtdvalid = argv[i];
+	    loaddtd++;
+	    options |= XML_PARSE_DTDLOAD;
+	} else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
+	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
+	    i++;
+	    dtdvalidfpi = argv[i];
+	    loaddtd++;
+	    options |= XML_PARSE_DTDLOAD;
+        }
+#endif /* LIBXML_VALID_ENABLED */
+	else if ((!strcmp(argv[i], "-dropdtd")) ||
+	         (!strcmp(argv[i], "--dropdtd")))
+	    dropdtd++;
+	else if ((!strcmp(argv[i], "-insert")) ||
+	         (!strcmp(argv[i], "--insert")))
+	    insert++;
+	else if ((!strcmp(argv[i], "-timing")) ||
+	         (!strcmp(argv[i], "--timing")))
+	    timing++;
+	else if ((!strcmp(argv[i], "-auto")) ||
+	         (!strcmp(argv[i], "--auto")))
+	    generate++;
+	else if ((!strcmp(argv[i], "-repeat")) ||
+	         (!strcmp(argv[i], "--repeat"))) {
+	    if (repeat)
+	        repeat *= 10;
+	    else
+	        repeat = 100;
+	}
+#ifdef LIBXML_PUSH_ENABLED
+	else if ((!strcmp(argv[i], "-push")) ||
+	         (!strcmp(argv[i], "--push")))
+	    push++;
+#endif /* LIBXML_PUSH_ENABLED */
+#ifdef HAVE_SYS_MMAN_H
+	else if ((!strcmp(argv[i], "-memory")) ||
+	         (!strcmp(argv[i], "--memory")))
+	    memory++;
+#endif
+	else if ((!strcmp(argv[i], "-testIO")) ||
+	         (!strcmp(argv[i], "--testIO")))
+	    testIO++;
+#ifdef LIBXML_XINCLUDE_ENABLED
+	else if ((!strcmp(argv[i], "-xinclude")) ||
+	         (!strcmp(argv[i], "--xinclude"))) {
+	    xinclude++;
+	    options |= XML_PARSE_XINCLUDE;
+	}
+	else if ((!strcmp(argv[i], "-noxincludenode")) ||
+	         (!strcmp(argv[i], "--noxincludenode"))) {
+	    xinclude++;
+	    options |= XML_PARSE_XINCLUDE;
+	    options |= XML_PARSE_NOXINCNODE;
+	}
+	else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
+	         (!strcmp(argv[i], "--nofixup-base-uris"))) {
+	    xinclude++;
+	    options |= XML_PARSE_XINCLUDE;
+	    options |= XML_PARSE_NOBASEFIX;
+	}
+#endif
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef HAVE_ZLIB_H
+	else if ((!strcmp(argv[i], "-compress")) ||
+	         (!strcmp(argv[i], "--compress"))) {
+	    compress++;
+	    xmlSetCompressMode(9);
+        }
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
+	else if ((!strcmp(argv[i], "-nowarning")) ||
+	         (!strcmp(argv[i], "--nowarning"))) {
+	    xmlGetWarningsDefaultValue = 0;
+	    xmlPedanticParserDefault(0);
+	    options |= XML_PARSE_NOWARNING;
+        }
+	else if ((!strcmp(argv[i], "-pedantic")) ||
+	         (!strcmp(argv[i], "--pedantic"))) {
+	    xmlGetWarningsDefaultValue = 1;
+	    xmlPedanticParserDefault(1);
+	    options |= XML_PARSE_PEDANTIC;
+        }
+#ifdef LIBXML_DEBUG_ENABLED
+	else if ((!strcmp(argv[i], "-debugent")) ||
+		 (!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")) ||
+		 (!strcmp(argv[i], "--catalogs"))) {
+	    catalogs++;
+	} else if ((!strcmp(argv[i], "-nocatalogs")) ||
+		 (!strcmp(argv[i], "--nocatalogs"))) {
+	    nocatalogs++;
+	}
+#endif
+	else if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    encoding = argv[i];
+	    /*
+	     * OK it's for testing purposes
+	     */
+	    xmlAddEncodingAlias("UTF-8", "DVEnc");
+        }
+	else if ((!strcmp(argv[i], "-noblanks")) ||
+	         (!strcmp(argv[i], "--noblanks"))) {
+	     noblanks++;
+	     xmlKeepBlanksDefault(0);
+        }
+	else if ((!strcmp(argv[i], "-maxmem")) ||
+	         (!strcmp(argv[i], "--maxmem"))) {
+	     i++;
+	     if (sscanf(argv[i], "%d", &maxmem) == 1) {
+	         xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
+		             myStrdupFunc);
+	     } else {
+	         maxmem = 0;
+	     }
+        }
+	else if ((!strcmp(argv[i], "-format")) ||
+	         (!strcmp(argv[i], "--format"))) {
+	     noblanks++;
+#ifdef LIBXML_OUTPUT_ENABLED
+	     format++;
+#endif /* LIBXML_OUTPUT_ENABLED */
+	     xmlKeepBlanksDefault(0);
+	}
+#ifdef LIBXML_READER_ENABLED
+	else if ((!strcmp(argv[i], "-stream")) ||
+	         (!strcmp(argv[i], "--stream"))) {
+	     stream++;
+	}
+	else if ((!strcmp(argv[i], "-walker")) ||
+	         (!strcmp(argv[i], "--walker"))) {
+	     walker++;
+             noout++;
+	}
+#endif /* LIBXML_READER_ENABLED */
+#ifdef LIBXML_SAX1_ENABLED
+	else if ((!strcmp(argv[i], "-sax1")) ||
+	         (!strcmp(argv[i], "--sax1"))) {
+	    sax1++;
+	    options |= XML_PARSE_SAX1;
+	}
+#endif /* LIBXML_SAX1_ENABLED */
+	else if ((!strcmp(argv[i], "-sax")) ||
+	         (!strcmp(argv[i], "--sax"))) {
+	    sax++;
+	}
+	else if ((!strcmp(argv[i], "-chkregister")) ||
+	         (!strcmp(argv[i], "--chkregister"))) {
+	    chkregister++;
+#ifdef LIBXML_SCHEMAS_ENABLED
+	} else if ((!strcmp(argv[i], "-relaxng")) ||
+	         (!strcmp(argv[i], "--relaxng"))) {
+	    i++;
+	    relaxng = argv[i];
+	    noent++;
+	    options |= XML_PARSE_NOENT;
+	} else if ((!strcmp(argv[i], "-schema")) ||
+	         (!strcmp(argv[i], "--schema"))) {
+	    i++;
+	    schema = argv[i];
+	    noent++;
+#endif
+#ifdef LIBXML_SCHEMATRON_ENABLED
+	} else if ((!strcmp(argv[i], "-schematron")) ||
+	         (!strcmp(argv[i], "--schematron"))) {
+	    i++;
+	    schematron = argv[i];
+	    noent++;
+#endif
+        } else if ((!strcmp(argv[i], "-nonet")) ||
+                   (!strcmp(argv[i], "--nonet"))) {
+	    options |= XML_PARSE_NONET;
+	    xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
+        } else if ((!strcmp(argv[i], "-nocompact")) ||
+                   (!strcmp(argv[i], "--nocompact"))) {
+	    options &= ~XML_PARSE_COMPACT;
+	} else if ((!strcmp(argv[i], "-load-trace")) ||
+	           (!strcmp(argv[i], "--load-trace"))) {
+	    load_trace++;
+        } else if ((!strcmp(argv[i], "-path")) ||
+                   (!strcmp(argv[i], "--path"))) {
+	    i++;
+	    parsePath(BAD_CAST argv[i]);
+#ifdef LIBXML_PATTERN_ENABLED
+        } else if ((!strcmp(argv[i], "-pattern")) ||
+                   (!strcmp(argv[i], "--pattern"))) {
+	    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++;
+	    options |= XML_PARSE_OLD10;
+	} else {
+	    fprintf(stderr, "Unknown option %s\n", argv[i]);
+	    usage(argv[0]);
+	    return(1);
+	}
+    }
+
+#ifdef LIBXML_CATALOG_ENABLED
+    if (nocatalogs == 0) {
+	if (catalogs) {
+	    const char *catal;
+
+	    catal = getenv("SGML_CATALOG_FILES");
+	    if (catal != NULL) {
+		xmlLoadCatalogs(catal);
+	    } else {
+		fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
+	    }
+	}
+    }
+#endif
+
+#ifdef LIBXML_SAX1_ENABLED
+    if (sax1)
+        xmlSAXDefaultVersion(1);
+    else
+        xmlSAXDefaultVersion(2);
+#endif /* LIBXML_SAX1_ENABLED */
+
+    if (chkregister) {
+	xmlRegisterNodeDefault(registerNode);
+	xmlDeregisterNodeDefault(deregisterNode);
+    }
+
+    indent = getenv("XMLLINT_INDENT");
+    if(indent != NULL) {
+	xmlTreeIndentString = indent;
+    }
+
+
+    defaultEntityLoader = xmlGetExternalEntityLoader();
+    xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
+
+    xmlLineNumbersDefault(1);
+    if (loaddtd != 0)
+	xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
+    if (dtdattrs)
+	xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
+    if (noent != 0) xmlSubstituteEntitiesDefault(1);
+#ifdef LIBXML_VALID_ENABLED
+    if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
+#endif /* LIBXML_VALID_ENABLED */
+    if ((htmlout) && (!nowrap)) {
+	xmlGenericError(xmlGenericErrorContext,
+         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
+	xmlGenericError(xmlGenericErrorContext,
+		"\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
+	xmlGenericError(xmlGenericErrorContext,
+	 "<html><head><title>%s output</title></head>\n",
+		argv[0]);
+	xmlGenericError(xmlGenericErrorContext,
+	 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
+		argv[0]);
+    }
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+    if ((schematron != NULL) && (sax == 0)
+#ifdef LIBXML_READER_ENABLED
+        && (stream == 0)
+#endif /* LIBXML_READER_ENABLED */
+	) {
+	xmlSchematronParserCtxtPtr ctxt;
+
+        /* forces loading the DTDs */
+        xmlLoadExtDtdDefaultValue |= 1;
+	options |= XML_PARSE_DTDLOAD;
+	if (timing) {
+	    startTimer();
+	}
+	ctxt = xmlSchematronNewParserCtxt(schematron);
+#if 0
+	xmlSchematronSetParserErrors(ctxt,
+		(xmlSchematronValidityErrorFunc) fprintf,
+		(xmlSchematronValidityWarningFunc) fprintf,
+		stderr);
+#endif
+	wxschematron = xmlSchematronParse(ctxt);
+	if (wxschematron == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Schematron schema %s failed to compile\n", schematron);
+            progresult = XMLLINT_ERR_SCHEMACOMP;
+	    schematron = NULL;
+	}
+	xmlSchematronFreeParserCtxt(ctxt);
+	if (timing) {
+	    endTimer("Compiling the schemas");
+	}
+    }
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if ((relaxng != NULL) && (sax == 0)
+#ifdef LIBXML_READER_ENABLED
+        && (stream == 0)
+#endif /* LIBXML_READER_ENABLED */
+	) {
+	xmlRelaxNGParserCtxtPtr ctxt;
+
+        /* forces loading the DTDs */
+        xmlLoadExtDtdDefaultValue |= 1;
+	options |= XML_PARSE_DTDLOAD;
+	if (timing) {
+	    startTimer();
+	}
+	ctxt = xmlRelaxNGNewParserCtxt(relaxng);
+	xmlRelaxNGSetParserErrors(ctxt,
+		(xmlRelaxNGValidityErrorFunc) fprintf,
+		(xmlRelaxNGValidityWarningFunc) fprintf,
+		stderr);
+	relaxngschemas = xmlRelaxNGParse(ctxt);
+	if (relaxngschemas == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Relax-NG schema %s failed to compile\n", relaxng);
+            progresult = XMLLINT_ERR_SCHEMACOMP;
+	    relaxng = NULL;
+	}
+	xmlRelaxNGFreeParserCtxt(ctxt);
+	if (timing) {
+	    endTimer("Compiling the schemas");
+	}
+    } else if ((schema != NULL)
+#ifdef LIBXML_READER_ENABLED
+		&& (stream == 0)
+#endif
+	) {
+	xmlSchemaParserCtxtPtr ctxt;
+
+	if (timing) {
+	    startTimer();
+	}
+	ctxt = xmlSchemaNewParserCtxt(schema);
+	xmlSchemaSetParserErrors(ctxt,
+		(xmlSchemaValidityErrorFunc) fprintf,
+		(xmlSchemaValidityWarningFunc) fprintf,
+		stderr);
+	wxschemas = xmlSchemaParse(ctxt);
+	if (wxschemas == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "WXS schema %s failed to compile\n", schema);
+            progresult = XMLLINT_ERR_SCHEMACOMP;
+	    schema = NULL;
+	}
+	xmlSchemaFreeParserCtxt(ctxt);
+	if (timing) {
+	    endTimer("Compiling the schemas");
+	}
+    }
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#ifdef LIBXML_PATTERN_ENABLED
+    if ((pattern != NULL)
+#ifdef LIBXML_READER_ENABLED
+        && (walker == 0)
+#endif
+	) {
+        patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
+	if (patternc == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Pattern %s failed to compile\n", pattern);
+            progresult = XMLLINT_ERR_SCHEMAPAT;
+	    pattern = NULL;
+	}
+    }
+#endif /* LIBXML_PATTERN_ENABLED */
+    for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    continue;
+        } else if ((!strcmp(argv[i], "-o")) ||
+                   (!strcmp(argv[i], "-output")) ||
+                   (!strcmp(argv[i], "--output"))) {
+            i++;
+	    continue;
+        }
+#ifdef LIBXML_VALID_ENABLED
+	if ((!strcmp(argv[i], "-dtdvalid")) ||
+	         (!strcmp(argv[i], "--dtdvalid"))) {
+	    i++;
+	    continue;
+        }
+	if ((!strcmp(argv[i], "-path")) ||
+                   (!strcmp(argv[i], "--path"))) {
+            i++;
+	    continue;
+        }
+	if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
+	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
+	    i++;
+	    continue;
+        }
+#endif /* LIBXML_VALID_ENABLED */
+	if ((!strcmp(argv[i], "-relaxng")) ||
+	         (!strcmp(argv[i], "--relaxng"))) {
+	    i++;
+	    continue;
+        }
+	if ((!strcmp(argv[i], "-maxmem")) ||
+	         (!strcmp(argv[i], "--maxmem"))) {
+	    i++;
+	    continue;
+        }
+	if ((!strcmp(argv[i], "-schema")) ||
+	         (!strcmp(argv[i], "--schema"))) {
+	    i++;
+	    continue;
+        }
+	if ((!strcmp(argv[i], "-schematron")) ||
+	         (!strcmp(argv[i], "--schematron"))) {
+	    i++;
+	    continue;
+        }
+#ifdef LIBXML_PATTERN_ENABLED
+        if ((!strcmp(argv[i], "-pattern")) ||
+	    (!strcmp(argv[i], "--pattern"))) {
+	    i++;
+	    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> */
+	if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
+	    if (repeat) {
+		xmlParserCtxtPtr ctxt = NULL;
+
+		for (acount = 0;acount < repeat;acount++) {
+#ifdef LIBXML_READER_ENABLED
+		    if (stream != 0) {
+			streamFile(argv[i]);
+		    } else {
+#endif /* LIBXML_READER_ENABLED */
+                        if (sax) {
+			    testSAX(argv[i]);
+			} else {
+			    if (ctxt == NULL)
+				ctxt = xmlNewParserCtxt();
+			    parseAndPrintFile(argv[i], ctxt);
+			}
+#ifdef LIBXML_READER_ENABLED
+		    }
+#endif /* LIBXML_READER_ENABLED */
+		}
+		if (ctxt != NULL)
+		    xmlFreeParserCtxt(ctxt);
+	    } else {
+		nbregister = 0;
+
+#ifdef LIBXML_READER_ENABLED
+		if (stream != 0)
+		    streamFile(argv[i]);
+		else
+#endif /* LIBXML_READER_ENABLED */
+                if (sax) {
+		    testSAX(argv[i]);
+		} else {
+		    parseAndPrintFile(argv[i], NULL);
+		}
+
+                if ((chkregister) && (nbregister != 0)) {
+		    fprintf(stderr, "Registration count off: %d\n", nbregister);
+		    progresult = XMLLINT_ERR_RDREGIS;
+		}
+	    }
+	    files ++;
+	    if ((timing) && (repeat)) {
+		endTimer("%d iterations", repeat);
+	    }
+	}
+    }
+    if (generate)
+	parseAndPrintFile(NULL, NULL);
+    if ((htmlout) && (!nowrap)) {
+	xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
+    }
+    if ((files == 0) && (!generate) && (version == 0)) {
+	usage(argv[0]);
+    }
+#ifdef LIBXML_SCHEMATRON_ENABLED
+    if (wxschematron != NULL)
+	xmlSchematronFree(wxschematron);
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (relaxngschemas != NULL)
+	xmlRelaxNGFree(relaxngschemas);
+    if (wxschemas != NULL)
+	xmlSchemaFree(wxschemas);
+    xmlRelaxNGCleanupTypes();
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+    if (patternc != NULL)
+        xmlFreePattern(patternc);
+#endif
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(progresult);
+}
+
diff --git a/src/xmlmemory.c b/src/xmlmemory.c
new file mode 100644
index 0000000..433abb8
--- /dev/null
+++ b/src/xmlmemory.c
@@ -0,0 +1,1120 @@
+/*
+ * xmlmemory.c:  libxml memory allocator wrapper.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#else
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#endif
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+/* #define DEBUG_MEMORY */
+
+/**
+ * MEM_LIST:
+ *
+ * keep track of all allocated blocks for error reporting
+ * Always build the memory list !
+ */
+#ifdef DEBUG_MEMORY_LOCATION
+#ifndef MEM_LIST
+#define MEM_LIST /* keep a list of all the allocated memory blocks */
+#endif
+#endif
+
+#include <libxml/globals.h>	/* must come before xmlmemory.h */
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlerror.h>
+#include <libxml/threads.h>
+
+static int xmlMemInitialized = 0;
+static unsigned long  debugMemSize = 0;
+static unsigned long  debugMemBlocks = 0;
+static unsigned long  debugMaxMemSize = 0;
+static xmlMutexPtr xmlMemMutex = NULL;
+
+void xmlMallocBreakpoint(void);
+
+/************************************************************************
+ *									*
+ * 		Macros, variables and associated types			*
+ *									*
+ ************************************************************************/
+
+#if !defined(LIBXML_THREAD_ENABLED) && !defined(LIBXML_THREAD_ALLOC_ENABLED)
+#ifdef xmlMalloc
+#undef xmlMalloc
+#endif
+#ifdef xmlRealloc
+#undef xmlRealloc
+#endif
+#ifdef xmlMemStrdup
+#undef xmlMemStrdup
+#endif
+#endif
+
+/*
+ * Each of the blocks allocated begin with a header containing informations
+ */
+
+#define MEMTAG 0x5aa5
+
+#define MALLOC_TYPE 1
+#define REALLOC_TYPE 2
+#define STRDUP_TYPE 3
+#define MALLOC_ATOMIC_TYPE 4
+#define REALLOC_ATOMIC_TYPE 5
+
+typedef struct memnod {
+    unsigned int   mh_tag;
+    unsigned int   mh_type;
+    unsigned long  mh_number;
+    size_t         mh_size;
+#ifdef MEM_LIST
+   struct memnod *mh_next;
+   struct memnod *mh_prev;
+#endif
+   const char    *mh_file;
+   unsigned int   mh_line;
+}  MEMHDR;
+
+
+#ifdef SUN4
+#define ALIGN_SIZE  16
+#else
+#define ALIGN_SIZE  sizeof(double)
+#endif
+#define HDR_SIZE    sizeof(MEMHDR)
+#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
+		      / ALIGN_SIZE ) * ALIGN_SIZE)
+
+
+#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
+#define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
+
+
+static unsigned int block=0;
+static unsigned int xmlMemStopAtBlock = 0;
+static void *xmlMemTraceBlockAt = NULL;
+#ifdef MEM_LIST
+static MEMHDR *memlist = NULL;
+#endif
+
+static void debugmem_tag_error(void *addr);
+#ifdef MEM_LIST
+static void  debugmem_list_add(MEMHDR *);
+static void debugmem_list_delete(MEMHDR *);
+#endif
+#define Mem_Tag_Err(a) debugmem_tag_error(a);
+
+#ifndef TEST_POINT
+#define TEST_POINT
+#endif
+
+/**
+ * xmlMallocBreakpoint:
+ *
+ * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
+ * number reaches the specified value this function is called. One need to add a breakpoint
+ * to it to get the context in which the given block is allocated.
+ */
+
+void
+xmlMallocBreakpoint(void) {
+    xmlGenericError(xmlGenericErrorContext,
+	    "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
+}
+
+/**
+ * xmlMallocLoc:
+ * @size:  an int specifying the size in byte to allocate.
+ * @file:  the file name or NULL
+ * @line:  the line number
+ *
+ * a malloc() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
+ */
+
+void *
+xmlMallocLoc(size_t size, const char * file, int line)
+{
+    MEMHDR *p;
+    void *ret;
+
+    if (!xmlMemInitialized) xmlInitMemory();
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Malloc(%d)\n",size);
+#endif
+
+    TEST_POINT
+
+    p = (MEMHDR *) malloc(RESERVE_SIZE+size);
+
+    if (!p) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlMallocLoc : Out of free space\n");
+	xmlMemoryDump();
+	return(NULL);
+    }
+    p->mh_tag = MEMTAG;
+    p->mh_size = size;
+    p->mh_type = MALLOC_TYPE;
+    p->mh_file = file;
+    p->mh_line = line;
+    xmlMutexLock(xmlMemMutex);
+    p->mh_number = ++block;
+    debugMemSize += size;
+    debugMemBlocks++;
+    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
+#ifdef MEM_LIST
+    debugmem_list_add(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Malloc(%d) Ok\n",size);
+#endif
+
+    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
+
+    ret = HDR_2_CLIENT(p);
+
+    if (xmlMemTraceBlockAt == ret) {
+	xmlGenericError(xmlGenericErrorContext,
+			"%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+	xmlMallocBreakpoint();
+    }
+
+    TEST_POINT
+
+    return(ret);
+}
+
+/**
+ * xmlMallocAtomicLoc:
+ * @size:  an int specifying the size in byte to allocate.
+ * @file:  the file name or NULL
+ * @line:  the line number
+ *
+ * a malloc() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
+ */
+
+void *
+xmlMallocAtomicLoc(size_t size, const char * file, int line)
+{
+    MEMHDR *p;
+    void *ret;
+
+    if (!xmlMemInitialized) xmlInitMemory();
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Malloc(%d)\n",size);
+#endif
+
+    TEST_POINT
+
+    p = (MEMHDR *) malloc(RESERVE_SIZE+size);
+
+    if (!p) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlMallocLoc : Out of free space\n");
+	xmlMemoryDump();
+	return(NULL);
+    }
+    p->mh_tag = MEMTAG;
+    p->mh_size = size;
+    p->mh_type = MALLOC_ATOMIC_TYPE;
+    p->mh_file = file;
+    p->mh_line = line;
+    xmlMutexLock(xmlMemMutex);
+    p->mh_number = ++block;
+    debugMemSize += size;
+    debugMemBlocks++;
+    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
+#ifdef MEM_LIST
+    debugmem_list_add(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Malloc(%d) Ok\n",size);
+#endif
+
+    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
+
+    ret = HDR_2_CLIENT(p);
+
+    if (xmlMemTraceBlockAt == ret) {
+	xmlGenericError(xmlGenericErrorContext,
+			"%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+	xmlMallocBreakpoint();
+    }
+
+    TEST_POINT
+
+    return(ret);
+}
+/**
+ * xmlMemMalloc:
+ * @size:  an int specifying the size in byte to allocate.
+ *
+ * a malloc() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
+ */
+
+void *
+xmlMemMalloc(size_t size)
+{
+    return(xmlMallocLoc(size, "none", 0));
+}
+
+/**
+ * xmlReallocLoc:
+ * @ptr:  the initial memory block pointer
+ * @size:  an int specifying the size in byte to allocate.
+ * @file:  the file name or NULL
+ * @line:  the line number
+ *
+ * a realloc() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
+ */
+
+void *
+xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
+{
+    MEMHDR *p;
+    unsigned long number;
+#ifdef DEBUG_MEMORY
+    size_t oldsize;
+#endif
+
+    if (ptr == NULL)
+        return(xmlMallocLoc(size, file, line));
+
+    if (!xmlMemInitialized) xmlInitMemory();
+    TEST_POINT
+
+    p = CLIENT_2_HDR(ptr);
+    number = p->mh_number;
+    if (xmlMemStopAtBlock == number) xmlMallocBreakpoint();
+    if (p->mh_tag != MEMTAG) {
+       Mem_Tag_Err(p);
+	 goto error;
+    }
+    p->mh_tag = ~MEMTAG;
+    xmlMutexLock(xmlMemMutex);
+    debugMemSize -= p->mh_size;
+    debugMemBlocks--;
+#ifdef DEBUG_MEMORY
+    oldsize = p->mh_size;
+#endif
+#ifdef MEM_LIST
+    debugmem_list_delete(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
+    if (!p) {
+	 goto error;
+    }
+    if (xmlMemTraceBlockAt == ptr) {
+	xmlGenericError(xmlGenericErrorContext,
+			"%p : Realloced(%ld -> %ld) Ok\n",
+			xmlMemTraceBlockAt, p->mh_size, size);
+	xmlMallocBreakpoint();
+    }
+    p->mh_tag = MEMTAG;
+    p->mh_number = number;
+    p->mh_type = REALLOC_TYPE;
+    p->mh_size = size;
+    p->mh_file = file;
+    p->mh_line = line;
+    xmlMutexLock(xmlMemMutex);
+    debugMemSize += size;
+    debugMemBlocks++;
+    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
+#ifdef MEM_LIST
+    debugmem_list_add(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+    TEST_POINT
+
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Realloced(%d to %d) Ok\n", oldsize, size);
+#endif
+    return(HDR_2_CLIENT(p));
+
+error:
+    return(NULL);
+}
+
+/**
+ * xmlMemRealloc:
+ * @ptr:  the initial memory block pointer
+ * @size:  an int specifying the size in byte to allocate.
+ *
+ * a realloc() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the allocated area or NULL in case of lack of memory.
+ */
+
+void *
+xmlMemRealloc(void *ptr,size_t size) {
+    return(xmlReallocLoc(ptr, size, "none", 0));
+}
+
+/**
+ * xmlMemFree:
+ * @ptr:  the memory block pointer
+ *
+ * a free() equivalent, with error checking.
+ */
+void
+xmlMemFree(void *ptr)
+{
+    MEMHDR *p;
+    char *target;
+#ifdef DEBUG_MEMORY
+    size_t size;
+#endif
+
+    if (ptr == NULL)
+	return;
+
+    if (ptr == (void *) -1) {
+	xmlGenericError(xmlGenericErrorContext,
+	    "trying to free pointer from freed area\n");
+        goto error;
+    }
+
+    if (xmlMemTraceBlockAt == ptr) {
+	xmlGenericError(xmlGenericErrorContext,
+			"%p : Freed()\n", xmlMemTraceBlockAt);
+	xmlMallocBreakpoint();
+    }
+
+    TEST_POINT
+
+    target = (char *) ptr;
+
+    p = CLIENT_2_HDR(ptr);
+    if (p->mh_tag != MEMTAG) {
+        Mem_Tag_Err(p);
+        goto error;
+    }
+    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
+    p->mh_tag = ~MEMTAG;
+    memset(target, -1, p->mh_size);
+    xmlMutexLock(xmlMemMutex);
+    debugMemSize -= p->mh_size;
+    debugMemBlocks--;
+#ifdef DEBUG_MEMORY
+    size = p->mh_size;
+#endif
+#ifdef MEM_LIST
+    debugmem_list_delete(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+    free(p);
+
+    TEST_POINT
+
+#ifdef DEBUG_MEMORY
+    xmlGenericError(xmlGenericErrorContext,
+	    "Freed(%d) Ok\n", size);
+#endif
+
+    return;
+
+error:
+    xmlGenericError(xmlGenericErrorContext,
+	    "xmlMemFree(%lX) error\n", (unsigned long) ptr);
+    xmlMallocBreakpoint();
+    return;
+}
+
+/**
+ * xmlMemStrdupLoc:
+ * @str:  the initial string pointer
+ * @file:  the file name or NULL
+ * @line:  the line number
+ *
+ * a strdup() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the new string or NULL if allocation error occurred.
+ */
+
+char *
+xmlMemStrdupLoc(const char *str, const char *file, int line)
+{
+    char *s;
+    size_t size = strlen(str) + 1;
+    MEMHDR *p;
+
+    if (!xmlMemInitialized) xmlInitMemory();
+    TEST_POINT
+
+    p = (MEMHDR *) malloc(RESERVE_SIZE+size);
+    if (!p) {
+      goto error;
+    }
+    p->mh_tag = MEMTAG;
+    p->mh_size = size;
+    p->mh_type = STRDUP_TYPE;
+    p->mh_file = file;
+    p->mh_line = line;
+    xmlMutexLock(xmlMemMutex);
+    p->mh_number = ++block;
+    debugMemSize += size;
+    debugMemBlocks++;
+    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
+#ifdef MEM_LIST
+    debugmem_list_add(p);
+#endif
+    xmlMutexUnlock(xmlMemMutex);
+
+    s = (char *) HDR_2_CLIENT(p);
+
+    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
+
+    if (s != NULL)
+      strcpy(s,str);
+    else
+      goto error;
+
+    TEST_POINT
+
+    if (xmlMemTraceBlockAt == s) {
+	xmlGenericError(xmlGenericErrorContext,
+			"%p : Strdup() Ok\n", xmlMemTraceBlockAt);
+	xmlMallocBreakpoint();
+    }
+
+    return(s);
+
+error:
+    return(NULL);
+}
+
+/**
+ * xmlMemoryStrdup:
+ * @str:  the initial string pointer
+ *
+ * a strdup() equivalent, with logging of the allocation info.
+ *
+ * Returns a pointer to the new string or NULL if allocation error occurred.
+ */
+
+char *
+xmlMemoryStrdup(const char *str) {
+    return(xmlMemStrdupLoc(str, "none", 0));
+}
+
+/**
+ * xmlMemUsed:
+ *
+ * Provides the amount of memory currently allocated
+ *
+ * Returns an int representing the amount of memory allocated.
+ */
+
+int
+xmlMemUsed(void) {
+     return(debugMemSize);
+}
+
+/**
+ * xmlMemBlocks:
+ *
+ * Provides the number of memory areas currently allocated
+ *
+ * Returns an int representing the number of blocks
+ */
+
+int
+xmlMemBlocks(void) {
+     return(debugMemBlocks);
+}
+
+#ifdef MEM_LIST
+/**
+ * xmlMemContentShow:
+ * @fp:  a FILE descriptor used as the output file
+ * @p:  a memory block header
+ *
+ * tries to show some content from the memory block
+ */
+
+static void
+xmlMemContentShow(FILE *fp, MEMHDR *p)
+{
+    int i,j,k,len = p->mh_size;
+    const char *buf = (const char *) HDR_2_CLIENT(p);
+
+    if (p == NULL) {
+	fprintf(fp, " NULL");
+	return;
+    }
+
+    for (i = 0;i < len;i++) {
+        if (buf[i] == 0) break;
+	if (!isprint((unsigned char) buf[i])) break;
+    }
+    if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
+        if (len >= 4) {
+	    MEMHDR *q;
+	    void *cur;
+
+            for (j = 0;(j < len -3) && (j < 40);j += 4) {
+		cur = *((void **) &buf[j]);
+		q = CLIENT_2_HDR(cur);
+		p = memlist;
+		k = 0;
+		while (p != NULL) {
+		    if (p == q) break;
+		    p = p->mh_next;
+		    if (k++ > 100) break;
+		}
+		if ((p != NULL) && (p == q)) {
+		    fprintf(fp, " pointer to #%lu at index %d",
+		            p->mh_number, j);
+		    return;
+		}
+	    }
+	}
+    } else if ((i == 0) && (buf[i] == 0)) {
+        fprintf(fp," null");
+    } else {
+        if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
+	else {
+            fprintf(fp," [");
+	    for (j = 0;j < i;j++)
+                fprintf(fp,"%c", buf[j]);
+            fprintf(fp,"]");
+	}
+    }
+}
+#endif
+
+/**
+ * xmlMemDisplayLast:
+ * @fp:  a FILE descriptor used as the output file, if NULL, the result is
+ *       written to the file .memorylist
+ * @nbBytes: the amount of memory to dump
+ *
+ * the last nbBytes of memory allocated and not freed, useful for dumping
+ * the memory left allocated between two places at runtime.
+ */
+
+void
+xmlMemDisplayLast(FILE *fp, long nbBytes)
+{
+#ifdef MEM_LIST
+    MEMHDR *p;
+    unsigned idx;
+    int     nb = 0;
+#endif
+    FILE *old_fp = fp;
+
+    if (nbBytes <= 0)
+        return;
+
+    if (fp == NULL) {
+	fp = fopen(".memorylist", "w");
+	if (fp == NULL)
+	    return;
+    }
+
+#ifdef MEM_LIST
+    fprintf(fp,"   Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n",
+            nbBytes, debugMemSize, debugMaxMemSize);
+    fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
+    idx = 0;
+    xmlMutexLock(xmlMemMutex);
+    p = memlist;
+    while ((p) && (nbBytes > 0)) {
+	  fprintf(fp,"%-5u  %6lu %6lu ",idx++,p->mh_number,
+		  (unsigned long)p->mh_size);
+        switch (p->mh_type) {
+           case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
+           case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
+           case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
+           case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc()  in ");break;
+           case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
+           default:
+	        fprintf(fp,"Unknown memory block, may be corrupted");
+		xmlMutexUnlock(xmlMemMutex);
+		if (old_fp == NULL)
+		    fclose(fp);
+		return;
+        }
+	if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
+        if (p->mh_tag != MEMTAG)
+	      fprintf(fp,"  INVALID");
+        nb++;
+	if (nb < 100)
+	    xmlMemContentShow(fp, p);
+	else
+	    fprintf(fp," skip");
+
+        fprintf(fp,"\n");
+	nbBytes -= (unsigned long)p->mh_size;
+        p = p->mh_next;
+    }
+    xmlMutexUnlock(xmlMemMutex);
+#else
+    fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
+#endif
+    if (old_fp == NULL)
+	fclose(fp);
+}
+
+/**
+ * xmlMemDisplay:
+ * @fp:  a FILE descriptor used as the output file, if NULL, the result is
+ *       written to the file .memorylist
+ *
+ * show in-extenso the memory blocks allocated
+ */
+
+void
+xmlMemDisplay(FILE *fp)
+{
+#ifdef MEM_LIST
+    MEMHDR *p;
+    unsigned idx;
+    int     nb = 0;
+#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
+    time_t currentTime;
+    char buf[500];
+    struct tm * tstruct;
+#endif
+#endif
+    FILE *old_fp = fp;
+
+    if (fp == NULL) {
+	fp = fopen(".memorylist", "w");
+	if (fp == NULL)
+	    return;
+    }
+
+#ifdef MEM_LIST
+#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
+    currentTime = time(NULL);
+    tstruct = localtime(&currentTime);
+    strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct);
+    fprintf(fp,"      %s\n\n", buf);
+#endif
+
+
+    fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",
+            debugMemSize, debugMaxMemSize);
+    fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
+    idx = 0;
+    xmlMutexLock(xmlMemMutex);
+    p = memlist;
+    while (p) {
+	  fprintf(fp,"%-5u  %6lu %6lu ",idx++,p->mh_number,
+		  (unsigned long)p->mh_size);
+        switch (p->mh_type) {
+           case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
+           case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
+           case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
+           case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc()  in ");break;
+           case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
+           default:
+	        fprintf(fp,"Unknown memory block, may be corrupted");
+		xmlMutexUnlock(xmlMemMutex);
+		if (old_fp == NULL)
+		    fclose(fp);
+		return;
+        }
+	if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
+        if (p->mh_tag != MEMTAG)
+	      fprintf(fp,"  INVALID");
+        nb++;
+	if (nb < 100)
+	    xmlMemContentShow(fp, p);
+	else
+	    fprintf(fp," skip");
+
+        fprintf(fp,"\n");
+        p = p->mh_next;
+    }
+    xmlMutexUnlock(xmlMemMutex);
+#else
+    fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
+#endif
+    if (old_fp == NULL)
+	fclose(fp);
+}
+
+#ifdef MEM_LIST
+
+static void debugmem_list_add(MEMHDR *p)
+{
+     p->mh_next = memlist;
+     p->mh_prev = NULL;
+     if (memlist) memlist->mh_prev = p;
+     memlist = p;
+#ifdef MEM_LIST_DEBUG
+     if (stderr)
+     Mem_Display(stderr);
+#endif
+}
+
+static void debugmem_list_delete(MEMHDR *p)
+{
+     if (p->mh_next)
+     p->mh_next->mh_prev = p->mh_prev;
+     if (p->mh_prev)
+     p->mh_prev->mh_next = p->mh_next;
+     else memlist = p->mh_next;
+#ifdef MEM_LIST_DEBUG
+     if (stderr)
+     Mem_Display(stderr);
+#endif
+}
+
+#endif
+
+/*
+ * debugmem_tag_error:
+ *
+ * internal error function.
+ */
+
+static void debugmem_tag_error(void *p)
+{
+     xmlGenericError(xmlGenericErrorContext,
+	     "Memory tag error occurs :%p \n\t bye\n", p);
+#ifdef MEM_LIST
+     if (stderr)
+     xmlMemDisplay(stderr);
+#endif
+}
+
+#ifdef MEM_LIST
+static FILE *xmlMemoryDumpFile = NULL;
+#endif
+
+/**
+ * xmlMemShow:
+ * @fp:  a FILE descriptor used as the output file
+ * @nr:  number of entries to dump
+ *
+ * show a show display of the memory allocated, and dump
+ * the @nr last allocated areas which were not freed
+ */
+
+void
+xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED)
+{
+#ifdef MEM_LIST
+    MEMHDR *p;
+#endif
+
+    if (fp != NULL)
+	fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",
+		debugMemSize, debugMaxMemSize);
+#ifdef MEM_LIST
+    xmlMutexLock(xmlMemMutex);
+    if (nr > 0) {
+	fprintf(fp,"NUMBER   SIZE  TYPE   WHERE\n");
+	p = memlist;
+	while ((p) && nr > 0) {
+	      fprintf(fp,"%6lu %6lu ",p->mh_number,(unsigned long)p->mh_size);
+	    switch (p->mh_type) {
+	       case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
+	       case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
+	       case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc()  in ");break;
+	      case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
+	      case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
+		default:fprintf(fp,"   ???    in ");break;
+	    }
+	    if (p->mh_file != NULL)
+	        fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
+	    if (p->mh_tag != MEMTAG)
+		fprintf(fp,"  INVALID");
+	    xmlMemContentShow(fp, p);
+	    fprintf(fp,"\n");
+	    nr--;
+	    p = p->mh_next;
+	}
+    }
+    xmlMutexUnlock(xmlMemMutex);
+#endif /* MEM_LIST */
+}
+
+/**
+ * xmlMemoryDump:
+ *
+ * Dump in-extenso the memory blocks allocated to the file .memorylist
+ */
+
+void
+xmlMemoryDump(void)
+{
+#ifdef MEM_LIST
+    FILE *dump;
+
+    if (debugMaxMemSize == 0)
+	return;
+    dump = fopen(".memdump", "w");
+    if (dump == NULL)
+	xmlMemoryDumpFile = stderr;
+    else xmlMemoryDumpFile = dump;
+
+    xmlMemDisplay(xmlMemoryDumpFile);
+
+    if (dump != NULL) fclose(dump);
+#endif /* MEM_LIST */
+}
+
+
+/****************************************************************
+ *								*
+ *		Initialization Routines				*
+ *								*
+ ****************************************************************/
+
+/**
+ * xmlInitMemory:
+ *
+ * Initialize the memory layer.
+ *
+ * Returns 0 on success
+ */
+int
+xmlInitMemory(void)
+{
+#ifdef HAVE_STDLIB_H
+     char *breakpoint;
+#endif
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlInitMemory()\n");
+#endif
+    /*
+     This is really not good code (see Bug 130419).  Suggestions for
+     improvement will be welcome!
+    */
+     if (xmlMemInitialized) return(-1);
+     xmlMemInitialized = 1;
+     xmlMemMutex = xmlNewMutex();
+
+#ifdef HAVE_STDLIB_H
+     breakpoint = getenv("XML_MEM_BREAKPOINT");
+     if (breakpoint != NULL) {
+         sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
+     }
+#endif
+#ifdef HAVE_STDLIB_H
+     breakpoint = getenv("XML_MEM_TRACE");
+     if (breakpoint != NULL) {
+         sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
+     }
+#endif
+
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlInitMemory() Ok\n");
+#endif
+     return(0);
+}
+
+/**
+ * xmlCleanupMemory:
+ *
+ * Free up all the memory allocated by the library for its own
+ * use. This should not be called by user level code.
+ */
+void
+xmlCleanupMemory(void) {
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlCleanupMemory()\n");
+#endif
+    if (xmlMemInitialized == 0)
+        return;
+
+    xmlFreeMutex(xmlMemMutex);
+    xmlMemMutex = NULL;
+    xmlMemInitialized = 0;
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlCleanupMemory() Ok\n");
+#endif
+}
+
+/**
+ * xmlMemSetup:
+ * @freeFunc: the free() function to use
+ * @mallocFunc: the malloc() function to use
+ * @reallocFunc: the realloc() function to use
+ * @strdupFunc: the strdup() function to use
+ *
+ * Override the default memory access functions with a new set
+ * This has to be called before any other libxml routines !
+ *
+ * Should this be blocked if there was already some allocations
+ * done ?
+ *
+ * Returns 0 on success
+ */
+int
+xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
+            xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlMemSetup()\n");
+#endif
+    if (freeFunc == NULL)
+	return(-1);
+    if (mallocFunc == NULL)
+	return(-1);
+    if (reallocFunc == NULL)
+	return(-1);
+    if (strdupFunc == NULL)
+	return(-1);
+    xmlFree = freeFunc;
+    xmlMalloc = mallocFunc;
+    xmlMallocAtomic = mallocFunc;
+    xmlRealloc = reallocFunc;
+    xmlMemStrdup = strdupFunc;
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlMemSetup() Ok\n");
+#endif
+    return(0);
+}
+
+/**
+ * xmlMemGet:
+ * @freeFunc: place to save the free() function in use
+ * @mallocFunc: place to save the malloc() function in use
+ * @reallocFunc: place to save the realloc() function in use
+ * @strdupFunc: place to save the strdup() function in use
+ *
+ * Provides the memory access functions set currently in use
+ *
+ * Returns 0 on success
+ */
+int
+xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
+	  xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
+    if (freeFunc != NULL) *freeFunc = xmlFree;
+    if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
+    if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
+    if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
+    return(0);
+}
+
+/**
+ * xmlGcMemSetup:
+ * @freeFunc: the free() function to use
+ * @mallocFunc: the malloc() function to use
+ * @mallocAtomicFunc: the malloc() function to use for atomic allocations
+ * @reallocFunc: the realloc() function to use
+ * @strdupFunc: the strdup() function to use
+ *
+ * Override the default memory access functions with a new set
+ * This has to be called before any other libxml routines !
+ * The mallocAtomicFunc is specialized for atomic block
+ * allocations (i.e. of areas  useful for garbage collected memory allocators
+ *
+ * Should this be blocked if there was already some allocations
+ * done ?
+ *
+ * Returns 0 on success
+ */
+int
+xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
+              xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc,
+	      xmlStrdupFunc strdupFunc) {
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlGcMemSetup()\n");
+#endif
+    if (freeFunc == NULL)
+	return(-1);
+    if (mallocFunc == NULL)
+	return(-1);
+    if (mallocAtomicFunc == NULL)
+	return(-1);
+    if (reallocFunc == NULL)
+	return(-1);
+    if (strdupFunc == NULL)
+	return(-1);
+    xmlFree = freeFunc;
+    xmlMalloc = mallocFunc;
+    xmlMallocAtomic = mallocAtomicFunc;
+    xmlRealloc = reallocFunc;
+    xmlMemStrdup = strdupFunc;
+#ifdef DEBUG_MEMORY
+     xmlGenericError(xmlGenericErrorContext,
+	     "xmlGcMemSetup() Ok\n");
+#endif
+    return(0);
+}
+
+/**
+ * xmlGcMemGet:
+ * @freeFunc: place to save the free() function in use
+ * @mallocFunc: place to save the malloc() function in use
+ * @mallocAtomicFunc: place to save the atomic malloc() function in use
+ * @reallocFunc: place to save the realloc() function in use
+ * @strdupFunc: place to save the strdup() function in use
+ *
+ * Provides the memory access functions set currently in use
+ * The mallocAtomicFunc is specialized for atomic block
+ * allocations (i.e. of areas  useful for garbage collected memory allocators
+ *
+ * Returns 0 on success
+ */
+int
+xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
+            xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc,
+	    xmlStrdupFunc *strdupFunc) {
+    if (freeFunc != NULL) *freeFunc = xmlFree;
+    if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
+    if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic;
+    if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
+    if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
+    return(0);
+}
+
+#define bottom_xmlmemory
+#include "elfgcchack.h"
diff --git a/src/xmlmodule.c b/src/xmlmodule.c
new file mode 100644
index 0000000..cbe30b6
--- /dev/null
+++ b/src/xmlmodule.c
@@ -0,0 +1,445 @@
+/*
+ * xmlmodule.c : basic API for dynamic module loading added 2.6.17
+ *
+ * See Copyright for the status of this software.
+ *
+ * joelwreed@comcast.net
+ *
+ * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlmodule.h>
+#include <libxml/globals.h>
+
+#ifdef LIBXML_MODULES_ENABLED
+
+struct _xmlModule {
+    unsigned char *name;
+    void *handle;
+};
+
+static void *xmlModulePlatformOpen(const char *name);
+static int xmlModulePlatformClose(void *handle);
+static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);
+
+/************************************************************************
+ *									*
+ * 		module memory error handler				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlModuleErrMemory:
+ * @extra:  extra information
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlModuleErrMemory(xmlModulePtr module, const char *extra)
+{
+    const char *name = NULL;
+
+    if (module != NULL) {
+        name = (const char *) module->name;
+    }
+
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+                    name, NULL, 0, 0,
+                    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlModuleOpen:
+ * @name: the module name
+ * @options: a set of xmlModuleOption
+ *
+ * Opens a module/shared library given its name or path
+ * TODO: options are not yet implemented.
+ *
+ * Returns a handle for the module or NULL in case of error
+ */
+xmlModulePtr
+xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
+{
+    xmlModulePtr module;
+
+    module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
+    if (module == NULL) {
+        xmlModuleErrMemory(NULL, "creating module");
+        return (NULL);
+    }
+
+    memset(module, 0, sizeof(xmlModule));
+
+    module->handle = xmlModulePlatformOpen(name);
+
+    if (module->handle == NULL) {
+        xmlFree(module);
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
+                        name, NULL, 0, 0, "failed to open %s\n", name);
+        return(NULL);
+    }
+
+    module->name = xmlStrdup((const xmlChar *) name);
+    return (module);
+}
+
+/**
+ * xmlModuleSymbol:
+ * @module: the module
+ * @name: the name of the symbol
+ * @symbol: the resulting symbol address
+ *
+ * Lookup for a symbol address in the given module
+ *
+ * Returns 0 if the symbol was found, or -1 in case of error
+ */
+int
+xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
+{
+    int rc = -1;
+	
+    if ((NULL == module) || (symbol == NULL)) {
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
+                        NULL, NULL, 0, 0, "null parameter\n");
+        return rc;
+    }
+
+    rc = xmlModulePlatformSymbol(module->handle, name, symbol);
+
+    if (rc == -1) {
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
+                        name, NULL, 0, 0,
+                        "failed to find symbol: %s\n",
+			(name == NULL ? "NULL" : name));
+        return rc;
+    }
+
+    return rc;
+}
+
+/**
+ * xmlModuleClose:
+ * @module: the module handle
+ *
+ * The close operations unload the associated module and free the
+ * data associated to the module.
+ *
+ * Returns 0 in case of success, -1 in case of argument error and -2
+ *         if the module could not be closed/unloaded.
+ */
+int
+xmlModuleClose(xmlModulePtr module)
+{
+    int rc;
+
+    if (NULL == module) {
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
+                        NULL, NULL, 0, 0, "null module pointer\n");
+        return -1;
+    }
+
+    rc = xmlModulePlatformClose(module->handle);
+
+    if (rc != 0) {
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
+                        (const char *) module->name, NULL, 0, 0,
+                        "failed to close: %s\n", module->name);
+        return -2;
+    }
+
+    rc = xmlModuleFree(module);
+    return (rc);
+}
+
+/**
+ * xmlModuleFree:
+ * @module: the module handle
+ *
+ * The free operations free the data associated to the module
+ * but does not unload the associated shared library which may still
+ * be in use.
+ *
+ * Returns 0 in case of success, -1 in case of argument error
+ */
+int
+xmlModuleFree(xmlModulePtr module)
+{
+    if (NULL == module) {
+        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
+                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, NULL,
+                        NULL, NULL, 0, 0, "null module pointer\n");
+        return -1;
+    }
+
+    xmlFree(module->name);
+    xmlFree(module);
+
+    return (0);
+}
+
+#if defined(HAVE_DLOPEN) && !defined(_WIN32)
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#ifndef RTLD_GLOBAL            /* For Tru64 UNIX 4.0 */
+#define RTLD_GLOBAL 0
+#endif
+
+/**
+ * xmlModulePlatformOpen:
+ * @name: path to the module
+ *
+ * returns a handle on success, and zero on error.
+ */
+
+static void *
+xmlModulePlatformOpen(const char *name)
+{
+    return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
+}
+
+/*
+ * xmlModulePlatformClose:
+ * @handle: handle to the module
+ *
+ * returns 0 on success, and non-zero on error.
+ */
+
+static int
+xmlModulePlatformClose(void *handle)
+{
+    return dlclose(handle);
+}
+
+/*
+ * xmlModulePlatformSymbol:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
+ * returns 0 on success and the loaded symbol in result, and -1 on error.
+ */
+
+static int
+xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
+{
+    *symbol = dlsym(handle, name);
+    if (dlerror() != NULL) {
+	return -1;
+    }
+    return 0;
+}
+
+#else /* ! HAVE_DLOPEN */
+
+#ifdef HAVE_SHLLOAD             /* HAVE_SHLLOAD */
+#ifdef HAVE_DL_H
+#include <dl.h>
+#endif
+/*
+ * xmlModulePlatformOpen:
+ * returns a handle on success, and zero on error.
+ */
+
+static void *
+xmlModulePlatformOpen(const char *name)
+{
+    return shl_load(name, BIND_IMMEDIATE, 0L);
+}
+
+/*
+ * xmlModulePlatformClose:
+ * returns 0 on success, and non-zero on error.
+ */
+
+static int
+xmlModulePlatformClose(void *handle)
+{
+    return shl_unload(handle);
+}
+
+/*
+ * xmlModulePlatformSymbol:
+ * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
+ * returns 0 on success and the loaded symbol in result, and -1 on error.
+ */
+
+static int
+xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
+{
+    int rc;
+
+    errno = 0;
+    rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
+    return rc;
+}
+
+#endif /* HAVE_SHLLOAD */
+#endif /* ! HAVE_DLOPEN */
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+/*
+ * xmlModulePlatformOpen:
+ * returns a handle on success, and zero on error.
+ */
+
+static void *
+xmlModulePlatformOpen(const char *name)
+{
+    return LoadLibraryA(name);
+}
+
+/*
+ * xmlModulePlatformClose:
+ * returns 0 on success, and non-zero on error.
+ */
+
+static int
+xmlModulePlatformClose(void *handle)
+{
+    int rc;
+
+    rc = FreeLibrary(handle);
+    return (0 == rc);
+}
+
+/*
+ * xmlModulePlatformSymbol:
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
+ * returns 0 on success and the loaded symbol in result, and -1 on error.
+ */
+
+static int
+xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
+{
+    *symbol = GetProcAddress(handle, name);
+    return (NULL == *symbol) ? -1 : 0;
+}
+
+#endif /* _WIN32 */
+
+#ifdef HAVE_BEOS
+
+#include <kernel/image.h>
+
+/*
+ * xmlModulePlatformOpen:
+ * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
+ * returns a handle on success, and zero on error.
+ */
+
+static void *
+xmlModulePlatformOpen(const char *name)
+{
+    return (void *) load_add_on(name);
+}
+
+/*
+ * xmlModulePlatformClose:
+ * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
+ * returns 0 on success, and non-zero on error.
+ */
+
+static int
+xmlModulePlatformClose(void *handle)
+{
+    status_t rc;
+
+    rc = unload_add_on((image_id) handle);
+
+    if (rc == B_OK)
+        return 0;
+    else
+        return -1;
+}
+
+/*
+ * xmlModulePlatformSymbol:
+ * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
+ * returns 0 on success and the loaded symbol in result, and -1 on error.
+ */
+
+static int
+xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
+{
+    status_t rc;
+
+    rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);
+
+    return (rc == B_OK) ? 0 : -1;
+}
+
+#endif /* HAVE_BEOS */
+
+#ifdef HAVE_OS2
+
+#include <os2.h>
+
+/*
+ * xmlModulePlatformOpen:
+ * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
+ * returns a handle on success, and zero on error.
+ */
+
+static void *
+xmlModulePlatformOpen(const char *name)
+{
+    char errbuf[256];
+    void *handle;
+    int rc;
+
+    rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);
+
+    if (rc)
+        return 0;
+    else
+        return (handle);
+}
+
+/*
+ * xmlModulePlatformClose:
+ * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
+ * returns 0 on success, and non-zero on error.
+ */
+
+static int
+xmlModulePlatformClose(void *handle)
+{
+    return DosFreeModule(handle);
+}
+
+/*
+ * xmlModulePlatformSymbol:
+ * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
+ * returns 0 on success and the loaded symbol in result, and -1 on error.
+ */
+
+static int
+xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
+{
+    int rc;
+
+    rc = DosQueryProcAddr(handle, 0, name, symbol);
+
+    return (rc == NO_ERROR) ? 0 : -1;
+}
+
+#endif /* HAVE_OS2 */
+
+#define bottom_xmlmodule
+#include "elfgcchack.h"
+#endif /* LIBXML_MODULES_ENABLED */
diff --git a/src/xmlreader.c b/src/xmlreader.c
new file mode 100644
index 0000000..e39faec
--- /dev/null
+++ b/src/xmlreader.c
@@ -0,0 +1,5760 @@
+/*
+ * xmlreader.c: implements the xmlTextReader streaming node API
+ *
+ * NOTE:
+ *   XmlTextReader.Normalization Property won't be supported, since
+ *     it makes the parser non compliant to the XML recommendation
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+/*
+ * TODOs:
+ *   - XML Schemas validation
+ */
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_READER_ENABLED
+#include <string.h> /* for memset() only ! */
+#include <stdarg.h>
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlreader.h>
+#include <libxml/parserInternals.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+#include <libxml/uri.h>
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
+
+#define MAX_ERR_MSG_SIZE 64000
+
+/*
+ * The following VA_COPY was coded following an example in
+ * the Samba project.  It may not be sufficient for some
+ * esoteric implementations of va_list (i.e. it may need
+ * something involving a memcpy) but (hopefully) will be
+ * sufficient for libxml2.
+ */
+#ifndef VA_COPY
+  #ifdef HAVE_VA_COPY
+    #define VA_COPY(dest, src) va_copy(dest, src)
+  #else
+    #ifdef HAVE___VA_COPY
+      #define VA_COPY(dest,src) __va_copy(dest, src)
+    #else
+      #define VA_COPY(dest,src) (dest) = (src)
+    #endif
+  #endif
+#endif
+
+/* #define DEBUG_CALLBACKS */
+/* #define DEBUG_READER */
+
+/**
+ * TODO:
+ *
+ * macro to flag unimplemented blocks
+ */
+#define TODO								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#ifdef DEBUG_READER
+#define DUMP_READER xmlTextReaderDebug(reader);
+#else
+#define DUMP_READER
+#endif
+
+#define CHUNK_SIZE 512
+/************************************************************************
+ *									*
+ *	The parser: maps the Text Reader API on top of the existing	*
+ *		parsing routines building a tree			*
+ *									*
+ ************************************************************************/
+
+#define XML_TEXTREADER_INPUT	1
+#define XML_TEXTREADER_CTXT	2
+
+typedef enum {
+    XML_TEXTREADER_NONE = -1,
+    XML_TEXTREADER_START= 0,
+    XML_TEXTREADER_ELEMENT= 1,
+    XML_TEXTREADER_END= 2,
+    XML_TEXTREADER_EMPTY= 3,
+    XML_TEXTREADER_BACKTRACK= 4,
+    XML_TEXTREADER_DONE= 5,
+    XML_TEXTREADER_ERROR= 6
+} xmlTextReaderState;
+
+typedef enum {
+    XML_TEXTREADER_NOT_VALIDATE = 0,
+    XML_TEXTREADER_VALIDATE_DTD = 1,
+    XML_TEXTREADER_VALIDATE_RNG = 2,
+    XML_TEXTREADER_VALIDATE_XSD = 4
+} xmlTextReaderValidate;
+
+struct _xmlTextReader {
+    int				mode;	/* the parsing mode */
+    xmlDocPtr			doc;    /* when walking an existing doc */
+    xmlTextReaderValidate       validate;/* is there any validation */
+    int				allocs;	/* what structure were deallocated */
+    xmlTextReaderState		state;
+    xmlParserCtxtPtr		ctxt;	/* the parser context */
+    xmlSAXHandlerPtr		sax;	/* the parser SAX callbacks */
+    xmlParserInputBufferPtr	input;	/* the input */
+    startElementSAXFunc		startElement;/* initial SAX callbacks */
+    endElementSAXFunc		endElement;  /* idem */
+    startElementNsSAX2Func	startElementNs;/* idem */
+    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 */
+    xmlNodePtr			node;	/* current node */
+    xmlNodePtr			curnode;/* current attribute node */
+    int				depth;  /* depth of the current node */
+    xmlNodePtr			faketext;/* fake xmlNs chld */
+    int				preserve;/* preserve the resulting document */
+    xmlBufferPtr		buffer; /* used to return const xmlChar * */
+    xmlDictPtr			dict;	/* the context dictionnary */
+
+    /* entity stack when traversing entities content */
+    xmlNodePtr         ent;          /* Current Entity Ref Node */
+    int                entNr;        /* Depth of the entities stack */
+    int                entMax;       /* Max depth of the entities stack */
+    xmlNodePtr        *entTab;       /* array of entities */
+
+    /* error handling */
+    xmlTextReaderErrorFunc errorFunc;    /* callback function */
+    void                  *errorFuncArg; /* callback function user argument */
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+    /* Handling of RelaxNG validation */
+    xmlRelaxNGPtr          rngSchemas;	/* The Relax NG schemas */
+    xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
+    int                    rngValidErrors;/* The number of errors detected */
+    xmlNodePtr             rngFullNode;	/* the node if RNG not progressive */
+    /* Handling of Schemas validation */
+    xmlSchemaPtr          xsdSchemas;	/* The Schemas schemas */
+    xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */
+    int                   xsdPreserveCtxt; /* 1 if the context was provided by the user */
+    int                   xsdValidErrors;/* The number of errors detected */
+    xmlSchemaSAXPlugPtr   xsdPlug;	/* the schemas plug in SAX pipeline */
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+    /* Handling of XInclude processing */
+    int                xinclude;	/* is xinclude asked for */
+    const xmlChar *    xinclude_name;	/* the xinclude name from dict */
+    xmlXIncludeCtxtPtr xincctxt;	/* the xinclude context */
+    int                in_xinclude;	/* counts for xinclude */
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+    int                patternNr;       /* number of preserve patterns */
+    int                patternMax;      /* max preserve patterns */
+    xmlPatternPtr     *patternTab;      /* array of preserve patterns */
+#endif
+    int                preserves;	/* level of preserves */
+    int                parserFlags;	/* the set of options set */
+    /* Structured error handling */
+    xmlStructuredErrorFunc sErrorFunc;  /* callback function */
+};
+
+#define NODE_IS_EMPTY		0x1
+#define NODE_IS_PRESERVED	0x2
+#define NODE_IS_SPRESERVED	0x4
+
+/**
+ * CONSTSTR:
+ *
+ * Macro used to return an interned string
+ */
+#define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
+#define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
+
+static int xmlTextReaderReadTree(xmlTextReaderPtr reader);
+static int xmlTextReaderNextTree(xmlTextReaderPtr reader);
+
+/************************************************************************
+ *									*
+ *	Our own version of the freeing routines as we recycle nodes	*
+ *									*
+ ************************************************************************/
+/**
+ * DICT_FREE:
+ * @str:  a string
+ *
+ * Free a string if it is not owned by the "dict" dictionnary in the
+ * current scope
+ */
+#define DICT_FREE(str)						\
+	if ((str) && ((!dict) ||				\
+	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
+	    xmlFree((char *)(str));
+
+static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
+static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);
+
+/**
+ * xmlFreeID:
+ * @not:  A id
+ *
+ * Deallocate the memory used by an id definition
+ */
+static void
+xmlFreeID(xmlIDPtr id) {
+    xmlDictPtr dict = NULL;
+
+    if (id == NULL) return;
+
+    if (id->doc != NULL)
+        dict = id->doc->dict;
+
+    if (id->value != NULL)
+	DICT_FREE(id->value)
+    xmlFree(id);
+}
+
+/**
+ * xmlTextReaderRemoveID:
+ * @doc:  the document
+ * @attr:  the attribute
+ *
+ * Remove the given attribute from the ID table maintained internally.
+ *
+ * Returns -1 if the lookup failed and 0 otherwise
+ */
+static int
+xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
+    xmlIDTablePtr table;
+    xmlIDPtr id;
+    xmlChar *ID;
+
+    if (doc == NULL) return(-1);
+    if (attr == NULL) return(-1);
+    table = (xmlIDTablePtr) doc->ids;
+    if (table == NULL)
+        return(-1);
+
+    ID = xmlNodeListGetString(doc, attr->children, 1);
+    if (ID == NULL)
+	return(-1);
+    id = xmlHashLookup(table, ID);
+    xmlFree(ID);
+    if (id == NULL || id->attr != attr) {
+	return(-1);
+    }
+    id->name = attr->name;
+    id->attr = NULL;
+    return(0);
+}
+
+/**
+ * xmlTextReaderFreeProp:
+ * @reader:  the xmlTextReaderPtr used
+ * @cur:  the node
+ *
+ * Free a node.
+ */
+static void
+xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
+    xmlDictPtr dict;
+
+    dict = reader->ctxt->dict;
+    if (cur == NULL) return;
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
+
+    /* Check for ID removal -> leading to invalid references ! */
+    if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
+	((cur->parent->doc->intSubset != NULL) ||
+	 (cur->parent->doc->extSubset != NULL))) {
+        if (xmlIsID(cur->parent->doc, cur->parent, cur))
+	    xmlTextReaderRemoveID(cur->parent->doc, cur);
+    }
+    if (cur->children != NULL)
+        xmlTextReaderFreeNodeList(reader, cur->children);
+
+    DICT_FREE(cur->name);
+    if ((reader != NULL) && (reader->ctxt != NULL) &&
+        (reader->ctxt->freeAttrsNr < 100)) {
+        cur->next = reader->ctxt->freeAttrs;
+	reader->ctxt->freeAttrs = cur;
+	reader->ctxt->freeAttrsNr++;
+    } else {
+	xmlFree(cur);
+    }
+}
+
+/**
+ * xmlTextReaderFreePropList:
+ * @reader:  the xmlTextReaderPtr used
+ * @cur:  the first property in the list
+ *
+ * Free a property and all its siblings, all the children are freed too.
+ */
+static void
+xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
+    xmlAttrPtr next;
+    if (cur == NULL) return;
+    while (cur != NULL) {
+        next = cur->next;
+        xmlTextReaderFreeProp(reader, cur);
+	cur = next;
+    }
+}
+
+/**
+ * xmlTextReaderFreeNodeList:
+ * @reader:  the xmlTextReaderPtr used
+ * @cur:  the first node in the list
+ *
+ * Free a node and all its siblings, this is a recursive behaviour, all
+ * the children are freed too.
+ */
+static void
+xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
+    xmlNodePtr next;
+    xmlDictPtr dict;
+
+    dict = reader->ctxt->dict;
+    if (cur == NULL) return;
+    if (cur->type == XML_NAMESPACE_DECL) {
+	xmlFreeNsList((xmlNsPtr) cur);
+	return;
+    }
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+	(cur->type == XML_HTML_DOCUMENT_NODE)) {
+	xmlFreeDoc((xmlDocPtr) cur);
+	return;
+    }
+    while (cur != NULL) {
+        next = cur->next;
+	/* unroll to speed up freeing the document */
+	if (cur->type != XML_DTD_NODE) {
+
+	    if ((cur->children != NULL) &&
+		(cur->type != XML_ENTITY_REF_NODE)) {
+		if (cur->children->parent == cur)
+		    xmlTextReaderFreeNodeList(reader, cur->children);
+		cur->children = NULL;
+	    }
+
+	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+		xmlDeregisterNodeDefaultValue(cur);
+
+	    if (((cur->type == XML_ELEMENT_NODE) ||
+		 (cur->type == XML_XINCLUDE_START) ||
+		 (cur->type == XML_XINCLUDE_END)) &&
+		(cur->properties != NULL))
+		xmlTextReaderFreePropList(reader, cur->properties);
+	    if ((cur->content != (xmlChar *) &(cur->properties)) &&
+	        (cur->type != XML_ELEMENT_NODE) &&
+		(cur->type != XML_XINCLUDE_START) &&
+		(cur->type != XML_XINCLUDE_END) &&
+		(cur->type != XML_ENTITY_REF_NODE)) {
+		DICT_FREE(cur->content);
+	    }
+	    if (((cur->type == XML_ELEMENT_NODE) ||
+	         (cur->type == XML_XINCLUDE_START) ||
+		 (cur->type == XML_XINCLUDE_END)) &&
+		(cur->nsDef != NULL))
+		xmlFreeNsList(cur->nsDef);
+
+	    /*
+	     * we don't free element names here they are interned now
+	     */
+	    if ((cur->type != XML_TEXT_NODE) &&
+		(cur->type != XML_COMMENT_NODE))
+		DICT_FREE(cur->name);
+	    if (((cur->type == XML_ELEMENT_NODE) ||
+		 (cur->type == XML_TEXT_NODE)) &&
+	        (reader != NULL) && (reader->ctxt != NULL) &&
+		(reader->ctxt->freeElemsNr < 100)) {
+	        cur->next = reader->ctxt->freeElems;
+		reader->ctxt->freeElems = cur;
+		reader->ctxt->freeElemsNr++;
+	    } else {
+		xmlFree(cur);
+	    }
+	}
+	cur = next;
+    }
+}
+
+/**
+ * xmlTextReaderFreeNode:
+ * @reader:  the xmlTextReaderPtr used
+ * @cur:  the node
+ *
+ * Free a node, this is a recursive behaviour, all the children are freed too.
+ * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
+ */
+static void
+xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
+    xmlDictPtr dict;
+
+    dict = reader->ctxt->dict;
+    if (cur->type == XML_DTD_NODE) {
+	xmlFreeDtd((xmlDtdPtr) cur);
+	return;
+    }
+    if (cur->type == XML_NAMESPACE_DECL) {
+	xmlFreeNs((xmlNsPtr) cur);
+        return;
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+	xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);
+	return;
+    }
+
+    if ((cur->children != NULL) &&
+	(cur->type != XML_ENTITY_REF_NODE)) {
+	if (cur->children->parent == cur)
+	    xmlTextReaderFreeNodeList(reader, cur->children);
+	cur->children = NULL;
+    }
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue(cur);
+
+    if (((cur->type == XML_ELEMENT_NODE) ||
+	 (cur->type == XML_XINCLUDE_START) ||
+	 (cur->type == XML_XINCLUDE_END)) &&
+	(cur->properties != NULL))
+	xmlTextReaderFreePropList(reader, cur->properties);
+    if ((cur->content != (xmlChar *) &(cur->properties)) &&
+        (cur->type != XML_ELEMENT_NODE) &&
+	(cur->type != XML_XINCLUDE_START) &&
+	(cur->type != XML_XINCLUDE_END) &&
+	(cur->type != XML_ENTITY_REF_NODE)) {
+	DICT_FREE(cur->content);
+    }
+    if (((cur->type == XML_ELEMENT_NODE) ||
+	 (cur->type == XML_XINCLUDE_START) ||
+	 (cur->type == XML_XINCLUDE_END)) &&
+	(cur->nsDef != NULL))
+	xmlFreeNsList(cur->nsDef);
+
+    /*
+     * we don't free names here they are interned now
+     */
+    if ((cur->type != XML_TEXT_NODE) &&
+        (cur->type != XML_COMMENT_NODE))
+	DICT_FREE(cur->name);
+
+    if (((cur->type == XML_ELEMENT_NODE) ||
+	 (cur->type == XML_TEXT_NODE)) &&
+	(reader != NULL) && (reader->ctxt != NULL) &&
+	(reader->ctxt->freeElemsNr < 100)) {
+	cur->next = reader->ctxt->freeElems;
+	reader->ctxt->freeElems = cur;
+	reader->ctxt->freeElemsNr++;
+    } else {
+	xmlFree(cur);
+    }
+}
+
+/**
+ * xmlTextReaderFreeIDTable:
+ * @table:  An id table
+ *
+ * Deallocate the memory used by an ID hash table.
+ */
+static void
+xmlTextReaderFreeIDTable(xmlIDTablePtr table) {
+    xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
+}
+
+/**
+ * xmlTextReaderFreeDoc:
+ * @reader:  the xmlTextReaderPtr used
+ * @cur:  pointer to the document
+ *
+ * Free up all the structures used by a document, tree included.
+ */
+static void
+xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
+    xmlDtdPtr extSubset, intSubset;
+
+    if (cur == NULL) return;
+
+    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
+	xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
+
+    /*
+     * Do this before freeing the children list to avoid ID lookups
+     */
+    if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids);
+    cur->ids = NULL;
+    if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
+    cur->refs = NULL;
+    extSubset = cur->extSubset;
+    intSubset = cur->intSubset;
+    if (intSubset == extSubset)
+	extSubset = NULL;
+    if (extSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) cur->extSubset);
+	cur->extSubset = NULL;
+	xmlFreeDtd(extSubset);
+    }
+    if (intSubset != NULL) {
+	xmlUnlinkNode((xmlNodePtr) cur->intSubset);
+	cur->intSubset = NULL;
+	xmlFreeDtd(intSubset);
+    }
+
+    if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);
+
+    if (cur->version != NULL) xmlFree((char *) cur->version);
+    if (cur->name != NULL) xmlFree((char *) cur->name);
+    if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
+    if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
+    if (cur->URL != NULL) xmlFree((char *) cur->URL);
+    if (cur->dict != NULL) xmlDictFree(cur->dict);
+
+    xmlFree(cur);
+}
+
+/************************************************************************
+ *									*
+ *			The reader core parser				*
+ *									*
+ ************************************************************************/
+#ifdef DEBUG_READER
+static void
+xmlTextReaderDebug(xmlTextReaderPtr reader) {
+    if ((reader == NULL) || (reader->ctxt == NULL)) {
+	fprintf(stderr, "xmlTextReader NULL\n");
+	return;
+    }
+    fprintf(stderr, "xmlTextReader: state %d depth %d ",
+	    reader->state, reader->depth);
+    if (reader->node == NULL) {
+	fprintf(stderr, "node = NULL\n");
+    } else {
+	fprintf(stderr, "node %s\n", reader->node->name);
+    }
+    fprintf(stderr, "  input: base %d, cur %d, depth %d: ",
+	    reader->base, reader->cur, reader->ctxt->nodeNr);
+    if (reader->input->buffer == NULL) {
+	fprintf(stderr, "buffer is NULL\n");
+    } else {
+#ifdef LIBXML_DEBUG_ENABLED
+	xmlDebugDumpString(stderr,
+		&reader->input->buffer->content[reader->cur]);
+#endif
+	fprintf(stderr, "\n");
+    }
+}
+#endif
+
+/**
+ * xmlTextReaderEntPush:
+ * @reader:  the xmlTextReaderPtr used
+ * @value:  the entity reference node
+ *
+ * Pushes a new entity reference node on top of the entities stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)
+{
+    if (reader->entMax <= 0) {
+	reader->entMax = 10;
+	reader->entTab = (xmlNodePtr *) xmlMalloc(reader->entMax *
+		                                  sizeof(reader->entTab[0]));
+        if (reader->entTab == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
+            return (0);
+        }
+    }
+    if (reader->entNr >= reader->entMax) {
+        reader->entMax *= 2;
+        reader->entTab =
+            (xmlNodePtr *) xmlRealloc(reader->entTab,
+                                      reader->entMax *
+                                      sizeof(reader->entTab[0]));
+        if (reader->entTab == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
+            return (0);
+        }
+    }
+    reader->entTab[reader->entNr] = value;
+    reader->ent = value;
+    return (reader->entNr++);
+}
+
+/**
+ * xmlTextReaderEntPop:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Pops the top element entity from the entities stack
+ *
+ * Returns the entity just removed
+ */
+static xmlNodePtr
+xmlTextReaderEntPop(xmlTextReaderPtr reader)
+{
+    xmlNodePtr ret;
+
+    if (reader->entNr <= 0)
+        return (NULL);
+    reader->entNr--;
+    if (reader->entNr > 0)
+        reader->ent = reader->entTab[reader->entNr - 1];
+    else
+        reader->ent = NULL;
+    ret = reader->entTab[reader->entNr];
+    reader->entTab[reader->entNr] = NULL;
+    return (ret);
+}
+
+/**
+ * xmlTextReaderStartElement:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The element name, including namespace prefix
+ * @atts:  An array of name/value attributes pairs, NULL terminated
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
+	                  const xmlChar **atts) {
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderStartElement(%s)\n", fullname);
+#endif
+    if ((reader != NULL) && (reader->startElement != NULL)) {
+	reader->startElement(ctx, fullname, atts);
+	if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
+	    (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
+	    (ctxt->input->cur[1] == '>'))
+	    ctxt->node->extra = NODE_IS_EMPTY;
+    }
+    if (reader != NULL)
+	reader->state = XML_TEXTREADER_ELEMENT;
+}
+
+/**
+ * xmlTextReaderEndElement:
+ * @ctx: the user data (XML parser context)
+ * @fullname:  The element name, including namespace prefix
+ *
+ * called when an ending tag has been processed.
+ */
+static void
+xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderEndElement(%s)\n", fullname);
+#endif
+    if ((reader != NULL) && (reader->endElement != NULL)) {
+	reader->endElement(ctx, fullname);
+    }
+}
+
+/**
+ * xmlTextReaderStartElementNs:
+ * @ctx: the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ * @nb_namespaces:  number of namespace definitions on that node
+ * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
+ * @nb_attributes:  the number of attributes on that node
+ * nb_defaulted:  the number of defaulted attributes.
+ * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
+ *               attribute values.
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+xmlTextReaderStartElementNs(void *ctx,
+                      const xmlChar *localname,
+		      const xmlChar *prefix,
+		      const xmlChar *URI,
+		      int nb_namespaces,
+		      const xmlChar **namespaces,
+		      int nb_attributes,
+		      int nb_defaulted,
+		      const xmlChar **attributes)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderStartElementNs(%s)\n", localname);
+#endif
+    if ((reader != NULL) && (reader->startElementNs != NULL)) {
+	reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
+	                       namespaces, nb_attributes, nb_defaulted,
+			       attributes);
+	if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
+	    (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
+	    (ctxt->input->cur[1] == '>'))
+	    ctxt->node->extra = NODE_IS_EMPTY;
+    }
+    if (reader != NULL)
+	reader->state = XML_TEXTREADER_ELEMENT;
+}
+
+/**
+ * xmlTextReaderEndElementNs:
+ * @ctx: the user data (XML parser context)
+ * @localname:  the local name of the element
+ * @prefix:  the element namespace prefix if available
+ * @URI:  the element namespace name if available
+ *
+ * called when an ending tag has been processed.
+ */
+static void
+xmlTextReaderEndElementNs(void *ctx,
+                          const xmlChar * localname,
+                          const xmlChar * prefix,
+		          const xmlChar * URI)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderEndElementNs(%s)\n", localname);
+#endif
+    if ((reader != NULL) && (reader->endElementNs != NULL)) {
+	reader->endElementNs(ctx, localname, prefix, URI);
+    }
+}
+
+
+/**
+ * xmlTextReaderCharacters:
+ * @ctx: the user data (XML parser context)
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ */
+static void
+xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderCharacters()\n");
+#endif
+    if ((reader != NULL) && (reader->characters != NULL)) {
+	reader->characters(ctx, ch, len);
+    }
+}
+
+/**
+ * xmlTextReaderCDataBlock:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlTextReaderPtr reader = ctxt->_private;
+
+#ifdef DEBUG_CALLBACKS
+    printf("xmlTextReaderCDataBlock()\n");
+#endif
+    if ((reader != NULL) && (reader->cdataBlock != NULL)) {
+	reader->cdataBlock(ctx, ch, len);
+    }
+}
+
+/**
+ * xmlTextReaderPushData:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Push data down the progressive parser until a significant callback
+ * got raised.
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+static int
+xmlTextReaderPushData(xmlTextReaderPtr reader) {
+    xmlBufferPtr inbuf;
+    int val, s;
+    xmlTextReaderState oldstate;
+
+    if ((reader->input == NULL) || (reader->input->buffer == NULL))
+	return(-1);
+
+    oldstate = reader->state;
+    reader->state = XML_TEXTREADER_NONE;
+    inbuf = reader->input->buffer;
+
+    while (reader->state == XML_TEXTREADER_NONE) {
+	if (inbuf->use < reader->cur + CHUNK_SIZE) {
+	    /*
+	     * Refill the buffer unless we are at the end of the stream
+	     */
+	    if (reader->mode != XML_TEXTREADER_MODE_EOF) {
+		val = xmlParserInputBufferRead(reader->input, 4096);
+		if ((val == 0) &&
+		    (inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
+		    if (inbuf->use == reader->cur) {
+			reader->mode = XML_TEXTREADER_MODE_EOF;
+			reader->state = oldstate;
+		    }
+		} else if (val < 0) {
+		    reader->mode = XML_TEXTREADER_MODE_EOF;
+		    reader->state = oldstate;
+		    if ((oldstate != XML_TEXTREADER_START) ||
+			(reader->ctxt->myDoc != NULL))
+			return(val);
+		} else if (val == 0) {
+		    /* mark the end of the stream and process the remains */
+		    reader->mode = XML_TEXTREADER_MODE_EOF;
+		    break;
+		}
+
+	    } else
+		break;
+	}
+	/*
+	 * parse by block of CHUNK_SIZE bytes, various tests show that
+	 * it's the best tradeoff at least on a 1.2GH Duron
+	 */
+	if (inbuf->use >= reader->cur + CHUNK_SIZE) {
+	    val = xmlParseChunk(reader->ctxt,
+		          (const char *) &inbuf->content[reader->cur],
+			  CHUNK_SIZE, 0);
+	    reader->cur += CHUNK_SIZE;
+	    if ((val != 0) || (reader->ctxt->wellFormed == 0))
+		return(-1);
+	} else {
+	    s = inbuf->use - reader->cur;
+	    val = xmlParseChunk(reader->ctxt,
+		          (const char *) &inbuf->content[reader->cur],
+			  s, 0);
+	    reader->cur += s;
+	    if ((val != 0) || (reader->ctxt->wellFormed == 0))
+		return(-1);
+	    break;
+	}
+    }
+
+    /*
+     * Discard the consumed input when needed and possible
+     */
+    if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
+        if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
+	    if ((reader->cur >= 4096) &&
+		(inbuf->use - reader->cur <= CHUNK_SIZE)) {
+		val = xmlBufferShrink(inbuf, reader->cur);
+		if (val >= 0) {
+		    reader->cur -= val;
+		}
+	    }
+	}
+    }
+
+    /*
+     * At the end of the stream signal that the work is done to the Push
+     * parser.
+     */
+    else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
+	if (reader->state != XML_TEXTREADER_DONE) {
+	    s = inbuf->use - reader->cur;
+	    val = xmlParseChunk(reader->ctxt,
+		    (const char *) &inbuf->content[reader->cur],
+		    s, 1);
+	    reader->cur = inbuf->use;
+	    reader->state  = XML_TEXTREADER_DONE;
+	    if ((val != 0) || (reader->ctxt->wellFormed == 0))
+	        return(-1);
+	}
+    }
+    reader->state = oldstate;
+    return(0);
+}
+
+#ifdef LIBXML_REGEXP_ENABLED
+/**
+ * xmlTextReaderValidatePush:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Push the current node for validation
+ */
+static void
+xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
+    xmlNodePtr node = reader->node;
+
+#ifdef LIBXML_VALID_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
+        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
+	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
+	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
+				    reader->ctxt->myDoc, node, node->name);
+	} else {
+	    /* TODO use the BuildQName interface */
+	    xmlChar *qname;
+
+	    qname = xmlStrdup(node->ns->prefix);
+	    qname = xmlStrcat(qname, BAD_CAST ":");
+	    qname = xmlStrcat(qname, node->name);
+	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
+				    reader->ctxt->myDoc, node, qname);
+	    if (qname != NULL)
+		xmlFree(qname);
+	}
+    }
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
+               (reader->rngValidCtxt != NULL)) {
+	int ret;
+
+	if (reader->rngFullNode != NULL) return;
+	ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
+	                                    reader->ctxt->myDoc,
+					    node);
+	if (ret == 0) {
+	    /*
+	     * this element requires a full tree
+	     */
+	    node = xmlTextReaderExpand(reader);
+	    if (node == NULL) {
+printf("Expand failed !\n");
+	        ret = -1;
+	    } else {
+		ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
+						    reader->ctxt->myDoc,
+						    node);
+		reader->rngFullNode = node;
+	    }
+	}
+	if (ret != 1)
+	    reader->rngValidErrors++;
+    }
+#endif
+}
+
+/**
+ * xmlTextReaderValidateCData:
+ * @reader:  the xmlTextReaderPtr used
+ * @data:  pointer to the CData
+ * @len:  lenght of the CData block in bytes.
+ *
+ * Push some CData for validation
+ */
+static void
+xmlTextReaderValidateCData(xmlTextReaderPtr reader,
+                           const xmlChar *data, int len) {
+#ifdef LIBXML_VALID_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
+        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
+	reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
+	                                            data, len);
+    }
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
+               (reader->rngValidCtxt != NULL)) {
+	int ret;
+
+	if (reader->rngFullNode != NULL) return;
+	ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
+	if (ret != 1)
+	    reader->rngValidErrors++;
+    }
+#endif
+}
+
+/**
+ * xmlTextReaderValidatePop:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Pop the current node from validation
+ */
+static void
+xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
+    xmlNodePtr node = reader->node;
+
+#ifdef LIBXML_VALID_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
+        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
+	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
+	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
+				    reader->ctxt->myDoc, node, node->name);
+	} else {
+	    /* TODO use the BuildQName interface */
+	    xmlChar *qname;
+
+	    qname = xmlStrdup(node->ns->prefix);
+	    qname = xmlStrcat(qname, BAD_CAST ":");
+	    qname = xmlStrcat(qname, node->name);
+	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
+				    reader->ctxt->myDoc, node, qname);
+	    if (qname != NULL)
+		xmlFree(qname);
+	}
+    }
+#endif /* LIBXML_VALID_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
+               (reader->rngValidCtxt != NULL)) {
+	int ret;
+
+	if (reader->rngFullNode != NULL) {
+	    if (node == reader->rngFullNode)
+	        reader->rngFullNode = NULL;
+	    return;
+	}
+	ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
+	                                   reader->ctxt->myDoc,
+					   node);
+	if (ret != 1)
+	    reader->rngValidErrors++;
+    }
+#endif
+}
+
+/**
+ * xmlTextReaderValidateEntity:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Handle the validation when an entity reference is encountered and
+ * entity substitution is not activated. As a result the parser interface
+ * must walk through the entity and do the validation calls
+ */
+static void
+xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
+    xmlNodePtr oldnode = reader->node;
+    xmlNodePtr node = reader->node;
+    xmlParserCtxtPtr ctxt = reader->ctxt;
+
+    do {
+	if (node->type == XML_ENTITY_REF_NODE) {
+	    /*
+	     * Case where the underlying tree is not availble, lookup the entity
+	     * and walk it.
+	     */
+	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
+		(ctxt->sax->getEntity != NULL)) {
+		node->children = (xmlNodePtr)
+		    ctxt->sax->getEntity(ctxt, node->name);
+	    }
+
+	    if ((node->children != NULL) &&
+		(node->children->type == XML_ENTITY_DECL) &&
+		(node->children->children != NULL)) {
+		xmlTextReaderEntPush(reader, node);
+		node = node->children->children;
+		continue;
+	    } else {
+		/*
+		 * The error has probably be raised already.
+		 */
+		if (node == oldnode)
+		    break;
+		node = node->next;
+	    }
+#ifdef LIBXML_REGEXP_ENABLED
+	} else if (node->type == XML_ELEMENT_NODE) {
+	    reader->node = node;
+	    xmlTextReaderValidatePush(reader);
+	} else if ((node->type == XML_TEXT_NODE) ||
+		   (node->type == XML_CDATA_SECTION_NODE)) {
+            xmlTextReaderValidateCData(reader, node->content,
+	                               xmlStrlen(node->content));
+#endif
+	}
+
+	/*
+	 * go to next node
+	 */
+	if (node->children != NULL) {
+	    node = node->children;
+	    continue;
+	} else if (node->type == XML_ELEMENT_NODE) {
+	    xmlTextReaderValidatePop(reader);
+	}
+	if (node->next != NULL) {
+	    node = node->next;
+	    continue;
+	}
+	do {
+	    node = node->parent;
+	    if (node->type == XML_ELEMENT_NODE) {
+	        xmlNodePtr tmp;
+		if (reader->entNr == 0) {
+		    while ((tmp = node->last) != NULL) {
+			if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
+			    xmlUnlinkNode(tmp);
+			    xmlTextReaderFreeNode(reader, tmp);
+			} else
+			    break;
+		    }
+		}
+		reader->node = node;
+		xmlTextReaderValidatePop(reader);
+	    }
+	    if ((node->type == XML_ENTITY_DECL) &&
+		(reader->ent != NULL) && (reader->ent->children == node)) {
+		node = xmlTextReaderEntPop(reader);
+	    }
+	    if (node == oldnode)
+		break;
+	    if (node->next != NULL) {
+		node = node->next;
+		break;
+	    }
+	} while ((node != NULL) && (node != oldnode));
+    } while ((node != NULL) && (node != oldnode));
+    reader->node = oldnode;
+}
+#endif /* LIBXML_REGEXP_ENABLED */
+
+
+/**
+ * xmlTextReaderGetSuccessor:
+ * @cur:  the current node
+ *
+ * Get the successor of a node if available.
+ *
+ * Returns the successor node or NULL
+ */
+static xmlNodePtr
+xmlTextReaderGetSuccessor(xmlNodePtr cur) {
+    if (cur == NULL) return(NULL) ; /* ERROR */
+    if (cur->next != NULL) return(cur->next) ;
+    do {
+        cur = cur->parent;
+        if (cur == NULL) break;
+        if (cur->next != NULL) return(cur->next);
+    } while (cur != NULL);
+    return(cur);
+}
+
+/**
+ * xmlTextReaderDoExpand:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Makes sure that the current node is fully read as well as all its
+ * descendant. It means the full DOM subtree must be available at the
+ * end of the call.
+ *
+ * Returns 1 if the node was expanded successfully, 0 if there is no more
+ *          nodes to read, or -1 in case of error
+ */
+static int
+xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
+    int val;
+
+    if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
+        return(-1);
+    do {
+	if (reader->ctxt->instate == XML_PARSER_EOF) return(1);
+
+        if (xmlTextReaderGetSuccessor(reader->node) != NULL)
+	    return(1);
+	if (reader->ctxt->nodeNr < reader->depth)
+	    return(1);
+	if (reader->mode == XML_TEXTREADER_MODE_EOF)
+	    return(1);
+	val = xmlTextReaderPushData(reader);
+	if (val < 0){
+	    reader->mode = XML_TEXTREADER_MODE_ERROR;
+	    return(-1);
+	}
+    } while(reader->mode != XML_TEXTREADER_MODE_EOF);
+    return(1);
+}
+
+/**
+ * xmlTextReaderCollectSiblings:
+ * @node:    the first child
+ *
+ *  Traverse depth-first through all sibling nodes and their children
+ *  nodes and concatenate their content. This is an auxiliary function
+ *  to xmlTextReaderReadString.
+ *
+ *  Returns a string containing the content, or NULL in case of error.
+ */
+static xmlChar *
+xmlTextReaderCollectSiblings(xmlNodePtr node)
+{
+    xmlBufferPtr buffer;
+    xmlChar *ret;
+
+    buffer = xmlBufferCreate();
+    if (buffer == NULL)
+       return NULL;
+
+    for ( ; node != NULL; node = node->next) {
+       switch (node->type) {
+       case XML_TEXT_NODE:
+       case XML_CDATA_SECTION_NODE:
+           xmlBufferCat(buffer, node->content);
+           break;
+       case XML_ELEMENT_NODE: {
+           xmlChar *tmp;
+
+	   tmp = xmlTextReaderCollectSiblings(node->children);
+           xmlBufferCat(buffer, tmp);
+	   xmlFree(tmp);
+	   break;
+       }
+       default:
+           break;
+       }
+    }
+    ret = buffer->content;
+    buffer->content = NULL;
+    xmlBufferFree(buffer);
+    return(ret);
+}
+
+/**
+ * xmlTextReaderRead:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ *  Moves the position of the current instance to the next node in
+ *  the stream, exposing its properties.
+ *
+ *  Returns 1 if the node was read successfully, 0 if there is no more
+ *          nodes to read, or -1 in case of error
+ */
+int
+xmlTextReaderRead(xmlTextReaderPtr reader) {
+    int val, olddepth = 0;
+    xmlTextReaderState oldstate = XML_TEXTREADER_START;
+    xmlNodePtr oldnode = NULL;
+
+
+    if (reader == NULL)
+	return(-1);
+    reader->curnode = NULL;
+    if (reader->doc != NULL)
+        return(xmlTextReaderReadTree(reader));
+    if (reader->ctxt == NULL)
+	return(-1);
+    if (reader->ctxt->wellFormed != 1)
+	return(-1);
+
+#ifdef DEBUG_READER
+    fprintf(stderr, "\nREAD ");
+    DUMP_READER
+#endif
+    if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
+	reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
+	/*
+	 * Initial state
+	 */
+	do {
+	    val = xmlTextReaderPushData(reader);
+		if (val < 0){
+			reader->mode = XML_TEXTREADER_MODE_ERROR;
+			reader->state = XML_TEXTREADER_ERROR;
+		return(-1);
+		}
+	} while ((reader->ctxt->node == NULL) &&
+		 ((reader->mode != XML_TEXTREADER_MODE_EOF) &&
+		  (reader->state != XML_TEXTREADER_DONE)));
+	if (reader->ctxt->node == NULL) {
+	    if (reader->ctxt->myDoc != NULL) {
+		reader->node = reader->ctxt->myDoc->children;
+	    }
+	    if (reader->node == NULL){
+			reader->mode = XML_TEXTREADER_MODE_ERROR;
+			reader->state = XML_TEXTREADER_ERROR;
+		return(-1);
+		}
+	    reader->state = XML_TEXTREADER_ELEMENT;
+	} else {
+	    if (reader->ctxt->myDoc != NULL) {
+		reader->node = reader->ctxt->myDoc->children;
+	    }
+	    if (reader->node == NULL)
+		reader->node = reader->ctxt->nodeTab[0];
+	    reader->state = XML_TEXTREADER_ELEMENT;
+	}
+	reader->depth = 0;
+	reader->ctxt->parseMode = XML_PARSE_READER;
+	goto node_found;
+    }
+    oldstate = reader->state;
+    olddepth = reader->ctxt->nodeNr;
+    oldnode = reader->node;
+
+get_next_node:
+    if (reader->node == NULL) {
+	if (reader->mode == XML_TEXTREADER_MODE_EOF)
+	    return(0);
+	else
+	    return(-1);
+    }
+
+    /*
+     * If we are not backtracking on ancestors or examined nodes,
+     * that the parser didn't finished or that we arent at the end
+     * of stream, continue processing.
+     */
+    while ((reader->node != NULL) && (reader->node->next == NULL) &&
+	   (reader->ctxt->nodeNr == olddepth) &&
+           ((oldstate == XML_TEXTREADER_BACKTRACK) ||
+            (reader->node->children == NULL) ||
+	    (reader->node->type == XML_ENTITY_REF_NODE) ||
+	    ((reader->node->children != NULL) &&
+	     (reader->node->children->type == XML_TEXT_NODE) &&
+	     (reader->node->children->next == NULL)) ||
+	    (reader->node->type == XML_DTD_NODE) ||
+	    (reader->node->type == XML_DOCUMENT_NODE) ||
+	    (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
+	   ((reader->ctxt->node == NULL) ||
+	    (reader->ctxt->node == reader->node) ||
+	    (reader->ctxt->node == reader->node->parent)) &&
+	   (reader->ctxt->instate != XML_PARSER_EOF)) {
+	val = xmlTextReaderPushData(reader);
+	if (val < 0){
+		reader->mode = XML_TEXTREADER_MODE_ERROR;
+		reader->state = XML_TEXTREADER_ERROR;
+	    return(-1);
+	}
+	if (reader->node == NULL)
+	    goto node_end;
+    }
+    if (oldstate != XML_TEXTREADER_BACKTRACK) {
+	if ((reader->node->children != NULL) &&
+	    (reader->node->type != XML_ENTITY_REF_NODE) &&
+	    (reader->node->type != XML_XINCLUDE_START) &&
+	    (reader->node->type != XML_DTD_NODE)) {
+	    reader->node = reader->node->children;
+	    reader->depth++;
+	    reader->state = XML_TEXTREADER_ELEMENT;
+	    goto node_found;
+	}
+    }
+    if (reader->node->next != NULL) {
+	if ((oldstate == XML_TEXTREADER_ELEMENT) &&
+            (reader->node->type == XML_ELEMENT_NODE) &&
+	    (reader->node->children == NULL) &&
+	    ((reader->node->extra & NODE_IS_EMPTY) == 0)
+#ifdef LIBXML_XINCLUDE_ENABLED
+	    && (reader->in_xinclude <= 0)
+#endif
+	    ) {
+	    reader->state = XML_TEXTREADER_END;
+	    goto node_found;
+	}
+#ifdef LIBXML_REGEXP_ENABLED
+	if ((reader->validate) &&
+	    (reader->node->type == XML_ELEMENT_NODE))
+	    xmlTextReaderValidatePop(reader);
+#endif /* LIBXML_REGEXP_ENABLED */
+        if ((reader->preserves > 0) &&
+	    (reader->node->extra & NODE_IS_SPRESERVED))
+	    reader->preserves--;
+	reader->node = reader->node->next;
+	reader->state = XML_TEXTREADER_ELEMENT;
+
+	/*
+	 * Cleanup of the old node
+	 */
+	if ((reader->preserves == 0) &&
+#ifdef LIBXML_XINCLUDE_ENABLED
+	    (reader->in_xinclude == 0) &&
+#endif
+	    (reader->entNr == 0) &&
+	    (reader->node->prev != NULL) &&
+	    (reader->node->prev->type != XML_DTD_NODE)) {
+	    xmlNodePtr tmp = reader->node->prev;
+	    if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
+		xmlUnlinkNode(tmp);
+		xmlTextReaderFreeNode(reader, tmp);
+	    }
+	}
+
+	goto node_found;
+    }
+    if ((oldstate == XML_TEXTREADER_ELEMENT) &&
+	(reader->node->type == XML_ELEMENT_NODE) &&
+	(reader->node->children == NULL) &&
+	((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
+	reader->state = XML_TEXTREADER_END;
+	goto node_found;
+    }
+#ifdef LIBXML_REGEXP_ENABLED
+    if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
+	xmlTextReaderValidatePop(reader);
+#endif /* LIBXML_REGEXP_ENABLED */
+    if ((reader->preserves > 0) &&
+	(reader->node->extra & NODE_IS_SPRESERVED))
+	reader->preserves--;
+    reader->node = reader->node->parent;
+    if ((reader->node == NULL) ||
+	(reader->node->type == XML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+	(reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+	(reader->node->type == XML_HTML_DOCUMENT_NODE)) {
+	if (reader->mode != XML_TEXTREADER_MODE_EOF) {
+	    val = xmlParseChunk(reader->ctxt, "", 0, 1);
+	    reader->state = XML_TEXTREADER_DONE;
+	    if (val != 0)
+	        return(-1);
+	}
+	reader->node = NULL;
+	reader->depth = -1;
+
+	/*
+	 * Cleanup of the old node
+	 */
+	if ((oldnode != NULL) && (reader->preserves == 0) &&
+#ifdef LIBXML_XINCLUDE_ENABLED
+	    (reader->in_xinclude == 0) &&
+#endif
+	    (reader->entNr == 0) &&
+	    (oldnode->type != XML_DTD_NODE) &&
+	    ((oldnode->extra & NODE_IS_PRESERVED) == 0)) {
+	    xmlUnlinkNode(oldnode);
+	    xmlTextReaderFreeNode(reader, oldnode);
+	}
+
+	goto node_end;
+    }
+    if ((reader->preserves == 0) &&
+#ifdef LIBXML_XINCLUDE_ENABLED
+        (reader->in_xinclude == 0) &&
+#endif
+	(reader->entNr == 0) &&
+        (reader->node->last != NULL) &&
+        ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
+	xmlNodePtr tmp = reader->node->last;
+	xmlUnlinkNode(tmp);
+	xmlTextReaderFreeNode(reader, tmp);
+    }
+    reader->depth--;
+    reader->state = XML_TEXTREADER_BACKTRACK;
+
+node_found:
+    DUMP_READER
+
+    /*
+     * If we are in the middle of a piece of CDATA make sure it's finished
+     */
+    if ((reader->node != NULL) &&
+        (reader->node->next == NULL) &&
+        ((reader->node->type == XML_TEXT_NODE) ||
+	 (reader->node->type == XML_CDATA_SECTION_NODE))) {
+            if (xmlTextReaderExpand(reader) == NULL)
+	        return -1;
+    }
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+    /*
+     * Handle XInclude if asked for
+     */
+    if ((reader->xinclude) && (reader->node != NULL) &&
+	(reader->node->type == XML_ELEMENT_NODE) &&
+	(reader->node->ns != NULL) &&
+	((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
+	 (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
+	if (reader->xincctxt == NULL) {
+	    reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
+	    xmlXIncludeSetFlags(reader->xincctxt,
+	                        reader->parserFlags & (~XML_PARSE_NOXINCNODE));
+	}
+	/*
+	 * expand that node and process it
+	 */
+	if (xmlTextReaderExpand(reader) == NULL)
+	    return -1;
+	xmlXIncludeProcessNode(reader->xincctxt, reader->node);
+    }
+    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;
+    }
+#endif
+    /*
+     * Handle entities enter and exit when in entity replacement mode
+     */
+    if ((reader->node != NULL) &&
+	(reader->node->type == XML_ENTITY_REF_NODE) &&
+	(reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
+	/*
+	 * Case where the underlying tree is not availble, lookup the entity
+	 * and walk it.
+	 */
+	if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
+	    (reader->ctxt->sax->getEntity != NULL)) {
+	    reader->node->children = (xmlNodePtr)
+		reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
+	}
+
+	if ((reader->node->children != NULL) &&
+	    (reader->node->children->type == XML_ENTITY_DECL) &&
+	    (reader->node->children->children != NULL)) {
+	    xmlTextReaderEntPush(reader, reader->node);
+	    reader->node = reader->node->children->children;
+	}
+#ifdef LIBXML_REGEXP_ENABLED
+    } else if ((reader->node != NULL) &&
+	       (reader->node->type == XML_ENTITY_REF_NODE) &&
+	       (reader->ctxt != NULL) && (reader->validate)) {
+	xmlTextReaderValidateEntity(reader);
+#endif /* LIBXML_REGEXP_ENABLED */
+    }
+    if ((reader->node != NULL) &&
+	(reader->node->type == XML_ENTITY_DECL) &&
+	(reader->ent != NULL) && (reader->ent->children == reader->node)) {
+	reader->node = xmlTextReaderEntPop(reader);
+	reader->depth++;
+        goto get_next_node;
+    }
+#ifdef LIBXML_REGEXP_ENABLED
+    if ((reader->validate) && (reader->node != NULL)) {
+	xmlNodePtr node = reader->node;
+
+	if ((node->type == XML_ELEMENT_NODE) &&
+            ((reader->state != XML_TEXTREADER_END) &&
+	     (reader->state != XML_TEXTREADER_BACKTRACK))) {
+	    xmlTextReaderValidatePush(reader);
+	} else if ((node->type == XML_TEXT_NODE) ||
+		   (node->type == XML_CDATA_SECTION_NODE)) {
+            xmlTextReaderValidateCData(reader, node->content,
+	                               xmlStrlen(node->content));
+	}
+    }
+#endif /* LIBXML_REGEXP_ENABLED */
+#ifdef LIBXML_PATTERN_ENABLED
+    if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
+        (reader->state != XML_TEXTREADER_BACKTRACK)) {
+        int i;
+	for (i = 0;i < reader->patternNr;i++) {
+	     if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
+	         xmlTextReaderPreserve(reader);
+		 break;
+             }
+	}
+    }
+#endif /* LIBXML_PATTERN_ENABLED */
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
+        (reader->xsdValidErrors == 0) &&
+	(reader->xsdValidCtxt != NULL)) {
+	reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
+    }
+#endif /* LIBXML_PATTERN_ENABLED */
+    return(1);
+node_end:
+    reader->state = XML_TEXTREADER_DONE;
+    return(0);
+}
+
+/**
+ * xmlTextReaderReadState:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Gets the read state of the reader.
+ *
+ * Returns the state value, or -1 in case of error
+ */
+int
+xmlTextReaderReadState(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    return(reader->mode);
+}
+
+/**
+ * xmlTextReaderExpand:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Reads the contents of the current node and the full subtree. It then makes
+ * the subtree available until the next xmlTextReaderRead() call
+ *
+ * Returns a node pointer valid until the next xmlTextReaderRead() call
+ *         or NULL in case of error.
+ */
+xmlNodePtr
+xmlTextReaderExpand(xmlTextReaderPtr reader) {
+    if ((reader == NULL) || (reader->node == NULL))
+        return(NULL);
+    if (reader->doc != NULL)
+        return(reader->node);
+    if (reader->ctxt == NULL)
+        return(NULL);
+    if (xmlTextReaderDoExpand(reader) < 0)
+        return(NULL);
+    return(reader->node);
+}
+
+/**
+ * xmlTextReaderNext:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Skip to the node following the current one in document order while
+ * avoiding the subtree if any.
+ *
+ * Returns 1 if the node was read successfully, 0 if there is no more
+ *          nodes to read, or -1 in case of error
+ */
+int
+xmlTextReaderNext(xmlTextReaderPtr reader) {
+    int ret;
+    xmlNodePtr cur;
+
+    if (reader == NULL)
+	return(-1);
+    if (reader->doc != NULL)
+        return(xmlTextReaderNextTree(reader));
+    cur = reader->node;
+    if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
+        return(xmlTextReaderRead(reader));
+    if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
+        return(xmlTextReaderRead(reader));
+    if (cur->extra & NODE_IS_EMPTY)
+        return(xmlTextReaderRead(reader));
+    do {
+        ret = xmlTextReaderRead(reader);
+	if (ret != 1)
+	    return(ret);
+    } while (reader->node != cur);
+    return(xmlTextReaderRead(reader));
+}
+
+#ifdef LIBXML_WRITER_ENABLED
+/**
+ * xmlTextReaderReadInnerXml:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * 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.
+ */
+xmlChar *
+xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
+{
+    xmlChar *resbuf;
+    xmlNodePtr node, cur_node;
+    xmlBufferPtr buff, buff2;
+    xmlDocPtr doc;
+
+    if (xmlTextReaderExpand(reader) == NULL) {
+        return NULL;
+    }
+    doc = reader->doc;
+    buff = xmlBufferCreate();
+    for (cur_node = reader->node->children; cur_node != NULL;
+         cur_node = cur_node->next) {
+        node = xmlDocCopyNode(cur_node, doc, 1);
+        buff2 = xmlBufferCreate();
+        if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
+            xmlFreeNode(node);
+            xmlBufferFree(buff2);
+            xmlBufferFree(buff);
+            return NULL;
+        }
+        xmlBufferCat(buff, buff2->content);
+        xmlFreeNode(node);
+        xmlBufferFree(buff2);
+    }
+    resbuf = buff->content;
+    buff->content = NULL;
+
+    xmlBufferFree(buff);
+    return resbuf;
+}
+#endif
+
+#ifdef LIBXML_WRITER_ENABLED
+/**
+ * xmlTextReaderReadOuterXml:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * 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.
+ */
+xmlChar *
+xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
+{
+    xmlChar *resbuf;
+    xmlNodePtr node;
+    xmlBufferPtr buff;
+    xmlDocPtr doc;
+
+    node = reader->node;
+    doc = reader->doc;
+    if (xmlTextReaderExpand(reader) == NULL) {
+        return NULL;
+    }
+    node = xmlDocCopyNode(node, doc, 1);
+    buff = xmlBufferCreate();
+    if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
+        xmlFreeNode(node);
+        xmlBufferFree(buff);
+        return NULL;
+    }
+
+    resbuf = buff->content;
+    buff->content = NULL;
+
+    xmlFreeNode(node);
+    xmlBufferFree(buff);
+    return resbuf;
+}
+#endif
+
+/**
+ * xmlTextReaderReadString:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Reads the contents of an element or a text node as a string.
+ *
+ * Returns a string containing the contents of the Element or Text node,
+ *         or NULL if the reader is positioned on any other type of node.
+ *         The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlTextReaderReadString(xmlTextReaderPtr reader)
+{
+    xmlNodePtr node;
+
+    if ((reader == NULL) || (reader->node == NULL))
+       return(NULL);
+
+    node = (reader->curnode != NULL) ? reader->curnode : reader->node;
+    switch (node->type) {
+    case XML_TEXT_NODE:
+       if (node->content != NULL)
+           return(xmlStrdup(node->content));
+       break;
+    case XML_ELEMENT_NODE:
+	if (xmlTextReaderDoExpand(reader) != -1) {
+	    return xmlTextReaderCollectSiblings(node->children);
+	}
+    case XML_ATTRIBUTE_NODE:
+	TODO
+	break;
+    default:
+       break;
+    }
+    return(NULL);
+}
+
+#if 0
+/**
+ * xmlTextReaderReadBase64:
+ * @reader:  the xmlTextReaderPtr used
+ * @array:  a byte array to store the content.
+ * @offset:  the zero-based index into array where the method should
+ *           begin to write.
+ * @len:  the number of bytes to write.
+ *
+ * Reads and decodes the Base64 encoded contents of an element and
+ * stores the result in a byte buffer.
+ *
+ * Returns the number of bytes written to array, or zero if the current
+ *         instance is not positioned on an element or -1 in case of error.
+ */
+int
+xmlTextReaderReadBase64(xmlTextReaderPtr reader,
+                        unsigned char *array ATTRIBUTE_UNUSED,
+	                int offset ATTRIBUTE_UNUSED,
+			int len ATTRIBUTE_UNUSED) {
+    if ((reader == NULL) || (reader->ctxt == NULL))
+	return(-1);
+    if (reader->ctxt->wellFormed != 1)
+	return(-1);
+
+    if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
+	return(0);
+    TODO
+    return(0);
+}
+
+/**
+ * xmlTextReaderReadBinHex:
+ * @reader:  the xmlTextReaderPtr used
+ * @array:  a byte array to store the content.
+ * @offset:  the zero-based index into array where the method should
+ *           begin to write.
+ * @len:  the number of bytes to write.
+ *
+ * Reads and decodes the BinHex encoded contents of an element and
+ * stores the result in a byte buffer.
+ *
+ * Returns the number of bytes written to array, or zero if the current
+ *         instance is not positioned on an element or -1 in case of error.
+ */
+int
+xmlTextReaderReadBinHex(xmlTextReaderPtr reader,
+                        unsigned char *array ATTRIBUTE_UNUSED,
+	                int offset ATTRIBUTE_UNUSED,
+			int len ATTRIBUTE_UNUSED) {
+    if ((reader == NULL) || (reader->ctxt == NULL))
+	return(-1);
+    if (reader->ctxt->wellFormed != 1)
+	return(-1);
+
+    if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
+	return(0);
+    TODO
+    return(0);
+}
+#endif
+
+/************************************************************************
+ *									*
+ *			Operating on a preparsed tree			*
+ *									*
+ ************************************************************************/
+static int
+xmlTextReaderNextTree(xmlTextReaderPtr reader)
+{
+    if (reader == NULL)
+        return(-1);
+
+    if (reader->state == XML_TEXTREADER_END)
+        return(0);
+
+    if (reader->node == NULL) {
+        if (reader->doc->children == NULL) {
+            reader->state = XML_TEXTREADER_END;
+            return(0);
+        }
+
+        reader->node = reader->doc->children;
+        reader->state = XML_TEXTREADER_START;
+        return(1);
+    }
+
+    if (reader->state != XML_TEXTREADER_BACKTRACK) {
+	/* Here removed traversal to child, because we want to skip the subtree,
+	replace with traversal to sibling to skip subtree */
+        if (reader->node->next != 0) {
+	    /* Move to sibling if present,skipping sub-tree */
+            reader->node = reader->node->next;
+            reader->state = XML_TEXTREADER_START;
+            return(1);
+        }
+
+	/* if reader->node->next is NULL mean no subtree for current node,
+	so need to move to sibling of parent node if present */
+        if ((reader->node->type == XML_ELEMENT_NODE) ||
+            (reader->node->type == XML_ATTRIBUTE_NODE)) {
+            reader->state = XML_TEXTREADER_BACKTRACK;
+	    /* This will move to parent if present */
+            xmlTextReaderRead(reader);
+        }
+    }
+
+    if (reader->node->next != 0) {
+        reader->node = reader->node->next;
+        reader->state = XML_TEXTREADER_START;
+        return(1);
+    }
+
+    if (reader->node->parent != 0) {
+        if (reader->node->parent->type == XML_DOCUMENT_NODE) {
+            reader->state = XML_TEXTREADER_END;
+            return(0);
+        }
+
+        reader->node = reader->node->parent;
+        reader->depth--;
+        reader->state = XML_TEXTREADER_BACKTRACK;
+	/* Repeat process to move to sibling of parent node if present */
+        xmlTextReaderNextTree(reader);
+    }
+
+    reader->state = XML_TEXTREADER_END;
+
+    return(1);
+}
+
+/**
+ * xmlTextReaderReadTree:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ *  Moves the position of the current instance to the next node in
+ *  the stream, exposing its properties.
+ *
+ *  Returns 1 if the node was read successfully, 0 if there is no more
+ *          nodes to read, or -1 in case of error
+ */
+static int
+xmlTextReaderReadTree(xmlTextReaderPtr reader) {
+    if (reader->state == XML_TEXTREADER_END)
+        return(0);
+
+next_node:
+    if (reader->node == NULL) {
+        if (reader->doc->children == NULL) {
+            reader->state = XML_TEXTREADER_END;
+            return(0);
+        }
+
+        reader->node = reader->doc->children;
+        reader->state = XML_TEXTREADER_START;
+        goto found_node;
+    }
+
+    if ((reader->state != XML_TEXTREADER_BACKTRACK) &&
+        (reader->node->type != XML_DTD_NODE) &&
+        (reader->node->type != XML_XINCLUDE_START) &&
+	(reader->node->type != XML_ENTITY_REF_NODE)) {
+        if (reader->node->children != NULL) {
+            reader->node = reader->node->children;
+            reader->depth++;
+            reader->state = XML_TEXTREADER_START;
+            goto found_node;
+        }
+
+        if (reader->node->type == XML_ATTRIBUTE_NODE) {
+            reader->state = XML_TEXTREADER_BACKTRACK;
+            goto found_node;
+        }
+    }
+
+    if (reader->node->next != NULL) {
+        reader->node = reader->node->next;
+        reader->state = XML_TEXTREADER_START;
+        goto found_node;
+    }
+
+    if (reader->node->parent != NULL) {
+        if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||
+	    (reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) {
+            reader->state = XML_TEXTREADER_END;
+            return(0);
+        }
+
+        reader->node = reader->node->parent;
+        reader->depth--;
+        reader->state = XML_TEXTREADER_BACKTRACK;
+        goto found_node;
+    }
+
+    reader->state = XML_TEXTREADER_END;
+
+found_node:
+    if ((reader->node->type == XML_XINCLUDE_START) ||
+        (reader->node->type == XML_XINCLUDE_END))
+	goto next_node;
+
+    return(1);
+}
+
+/**
+ * xmlTextReaderNextSibling:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Skip to the node following the current one in document order while
+ * avoiding the subtree if any.
+ * Currently implemented only for Readers built on a document
+ *
+ * Returns 1 if the node was read successfully, 0 if there is no more
+ *          nodes to read, or -1 in case of error
+ */
+int
+xmlTextReaderNextSibling(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+        return(-1);
+    if (reader->doc == NULL) {
+        /* TODO */
+	return(-1);
+    }
+
+    if (reader->state == XML_TEXTREADER_END)
+        return(0);
+
+    if (reader->node == NULL)
+        return(xmlTextReaderNextTree(reader));
+
+    if (reader->node->next != NULL) {
+        reader->node = reader->node->next;
+        reader->state = XML_TEXTREADER_START;
+        return(1);
+    }
+
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			Constructor and destructors			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlNewTextReader:
+ * @input: the xmlParserInputBufferPtr used to read data
+ * @URI: the URI information for the source if available
+ *
+ * Create an xmlTextReader structure fed with @input
+ *
+ * Returns the new xmlTextReaderPtr or NULL in case of error
+ */
+xmlTextReaderPtr
+xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
+    xmlTextReaderPtr ret;
+
+    if (input == NULL)
+	return(NULL);
+    ret = xmlMalloc(sizeof(xmlTextReader));
+    if (ret == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextReader : malloc failed\n");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlTextReader));
+    ret->doc = NULL;
+    ret->entTab = NULL;
+    ret->entMax = 0;
+    ret->entNr = 0;
+    ret->input = input;
+    ret->buffer = xmlBufferCreateSize(100);
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextReader : malloc failed\n");
+	return(NULL);
+    }
+    ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
+    if (ret->sax == NULL) {
+	xmlBufferFree(ret->buffer);
+	xmlFree(ret);
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextReader : malloc failed\n");
+	return(NULL);
+    }
+    xmlSAXVersion(ret->sax, 2);
+    ret->startElement = ret->sax->startElement;
+    ret->sax->startElement = xmlTextReaderStartElement;
+    ret->endElement = ret->sax->endElement;
+    ret->sax->endElement = xmlTextReaderEndElement;
+#ifdef LIBXML_SAX1_ENABLED
+    if (ret->sax->initialized == XML_SAX2_MAGIC) {
+#endif /* LIBXML_SAX1_ENABLED */
+	ret->startElementNs = ret->sax->startElementNs;
+	ret->sax->startElementNs = xmlTextReaderStartElementNs;
+	ret->endElementNs = ret->sax->endElementNs;
+	ret->sax->endElementNs = xmlTextReaderEndElementNs;
+#ifdef LIBXML_SAX1_ENABLED
+    } else {
+	ret->startElementNs = NULL;
+	ret->endElementNs = NULL;
+    }
+#endif /* LIBXML_SAX1_ENABLED */
+    ret->characters = ret->sax->characters;
+    ret->sax->characters = xmlTextReaderCharacters;
+    ret->sax->ignorableWhitespace = xmlTextReaderCharacters;
+    ret->cdataBlock = ret->sax->cdataBlock;
+    ret->sax->cdataBlock = xmlTextReaderCDataBlock;
+
+    ret->mode = XML_TEXTREADER_MODE_INITIAL;
+    ret->node = NULL;
+    ret->curnode = NULL;
+    if (ret->input->buffer->use < 4) {
+	xmlParserInputBufferRead(input, 4);
+    }
+    if (ret->input->buffer->use >= 4) {
+	ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
+			(const char *) ret->input->buffer->content, 4, URI);
+	ret->base = 0;
+	ret->cur = 4;
+    } else {
+	ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);
+	ret->base = 0;
+	ret->cur = 0;
+    }
+
+    if (ret->ctxt == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextReader : malloc failed\n");
+	xmlBufferFree(ret->buffer);
+	xmlFree(ret->sax);
+	xmlFree(ret);
+	return(NULL);
+    }
+    ret->ctxt->parseMode = XML_PARSE_READER;
+    ret->ctxt->_private = ret;
+    ret->ctxt->linenumbers = 1;
+    ret->ctxt->dictNames = 1;
+    ret->allocs = XML_TEXTREADER_CTXT;
+    /*
+     * use the parser dictionnary to allocate all elements and attributes names
+     */
+    ret->ctxt->docdict = 1;
+    ret->dict = ret->ctxt->dict;
+#ifdef LIBXML_XINCLUDE_ENABLED
+    ret->xinclude = 0;
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+    ret->patternMax = 0;
+    ret->patternTab = NULL;
+#endif
+    return(ret);
+}
+
+/**
+ * xmlNewTextReaderFilename:
+ * @URI: the URI of the resource to process
+ *
+ * Create an xmlTextReader structure fed with the resource at @URI
+ *
+ * Returns the new xmlTextReaderPtr or NULL in case of error
+ */
+xmlTextReaderPtr
+xmlNewTextReaderFilename(const char *URI) {
+    xmlParserInputBufferPtr input;
+    xmlTextReaderPtr ret;
+    char *directory = NULL;
+
+    input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+	return(NULL);
+    ret = xmlNewTextReader(input, URI);
+    if (ret == NULL) {
+	xmlFreeParserInputBuffer(input);
+	return(NULL);
+    }
+    ret->allocs |= XML_TEXTREADER_INPUT;
+    if (ret->ctxt->directory == NULL)
+        directory = xmlParserGetDirectory(URI);
+    if ((ret->ctxt->directory == NULL) && (directory != NULL))
+        ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
+    if (directory != NULL)
+	xmlFree(directory);
+    return(ret);
+}
+
+/**
+ * xmlFreeTextReader:
+ * @reader:  the xmlTextReaderPtr
+ *
+ * Deallocate all the resources associated to the reader
+ */
+void
+xmlFreeTextReader(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return;
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (reader->rngSchemas != NULL) {
+	xmlRelaxNGFree(reader->rngSchemas);
+	reader->rngSchemas = NULL;
+    }
+    if (reader->rngValidCtxt != NULL) {
+	xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
+	reader->rngValidCtxt = NULL;
+    }
+    if (reader->xsdPlug != NULL) {
+	xmlSchemaSAXUnplug(reader->xsdPlug);
+	reader->xsdPlug = NULL;
+    }
+    if (reader->xsdValidCtxt != NULL) {
+	if (! reader->xsdPreserveCtxt)
+	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+	reader->xsdValidCtxt = NULL;
+    }
+    if (reader->xsdSchemas != NULL) {
+	xmlSchemaFree(reader->xsdSchemas);
+	reader->xsdSchemas = NULL;
+    }
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+    if (reader->xincctxt != NULL)
+	xmlXIncludeFreeContext(reader->xincctxt);
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+    if (reader->patternTab != NULL) {
+        int i;
+	for (i = 0;i < reader->patternNr;i++) {
+	    if (reader->patternTab[i] != NULL)
+	        xmlFreePattern(reader->patternTab[i]);
+	}
+	xmlFree(reader->patternTab);
+    }
+#endif
+    if (reader->faketext != NULL) {
+	xmlFreeNode(reader->faketext);
+    }
+    if (reader->ctxt != NULL) {
+        if (reader->dict == reader->ctxt->dict)
+	    reader->dict = NULL;
+	if (reader->ctxt->myDoc != NULL) {
+	    if (reader->preserve == 0)
+		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
+	    reader->ctxt->myDoc = NULL;
+	}
+	if ((reader->ctxt->vctxt.vstateTab != NULL) &&
+	    (reader->ctxt->vctxt.vstateMax > 0)){
+	    xmlFree(reader->ctxt->vctxt.vstateTab);
+	    reader->ctxt->vctxt.vstateTab = NULL;
+	    reader->ctxt->vctxt.vstateMax = 0;
+	}
+	if (reader->allocs & XML_TEXTREADER_CTXT)
+	    xmlFreeParserCtxt(reader->ctxt);
+    }
+    if (reader->sax != NULL)
+	xmlFree(reader->sax);
+    if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT))
+	xmlFreeParserInputBuffer(reader->input);
+    if (reader->buffer != NULL)
+        xmlBufferFree(reader->buffer);
+    if (reader->entTab != NULL)
+	xmlFree(reader->entTab);
+    if (reader->dict != NULL)
+        xmlDictFree(reader->dict);
+    xmlFree(reader);
+}
+
+/************************************************************************
+ *									*
+ *			Methods for XmlTextReader			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlTextReaderClose:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * This method releases any resources allocated by the current instance
+ * changes the state to Closed and close any underlying input.
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlTextReaderClose(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    reader->node = NULL;
+    reader->curnode = NULL;
+    reader->mode = XML_TEXTREADER_MODE_CLOSED;
+    if (reader->ctxt != NULL) {
+	xmlStopParser(reader->ctxt);
+	if (reader->ctxt->myDoc != NULL) {
+	    if (reader->preserve == 0)
+		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
+	    reader->ctxt->myDoc = NULL;
+	}
+    }
+    if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT)) {
+	xmlFreeParserInputBuffer(reader->input);
+	reader->allocs -= XML_TEXTREADER_INPUT;
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderGetAttributeNo:
+ * @reader:  the xmlTextReaderPtr used
+ * @no: the zero-based index of the attribute relative to the containing element
+ *
+ * Provides the value of the attribute with the specified index relative
+ * to the containing element.
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
+    xmlChar *ret;
+    int i;
+    xmlAttrPtr cur;
+    xmlNsPtr ns;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(NULL);
+
+    ns = reader->node->nsDef;
+    for (i = 0;(i < no) && (ns != NULL);i++) {
+	ns = ns->next;
+    }
+    if (ns != NULL)
+	return(xmlStrdup(ns->href));
+
+    cur = reader->node->properties;
+    if (cur == NULL)
+	return(NULL);
+    for (;i < no;i++) {
+	cur = cur->next;
+	if (cur == NULL)
+	    return(NULL);
+    }
+    /* TODO walk the DTD if present */
+
+    ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
+    if (ret == NULL) return(xmlStrdup((xmlChar *)""));
+    return(ret);
+}
+
+/**
+ * xmlTextReaderGetAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ * @name: the qualified name of the attribute.
+ *
+ * Provides the value of the attribute with the specified qualified name.
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
+    xmlChar *prefix = NULL;
+    xmlChar *localname;
+    xmlNsPtr ns;
+    xmlChar *ret = NULL;
+
+    if ((reader == NULL) || (name == NULL))
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
+
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(NULL);
+
+    localname = xmlSplitQName2(name, &prefix);
+    if (localname == NULL) {
+		/*
+		 * Namespace default decl
+		 */
+		if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+			ns = reader->node->nsDef;
+			while (ns != NULL) {
+				if (ns->prefix == NULL) {
+					return(xmlStrdup(ns->href));
+				}
+				ns = ns->next;
+			}
+			return NULL;
+		}
+		return(xmlGetNoNsProp(reader->node, name));
+	}
+
+    /*
+     * Namespace default decl
+     */
+    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+		ns = reader->node->nsDef;
+		while (ns != NULL) {
+			if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
+				ret = xmlStrdup(ns->href);
+				break;
+			}
+			ns = ns->next;
+		}
+    } else {
+		ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
+		if (ns != NULL)
+			ret = xmlGetNsProp(reader->node, localname, ns->href);
+	}
+
+    xmlFree(localname);
+    if (prefix != NULL)
+        xmlFree(prefix);
+    return(ret);
+}
+
+
+/**
+ * xmlTextReaderGetAttributeNs:
+ * @reader:  the xmlTextReaderPtr used
+ * @localName: the local name of the attribute.
+ * @namespaceURI: the namespace URI of the attribute.
+ *
+ * Provides the value of the specified attribute
+ *
+ * Returns a string containing the value of the specified attribute, or NULL
+ *    in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,
+			    const xmlChar *namespaceURI) {
+    xmlChar *prefix = NULL;
+    xmlNsPtr ns;
+
+    if ((reader == NULL) || (localName == NULL))
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    if (reader->curnode != NULL)
+	return(NULL);
+
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(NULL);
+
+    if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
+		if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
+			prefix = BAD_CAST localName;
+		}
+		ns = reader->node->nsDef;
+		while (ns != NULL) {
+			if ((prefix == NULL && ns->prefix == NULL) ||
+				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
+				return xmlStrdup(ns->href);
+			}
+			ns = ns->next;
+		}
+		return NULL;
+    }
+
+    return(xmlGetNsProp(reader->node, localName, namespaceURI));
+}
+
+/**
+ * xmlTextReaderGetRemainder:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Method to get the remainder of the buffered XML. this method stops the
+ * parser, set its state to End Of File and return the input stream with
+ * what is left that the parser did not use.
+ *
+ * The implementation is not good, the parser certainly procgressed past
+ * what's left in reader->input, and there is an allocation problem. Best
+ * would be to rewrite it differently.
+ *
+ * Returns the xmlParserInputBufferPtr attached to the XML or NULL
+ *    in case of error.
+ */
+xmlParserInputBufferPtr
+xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
+    xmlParserInputBufferPtr ret = NULL;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+
+    reader->node = NULL;
+    reader->curnode = NULL;
+    reader->mode = XML_TEXTREADER_MODE_EOF;
+    if (reader->ctxt != NULL) {
+	xmlStopParser(reader->ctxt);
+	if (reader->ctxt->myDoc != NULL) {
+	    if (reader->preserve == 0)
+		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
+	    reader->ctxt->myDoc = NULL;
+	}
+    }
+    if (reader->allocs & XML_TEXTREADER_INPUT) {
+	ret = reader->input;
+	reader->input = NULL;
+	reader->allocs -= XML_TEXTREADER_INPUT;
+    } else {
+	/*
+	 * Hum, one may need to duplicate the data structure because
+	 * without reference counting the input may be freed twice:
+	 *   - by the layer which allocated it.
+	 *   - by the layer to which would have been returned to.
+	 */
+	TODO
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlTextReaderLookupNamespace:
+ * @reader:  the xmlTextReaderPtr used
+ * @prefix: the prefix whose namespace URI is to be resolved. To return
+ *          the default namespace, specify NULL
+ *
+ * Resolves a namespace prefix in the scope of the current element.
+ *
+ * Returns a string containing the namespace URI to which the prefix maps
+ *    or NULL in case of error. The string must be deallocated by the caller.
+ */
+xmlChar *
+xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
+    xmlNsPtr ns;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+
+    ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
+    if (ns == NULL)
+	return(NULL);
+    return(xmlStrdup(ns->href));
+}
+
+/**
+ * xmlTextReaderMoveToAttributeNo:
+ * @reader:  the xmlTextReaderPtr used
+ * @no: the zero-based index of the attribute relative to the containing
+ *      element.
+ *
+ * Moves the position of the current instance to the attribute with
+ * the specified index relative to the containing element.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
+    int i;
+    xmlAttrPtr cur;
+    xmlNsPtr ns;
+
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(-1);
+
+    reader->curnode = NULL;
+
+    ns = reader->node->nsDef;
+    for (i = 0;(i < no) && (ns != NULL);i++) {
+	ns = ns->next;
+    }
+    if (ns != NULL) {
+	reader->curnode = (xmlNodePtr) ns;
+	return(1);
+    }
+
+    cur = reader->node->properties;
+    if (cur == NULL)
+	return(0);
+    for (;i < no;i++) {
+	cur = cur->next;
+	if (cur == NULL)
+	    return(0);
+    }
+    /* TODO walk the DTD if present */
+
+    reader->curnode = (xmlNodePtr) cur;
+    return(1);
+}
+
+/**
+ * xmlTextReaderMoveToAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ * @name: the qualified name of the attribute.
+ *
+ * Moves the position of the current instance to the attribute with
+ * the specified qualified name.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
+    xmlChar *prefix = NULL;
+    xmlChar *localname;
+    xmlNsPtr ns;
+    xmlAttrPtr prop;
+
+    if ((reader == NULL) || (name == NULL))
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+
+    /* TODO: handle the xmlDecl */
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+
+    localname = xmlSplitQName2(name, &prefix);
+    if (localname == NULL) {
+	/*
+	 * Namespace default decl
+	 */
+	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+	    ns = reader->node->nsDef;
+	    while (ns != NULL) {
+		if (ns->prefix == NULL) {
+		    reader->curnode = (xmlNodePtr) ns;
+		    return(1);
+		}
+		ns = ns->next;
+	    }
+	    return(0);
+	}
+
+	prop = reader->node->properties;
+	while (prop != NULL) {
+	    /*
+	     * One need to have
+	     *   - same attribute names
+	     *   - and the attribute carrying that namespace
+	     */
+	    if ((xmlStrEqual(prop->name, name)) &&
+		((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
+		reader->curnode = (xmlNodePtr) prop;
+		return(1);
+	    }
+	    prop = prop->next;
+	}
+	return(0);
+    }
+
+    /*
+     * Namespace default decl
+     */
+    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+	ns = reader->node->nsDef;
+	while (ns != NULL) {
+	    if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
+		reader->curnode = (xmlNodePtr) ns;
+		goto found;
+	    }
+	    ns = ns->next;
+	}
+	goto not_found;
+    }
+    prop = reader->node->properties;
+    while (prop != NULL) {
+	/*
+	 * One need to have
+	 *   - same attribute names
+	 *   - and the attribute carrying that namespace
+	 */
+	if ((xmlStrEqual(prop->name, localname)) &&
+	    (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
+	    reader->curnode = (xmlNodePtr) prop;
+	    goto found;
+	}
+	prop = prop->next;
+    }
+not_found:
+    if (localname != NULL)
+        xmlFree(localname);
+    if (prefix != NULL)
+        xmlFree(prefix);
+    return(0);
+
+found:
+    if (localname != NULL)
+        xmlFree(localname);
+    if (prefix != NULL)
+        xmlFree(prefix);
+    return(1);
+}
+
+/**
+ * xmlTextReaderMoveToAttributeNs:
+ * @reader:  the xmlTextReaderPtr used
+ * @localName:  the local name of the attribute.
+ * @namespaceURI:  the namespace URI of the attribute.
+ *
+ * Moves the position of the current instance to the attribute with the
+ * specified local name and namespace URI.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
+	const xmlChar *localName, const xmlChar *namespaceURI) {
+    xmlAttrPtr prop;
+    xmlNodePtr node;
+    xmlNsPtr ns;
+    xmlChar *prefix = NULL;
+
+    if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    node = reader->node;
+
+    if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
+		if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
+			prefix = BAD_CAST localName;
+		}
+		ns = reader->node->nsDef;
+		while (ns != NULL) {
+			if ((prefix == NULL && ns->prefix == NULL) ||
+				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
+				reader->curnode = (xmlNodePtr) ns;
+				return(1);
+			}
+			ns = ns->next;
+		}
+		return(0);
+    }
+
+    prop = node->properties;
+    while (prop != NULL) {
+	/*
+	 * One need to have
+	 *   - same attribute names
+	 *   - and the attribute carrying that namespace
+	 */
+        if (xmlStrEqual(prop->name, localName) &&
+	    ((prop->ns != NULL) &&
+	     (xmlStrEqual(prop->ns->href, namespaceURI)))) {
+	    reader->curnode = (xmlNodePtr) prop;
+	    return(1);
+        }
+	prop = prop->next;
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToFirstAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Moves the position of the current instance to the first attribute
+ * associated with the current node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+
+    if (reader->node->nsDef != NULL) {
+	reader->curnode = (xmlNodePtr) reader->node->nsDef;
+	return(1);
+    }
+    if (reader->node->properties != NULL) {
+	reader->curnode = (xmlNodePtr) reader->node->properties;
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToNextAttribute:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Moves the position of the current instance to the next attribute
+ * associated with the current node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not found
+ */
+int
+xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (reader->curnode == NULL)
+	return(xmlTextReaderMoveToFirstAttribute(reader));
+
+    if (reader->curnode->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) reader->curnode;
+	if (ns->next != NULL) {
+	    reader->curnode = (xmlNodePtr) ns->next;
+	    return(1);
+	}
+	if (reader->node->properties != NULL) {
+	    reader->curnode = (xmlNodePtr) reader->node->properties;
+	    return(1);
+	}
+	return(0);
+    } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
+	       (reader->curnode->next != NULL)) {
+	reader->curnode = reader->curnode->next;
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderMoveToElement:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Moves the position of the current instance to the node that
+ * contains the current Attribute  node.
+ *
+ * Returns 1 in case of success, -1 in case of error, 0 if not moved
+ */
+int
+xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (reader->curnode != NULL) {
+	reader->curnode = NULL;
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderReadAttributeValue:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Parses an attribute value into one or more Text and EntityReference nodes.
+ *
+ * Returns 1 in case of success, 0 if the reader was not positionned on an
+ *         ttribute node or all the attribute values have been read, or -1
+ *         in case of error.
+ */
+int
+xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->curnode == NULL)
+	return(0);
+    if (reader->curnode->type == XML_ATTRIBUTE_NODE) {
+	if (reader->curnode->children == NULL)
+	    return(0);
+	reader->curnode = reader->curnode->children;
+    } else if (reader->curnode->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) reader->curnode;
+
+	if (reader->faketext == NULL) {
+	    reader->faketext = xmlNewDocText(reader->node->doc,
+		                             ns->href);
+	} else {
+            if ((reader->faketext->content != NULL) &&
+	        (reader->faketext->content !=
+		 (xmlChar *) &(reader->faketext->properties)))
+		xmlFree(reader->faketext->content);
+	    reader->faketext->content = xmlStrdup(ns->href);
+	}
+	reader->curnode = reader->faketext;
+    } else {
+	if (reader->curnode->next == NULL)
+	    return(0);
+	reader->curnode = reader->curnode->next;
+    }
+    return(1);
+}
+
+/**
+ * xmlTextReaderConstEncoding:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Determine the encoding of the document being read.
+ *
+ * Returns a string containing the encoding of the document or NULL in
+ * case of error.  The string is deallocated with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstEncoding(xmlTextReaderPtr reader) {
+    xmlDocPtr doc = NULL;
+    if (reader == NULL)
+	return(NULL);
+    if (reader->doc != NULL)
+        doc = reader->doc;
+    else if (reader->ctxt != NULL)
+	doc = reader->ctxt->myDoc;
+    if (doc == NULL)
+	return(NULL);
+
+    if (doc->encoding == NULL)
+	return(NULL);
+    else
+      return(CONSTSTR(doc->encoding));
+}
+
+
+/************************************************************************
+ *									*
+ *			Acces API to the current node			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlTextReaderAttributeCount:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Provides the number of attributes of the current node
+ *
+ * Returns 0 i no attributes, -1 in case of error or the attribute count
+ */
+int
+xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
+    int ret;
+    xmlAttrPtr attr;
+    xmlNsPtr ns;
+    xmlNodePtr node;
+
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(0);
+
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    if (node->type != XML_ELEMENT_NODE)
+	return(0);
+    if ((reader->state == XML_TEXTREADER_END) ||
+	(reader->state == XML_TEXTREADER_BACKTRACK))
+	return(0);
+    ret = 0;
+    attr = node->properties;
+    while (attr != NULL) {
+	ret++;
+	attr = attr->next;
+    }
+    ns = node->nsDef;
+    while (ns != NULL) {
+	ret++;
+	ns = ns->next;
+    }
+    return(ret);
+}
+
+/**
+ * xmlTextReaderNodeType:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Get the node type of the current node
+ * Reference:
+ * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
+ *
+ * Returns the xmlNodeType of the current node or -1 in case of error
+ */
+int
+xmlTextReaderNodeType(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(XML_READER_TYPE_NONE);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+	    if ((reader->state == XML_TEXTREADER_END) ||
+		(reader->state == XML_TEXTREADER_BACKTRACK))
+		return(XML_READER_TYPE_END_ELEMENT);
+	    return(XML_READER_TYPE_ELEMENT);
+        case XML_NAMESPACE_DECL:
+        case XML_ATTRIBUTE_NODE:
+	    return(XML_READER_TYPE_ATTRIBUTE);
+        case XML_TEXT_NODE:
+	    if (xmlIsBlankNode(reader->node)) {
+		if (xmlNodeGetSpacePreserve(reader->node))
+		    return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
+		else
+		    return(XML_READER_TYPE_WHITESPACE);
+	    } else {
+		return(XML_READER_TYPE_TEXT);
+	    }
+        case XML_CDATA_SECTION_NODE:
+	    return(XML_READER_TYPE_CDATA);
+        case XML_ENTITY_REF_NODE:
+	    return(XML_READER_TYPE_ENTITY_REFERENCE);
+        case XML_ENTITY_NODE:
+	    return(XML_READER_TYPE_ENTITY);
+        case XML_PI_NODE:
+	    return(XML_READER_TYPE_PROCESSING_INSTRUCTION);
+        case XML_COMMENT_NODE:
+	    return(XML_READER_TYPE_COMMENT);
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return(XML_READER_TYPE_DOCUMENT);
+        case XML_DOCUMENT_FRAG_NODE:
+	    return(XML_READER_TYPE_DOCUMENT_FRAGMENT);
+        case XML_NOTATION_NODE:
+	    return(XML_READER_TYPE_NOTATION);
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DTD_NODE:
+	    return(XML_READER_TYPE_DOCUMENT_TYPE);
+
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+	    return(XML_READER_TYPE_NONE);
+    }
+    return(-1);
+}
+
+/**
+ * xmlTextReaderIsEmptyElement:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Check if the current node is empty
+ *
+ * Returns 1 if empty, 0 if not and -1 in case of error
+ */
+int
+xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
+    if ((reader == NULL) || (reader->node == NULL))
+	return(-1);
+    if (reader->node->type != XML_ELEMENT_NODE)
+	return(0);
+    if (reader->curnode != NULL)
+	return(0);
+    if (reader->node->children != NULL)
+	return(0);
+    if (reader->state == XML_TEXTREADER_END)
+	return(0);
+    if (reader->doc != NULL)
+        return(1);
+#ifdef LIBXML_XINCLUDE_ENABLED
+    if (reader->in_xinclude > 0)
+        return(1);
+#endif
+    return((reader->node->extra & NODE_IS_EMPTY) != 0);
+}
+
+/**
+ * xmlTextReaderLocalName:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The local name of the node.
+ *
+ * Returns the local name or NULL if not available,
+ *   if non NULL it need to be freed by the caller.
+ */
+xmlChar *
+xmlTextReaderLocalName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(xmlStrdup(BAD_CAST "xmlns"));
+	else
+	    return(xmlStrdup(ns->prefix));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(xmlTextReaderName(reader));
+    return(xmlStrdup(node->name));
+}
+
+/**
+ * xmlTextReaderConstLocalName:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The local name of the node.
+ *
+ * Returns the local name or NULL if not available, the
+ *         string will be deallocated with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstLocalName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(CONSTSTR(BAD_CAST "xmlns"));
+	else
+	    return(ns->prefix);
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(xmlTextReaderConstName(reader));
+    return(node->name);
+}
+
+/**
+ * xmlTextReaderName:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The qualified name of the node, equal to Prefix :LocalName.
+ *
+ * Returns the local name or NULL if not available,
+ *   if non NULL it need to be freed by the caller.
+ */
+xmlChar *
+xmlTextReaderName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    xmlChar *ret;
+
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    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);
+	    return(ret);
+        case XML_TEXT_NODE:
+	    return(xmlStrdup(BAD_CAST "#text"));
+        case XML_CDATA_SECTION_NODE:
+	    return(xmlStrdup(BAD_CAST "#cdata-section"));
+        case XML_ENTITY_NODE:
+        case XML_ENTITY_REF_NODE:
+	    return(xmlStrdup(node->name));
+        case XML_PI_NODE:
+	    return(xmlStrdup(node->name));
+        case XML_COMMENT_NODE:
+	    return(xmlStrdup(BAD_CAST "#comment"));
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return(xmlStrdup(BAD_CAST "#document"));
+        case XML_DOCUMENT_FRAG_NODE:
+	    return(xmlStrdup(BAD_CAST "#document-fragment"));
+        case XML_NOTATION_NODE:
+	    return(xmlStrdup(node->name));
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DTD_NODE:
+	    return(xmlStrdup(node->name));
+        case XML_NAMESPACE_DECL: {
+	    xmlNsPtr ns = (xmlNsPtr) node;
+
+	    ret = xmlStrdup(BAD_CAST "xmlns");
+	    if (ns->prefix == NULL)
+		return(ret);
+	    ret = xmlStrcat(ret, BAD_CAST ":");
+	    ret = xmlStrcat(ret, ns->prefix);
+	    return(ret);
+	}
+
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+	    return(NULL);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderConstName:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The qualified name of the node, equal to Prefix :LocalName.
+ *
+ * Returns the local name or NULL if not available, the string is
+ *         deallocated with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstName(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    switch (node->type) {
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
+	    if ((node->ns == NULL) ||
+		(node->ns->prefix == NULL))
+		return(node->name);
+	    return(CONSTQSTR(node->ns->prefix, node->name));
+        case XML_TEXT_NODE:
+	    return(CONSTSTR(BAD_CAST "#text"));
+        case XML_CDATA_SECTION_NODE:
+	    return(CONSTSTR(BAD_CAST "#cdata-section"));
+        case XML_ENTITY_NODE:
+        case XML_ENTITY_REF_NODE:
+	    return(CONSTSTR(node->name));
+        case XML_PI_NODE:
+	    return(CONSTSTR(node->name));
+        case XML_COMMENT_NODE:
+	    return(CONSTSTR(BAD_CAST "#comment"));
+        case XML_DOCUMENT_NODE:
+        case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+        case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return(CONSTSTR(BAD_CAST "#document"));
+        case XML_DOCUMENT_FRAG_NODE:
+	    return(CONSTSTR(BAD_CAST "#document-fragment"));
+        case XML_NOTATION_NODE:
+	    return(CONSTSTR(node->name));
+        case XML_DOCUMENT_TYPE_NODE:
+        case XML_DTD_NODE:
+	    return(CONSTSTR(node->name));
+        case XML_NAMESPACE_DECL: {
+	    xmlNsPtr ns = (xmlNsPtr) node;
+
+	    if (ns->prefix == NULL)
+		return(CONSTSTR(BAD_CAST "xmlns"));
+	    return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));
+	}
+
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+        case XML_XINCLUDE_START:
+        case XML_XINCLUDE_END:
+	    return(NULL);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderPrefix:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * A shorthand reference to the namespace associated with the node.
+ *
+ * Returns the prefix or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
+ */
+xmlChar *
+xmlTextReaderPrefix(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(NULL);
+	return(xmlStrdup(BAD_CAST "xmlns"));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(NULL);
+    if ((node->ns != NULL) && (node->ns->prefix != NULL))
+	return(xmlStrdup(node->ns->prefix));
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderConstPrefix:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * A shorthand reference to the namespace associated with the node.
+ *
+ * Returns the prefix or NULL if not available, the string is deallocated
+ *         with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstPrefix(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) node;
+	if (ns->prefix == NULL)
+	    return(NULL);
+	return(CONSTSTR(BAD_CAST "xmlns"));
+    }
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(NULL);
+    if ((node->ns != NULL) && (node->ns->prefix != NULL))
+	return(CONSTSTR(node->ns->prefix));
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderNamespaceUri:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The URI defining the namespace associated with the node.
+ *
+ * Returns the namespace URI or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
+ */
+xmlChar *
+xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL)
+	return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(NULL);
+    if (node->ns != NULL)
+	return(xmlStrdup(node->ns->href));
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderConstNamespaceUri:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The URI defining the namespace associated with the node.
+ *
+ * Returns the namespace URI or NULL if not available, the string
+ *         will be deallocated with the reader
+ */
+const xmlChar *
+xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+    if (node->type == XML_NAMESPACE_DECL)
+	return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));
+    if ((node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+	return(NULL);
+    if (node->ns != NULL)
+	return(CONSTSTR(node->ns->href));
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderBaseUri:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The base URI of the node.
+ *
+ * Returns the base URI or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
+ */
+xmlChar *
+xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    return(xmlNodeGetBase(NULL, reader->node));
+}
+
+/**
+ * xmlTextReaderConstBaseUri:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The base URI of the node.
+ *
+ * Returns the base URI or NULL if not available, the string
+ *         will be deallocated with the reader
+ */
+const xmlChar *
+xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) {
+    xmlChar *tmp;
+    const xmlChar *ret;
+
+    if ((reader == NULL) || (reader->node == NULL))
+	return(NULL);
+    tmp = xmlNodeGetBase(NULL, reader->node);
+    if (tmp == NULL)
+        return(NULL);
+    ret = CONSTSTR(tmp);
+    xmlFree(tmp);
+    return(ret);
+}
+
+/**
+ * xmlTextReaderDepth:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The depth of the node in the tree.
+ *
+ * Returns the depth or -1 in case of error
+ */
+int
+xmlTextReaderDepth(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(0);
+
+    if (reader->curnode != NULL) {
+	if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||
+	    (reader->curnode->type == XML_NAMESPACE_DECL))
+	    return(reader->depth + 1);
+	return(reader->depth + 2);
+    }
+    return(reader->depth);
+}
+
+/**
+ * xmlTextReaderHasAttributes:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Whether the node has attributes.
+ *
+ * Returns 1 if true, 0 if false, and -1 in case or error
+ */
+int
+xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(0);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    if ((node->type == XML_ELEMENT_NODE) &&
+	((node->properties != NULL) || (node->nsDef != NULL)))
+	return(1);
+    /* TODO: handle the xmlDecl */
+    return(0);
+}
+
+/**
+ * xmlTextReaderHasValue:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Whether the node can have a text value.
+ *
+ * Returns 1 if true, 0 if false, and -1 in case or error
+ */
+int
+xmlTextReaderHasValue(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(0);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    switch (node->type) {
+        case XML_ATTRIBUTE_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_NAMESPACE_DECL:
+	    return(1);
+	default:
+	    break;
+    }
+    return(0);
+}
+
+/**
+ * xmlTextReaderValue:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Provides the text value of the node if present
+ *
+ * Returns the string or NULL if not available. The result must be deallocated
+ *     with xmlFree()
+ */
+xmlChar *
+xmlTextReaderValue(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    switch (node->type) {
+        case XML_NAMESPACE_DECL:
+	    return(xmlStrdup(((xmlNsPtr) node)->href));
+        case XML_ATTRIBUTE_NODE:{
+	    xmlAttrPtr attr = (xmlAttrPtr) node;
+
+	    if (attr->parent != NULL)
+		return (xmlNodeListGetString
+			(attr->parent->doc, attr->children, 1));
+	    else
+		return (xmlNodeListGetString(NULL, attr->children, 1));
+	    break;
+	}
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+            if (node->content != NULL)
+                return (xmlStrdup(node->content));
+	default:
+	    break;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderConstValue:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Provides the text value of the node if present
+ *
+ * Returns the string or NULL if not available. The result will be
+ *     deallocated on the next Read() operation.
+ */
+const xmlChar *
+xmlTextReaderConstValue(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    switch (node->type) {
+        case XML_NAMESPACE_DECL:
+	    return(((xmlNsPtr) node)->href);
+        case XML_ATTRIBUTE_NODE:{
+	    xmlAttrPtr attr = (xmlAttrPtr) node;
+
+	    if ((attr->children != NULL) &&
+	        (attr->children->type == XML_TEXT_NODE) &&
+		(attr->children->next == NULL))
+		return(attr->children->content);
+	    else {
+		if (reader->buffer == NULL)
+		    reader->buffer = xmlBufferCreateSize(100);
+		if (reader->buffer == NULL) {
+		    xmlGenericError(xmlGenericErrorContext,
+				    "xmlTextReaderSetup : malloc failed\n");
+		    return (NULL);
+		}
+	        reader->buffer->use = 0;
+	        xmlNodeBufGetContent(reader->buffer, node);
+		return(reader->buffer->content);
+	    }
+	    break;
+	}
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+	    return(node->content);
+	default:
+	    break;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlTextReaderIsDefault:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Whether an Attribute  node was generated from the default value
+ * defined in the DTD or schema.
+ *
+ * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
+ */
+int
+xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    return(0);
+}
+
+/**
+ * xmlTextReaderQuoteChar:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The quotation mark character used to enclose the value of an attribute.
+ *
+ * Returns " or ' and -1 in case of error
+ */
+int
+xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    /* TODO maybe lookup the attribute value for " first */
+    return((int) '"');
+}
+
+/**
+ * xmlTextReaderXmlLang:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The xml:lang scope within which the node resides.
+ *
+ * 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) {
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    return(xmlNodeGetLang(reader->node));
+}
+
+/**
+ * xmlTextReaderConstXmlLang:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The xml:lang scope within which the node resides.
+ *
+ * Returns the xml:lang value or NULL if none exists.
+ */
+const xmlChar *
+xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) {
+    xmlChar *tmp;
+    const xmlChar *ret;
+
+    if (reader == NULL)
+	return(NULL);
+    if (reader->node == NULL)
+	return(NULL);
+    tmp = xmlNodeGetLang(reader->node);
+    if (tmp == NULL)
+        return(NULL);
+    ret = CONSTSTR(tmp);
+    xmlFree(tmp);
+    return(ret);
+}
+
+/**
+ * xmlTextReaderConstString:
+ * @reader:  the xmlTextReaderPtr used
+ * @str:  the string to intern.
+ *
+ * Get an interned string from the reader, allows for example to
+ * speedup string name comparisons
+ *
+ * Returns an interned copy of the string or NULL in case of error. The
+ *         string will be deallocated with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) {
+    if (reader == NULL)
+	return(NULL);
+    return(CONSTSTR(str));
+}
+
+/**
+ * xmlTextReaderNormalization:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * The value indicating whether to normalize white space and attribute values.
+ * Since attribute value and end of line normalizations are a MUST in the XML
+ * specification only the value true is accepted. The broken bahaviour of
+ * accepting out of range character entities like &#0; is of course not
+ * supported either.
+ *
+ * Returns 1 or -1 in case of error.
+ */
+int
+xmlTextReaderNormalization(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(-1);
+    return(1);
+}
+
+/************************************************************************
+ *									*
+ *			Extensions to the base APIs			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlTextReaderSetParserProp:
+ * @reader:  the xmlTextReaderPtr used
+ * @prop:  the xmlParserProperties to set
+ * @value:  usually 0 or 1 to (de)activate it
+ *
+ * Change the parser processing behaviour by changing some of its internal
+ * properties. Note that some properties can only be changed before any
+ * read has been done.
+ *
+ * Returns 0 if the call was successful, or -1 in case of error
+ */
+int
+xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) {
+    xmlParserProperties p = (xmlParserProperties) prop;
+    xmlParserCtxtPtr ctxt;
+
+    if ((reader == NULL) || (reader->ctxt == NULL))
+	return(-1);
+    ctxt = reader->ctxt;
+
+    switch (p) {
+        case XML_PARSER_LOADDTD:
+	    if (value != 0) {
+		if (ctxt->loadsubset == 0) {
+		    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
+			return(-1);
+		    ctxt->loadsubset = XML_DETECT_IDS;
+		}
+	    } else {
+		ctxt->loadsubset = 0;
+	    }
+	    return(0);
+        case XML_PARSER_DEFAULTATTRS:
+	    if (value != 0) {
+		ctxt->loadsubset |= XML_COMPLETE_ATTRS;
+	    } else {
+		if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
+		    ctxt->loadsubset -= XML_COMPLETE_ATTRS;
+	    }
+	    return(0);
+        case XML_PARSER_VALIDATE:
+	    if (value != 0) {
+		ctxt->validate = 1;
+		reader->validate = XML_TEXTREADER_VALIDATE_DTD;
+	    } else {
+		ctxt->validate = 0;
+	    }
+	    return(0);
+        case XML_PARSER_SUBST_ENTITIES:
+	    if (value != 0) {
+		ctxt->replaceEntities = 1;
+	    } else {
+		ctxt->replaceEntities = 0;
+	    }
+	    return(0);
+    }
+    return(-1);
+}
+
+/**
+ * xmlTextReaderGetParserProp:
+ * @reader:  the xmlTextReaderPtr used
+ * @prop:  the xmlParserProperties to get
+ *
+ * Read the parser internal property.
+ *
+ * Returns the value, usually 0 or 1, or -1 in case of error.
+ */
+int
+xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) {
+    xmlParserProperties p = (xmlParserProperties) prop;
+    xmlParserCtxtPtr ctxt;
+
+    if ((reader == NULL) || (reader->ctxt == NULL))
+	return(-1);
+    ctxt = reader->ctxt;
+
+    switch (p) {
+        case XML_PARSER_LOADDTD:
+	    if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))
+		return(1);
+	    return(0);
+        case XML_PARSER_DEFAULTATTRS:
+	    if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
+		return(1);
+	    return(0);
+        case XML_PARSER_VALIDATE:
+	    return(reader->validate);
+	case XML_PARSER_SUBST_ENTITIES:
+	    return(ctxt->replaceEntities);
+    }
+    return(-1);
+}
+
+
+/**
+ * xmlTextReaderGetParserLineNumber:
+ * @reader: the user data (XML reader context)
+ *
+ * Provide the line number of the current parsing point.
+ *
+ * Returns an int or 0 if not available
+ */
+int
+xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)
+{
+    if ((reader == NULL) || (reader->ctxt == NULL) ||
+        (reader->ctxt->input == NULL)) {
+        return (0);
+    }
+    return (reader->ctxt->input->line);
+}
+
+/**
+ * xmlTextReaderGetParserColumnNumber:
+ * @reader: the user data (XML reader context)
+ *
+ * Provide the column number of the current parsing point.
+ *
+ * Returns an int or 0 if not available
+ */
+int
+xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)
+{
+    if ((reader == NULL) || (reader->ctxt == NULL) ||
+        (reader->ctxt->input == NULL)) {
+        return (0);
+    }
+    return (reader->ctxt->input->col);
+}
+
+/**
+ * xmlTextReaderCurrentNode:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Hacking interface allowing to get the xmlNodePtr correponding to the
+ * current node being accessed by the xmlTextReader. This is dangerous
+ * because the underlying node may be destroyed on the next Reads.
+ *
+ * Returns the xmlNodePtr or NULL in case of error.
+ */
+xmlNodePtr
+xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(NULL);
+
+    if (reader->curnode != NULL)
+	return(reader->curnode);
+    return(reader->node);
+}
+
+/**
+ * xmlTextReaderPreserve:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * This tells the XML Reader to preserve the current node.
+ * The caller must also use xmlTextReaderCurrentDoc() to
+ * keep an handle on the resulting document once parsing has finished
+ *
+ * Returns the xmlNodePtr or NULL in case of error.
+ */
+xmlNodePtr
+xmlTextReaderPreserve(xmlTextReaderPtr reader) {
+    xmlNodePtr cur, parent;
+
+    if (reader == NULL)
+	return(NULL);
+
+    if (reader->curnode != NULL)
+        cur = reader->curnode;
+    else
+        cur = reader->node;
+    if (cur == NULL)
+        return(NULL);
+
+    if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
+	cur->extra |= NODE_IS_PRESERVED;
+	cur->extra |= NODE_IS_SPRESERVED;
+    }
+    reader->preserves++;
+
+    parent = cur->parent;;
+    while (parent != NULL) {
+        if (parent->type == XML_ELEMENT_NODE)
+	    parent->extra |= NODE_IS_PRESERVED;
+	parent = parent->parent;
+    }
+    return(cur);
+}
+
+#ifdef LIBXML_PATTERN_ENABLED
+/**
+ * xmlTextReaderPreservePattern:
+ * @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
+ *
+ * Returns a positive number in case of success and -1 in case of error
+ */
+int
+xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
+                             const xmlChar **namespaces)
+{
+    xmlPatternPtr comp;
+
+    if ((reader == NULL) || (pattern == NULL))
+	return(-1);
+
+    comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
+    if (comp == NULL)
+        return(-1);
+
+    if (reader->patternMax <= 0) {
+	reader->patternMax = 4;
+	reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
+					      sizeof(reader->patternTab[0]));
+        if (reader->patternTab == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
+            return (-1);
+        }
+    }
+    if (reader->patternNr >= reader->patternMax) {
+        xmlPatternPtr *tmp;
+        reader->patternMax *= 2;
+	tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
+                                      reader->patternMax *
+                                      sizeof(reader->patternTab[0]));
+        if (tmp == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
+	    reader->patternMax /= 2;
+            return (-1);
+        }
+	reader->patternTab = tmp;
+    }
+    reader->patternTab[reader->patternNr] = comp;
+    return(reader->patternNr++);
+}
+#endif
+
+/**
+ * xmlTextReaderCurrentDoc:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Hacking interface allowing to get the xmlDocPtr correponding to the
+ * 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.
+ *
+ * Returns the xmlDocPtr or NULL in case of error.
+ */
+xmlDocPtr
+xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) {
+    if (reader == NULL)
+	return(NULL);
+    if (reader->doc != NULL)
+        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 void XMLCDECL
+xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
+
+static void XMLCDECL
+xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
+
+static void XMLCDECL
+xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
+{
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
+
+    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, ...)
+{
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
+
+    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
+xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
+{
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
+
+    if (reader->sErrorFunc) {
+        reader->sErrorFunc(reader->errorFuncArg, error);
+    } else {
+        xmlTextReaderStructuredError(reader, error);
+    }
+}
+/**
+ * xmlTextReaderRelaxNGSetSchema:
+ * @reader:  the xmlTextReaderPtr used
+ * @schema:  a precompiled RelaxNG schema
+ *
+ * Use RelaxNG to validate the document as it is processed.
+ * Activation is only possible before the first Read().
+ * if @schema is NULL, then RelaxNG validation is desactivated.
+ @ The @schema should not be freed until the reader is deallocated
+ * or its use has been deactivated.
+ *
+ * Returns 0 in case the RelaxNG validation could be (des)activated and
+ *         -1 in case of error.
+ */
+int
+xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
+    if (reader == NULL)
+        return(-1);
+    if (schema == NULL) {
+        if (reader->rngSchemas != NULL) {
+	    xmlRelaxNGFree(reader->rngSchemas);
+	    reader->rngSchemas = NULL;
+	}
+        if (reader->rngValidCtxt != NULL) {
+	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
+	    reader->rngValidCtxt = NULL;
+        }
+	return(0);
+    }
+    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
+	return(-1);
+    if (reader->rngSchemas != NULL) {
+	xmlRelaxNGFree(reader->rngSchemas);
+	reader->rngSchemas = NULL;
+    }
+    if (reader->rngValidCtxt != NULL) {
+	xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
+	reader->rngValidCtxt = NULL;
+    }
+    reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
+    if (reader->rngValidCtxt == NULL)
+        return(-1);
+    if (reader->errorFunc != NULL) {
+	xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
+			xmlTextReaderValidityErrorRelay,
+			xmlTextReaderValidityWarningRelay,
+			reader);
+    }
+	if (reader->sErrorFunc != NULL) {
+		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+			xmlTextReaderValidityStructuredRelay,
+			reader);
+    }
+    reader->rngValidErrors = 0;
+    reader->rngFullNode = NULL;
+    reader->validate = XML_TEXTREADER_VALIDATE_RNG;
+    return(0);
+}
+
+/**
+ * xmlTextReaderSetSchema:
+ * @reader:  the xmlTextReaderPtr used
+ * @schema:  a precompiled Schema schema
+ *
+ * Use XSD Schema to validate the document as it is processed.
+ * Activation is only possible before the first Read().
+ * if @schema is NULL, then Schema validation is desactivated.
+ @ The @schema should not be freed until the reader is deallocated
+ * or its use has been deactivated.
+ *
+ * Returns 0 in case the Schema validation could be (des)activated and
+ *         -1 in case of error.
+ */
+int
+xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
+    if (reader == NULL)
+        return(-1);
+    if (schema == NULL) {
+	if (reader->xsdPlug != NULL) {
+	    xmlSchemaSAXUnplug(reader->xsdPlug);
+	    reader->xsdPlug = NULL;
+	}
+        if (reader->xsdValidCtxt != NULL) {
+	    if (! reader->xsdPreserveCtxt)
+		xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+	    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) {
+	xmlSchemaSAXUnplug(reader->xsdPlug);
+	reader->xsdPlug = NULL;
+    }
+    if (reader->xsdValidCtxt != NULL) {
+	if (! reader->xsdPreserveCtxt)
+	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+	reader->xsdValidCtxt = NULL;
+    }
+    reader->xsdPreserveCtxt = 0;
+    if (reader->xsdSchemas != NULL) {
+	xmlSchemaFree(reader->xsdSchemas);
+	reader->xsdSchemas = NULL;
+    }
+    reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);
+    if (reader->xsdValidCtxt == NULL) {
+	xmlSchemaFree(reader->xsdSchemas);
+	reader->xsdSchemas = NULL;
+        return(-1);
+    }
+    reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
+                                       &(reader->ctxt->sax),
+				       &(reader->ctxt->userData));
+    if (reader->xsdPlug == NULL) {
+	xmlSchemaFree(reader->xsdSchemas);
+	reader->xsdSchemas = NULL;
+	xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+	reader->xsdValidCtxt = NULL;
+	return(-1);
+    }
+    if (reader->errorFunc != NULL) {
+	xmlSchemaSetValidErrors(reader->xsdValidCtxt,
+			xmlTextReaderValidityErrorRelay,
+			xmlTextReaderValidityWarningRelay,
+			reader);
+    }
+	if (reader->sErrorFunc != NULL) {
+		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
+			xmlTextReaderValidityStructuredRelay,
+			reader);
+    }
+    reader->xsdValidErrors = 0;
+    reader->validate = XML_TEXTREADER_VALIDATE_XSD;
+    return(0);
+}
+
+/**
+ * xmlTextReaderRelaxNGValidate:
+ * @reader:  the xmlTextReaderPtr used
+ * @rng:  the path to a RelaxNG schema or NULL
+ *
+ * Use RelaxNG to validate the document as it is processed.
+ * Activation is only possible before the first Read().
+ * if @rng is NULL, then RelaxNG validation is deactivated.
+ *
+ * Returns 0 in case the RelaxNG validation could be (de)activated and
+ *         -1 in case of error.
+ */
+int
+xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng) {
+    xmlRelaxNGParserCtxtPtr ctxt;
+
+    if (reader == NULL)
+        return(-1);
+
+    if (rng == NULL) {
+        if (reader->rngValidCtxt != NULL) {
+	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
+	    reader->rngValidCtxt = NULL;
+        }
+        if (reader->rngSchemas != NULL) {
+	    xmlRelaxNGFree(reader->rngSchemas);
+	    reader->rngSchemas = NULL;
+	}
+	return(0);
+    }
+    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
+	return(-1);
+    if (reader->rngSchemas != NULL) {
+	xmlRelaxNGFree(reader->rngSchemas);
+	reader->rngSchemas = NULL;
+    }
+    if (reader->rngValidCtxt != NULL) {
+	xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
+	reader->rngValidCtxt = NULL;
+    }
+    ctxt = xmlRelaxNGNewParserCtxt(rng);
+    if (reader->errorFunc != NULL) {
+	xmlRelaxNGSetParserErrors(ctxt,
+			 xmlTextReaderValidityErrorRelay,
+			 xmlTextReaderValidityWarningRelay,
+			 reader);
+    }
+    if (reader->sErrorFunc != NULL) {
+	xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+			xmlTextReaderValidityStructuredRelay,
+			reader);
+    }
+    reader->rngSchemas = xmlRelaxNGParse(ctxt);
+    xmlRelaxNGFreeParserCtxt(ctxt);
+    if (reader->rngSchemas == NULL)
+        return(-1);
+    reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
+    if (reader->rngValidCtxt == NULL) {
+	xmlRelaxNGFree(reader->rngSchemas);
+	reader->rngSchemas = NULL;
+        return(-1);
+    }
+    if (reader->errorFunc != NULL) {
+	xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
+			 xmlTextReaderValidityErrorRelay,
+			 xmlTextReaderValidityWarningRelay,
+			 reader);
+    }
+	if (reader->sErrorFunc != NULL) {
+		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+			xmlTextReaderValidityStructuredRelay,
+			reader);
+    }
+    reader->rngValidErrors = 0;
+    reader->rngFullNode = NULL;
+    reader->validate = XML_TEXTREADER_VALIDATE_RNG;
+    return(0);
+}
+
+/**
+ * xmlTextReaderSchemaValidateInternal:
+ * @reader:  the xmlTextReaderPtr used
+ * @xsd:  the path to a W3C XSD schema or NULL
+ * @ctxt: the XML Schema validation context or NULL
+ * @options: options (not used yet)
+ *
+ * Validate the document as it is processed using XML Schema.
+ * Activation is only possible before the first Read().
+ * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
+ *
+ * Returns 0 in case the schemas validation could be (de)activated and
+ *         -1 in case of error.
+ */
+static int
+xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
+				    const char *xsd,
+				    xmlSchemaValidCtxtPtr ctxt,
+				    int options ATTRIBUTE_UNUSED)
+{
+    if (reader == NULL)
+        return(-1);
+
+    if ((xsd != NULL) && (ctxt != NULL))
+	return(-1);
+
+    if (((xsd != NULL) || (ctxt != NULL)) &&
+	((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
+        (reader->ctxt == NULL)))
+	return(-1);
+
+    /* Cleanup previous validation stuff. */
+    if (reader->xsdPlug != NULL) {
+	xmlSchemaSAXUnplug(reader->xsdPlug);
+	reader->xsdPlug = NULL;
+    }
+    if (reader->xsdValidCtxt != NULL) {
+	if (! reader->xsdPreserveCtxt)
+	    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. */
+	pctxt = xmlSchemaNewParserCtxt(xsd);
+	if (reader->errorFunc != NULL) {
+	    xmlSchemaSetParserErrors(pctxt,
+		xmlTextReaderValidityErrorRelay,
+		xmlTextReaderValidityWarningRelay,
+		reader);
+	}
+	reader->xsdSchemas = xmlSchemaParse(pctxt);
+	xmlSchemaFreeParserCtxt(pctxt);
+	if (reader->xsdSchemas == NULL)
+	    return(-1);
+	reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);
+	if (reader->xsdValidCtxt == NULL) {
+	    xmlSchemaFree(reader->xsdSchemas);
+	    reader->xsdSchemas = NULL;
+	    return(-1);
+	}
+	reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
+	    &(reader->ctxt->sax),
+	    &(reader->ctxt->userData));
+	if (reader->xsdPlug == NULL) {
+	    xmlSchemaFree(reader->xsdSchemas);
+	    reader->xsdSchemas = NULL;
+	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+	    reader->xsdValidCtxt = NULL;
+	    return(-1);
+	}
+    } else {
+	/* 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) {
+	    reader->xsdValidCtxt = NULL;
+	    reader->xsdPreserveCtxt = 0;
+	    return(-1);
+	}
+    }
+    /*
+    * Redirect the validation context's error channels to use
+    * the reader channels.
+    * TODO: In case the user provides the validation context we
+    *   could make this redirection optional.
+    */
+    if (reader->errorFunc != NULL) {
+	xmlSchemaSetValidErrors(reader->xsdValidCtxt,
+			 xmlTextReaderValidityErrorRelay,
+			 xmlTextReaderValidityWarningRelay,
+			 reader);
+    }
+	if (reader->sErrorFunc != NULL) {
+		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
+			xmlTextReaderValidityStructuredRelay,
+			reader);
+    }
+    reader->xsdValidErrors = 0;
+    reader->validate = XML_TEXTREADER_VALIDATE_XSD;
+    return(0);
+}
+
+/**
+ * xmlTextReaderSchemaValidateCtxt:
+ * @reader:  the xmlTextReaderPtr used
+ * @ctxt: the XML Schema validation context or NULL
+ * @options: options (not used yet)
+ *
+ * Use W3C XSD schema context to validate the document as it is processed.
+ * Activation is only possible before the first Read().
+ * If @ctxt is NULL, then XML Schema validation is deactivated.
+ *
+ * Returns 0 in case the schemas validation could be (de)activated and
+ *         -1 in case of error.
+ */
+int
+xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
+				    xmlSchemaValidCtxtPtr ctxt,
+				    int options)
+{
+    return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));
+}
+
+/**
+ * xmlTextReaderSchemaValidate:
+ * @reader:  the xmlTextReaderPtr used
+ * @xsd:  the path to a W3C XSD schema or NULL
+ *
+ * Use W3C XSD schema to validate the document as it is processed.
+ * Activation is only possible before the first Read().
+ * If @xsd is NULL, then XML Schema validation is deactivated.
+ *
+ * Returns 0 in case the schemas validation could be (de)activated and
+ *         -1 in case of error.
+ */
+int
+xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
+{
+    return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
+}
+#endif
+
+/**
+ * xmlTextReaderIsNamespaceDecl:
+ * @reader: the xmlTextReaderPtr used
+ *
+ * Determine whether the current node is a namespace declaration
+ * rather than a regular attribute.
+ *
+ * Returns 1 if the current node is a namespace declaration, 0 if it
+ * is a regular attribute or other type of node, or -1 in case of
+ * error.
+ */
+int
+xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) {
+    xmlNodePtr node;
+    if (reader == NULL)
+	return(-1);
+    if (reader->node == NULL)
+	return(-1);
+    if (reader->curnode != NULL)
+	node = reader->curnode;
+    else
+	node = reader->node;
+
+    if (XML_NAMESPACE_DECL == node->type)
+	return(1);
+    else
+	return(0);
+}
+
+/**
+ * xmlTextReaderConstXmlVersion:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Determine the XML version of the document being read.
+ *
+ * Returns a string containing the XML version of the document or NULL
+ * in case of error.  The string is deallocated with the reader.
+ */
+const xmlChar *
+xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) {
+    xmlDocPtr doc = NULL;
+    if (reader == NULL)
+	return(NULL);
+    if (reader->doc != NULL)
+        doc = reader->doc;
+    else if (reader->ctxt != NULL)
+	doc = reader->ctxt->myDoc;
+    if (doc == NULL)
+	return(NULL);
+
+    if (doc->version == NULL)
+	return(NULL);
+    else
+      return(CONSTSTR(doc->version));
+}
+
+/**
+ * xmlTextReaderStandalone:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Determine the standalone status of the document being read.
+ *
+ * Returns 1 if the document was declared to be standalone, 0 if it
+ * was declared to be not standalone, or -1 if the document did not
+ * specify its standalone status or in case of error.
+ */
+int
+xmlTextReaderStandalone(xmlTextReaderPtr reader) {
+    xmlDocPtr doc = NULL;
+    if (reader == NULL)
+	return(-1);
+    if (reader->doc != NULL)
+        doc = reader->doc;
+    else if (reader->ctxt != NULL)
+	doc = reader->ctxt->myDoc;
+    if (doc == NULL)
+	return(-1);
+
+    return(doc->standalone);
+}
+
+/************************************************************************
+ *									*
+ *			Error Handling Extensions                       *
+ *									*
+ ************************************************************************/
+
+/* helper to build a xmlMalloc'ed string from a format and va_list */
+static char *
+xmlTextReaderBuildMessage(const char *msg, va_list ap) {
+    int size = 0;
+    int chars;
+    char *larger;
+    char *str = NULL;
+    va_list aq;
+
+    while (1) {
+        VA_COPY(aq, ap);
+        chars = vsnprintf(str, size, msg, aq);
+        va_end(aq);
+        if (chars < 0) {
+	    xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
+	    if (str)
+		xmlFree(str);
+	    return NULL;
+	}
+	if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
+            break;
+        if (chars < MAX_ERR_MSG_SIZE)
+	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);
+            return NULL;
+        }
+        str = larger;
+    }
+
+    return str;
+}
+
+/**
+ * xmlTextReaderLocatorLineNumber:
+ * @locator: the xmlTextReaderLocatorPtr used
+ *
+ * Obtain the line number for the given locator.
+ *
+ * Returns the line number or -1 in case of error.
+ */
+int
+xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
+    /* we know that locator is a xmlParserCtxtPtr */
+    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
+    int ret = -1;
+
+    if (locator == NULL)
+        return(-1);
+    if (ctx->node != NULL) {
+	ret = xmlGetLineNo(ctx->node);
+    }
+    else {
+	/* inspired from error.c */
+	xmlParserInputPtr input;
+	input = ctx->input;
+	if ((input->filename == NULL) && (ctx->inputNr > 1))
+	    input = ctx->inputTab[ctx->inputNr - 2];
+	if (input != NULL) {
+	    ret = input->line;
+	}
+	else {
+	    ret = -1;
+	}
+    }
+
+    return ret;
+}
+
+/**
+ * xmlTextReaderLocatorBaseURI:
+ * @locator: the xmlTextReaderLocatorPtr used
+ *
+ * Obtain the base URI for the given locator.
+ *
+ * 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) {
+    /* we know that locator is a xmlParserCtxtPtr */
+    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
+    xmlChar *ret = NULL;
+
+    if (locator == NULL)
+        return(NULL);
+    if (ctx->node != NULL) {
+	ret = xmlNodeGetBase(NULL,ctx->node);
+    }
+    else {
+	/* inspired from error.c */
+	xmlParserInputPtr input;
+	input = ctx->input;
+	if ((input->filename == NULL) && (ctx->inputNr > 1))
+	    input = ctx->inputTab[ctx->inputNr - 2];
+	if (input != NULL) {
+	    ret = xmlStrdup(BAD_CAST input->filename);
+	}
+	else {
+	    ret = NULL;
+	}
+    }
+
+    return ret;
+}
+
+static void
+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);
+    }
+}
+
+static void
+xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
+{
+    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
+
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
+
+    if (error && reader->sErrorFunc) {
+        reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
+    }
+}
+
+static void XMLCDECL
+xmlTextReaderError(void *ctxt, const char *msg, ...)
+{
+    va_list ap;
+
+    va_start(ap, msg);
+    xmlTextReaderGenericError(ctxt,
+                              XML_PARSER_SEVERITY_ERROR,
+                              xmlTextReaderBuildMessage(msg, ap));
+    va_end(ap);
+
+}
+
+static void XMLCDECL
+xmlTextReaderWarning(void *ctxt, const char *msg, ...)
+{
+    va_list ap;
+
+    va_start(ap, msg);
+    xmlTextReaderGenericError(ctxt,
+                              XML_PARSER_SEVERITY_WARNING,
+                              xmlTextReaderBuildMessage(msg, ap));
+    va_end(ap);
+}
+
+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);
+    }
+}
+
+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);
+    }
+}
+
+/**
+ * xmlTextReaderSetErrorHandler:
+ * @reader:  the xmlTextReaderPtr used
+ * @f:	the callback function to call on error and warnings
+ * @arg:    a user argument to pass to the callback function
+ *
+ * Register a callback function that will be called on error and warnings.
+ *
+ * If @f is NULL, the default error and warning handlers are restored.
+ */
+void
+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;
+#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);
+        }
+#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;
+#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);
+        }
+#endif
+    }
+}
+
+/**
+* xmlTextReaderSetStructuredErrorHandler:
+ * @reader:  the xmlTextReaderPtr used
+ * @f:	the callback function to call on error and warnings
+ * @arg:    a user argument to pass to the callback function
+ *
+ * Register a callback function that will be called on error and warnings.
+ *
+ * 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;
+#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);
+        }
+#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;
+#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);
+        }
+#endif
+    }
+}
+
+/**
+ * xmlTextReaderIsValid:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Retrieve the validity status from the parser context
+ *
+ * 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);
+#ifdef LIBXML_SCHEMAS_ENABLED
+    if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
+        return (reader->rngValidErrors == 0);
+    if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
+        return (reader->xsdValidErrors == 0);
+#endif
+    if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
+        return (reader->ctxt->valid);
+    return (0);
+}
+
+/**
+ * xmlTextReaderGetErrorHandler:
+ * @reader:  the xmlTextReaderPtr used
+ * @f:	the callback function or NULL is no callback has been registered
+ * @arg:    a user argument
+ *
+ * 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;
+}
+/************************************************************************
+ *									*
+ *	New set (2.6.0) of simpler and more flexible APIs		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlTextReaderSetup:
+ * @reader:  an XML reader
+ * @input: xmlParserInputBufferPtr used to feed the reader, will
+ *         be destroyed with it.
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @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
+xmlTextReaderSetup(xmlTextReaderPtr reader,
+                   xmlParserInputBufferPtr input, const char *URL,
+                   const char *encoding, int options)
+{
+    if (reader == NULL) {
+        if (input != NULL)
+	    xmlFreeParserInputBuffer(input);
+        return (-1);
+    }
+
+    /*
+     * we force the generation of compact text nodes on the reader
+     * since usr applications should never modify the tree
+     */
+    options |= XML_PARSE_COMPACT;
+
+    reader->doc = NULL;
+    reader->entNr = 0;
+    reader->parserFlags = options;
+    reader->validate = XML_TEXTREADER_NOT_VALIDATE;
+    if ((input != NULL) && (reader->input != NULL) &&
+        (reader->allocs & XML_TEXTREADER_INPUT)) {
+	xmlFreeParserInputBuffer(reader->input);
+	reader->input = NULL;
+	reader->allocs -= XML_TEXTREADER_INPUT;
+    }
+    if (input != NULL) {
+	reader->input = input;
+	reader->allocs |= XML_TEXTREADER_INPUT;
+    }
+    if (reader->buffer == NULL)
+        reader->buffer = xmlBufferCreateSize(100);
+    if (reader->buffer == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlTextReaderSetup : malloc failed\n");
+        return (-1);
+    }
+    if (reader->sax == NULL)
+	reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
+    if (reader->sax == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlTextReaderSetup : malloc failed\n");
+        return (-1);
+    }
+    xmlSAXVersion(reader->sax, 2);
+    reader->startElement = reader->sax->startElement;
+    reader->sax->startElement = xmlTextReaderStartElement;
+    reader->endElement = reader->sax->endElement;
+    reader->sax->endElement = xmlTextReaderEndElement;
+#ifdef LIBXML_SAX1_ENABLED
+    if (reader->sax->initialized == XML_SAX2_MAGIC) {
+#endif /* LIBXML_SAX1_ENABLED */
+        reader->startElementNs = reader->sax->startElementNs;
+        reader->sax->startElementNs = xmlTextReaderStartElementNs;
+        reader->endElementNs = reader->sax->endElementNs;
+        reader->sax->endElementNs = xmlTextReaderEndElementNs;
+#ifdef LIBXML_SAX1_ENABLED
+    } else {
+        reader->startElementNs = NULL;
+        reader->endElementNs = NULL;
+    }
+#endif /* LIBXML_SAX1_ENABLED */
+    reader->characters = reader->sax->characters;
+    reader->sax->characters = xmlTextReaderCharacters;
+    reader->sax->ignorableWhitespace = xmlTextReaderCharacters;
+    reader->cdataBlock = reader->sax->cdataBlock;
+    reader->sax->cdataBlock = xmlTextReaderCDataBlock;
+
+    reader->mode = XML_TEXTREADER_MODE_INITIAL;
+    reader->node = NULL;
+    reader->curnode = NULL;
+    if (input != NULL) {
+        if (reader->input->buffer->use < 4) {
+            xmlParserInputBufferRead(input, 4);
+        }
+        if (reader->ctxt == NULL) {
+            if (reader->input->buffer->use >= 4) {
+                reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
+		       (const char *) reader->input->buffer->content, 4, URL);
+                reader->base = 0;
+                reader->cur = 4;
+            } else {
+                reader->ctxt =
+                    xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);
+                reader->base = 0;
+                reader->cur = 0;
+            }
+        } else {
+	    xmlParserInputPtr inputStream;
+	    xmlParserInputBufferPtr buf;
+	    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
+
+	    xmlCtxtReset(reader->ctxt);
+	    buf = xmlAllocParserInputBuffer(enc);
+	    if (buf == NULL) return(-1);
+	    inputStream = xmlNewInputStream(reader->ctxt);
+	    if (inputStream == NULL) {
+		xmlFreeParserInputBuffer(buf);
+		return(-1);
+	    }
+
+	    if (URL == NULL)
+		inputStream->filename = NULL;
+	    else
+		inputStream->filename = (char *)
+		    xmlCanonicPath((const xmlChar *) URL);
+	    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];
+
+	    inputPush(reader->ctxt, inputStream);
+	    reader->cur = 0;
+	}
+        if (reader->ctxt == NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlTextReaderSetup : malloc failed\n");
+            return (-1);
+        }
+    }
+    if (reader->dict != NULL) {
+        if (reader->ctxt->dict != NULL) {
+	    if (reader->dict != reader->ctxt->dict) {
+		xmlDictFree(reader->dict);
+		reader->dict = reader->ctxt->dict;
+	    }
+	} else {
+	    reader->ctxt->dict = reader->dict;
+	}
+    } else {
+	if (reader->ctxt->dict == NULL)
+	    reader->ctxt->dict = xmlDictCreate();
+        reader->dict = reader->ctxt->dict;
+    }
+    reader->ctxt->_private = reader;
+    reader->ctxt->linenumbers = 1;
+    reader->ctxt->dictNames = 1;
+    /*
+     * use the parser dictionnary to allocate all elements and attributes names
+     */
+    reader->ctxt->docdict = 1;
+    reader->ctxt->parseMode = XML_PARSE_READER;
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+    if (reader->xincctxt != NULL) {
+	xmlXIncludeFreeContext(reader->xincctxt);
+	reader->xincctxt = NULL;
+    }
+    if (options & XML_PARSE_XINCLUDE) {
+        reader->xinclude = 1;
+	reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);
+	options -= XML_PARSE_XINCLUDE;
+    } else
+        reader->xinclude = 0;
+    reader->in_xinclude = 0;
+#endif
+#ifdef LIBXML_PATTERN_ENABLED
+    if (reader->patternTab == NULL) {
+        reader->patternNr = 0;
+	reader->patternMax = 0;
+    }
+    while (reader->patternNr > 0) {
+        reader->patternNr--;
+	if (reader->patternTab[reader->patternNr] != NULL) {
+	    xmlFreePattern(reader->patternTab[reader->patternNr]);
+            reader->patternTab[reader->patternNr] = NULL;
+	}
+    }
+#endif
+
+    if (options & XML_PARSE_DTDVALID)
+        reader->validate = XML_TEXTREADER_VALIDATE_DTD;
+
+    xmlCtxtUseOptions(reader->ctxt, options);
+    if (encoding != NULL) {
+        xmlCharEncodingHandlerPtr hdlr;
+
+        hdlr = xmlFindCharEncodingHandler(encoding);
+        if (hdlr != NULL)
+            xmlSwitchToEncoding(reader->ctxt, hdlr);
+    }
+    if ((URL != NULL) && (reader->ctxt->input != NULL) &&
+        (reader->ctxt->input->filename == NULL))
+        reader->ctxt->input->filename = (char *)
+            xmlStrdup((const xmlChar *) URL);
+
+    reader->doc = NULL;
+
+    return (0);
+}
+
+/**
+ * xmlTextReaderByteConsumed:
+ * @reader: an XML reader
+ *
+ * This function provides the current index of the parser used
+ * by the reader, relative to the start of the current entity.
+ * This function actually just wraps a call to xmlBytesConsumed()
+ * for the parser context associated with the reader.
+ * See xmlBytesConsumed() for more information.
+ *
+ * Returns the index in bytes from the beginning of the entity or -1
+ *         in case the index could not be computed.
+ */
+long
+xmlTextReaderByteConsumed(xmlTextReaderPtr reader) {
+    if ((reader == NULL) || (reader->ctxt == NULL))
+        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
+xmlReaderWalker(xmlDocPtr doc)
+{
+    xmlTextReaderPtr ret;
+
+    if (doc == NULL)
+        return(NULL);
+
+    ret = xmlMalloc(sizeof(xmlTextReader));
+    if (ret == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlNewTextReader : malloc failed\n");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlTextReader));
+    ret->entNr = 0;
+    ret->input = NULL;
+    ret->mode = XML_TEXTREADER_MODE_INITIAL;
+    ret->node = NULL;
+    ret->curnode = NULL;
+    ret->base = 0;
+    ret->cur = 0;
+    ret->allocs = XML_TEXTREADER_CTXT;
+    ret->doc = doc;
+    ret->state = XML_TEXTREADER_START;
+    ret->dict = xmlDictCreate();
+    return(ret);
+}
+
+/**
+ * xmlReaderForDoc:
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,
+                int options)
+{
+    int len;
+
+    if (cur == NULL)
+        return (NULL);
+    len = xmlStrlen(cur);
+
+    return (xmlReaderForMemory
+            ((const char *) cur, len, URL, encoding, options));
+}
+
+/**
+ * xmlReaderForFile:
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderForFile(const char *filename, const char *encoding, int options)
+{
+    xmlTextReaderPtr reader;
+
+    reader = xmlNewTextReaderFilename(filename);
+    if (reader == NULL)
+        return (NULL);
+    xmlTextReaderSetup(reader, NULL, NULL, encoding, options);
+    return (reader);
+}
+
+/**
+ * xmlReaderForMemory:
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderForMemory(const char *buffer, int size, const char *URL,
+                   const char *encoding, int options)
+{
+    xmlTextReaderPtr reader;
+    xmlParserInputBufferPtr buf;
+
+    buf = xmlParserInputBufferCreateStatic(buffer, size,
+                                      XML_CHAR_ENCODING_NONE);
+    if (buf == NULL) {
+        return (NULL);
+    }
+    reader = xmlNewTextReader(buf, URL);
+    if (reader == NULL) {
+        xmlFreeParserInputBuffer(buf);
+        return (NULL);
+    }
+    reader->allocs |= XML_TEXTREADER_INPUT;
+    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
+    return (reader);
+}
+
+/**
+ * xmlReaderForFd:
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * Create an xmltextReader for an XML from a file descriptor.
+ * 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
+xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)
+{
+    xmlTextReaderPtr reader;
+    xmlParserInputBufferPtr input;
+
+    if (fd < 0)
+        return (NULL);
+
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    input->closecallback = NULL;
+    reader = xmlNewTextReader(input, URL);
+    if (reader == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    reader->allocs |= XML_TEXTREADER_INPUT;
+    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
+    return (reader);
+}
+
+/**
+ * xmlReaderForIO:
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
+               void *ioctx, const char *URL, const char *encoding,
+               int options)
+{
+    xmlTextReaderPtr reader;
+    xmlParserInputBufferPtr input;
+
+    if (ioread == NULL)
+        return (NULL);
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (NULL);
+    reader = xmlNewTextReader(input, URL);
+    if (reader == NULL) {
+        xmlFreeParserInputBuffer(input);
+        return (NULL);
+    }
+    reader->allocs |= XML_TEXTREADER_INPUT;
+    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
+    return (reader);
+}
+
+/**
+ * xmlReaderNewWalker:
+ * @reader:  an XML reader
+ * @doc:  a preparsed document
+ *
+ * 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
+xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)
+{
+    if (doc == NULL)
+        return (-1);
+    if (reader == NULL)
+        return (-1);
+
+    if (reader->input != NULL) {
+        xmlFreeParserInputBuffer(reader->input);
+    }
+    if (reader->ctxt != NULL) {
+	xmlCtxtReset(reader->ctxt);
+    }
+
+    reader->entNr = 0;
+    reader->input = NULL;
+    reader->mode = XML_TEXTREADER_MODE_INITIAL;
+    reader->node = NULL;
+    reader->curnode = NULL;
+    reader->base = 0;
+    reader->cur = 0;
+    reader->allocs = XML_TEXTREADER_CTXT;
+    reader->doc = doc;
+    reader->state = XML_TEXTREADER_START;
+    if (reader->dict == NULL) {
+        if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))
+	    reader->dict = reader->ctxt->dict;
+	else
+	    reader->dict = xmlDictCreate();
+    }
+    return(0);
+}
+
+/**
+ * xmlReaderNewDoc:
+ * @reader:  an XML reader
+ * @cur:  a pointer to a zero terminated string
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,
+                const char *URL, const char *encoding, int options)
+{
+
+    int len;
+
+    if (cur == NULL)
+        return (-1);
+    if (reader == NULL)
+        return (-1);
+
+    len = xmlStrlen(cur);
+    return (xmlReaderNewMemory(reader, (const char *)cur, len,
+                               URL, encoding, options));
+}
+
+/**
+ * xmlReaderNewFile:
+ * @reader:  an XML reader
+ * @filename:  a file or URL
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,
+                 const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+
+    if (filename == NULL)
+        return (-1);
+    if (reader == NULL)
+        return (-1);
+
+    input =
+        xmlParserInputBufferCreateFilename(filename,
+                                           XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (-1);
+    return (xmlTextReaderSetup(reader, input, filename, encoding, options));
+}
+
+/**
+ * xmlReaderNewMemory:
+ * @reader:  an XML reader
+ * @buffer:  a pointer to a char array
+ * @size:  the size of the array
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * 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
+xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,
+                   const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+
+    if (reader == NULL)
+        return (-1);
+    if (buffer == NULL)
+        return (-1);
+
+    input = xmlParserInputBufferCreateStatic(buffer, size,
+                                      XML_CHAR_ENCODING_NONE);
+    if (input == NULL) {
+        return (-1);
+    }
+    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
+}
+
+/**
+ * xmlReaderNewFd:
+ * @reader:  an XML reader
+ * @fd:  an open file descriptor
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * Setup an xmltextReader to parse an XML from a file descriptor.
+ * NOTE that the file descriptor will not be closed when the
+ *      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
+xmlReaderNewFd(xmlTextReaderPtr reader, int fd,
+               const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+
+    if (fd < 0)
+        return (-1);
+    if (reader == NULL)
+        return (-1);
+
+    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (-1);
+    input->closecallback = NULL;
+    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
+}
+
+/**
+ * xmlReaderNewIO:
+ * @reader:  an XML reader
+ * @ioread:  an I/O read function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @URL:  the base URL to use for the document
+ * @encoding:  the document encoding, or NULL
+ * @options:  a combination of xmlParserOption
+ *
+ * Setup an xmltextReader to parse an XML document from I/O functions
+ * 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
+xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
+               xmlInputCloseCallback ioclose, void *ioctx,
+               const char *URL, const char *encoding, int options)
+{
+    xmlParserInputBufferPtr input;
+
+    if (ioread == NULL)
+        return (-1);
+    if (reader == NULL)
+        return (-1);
+
+    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
+                                         XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+        return (-1);
+    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
+}
+/************************************************************************
+ *									*
+ *			Utilities					*
+ *									*
+ ************************************************************************/
+#ifdef NOT_USED_YET
+
+/**
+ * xmlBase64Decode:
+ * @in:  the input buffer
+ * @inlen:  the size of the input (in), the size read from it (out)
+ * @to:  the output buffer
+ * @tolen:  the size of the output (in), the size written to (out)
+ *
+ * Base64 decoder, reads from @in and save in @to
+ * TODO: tell jody when this is actually exported
+ *
+ * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
+ *         2 if there wasn't enough space on the output or -1 in case of error.
+ */
+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 */
+
+    int retval = 1;
+
+    int i;
+
+    if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
+        return (-1);
+
+    incur = 0;
+    inblk = 0;
+    outcur = 0;
+    inmax = *inlen;
+    outmax = *tolen;
+    nbintmp = 0;
+
+    while (1) {
+        if (incur >= inmax)
+            break;
+        cur = in[incur++];
+        is_ignore = 0;
+        if ((cur >= 'A') && (cur <= 'Z'))
+            cur = cur - 'A';
+        else if ((cur >= 'a') && (cur <= 'z'))
+            cur = cur - 'a' + 26;
+        else if ((cur >= '0') && (cur <= '9'))
+            cur = cur - '0' + 52;
+        else if (cur == '+')
+            cur = 62;
+        else if (cur == '/')
+            cur = 63;
+        else if (cur == '.')
+            cur = 0;
+        else if (cur == '=')    /*no op , end of the base64 stream */
+            is_end = 1;
+        else {
+            is_ignore = 1;
+            if (nbintmp == 0)
+                inblk = incur;
+        }
+
+        if (!is_ignore) {
+            int nbouttmp = 3;
+
+            int is_break = 0;
+
+            if (is_end) {
+                if (nbintmp == 0)
+                    break;
+                if ((nbintmp == 1) || (nbintmp == 2))
+                    nbouttmp = 1;
+                else
+                    nbouttmp = 2;
+                nbintmp = 3;
+                is_break = 1;
+            }
+            intmp[nbintmp++] = cur;
+            /*
+             * 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;
+                }
+
+                for (i = 0; i < nbouttmp; i++)
+                    to[outcur++] = outtmp[i];
+                inblk = incur;
+            }
+
+            if (is_break) {
+                retval = 0;
+                break;
+            }
+        }
+    }
+
+    *tolen = outcur;
+    *inlen = inblk;
+    return (retval);
+}
+
+/*
+ * Test routine for the xmlBase64Decode function
+ */
+#if 0
+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;
+
+    /*
+     * Direct
+     */
+    ret = xmlBase64Decode(input, &inlen, output, &outlen);
+
+    output[outlen] = 0;
+    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;
+
+        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);
+
+    /*
+     * input chunking
+     */
+    cons = 0;
+    prod = 0;
+    while (cons < inlen) {
+        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);
+    }
+    output3[outlen] = 0;
+    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
+           prod, output3);
+    return (0);
+
+}
+#endif
+#endif /* NOT_USED_YET */
+#define bottom_xmlreader
+#include "elfgcchack.h"
+#endif /* LIBXML_READER_ENABLED */
diff --git a/src/xmlregexp.c b/src/xmlregexp.c
new file mode 100644
index 0000000..feae874
--- /dev/null
+++ b/src/xmlregexp.c
@@ -0,0 +1,8153 @@
+/*
+ * regexp.c: generic and extensible Regular Expression engine
+ *
+ * Basically designed with the purpose of compiling regexps for 
+ * the variety of validation/shemas mechanisms now available in
+ * XML related specifications these include:
+ *    - XML-1.0 DTD validation
+ *    - XML Schemas structure part 1
+ *    - XML Schemas Datatypes part 2 especially Appendix F
+ *    - RELAX-NG/TREX i.e. the counter proposal
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+/* #define DEBUG_ERR */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <libxml/tree.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlunicode.h>
+
+#ifndef INT_MAX
+#define INT_MAX 123456789 /* easy to flag and big enough for our needs */
+#endif
+
+/* #define DEBUG_REGEXP_GRAPH */
+/* #define DEBUG_REGEXP_EXEC */
+/* #define DEBUG_PUSH */
+/* #define DEBUG_COMPACTION */
+
+#define MAX_PUSH 10000000
+
+#define ERROR(str)							\
+    ctxt->error = XML_REGEXP_COMPILE_ERROR;				\
+    xmlRegexpErrCompile(ctxt, str);
+#define NEXT ctxt->cur++
+#define CUR (*(ctxt->cur))
+#define NXT(index) (ctxt->cur[index])
+
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
+#define NEXTL(l) ctxt->cur += l;
+#define XML_REG_STRING_SEPARATOR '|'
+/*
+ * Need PREV to check on a '-' within a Character Group. May only be used
+ * when it's guaranteed that cur is not at the beginning of ctxt->string!
+ */
+#define PREV (ctxt->cur[-1])
+
+/**
+ * TODO:
+ *
+ * macro to flag unimplemented blocks
+ */
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+/************************************************************************
+ * 									*
+ * 			Datatypes and structures			*
+ * 									*
+ ************************************************************************/
+
+/*
+ * Note: the order of the enums below is significant, do not shuffle
+ */
+typedef enum {
+    XML_REGEXP_EPSILON = 1,
+    XML_REGEXP_CHARVAL,
+    XML_REGEXP_RANGES,
+    XML_REGEXP_SUBREG,  /* used for () sub regexps */
+    XML_REGEXP_STRING,
+    XML_REGEXP_ANYCHAR, /* . */
+    XML_REGEXP_ANYSPACE, /* \s */
+    XML_REGEXP_NOTSPACE, /* \S */
+    XML_REGEXP_INITNAME, /* \l */
+    XML_REGEXP_NOTINITNAME, /* \L */
+    XML_REGEXP_NAMECHAR, /* \c */
+    XML_REGEXP_NOTNAMECHAR, /* \C */
+    XML_REGEXP_DECIMAL, /* \d */
+    XML_REGEXP_NOTDECIMAL, /* \D */
+    XML_REGEXP_REALCHAR, /* \w */
+    XML_REGEXP_NOTREALCHAR, /* \W */
+    XML_REGEXP_LETTER = 100,
+    XML_REGEXP_LETTER_UPPERCASE,
+    XML_REGEXP_LETTER_LOWERCASE,
+    XML_REGEXP_LETTER_TITLECASE,
+    XML_REGEXP_LETTER_MODIFIER,
+    XML_REGEXP_LETTER_OTHERS,
+    XML_REGEXP_MARK,
+    XML_REGEXP_MARK_NONSPACING,
+    XML_REGEXP_MARK_SPACECOMBINING,
+    XML_REGEXP_MARK_ENCLOSING,
+    XML_REGEXP_NUMBER,
+    XML_REGEXP_NUMBER_DECIMAL,
+    XML_REGEXP_NUMBER_LETTER,
+    XML_REGEXP_NUMBER_OTHERS,
+    XML_REGEXP_PUNCT,
+    XML_REGEXP_PUNCT_CONNECTOR,
+    XML_REGEXP_PUNCT_DASH,
+    XML_REGEXP_PUNCT_OPEN,
+    XML_REGEXP_PUNCT_CLOSE,
+    XML_REGEXP_PUNCT_INITQUOTE,
+    XML_REGEXP_PUNCT_FINQUOTE,
+    XML_REGEXP_PUNCT_OTHERS,
+    XML_REGEXP_SEPAR,
+    XML_REGEXP_SEPAR_SPACE,
+    XML_REGEXP_SEPAR_LINE,
+    XML_REGEXP_SEPAR_PARA,
+    XML_REGEXP_SYMBOL,
+    XML_REGEXP_SYMBOL_MATH,
+    XML_REGEXP_SYMBOL_CURRENCY,
+    XML_REGEXP_SYMBOL_MODIFIER,
+    XML_REGEXP_SYMBOL_OTHERS,
+    XML_REGEXP_OTHER,
+    XML_REGEXP_OTHER_CONTROL,
+    XML_REGEXP_OTHER_FORMAT,
+    XML_REGEXP_OTHER_PRIVATE,
+    XML_REGEXP_OTHER_NA,
+    XML_REGEXP_BLOCK_NAME
+} xmlRegAtomType;
+
+typedef enum {
+    XML_REGEXP_QUANT_EPSILON = 1,
+    XML_REGEXP_QUANT_ONCE,
+    XML_REGEXP_QUANT_OPT,
+    XML_REGEXP_QUANT_MULT,
+    XML_REGEXP_QUANT_PLUS,
+    XML_REGEXP_QUANT_ONCEONLY,
+    XML_REGEXP_QUANT_ALL,
+    XML_REGEXP_QUANT_RANGE
+} xmlRegQuantType;
+
+typedef enum {
+    XML_REGEXP_START_STATE = 1,
+    XML_REGEXP_FINAL_STATE,
+    XML_REGEXP_TRANS_STATE,
+    XML_REGEXP_SINK_STATE,
+    XML_REGEXP_UNREACH_STATE
+} xmlRegStateType;
+
+typedef enum {
+    XML_REGEXP_MARK_NORMAL = 0,
+    XML_REGEXP_MARK_START,
+    XML_REGEXP_MARK_VISITED
+} xmlRegMarkedType;
+
+typedef struct _xmlRegRange xmlRegRange;
+typedef xmlRegRange *xmlRegRangePtr;
+
+struct _xmlRegRange {
+    int neg;		/* 0 normal, 1 not, 2 exclude */
+    xmlRegAtomType type;
+    int start;
+    int end;
+    xmlChar *blockName;
+};
+
+typedef struct _xmlRegAtom xmlRegAtom;
+typedef xmlRegAtom *xmlRegAtomPtr;
+
+typedef struct _xmlAutomataState xmlRegState;
+typedef xmlRegState *xmlRegStatePtr;
+
+struct _xmlRegAtom {
+    int no;
+    xmlRegAtomType type;
+    xmlRegQuantType quant;
+    int min;
+    int max;
+
+    void *valuep;
+    void *valuep2;
+    int neg;
+    int codepoint;
+    xmlRegStatePtr start;
+    xmlRegStatePtr start0;
+    xmlRegStatePtr stop;
+    int maxRanges;
+    int nbRanges;
+    xmlRegRangePtr *ranges;
+    void *data;
+};
+
+typedef struct _xmlRegCounter xmlRegCounter;
+typedef xmlRegCounter *xmlRegCounterPtr;
+
+struct _xmlRegCounter {
+    int min;
+    int max;
+};
+
+typedef struct _xmlRegTrans xmlRegTrans;
+typedef xmlRegTrans *xmlRegTransPtr;
+
+struct _xmlRegTrans {
+    xmlRegAtomPtr atom;
+    int to;
+    int counter;
+    int count;
+    int nd;
+};
+
+struct _xmlAutomataState {
+    xmlRegStateType type;
+    xmlRegMarkedType mark;
+    xmlRegMarkedType reached;
+    int no;
+    int maxTrans;
+    int nbTrans;
+    xmlRegTrans *trans;
+    /*  knowing states ponting to us can speed things up */
+    int maxTransTo;
+    int nbTransTo;
+    int *transTo;
+};
+
+typedef struct _xmlAutomata xmlRegParserCtxt;
+typedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
+
+#define AM_AUTOMATA_RNG 1
+
+struct _xmlAutomata {
+    xmlChar *string;
+    xmlChar *cur;
+
+    int error;
+    int neg;
+
+    xmlRegStatePtr start;
+    xmlRegStatePtr end;
+    xmlRegStatePtr state;
+
+    xmlRegAtomPtr atom;
+
+    int maxAtoms;
+    int nbAtoms;
+    xmlRegAtomPtr *atoms;
+
+    int maxStates;
+    int nbStates;
+    xmlRegStatePtr *states;
+
+    int maxCounters;
+    int nbCounters;
+    xmlRegCounter *counters;
+
+    int determinist;
+    int negs;
+    int flags;
+};
+
+struct _xmlRegexp {
+    xmlChar *string;
+    int nbStates;
+    xmlRegStatePtr *states;
+    int nbAtoms;
+    xmlRegAtomPtr *atoms;
+    int nbCounters;
+    xmlRegCounter *counters;
+    int determinist;
+    int flags;
+    /*
+     * That's the compact form for determinists automatas
+     */
+    int nbstates;
+    int *compact;
+    void **transdata;
+    int nbstrings;
+    xmlChar **stringMap;
+};
+
+typedef struct _xmlRegExecRollback xmlRegExecRollback;
+typedef xmlRegExecRollback *xmlRegExecRollbackPtr;
+
+struct _xmlRegExecRollback {
+    xmlRegStatePtr state;/* the current state */
+    int index;		/* the index in the input stack */
+    int nextbranch;	/* the next transition to explore in that state */
+    int *counts;	/* save the automata state if it has some */
+};
+
+typedef struct _xmlRegInputToken xmlRegInputToken;
+typedef xmlRegInputToken *xmlRegInputTokenPtr;
+
+struct _xmlRegInputToken {
+    xmlChar *value;
+    void *data;
+};
+
+struct _xmlRegExecCtxt {
+    int status;		/* execution status != 0 indicate an error */
+    int determinist;	/* did we find an indeterministic behaviour */
+    xmlRegexpPtr comp;	/* the compiled regexp */
+    xmlRegExecCallbacks callback;
+    void *data;
+
+    xmlRegStatePtr state;/* the current state */
+    int transno;	/* the current transition on that state */
+    int transcount;	/* the number of chars in char counted transitions */
+
+    /*
+     * A stack of rollback states
+     */
+    int maxRollbacks;
+    int nbRollbacks;
+    xmlRegExecRollback *rollbacks;
+
+    /*
+     * The state of the automata if any
+     */
+    int *counts;
+
+    /*
+     * The input stack
+     */
+    int inputStackMax;
+    int inputStackNr;
+    int index;
+    int *charStack;
+    const xmlChar *inputString; /* when operating on characters */
+    xmlRegInputTokenPtr inputStack;/* when operating on strings */
+
+    /*
+     * error handling
+     */
+    int errStateNo;		/* the error state number */
+    xmlRegStatePtr errState;    /* the error state */
+    xmlChar *errString;		/* the string raising the error */
+    int *errCounts;		/* counters at the error state */
+    int nbPush;
+};
+
+#define REGEXP_ALL_COUNTER	0x123456
+#define REGEXP_ALL_LAX_COUNTER	0x123457
+
+static void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top);
+static void xmlRegFreeState(xmlRegStatePtr state);
+static void xmlRegFreeAtom(xmlRegAtomPtr atom);
+static int xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr);
+static int xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint);
+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				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlRegexpErrMemory:
+ * @extra:  extra information
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlRegexpErrMemory(xmlRegParserCtxtPtr ctxt, const char *extra)
+{
+    const char *regexp = NULL;
+    if (ctxt != NULL) {
+        regexp = (const char *) ctxt->string;
+	ctxt->error = XML_ERR_NO_MEMORY;
+    }
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
+		    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
+		    regexp, NULL, 0, 0,
+		    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlRegexpErrCompile:
+ * @extra:  extra information
+ *
+ * Handle a compilation failure
+ */
+static void
+xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra)
+{
+    const char *regexp = NULL;
+    int idx = 0;
+
+    if (ctxt != NULL) {
+        regexp = (const char *) ctxt->string;
+	idx = ctxt->cur - ctxt->string;
+	ctxt->error = XML_REGEXP_COMPILE_ERROR;
+    }
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
+		    XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra,
+		    regexp, NULL, idx, 0,
+		    "failed to compile: %s\n", extra);
+}
+
+/************************************************************************
+ * 									*
+ * 			Allocation/Deallocation				*
+ * 									*
+ ************************************************************************/
+
+static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
+/**
+ * xmlRegEpxFromParse:
+ * @ctxt:  the parser context used to build it
+ *
+ * Allocate a new regexp and fill it with the result from the parser
+ *
+ * Returns the new regexp or NULL in case of error
+ */
+static xmlRegexpPtr
+xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
+    xmlRegexpPtr ret;
+
+    ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp));
+    if (ret == NULL) {
+	xmlRegexpErrMemory(ctxt, "compiling regexp");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlRegexp));
+    ret->string = ctxt->string;
+    ret->nbStates = ctxt->nbStates;
+    ret->states = ctxt->states;
+    ret->nbAtoms = ctxt->nbAtoms;
+    ret->atoms = ctxt->atoms;
+    ret->nbCounters = ctxt->nbCounters;
+    ret->counters = ctxt->counters;
+    ret->determinist = ctxt->determinist;
+    ret->flags = ctxt->flags;
+    if (ret->determinist == -1) {
+        xmlRegexpIsDeterminist(ret);
+    }
+
+    if ((ret->determinist != 0) &&
+	(ret->nbCounters == 0) &&
+	(ctxt->negs == 0) &&
+	(ret->atoms != NULL) &&
+	(ret->atoms[0] != NULL) &&
+	(ret->atoms[0]->type == XML_REGEXP_STRING)) {
+	int i, j, nbstates = 0, nbatoms = 0;
+	int *stateRemap;
+	int *stringRemap;
+	int *transitions;
+	void **transdata;
+	xmlChar **stringMap;
+        xmlChar *value;
+
+	/*
+	 * Switch to a compact representation
+	 * 1/ counting the effective number of states left
+	 * 2/ counting the unique number of atoms, and check that
+	 *    they are all of the string type
+	 * 3/ build a table state x atom for the transitions
+	 */
+
+	stateRemap = xmlMalloc(ret->nbStates * sizeof(int));
+	if (stateRemap == NULL) {
+	    xmlRegexpErrMemory(ctxt, "compiling regexp");
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	for (i = 0;i < ret->nbStates;i++) {
+	    if (ret->states[i] != NULL) {
+		stateRemap[i] = nbstates;
+		nbstates++;
+	    } else {
+		stateRemap[i] = -1;
+	    }
+	}
+#ifdef DEBUG_COMPACTION
+	printf("Final: %d states\n", nbstates);
+#endif
+	stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *));
+	if (stringMap == NULL) {
+	    xmlRegexpErrMemory(ctxt, "compiling regexp");
+	    xmlFree(stateRemap);
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int));
+	if (stringRemap == NULL) {
+	    xmlRegexpErrMemory(ctxt, "compiling regexp");
+	    xmlFree(stringMap);
+	    xmlFree(stateRemap);
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	for (i = 0;i < ret->nbAtoms;i++) {
+	    if ((ret->atoms[i]->type == XML_REGEXP_STRING) &&
+		(ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) {
+		value = ret->atoms[i]->valuep;
+                for (j = 0;j < nbatoms;j++) {
+		    if (xmlStrEqual(stringMap[j], value)) {
+			stringRemap[i] = j;
+			break;
+		    }
+		}
+		if (j >= nbatoms) {
+		    stringRemap[i] = nbatoms;
+		    stringMap[nbatoms] = xmlStrdup(value);
+		    if (stringMap[nbatoms] == NULL) {
+			for (i = 0;i < nbatoms;i++)
+			    xmlFree(stringMap[i]);
+			xmlFree(stringRemap);
+			xmlFree(stringMap);
+			xmlFree(stateRemap);
+			xmlFree(ret);
+			return(NULL);
+		    }
+		    nbatoms++;
+		}
+	    } else {
+		xmlFree(stateRemap);
+		xmlFree(stringRemap);
+		for (i = 0;i < nbatoms;i++)
+		    xmlFree(stringMap[i]);
+		xmlFree(stringMap);
+		xmlFree(ret);
+		return(NULL);
+	    }
+	}
+#ifdef DEBUG_COMPACTION
+	printf("Final: %d atoms\n", nbatoms);
+#endif
+	transitions = (int *) xmlMalloc((nbstates + 1) *
+	                                (nbatoms + 1) * sizeof(int));
+	if (transitions == NULL) {
+	    xmlFree(stateRemap);
+	    xmlFree(stringRemap);
+	    xmlFree(stringMap);
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int));
+
+	/*
+	 * Allocate the transition table. The first entry for each
+	 * state corresponds to the state type.
+	 */
+	transdata = NULL;
+
+	for (i = 0;i < ret->nbStates;i++) {
+	    int stateno, atomno, targetno, prev;
+	    xmlRegStatePtr state;
+	    xmlRegTransPtr trans;
+
+	    stateno = stateRemap[i];
+	    if (stateno == -1)
+		continue;
+	    state = ret->states[i];
+
+	    transitions[stateno * (nbatoms + 1)] = state->type;
+
+	    for (j = 0;j < state->nbTrans;j++) {
+		trans = &(state->trans[j]);
+		if ((trans->to == -1) || (trans->atom == NULL))
+		    continue;
+                atomno = stringRemap[trans->atom->no];
+		if ((trans->atom->data != NULL) && (transdata == NULL)) {
+		    transdata = (void **) xmlMalloc(nbstates * nbatoms *
+			                            sizeof(void *));
+		    if (transdata != NULL)
+			memset(transdata, 0,
+			       nbstates * nbatoms * sizeof(void *));
+		    else {
+			xmlRegexpErrMemory(ctxt, "compiling regexp");
+			break;
+		    }
+		}
+		targetno = stateRemap[trans->to];
+		/*
+		 * if the same atom can generate transitions to 2 different
+		 * states then it means the automata is not determinist and
+		 * the compact form can't be used !
+		 */
+		prev = transitions[stateno * (nbatoms + 1) + atomno + 1];
+		if (prev != 0) {
+		    if (prev != targetno + 1) {
+			ret->determinist = 0;
+#ifdef DEBUG_COMPACTION
+			printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n",
+			       i, j, trans->atom->no, trans->to, atomno, targetno);
+			printf("       previous to is %d\n", prev);
+#endif
+			if (transdata != NULL)
+			    xmlFree(transdata);
+			xmlFree(transitions);
+			xmlFree(stateRemap);
+			xmlFree(stringRemap);
+			for (i = 0;i < nbatoms;i++)
+			    xmlFree(stringMap[i]);
+			xmlFree(stringMap);
+			goto not_determ;
+		    }
+		} else {
+#if 0
+		    printf("State %d trans %d: atom %d to %d : %d to %d\n",
+			   i, j, trans->atom->no, trans->to, atomno, targetno);
+#endif
+		    transitions[stateno * (nbatoms + 1) + atomno + 1] =
+			targetno + 1; /* to avoid 0 */
+		    if (transdata != NULL)
+			transdata[stateno * nbatoms + atomno] =
+			    trans->atom->data;
+		}
+	    }
+	}
+	ret->determinist = 1;
+#ifdef DEBUG_COMPACTION
+	/*
+	 * Debug
+	 */
+	for (i = 0;i < nbstates;i++) {
+	    for (j = 0;j < nbatoms + 1;j++) {
+                printf("%02d ", transitions[i * (nbatoms + 1) + j]);
+	    }
+	    printf("\n");
+	}
+	printf("\n");
+#endif
+	/*
+	 * Cleanup of the old data
+	 */
+	if (ret->states != NULL) {
+	    for (i = 0;i < ret->nbStates;i++)
+		xmlRegFreeState(ret->states[i]);
+	    xmlFree(ret->states);
+	}
+	ret->states = NULL;
+	ret->nbStates = 0;
+	if (ret->atoms != NULL) {
+	    for (i = 0;i < ret->nbAtoms;i++)
+		xmlRegFreeAtom(ret->atoms[i]);
+	    xmlFree(ret->atoms);
+	}
+	ret->atoms = NULL;
+	ret->nbAtoms = 0;
+
+	ret->compact = transitions;
+	ret->transdata = transdata;
+	ret->stringMap = stringMap;
+	ret->nbstrings = nbatoms;
+	ret->nbstates = nbstates;
+	xmlFree(stateRemap);
+	xmlFree(stringRemap);
+    }
+not_determ:
+    ctxt->string = NULL;
+    ctxt->nbStates = 0;
+    ctxt->states = NULL;
+    ctxt->nbAtoms = 0;
+    ctxt->atoms = NULL;
+    ctxt->nbCounters = 0;
+    ctxt->counters = NULL;
+    return(ret);
+}
+
+/**
+ * xmlRegNewParserCtxt:
+ * @string:  the string to parse
+ *
+ * Allocate a new regexp parser context
+ *
+ * Returns the new context or NULL in case of error
+ */
+static xmlRegParserCtxtPtr
+xmlRegNewParserCtxt(const xmlChar *string) {
+    xmlRegParserCtxtPtr ret;
+
+    ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt));
+    if (ret == NULL)
+	return(NULL);
+    memset(ret, 0, sizeof(xmlRegParserCtxt));
+    if (string != NULL)
+	ret->string = xmlStrdup(string);
+    ret->cur = ret->string;
+    ret->neg = 0;
+    ret->negs = 0;
+    ret->error = 0;
+    ret->determinist = -1;
+    return(ret);
+}
+
+/**
+ * xmlRegNewRange:
+ * @ctxt:  the regexp parser context
+ * @neg:  is that negative
+ * @type:  the type of range
+ * @start:  the start codepoint
+ * @end:  the end codepoint
+ *
+ * Allocate a new regexp range
+ *
+ * Returns the new range or NULL in case of error
+ */
+static xmlRegRangePtr
+xmlRegNewRange(xmlRegParserCtxtPtr ctxt,
+	       int neg, xmlRegAtomType type, int start, int end) {
+    xmlRegRangePtr ret;
+
+    ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange));
+    if (ret == NULL) {
+	xmlRegexpErrMemory(ctxt, "allocating range");
+	return(NULL);
+    }
+    ret->neg = neg;
+    ret->type = type;
+    ret->start = start;
+    ret->end = end;
+    return(ret);
+}
+
+/**
+ * xmlRegFreeRange:
+ * @range:  the regexp range
+ *
+ * Free a regexp range
+ */
+static void
+xmlRegFreeRange(xmlRegRangePtr range) {
+    if (range == NULL)
+	return;
+
+    if (range->blockName != NULL)
+	xmlFree(range->blockName);
+    xmlFree(range);
+}
+
+/**
+ * xmlRegCopyRange:
+ * @range:  the regexp range
+ *
+ * Copy a regexp range
+ *
+ * Returns the new copy or NULL in case of error.
+ */
+static xmlRegRangePtr
+xmlRegCopyRange(xmlRegParserCtxtPtr ctxt, xmlRegRangePtr range) {
+    xmlRegRangePtr ret;
+
+    if (range == NULL)
+	return(NULL);
+
+    ret = xmlRegNewRange(ctxt, range->neg, range->type, range->start,
+                         range->end);
+    if (ret == NULL)
+        return(NULL);
+    if (range->blockName != NULL) {
+	ret->blockName = xmlStrdup(range->blockName);
+	if (ret->blockName == NULL) {
+	    xmlRegexpErrMemory(ctxt, "allocating range");
+	    xmlRegFreeRange(ret);
+	    return(NULL);
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlRegNewAtom:
+ * @ctxt:  the regexp parser context
+ * @type:  the type of atom
+ *
+ * Allocate a new atom
+ *
+ * Returns the new atom or NULL in case of error
+ */
+static xmlRegAtomPtr
+xmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) {
+    xmlRegAtomPtr ret;
+
+    ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
+    if (ret == NULL) {
+	xmlRegexpErrMemory(ctxt, "allocating atom");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlRegAtom));
+    ret->type = type;
+    ret->quant = XML_REGEXP_QUANT_ONCE;
+    ret->min = 0;
+    ret->max = 0;
+    return(ret);
+}
+
+/**
+ * xmlRegFreeAtom:
+ * @atom:  the regexp atom
+ *
+ * Free a regexp atom
+ */
+static void
+xmlRegFreeAtom(xmlRegAtomPtr atom) {
+    int i;
+
+    if (atom == NULL)
+	return;
+
+    for (i = 0;i < atom->nbRanges;i++)
+	xmlRegFreeRange(atom->ranges[i]);
+    if (atom->ranges != NULL)
+	xmlFree(atom->ranges);
+    if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL))
+	xmlFree(atom->valuep);
+    if ((atom->type == XML_REGEXP_STRING) && (atom->valuep2 != NULL))
+	xmlFree(atom->valuep2);
+    if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL))
+	xmlFree(atom->valuep);
+    xmlFree(atom);
+}
+
+/**
+ * xmlRegCopyAtom:
+ * @ctxt:  the regexp parser context
+ * @atom:  the oiginal atom
+ *
+ * Allocate a new regexp range
+ *
+ * Returns the new atom or NULL in case of error
+ */
+static xmlRegAtomPtr
+xmlRegCopyAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
+    xmlRegAtomPtr ret;
+
+    ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
+    if (ret == NULL) {
+	xmlRegexpErrMemory(ctxt, "copying atom");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlRegAtom));
+    ret->type = atom->type;
+    ret->quant = atom->quant;
+    ret->min = atom->min;
+    ret->max = atom->max;
+    if (atom->nbRanges > 0) {
+        int i;
+
+        ret->ranges = (xmlRegRangePtr *) xmlMalloc(sizeof(xmlRegRangePtr) *
+	                                           atom->nbRanges);
+	if (ret->ranges == NULL) {
+	    xmlRegexpErrMemory(ctxt, "copying atom");
+	    goto error;
+	}
+	for (i = 0;i < atom->nbRanges;i++) {
+	    ret->ranges[i] = xmlRegCopyRange(ctxt, atom->ranges[i]);
+	    if (ret->ranges[i] == NULL)
+	        goto error;
+	    ret->nbRanges = i + 1;
+	}
+    }
+    return(ret);
+
+error:
+    xmlRegFreeAtom(ret);
+    return(NULL);
+}
+
+static xmlRegStatePtr
+xmlRegNewState(xmlRegParserCtxtPtr ctxt) {
+    xmlRegStatePtr ret;
+
+    ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState));
+    if (ret == NULL) {
+	xmlRegexpErrMemory(ctxt, "allocating state");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlRegState));
+    ret->type = XML_REGEXP_TRANS_STATE;
+    ret->mark = XML_REGEXP_MARK_NORMAL;
+    return(ret);
+}
+
+/**
+ * xmlRegFreeState:
+ * @state:  the regexp state
+ *
+ * Free a regexp state
+ */
+static void
+xmlRegFreeState(xmlRegStatePtr state) {
+    if (state == NULL)
+	return;
+
+    if (state->trans != NULL)
+	xmlFree(state->trans);
+    if (state->transTo != NULL)
+	xmlFree(state->transTo);
+    xmlFree(state);
+}
+
+/**
+ * xmlRegFreeParserCtxt:
+ * @ctxt:  the regexp parser context
+ *
+ * Free a regexp parser context
+ */
+static void
+xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
+    int i;
+    if (ctxt == NULL)
+	return;
+
+    if (ctxt->string != NULL)
+	xmlFree(ctxt->string);
+    if (ctxt->states != NULL) {
+	for (i = 0;i < ctxt->nbStates;i++)
+	    xmlRegFreeState(ctxt->states[i]);
+	xmlFree(ctxt->states);
+    }
+    if (ctxt->atoms != NULL) {
+	for (i = 0;i < ctxt->nbAtoms;i++)
+	    xmlRegFreeAtom(ctxt->atoms[i]);
+	xmlFree(ctxt->atoms);
+    }
+    if (ctxt->counters != NULL)
+	xmlFree(ctxt->counters);
+    xmlFree(ctxt);
+}
+
+/************************************************************************
+ * 									*
+ * 			Display of Data structures			*
+ * 									*
+ ************************************************************************/
+
+static void
+xmlRegPrintAtomType(FILE *output, xmlRegAtomType type) {
+    switch (type) {
+        case XML_REGEXP_EPSILON:
+	    fprintf(output, "epsilon "); break;
+        case XML_REGEXP_CHARVAL:
+	    fprintf(output, "charval "); break;
+        case XML_REGEXP_RANGES:
+	    fprintf(output, "ranges "); break;
+        case XML_REGEXP_SUBREG:
+	    fprintf(output, "subexpr "); break;
+        case XML_REGEXP_STRING:
+	    fprintf(output, "string "); break;
+        case XML_REGEXP_ANYCHAR:
+	    fprintf(output, "anychar "); break;
+        case XML_REGEXP_ANYSPACE:
+	    fprintf(output, "anyspace "); break;
+        case XML_REGEXP_NOTSPACE:
+	    fprintf(output, "notspace "); break;
+        case XML_REGEXP_INITNAME:
+	    fprintf(output, "initname "); break;
+        case XML_REGEXP_NOTINITNAME:
+	    fprintf(output, "notinitname "); break;
+        case XML_REGEXP_NAMECHAR:
+	    fprintf(output, "namechar "); break;
+        case XML_REGEXP_NOTNAMECHAR:
+	    fprintf(output, "notnamechar "); break;
+        case XML_REGEXP_DECIMAL:
+	    fprintf(output, "decimal "); break;
+        case XML_REGEXP_NOTDECIMAL:
+	    fprintf(output, "notdecimal "); break;
+        case XML_REGEXP_REALCHAR:
+	    fprintf(output, "realchar "); break;
+        case XML_REGEXP_NOTREALCHAR:
+	    fprintf(output, "notrealchar "); break;
+        case XML_REGEXP_LETTER:
+            fprintf(output, "LETTER "); break;
+        case XML_REGEXP_LETTER_UPPERCASE:
+            fprintf(output, "LETTER_UPPERCASE "); break;
+        case XML_REGEXP_LETTER_LOWERCASE:
+            fprintf(output, "LETTER_LOWERCASE "); break;
+        case XML_REGEXP_LETTER_TITLECASE:
+            fprintf(output, "LETTER_TITLECASE "); break;
+        case XML_REGEXP_LETTER_MODIFIER:
+            fprintf(output, "LETTER_MODIFIER "); break;
+        case XML_REGEXP_LETTER_OTHERS:
+            fprintf(output, "LETTER_OTHERS "); break;
+        case XML_REGEXP_MARK:
+            fprintf(output, "MARK "); break;
+        case XML_REGEXP_MARK_NONSPACING:
+            fprintf(output, "MARK_NONSPACING "); break;
+        case XML_REGEXP_MARK_SPACECOMBINING:
+            fprintf(output, "MARK_SPACECOMBINING "); break;
+        case XML_REGEXP_MARK_ENCLOSING:
+            fprintf(output, "MARK_ENCLOSING "); break;
+        case XML_REGEXP_NUMBER:
+            fprintf(output, "NUMBER "); break;
+        case XML_REGEXP_NUMBER_DECIMAL:
+            fprintf(output, "NUMBER_DECIMAL "); break;
+        case XML_REGEXP_NUMBER_LETTER:
+            fprintf(output, "NUMBER_LETTER "); break;
+        case XML_REGEXP_NUMBER_OTHERS:
+            fprintf(output, "NUMBER_OTHERS "); break;
+        case XML_REGEXP_PUNCT:
+            fprintf(output, "PUNCT "); break;
+        case XML_REGEXP_PUNCT_CONNECTOR:
+            fprintf(output, "PUNCT_CONNECTOR "); break;
+        case XML_REGEXP_PUNCT_DASH:
+            fprintf(output, "PUNCT_DASH "); break;
+        case XML_REGEXP_PUNCT_OPEN:
+            fprintf(output, "PUNCT_OPEN "); break;
+        case XML_REGEXP_PUNCT_CLOSE:
+            fprintf(output, "PUNCT_CLOSE "); break;
+        case XML_REGEXP_PUNCT_INITQUOTE:
+            fprintf(output, "PUNCT_INITQUOTE "); break;
+        case XML_REGEXP_PUNCT_FINQUOTE:
+            fprintf(output, "PUNCT_FINQUOTE "); break;
+        case XML_REGEXP_PUNCT_OTHERS:
+            fprintf(output, "PUNCT_OTHERS "); break;
+        case XML_REGEXP_SEPAR:
+            fprintf(output, "SEPAR "); break;
+        case XML_REGEXP_SEPAR_SPACE:
+            fprintf(output, "SEPAR_SPACE "); break;
+        case XML_REGEXP_SEPAR_LINE:
+            fprintf(output, "SEPAR_LINE "); break;
+        case XML_REGEXP_SEPAR_PARA:
+            fprintf(output, "SEPAR_PARA "); break;
+        case XML_REGEXP_SYMBOL:
+            fprintf(output, "SYMBOL "); break;
+        case XML_REGEXP_SYMBOL_MATH:
+            fprintf(output, "SYMBOL_MATH "); break;
+        case XML_REGEXP_SYMBOL_CURRENCY:
+            fprintf(output, "SYMBOL_CURRENCY "); break;
+        case XML_REGEXP_SYMBOL_MODIFIER:
+            fprintf(output, "SYMBOL_MODIFIER "); break;
+        case XML_REGEXP_SYMBOL_OTHERS:
+            fprintf(output, "SYMBOL_OTHERS "); break;
+        case XML_REGEXP_OTHER:
+            fprintf(output, "OTHER "); break;
+        case XML_REGEXP_OTHER_CONTROL:
+            fprintf(output, "OTHER_CONTROL "); break;
+        case XML_REGEXP_OTHER_FORMAT:
+            fprintf(output, "OTHER_FORMAT "); break;
+        case XML_REGEXP_OTHER_PRIVATE:
+            fprintf(output, "OTHER_PRIVATE "); break;
+        case XML_REGEXP_OTHER_NA:
+            fprintf(output, "OTHER_NA "); break;
+        case XML_REGEXP_BLOCK_NAME:
+	    fprintf(output, "BLOCK "); break;
+    }
+}
+
+static void
+xmlRegPrintQuantType(FILE *output, xmlRegQuantType type) {
+    switch (type) {
+        case XML_REGEXP_QUANT_EPSILON:
+	    fprintf(output, "epsilon "); break;
+        case XML_REGEXP_QUANT_ONCE:
+	    fprintf(output, "once "); break;
+        case XML_REGEXP_QUANT_OPT:
+	    fprintf(output, "? "); break;
+        case XML_REGEXP_QUANT_MULT:
+	    fprintf(output, "* "); break;
+        case XML_REGEXP_QUANT_PLUS:
+	    fprintf(output, "+ "); break;
+	case XML_REGEXP_QUANT_RANGE:
+	    fprintf(output, "range "); break;
+	case XML_REGEXP_QUANT_ONCEONLY:
+	    fprintf(output, "onceonly "); break;
+	case XML_REGEXP_QUANT_ALL:
+	    fprintf(output, "all "); break;
+    }
+}
+static void
+xmlRegPrintRange(FILE *output, xmlRegRangePtr range) {
+    fprintf(output, "  range: ");
+    if (range->neg)
+	fprintf(output, "negative ");
+    xmlRegPrintAtomType(output, range->type);
+    fprintf(output, "%c - %c\n", range->start, range->end);
+}
+
+static void
+xmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) {
+    fprintf(output, " atom: ");
+    if (atom == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    if (atom->neg)
+        fprintf(output, "not ");
+    xmlRegPrintAtomType(output, atom->type);
+    xmlRegPrintQuantType(output, atom->quant);
+    if (atom->quant == XML_REGEXP_QUANT_RANGE)
+	fprintf(output, "%d-%d ", atom->min, atom->max);
+    if (atom->type == XML_REGEXP_STRING)
+	fprintf(output, "'%s' ", (char *) atom->valuep);
+    if (atom->type == XML_REGEXP_CHARVAL)
+	fprintf(output, "char %c\n", atom->codepoint);
+    else if (atom->type == XML_REGEXP_RANGES) {
+	int i;
+	fprintf(output, "%d entries\n", atom->nbRanges);
+	for (i = 0; i < atom->nbRanges;i++)
+	    xmlRegPrintRange(output, atom->ranges[i]);
+    } else if (atom->type == XML_REGEXP_SUBREG) {
+	fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no);
+    } else {
+	fprintf(output, "\n");
+    }
+}
+
+static void
+xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) {
+    fprintf(output, "  trans: ");
+    if (trans == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    if (trans->to < 0) {
+	fprintf(output, "removed\n");
+	return;
+    }
+    if (trans->nd != 0) {
+	if (trans->nd == 2)
+	    fprintf(output, "last not determinist, ");
+	else
+	    fprintf(output, "not determinist, ");
+    }
+    if (trans->counter >= 0) {
+	fprintf(output, "counted %d, ", trans->counter);
+    }
+    if (trans->count == REGEXP_ALL_COUNTER) {
+	fprintf(output, "all transition, ");
+    } else if (trans->count >= 0) {
+	fprintf(output, "count based %d, ", trans->count);
+    }
+    if (trans->atom == NULL) {
+	fprintf(output, "epsilon to %d\n", trans->to);
+	return;
+    }
+    if (trans->atom->type == XML_REGEXP_CHARVAL)
+	fprintf(output, "char %c ", trans->atom->codepoint);
+    fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);
+}
+    
+static void
+xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
+    int i;
+
+    fprintf(output, " state: ");
+    if (state == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    if (state->type == XML_REGEXP_START_STATE)
+	fprintf(output, "START ");
+    if (state->type == XML_REGEXP_FINAL_STATE)
+	fprintf(output, "FINAL ");
+    
+    fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);
+    for (i = 0;i < state->nbTrans; i++) {
+	xmlRegPrintTrans(output, &(state->trans[i]));
+    }
+}
+
+#ifdef DEBUG_REGEXP_GRAPH
+static void
+xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) {
+    int i;
+
+    fprintf(output, " ctxt: ");
+    if (ctxt == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    fprintf(output, "'%s' ", ctxt->string);
+    if (ctxt->error)
+	fprintf(output, "error ");
+    if (ctxt->neg)
+	fprintf(output, "neg ");
+    fprintf(output, "\n");
+    fprintf(output, "%d atoms:\n", ctxt->nbAtoms);
+    for (i = 0;i < ctxt->nbAtoms; i++) {
+	fprintf(output, " %02d ", i);
+	xmlRegPrintAtom(output, ctxt->atoms[i]);
+    }
+    if (ctxt->atom != NULL) {
+	fprintf(output, "current atom:\n");
+	xmlRegPrintAtom(output, ctxt->atom);
+    }
+    fprintf(output, "%d states:", ctxt->nbStates);
+    if (ctxt->start != NULL)
+	fprintf(output, " start: %d", ctxt->start->no);
+    if (ctxt->end != NULL)
+	fprintf(output, " end: %d", ctxt->end->no);
+    fprintf(output, "\n");
+    for (i = 0;i < ctxt->nbStates; i++) {
+	xmlRegPrintState(output, ctxt->states[i]);
+    }
+    fprintf(output, "%d counters:\n", ctxt->nbCounters);
+    for (i = 0;i < ctxt->nbCounters; i++) {
+	fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min,
+		                                ctxt->counters[i].max);
+    }
+}
+#endif
+
+/************************************************************************
+ * 									*
+ *		 Finite Automata structures manipulations		*
+ * 									*
+ ************************************************************************/
+
+static void 
+xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
+	           int neg, xmlRegAtomType type, int start, int end,
+		   xmlChar *blockName) {
+    xmlRegRangePtr range;
+
+    if (atom == NULL) {
+	ERROR("add range: atom is NULL");
+	return;
+    }
+    if (atom->type != XML_REGEXP_RANGES) {
+	ERROR("add range: atom is not ranges");
+	return;
+    }
+    if (atom->maxRanges == 0) {
+	atom->maxRanges = 4;
+	atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges *
+		                             sizeof(xmlRegRangePtr));
+	if (atom->ranges == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding ranges");
+	    atom->maxRanges = 0;
+	    return;
+	}
+    } else if (atom->nbRanges >= atom->maxRanges) {
+	xmlRegRangePtr *tmp;
+	atom->maxRanges *= 2;
+	tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges *
+		                             sizeof(xmlRegRangePtr));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding ranges");
+	    atom->maxRanges /= 2;
+	    return;
+	}
+	atom->ranges = tmp;
+    }
+    range = xmlRegNewRange(ctxt, neg, type, start, end);
+    if (range == NULL)
+	return;
+    range->blockName = blockName;
+    atom->ranges[atom->nbRanges++] = range;
+    
+}
+
+static int
+xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
+    if (ctxt->maxCounters == 0) {
+	ctxt->maxCounters = 4;
+	ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters *
+		                             sizeof(xmlRegCounter));
+	if (ctxt->counters == NULL) {
+	    xmlRegexpErrMemory(ctxt, "allocating counter");
+	    ctxt->maxCounters = 0;
+	    return(-1);
+	}
+    } else if (ctxt->nbCounters >= ctxt->maxCounters) {
+	xmlRegCounter *tmp;
+	ctxt->maxCounters *= 2;
+	tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters *
+		                           sizeof(xmlRegCounter));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "allocating counter");
+	    ctxt->maxCounters /= 2;
+	    return(-1);
+	}
+	ctxt->counters = tmp;
+    }
+    ctxt->counters[ctxt->nbCounters].min = -1;
+    ctxt->counters[ctxt->nbCounters].max = -1;
+    return(ctxt->nbCounters++);
+}
+
+static int 
+xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
+    if (atom == NULL) {
+	ERROR("atom push: atom is NULL");
+	return(-1);
+    }
+    if (ctxt->maxAtoms == 0) {
+	ctxt->maxAtoms = 4;
+	ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms *
+		                             sizeof(xmlRegAtomPtr));
+	if (ctxt->atoms == NULL) {
+	    xmlRegexpErrMemory(ctxt, "pushing atom");
+	    ctxt->maxAtoms = 0;
+	    return(-1);
+	}
+    } else if (ctxt->nbAtoms >= ctxt->maxAtoms) {
+	xmlRegAtomPtr *tmp;
+	ctxt->maxAtoms *= 2;
+	tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms *
+		                             sizeof(xmlRegAtomPtr));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "allocating counter");
+	    ctxt->maxAtoms /= 2;
+	    return(-1);
+	}
+	ctxt->atoms = tmp;
+    }
+    atom->no = ctxt->nbAtoms;
+    ctxt->atoms[ctxt->nbAtoms++] = atom;
+    return(0);
+}
+
+static void 
+xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,
+                      int from) {
+    if (target->maxTransTo == 0) {
+	target->maxTransTo = 8;
+	target->transTo = (int *) xmlMalloc(target->maxTransTo *
+		                             sizeof(int));
+	if (target->transTo == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding transition");
+	    target->maxTransTo = 0;
+	    return;
+	}
+    } else if (target->nbTransTo >= target->maxTransTo) {
+	int *tmp;
+	target->maxTransTo *= 2;
+	tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo *
+		                             sizeof(int));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding transition");
+	    target->maxTransTo /= 2;
+	    return;
+	}
+	target->transTo = tmp;
+    }
+    target->transTo[target->nbTransTo] = from;
+    target->nbTransTo++;
+}
+
+static void 
+xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
+	            xmlRegAtomPtr atom, xmlRegStatePtr target,
+		    int counter, int count) {
+
+    int nrtrans;
+
+    if (state == NULL) {
+	ERROR("add state: state is NULL");
+	return;
+    }
+    if (target == NULL) {
+	ERROR("add state: target is NULL");
+	return;
+    }
+    /*
+     * Other routines follow the philosophy 'When in doubt, add a transition'
+     * so we check here whether such a transition is already present and, if
+     * so, silently ignore this request.
+     */
+
+    for (nrtrans = state->nbTrans - 1; nrtrans >= 0; nrtrans--) {
+	xmlRegTransPtr trans = &(state->trans[nrtrans]);
+	if ((trans->atom == atom) &&
+	    (trans->to == target->no) &&
+	    (trans->counter == counter) &&
+	    (trans->count == count)) {
+#ifdef DEBUG_REGEXP_GRAPH
+	    printf("Ignoring duplicate transition from %d to %d\n",
+		    state->no, target->no);
+#endif
+	    return;
+	}
+    }
+
+    if (state->maxTrans == 0) {
+	state->maxTrans = 8;
+	state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans *
+		                             sizeof(xmlRegTrans));
+	if (state->trans == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding transition");
+	    state->maxTrans = 0;
+	    return;
+	}
+    } else if (state->nbTrans >= state->maxTrans) {
+	xmlRegTrans *tmp;
+	state->maxTrans *= 2;
+	tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans *
+		                             sizeof(xmlRegTrans));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding transition");
+	    state->maxTrans /= 2;
+	    return;
+	}
+	state->trans = tmp;
+    }
+#ifdef DEBUG_REGEXP_GRAPH
+    printf("Add trans from %d to %d ", state->no, target->no);
+    if (count == REGEXP_ALL_COUNTER)
+	printf("all transition\n");
+    else if (count >= 0)
+	printf("count based %d\n", count);
+    else if (counter >= 0)
+	printf("counted %d\n", counter);
+    else if (atom == NULL)
+	printf("epsilon transition\n");
+    else if (atom != NULL) 
+        xmlRegPrintAtom(stdout, atom);
+#endif
+
+    state->trans[state->nbTrans].atom = atom;
+    state->trans[state->nbTrans].to = target->no;
+    state->trans[state->nbTrans].counter = counter;
+    state->trans[state->nbTrans].count = count;
+    state->trans[state->nbTrans].nd = 0;
+    state->nbTrans++;
+    xmlRegStateAddTransTo(ctxt, target, state->no);
+}
+
+static int
+xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
+    if (state == NULL) return(-1);
+    if (ctxt->maxStates == 0) {
+	ctxt->maxStates = 4;
+	ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
+		                             sizeof(xmlRegStatePtr));
+	if (ctxt->states == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding state");
+	    ctxt->maxStates = 0;
+	    return(-1);
+	}
+    } else if (ctxt->nbStates >= ctxt->maxStates) {
+	xmlRegStatePtr *tmp;
+	ctxt->maxStates *= 2;
+	tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
+		                             sizeof(xmlRegStatePtr));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(ctxt, "adding state");
+	    ctxt->maxStates /= 2;
+	    return(-1);
+	}
+	ctxt->states = tmp;
+    }
+    state->no = ctxt->nbStates;
+    ctxt->states[ctxt->nbStates++] = state;
+    return(0);
+}
+
+/**
+ * xmlFAGenerateAllTransition:
+ * @ctxt:  a regexp parser context
+ * @from:  the from state
+ * @to:  the target state or NULL for building a new one
+ * @lax:
+ *
+ */
+static void
+xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
+			   xmlRegStatePtr from, xmlRegStatePtr to,
+			   int lax) {
+    if (to == NULL) {
+	to = xmlRegNewState(ctxt);
+	xmlRegStatePush(ctxt, to);
+	ctxt->state = to;
+    }
+    if (lax)
+	xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER);
+    else
+	xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
+}
+
+/**
+ * xmlFAGenerateEpsilonTransition:
+ * @ctxt:  a regexp parser context
+ * @from:  the from state
+ * @to:  the target state or NULL for building a new one
+ *
+ */
+static void
+xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
+			       xmlRegStatePtr from, xmlRegStatePtr to) {
+    if (to == NULL) {
+	to = xmlRegNewState(ctxt);
+	xmlRegStatePush(ctxt, to);
+	ctxt->state = to;
+    }
+    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
+}
+
+/**
+ * xmlFAGenerateCountedEpsilonTransition:
+ * @ctxt:  a regexp parser context
+ * @from:  the from state
+ * @to:  the target state or NULL for building a new one
+ * counter:  the counter for that transition
+ *
+ */
+static void
+xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
+	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
+    if (to == NULL) {
+	to = xmlRegNewState(ctxt);
+	xmlRegStatePush(ctxt, to);
+	ctxt->state = to;
+    }
+    xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
+}
+
+/**
+ * xmlFAGenerateCountedTransition:
+ * @ctxt:  a regexp parser context
+ * @from:  the from state
+ * @to:  the target state or NULL for building a new one
+ * counter:  the counter for that transition
+ *
+ */
+static void
+xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
+	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
+    if (to == NULL) {
+	to = xmlRegNewState(ctxt);
+	xmlRegStatePush(ctxt, to);
+	ctxt->state = to;
+    }
+    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
+}
+
+/**
+ * xmlFAGenerateTransitions:
+ * @ctxt:  a regexp parser context
+ * @from:  the from state
+ * @to:  the target state or NULL for building a new one
+ * @atom:  the atom generating the transition
+ *
+ * Returns 0 if success and -1 in case of error.
+ */
+static int
+xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
+	                 xmlRegStatePtr to, xmlRegAtomPtr atom) {
+    xmlRegStatePtr end;
+
+    if (atom == NULL) {
+	ERROR("genrate transition: atom == NULL");
+	return(-1);
+    }
+    if (atom->type == XML_REGEXP_SUBREG) {
+	/*
+	 * this is a subexpression handling one should not need to
+	 * create a new node except for XML_REGEXP_QUANT_RANGE.
+	 */
+	if (xmlRegAtomPush(ctxt, atom) < 0) {
+	    return(-1);
+	}
+	if ((to != NULL) && (atom->stop != to) &&
+	    (atom->quant != XML_REGEXP_QUANT_RANGE)) {
+	    /*
+	     * Generate an epsilon transition to link to the target
+	     */
+	    xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
+#ifdef DV
+	} else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) && 
+		   (atom->quant != XML_REGEXP_QUANT_ONCE)) {
+	    to = xmlRegNewState(ctxt);
+	    xmlRegStatePush(ctxt, to);
+	    ctxt->state = to;
+	    xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
+#endif
+	}
+	switch (atom->quant) {
+	    case XML_REGEXP_QUANT_OPT:
+		atom->quant = XML_REGEXP_QUANT_ONCE;
+		/*
+		 * transition done to the state after end of atom.
+		 *      1. set transition from atom start to new state
+		 *      2. set transition from atom end to this 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;
+		xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
+		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
+		break;
+	    case XML_REGEXP_QUANT_PLUS:
+		atom->quant = XML_REGEXP_QUANT_ONCE;
+		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
+		break;
+	    case XML_REGEXP_QUANT_RANGE: {
+		int counter;
+		xmlRegStatePtr inter, newstate;
+
+		/*
+		 * create the final state now if needed
+		 */
+		if (to != NULL) {
+		    newstate = to;
+		} else {
+		    newstate = xmlRegNewState(ctxt);
+		    xmlRegStatePush(ctxt, newstate);
+		}
+
+		/*
+		 * The principle here is to use counted transition
+		 * to avoid explosion in the number of states in the
+		 * graph. This is clearly more complex but should not
+		 * be exploitable at runtime.
+		 */
+		if ((atom->min == 0) && (atom->start0 == NULL)) {
+		    xmlRegAtomPtr copy;
+		    /*
+		     * duplicate a transition based on atom to count next
+		     * occurences after 1. We cannot loop to atom->start
+		     * directly because we need an epsilon transition to 
+		     * newstate.
+		     */
+		     /* ???? For some reason it seems we never reach that
+		        case, I suppose this got optimized out before when
+			building the automata */
+		    copy = xmlRegCopyAtom(ctxt, atom);
+		    if (copy == NULL)
+		        return(-1);
+		    copy->quant = XML_REGEXP_QUANT_ONCE;
+		    copy->min = 0;
+		    copy->max = 0;
+
+		    if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy)
+		        < 0)
+			return(-1);
+		    inter = ctxt->state;
+		    counter = xmlRegGetCounter(ctxt);
+		    ctxt->counters[counter].min = atom->min - 1;
+		    ctxt->counters[counter].max = atom->max - 1;
+		    /* count the number of times we see it again */
+		    xmlFAGenerateCountedEpsilonTransition(ctxt, inter,
+						   atom->stop, counter);
+		    /* allow a way out based on the count */
+		    xmlFAGenerateCountedTransition(ctxt, inter,
+			                           newstate, counter);
+		    /* and also allow a direct exit for 0 */
+		    xmlFAGenerateEpsilonTransition(ctxt, atom->start,
+		                                   newstate);
+		} else {
+		    /*
+		     * either we need the atom at least once or there
+		     * is an atom->start0 allowing to easilly plug the
+		     * epsilon transition.
+		     */
+		    counter = xmlRegGetCounter(ctxt);
+		    ctxt->counters[counter].min = atom->min - 1;
+		    ctxt->counters[counter].max = atom->max - 1;
+		    /* count the number of times we see it again */
+		    xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
+						   atom->start, counter);
+		    /* allow a way out based on the count */
+		    xmlFAGenerateCountedTransition(ctxt, atom->stop,
+			                           newstate, counter);
+		    /* and if needed allow a direct exit for 0 */
+		    if (atom->min == 0)
+			xmlFAGenerateEpsilonTransition(ctxt, atom->start0,
+						       newstate);
+
+		}
+		atom->min = 0;
+		atom->max = 0;
+		atom->quant = XML_REGEXP_QUANT_ONCE;
+		ctxt->state = newstate;
+	    }
+	    default:
+		break;
+	}
+	return(0);
+    } 
+    if ((atom->min == 0) && (atom->max == 0) &&
+               (atom->quant == XML_REGEXP_QUANT_RANGE)) {
+        /*
+	 * we can discard the atom and generate an epsilon transition instead
+	 */
+	if (to == NULL) {
+	    to = xmlRegNewState(ctxt);
+	    if (to != NULL)
+		xmlRegStatePush(ctxt, to);
+	    else {
+		return(-1);
+	    }
+	}
+	xmlFAGenerateEpsilonTransition(ctxt, from, to);
+	ctxt->state = to;
+	xmlRegFreeAtom(atom);
+	return(0);
+    }
+    if (to == NULL) {
+	to = xmlRegNewState(ctxt);
+	if (to != NULL)
+	    xmlRegStatePush(ctxt, to);
+	else {
+	    return(-1);
+	}
+    } 
+    end = to;
+    if ((atom->quant == XML_REGEXP_QUANT_MULT) || 
+        (atom->quant == XML_REGEXP_QUANT_PLUS)) {
+	/*
+	 * Do not pollute the target state by adding transitions from
+	 * it as it is likely to be the shared target of multiple branches.
+	 * So isolate with an epsilon transition.
+	 */
+        xmlRegStatePtr tmp;
+	
+	tmp = xmlRegNewState(ctxt);
+	if (tmp != NULL)
+	    xmlRegStatePush(ctxt, tmp);
+	else {
+	    return(-1);
+	}
+	xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
+	to = tmp;
+    }
+    if (xmlRegAtomPush(ctxt, atom) < 0) {
+	return(-1);
+    }
+    xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1);
+    ctxt->state = end;
+    switch (atom->quant) {
+	case XML_REGEXP_QUANT_OPT:
+	    atom->quant = XML_REGEXP_QUANT_ONCE;
+	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
+	    break;
+	case XML_REGEXP_QUANT_MULT:
+	    atom->quant = XML_REGEXP_QUANT_ONCE;
+	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
+	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
+	    break;
+	case XML_REGEXP_QUANT_PLUS:
+	    atom->quant = XML_REGEXP_QUANT_ONCE;
+	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
+	    break;
+	case XML_REGEXP_QUANT_RANGE: 
+#if DV_test
+	    if (atom->min == 0) {
+		xmlFAGenerateEpsilonTransition(ctxt, from, to);
+	    }
+#endif
+	    break;
+	default:
+	    break;
+    }
+    return(0);
+}
+
+/**
+ * xmlFAReduceEpsilonTransitions:
+ * @ctxt:  a regexp parser context
+ * @fromnr:  the from state
+ * @tonr:  the to state 
+ * @counter:  should that transition be associated to a counted
+ *
+ */
+static void
+xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
+	                      int tonr, int counter) {
+    int transnr;
+    xmlRegStatePtr from;
+    xmlRegStatePtr to;
+
+#ifdef DEBUG_REGEXP_GRAPH
+    printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr);
+#endif
+    from = ctxt->states[fromnr];
+    if (from == NULL)
+	return;
+    to = ctxt->states[tonr];
+    if (to == NULL)
+	return;
+    if ((to->mark == XML_REGEXP_MARK_START) ||
+	(to->mark == XML_REGEXP_MARK_VISITED))
+	return;
+
+    to->mark = XML_REGEXP_MARK_VISITED;
+    if (to->type == XML_REGEXP_FINAL_STATE) {
+#ifdef DEBUG_REGEXP_GRAPH
+	printf("State %d is final, so %d becomes final\n", tonr, fromnr);
+#endif
+	from->type = XML_REGEXP_FINAL_STATE;
+    }
+    for (transnr = 0;transnr < to->nbTrans;transnr++) {
+        if (to->trans[transnr].to < 0)
+	    continue;
+	if (to->trans[transnr].atom == NULL) {
+	    /*
+	     * Don't remove counted transitions
+	     * Don't loop either
+	     */
+	    if (to->trans[transnr].to != fromnr) {
+		if (to->trans[transnr].count >= 0) {
+		    int newto = to->trans[transnr].to;
+
+		    xmlRegStateAddTrans(ctxt, from, NULL,
+					ctxt->states[newto], 
+					-1, to->trans[transnr].count);
+		} else {
+#ifdef DEBUG_REGEXP_GRAPH
+		    printf("Found epsilon trans %d from %d to %d\n",
+			   transnr, tonr, to->trans[transnr].to);
+#endif
+		    if (to->trans[transnr].counter >= 0) {
+			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
+					      to->trans[transnr].to,
+					      to->trans[transnr].counter);
+		    } else {
+			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
+					      to->trans[transnr].to,
+					      counter);
+		    }
+		}
+	    }
+	} else {
+	    int newto = to->trans[transnr].to;
+
+	    if (to->trans[transnr].counter >= 0) {
+		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 
+				    ctxt->states[newto], 
+				    to->trans[transnr].counter, -1);
+	    } else {
+		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 
+				    ctxt->states[newto], counter, -1);
+	    }
+	}
+    }
+    to->mark = XML_REGEXP_MARK_NORMAL;
+}
+
+/**
+ * xmlFAEliminateSimpleEpsilonTransitions:
+ * @ctxt:  a regexp parser context
+ *
+ * Eliminating general epsilon transitions can get costly in the general 
+ * algorithm due to the large amount of generated new transitions and
+ * associated comparisons. However for simple epsilon transition used just
+ * to separate building blocks when generating the automata this can be
+ * reduced to state elimination:
+ *    - if there exists an epsilon from X to Y
+ *    - if there is no other transition from X
+ * then X and Y are semantically equivalent and X can be eliminated
+ * If X is the start state then make Y the start state, else replace the
+ * target of all transitions to X by transitions to Y.
+ */
+static void
+xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
+    int statenr, i, j, newto;
+    xmlRegStatePtr state, tmp;
+
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if (state == NULL)
+	    continue;
+	if (state->nbTrans != 1)
+	    continue;
+	if (state->type == XML_REGEXP_UNREACH_STATE)
+	    continue;
+	/* is the only transition out a basic transition */
+	if ((state->trans[0].atom == NULL) &&
+	    (state->trans[0].to >= 0) &&
+	    (state->trans[0].to != statenr) &&
+	    (state->trans[0].counter < 0) &&
+	    (state->trans[0].count < 0)) {
+	    newto = state->trans[0].to;
+
+            if (state->type == XML_REGEXP_START_STATE) {
+#ifdef DEBUG_REGEXP_GRAPH
+		printf("Found simple epsilon trans from start %d to %d\n",
+		       statenr, newto);
+#endif     
+            } else {
+#ifdef DEBUG_REGEXP_GRAPH
+		printf("Found simple epsilon trans from %d to %d\n",
+		       statenr, newto);
+#endif     
+	        for (i = 0;i < state->nbTransTo;i++) {
+		    tmp = ctxt->states[state->transTo[i]];
+		    for (j = 0;j < tmp->nbTrans;j++) {
+			if (tmp->trans[j].to == statenr) {
+#ifdef DEBUG_REGEXP_GRAPH
+			    printf("Changed transition %d on %d to go to %d\n",
+				   j, tmp->no, newto);
+#endif     
+			    tmp->trans[j].to = -1;
+			    xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom,
+			    			ctxt->states[newto],
+					        tmp->trans[j].counter,
+						tmp->trans[j].count);
+			}
+		    }
+		}
+		if (state->type == XML_REGEXP_FINAL_STATE)
+		    ctxt->states[newto]->type = XML_REGEXP_FINAL_STATE;
+		/* eliminate the transition completely */
+		state->nbTrans = 0;
+
+                state->type = XML_REGEXP_UNREACH_STATE;
+
+	    }
+            
+	}
+    }
+}
+/**
+ * xmlFAEliminateEpsilonTransitions:
+ * @ctxt:  a regexp parser context
+ *
+ */
+static void
+xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
+    int statenr, transnr;
+    xmlRegStatePtr state;
+    int has_epsilon;
+
+    if (ctxt->states == NULL) return;
+
+    /*
+     * Eliminate simple epsilon transition and the associated unreachable
+     * states.
+     */
+    xmlFAEliminateSimpleEpsilonTransitions(ctxt);
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) {
+#ifdef DEBUG_REGEXP_GRAPH
+	    printf("Removed unreachable state %d\n", statenr);
+#endif
+	    xmlRegFreeState(state);
+	    ctxt->states[statenr] = NULL;
+	}
+    }
+
+    has_epsilon = 0;
+
+    /*
+     * Build the completed transitions bypassing the epsilons
+     * Use a marking algorithm to avoid loops
+     * Mark sink states too.
+     * Process from the latests states backward to the start when
+     * there is long cascading epsilon chains this minimize the
+     * recursions and transition compares when adding the new ones
+     */
+    for (statenr = ctxt->nbStates - 1;statenr >= 0;statenr--) {
+	state = ctxt->states[statenr];
+	if (state == NULL)
+	    continue;
+	if ((state->nbTrans == 0) &&
+	    (state->type != XML_REGEXP_FINAL_STATE)) {
+	    state->type = XML_REGEXP_SINK_STATE;
+	}
+	for (transnr = 0;transnr < state->nbTrans;transnr++) {
+	    if ((state->trans[transnr].atom == NULL) &&
+		(state->trans[transnr].to >= 0)) {
+		if (state->trans[transnr].to == statenr) {
+		    state->trans[transnr].to = -1;
+#ifdef DEBUG_REGEXP_GRAPH
+		    printf("Removed loopback epsilon trans %d on %d\n",
+			   transnr, statenr);
+#endif
+		} else if (state->trans[transnr].count < 0) {
+		    int newto = state->trans[transnr].to;
+
+#ifdef DEBUG_REGEXP_GRAPH
+		    printf("Found epsilon trans %d from %d to %d\n",
+			   transnr, statenr, newto);
+#endif
+		    has_epsilon = 1;
+		    state->trans[transnr].to = -2;
+		    state->mark = XML_REGEXP_MARK_START;
+		    xmlFAReduceEpsilonTransitions(ctxt, statenr,
+				      newto, state->trans[transnr].counter);
+		    state->mark = XML_REGEXP_MARK_NORMAL;
+#ifdef DEBUG_REGEXP_GRAPH
+		} else {
+		    printf("Found counted transition %d on %d\n",
+			   transnr, statenr);
+#endif
+	        }
+	    }
+	}
+    }
+    /*
+     * Eliminate the epsilon transitions
+     */
+    if (has_epsilon) {
+	for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	    state = ctxt->states[statenr];
+	    if (state == NULL)
+		continue;
+	    for (transnr = 0;transnr < state->nbTrans;transnr++) {
+		xmlRegTransPtr trans = &(state->trans[transnr]);
+		if ((trans->atom == NULL) &&
+		    (trans->count < 0) &&
+		    (trans->to >= 0)) {
+		    trans->to = -1;
+		}
+	    }
+	}
+    }
+
+    /*
+     * Use this pass to detect unreachable states too
+     */
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if (state != NULL)
+	    state->reached = XML_REGEXP_MARK_NORMAL;
+    }
+    state = ctxt->states[0];
+    if (state != NULL)
+	state->reached = XML_REGEXP_MARK_START;
+    while (state != NULL) {
+	xmlRegStatePtr target = NULL;
+	state->reached = XML_REGEXP_MARK_VISITED;
+	/*
+	 * Mark all states reachable from the current reachable state
+	 */
+	for (transnr = 0;transnr < state->nbTrans;transnr++) {
+	    if ((state->trans[transnr].to >= 0) &&
+		((state->trans[transnr].atom != NULL) ||
+		 (state->trans[transnr].count >= 0))) {
+		int newto = state->trans[transnr].to;
+
+		if (ctxt->states[newto] == NULL)
+		    continue;
+		if (ctxt->states[newto]->reached == XML_REGEXP_MARK_NORMAL) {
+		    ctxt->states[newto]->reached = XML_REGEXP_MARK_START;
+		    target = ctxt->states[newto];
+		}
+	    }
+	}
+
+	/*
+	 * find the next accessible state not explored
+	 */
+	if (target == NULL) {
+	    for (statenr = 1;statenr < ctxt->nbStates;statenr++) {
+		state = ctxt->states[statenr];
+		if ((state != NULL) && (state->reached ==
+			XML_REGEXP_MARK_START)) {
+		    target = state;
+		    break;
+		}
+	    }
+	}
+	state = target;
+    }
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) {
+#ifdef DEBUG_REGEXP_GRAPH
+	    printf("Removed unreachable state %d\n", statenr);
+#endif
+	    xmlRegFreeState(state);
+	    ctxt->states[statenr] = NULL;
+	}
+    }
+
+}
+
+static int
+xmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangePtr range2) {
+    int ret = 0;
+
+    if ((range1->type == XML_REGEXP_RANGES) ||
+        (range2->type == XML_REGEXP_RANGES) ||
+        (range2->type == XML_REGEXP_SUBREG) ||
+        (range1->type == XML_REGEXP_SUBREG) ||
+        (range1->type == XML_REGEXP_STRING) ||
+        (range2->type == XML_REGEXP_STRING))
+	return(-1);
+
+    /* put them in order */
+    if (range1->type > range2->type) {
+        xmlRegRangePtr tmp;
+
+	tmp = range1;
+	range1 = range2;
+	range2 = tmp;
+    }
+    if ((range1->type == XML_REGEXP_ANYCHAR) ||
+        (range2->type == XML_REGEXP_ANYCHAR)) {
+	ret = 1;
+    } else if ((range1->type == XML_REGEXP_EPSILON) ||
+               (range2->type == XML_REGEXP_EPSILON)) {
+	return(0);
+    } else if (range1->type == range2->type) {
+        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;
+
+	/*
+	 * just check all codepoints in the range for acceptance,
+	 * this is usually way cheaper since done only once at
+	 * compilation than testing over and over at runtime or 
+	 * pushing too many states when evaluating.
+	 */
+	if (((range1->neg == 0) && (range2->neg != 0)) ||
+	    ((range1->neg != 0) && (range2->neg == 0)))
+	    neg = 1;
+
+	for (codepoint = range1->start;codepoint <= range1->end ;codepoint++) {
+	    ret = xmlRegCheckCharacterRange(range2->type, codepoint,
+					    0, range2->start, range2->end,
+					    range2->blockName);
+	    if (ret < 0)
+	        return(-1);
+	    if (((neg == 1) && (ret == 0)) ||
+	        ((neg == 0) && (ret == 1)))
+		return(1);
+	}
+	return(0);
+    } else if ((range1->type == XML_REGEXP_BLOCK_NAME) ||
+               (range2->type == XML_REGEXP_BLOCK_NAME)) {
+	if (range1->type == range2->type) {
+	    ret = xmlStrEqual(range1->blockName, range2->blockName);
+	} else {
+	    /*
+	     * comparing a block range with anything else is way
+	     * too costly, and maintining the table is like too much
+	     * memory too, so let's force the automata to save state
+	     * here.
+	     */
+	    return(1);
+	}
+    } else if ((range1->type < XML_REGEXP_LETTER) ||
+               (range2->type < XML_REGEXP_LETTER)) {
+	if ((range1->type == XML_REGEXP_ANYSPACE) &&
+	    (range2->type == XML_REGEXP_NOTSPACE))
+	    ret = 0;
+	else if ((range1->type == XML_REGEXP_INITNAME) &&
+	         (range2->type == XML_REGEXP_NOTINITNAME))
+	    ret = 0;
+	else if ((range1->type == XML_REGEXP_NAMECHAR) &&
+	         (range2->type == XML_REGEXP_NOTNAMECHAR))
+	    ret = 0;
+	else if ((range1->type == XML_REGEXP_DECIMAL) &&
+	         (range2->type == XML_REGEXP_NOTDECIMAL))
+	    ret = 0;
+	else if ((range1->type == XML_REGEXP_REALCHAR) &&
+	         (range2->type == XML_REGEXP_NOTREALCHAR))
+	    ret = 0;
+	else {
+	    /* same thing to limit complexity */
+	    return(1);
+	}
+    } else {
+        ret = 0;
+        /* range1->type < range2->type here */
+        switch (range1->type) {
+	    case XML_REGEXP_LETTER:
+	         /* all disjoint except in the subgroups */
+	         if ((range2->type == XML_REGEXP_LETTER_UPPERCASE) ||
+		     (range2->type == XML_REGEXP_LETTER_LOWERCASE) ||
+		     (range2->type == XML_REGEXP_LETTER_TITLECASE) ||
+		     (range2->type == XML_REGEXP_LETTER_MODIFIER) ||
+		     (range2->type == XML_REGEXP_LETTER_OTHERS))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_MARK:
+	         if ((range2->type == XML_REGEXP_MARK_NONSPACING) ||
+		     (range2->type == XML_REGEXP_MARK_SPACECOMBINING) ||
+		     (range2->type == XML_REGEXP_MARK_ENCLOSING))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_NUMBER:
+	         if ((range2->type == XML_REGEXP_NUMBER_DECIMAL) ||
+		     (range2->type == XML_REGEXP_NUMBER_LETTER) ||
+		     (range2->type == XML_REGEXP_NUMBER_OTHERS))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_PUNCT:
+	         if ((range2->type == XML_REGEXP_PUNCT_CONNECTOR) ||
+		     (range2->type == XML_REGEXP_PUNCT_DASH) ||
+		     (range2->type == XML_REGEXP_PUNCT_OPEN) ||
+		     (range2->type == XML_REGEXP_PUNCT_CLOSE) ||
+		     (range2->type == XML_REGEXP_PUNCT_INITQUOTE) ||
+		     (range2->type == XML_REGEXP_PUNCT_FINQUOTE) ||
+		     (range2->type == XML_REGEXP_PUNCT_OTHERS))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_SEPAR:
+	         if ((range2->type == XML_REGEXP_SEPAR_SPACE) ||
+		     (range2->type == XML_REGEXP_SEPAR_LINE) ||
+		     (range2->type == XML_REGEXP_SEPAR_PARA))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_SYMBOL:
+	         if ((range2->type == XML_REGEXP_SYMBOL_MATH) ||
+		     (range2->type == XML_REGEXP_SYMBOL_CURRENCY) ||
+		     (range2->type == XML_REGEXP_SYMBOL_MODIFIER) ||
+		     (range2->type == XML_REGEXP_SYMBOL_OTHERS))
+		     ret = 1;
+		 break;
+	    case XML_REGEXP_OTHER:
+	         if ((range2->type == XML_REGEXP_OTHER_CONTROL) ||
+		     (range2->type == XML_REGEXP_OTHER_FORMAT) ||
+		     (range2->type == XML_REGEXP_OTHER_PRIVATE))
+		     ret = 1;
+		 break;
+            default:
+	         if ((range2->type >= XML_REGEXP_LETTER) &&
+		     (range2->type < XML_REGEXP_BLOCK_NAME))
+		     ret = 0;
+		 else {
+		     /* safety net ! */
+		     return(1);
+		 }
+	}
+    }
+    if (((range1->neg == 0) && (range2->neg != 0)) ||
+        ((range1->neg != 0) && (range2->neg == 0)))
+	ret = !ret;
+    return(ret);
+}
+
+/**
+ * xmlFACompareAtomTypes:
+ * @type1:  an atom type
+ * @type2:  an atom type
+ *
+ * Compares two atoms type to check whether they intersect in some ways,
+ * this is used by xmlFACompareAtoms only
+ *
+ * Returns 1 if they may intersect and 0 otherwise
+ */
+static int
+xmlFACompareAtomTypes(xmlRegAtomType type1, xmlRegAtomType type2) {
+    if ((type1 == XML_REGEXP_EPSILON) ||
+        (type1 == XML_REGEXP_CHARVAL) ||
+	(type1 == XML_REGEXP_RANGES) ||
+	(type1 == XML_REGEXP_SUBREG) ||
+	(type1 == XML_REGEXP_STRING) ||
+	(type1 == XML_REGEXP_ANYCHAR))
+	return(1);
+    if ((type2 == XML_REGEXP_EPSILON) ||
+        (type2 == XML_REGEXP_CHARVAL) ||
+	(type2 == XML_REGEXP_RANGES) ||
+	(type2 == XML_REGEXP_SUBREG) ||
+	(type2 == XML_REGEXP_STRING) ||
+	(type2 == XML_REGEXP_ANYCHAR))
+	return(1);
+
+    if (type1 == type2) return(1);
+
+    /* simplify subsequent compares by making sure type1 < type2 */
+    if (type1 > type2) {
+        xmlRegAtomType tmp = type1;
+	type1 = type2;
+	type2 = tmp;
+    }
+    switch (type1) {
+        case XML_REGEXP_ANYSPACE: /* \s */
+	    /* can't be a letter, number, mark, pontuation, symbol */
+	    if ((type2 == XML_REGEXP_NOTSPACE) ||
+		((type2 >= XML_REGEXP_LETTER) &&
+		 (type2 <= XML_REGEXP_LETTER_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_NUMBER) &&
+		 (type2 <= XML_REGEXP_NUMBER_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_MARK) &&
+		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
+	        ((type2 >= XML_REGEXP_PUNCT) &&
+		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_SYMBOL) &&
+		 (type2 <= XML_REGEXP_SYMBOL_OTHERS))
+	        ) return(0);
+	    break;
+        case XML_REGEXP_NOTSPACE: /* \S */
+	    break;
+        case XML_REGEXP_INITNAME: /* \l */
+	    /* can't be a number, mark, separator, pontuation, symbol or other */
+	    if ((type2 == XML_REGEXP_NOTINITNAME) ||
+	        ((type2 >= XML_REGEXP_NUMBER) &&
+		 (type2 <= XML_REGEXP_NUMBER_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_MARK) &&
+		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
+	        ((type2 >= XML_REGEXP_SEPAR) &&
+		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
+	        ((type2 >= XML_REGEXP_PUNCT) &&
+		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_SYMBOL) &&
+		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_OTHER) &&
+		 (type2 <= XML_REGEXP_OTHER_NA))
+		) return(0);
+	    break;
+        case XML_REGEXP_NOTINITNAME: /* \L */
+	    break;
+        case XML_REGEXP_NAMECHAR: /* \c */
+	    /* can't be a mark, separator, pontuation, symbol or other */
+	    if ((type2 == XML_REGEXP_NOTNAMECHAR) ||
+	        ((type2 >= XML_REGEXP_MARK) &&
+		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
+	        ((type2 >= XML_REGEXP_PUNCT) &&
+		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_SEPAR) &&
+		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
+	        ((type2 >= XML_REGEXP_SYMBOL) &&
+		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_OTHER) &&
+		 (type2 <= XML_REGEXP_OTHER_NA))
+		) return(0);
+	    break;
+        case XML_REGEXP_NOTNAMECHAR: /* \C */
+	    break;
+        case XML_REGEXP_DECIMAL: /* \d */
+	    /* can't be a letter, mark, separator, pontuation, symbol or other */
+	    if ((type2 == XML_REGEXP_NOTDECIMAL) ||
+	        (type2 == XML_REGEXP_REALCHAR) ||
+		((type2 >= XML_REGEXP_LETTER) &&
+		 (type2 <= XML_REGEXP_LETTER_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_MARK) &&
+		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
+	        ((type2 >= XML_REGEXP_PUNCT) &&
+		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_SEPAR) &&
+		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
+	        ((type2 >= XML_REGEXP_SYMBOL) &&
+		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_OTHER) &&
+		 (type2 <= XML_REGEXP_OTHER_NA))
+		)return(0);
+	    break;
+        case XML_REGEXP_NOTDECIMAL: /* \D */
+	    break;
+        case XML_REGEXP_REALCHAR: /* \w */
+	    /* can't be a mark, separator, pontuation, symbol or other */
+	    if ((type2 == XML_REGEXP_NOTDECIMAL) ||
+	        ((type2 >= XML_REGEXP_MARK) &&
+		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
+	        ((type2 >= XML_REGEXP_PUNCT) &&
+		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_SEPAR) &&
+		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
+	        ((type2 >= XML_REGEXP_SYMBOL) &&
+		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
+	        ((type2 >= XML_REGEXP_OTHER) &&
+		 (type2 <= XML_REGEXP_OTHER_NA))
+		)return(0);
+	    break;
+        case XML_REGEXP_NOTREALCHAR: /* \W */
+	    break;
+	/*
+	 * at that point we know both type 1 and type2 are from
+	 * character categories are ordered and are different,
+	 * it becomes simple because this is a partition
+	 */
+        case XML_REGEXP_LETTER:
+	    if (type2 <= XML_REGEXP_LETTER_OTHERS)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_LETTER_UPPERCASE:
+        case XML_REGEXP_LETTER_LOWERCASE:
+        case XML_REGEXP_LETTER_TITLECASE:
+        case XML_REGEXP_LETTER_MODIFIER:
+        case XML_REGEXP_LETTER_OTHERS:
+	    return(0);
+        case XML_REGEXP_MARK:
+	    if (type2 <= XML_REGEXP_MARK_ENCLOSING)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_MARK_NONSPACING:
+        case XML_REGEXP_MARK_SPACECOMBINING:
+        case XML_REGEXP_MARK_ENCLOSING:
+	    return(0);
+        case XML_REGEXP_NUMBER:
+	    if (type2 <= XML_REGEXP_NUMBER_OTHERS)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_NUMBER_DECIMAL:
+        case XML_REGEXP_NUMBER_LETTER:
+        case XML_REGEXP_NUMBER_OTHERS:
+	    return(0);
+        case XML_REGEXP_PUNCT:
+	    if (type2 <= XML_REGEXP_PUNCT_OTHERS)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_PUNCT_CONNECTOR:
+        case XML_REGEXP_PUNCT_DASH:
+        case XML_REGEXP_PUNCT_OPEN:
+        case XML_REGEXP_PUNCT_CLOSE:
+        case XML_REGEXP_PUNCT_INITQUOTE:
+        case XML_REGEXP_PUNCT_FINQUOTE:
+        case XML_REGEXP_PUNCT_OTHERS:
+	    return(0);
+        case XML_REGEXP_SEPAR:
+	    if (type2 <= XML_REGEXP_SEPAR_PARA)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_SEPAR_SPACE:
+        case XML_REGEXP_SEPAR_LINE:
+        case XML_REGEXP_SEPAR_PARA:
+	    return(0);
+        case XML_REGEXP_SYMBOL:
+	    if (type2 <= XML_REGEXP_SYMBOL_OTHERS)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_SYMBOL_MATH:
+        case XML_REGEXP_SYMBOL_CURRENCY:
+        case XML_REGEXP_SYMBOL_MODIFIER:
+        case XML_REGEXP_SYMBOL_OTHERS:
+	    return(0);
+        case XML_REGEXP_OTHER:
+	    if (type2 <= XML_REGEXP_OTHER_NA)
+	        return(1);
+	    return(0);
+        case XML_REGEXP_OTHER_CONTROL:
+        case XML_REGEXP_OTHER_FORMAT:
+        case XML_REGEXP_OTHER_PRIVATE:
+        case XML_REGEXP_OTHER_NA:
+	    return(0);
+	default:
+	    break;
+    }
+    return(1);
+}
+
+/**
+ * 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
+ *
+ * Returns 1 if same and 0 otherwise
+ */
+static int
+xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
+    int ret = 0;
+
+    if (atom1 == atom2)
+	return(1);
+    if ((atom1 == NULL) || (atom2 == NULL))
+	return(0);
+
+    if (atom1->type != atom2->type)
+        return(0);
+    switch (atom1->type) {
+        case XML_REGEXP_EPSILON:
+	    ret = 0;
+	    break;
+        case XML_REGEXP_STRING:
+            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);
+	    break;
+	case XML_REGEXP_RANGES:
+	    /* too hard to do in the general case */
+	    ret = 0;
+	default:
+	    break;
+    }
+    return(ret);
+}
+
+/**
+ * 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
+ *
+ * Returns 1 if yes and 0 otherwise
+ */
+static int
+xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
+    int ret = 1;
+
+    if (atom1 == atom2)
+	return(1);
+    if ((atom1 == NULL) || (atom2 == NULL))
+	return(0);
+
+    if ((atom1->type == XML_REGEXP_ANYCHAR) ||
+        (atom2->type == XML_REGEXP_ANYCHAR))
+	return(1);
+
+    if (atom1->type > atom2->type) {
+	xmlRegAtomPtr tmp;
+	tmp = atom1;
+	atom1 = atom2;
+	atom2 = tmp;
+    }
+    if (atom1->type != atom2->type) {
+        ret = xmlFACompareAtomTypes(atom1->type, atom2->type);
+	/* if they can't intersect at the type level break now */
+	if (ret == 0)
+	    return(0);
+    }
+    switch (atom1->type) {
+        case XML_REGEXP_STRING:
+            if (!deep)
+                ret = (atom1->valuep != atom2->valuep);
+            else
+                ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
+                                             (xmlChar *)atom2->valuep);
+	    break;
+        case XML_REGEXP_EPSILON:
+	    goto not_determinist;
+        case XML_REGEXP_CHARVAL:
+	    if (atom2->type == XML_REGEXP_CHARVAL) {
+		ret = (atom1->codepoint == atom2->codepoint);
+	    } else {
+	        ret = xmlRegCheckCharacter(atom2, atom1->codepoint);
+		if (ret < 0)
+		    ret = 1;
+	    }
+	    break;
+        case XML_REGEXP_RANGES:
+	    if (atom2->type == XML_REGEXP_RANGES) {
+	        int i, j, res;
+		xmlRegRangePtr r1, r2;
+
+		/*
+		 * need to check that none of the ranges eventually matches
+		 */
+		for (i = 0;i < atom1->nbRanges;i++) {
+		    for (j = 0;j < atom2->nbRanges;j++) {
+			r1 = atom1->ranges[i];
+			r2 = atom2->ranges[j];
+			res = xmlFACompareRanges(r1, r2);
+			if (res == 1) {
+			    ret = 1;
+			    goto done;
+			}
+		    }
+		}
+		ret = 0;
+	    }
+	    break;
+	default:
+	    goto not_determinist;
+    }
+done:
+    if (atom1->neg != atom2->neg) {
+        ret = !ret;
+    }
+    if (ret == 0)
+        return(0);
+not_determinist:
+    return(1);
+}
+
+/**
+ * xmlFARecurseDeterminism:
+ * @ctxt:  a regexp parser context
+ *
+ * Check whether the associated regexp is determinist,
+ * should be called after xmlFAEliminateEpsilonTransitions()
+ *
+ */
+static int
+xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
+	                 int to, xmlRegAtomPtr atom) {
+    int ret = 1;
+    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.
+     */
+    nbTrans = state->nbTrans;
+    for (transnr = 0;transnr < nbTrans;transnr++) {
+	t1 = &(state->trans[transnr]);
+	/*
+	 * check transitions conflicting with the one looked at
+	 */
+	if (t1->atom == NULL) {
+	    if (t1->to < 0)
+		continue;
+	    res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
+		                           to, atom);
+	    if (res == 0) {
+	        ret = 0;
+		/* t1->nd = 1; */
+	    }
+	    continue;
+	}
+	if (t1->to != to)
+	    continue;
+	if (xmlFACompareAtoms(t1->atom, atom, deep)) {
+	    ret = 0;
+	    /* mark the transition as non-deterministic */
+	    t1->nd = 1;
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlFAComputesDeterminism:
+ * @ctxt:  a regexp parser context
+ *
+ * Check whether the associated regexp is determinist,
+ * should be called after xmlFAEliminateEpsilonTransitions()
+ *
+ */
+static int
+xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
+    int statenr, transnr;
+    xmlRegStatePtr state;
+    xmlRegTransPtr t1, t2, last;
+    int i;
+    int ret = 1;
+    int deep = 1;
+
+#ifdef DEBUG_REGEXP_GRAPH
+    printf("xmlFAComputesDeterminism\n");
+    xmlRegPrintCtxt(stdout, ctxt);
+#endif
+    if (ctxt->determinist != -1)
+	return(ctxt->determinist);
+
+    if (ctxt->flags & AM_AUTOMATA_RNG)
+        deep = 0;
+
+    /*
+     * First cleanup the automata removing cancelled transitions
+     */
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if (state == NULL)
+	    continue;
+	if (state->nbTrans < 2)
+	    continue;
+	for (transnr = 0;transnr < state->nbTrans;transnr++) {
+	    t1 = &(state->trans[transnr]);
+	    /*
+	     * Determinism checks in case of counted or all transitions
+	     * will have to be handled separately
+	     */
+	    if (t1->atom == NULL) {
+		/* t1->nd = 1; */
+		continue;
+	    }
+	    if (t1->to == -1) /* eliminated */
+		continue;
+	    for (i = 0;i < transnr;i++) {
+		t2 = &(state->trans[i]);
+		if (t2->to == -1) /* eliminated */
+		    continue;
+		if (t2->atom != NULL) {
+		    if (t1->to == t2->to) {
+                        /*
+                         * 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 */
+		    }
+		}
+	    }
+	}
+    }
+
+    /*
+     * Check for all states that there aren't 2 transitions
+     * with the same atom and a different target.
+     */
+    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
+	state = ctxt->states[statenr];
+	if (state == NULL)
+	    continue;
+	if (state->nbTrans < 2)
+	    continue;
+	last = NULL;
+	for (transnr = 0;transnr < state->nbTrans;transnr++) {
+	    t1 = &(state->trans[transnr]);
+	    /*
+	     * Determinism checks in case of counted or all transitions
+	     * will have to be handled separately
+	     */
+	    if (t1->atom == NULL) {
+		continue;
+	    }
+	    if (t1->to == -1) /* eliminated */
+		continue;
+	    for (i = 0;i < transnr;i++) {
+		t2 = &(state->trans[i]);
+		if (t2->to == -1) /* eliminated */
+		    continue;
+		if (t2->atom != NULL) {
+                    /*
+                     * 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;
+			t2->nd = 1;
+			last = t1;
+		    }
+		} else if (t1->to != -1) {
+		    /*
+		     * do the closure in case of remaining specific
+		     * epsilon transitions like choices or all
+		     */
+		    ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
+						   t2->to, t2->atom);
+		    /* don't shortcut the computation so all non deterministic
+		       transition get marked down
+		    if (ret == 0)
+			return(0);
+		     */
+		    if (ret == 0) {
+			t1->nd = 1;
+			/* t2->nd = 1; */
+			last = t1;
+		    }
+		}
+	    }
+	    /* don't shortcut the computation so all non deterministic
+	       transition get marked down
+	    if (ret == 0)
+		break; */
+	}
+
+	/*
+	 * mark specifically the last non-deterministic transition
+	 * from a state since there is no need to set-up rollback
+	 * from it
+	 */
+	if (last != NULL) {
+	    last->nd = 2;
+	}
+
+	/* don't shortcut the computation so all non deterministic
+	   transition get marked down
+	if (ret == 0)
+	    break; */
+    }
+
+    ctxt->determinist = ret;
+    return(ret);
+}
+
+/************************************************************************
+ * 									*
+ *	Routines to check input against transition atoms		*
+ * 									*
+ ************************************************************************/
+
+static int
+xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
+	                  int start, int end, const xmlChar *blockName) {
+    int ret = 0;
+
+    switch (type) {
+        case XML_REGEXP_STRING:
+        case XML_REGEXP_SUBREG:
+        case XML_REGEXP_RANGES:
+        case XML_REGEXP_EPSILON:
+	    return(-1);
+        case XML_REGEXP_ANYCHAR:
+	    ret = ((codepoint != '\n') && (codepoint != '\r'));
+	    break;
+        case XML_REGEXP_CHARVAL:
+	    ret = ((codepoint >= start) && (codepoint <= end));
+	    break;
+        case XML_REGEXP_NOTSPACE:
+	    neg = !neg;
+        case XML_REGEXP_ANYSPACE:
+	    ret = ((codepoint == '\n') || (codepoint == '\r') ||
+		   (codepoint == '\t') || (codepoint == ' '));
+	    break;
+        case XML_REGEXP_NOTINITNAME:
+	    neg = !neg;
+        case XML_REGEXP_INITNAME:
+	    ret = (IS_LETTER(codepoint) || 
+		   (codepoint == '_') || (codepoint == ':'));
+	    break;
+        case XML_REGEXP_NOTNAMECHAR:
+	    neg = !neg;
+        case XML_REGEXP_NAMECHAR:
+	    ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) ||
+		   (codepoint == '.') || (codepoint == '-') ||
+		   (codepoint == '_') || (codepoint == ':') ||
+		   IS_COMBINING(codepoint) || IS_EXTENDER(codepoint));
+	    break;
+        case XML_REGEXP_NOTDECIMAL:
+	    neg = !neg;
+        case XML_REGEXP_DECIMAL:
+	    ret = xmlUCSIsCatNd(codepoint);
+	    break;
+        case XML_REGEXP_REALCHAR:
+	    neg = !neg;
+        case XML_REGEXP_NOTREALCHAR:
+	    ret = xmlUCSIsCatP(codepoint);
+	    if (ret == 0)
+		ret = xmlUCSIsCatZ(codepoint);
+	    if (ret == 0)
+		ret = xmlUCSIsCatC(codepoint);
+	    break;
+        case XML_REGEXP_LETTER:
+	    ret = xmlUCSIsCatL(codepoint);
+	    break;
+        case XML_REGEXP_LETTER_UPPERCASE:
+	    ret = xmlUCSIsCatLu(codepoint);
+	    break;
+        case XML_REGEXP_LETTER_LOWERCASE:
+	    ret = xmlUCSIsCatLl(codepoint);
+	    break;
+        case XML_REGEXP_LETTER_TITLECASE:
+	    ret = xmlUCSIsCatLt(codepoint);
+	    break;
+        case XML_REGEXP_LETTER_MODIFIER:
+	    ret = xmlUCSIsCatLm(codepoint);
+	    break;
+        case XML_REGEXP_LETTER_OTHERS:
+	    ret = xmlUCSIsCatLo(codepoint);
+	    break;
+        case XML_REGEXP_MARK:
+	    ret = xmlUCSIsCatM(codepoint);
+	    break;
+        case XML_REGEXP_MARK_NONSPACING:
+	    ret = xmlUCSIsCatMn(codepoint);
+	    break;
+        case XML_REGEXP_MARK_SPACECOMBINING:
+	    ret = xmlUCSIsCatMc(codepoint);
+	    break;
+        case XML_REGEXP_MARK_ENCLOSING:
+	    ret = xmlUCSIsCatMe(codepoint);
+	    break;
+        case XML_REGEXP_NUMBER:
+	    ret = xmlUCSIsCatN(codepoint);
+	    break;
+        case XML_REGEXP_NUMBER_DECIMAL:
+	    ret = xmlUCSIsCatNd(codepoint);
+	    break;
+        case XML_REGEXP_NUMBER_LETTER:
+	    ret = xmlUCSIsCatNl(codepoint);
+	    break;
+        case XML_REGEXP_NUMBER_OTHERS:
+	    ret = xmlUCSIsCatNo(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT:
+	    ret = xmlUCSIsCatP(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_CONNECTOR:
+	    ret = xmlUCSIsCatPc(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_DASH:
+	    ret = xmlUCSIsCatPd(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_OPEN:
+	    ret = xmlUCSIsCatPs(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_CLOSE:
+	    ret = xmlUCSIsCatPe(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_INITQUOTE:
+	    ret = xmlUCSIsCatPi(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_FINQUOTE:
+	    ret = xmlUCSIsCatPf(codepoint);
+	    break;
+        case XML_REGEXP_PUNCT_OTHERS:
+	    ret = xmlUCSIsCatPo(codepoint);
+	    break;
+        case XML_REGEXP_SEPAR:
+	    ret = xmlUCSIsCatZ(codepoint);
+	    break;
+        case XML_REGEXP_SEPAR_SPACE:
+	    ret = xmlUCSIsCatZs(codepoint);
+	    break;
+        case XML_REGEXP_SEPAR_LINE:
+	    ret = xmlUCSIsCatZl(codepoint);
+	    break;
+        case XML_REGEXP_SEPAR_PARA:
+	    ret = xmlUCSIsCatZp(codepoint);
+	    break;
+        case XML_REGEXP_SYMBOL:
+	    ret = xmlUCSIsCatS(codepoint);
+	    break;
+        case XML_REGEXP_SYMBOL_MATH:
+	    ret = xmlUCSIsCatSm(codepoint);
+	    break;
+        case XML_REGEXP_SYMBOL_CURRENCY:
+	    ret = xmlUCSIsCatSc(codepoint);
+	    break;
+        case XML_REGEXP_SYMBOL_MODIFIER:
+	    ret = xmlUCSIsCatSk(codepoint);
+	    break;
+        case XML_REGEXP_SYMBOL_OTHERS:
+	    ret = xmlUCSIsCatSo(codepoint);
+	    break;
+        case XML_REGEXP_OTHER:
+	    ret = xmlUCSIsCatC(codepoint);
+	    break;
+        case XML_REGEXP_OTHER_CONTROL:
+	    ret = xmlUCSIsCatCc(codepoint);
+	    break;
+        case XML_REGEXP_OTHER_FORMAT:
+	    ret = xmlUCSIsCatCf(codepoint);
+	    break;
+        case XML_REGEXP_OTHER_PRIVATE:
+	    ret = xmlUCSIsCatCo(codepoint);
+	    break;
+        case XML_REGEXP_OTHER_NA:
+	    /* ret = xmlUCSIsCatCn(codepoint); */
+	    /* Seems it doesn't exist anymore in recent Unicode releases */
+	    ret = 0;
+	    break;
+        case XML_REGEXP_BLOCK_NAME:
+	    ret = xmlUCSIsBlock(codepoint, (const char *) blockName);
+	    break;
+    }
+    if (neg)
+	return(!ret);
+    return(ret);
+}
+
+static int
+xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) {
+    int i, ret = 0;
+    xmlRegRangePtr range;
+
+    if ((atom == NULL) || (!IS_CHAR(codepoint)))
+	return(-1);
+
+    switch (atom->type) {
+        case XML_REGEXP_SUBREG:
+        case XML_REGEXP_EPSILON:
+	    return(-1);
+        case XML_REGEXP_CHARVAL:
+            return(codepoint == atom->codepoint);
+        case XML_REGEXP_RANGES: {
+	    int accept = 0;
+
+	    for (i = 0;i < atom->nbRanges;i++) {
+		range = atom->ranges[i];
+		if (range->neg == 2) {
+		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
+						0, range->start, range->end,
+						range->blockName);
+		    if (ret != 0)
+			return(0); /* excluded char */
+		} else if (range->neg) {
+		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
+						0, range->start, range->end,
+						range->blockName);
+		    if (ret == 0)
+		        accept = 1;
+		    else
+		        return(0);
+		} else {
+		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
+						0, range->start, range->end,
+						range->blockName);
+		    if (ret != 0)
+			accept = 1; /* might still be excluded */
+		}
+	    }
+	    return(accept);
+	}
+        case XML_REGEXP_STRING:
+	    printf("TODO: XML_REGEXP_STRING\n");
+	    return(-1);
+        case XML_REGEXP_ANYCHAR:
+        case XML_REGEXP_ANYSPACE:
+        case XML_REGEXP_NOTSPACE:
+        case XML_REGEXP_INITNAME:
+        case XML_REGEXP_NOTINITNAME:
+        case XML_REGEXP_NAMECHAR:
+        case XML_REGEXP_NOTNAMECHAR:
+        case XML_REGEXP_DECIMAL:
+        case XML_REGEXP_NOTDECIMAL:
+        case XML_REGEXP_REALCHAR:
+        case XML_REGEXP_NOTREALCHAR:
+        case XML_REGEXP_LETTER:
+        case XML_REGEXP_LETTER_UPPERCASE:
+        case XML_REGEXP_LETTER_LOWERCASE:
+        case XML_REGEXP_LETTER_TITLECASE:
+        case XML_REGEXP_LETTER_MODIFIER:
+        case XML_REGEXP_LETTER_OTHERS:
+        case XML_REGEXP_MARK:
+        case XML_REGEXP_MARK_NONSPACING:
+        case XML_REGEXP_MARK_SPACECOMBINING:
+        case XML_REGEXP_MARK_ENCLOSING:
+        case XML_REGEXP_NUMBER:
+        case XML_REGEXP_NUMBER_DECIMAL:
+        case XML_REGEXP_NUMBER_LETTER:
+        case XML_REGEXP_NUMBER_OTHERS:
+        case XML_REGEXP_PUNCT:
+        case XML_REGEXP_PUNCT_CONNECTOR:
+        case XML_REGEXP_PUNCT_DASH:
+        case XML_REGEXP_PUNCT_OPEN:
+        case XML_REGEXP_PUNCT_CLOSE:
+        case XML_REGEXP_PUNCT_INITQUOTE:
+        case XML_REGEXP_PUNCT_FINQUOTE:
+        case XML_REGEXP_PUNCT_OTHERS:
+        case XML_REGEXP_SEPAR:
+        case XML_REGEXP_SEPAR_SPACE:
+        case XML_REGEXP_SEPAR_LINE:
+        case XML_REGEXP_SEPAR_PARA:
+        case XML_REGEXP_SYMBOL:
+        case XML_REGEXP_SYMBOL_MATH:
+        case XML_REGEXP_SYMBOL_CURRENCY:
+        case XML_REGEXP_SYMBOL_MODIFIER:
+        case XML_REGEXP_SYMBOL_OTHERS:
+        case XML_REGEXP_OTHER:
+        case XML_REGEXP_OTHER_CONTROL:
+        case XML_REGEXP_OTHER_FORMAT:
+        case XML_REGEXP_OTHER_PRIVATE:
+        case XML_REGEXP_OTHER_NA:
+	case XML_REGEXP_BLOCK_NAME:
+	    ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0,
+		                            (const xmlChar *)atom->valuep);
+	    if (atom->neg)
+		ret = !ret;
+	    break;
+    }
+    return(ret);
+}
+
+/************************************************************************
+ * 									*
+ *	Saving and restoring state of an execution context		*
+ * 									*
+ ************************************************************************/
+
+#ifdef DEBUG_REGEXP_EXEC
+static void
+xmlFARegDebugExec(xmlRegExecCtxtPtr exec) {
+    printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index);
+    if (exec->inputStack != NULL) {
+	int i;
+	printf(": ");
+	for (i = 0;(i < 3) && (i < exec->inputStackNr);i++)
+	    printf("%s ", (const char *)
+	           exec->inputStack[exec->inputStackNr - (i + 1)].value);
+    } else {
+	printf(": %s", &(exec->inputString[exec->index]));
+    }
+    printf("\n");
+}
+#endif
+
+static void
+xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
+#ifdef DEBUG_REGEXP_EXEC
+    printf("saving ");
+    exec->transno++;
+    xmlFARegDebugExec(exec);
+    exec->transno--;
+#endif
+#ifdef MAX_PUSH
+    if (exec->nbPush > MAX_PUSH) {
+        return;
+    }
+    exec->nbPush++;
+#endif
+
+    if (exec->maxRollbacks == 0) {
+	exec->maxRollbacks = 4;
+	exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks *
+		                             sizeof(xmlRegExecRollback));
+	if (exec->rollbacks == NULL) {
+	    xmlRegexpErrMemory(NULL, "saving regexp");
+	    exec->maxRollbacks = 0;
+	    return;
+	}
+	memset(exec->rollbacks, 0,
+	       exec->maxRollbacks * sizeof(xmlRegExecRollback));
+    } else if (exec->nbRollbacks >= exec->maxRollbacks) {
+	xmlRegExecRollback *tmp;
+	int len = exec->maxRollbacks;
+
+	exec->maxRollbacks *= 2;
+	tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks,
+			exec->maxRollbacks * sizeof(xmlRegExecRollback));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(NULL, "saving regexp");
+	    exec->maxRollbacks /= 2;
+	    return;
+	}
+	exec->rollbacks = tmp;
+	tmp = &exec->rollbacks[len];
+	memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
+    }
+    exec->rollbacks[exec->nbRollbacks].state = exec->state;
+    exec->rollbacks[exec->nbRollbacks].index = exec->index;
+    exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1;
+    if (exec->comp->nbCounters > 0) {
+	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
+	    exec->rollbacks[exec->nbRollbacks].counts = (int *)
+		xmlMalloc(exec->comp->nbCounters * sizeof(int));
+	    if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
+		xmlRegexpErrMemory(NULL, "saving regexp");
+		exec->status = -5;
+		return;
+	    }
+	}
+	memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts,
+	       exec->comp->nbCounters * sizeof(int));
+    }
+    exec->nbRollbacks++;
+}
+
+static void
+xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
+    if (exec->nbRollbacks <= 0) {
+	exec->status = -1;
+#ifdef DEBUG_REGEXP_EXEC
+	printf("rollback failed on empty stack\n");
+#endif
+	return;
+    }
+    exec->nbRollbacks--;
+    exec->state = exec->rollbacks[exec->nbRollbacks].state;
+    exec->index = exec->rollbacks[exec->nbRollbacks].index;
+    exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch;
+    if (exec->comp->nbCounters > 0) {
+	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
+	    fprintf(stderr, "exec save: allocation failed");
+	    exec->status = -6;
+	    return;
+	}
+	memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
+	       exec->comp->nbCounters * sizeof(int));
+    }
+
+#ifdef DEBUG_REGEXP_EXEC
+    printf("restored ");
+    xmlFARegDebugExec(exec);
+#endif
+}
+
+/************************************************************************
+ * 									*
+ *	Verifier, running an input against a compiled regexp		*
+ * 									*
+ ************************************************************************/
+
+static int
+xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
+    xmlRegExecCtxt execval;
+    xmlRegExecCtxtPtr exec = &execval;
+    int ret, codepoint = 0, len, deter;
+
+    exec->inputString = content;
+    exec->index = 0;
+    exec->nbPush = 0;
+    exec->determinist = 1;
+    exec->maxRollbacks = 0;
+    exec->nbRollbacks = 0;
+    exec->rollbacks = NULL;
+    exec->status = 0;
+    exec->comp = comp;
+    exec->state = comp->states[0];
+    exec->transno = 0;
+    exec->transcount = 0;
+    exec->inputStack = NULL;
+    exec->inputStackMax = 0;
+    if (comp->nbCounters > 0) {
+	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
+	if (exec->counts == NULL) {
+	    xmlRegexpErrMemory(NULL, "running regexp");
+	    return(-1);
+	}
+        memset(exec->counts, 0, comp->nbCounters * sizeof(int));
+    } else
+	exec->counts = NULL;
+    while ((exec->status == 0) &&
+	   ((exec->inputString[exec->index] != 0) ||
+	    ((exec->state != NULL) &&
+	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
+	xmlRegTransPtr trans;
+	xmlRegAtomPtr atom;
+
+	/*
+	 * If end of input on non-terminal state, rollback, however we may
+	 * still have epsilon like transition for counted transitions
+	 * on counters, in that case don't break too early.  Additionally,
+	 * if we are working on a range like "AB{0,2}", where B is not present,
+	 * we don't want to break.
+	 */
+	len = 1;
+	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) {
+	    /*
+	     * if there is a transition, we must check if
+	     *  atom allows minOccurs of 0
+	     */
+	    if (exec->transno < exec->state->nbTrans) {
+	        trans = &exec->state->trans[exec->transno];
+		if (trans->to >=0) {
+		    atom = trans->atom;
+		    if (!((atom->min == 0) && (atom->max > 0)))
+		        goto rollback;
+		}
+	    } else
+	        goto rollback;
+	}
+
+	exec->transcount = 0;
+	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
+	    trans = &exec->state->trans[exec->transno];
+	    if (trans->to < 0)
+		continue;
+	    atom = trans->atom;
+	    ret = 0;
+	    deter = 1;
+	    if (trans->count >= 0) {
+		int count;
+		xmlRegCounterPtr counter;
+
+		if (exec->counts == NULL) {
+		    exec->status = -1;
+		    goto error;
+		}
+		/*
+		 * A counted transition.
+		 */
+
+		count = exec->counts[trans->count];
+		counter = &exec->comp->counters[trans->count];
+#ifdef DEBUG_REGEXP_EXEC
+		printf("testing count %d: val %d, min %d, max %d\n",
+		       trans->count, count, counter->min,  counter->max);
+#endif
+		ret = ((count >= counter->min) && (count <= counter->max));
+		if ((ret) && (counter->min != counter->max))
+		    deter = 0;
+	    } else if (atom == NULL) {
+		fprintf(stderr, "epsilon transition left at runtime\n");
+		exec->status = -2;
+		break;
+	    } else if (exec->inputString[exec->index] != 0) {
+                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
+		ret = xmlRegCheckCharacter(atom, codepoint);
+		if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) {
+		    xmlRegStatePtr to = comp->states[trans->to];
+
+		    /*
+		     * this is a multiple input sequence
+		     * If there is a counter associated increment it now.
+		     * before potentially saving and rollback
+		     * do not increment if the counter is already over the
+		     * maximum limit in which case get to next transition
+		     */
+		    if (trans->counter >= 0) {
+			xmlRegCounterPtr counter;
+
+			if ((exec->counts == NULL) ||
+			    (exec->comp == NULL) ||
+			    (exec->comp->counters == NULL)) {
+			    exec->status = -1;
+			    goto error;
+			}
+			counter = &exec->comp->counters[trans->counter];
+			if (exec->counts[trans->counter] >= counter->max)
+			    continue; /* for loop on transitions */
+
+#ifdef DEBUG_REGEXP_EXEC
+			printf("Increasing count %d\n", trans->counter);
+#endif
+			exec->counts[trans->counter]++;
+		    }
+		    if (exec->state->nbTrans > exec->transno + 1) {
+			xmlFARegExecSave(exec);
+		    }
+		    exec->transcount = 1;
+		    do {
+			/*
+			 * Try to progress as much as possible on the input
+			 */
+			if (exec->transcount == atom->max) {
+			    break;
+			}
+			exec->index += len;
+			/*
+			 * End of input: stop here
+			 */
+			if (exec->inputString[exec->index] == 0) {
+			    exec->index -= len;
+			    break;
+			}
+			if (exec->transcount >= atom->min) {
+			    int transno = exec->transno;
+			    xmlRegStatePtr state = exec->state;
+
+			    /*
+			     * The transition is acceptable save it
+			     */
+			    exec->transno = -1; /* trick */
+			    exec->state = to;
+			    xmlFARegExecSave(exec);
+			    exec->transno = transno;
+			    exec->state = state;
+			}
+			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
+				              len);
+			ret = xmlRegCheckCharacter(atom, codepoint);
+			exec->transcount++;
+		    } while (ret == 1);
+		    if (exec->transcount < atom->min)
+			ret = 0;
+
+		    /*
+		     * If the last check failed but one transition was found
+		     * possible, rollback
+		     */
+		    if (ret < 0)
+			ret = 0;
+		    if (ret == 0) {
+			goto rollback;
+		    }
+		    if (trans->counter >= 0) {
+			if (exec->counts == NULL) {
+			    exec->status = -1;
+			    goto error;
+			}
+#ifdef DEBUG_REGEXP_EXEC
+			printf("Decreasing count %d\n", trans->counter);
+#endif
+			exec->counts[trans->counter]--;
+		    }
+		} else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) {
+		    /*
+		     * we don't match on the codepoint, but minOccurs of 0
+		     * says that's ok.  Setting len to 0 inhibits stepping
+		     * over the codepoint.
+		     */
+		    exec->transcount = 1;
+		    len = 0;
+		    ret = 1;
+		}
+	    } else if ((atom->min == 0) && (atom->max > 0)) {
+	        /* another spot to match when minOccurs is 0 */
+		exec->transcount = 1;
+		len = 0;
+		ret = 1;
+	    }
+	    if (ret == 1) {
+		if ((trans->nd == 1) ||
+		    ((trans->count >= 0) && (deter == 0) &&
+		     (exec->state->nbTrans > exec->transno + 1))) {
+#ifdef DEBUG_REGEXP_EXEC
+		    if (trans->nd == 1)
+		        printf("Saving on nd transition atom %d for %c at %d\n",
+			       trans->atom->no, codepoint, exec->index);
+		    else
+		        printf("Saving on counted transition count %d for %c at %d\n",
+			       trans->count, codepoint, exec->index);
+#endif
+		    xmlFARegExecSave(exec);
+		}
+		if (trans->counter >= 0) {
+		    xmlRegCounterPtr counter;
+
+                    /* make sure we don't go over the counter maximum value */
+		    if ((exec->counts == NULL) ||
+			(exec->comp == NULL) ||
+			(exec->comp->counters == NULL)) {
+			exec->status = -1;
+			goto error;
+		    }
+		    counter = &exec->comp->counters[trans->counter];
+		    if (exec->counts[trans->counter] >= counter->max)
+			continue; /* for loop on transitions */
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("Increasing count %d\n", trans->counter);
+#endif
+		    exec->counts[trans->counter]++;
+		}
+		if ((trans->count >= 0) &&
+		    (trans->count < REGEXP_ALL_COUNTER)) {
+		    if (exec->counts == NULL) {
+		        exec->status = -1;
+			goto error;
+		    }
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("resetting count %d on transition\n",
+		           trans->count);
+#endif
+		    exec->counts[trans->count] = 0;
+		}
+#ifdef DEBUG_REGEXP_EXEC
+		printf("entering state %d\n", trans->to);
+#endif
+		exec->state = comp->states[trans->to];
+		exec->transno = 0;
+		if (trans->atom != NULL) {
+		    exec->index += len;
+		}
+		goto progress;
+	    } else if (ret < 0) {
+		exec->status = -4;
+		break;
+	    }
+	}
+	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
+rollback:
+	    /*
+	     * Failed to find a way out
+	     */
+	    exec->determinist = 0;
+#ifdef DEBUG_REGEXP_EXEC
+	    printf("rollback from state %d on %d:%c\n", exec->state->no,
+	           codepoint,codepoint);
+#endif
+	    xmlFARegExecRollBack(exec);
+	}
+progress:
+	continue;
+    }
+error:
+    if (exec->rollbacks != NULL) {
+	if (exec->counts != NULL) {
+	    int i;
+
+	    for (i = 0;i < exec->maxRollbacks;i++)
+		if (exec->rollbacks[i].counts != NULL)
+		    xmlFree(exec->rollbacks[i].counts);
+	}
+	xmlFree(exec->rollbacks);
+    }
+    if (exec->counts != NULL)
+	xmlFree(exec->counts);
+    if (exec->status == 0)
+	return(1);
+    if (exec->status == -1) {
+	if (exec->nbPush > MAX_PUSH)
+	    return(-1);
+	return(0);
+    }
+    return(exec->status);
+}
+
+/************************************************************************
+ * 									*
+ *	Progressive interface to the verifier one atom at a time	*
+ * 									*
+ ************************************************************************/
+#ifdef DEBUG_ERR
+static void testerr(xmlRegExecCtxtPtr exec);
+#endif
+
+/**
+ * xmlRegNewExecCtxt:
+ * @comp: a precompiled regular expression
+ * @callback: a callback function used for handling progresses in the
+ *            automata matching phase
+ * @data: the context data associated to the callback in this context
+ *
+ * Build a context used for progressive evaluation of a regexp.
+ *
+ * Returns the new context
+ */
+xmlRegExecCtxtPtr
+xmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) {
+    xmlRegExecCtxtPtr exec;
+
+    if (comp == NULL)
+	return(NULL);
+    if ((comp->compact == NULL) && (comp->states == NULL))
+        return(NULL);
+    exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt));
+    if (exec == NULL) {
+	xmlRegexpErrMemory(NULL, "creating execution context");
+	return(NULL);
+    }
+    memset(exec, 0, sizeof(xmlRegExecCtxt));
+    exec->inputString = NULL;
+    exec->index = 0;
+    exec->determinist = 1;
+    exec->maxRollbacks = 0;
+    exec->nbRollbacks = 0;
+    exec->rollbacks = NULL;
+    exec->status = 0;
+    exec->comp = comp;
+    if (comp->compact == NULL)
+	exec->state = comp->states[0];
+    exec->transno = 0;
+    exec->transcount = 0;
+    exec->callback = callback;
+    exec->data = data;
+    if (comp->nbCounters > 0) {
+        /*
+	 * For error handling, exec->counts is allocated twice the size
+	 * the second half is used to store the data in case of rollback
+	 */
+	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int)
+	                                 * 2);
+	if (exec->counts == NULL) {
+	    xmlRegexpErrMemory(NULL, "creating execution context");
+	    xmlFree(exec);
+	    return(NULL);
+	}
+        memset(exec->counts, 0, comp->nbCounters * sizeof(int) * 2);
+	exec->errCounts = &exec->counts[comp->nbCounters];
+    } else {
+	exec->counts = NULL;
+	exec->errCounts = NULL;
+    }
+    exec->inputStackMax = 0;
+    exec->inputStackNr = 0;
+    exec->inputStack = NULL;
+    exec->errStateNo = -1;
+    exec->errString = NULL;
+    exec->nbPush = 0;
+    return(exec);
+}
+
+/**
+ * xmlRegFreeExecCtxt:
+ * @exec: a regular expression evaulation context
+ *
+ * Free the structures associated to a regular expression evaulation context.
+ */
+void
+xmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) {
+    if (exec == NULL)
+	return;
+
+    if (exec->rollbacks != NULL) {
+	if (exec->counts != NULL) {
+	    int i;
+
+	    for (i = 0;i < exec->maxRollbacks;i++)
+		if (exec->rollbacks[i].counts != NULL)
+		    xmlFree(exec->rollbacks[i].counts);
+	}
+	xmlFree(exec->rollbacks);
+    }
+    if (exec->counts != NULL)
+	xmlFree(exec->counts);
+    if (exec->inputStack != NULL) {
+	int i;
+
+	for (i = 0;i < exec->inputStackNr;i++) {
+	    if (exec->inputStack[i].value != NULL)
+		xmlFree(exec->inputStack[i].value);
+	}
+	xmlFree(exec->inputStack);
+    }
+    if (exec->errString != NULL)
+        xmlFree(exec->errString);
+    xmlFree(exec);
+}
+
+static void
+xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
+	                    void *data) {
+#ifdef DEBUG_PUSH
+    printf("saving value: %d:%s\n", exec->inputStackNr, value);
+#endif
+    if (exec->inputStackMax == 0) {
+	exec->inputStackMax = 4;
+	exec->inputStack = (xmlRegInputTokenPtr) 
+	    xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
+	if (exec->inputStack == NULL) {
+	    xmlRegexpErrMemory(NULL, "pushing input string");
+	    exec->inputStackMax = 0;
+	    return;
+	}
+    } else if (exec->inputStackNr + 1 >= exec->inputStackMax) {
+	xmlRegInputTokenPtr tmp;
+
+	exec->inputStackMax *= 2;
+	tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack,
+			exec->inputStackMax * sizeof(xmlRegInputToken));
+	if (tmp == NULL) {
+	    xmlRegexpErrMemory(NULL, "pushing input string");
+	    exec->inputStackMax /= 2;
+	    return;
+	}
+	exec->inputStack = tmp;
+    }
+    exec->inputStack[exec->inputStackNr].value = xmlStrdup(value);
+    exec->inputStack[exec->inputStackNr].data = data;
+    exec->inputStackNr++;
+    exec->inputStack[exec->inputStackNr].value = NULL;
+    exec->inputStack[exec->inputStackNr].data = NULL;
+}
+
+/**
+ * xmlRegStrEqualWildcard:
+ * @expStr:  the string to be evaluated 
+ * @valStr:  the validation string
+ *
+ * Checks if both strings are equal or have the same content. "*"
+ * can be used as a wildcard in @valStr; "|" is used as a seperator of 
+ * substrings in both @expStr and @valStr.
+ *
+ * Returns 1 if the comparison is satisfied and the number of substrings
+ * is equal, 0 otherwise.
+ */
+
+static int
+xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr) {
+    if (expStr == valStr) return(1);
+    if (expStr == NULL) return(0);
+    if (valStr == NULL) return(0);
+    do {
+	/*
+	* Eval if we have a wildcard for the current item.
+	*/
+        if (*expStr != *valStr) {
+	    /* if one of them starts with a wildcard make valStr be it */
+	    if (*valStr == '*') {
+	        const xmlChar *tmp;
+
+		tmp = valStr;
+		valStr = expStr;
+		expStr = tmp;
+	    }
+	    if ((*valStr != 0) && (*expStr != 0) && (*expStr++ == '*')) {
+		do {
+		    if (*valStr == XML_REG_STRING_SEPARATOR)
+			break;
+		    valStr++;
+		} while (*valStr != 0);
+		continue;
+	    } else
+		return(0);
+	}
+	expStr++;
+	valStr++;
+    } while (*valStr != 0);
+    if (*expStr != 0)
+	return (0);
+    else
+	return (1);
+}
+
+/**
+ * xmlRegCompactPushString:
+ * @exec: a regexp execution context
+ * @comp:  the precompiled exec with a compact table
+ * @value: a string token input
+ * @data: data associated to the token to reuse in callbacks
+ *
+ * Push one input token in the execution context
+ *
+ * Returns: 1 if the regexp reached a final state, 0 if non-final, and
+ *     a negative value in case of error.
+ */
+static int
+xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
+	                xmlRegexpPtr comp,
+	                const xmlChar *value,
+	                void *data) {
+    int state = exec->index;
+    int i, target;
+
+    if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL))
+	return(-1);
+    
+    if (value == NULL) {
+	/*
+	 * are we at a final state ?
+	 */
+	if (comp->compact[state * (comp->nbstrings + 1)] ==
+            XML_REGEXP_FINAL_STATE)
+	    return(1);
+	return(0);
+    }
+
+#ifdef DEBUG_PUSH
+    printf("value pushed: %s\n", value);
+#endif
+
+    /*
+     * Examine all outside transitions from current state
+     */
+    for (i = 0;i < comp->nbstrings;i++) {
+	target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
+	if ((target > 0) && (target <= comp->nbstates)) {
+	    target--; /* to avoid 0 */    
+	    if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) {
+		exec->index = target;		
+		if ((exec->callback != NULL) && (comp->transdata != NULL)) {
+		    exec->callback(exec->data, value,
+			  comp->transdata[state * comp->nbstrings + i], data);
+		}
+#ifdef DEBUG_PUSH
+		printf("entering state %d\n", target);
+#endif
+		if (comp->compact[target * (comp->nbstrings + 1)] ==
+		    XML_REGEXP_SINK_STATE)
+		    goto error;
+
+		if (comp->compact[target * (comp->nbstrings + 1)] ==
+		    XML_REGEXP_FINAL_STATE)
+		    return(1);
+		return(0);
+	    }
+	}
+    }
+    /*
+     * Failed to find an exit transition out from current state for the
+     * current token
+     */
+#ifdef DEBUG_PUSH
+    printf("failed to find a transition for %s on state %d\n", value, state);
+#endif
+error:
+    if (exec->errString != NULL)
+        xmlFree(exec->errString);
+    exec->errString = xmlStrdup(value);
+    exec->errStateNo = state;
+    exec->status = -1;
+#ifdef DEBUG_ERR
+    testerr(exec);
+#endif
+    return(-1);
+}
+
+/**
+ * xmlRegExecPushStringInternal:
+ * @exec: a regexp execution context or NULL to indicate the end
+ * @value: a string token input
+ * @data: data associated to the token to reuse in callbacks
+ * @compound: value was assembled from 2 strings
+ *
+ * Push one input token in the execution context
+ *
+ * Returns: 1 if the regexp reached a final state, 0 if non-final, and
+ *     a negative value in case of error.
+ */
+static int
+xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
+	                     void *data, int compound) {
+    xmlRegTransPtr trans;
+    xmlRegAtomPtr atom;
+    int ret;
+    int final = 0;
+    int progress = 1;
+
+    if (exec == NULL)
+	return(-1);
+    if (exec->comp == NULL)
+	return(-1);
+    if (exec->status != 0)
+	return(exec->status);
+
+    if (exec->comp->compact != NULL)
+	return(xmlRegCompactPushString(exec, exec->comp, value, data));
+
+    if (value == NULL) {
+        if (exec->state->type == XML_REGEXP_FINAL_STATE)
+	    return(1);
+	final = 1;
+    }
+
+#ifdef DEBUG_PUSH
+    printf("value pushed: %s\n", value);
+#endif
+    /*
+     * If we have an active rollback stack push the new value there
+     * and get back to where we were left
+     */
+    if ((value != NULL) && (exec->inputStackNr > 0)) {
+	xmlFARegExecSaveInputString(exec, value, data);
+	value = exec->inputStack[exec->index].value;
+	data = exec->inputStack[exec->index].data;
+#ifdef DEBUG_PUSH
+	printf("value loaded: %s\n", value);
+#endif
+    }
+
+    while ((exec->status == 0) &&
+	   ((value != NULL) ||
+	    ((final == 1) &&
+	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
+
+	/*
+	 * End of input on non-terminal state, rollback, however we may
+	 * still have epsilon like transition for counted transitions
+	 * on counters, in that case don't break too early.
+	 */
+	if ((value == NULL) && (exec->counts == NULL))
+	    goto rollback;
+
+	exec->transcount = 0;
+	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
+	    trans = &exec->state->trans[exec->transno];
+	    if (trans->to < 0)
+		continue;
+	    atom = trans->atom;
+	    ret = 0;
+	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
+		int i;
+		int count;
+		xmlRegTransPtr t;
+		xmlRegCounterPtr counter;
+
+		ret = 0;
+
+#ifdef DEBUG_PUSH
+		printf("testing all lax %d\n", trans->count);
+#endif
+		/*
+		 * Check all counted transitions from the current state
+		 */
+		if ((value == NULL) && (final)) {
+		    ret = 1;
+		} else if (value != NULL) {
+		    for (i = 0;i < exec->state->nbTrans;i++) {
+			t = &exec->state->trans[i];
+			if ((t->counter < 0) || (t == trans))
+			    continue;
+			counter = &exec->comp->counters[t->counter];
+			count = exec->counts[t->counter];
+			if ((count < counter->max) && 
+		            (t->atom != NULL) &&
+			    (xmlStrEqual(value, t->atom->valuep))) {
+			    ret = 0;
+			    break;
+			}
+			if ((count >= counter->min) &&
+			    (count < counter->max) &&
+			    (t->atom != NULL) &&
+			    (xmlStrEqual(value, t->atom->valuep))) {
+			    ret = 1;
+			    break;
+			}
+		    }
+		}
+	    } else if (trans->count == REGEXP_ALL_COUNTER) {
+		int i;
+		int count;
+		xmlRegTransPtr t;
+		xmlRegCounterPtr counter;
+
+		ret = 1;
+
+#ifdef DEBUG_PUSH
+		printf("testing all %d\n", trans->count);
+#endif
+		/*
+		 * Check all counted transitions from the current state
+		 */
+		for (i = 0;i < exec->state->nbTrans;i++) {
+                    t = &exec->state->trans[i];
+		    if ((t->counter < 0) || (t == trans))
+			continue;
+                    counter = &exec->comp->counters[t->counter];
+		    count = exec->counts[t->counter];
+		    if ((count < counter->min) || (count > counter->max)) {
+			ret = 0;
+			break;
+		    }
+		}
+	    } else if (trans->count >= 0) {
+		int count;
+		xmlRegCounterPtr counter;
+
+		/*
+		 * A counted transition.
+		 */
+
+		count = exec->counts[trans->count];
+		counter = &exec->comp->counters[trans->count];
+#ifdef DEBUG_PUSH
+		printf("testing count %d: val %d, min %d, max %d\n",
+		       trans->count, count, counter->min,  counter->max);
+#endif
+		ret = ((count >= counter->min) && (count <= counter->max));
+	    } else if (atom == NULL) {
+		fprintf(stderr, "epsilon transition left at runtime\n");
+		exec->status = -2;
+		break;
+	    } else if (value != NULL) {
+		ret = xmlRegStrEqualWildcard(atom->valuep, value);
+		if (atom->neg) {
+		    ret = !ret;
+		    if (!compound)
+		        ret = 0;
+		}
+		if ((ret == 1) && (trans->counter >= 0)) {
+		    xmlRegCounterPtr counter;
+		    int count;
+
+		    count = exec->counts[trans->counter];
+		    counter = &exec->comp->counters[trans->counter];
+		    if (count >= counter->max)
+			ret = 0;
+		}
+
+		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
+		    xmlRegStatePtr to = exec->comp->states[trans->to];
+
+		    /*
+		     * this is a multiple input sequence
+		     */
+		    if (exec->state->nbTrans > exec->transno + 1) {
+			if (exec->inputStackNr <= 0) {
+			    xmlFARegExecSaveInputString(exec, value, data);
+			}
+			xmlFARegExecSave(exec);
+		    }
+		    exec->transcount = 1;
+		    do {
+			/*
+			 * Try to progress as much as possible on the input
+			 */
+			if (exec->transcount == atom->max) {
+			    break;
+			}
+			exec->index++;
+			value = exec->inputStack[exec->index].value;
+			data = exec->inputStack[exec->index].data;
+#ifdef DEBUG_PUSH
+			printf("value loaded: %s\n", value);
+#endif
+
+			/*
+			 * End of input: stop here
+			 */
+			if (value == NULL) {
+			    exec->index --;
+			    break;
+			}
+			if (exec->transcount >= atom->min) {
+			    int transno = exec->transno;
+			    xmlRegStatePtr state = exec->state;
+
+			    /*
+			     * The transition is acceptable save it
+			     */
+			    exec->transno = -1; /* trick */
+			    exec->state = to;
+			    if (exec->inputStackNr <= 0) {
+				xmlFARegExecSaveInputString(exec, value, data);
+			    }
+			    xmlFARegExecSave(exec);
+			    exec->transno = transno;
+			    exec->state = state;
+			}
+			ret = xmlStrEqual(value, atom->valuep);
+			exec->transcount++;
+		    } while (ret == 1);
+		    if (exec->transcount < atom->min)
+			ret = 0;
+
+		    /*
+		     * If the last check failed but one transition was found
+		     * possible, rollback
+		     */
+		    if (ret < 0)
+			ret = 0;
+		    if (ret == 0) {
+			goto rollback;
+		    }
+		}
+	    }
+	    if (ret == 1) {
+		if ((exec->callback != NULL) && (atom != NULL) &&
+			(data != NULL)) {
+		    exec->callback(exec->data, atom->valuep,
+			           atom->data, data);
+		}
+		if (exec->state->nbTrans > exec->transno + 1) {
+		    if (exec->inputStackNr <= 0) {
+			xmlFARegExecSaveInputString(exec, value, data);
+		    }
+		    xmlFARegExecSave(exec);
+		}
+		if (trans->counter >= 0) {
+#ifdef DEBUG_PUSH
+		    printf("Increasing count %d\n", trans->counter);
+#endif
+		    exec->counts[trans->counter]++;
+		}
+		if ((trans->count >= 0) &&
+		    (trans->count < REGEXP_ALL_COUNTER)) {
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("resetting count %d on transition\n",
+		           trans->count);
+#endif
+		    exec->counts[trans->count] = 0;
+		}
+#ifdef DEBUG_PUSH
+		printf("entering state %d\n", trans->to);
+#endif
+                if ((exec->comp->states[trans->to] != NULL) &&
+		    (exec->comp->states[trans->to]->type ==
+		     XML_REGEXP_SINK_STATE)) {
+		    /*
+		     * entering a sink state, save the current state as error
+		     * state.
+		     */
+		    if (exec->errString != NULL)
+			xmlFree(exec->errString);
+		    exec->errString = xmlStrdup(value);
+		    exec->errState = exec->state;
+		    memcpy(exec->errCounts, exec->counts,
+			   exec->comp->nbCounters * sizeof(int));
+		}
+		exec->state = exec->comp->states[trans->to];
+		exec->transno = 0;
+		if (trans->atom != NULL) {
+		    if (exec->inputStack != NULL) {
+			exec->index++;
+			if (exec->index < exec->inputStackNr) {
+			    value = exec->inputStack[exec->index].value;
+			    data = exec->inputStack[exec->index].data;
+#ifdef DEBUG_PUSH
+			    printf("value loaded: %s\n", value);
+#endif
+			} else {
+			    value = NULL;
+			    data = NULL;
+#ifdef DEBUG_PUSH
+			    printf("end of input\n");
+#endif
+			}
+		    } else {
+			value = NULL;
+			data = NULL;
+#ifdef DEBUG_PUSH
+			printf("end of input\n");
+#endif
+		    }
+		}
+		goto progress;
+	    } else if (ret < 0) {
+		exec->status = -4;
+		break;
+	    }
+	}
+	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
+rollback:
+            /*
+	     * if we didn't yet rollback on the current input
+	     * store the current state as the error state.
+	     */
+	    if ((progress) && (exec->state != NULL) &&
+	        (exec->state->type != XML_REGEXP_SINK_STATE)) {
+	        progress = 0;
+		if (exec->errString != NULL)
+		    xmlFree(exec->errString);
+		exec->errString = xmlStrdup(value);
+		exec->errState = exec->state;
+		memcpy(exec->errCounts, exec->counts,
+		       exec->comp->nbCounters * sizeof(int));
+	    }
+
+	    /*
+	     * Failed to find a way out
+	     */
+	    exec->determinist = 0;
+	    xmlFARegExecRollBack(exec);
+	    if (exec->status == 0) {
+		value = exec->inputStack[exec->index].value;
+		data = exec->inputStack[exec->index].data;
+#ifdef DEBUG_PUSH
+		printf("value loaded: %s\n", value);
+#endif
+	    }
+	}
+	continue;
+progress:
+        progress = 1;
+	continue;
+    }
+    if (exec->status == 0) {
+        return(exec->state->type == XML_REGEXP_FINAL_STATE);
+    }
+#ifdef DEBUG_ERR
+    if (exec->status < 0) {
+	testerr(exec);
+    }
+#endif
+    return(exec->status);
+}
+
+/**
+ * xmlRegExecPushString:
+ * @exec: a regexp execution context or NULL to indicate the end
+ * @value: a string token input
+ * @data: data associated to the token to reuse in callbacks
+ *
+ * Push one input token in the execution context
+ *
+ * Returns: 1 if the regexp reached a final state, 0 if non-final, and
+ *     a negative value in case of error.
+ */
+int
+xmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value,
+	             void *data) {
+    return(xmlRegExecPushStringInternal(exec, value, data, 0));
+}
+
+/**
+ * xmlRegExecPushString2:
+ * @exec: a regexp execution context or NULL to indicate the end
+ * @value: the first string token input
+ * @value2: the second string token input
+ * @data: data associated to the token to reuse in callbacks
+ *
+ * Push one input token in the execution context
+ *
+ * Returns: 1 if the regexp reached a final state, 0 if non-final, and
+ *     a negative value in case of error.
+ */
+int
+xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value,
+                      const xmlChar *value2, void *data) {
+    xmlChar buf[150];
+    int lenn, lenp, ret;
+    xmlChar *str;
+
+    if (exec == NULL)
+	return(-1);
+    if (exec->comp == NULL)
+	return(-1);
+    if (exec->status != 0)
+	return(exec->status);
+
+    if (value2 == NULL)
+        return(xmlRegExecPushString(exec, value, data));
+
+    lenn = strlen((char *) value2);
+    lenp = strlen((char *) value);
+
+    if (150 < lenn + lenp + 2) {
+	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (str == NULL) {
+	    exec->status = -1;
+	    return(-1);
+	}
+    } else {
+	str = buf;
+    }
+    memcpy(&str[0], value, lenp);
+    str[lenp] = XML_REG_STRING_SEPARATOR;
+    memcpy(&str[lenp + 1], value2, lenn);
+    str[lenn + lenp + 1] = 0;
+
+    if (exec->comp->compact != NULL)
+	ret = xmlRegCompactPushString(exec, exec->comp, str, data);
+    else
+        ret = xmlRegExecPushStringInternal(exec, str, data, 1);
+
+    if (str != buf)
+        xmlFree(str);
+    return(ret);
+}
+
+/**
+ * xmlRegExecGetValues:
+ * @exec: a regexp execution context
+ * @err: error extraction or normal one
+ * @nbval: pointer to the number of accepted values IN/OUT
+ * @nbneg: return number of negative transitions
+ * @values: pointer to the array of acceptable values
+ * @terminal: return value if this was a terminal state
+ *
+ * Extract informations from the regexp execution, internal routine to
+ * implement xmlRegExecNextValues() and xmlRegExecErrInfo()
+ *
+ * Returns: 0 in case of success or -1 in case of error.
+ */
+static int
+xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err,
+                    int *nbval, int *nbneg,
+		    xmlChar **values, int *terminal) {
+    int maxval;
+    int nb = 0;
+
+    if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) || 
+        (values == NULL) || (*nbval <= 0))
+        return(-1);
+
+    maxval = *nbval;
+    *nbval = 0;
+    *nbneg = 0;
+    if ((exec->comp != NULL) && (exec->comp->compact != NULL)) {
+        xmlRegexpPtr comp;
+	int target, i, state;
+
+        comp = exec->comp;
+
+	if (err) {
+	    if (exec->errStateNo == -1) return(-1);
+	    state = exec->errStateNo;
+	} else {
+	    state = exec->index;
+	}
+	if (terminal != NULL) {
+	    if (comp->compact[state * (comp->nbstrings + 1)] ==
+	        XML_REGEXP_FINAL_STATE)
+		*terminal = 1;
+	    else
+		*terminal = 0;
+	}
+	for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) {
+	    target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
+	    if ((target > 0) && (target <= comp->nbstates) &&
+	        (comp->compact[(target - 1) * (comp->nbstrings + 1)] !=
+		 XML_REGEXP_SINK_STATE)) {
+	        values[nb++] = comp->stringMap[i];
+		(*nbval)++;
+	    }
+	}
+	for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) {
+	    target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
+	    if ((target > 0) && (target <= comp->nbstates) &&
+	        (comp->compact[(target - 1) * (comp->nbstrings + 1)] ==
+		 XML_REGEXP_SINK_STATE)) {
+	        values[nb++] = comp->stringMap[i];
+		(*nbneg)++;
+	    }
+	}
+    } else {
+        int transno;
+	xmlRegTransPtr trans;
+	xmlRegAtomPtr atom;
+	xmlRegStatePtr state;
+
+	if (terminal != NULL) {
+	    if (exec->state->type == XML_REGEXP_FINAL_STATE)
+		*terminal = 1;
+	    else
+		*terminal = 0;
+	}
+
+	if (err) {
+	    if (exec->errState == NULL) return(-1);
+	    state = exec->errState;
+	} else {
+	    if (exec->state == NULL) return(-1);
+	    state = exec->state;
+	}
+	for (transno = 0;
+	     (transno < state->nbTrans) && (nb < maxval);
+	     transno++) {
+	    trans = &state->trans[transno];
+	    if (trans->to < 0)
+		continue;
+	    atom = trans->atom;
+	    if ((atom == NULL) || (atom->valuep == NULL))
+		continue;
+	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
+	        /* this should not be reached but ... */
+	        TODO;
+	    } else if (trans->count == REGEXP_ALL_COUNTER) {
+	        /* this should not be reached but ... */
+	        TODO;
+	    } else if (trans->counter >= 0) {
+		xmlRegCounterPtr counter = NULL;
+		int count;
+
+		if (err)
+		    count = exec->errCounts[trans->counter];
+		else
+		    count = exec->counts[trans->counter];
+		if (exec->comp != NULL)
+		    counter = &exec->comp->counters[trans->counter];
+		if ((counter == NULL) || (count < counter->max)) {
+		    if (atom->neg)
+			values[nb++] = (xmlChar *) atom->valuep2;
+		    else
+			values[nb++] = (xmlChar *) atom->valuep;
+		    (*nbval)++;
+		}
+	    } else {
+                if ((exec->comp->states[trans->to] != NULL) &&
+		    (exec->comp->states[trans->to]->type !=
+		     XML_REGEXP_SINK_STATE)) {
+		    if (atom->neg)
+			values[nb++] = (xmlChar *) atom->valuep2;
+		    else
+			values[nb++] = (xmlChar *) atom->valuep;
+		    (*nbval)++;
+		}
+	    } 
+	}
+	for (transno = 0;
+	     (transno < state->nbTrans) && (nb < maxval);
+	     transno++) {
+	    trans = &state->trans[transno];
+	    if (trans->to < 0)
+		continue;
+	    atom = trans->atom;
+	    if ((atom == NULL) || (atom->valuep == NULL))
+		continue;
+	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
+	        continue;
+	    } else if (trans->count == REGEXP_ALL_COUNTER) {
+	        continue;
+	    } else if (trans->counter >= 0) {
+	        continue;
+	    } else {
+                if ((exec->comp->states[trans->to] != NULL) &&
+		    (exec->comp->states[trans->to]->type ==
+		     XML_REGEXP_SINK_STATE)) {
+		    if (atom->neg)
+			values[nb++] = (xmlChar *) atom->valuep2;
+		    else
+			values[nb++] = (xmlChar *) atom->valuep;
+		    (*nbneg)++;
+		}
+	    } 
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlRegExecNextValues:
+ * @exec: a regexp execution context
+ * @nbval: pointer to the number of accepted values IN/OUT
+ * @nbneg: return number of negative transitions
+ * @values: pointer to the array of acceptable values
+ * @terminal: return value if this was a terminal state
+ *
+ * Extract informations from the regexp execution,
+ * the parameter @values must point to an array of @nbval string pointers
+ * on return nbval will contain the number of possible strings in that
+ * state and the @values array will be updated with them. The string values
+ * returned will be freed with the @exec context and don't need to be
+ * deallocated.
+ *
+ * Returns: 0 in case of success or -1 in case of error.
+ */
+int
+xmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg,
+                     xmlChar **values, int *terminal) {
+    return(xmlRegExecGetValues(exec, 0, nbval, nbneg, values, terminal));
+}
+
+/**
+ * xmlRegExecErrInfo:
+ * @exec: a regexp execution context generating an error
+ * @string: return value for the error string
+ * @nbval: pointer to the number of accepted values IN/OUT
+ * @nbneg: return number of negative transitions
+ * @values: pointer to the array of acceptable values
+ * @terminal: return value if this was a terminal state
+ *
+ * Extract error informations from the regexp execution, the parameter
+ * @string will be updated with the value pushed and not accepted,
+ * the parameter @values must point to an array of @nbval string pointers
+ * on return nbval will contain the number of possible strings in that
+ * state and the @values array will be updated with them. The string values
+ * returned will be freed with the @exec context and don't need to be
+ * deallocated.
+ *
+ * Returns: 0 in case of success or -1 in case of error.
+ */
+int
+xmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string,
+                  int *nbval, int *nbneg, xmlChar **values, int *terminal) {
+    if (exec == NULL)
+        return(-1);
+    if (string != NULL) {
+        if (exec->status != 0)
+	    *string = exec->errString;
+	else
+	    *string = NULL;
+    }
+    return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal));
+}
+
+#ifdef DEBUG_ERR
+static void testerr(xmlRegExecCtxtPtr exec) {
+    const xmlChar *string;
+    xmlChar *values[5];
+    int nb = 5;
+    int nbneg;
+    int terminal;
+    xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal);
+}
+#endif
+
+#if 0
+static int
+xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
+    xmlRegTransPtr trans;
+    xmlRegAtomPtr atom;
+    int ret;
+    int codepoint, len;
+
+    if (exec == NULL)
+	return(-1);
+    if (exec->status != 0)
+	return(exec->status);
+
+    while ((exec->status == 0) &&
+	   ((exec->inputString[exec->index] != 0) ||
+	    (exec->state->type != XML_REGEXP_FINAL_STATE))) {
+
+	/*
+	 * End of input on non-terminal state, rollback, however we may
+	 * still have epsilon like transition for counted transitions
+	 * on counters, in that case don't break too early.
+	 */
+	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
+	    goto rollback;
+
+	exec->transcount = 0;
+	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
+	    trans = &exec->state->trans[exec->transno];
+	    if (trans->to < 0)
+		continue;
+	    atom = trans->atom;
+	    ret = 0;
+	    if (trans->count >= 0) {
+		int count;
+		xmlRegCounterPtr counter;
+
+		/*
+		 * A counted transition.
+		 */
+
+		count = exec->counts[trans->count];
+		counter = &exec->comp->counters[trans->count];
+#ifdef DEBUG_REGEXP_EXEC
+		printf("testing count %d: val %d, min %d, max %d\n",
+		       trans->count, count, counter->min,  counter->max);
+#endif
+		ret = ((count >= counter->min) && (count <= counter->max));
+	    } else if (atom == NULL) {
+		fprintf(stderr, "epsilon transition left at runtime\n");
+		exec->status = -2;
+		break;
+	    } else if (exec->inputString[exec->index] != 0) {
+                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
+		ret = xmlRegCheckCharacter(atom, codepoint);
+		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
+		    xmlRegStatePtr to = exec->comp->states[trans->to];
+
+		    /*
+		     * this is a multiple input sequence
+		     */
+		    if (exec->state->nbTrans > exec->transno + 1) {
+			xmlFARegExecSave(exec);
+		    }
+		    exec->transcount = 1;
+		    do {
+			/*
+			 * Try to progress as much as possible on the input
+			 */
+			if (exec->transcount == atom->max) {
+			    break;
+			}
+			exec->index += len;
+			/*
+			 * End of input: stop here
+			 */
+			if (exec->inputString[exec->index] == 0) {
+			    exec->index -= len;
+			    break;
+			}
+			if (exec->transcount >= atom->min) {
+			    int transno = exec->transno;
+			    xmlRegStatePtr state = exec->state;
+
+			    /*
+			     * The transition is acceptable save it
+			     */
+			    exec->transno = -1; /* trick */
+			    exec->state = to;
+			    xmlFARegExecSave(exec);
+			    exec->transno = transno;
+			    exec->state = state;
+			}
+			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
+				              len);
+			ret = xmlRegCheckCharacter(atom, codepoint);
+			exec->transcount++;
+		    } while (ret == 1);
+		    if (exec->transcount < atom->min)
+			ret = 0;
+
+		    /*
+		     * If the last check failed but one transition was found
+		     * possible, rollback
+		     */
+		    if (ret < 0)
+			ret = 0;
+		    if (ret == 0) {
+			goto rollback;
+		    }
+		}
+	    }
+	    if (ret == 1) {
+		if (exec->state->nbTrans > exec->transno + 1) {
+		    xmlFARegExecSave(exec);
+		}
+		/*
+		 * restart count for expressions like this ((abc){2})*
+		 */
+		if (trans->count >= 0) {
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("Reset count %d\n", trans->count);
+#endif
+		    exec->counts[trans->count] = 0;
+		}
+		if (trans->counter >= 0) {
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("Increasing count %d\n", trans->counter);
+#endif
+		    exec->counts[trans->counter]++;
+		}
+#ifdef DEBUG_REGEXP_EXEC
+		printf("entering state %d\n", trans->to);
+#endif
+		exec->state = exec->comp->states[trans->to];
+		exec->transno = 0;
+		if (trans->atom != NULL) {
+		    exec->index += len;
+		}
+		goto progress;
+	    } else if (ret < 0) {
+		exec->status = -4;
+		break;
+	    }
+	}
+	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
+rollback:
+	    /*
+	     * Failed to find a way out
+	     */
+	    exec->determinist = 0;
+	    xmlFARegExecRollBack(exec);
+	}
+progress:
+	continue;
+    }
+}
+#endif
+/************************************************************************
+ * 									*
+ *	Parser for the Schemas Datatype Regular Expressions		*
+ *	http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs	*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlFAIsChar:
+ * @ctxt:  a regexp parser context
+ *
+ * [10]   Char   ::=   [^.\?*+()|#x5B#x5D]
+ */
+static int
+xmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
+    int cur;
+    int len;
+
+    cur = CUR_SCHAR(ctxt->cur, len);
+    if ((cur == '.') || (cur == '\\') || (cur == '?') ||
+	(cur == '*') || (cur == '+') || (cur == '(') ||
+	(cur == ')') || (cur == '|') || (cur == 0x5B) ||
+	(cur == 0x5D) || (cur == 0))
+	return(-1);
+    return(cur);
+}
+
+/**
+ * xmlFAParseCharProp:
+ * @ctxt:  a regexp parser context
+ *
+ * [27]   charProp   ::=   IsCategory | IsBlock
+ * [28]   IsCategory ::= Letters | Marks | Numbers | Punctuation |
+ *                       Separators | Symbols | Others 
+ * [29]   Letters   ::=   'L' [ultmo]?
+ * [30]   Marks   ::=   'M' [nce]?
+ * [31]   Numbers   ::=   'N' [dlo]?
+ * [32]   Punctuation   ::=   'P' [cdseifo]?
+ * [33]   Separators   ::=   'Z' [slp]?
+ * [34]   Symbols   ::=   'S' [mcko]?
+ * [35]   Others   ::=   'C' [cfon]?
+ * [36]   IsBlock   ::=   'Is' [a-zA-Z0-9#x2D]+
+ */
+static void
+xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
+    int cur;
+    xmlRegAtomType type = (xmlRegAtomType) 0;
+    xmlChar *blockName = NULL;
+    
+    cur = CUR;
+    if (cur == 'L') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'u') {
+	    NEXT;
+	    type = XML_REGEXP_LETTER_UPPERCASE;
+	} else if (cur == 'l') {
+	    NEXT;
+	    type = XML_REGEXP_LETTER_LOWERCASE;
+	} else if (cur == 't') {
+	    NEXT;
+	    type = XML_REGEXP_LETTER_TITLECASE;
+	} else if (cur == 'm') {
+	    NEXT;
+	    type = XML_REGEXP_LETTER_MODIFIER;
+	} else if (cur == 'o') {
+	    NEXT;
+	    type = XML_REGEXP_LETTER_OTHERS;
+	} else {
+	    type = XML_REGEXP_LETTER;
+	}
+    } else if (cur == 'M') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'n') {
+	    NEXT;
+	    /* nonspacing */
+	    type = XML_REGEXP_MARK_NONSPACING;
+	} else if (cur == 'c') {
+	    NEXT;
+	    /* spacing combining */
+	    type = XML_REGEXP_MARK_SPACECOMBINING;
+	} else if (cur == 'e') {
+	    NEXT;
+	    /* enclosing */
+	    type = XML_REGEXP_MARK_ENCLOSING;
+	} else {
+	    /* all marks */
+	    type = XML_REGEXP_MARK;
+	}
+    } else if (cur == 'N') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'd') {
+	    NEXT;
+	    /* digital */
+	    type = XML_REGEXP_NUMBER_DECIMAL;
+	} else if (cur == 'l') {
+	    NEXT;
+	    /* letter */
+	    type = XML_REGEXP_NUMBER_LETTER;
+	} else if (cur == 'o') {
+	    NEXT;
+	    /* other */
+	    type = XML_REGEXP_NUMBER_OTHERS;
+	} else {
+	    /* all numbers */
+	    type = XML_REGEXP_NUMBER;
+	}
+    } else if (cur == 'P') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'c') {
+	    NEXT;
+	    /* connector */
+	    type = XML_REGEXP_PUNCT_CONNECTOR;
+	} else if (cur == 'd') {
+	    NEXT;
+	    /* dash */
+	    type = XML_REGEXP_PUNCT_DASH;
+	} else if (cur == 's') {
+	    NEXT;
+	    /* open */
+	    type = XML_REGEXP_PUNCT_OPEN;
+	} else if (cur == 'e') {
+	    NEXT;
+	    /* close */
+	    type = XML_REGEXP_PUNCT_CLOSE;
+	} else if (cur == 'i') {
+	    NEXT;
+	    /* initial quote */
+	    type = XML_REGEXP_PUNCT_INITQUOTE;
+	} else if (cur == 'f') {
+	    NEXT;
+	    /* final quote */
+	    type = XML_REGEXP_PUNCT_FINQUOTE;
+	} else if (cur == 'o') {
+	    NEXT;
+	    /* other */
+	    type = XML_REGEXP_PUNCT_OTHERS;
+	} else {
+	    /* all punctuation */
+	    type = XML_REGEXP_PUNCT;
+	}
+    } else if (cur == 'Z') {
+	NEXT;
+	cur = CUR;
+	if (cur == 's') {
+	    NEXT;
+	    /* space */
+	    type = XML_REGEXP_SEPAR_SPACE;
+	} else if (cur == 'l') {
+	    NEXT;
+	    /* line */
+	    type = XML_REGEXP_SEPAR_LINE;
+	} else if (cur == 'p') {
+	    NEXT;
+	    /* paragraph */
+	    type = XML_REGEXP_SEPAR_PARA;
+	} else {
+	    /* all separators */
+	    type = XML_REGEXP_SEPAR;
+	}
+    } else if (cur == 'S') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'm') {
+	    NEXT;
+	    type = XML_REGEXP_SYMBOL_MATH;
+	    /* math */
+	} else if (cur == 'c') {
+	    NEXT;
+	    type = XML_REGEXP_SYMBOL_CURRENCY;
+	    /* currency */
+	} else if (cur == 'k') {
+	    NEXT;
+	    type = XML_REGEXP_SYMBOL_MODIFIER;
+	    /* modifiers */
+	} else if (cur == 'o') {
+	    NEXT;
+	    type = XML_REGEXP_SYMBOL_OTHERS;
+	    /* other */
+	} else {
+	    /* all symbols */
+	    type = XML_REGEXP_SYMBOL;
+	}
+    } else if (cur == 'C') {
+	NEXT;
+	cur = CUR;
+	if (cur == 'c') {
+	    NEXT;
+	    /* control */
+	    type = XML_REGEXP_OTHER_CONTROL;
+	} else if (cur == 'f') {
+	    NEXT;
+	    /* format */
+	    type = XML_REGEXP_OTHER_FORMAT;
+	} else if (cur == 'o') {
+	    NEXT;
+	    /* private use */
+	    type = XML_REGEXP_OTHER_PRIVATE;
+	} else if (cur == 'n') {
+	    NEXT;
+	    /* not assigned */
+	    type = XML_REGEXP_OTHER_NA;
+	} else {
+	    /* all others */
+	    type = XML_REGEXP_OTHER;
+	}
+    } else if (cur == 'I') {
+	const xmlChar *start;
+	NEXT;
+	cur = CUR;
+	if (cur != 's') {
+	    ERROR("IsXXXX expected");
+	    return;
+	}
+	NEXT;
+	start = ctxt->cur;
+	cur = CUR;
+	if (((cur >= 'a') && (cur <= 'z')) || 
+	    ((cur >= 'A') && (cur <= 'Z')) || 
+	    ((cur >= '0') && (cur <= '9')) || 
+	    (cur == 0x2D)) {
+	    NEXT;
+	    cur = CUR;
+	    while (((cur >= 'a') && (cur <= 'z')) || 
+		((cur >= 'A') && (cur <= 'Z')) || 
+		((cur >= '0') && (cur <= '9')) || 
+		(cur == 0x2D)) {
+		NEXT;
+		cur = CUR;
+	    }
+	}
+	type = XML_REGEXP_BLOCK_NAME;
+	blockName = xmlStrndup(start, ctxt->cur - start);
+    } else {
+	ERROR("Unknown char property");
+	return;
+    }
+    if (ctxt->atom == NULL) {
+	ctxt->atom = xmlRegNewAtom(ctxt, type);
+	if (ctxt->atom != NULL)
+	    ctxt->atom->valuep = blockName;
+    } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
+        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+		           type, 0, 0, blockName);
+    }
+}
+
+/**
+ * xmlFAParseCharClassEsc:
+ * @ctxt:  a regexp parser context
+ *
+ * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc ) 
+ * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]
+ * [25] catEsc   ::=   '\p{' charProp '}'
+ * [26] complEsc ::=   '\P{' charProp '}'
+ * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW])
+ */
+static void
+xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
+    int cur;
+
+    if (CUR == '.') {
+	if (ctxt->atom == NULL) {
+	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR);
+	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
+	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+			       XML_REGEXP_ANYCHAR, 0, 0, NULL);
+	}
+	NEXT;
+	return;
+    }
+    if (CUR != '\\') {
+	ERROR("Escaped sequence: expecting \\");
+	return;
+    }
+    NEXT;
+    cur = CUR;
+    if (cur == 'p') {
+	NEXT;
+	if (CUR != '{') {
+	    ERROR("Expecting '{'");
+	    return;
+	}
+	NEXT;
+	xmlFAParseCharProp(ctxt);
+	if (CUR != '}') {
+	    ERROR("Expecting '}'");
+	    return;
+	}
+	NEXT;
+    } else if (cur == 'P') {
+	NEXT;
+	if (CUR != '{') {
+	    ERROR("Expecting '{'");
+	    return;
+	}
+	NEXT;
+	xmlFAParseCharProp(ctxt);
+	ctxt->atom->neg = 1;
+	if (CUR != '}') {
+	    ERROR("Expecting '}'");
+	    return;
+	}
+	NEXT;
+    } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') ||
+	(cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') ||
+	(cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') ||
+	(cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) ||
+	(cur == 0x5E)) {
+	if (ctxt->atom == NULL) {
+	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
+	    if (ctxt->atom != NULL) {
+	        switch (cur) {
+		    case 'n':
+		        ctxt->atom->codepoint = '\n';
+			break;
+		    case 'r':
+		        ctxt->atom->codepoint = '\r';
+			break;
+		    case 't':
+		        ctxt->atom->codepoint = '\t';
+			break;
+		    default:
+			ctxt->atom->codepoint = cur;
+		}
+	    }
+	} 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);
+	}
+	NEXT;
+    } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') ||
+	(cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') ||
+	(cur == 'w') || (cur == 'W')) {
+	xmlRegAtomType type = XML_REGEXP_ANYSPACE;
+
+	switch (cur) {
+	    case 's': 
+		type = XML_REGEXP_ANYSPACE;
+		break;
+	    case 'S': 
+		type = XML_REGEXP_NOTSPACE;
+		break;
+	    case 'i': 
+		type = XML_REGEXP_INITNAME;
+		break;
+	    case 'I': 
+		type = XML_REGEXP_NOTINITNAME;
+		break;
+	    case 'c': 
+		type = XML_REGEXP_NAMECHAR;
+		break;
+	    case 'C': 
+		type = XML_REGEXP_NOTNAMECHAR;
+		break;
+	    case 'd': 
+		type = XML_REGEXP_DECIMAL;
+		break;
+	    case 'D': 
+		type = XML_REGEXP_NOTDECIMAL;
+		break;
+	    case 'w': 
+		type = XML_REGEXP_REALCHAR;
+		break;
+	    case 'W': 
+		type = XML_REGEXP_NOTREALCHAR;
+		break;
+	}
+	NEXT;
+	if (ctxt->atom == NULL) {
+	    ctxt->atom = xmlRegNewAtom(ctxt, type);
+	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
+	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+			       type, 0, 0, NULL);
+	}
+    } else {
+	ERROR("Wrong escape sequence, misuse of character '\\'");
+    }
+}
+
+/**
+ * xmlFAParseCharRange:
+ * @ctxt:  a regexp parser context
+ *
+ * [17]   charRange   ::=     seRange | XmlCharRef | XmlCharIncDash 
+ * [18]   seRange   ::=   charOrEsc '-' charOrEsc
+ * [20]   charOrEsc   ::=   XmlChar | SingleCharEsc
+ * [21]   XmlChar   ::=   [^\#x2D#x5B#x5D]
+ * [22]   XmlCharIncDash   ::=   [^\#x5B#x5D]
+ */
+static void
+xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
+    int cur, len;
+    int start = -1;
+    int end = -1;
+
+    if (CUR == '\0') {
+        ERROR("Expecting ']'");
+	return;
+    }
+
+    cur = CUR;
+    if (cur == '\\') {
+	NEXT;
+	cur = CUR;
+	switch (cur) {
+	    case 'n': start = 0xA; break;
+	    case 'r': start = 0xD; break;
+	    case 't': start = 0x9; break;
+	    case '\\': case '|': case '.': case '-': case '^': case '?':
+	    case '*': case '+': case '{': case '}': case '(': case ')':
+	    case '[': case ']':
+		start = cur; break;
+	    default:
+		ERROR("Invalid escape value");
+		return;
+	}
+	end = start;
+        len = 1;
+    } else if ((cur != 0x5B) && (cur != 0x5D)) {
+        end = start = CUR_SCHAR(ctxt->cur, len);
+    } else {
+	ERROR("Expecting a char range");
+	return;
+    }
+    /*
+     * Since we are "inside" a range, we can assume ctxt->cur is past
+     * the start of ctxt->string, and PREV should be safe
+     */
+    if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) {
+	NEXTL(len);
+	return;
+    }
+    NEXTL(len);
+    cur = CUR;
+    if ((cur != '-') || (NXT(1) == ']')) {
+        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+		              XML_REGEXP_CHARVAL, start, end, NULL);
+	return;
+    }
+    NEXT;
+    cur = CUR;
+    if (cur == '\\') {
+	NEXT;
+	cur = CUR;
+	switch (cur) {
+	    case 'n': end = 0xA; break;
+	    case 'r': end = 0xD; break;
+	    case 't': end = 0x9; break;
+	    case '\\': case '|': case '.': case '-': case '^': case '?':
+	    case '*': case '+': case '{': case '}': case '(': case ')':
+	    case '[': case ']':
+		end = cur; break;
+	    default:
+		ERROR("Invalid escape value");
+		return;
+	}
+        len = 1;
+    } else if ((cur != 0x5B) && (cur != 0x5D)) {
+        end = CUR_SCHAR(ctxt->cur, len);
+    } else {
+	ERROR("Expecting the end of a char range");
+	return;
+    }
+    NEXTL(len);
+    /* TODO check that the values are acceptable character ranges for XML */
+    if (end < start) {
+	ERROR("End of range is before start of range");
+    } else {
+        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
+		           XML_REGEXP_CHARVAL, start, end, NULL);
+    }
+    return;
+}
+
+/**
+ * xmlFAParsePosCharGroup:
+ * @ctxt:  a regexp parser context
+ *
+ * [14]   posCharGroup ::= ( charRange | charClassEsc  )+
+ */
+static void
+xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) {
+    do {
+	if (CUR == '\\') {
+	    xmlFAParseCharClassEsc(ctxt);
+	} else {
+	    xmlFAParseCharRange(ctxt);
+	}
+    } while ((CUR != ']') && (CUR != '^') && (CUR != '-') &&
+             (CUR != 0) && (ctxt->error == 0));
+}
+
+/**
+ * xmlFAParseCharGroup:
+ * @ctxt:  a regexp parser context
+ *
+ * [13]   charGroup    ::= posCharGroup | negCharGroup | charClassSub
+ * [15]   negCharGroup ::= '^' posCharGroup
+ * [16]   charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr  
+ * [12]   charClassExpr ::= '[' charGroup ']'
+ */
+static void
+xmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) {
+    int n = ctxt->neg;
+    while ((CUR != ']') && (ctxt->error == 0)) {
+	if (CUR == '^') {
+	    int neg = ctxt->neg;
+
+	    NEXT;
+	    ctxt->neg = !ctxt->neg;
+	    xmlFAParsePosCharGroup(ctxt);
+	    ctxt->neg = neg;
+	} else if ((CUR == '-') && (NXT(1) == '[')) {
+	    int neg = ctxt->neg;
+	    ctxt->neg = 2;
+	    NEXT;	/* eat the '-' */
+	    NEXT;	/* eat the '[' */
+	    xmlFAParseCharGroup(ctxt);
+	    if (CUR == ']') {
+		NEXT;
+	    } else {
+		ERROR("charClassExpr: ']' expected");
+		break;
+	    }
+	    ctxt->neg = neg;
+	    break;
+	} else if (CUR != ']') {
+	    xmlFAParsePosCharGroup(ctxt);
+	}
+    }
+    ctxt->neg = n;
+}
+
+/**
+ * xmlFAParseCharClass:
+ * @ctxt:  a regexp parser context
+ *
+ * [11]   charClass   ::=     charClassEsc | charClassExpr
+ * [12]   charClassExpr   ::=   '[' charGroup ']'
+ */
+static void
+xmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) {
+    if (CUR == '[') {
+	NEXT;
+	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES);
+	if (ctxt->atom == NULL)
+	    return;
+	xmlFAParseCharGroup(ctxt);
+	if (CUR == ']') {
+	    NEXT;
+	} else {
+	    ERROR("xmlFAParseCharClass: ']' expected");
+	}
+    } else {
+	xmlFAParseCharClassEsc(ctxt);
+    }
+}
+
+/**
+ * xmlFAParseQuantExact:
+ * @ctxt:  a regexp parser context
+ *
+ * [8]   QuantExact   ::=   [0-9]+
+ *
+ * Returns 0 if success or -1 in case of error
+ */
+static int
+xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) {
+    int ret = 0;
+    int ok = 0;
+
+    while ((CUR >= '0') && (CUR <= '9')) {
+	ret = ret * 10 + (CUR - '0');
+	ok = 1;
+	NEXT;
+    }
+    if (ok != 1) {
+	return(-1);
+    }
+    return(ret);
+}
+
+/**
+ * xmlFAParseQuantifier:
+ * @ctxt:  a regexp parser context
+ *
+ * [4]   quantifier   ::=   [?*+] | ( '{' quantity '}' )
+ * [5]   quantity   ::=   quantRange | quantMin | QuantExact
+ * [6]   quantRange   ::=   QuantExact ',' QuantExact
+ * [7]   quantMin   ::=   QuantExact ','
+ * [8]   QuantExact   ::=   [0-9]+
+ */
+static int
+xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) {
+    int cur;
+
+    cur = CUR;
+    if ((cur == '?') || (cur == '*') || (cur == '+')) {
+	if (ctxt->atom != NULL) {
+	    if (cur == '?')
+		ctxt->atom->quant = XML_REGEXP_QUANT_OPT;
+	    else if (cur == '*')
+		ctxt->atom->quant = XML_REGEXP_QUANT_MULT;
+	    else if (cur == '+')
+		ctxt->atom->quant = XML_REGEXP_QUANT_PLUS;
+	}
+	NEXT;
+	return(1);
+    }
+    if (cur == '{') {
+	int min = 0, max = 0;
+
+	NEXT;
+	cur = xmlFAParseQuantExact(ctxt);
+	if (cur >= 0)
+	    min = cur;
+	if (CUR == ',') {
+	    NEXT;
+	    if (CUR == '}')
+	        max = INT_MAX;
+	    else {
+	        cur = xmlFAParseQuantExact(ctxt);
+	        if (cur >= 0)
+		    max = cur;
+		else {
+		    ERROR("Improper quantifier");
+		}
+	    }
+	}
+	if (CUR == '}') {
+	    NEXT;
+	} else {
+	    ERROR("Unterminated quantifier");
+	}
+	if (max == 0)
+	    max = min;
+	if (ctxt->atom != NULL) {
+	    ctxt->atom->quant = XML_REGEXP_QUANT_RANGE;
+	    ctxt->atom->min = min;
+	    ctxt->atom->max = max;
+	}
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlFAParseAtom:
+ * @ctxt:  a regexp parser context
+ *
+ * [9]   atom   ::=   Char | charClass | ( '(' regExp ')' )
+ */
+static int
+xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
+    int codepoint, len;
+
+    codepoint = xmlFAIsChar(ctxt);
+    if (codepoint > 0) {
+	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
+	if (ctxt->atom == NULL)
+	    return(-1);
+	codepoint = CUR_SCHAR(ctxt->cur, len);
+	ctxt->atom->codepoint = codepoint;
+	NEXTL(len);
+	return(1);
+    } else if (CUR == '|') {
+	return(0);
+    } else if (CUR == 0) {
+	return(0);
+    } else if (CUR == ')') {
+	return(0);
+    } else if (CUR == '(') {
+	xmlRegStatePtr start, oldend, start0;
+
+	NEXT;
+	/*
+	 * this extra Epsilon transition is needed if we count with 0 allowed
+	 * unfortunately this can't be known at that point
+	 */
+	xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
+	start0 = ctxt->state;
+	xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
+	start = ctxt->state;
+	oldend = ctxt->end;
+	ctxt->end = NULL;
+	ctxt->atom = NULL;
+	xmlFAParseRegExp(ctxt, 0);
+	if (CUR == ')') {
+	    NEXT;
+	} else {
+	    ERROR("xmlFAParseAtom: expecting ')'");
+	}
+	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG);
+	if (ctxt->atom == NULL)
+	    return(-1);
+	ctxt->atom->start = start;
+	ctxt->atom->start0 = start0;
+	ctxt->atom->stop = ctxt->state;
+	ctxt->end = oldend;
+	return(1);
+    } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) {
+	xmlFAParseCharClass(ctxt);
+	return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlFAParsePiece:
+ * @ctxt:  a regexp parser context
+ *
+ * [3]   piece   ::=   atom quantifier?
+ */
+static int
+xmlFAParsePiece(xmlRegParserCtxtPtr ctxt) {
+    int ret;
+
+    ctxt->atom = NULL;
+    ret = xmlFAParseAtom(ctxt);
+    if (ret == 0)
+	return(0);
+    if (ctxt->atom == NULL) {
+	ERROR("internal: no atom generated");
+    }
+    xmlFAParseQuantifier(ctxt);
+    return(1);
+}
+
+/**
+ * xmlFAParseBranch:
+ * @ctxt:  a regexp parser context
+ * @to: optional target to the end of the branch
+ *
+ * @to is used to optimize by removing duplicate path in automata
+ * in expressions like (a|b)(c|d)
+ *
+ * [2]   branch   ::=   piece*
+ */
+static int
+xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
+    xmlRegStatePtr previous;
+    int ret;
+
+    previous = ctxt->state;
+    ret = xmlFAParsePiece(ctxt);
+    if (ret != 0) {
+	if (xmlFAGenerateTransitions(ctxt, previous, 
+	        (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
+	    return(-1);
+	previous = ctxt->state;
+	ctxt->atom = NULL;
+    }
+    while ((ret != 0) && (ctxt->error == 0)) {
+	ret = xmlFAParsePiece(ctxt);
+	if (ret != 0) {
+	    if (xmlFAGenerateTransitions(ctxt, previous, 
+	            (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
+		    return(-1);
+	    previous = ctxt->state;
+	    ctxt->atom = NULL;
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlFAParseRegExp:
+ * @ctxt:  a regexp parser context
+ * @top:  is this the top-level expression ?
+ *
+ * [1]   regExp   ::=     branch  ( '|' branch )*
+ */
+static void
+xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
+    xmlRegStatePtr start, end;
+
+    /* if not top start should have been generated by an epsilon trans */
+    start = ctxt->state;
+    ctxt->end = NULL;
+    xmlFAParseBranch(ctxt, NULL);
+    if (top) {
+#ifdef DEBUG_REGEXP_GRAPH
+	printf("State %d is final\n", ctxt->state->no);
+#endif
+	ctxt->state->type = XML_REGEXP_FINAL_STATE;
+    }
+    if (CUR != '|') {
+	ctxt->end = ctxt->state;
+	return;
+    }
+    end = ctxt->state;
+    while ((CUR == '|') && (ctxt->error == 0)) {
+	NEXT;
+	ctxt->state = start;
+	ctxt->end = NULL;
+	xmlFAParseBranch(ctxt, end);
+    }
+    if (!top) {
+	ctxt->state = end;
+	ctxt->end = end;
+    }
+}
+
+/************************************************************************
+ * 									*
+ * 			The basic API					*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlRegexpPrint:
+ * @output: the file for the output debug
+ * @regexp: the compiled regexp
+ *
+ * Print the content of the compiled regular expression
+ */
+void
+xmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) {
+    int i;
+
+    if (output == NULL)
+        return;
+    fprintf(output, " regexp: ");
+    if (regexp == NULL) {
+	fprintf(output, "NULL\n");
+	return;
+    }
+    fprintf(output, "'%s' ", regexp->string);
+    fprintf(output, "\n");
+    fprintf(output, "%d atoms:\n", regexp->nbAtoms);
+    for (i = 0;i < regexp->nbAtoms; i++) {
+	fprintf(output, " %02d ", i);
+	xmlRegPrintAtom(output, regexp->atoms[i]);
+    }
+    fprintf(output, "%d states:", regexp->nbStates);
+    fprintf(output, "\n");
+    for (i = 0;i < regexp->nbStates; i++) {
+	xmlRegPrintState(output, regexp->states[i]);
+    }
+    fprintf(output, "%d counters:\n", regexp->nbCounters);
+    for (i = 0;i < regexp->nbCounters; i++) {
+	fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min,
+		                                regexp->counters[i].max);
+    }
+}
+
+/**
+ * xmlRegexpCompile:
+ * @regexp:  a regular expression string
+ *
+ * Parses a regular expression conforming to XML Schemas Part 2 Datatype
+ * Appendix F and builds an automata suitable for testing strings against
+ * that regular expression
+ *
+ * Returns the compiled expression or NULL in case of error
+ */
+xmlRegexpPtr
+xmlRegexpCompile(const xmlChar *regexp) {
+    xmlRegexpPtr ret;
+    xmlRegParserCtxtPtr ctxt;
+
+    ctxt = xmlRegNewParserCtxt(regexp);
+    if (ctxt == NULL)
+	return(NULL);
+
+    /* initialize the parser */
+    ctxt->end = NULL;
+    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
+    xmlRegStatePush(ctxt, ctxt->start);
+
+    /* parse the expression building an automata */
+    xmlFAParseRegExp(ctxt, 1);
+    if (CUR != 0) {
+	ERROR("xmlFAParseRegExp: extra characters");
+    }
+    if (ctxt->error != 0) {
+	xmlRegFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    ctxt->end = ctxt->state;
+    ctxt->start->type = XML_REGEXP_START_STATE;
+    ctxt->end->type = XML_REGEXP_FINAL_STATE;
+
+    /* remove the Epsilon except for counted transitions */
+    xmlFAEliminateEpsilonTransitions(ctxt);
+
+
+    if (ctxt->error != 0) {
+	xmlRegFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    ret = xmlRegEpxFromParse(ctxt);
+    xmlRegFreeParserCtxt(ctxt);
+    return(ret);
+}
+
+/**
+ * xmlRegexpExec:
+ * @comp:  the compiled regular expression
+ * @content:  the value to check against the regular expression
+ *
+ * Check if the regular expression generates the value
+ *
+ * Returns 1 if it matches, 0 if not and a negative value in case of error
+ */
+int
+xmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) {
+    if ((comp == NULL) || (content == NULL))
+	return(-1);
+    return(xmlFARegExec(comp, content));
+}
+
+/**
+ * xmlRegexpIsDeterminist:
+ * @comp:  the compiled regular expression
+ *
+ * Check if the regular expression is determinist
+ *
+ * Returns 1 if it yes, 0 if not and a negative value in case of error
+ */
+int
+xmlRegexpIsDeterminist(xmlRegexpPtr comp) {
+    xmlAutomataPtr am;
+    int ret;
+
+    if (comp == NULL)
+	return(-1);
+    if (comp->determinist != -1)
+	return(comp->determinist);
+
+    am = xmlNewAutomata();
+    if (am->states != NULL) {
+	int i;
+
+	for (i = 0;i < am->nbStates;i++)
+	    xmlRegFreeState(am->states[i]);
+	xmlFree(am->states);
+    }
+    am->nbAtoms = comp->nbAtoms;
+    am->atoms = comp->atoms;
+    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);
+}
+
+/**
+ * xmlRegFreeRegexp:
+ * @regexp:  the regexp
+ *
+ * Free a regexp
+ */
+void
+xmlRegFreeRegexp(xmlRegexpPtr regexp) {
+    int i;
+    if (regexp == NULL)
+	return;
+
+    if (regexp->string != NULL)
+	xmlFree(regexp->string);
+    if (regexp->states != NULL) {
+	for (i = 0;i < regexp->nbStates;i++)
+	    xmlRegFreeState(regexp->states[i]);
+	xmlFree(regexp->states);
+    }
+    if (regexp->atoms != NULL) {
+	for (i = 0;i < regexp->nbAtoms;i++)
+	    xmlRegFreeAtom(regexp->atoms[i]);
+	xmlFree(regexp->atoms);
+    }
+    if (regexp->counters != NULL)
+	xmlFree(regexp->counters);
+    if (regexp->compact != NULL)
+	xmlFree(regexp->compact);
+    if (regexp->transdata != NULL)
+	xmlFree(regexp->transdata);
+    if (regexp->stringMap != NULL) {
+	for (i = 0; i < regexp->nbstrings;i++)
+	    xmlFree(regexp->stringMap[i]);
+	xmlFree(regexp->stringMap);
+    }
+
+    xmlFree(regexp);
+}
+
+#ifdef LIBXML_AUTOMATA_ENABLED
+/************************************************************************
+ * 									*
+ * 			The Automata interface				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlNewAutomata:
+ *
+ * Create a new automata
+ *
+ * Returns the new object or NULL in case of failure
+ */
+xmlAutomataPtr
+xmlNewAutomata(void) {
+    xmlAutomataPtr ctxt;
+
+    ctxt = xmlRegNewParserCtxt(NULL);
+    if (ctxt == NULL)
+	return(NULL);
+
+    /* initialize the parser */
+    ctxt->end = NULL;
+    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
+    if (ctxt->start == NULL) {
+	xmlFreeAutomata(ctxt);
+	return(NULL);
+    }
+    ctxt->start->type = XML_REGEXP_START_STATE;
+    if (xmlRegStatePush(ctxt, ctxt->start) < 0) {
+        xmlRegFreeState(ctxt->start);
+	xmlFreeAutomata(ctxt);
+	return(NULL);
+    }
+    ctxt->flags = 0;
+
+    return(ctxt);
+}
+
+/**
+ * xmlFreeAutomata:
+ * @am: an automata
+ *
+ * Free an automata
+ */
+void
+xmlFreeAutomata(xmlAutomataPtr am) {
+    if (am == NULL)
+	return;
+    xmlRegFreeParserCtxt(am);
+}
+
+/**
+ * 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
+ *
+ * Initial state lookup
+ *
+ * Returns the initial state of the automata
+ */
+xmlAutomataStatePtr
+xmlAutomataGetInitState(xmlAutomataPtr am) {
+    if (am == NULL)
+	return(NULL);
+    return(am->start);
+}
+
+/**
+ * xmlAutomataSetFinalState:
+ * @am: an automata
+ * @state: a state in this automata
+ *
+ * Makes that state a final state
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) {
+    if ((am == NULL) || (state == NULL))
+	return(-1);
+    state->type = XML_REGEXP_FINAL_STATE;
+    return(0);
+}
+
+/**
+ * xmlAutomataNewTransition:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the input string associated to that transition
+ * @data: data passed to the callback function if the transition is activated
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by the value of @token
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			 xmlAutomataStatePtr to, const xmlChar *token,
+			 void *data) {
+    xmlRegAtomPtr atom;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+        return(NULL);
+    atom->data = data;
+    if (atom == NULL)
+	return(NULL);
+    atom->valuep = xmlStrdup(token);
+
+    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
+        xmlRegFreeAtom(atom);
+	return(NULL);
+    }
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewTransition2:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the first input string associated to that transition
+ * @token2: the second input string associated to that transition
+ * @data: data passed to the callback function if the transition is activated
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by the value of @token
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			  xmlAutomataStatePtr to, const xmlChar *token,
+			  const xmlChar *token2, void *data) {
+    xmlRegAtomPtr atom;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    atom->data = data;
+    if ((token2 == NULL) || (*token2 == 0)) {
+	atom->valuep = xmlStrdup(token);
+    } else {
+	int lenn, lenp;
+	xmlChar *str;
+
+	lenn = strlen((char *) token2);
+	lenp = strlen((char *) token);
+
+	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (str == NULL) {
+	    xmlRegFreeAtom(atom);
+	    return(NULL);
+	}
+	memcpy(&str[0], token, lenp);
+	str[lenp] = '|';
+	memcpy(&str[lenp + 1], token2, lenn);
+	str[lenn + lenp + 1] = 0;
+
+	atom->valuep = str;
+    }
+
+    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
+        xmlRegFreeAtom(atom);
+	return(NULL);
+    }
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewNegTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the first input string associated to that transition
+ * @token2: the second input string associated to that transition
+ * @data: data passed to the callback function if the transition is activated
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by any value except (@token,@token2)
+ * Note that if @token2 is not NULL, then (X, NULL) won't match to follow
+ # the semantic of XSD ##other
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+		       xmlAutomataStatePtr to, const xmlChar *token,
+		       const xmlChar *token2, void *data) {
+    xmlRegAtomPtr atom;
+    xmlChar err_msg[200];
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    atom->data = data;
+    atom->neg = 1;
+    if ((token2 == NULL) || (*token2 == 0)) {
+	atom->valuep = xmlStrdup(token);
+    } else {
+	int lenn, lenp;
+	xmlChar *str;
+
+	lenn = strlen((char *) token2);
+	lenp = strlen((char *) token);
+
+	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (str == NULL) {
+	    xmlRegFreeAtom(atom);
+	    return(NULL);
+	}
+	memcpy(&str[0], token, lenp);
+	str[lenp] = '|';
+	memcpy(&str[lenp + 1], token2, lenn);
+	str[lenn + lenp + 1] = 0;
+
+	atom->valuep = str;
+    }
+    snprintf((char *) err_msg, 199, "not %s", (const char *) atom->valuep);
+    err_msg[199] = 0;
+    atom->valuep2 = xmlStrdup(err_msg);
+
+    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
+        xmlRegFreeAtom(atom);
+	return(NULL);
+    }
+    am->negs++;
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewCountTrans2:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the input string associated to that transition
+ * @token2: the second input string associated to that transition
+ * @min:  the minimum successive occurences of token
+ * @max:  the maximum successive occurences of token
+ * @data:  data associated to the transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by a succession of input of value @token and @token2 and 
+ * whose number is between @min and @max
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			 xmlAutomataStatePtr to, const xmlChar *token,
+			 const xmlChar *token2,
+			 int min, int max, void *data) {
+    xmlRegAtomPtr atom;
+    int counter;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    if (min < 0)
+	return(NULL);
+    if ((max < min) || (max < 1))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    if ((token2 == NULL) || (*token2 == 0)) {
+	atom->valuep = xmlStrdup(token);
+    } else {
+	int lenn, lenp;
+	xmlChar *str;
+
+	lenn = strlen((char *) token2);
+	lenp = strlen((char *) token);
+
+	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (str == NULL) {
+	    xmlRegFreeAtom(atom);
+	    return(NULL);
+	}
+	memcpy(&str[0], token, lenp);
+	str[lenp] = '|';
+	memcpy(&str[lenp + 1], token2, lenn);
+	str[lenn + lenp + 1] = 0;
+
+	atom->valuep = str;
+    }
+    atom->data = data;
+    if (min == 0)
+	atom->min = 1;
+    else
+	atom->min = min;
+    atom->max = max;
+
+    /*
+     * associate a counter to the transition.
+     */
+    counter = xmlRegGetCounter(am);
+    am->counters[counter].min = min;
+    am->counters[counter].max = max;
+
+    /* xmlFAGenerateTransitions(am, from, to, atom); */
+    if (to == NULL) {
+        to = xmlRegNewState(am);
+	xmlRegStatePush(am, to);
+    }
+    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
+    xmlRegAtomPush(am, atom);
+    am->state = to;
+
+    if (to == NULL)
+	to = am->state;
+    if (to == NULL)
+	return(NULL);
+    if (min == 0)
+	xmlFAGenerateEpsilonTransition(am, from, to);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewCountTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the input string associated to that transition
+ * @min:  the minimum successive occurences of token
+ * @max:  the maximum successive occurences of token
+ * @data:  data associated to the transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by a succession of input of value @token and whose number
+ * is between @min and @max
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			 xmlAutomataStatePtr to, const xmlChar *token,
+			 int min, int max, void *data) {
+    xmlRegAtomPtr atom;
+    int counter;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    if (min < 0)
+	return(NULL);
+    if ((max < min) || (max < 1))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    atom->valuep = xmlStrdup(token);
+    atom->data = data;
+    if (min == 0)
+	atom->min = 1;
+    else
+	atom->min = min;
+    atom->max = max;
+
+    /*
+     * associate a counter to the transition.
+     */
+    counter = xmlRegGetCounter(am);
+    am->counters[counter].min = min;
+    am->counters[counter].max = max;
+
+    /* xmlFAGenerateTransitions(am, from, to, atom); */
+    if (to == NULL) {
+        to = xmlRegNewState(am);
+	xmlRegStatePush(am, to);
+    }
+    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
+    xmlRegAtomPush(am, atom);
+    am->state = to;
+
+    if (to == NULL)
+	to = am->state;
+    if (to == NULL)
+	return(NULL);
+    if (min == 0)
+	xmlFAGenerateEpsilonTransition(am, from, to);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewOnceTrans2:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the input string associated to that transition
+ * @token2: the second input string associated to that transition
+ * @min:  the minimum successive occurences of token
+ * @max:  the maximum successive occurences of token
+ * @data:  data associated to the transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by a succession of input of value @token and @token2 and whose 
+ * number is between @min and @max, moreover that transition can only be 
+ * crossed once.
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			 xmlAutomataStatePtr to, const xmlChar *token,
+			 const xmlChar *token2,
+			 int min, int max, void *data) {
+    xmlRegAtomPtr atom;
+    int counter;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    if (min < 1)
+	return(NULL);
+    if ((max < min) || (max < 1))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    if ((token2 == NULL) || (*token2 == 0)) {
+	atom->valuep = xmlStrdup(token);
+    } else {
+	int lenn, lenp;
+	xmlChar *str;
+
+	lenn = strlen((char *) token2);
+	lenp = strlen((char *) token);
+
+	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
+	if (str == NULL) {
+	    xmlRegFreeAtom(atom);
+	    return(NULL);
+	}
+	memcpy(&str[0], token, lenp);
+	str[lenp] = '|';
+	memcpy(&str[lenp + 1], token2, lenn);
+	str[lenn + lenp + 1] = 0;
+
+	atom->valuep = str;
+    }    
+    atom->data = data;
+    atom->quant = XML_REGEXP_QUANT_ONCEONLY;
+    atom->min = min;
+    atom->max = max;
+    /*
+     * associate a counter to the transition.
+     */
+    counter = xmlRegGetCounter(am);
+    am->counters[counter].min = 1;
+    am->counters[counter].max = 1;
+
+    /* xmlFAGenerateTransitions(am, from, to, atom); */
+    if (to == NULL) {
+	to = xmlRegNewState(am);
+	xmlRegStatePush(am, to);
+    }
+    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
+    xmlRegAtomPush(am, atom);
+    am->state = to;
+    return(to);
+}
+
+    
+
+/**
+ * xmlAutomataNewOnceTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @token: the input string associated to that transition
+ * @min:  the minimum successive occurences of token
+ * @max:  the maximum successive occurences of token
+ * @data:  data associated to the transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a transition from the @from state to the target state
+ * activated by a succession of input of value @token and whose number
+ * is between @min and @max, moreover that transition can only be crossed
+ * once.
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+			 xmlAutomataStatePtr to, const xmlChar *token,
+			 int min, int max, void *data) {
+    xmlRegAtomPtr atom;
+    int counter;
+
+    if ((am == NULL) || (from == NULL) || (token == NULL))
+	return(NULL);
+    if (min < 1)
+	return(NULL);
+    if ((max < min) || (max < 1))
+	return(NULL);
+    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
+    if (atom == NULL)
+	return(NULL);
+    atom->valuep = xmlStrdup(token);
+    atom->data = data;
+    atom->quant = XML_REGEXP_QUANT_ONCEONLY;
+    atom->min = min;
+    atom->max = max;
+    /*
+     * associate a counter to the transition.
+     */
+    counter = xmlRegGetCounter(am);
+    am->counters[counter].min = 1;
+    am->counters[counter].max = 1;
+
+    /* xmlFAGenerateTransitions(am, from, to, atom); */
+    if (to == NULL) {
+	to = xmlRegNewState(am);
+	xmlRegStatePush(am, to);
+    }
+    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
+    xmlRegAtomPush(am, atom);
+    am->state = to;
+    return(to);
+}
+
+/**
+ * xmlAutomataNewState:
+ * @am: an automata
+ *
+ * Create a new disconnected state in the automata
+ *
+ * Returns the new state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewState(xmlAutomataPtr am) {
+    xmlAutomataStatePtr to; 
+
+    if (am == NULL)
+	return(NULL);
+    to = xmlRegNewState(am);
+    xmlRegStatePush(am, to);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewEpsilon:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds an epsilon transition from the @from state to the
+ * target state
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from,
+		      xmlAutomataStatePtr to) {
+    if ((am == NULL) || (from == NULL))
+	return(NULL);
+    xmlFAGenerateEpsilonTransition(am, from, to);
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewAllTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @lax: allow to transition if not all all transitions have been activated
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds a an ALL transition from the @from state to the
+ * target state. That transition is an epsilon transition allowed only when
+ * all transitions from the @from node have been activated.
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+		       xmlAutomataStatePtr to, int lax) {
+    if ((am == NULL) || (from == NULL))
+	return(NULL);
+    xmlFAGenerateAllTransition(am, from, to, lax);
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewCounter:
+ * @am: an automata
+ * @min:  the minimal value on the counter
+ * @max:  the maximal value on the counter
+ *
+ * Create a new counter
+ *
+ * Returns the counter number or -1 in case of error
+ */
+int		
+xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {
+    int ret;
+
+    if (am == NULL)
+	return(-1);
+
+    ret = xmlRegGetCounter(am);
+    if (ret < 0)
+	return(-1);
+    am->counters[ret].min = min;
+    am->counters[ret].max = max;
+    return(ret);
+}
+
+/**
+ * xmlAutomataNewCountedTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @counter: the counter associated to that transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds an epsilon transition from the @from state to the target state
+ * which will increment the counter provided
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+		xmlAutomataStatePtr to, int counter) {
+    if ((am == NULL) || (from == NULL) || (counter < 0))
+	return(NULL);
+    xmlFAGenerateCountedEpsilonTransition(am, from, to, counter);
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataNewCounterTrans:
+ * @am: an automata
+ * @from: the starting point of the transition
+ * @to: the target point of the transition or NULL
+ * @counter: the counter associated to that transition
+ *
+ * If @to is NULL, this creates first a new target state in the automata
+ * and then adds an epsilon transition from the @from state to the target state
+ * which will be allowed only if the counter is within the right range.
+ *
+ * Returns the target state or NULL in case of error
+ */
+xmlAutomataStatePtr
+xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
+		xmlAutomataStatePtr to, int counter) {
+    if ((am == NULL) || (from == NULL) || (counter < 0))
+	return(NULL);
+    xmlFAGenerateCountedTransition(am, from, to, counter);
+    if (to == NULL)
+	return(am->state);
+    return(to);
+}
+
+/**
+ * xmlAutomataCompile:
+ * @am: an automata
+ *
+ * Compile the automata into a Reg Exp ready for being executed.
+ * The automata should be free after this point.
+ *
+ * Returns the compiled regexp or NULL in case of error
+ */
+xmlRegexpPtr          
+xmlAutomataCompile(xmlAutomataPtr am) {
+    xmlRegexpPtr ret;
+
+    if ((am == NULL) || (am->error != 0)) return(NULL);
+    xmlFAEliminateEpsilonTransitions(am);
+    /* xmlFAComputesDeterminism(am); */
+    ret = xmlRegEpxFromParse(am);
+
+    return(ret);
+}
+
+/**
+ * xmlAutomataIsDeterminist:
+ * @am: an automata
+ *
+ * Checks if an automata is determinist.
+ *
+ * Returns 1 if true, 0 if not, and -1 in case of error
+ */
+int          
+xmlAutomataIsDeterminist(xmlAutomataPtr am) {
+    int ret;
+
+    if (am == NULL)
+	return(-1);
+
+    ret = xmlFAComputesDeterminism(am);
+    return(ret);
+}
+#endif /* LIBXML_AUTOMATA_ENABLED */
+
+#ifdef LIBXML_EXPR_ENABLED
+/************************************************************************
+ *									*
+ *		Formal Expression handling code				*
+ *									*
+ ************************************************************************/
+/************************************************************************
+ *									*
+ *		Expression handling context				*
+ *									*
+ ************************************************************************/
+
+struct _xmlExpCtxt {
+    xmlDictPtr dict;
+    xmlExpNodePtr *table;
+    int size;
+    int nbElems;
+    int nb_nodes;
+    int maxNodes;
+    const char *expr;
+    const char *cur;
+    int nb_cons;
+    int tabSize;
+};
+
+/**
+ * xmlExpNewCtxt:
+ * @maxNodes:  the maximum number of nodes
+ * @dict:  optional dictionnary to use internally
+ *
+ * Creates a new context for manipulating expressions
+ *
+ * Returns the context or NULL in case of error
+ */
+xmlExpCtxtPtr
+xmlExpNewCtxt(int maxNodes, xmlDictPtr dict) {
+    xmlExpCtxtPtr ret;
+    int size = 256;
+
+    if (maxNodes <= 4096)
+        maxNodes = 4096;
+    
+    ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt));
+    if (ret == NULL)
+        return(NULL);
+    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);
+	return(NULL);
+    }
+    memset(ret->table, 0, size * sizeof(xmlExpNodePtr));
+    if (dict == NULL) {
+        ret->dict = xmlDictCreate();
+	if (ret->dict == NULL) {
+	    xmlFree(ret->table);
+	    xmlFree(ret);
+	    return(NULL);
+	}
+    } else {
+        ret->dict = dict;
+	xmlDictReference(ret->dict);
+    }
+    return(ret);
+}
+
+/**
+ * xmlExpFreeCtxt:
+ * @ctxt:  an expression context
+ *
+ * Free an expression context
+ */
+void
+xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    xmlDictFree(ctxt->dict);
+    if (ctxt->table != NULL)
+	xmlFree(ctxt->table);
+    xmlFree(ctxt);
+}
+
+/************************************************************************
+ *									*
+ *		Structure associated to an expression node		*
+ *									*
+ ************************************************************************/
+#define MAX_NODES 10000
+
+/* #define DEBUG_DERIV */
+
+/*
+ * TODO: 
+ * - Wildcards
+ * - public API for creation
+ *
+ * Started
+ * - regression testing
+ *
+ * Done
+ * - split into module and test tool
+ * - memleaks
+ */
+
+typedef enum {
+    XML_EXP_NILABLE = (1 << 0)
+} xmlExpNodeInfo;
+
+#define IS_NILLABLE(node) ((node)->info & XML_EXP_NILABLE)
+
+struct _xmlExpNode {
+    unsigned char type;/* xmlExpNodeType */
+    unsigned char info;/* OR of xmlExpNodeInfo */
+    unsigned short key;	/* the hash key */
+    unsigned int ref;	/* The number of references */
+    int c_max;		/* the maximum length it can consume */
+    xmlExpNodePtr exp_left;
+    xmlExpNodePtr next;/* the next node in the hash table or free list */
+    union {
+	struct {
+	    int f_min;
+	    int f_max;
+	} count;
+	struct {
+	    xmlExpNodePtr f_right;
+	} children;
+        const xmlChar *f_str;
+    } field;
+};
+
+#define exp_min field.count.f_min
+#define exp_max field.count.f_max
+/* #define exp_left field.children.f_left */
+#define exp_right field.children.f_right
+#define exp_str field.f_str
+
+static xmlExpNodePtr xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type);
+static xmlExpNode forbiddenExpNode = {
+    XML_EXP_FORBID, 0, 0, 0, 0, NULL, NULL, {{ 0, 0}}
+};
+xmlExpNodePtr forbiddenExp = &forbiddenExpNode;
+static xmlExpNode emptyExpNode = {
+    XML_EXP_EMPTY, 1, 0, 0, 0, NULL, NULL, {{ 0, 0}}
+};
+xmlExpNodePtr emptyExp = &emptyExpNode;
+
+/************************************************************************
+ *									*
+ *  The custom hash table for unicity and canonicalization		*
+ *  of sub-expressions pointers						*
+ *									*
+ ************************************************************************/
+/*
+ * xmlExpHashNameComputeKey:
+ * Calculate the hash key for a token
+ */
+static unsigned short
+xmlExpHashNameComputeKey(const xmlChar *name) {
+    unsigned short value = 0L;
+    char ch;
+    
+    if (name != NULL) {
+	value += 30 * (*name);
+	while ((ch = *name++) != 0) {
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch);
+	}
+    }
+    return (value);
+}
+
+/*
+ * xmlExpHashComputeKey:
+ * Calculate the hash key for a compound expression
+ */
+static unsigned short
+xmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePtr left,
+                     xmlExpNodePtr right) {
+    unsigned long value;
+    unsigned short ret;
+    
+    switch (type) {
+        case XML_EXP_SEQ:
+	    value = left->key;
+	    value += right->key;
+	    value *= 3;
+	    ret = (unsigned short) value;
+	    break;
+        case XML_EXP_OR:
+	    value = left->key;
+	    value += right->key;
+	    value *= 7;
+	    ret = (unsigned short) value;
+	    break;
+        case XML_EXP_COUNT:
+	    value = left->key;
+	    value += right->key;
+	    ret = (unsigned short) value;
+	    break;
+	default:
+	    ret = 0;
+    }
+    return(ret);
+}
+
+
+static xmlExpNodePtr
+xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type) {
+    xmlExpNodePtr ret;
+
+    if (ctxt->nb_nodes >= MAX_NODES)
+        return(NULL);
+    ret = (xmlExpNodePtr) xmlMalloc(sizeof(xmlExpNode));
+    if (ret == NULL)
+        return(NULL);
+    memset(ret, 0, sizeof(xmlExpNode));
+    ret->type = type;
+    ret->next = NULL;
+    ctxt->nb_nodes++;
+    ctxt->nb_cons++;
+    return(ret);
+}
+
+/**
+ * xmlExpHashGetEntry:
+ * @table: the hash table
+ *
+ * Get the unique entry from the hash table. The entry is created if
+ * needed. @left and @right are consumed, i.e. their ref count will
+ * be decremented by the operation.
+ *
+ * Returns the pointer or NULL in case of error
+ */
+static xmlExpNodePtr
+xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType type,
+                   xmlExpNodePtr left, xmlExpNodePtr right,
+		   const xmlChar *name, int min, int max) {
+    unsigned short kbase, key;
+    xmlExpNodePtr entry;
+    xmlExpNodePtr insert;
+
+    if (ctxt == NULL)
+	return(NULL);
+
+    /*
+     * Check for duplicate and insertion location.
+     */
+    if (type == XML_EXP_ATOM) {
+	kbase = xmlExpHashNameComputeKey(name);
+    } else if (type == XML_EXP_COUNT) {
+        /* COUNT reduction rule 1 */
+	/* a{1} -> a */
+	if (min == max) {
+	    if (min == 1) {
+		return(left);
+	    }
+	    if (min == 0) {
+		xmlExpFree(ctxt, left);
+	        return(emptyExp);
+	    }
+	}
+	if (min < 0) {
+	    xmlExpFree(ctxt, left);
+	    return(forbiddenExp);
+	}
+        if (max == -1)
+	    kbase = min + 79;
+	else
+	    kbase = max - min;
+	kbase += left->key;
+    } else if (type == XML_EXP_OR) {
+        /* Forbid reduction rules */
+        if (left->type == XML_EXP_FORBID) {
+	    xmlExpFree(ctxt, left);
+	    return(right);
+	}
+        if (right->type == XML_EXP_FORBID) {
+	    xmlExpFree(ctxt, right);
+	    return(left);
+	}
+
+        /* OR reduction rule 1 */
+	/* a | a reduced to a */
+        if (left == right) {
+	    left->ref--;
+	    return(left);
+	}
+        /* OR canonicalization rule 1 */
+	/* linearize (a | b) | c into a | (b | c) */
+        if ((left->type == XML_EXP_OR) && (right->type != XML_EXP_OR)) {
+	    xmlExpNodePtr tmp = left;
+            left = right;
+	    right = tmp;
+	}
+        /* OR reduction rule 2 */
+	/* a | (a | b) and b | (a | b) are reduced to a | b */
+        if (right->type == XML_EXP_OR) {
+	    if ((left == right->exp_left) ||
+	        (left == right->exp_right)) {
+		xmlExpFree(ctxt, left);
+		return(right);
+	    }
+	}
+        /* OR canonicalization rule 2 */
+	/* linearize (a | b) | c into a | (b | c) */
+        if (left->type == XML_EXP_OR) {
+	    xmlExpNodePtr tmp;
+
+	    /* OR canonicalization rule 2 */
+	    if ((left->exp_right->type != XML_EXP_OR) &&
+	        (left->exp_right->key < left->exp_left->key)) {
+	        tmp = left->exp_right;
+		left->exp_right = left->exp_left;
+		left->exp_left = tmp;
+	    }
+	    left->exp_right->ref++;
+	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_right, right,
+	                             NULL, 0, 0);
+	    left->exp_left->ref++;
+	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp,
+	                             NULL, 0, 0);
+	
+	    xmlExpFree(ctxt, left);
+	    return(tmp);
+	}
+	if (right->type == XML_EXP_OR) {
+	    /* Ordering in the tree */
+	    /* C | (A | B) -> A | (B | C) */
+	    if (left->key > right->exp_right->key) {
+		xmlExpNodePtr tmp;
+		right->exp_right->ref++;
+		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_right,
+		                         left, NULL, 0, 0);
+		right->exp_left->ref++;
+		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left,
+		                         tmp, NULL, 0, 0);
+		xmlExpFree(ctxt, right);
+		return(tmp);
+	    }
+	    /* Ordering in the tree */
+	    /* B | (A | C) -> A | (B | C) */
+	    if (left->key > right->exp_left->key) {
+		xmlExpNodePtr tmp;
+		right->exp_right->ref++;
+		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left,
+		                         right->exp_right, NULL, 0, 0);
+		right->exp_left->ref++;
+		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left,
+		                         tmp, NULL, 0, 0);
+		xmlExpFree(ctxt, right);
+		return(tmp);
+	    }
+	}
+	/* we know both types are != XML_EXP_OR here */
+        else if (left->key > right->key) {
+	    xmlExpNodePtr tmp = left;
+            left = right;
+	    right = tmp;
+	}
+	kbase = xmlExpHashComputeKey(type, left, right);
+    } else if (type == XML_EXP_SEQ) {
+        /* Forbid reduction rules */
+        if (left->type == XML_EXP_FORBID) {
+	    xmlExpFree(ctxt, right);
+	    return(left);
+	}
+        if (right->type == XML_EXP_FORBID) {
+	    xmlExpFree(ctxt, left);
+	    return(right);
+	}
+        /* Empty reduction rules */
+        if (right->type == XML_EXP_EMPTY) {
+	    return(left);
+	}
+        if (left->type == XML_EXP_EMPTY) {
+	    return(right);
+	}
+	kbase = xmlExpHashComputeKey(type, left, right);
+    } else 
+        return(NULL);
+
+    key = kbase % ctxt->size;
+    if (ctxt->table[key] != NULL) {
+	for (insert = ctxt->table[key]; insert != NULL;
+	     insert = insert->next) {
+	    if ((insert->key == kbase) &&
+	        (insert->type == type)) {
+		if (type == XML_EXP_ATOM) {
+		    if (name == insert->exp_str) {
+			insert->ref++;
+			return(insert);
+		    }
+		} else if (type == XML_EXP_COUNT) {
+		    if ((insert->exp_min == min) && (insert->exp_max == max) &&
+		        (insert->exp_left == left)) {
+			insert->ref++;
+			left->ref--;
+			return(insert);
+		    }
+		} else if ((insert->exp_left == left) &&
+			   (insert->exp_right == right)) {
+		    insert->ref++;
+		    left->ref--;
+		    right->ref--;
+		    return(insert);
+		}
+	    }
+	}
+    }
+
+    entry = xmlExpNewNode(ctxt, type);
+    if (entry == NULL)
+        return(NULL);
+    entry->key = kbase;
+    if (type == XML_EXP_ATOM) {
+	entry->exp_str = name;
+	entry->c_max = 1;
+    } else if (type == XML_EXP_COUNT) {
+        entry->exp_min = min;
+        entry->exp_max = max;
+	entry->exp_left = left;
+	if ((min == 0) || (IS_NILLABLE(left)))
+	    entry->info |= XML_EXP_NILABLE;
+	if (max < 0)
+	    entry->c_max = -1;
+	else
+	    entry->c_max = max * entry->exp_left->c_max;
+    } else {
+	entry->exp_left = left;
+	entry->exp_right = right;
+	if (type == XML_EXP_OR) {
+	    if ((IS_NILLABLE(left)) || (IS_NILLABLE(right)))
+		entry->info |= XML_EXP_NILABLE;
+	    if ((entry->exp_left->c_max == -1) ||
+	        (entry->exp_right->c_max == -1))
+		entry->c_max = -1;
+	    else if (entry->exp_left->c_max > entry->exp_right->c_max)
+	        entry->c_max = entry->exp_left->c_max;
+	    else
+	        entry->c_max = entry->exp_right->c_max;
+	} else {
+	    if ((IS_NILLABLE(left)) && (IS_NILLABLE(right)))
+		entry->info |= XML_EXP_NILABLE;
+	    if ((entry->exp_left->c_max == -1) ||
+	        (entry->exp_right->c_max == -1))
+		entry->c_max = -1;
+	    else
+	        entry->c_max = entry->exp_left->c_max + entry->exp_right->c_max;
+	}
+    }
+    entry->ref = 1;
+    if (ctxt->table[key] != NULL)
+        entry->next = ctxt->table[key];
+
+    ctxt->table[key] = entry;
+    ctxt->nbElems++;
+
+    return(entry);
+}
+
+/**
+ * xmlExpFree:
+ * @ctxt: the expression context
+ * @exp: the expression
+ *
+ * Dereference the expression
+ */
+void
+xmlExpFree(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp) {
+    if ((exp == NULL) || (exp == forbiddenExp) || (exp == emptyExp))
+        return;
+    exp->ref--;
+    if (exp->ref == 0) {
+        unsigned short key;
+
+        /* Unlink it first from the hash table */
+	key = exp->key % ctxt->size;
+	if (ctxt->table[key] == exp) {
+	    ctxt->table[key] = exp->next;
+	} else {
+	    xmlExpNodePtr tmp;
+
+	    tmp = ctxt->table[key];
+	    while (tmp != NULL) {
+	        if (tmp->next == exp) {
+		    tmp->next = exp->next;
+		    break;
+		}
+	        tmp = tmp->next;
+	    }
+	}
+
+        if ((exp->type == XML_EXP_SEQ) || (exp->type == XML_EXP_OR)) {
+	    xmlExpFree(ctxt, exp->exp_left);
+	    xmlExpFree(ctxt, exp->exp_right);
+	} else if (exp->type == XML_EXP_COUNT) {
+	    xmlExpFree(ctxt, exp->exp_left);
+	}
+        xmlFree(exp);
+	ctxt->nb_nodes--;
+    }
+}
+
+/**
+ * xmlExpRef:
+ * @exp: the expression
+ *
+ * Increase the reference count of the expression
+ */
+void
+xmlExpRef(xmlExpNodePtr exp) {
+    if (exp != NULL)
+        exp->ref++;
+}
+
+/**
+ * xmlExpNewAtom:
+ * @ctxt: the expression context
+ * @name: the atom name
+ * @len: the atom name lenght in byte (or -1);
+ *
+ * Get the atom associated to this name from that context
+ *
+ * Returns the node or NULL in case of error
+ */
+xmlExpNodePtr
+xmlExpNewAtom(xmlExpCtxtPtr ctxt, const xmlChar *name, int len) {
+    if ((ctxt == NULL) || (name == NULL))
+        return(NULL);
+    name = xmlDictLookup(ctxt->dict, name, len);
+    if (name == NULL)
+        return(NULL);
+    return(xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, name, 0, 0));
+}
+
+/**
+ * xmlExpNewOr:
+ * @ctxt: the expression context
+ * @left: left expression
+ * @right: right expression
+ *
+ * Get the atom associated to the choice @left | @right
+ * Note that @left and @right are consumed in the operation, to keep
+ * an handle on them use xmlExpRef() and use xmlExpFree() to release them,
+ * this is true even in case of failure (unless ctxt == NULL).
+ *
+ * Returns the node or NULL in case of error
+ */
+xmlExpNodePtr
+xmlExpNewOr(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) {
+    if (ctxt == NULL)
+        return(NULL);
+    if ((left == NULL) || (right == NULL)) {
+        xmlExpFree(ctxt, left);
+        xmlExpFree(ctxt, right);
+        return(NULL);
+    }
+    return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, right, NULL, 0, 0));
+}
+
+/**
+ * xmlExpNewSeq:
+ * @ctxt: the expression context
+ * @left: left expression
+ * @right: right expression
+ *
+ * Get the atom associated to the sequence @left , @right
+ * Note that @left and @right are consumed in the operation, to keep
+ * an handle on them use xmlExpRef() and use xmlExpFree() to release them,
+ * this is true even in case of failure (unless ctxt == NULL).
+ *
+ * Returns the node or NULL in case of error
+ */
+xmlExpNodePtr
+xmlExpNewSeq(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) {
+    if (ctxt == NULL)
+        return(NULL);
+    if ((left == NULL) || (right == NULL)) {
+        xmlExpFree(ctxt, left);
+        xmlExpFree(ctxt, right);
+        return(NULL);
+    }
+    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, left, right, NULL, 0, 0));
+}
+
+/**
+ * xmlExpNewRange:
+ * @ctxt: the expression context
+ * @subset: the expression to be repeated
+ * @min: the lower bound for the repetition
+ * @max: the upper bound for the repetition, -1 means infinite
+ *
+ * Get the atom associated to the range (@subset){@min, @max}
+ * Note that @subset is consumed in the operation, to keep
+ * an handle on it use xmlExpRef() and use xmlExpFree() to release it,
+ * this is true even in case of failure (unless ctxt == NULL).
+ *
+ * Returns the node or NULL in case of error
+ */
+xmlExpNodePtr
+xmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subset, int min, int max) {
+    if (ctxt == NULL)
+        return(NULL);
+    if ((subset == NULL) || (min < 0) || (max < -1) ||
+        ((max >= 0) && (min > max))) {
+	xmlExpFree(ctxt, subset);
+        return(NULL);
+    }
+    return(xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, subset,
+                              NULL, NULL, min, max));
+}
+
+/************************************************************************
+ *									*
+ *		Public API for operations on expressions		*
+ *									*
+ ************************************************************************/
+
+static int
+xmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 
+                     const xmlChar**list, int len, int nb) {
+    int tmp, tmp2;
+tail:
+    switch (exp->type) {
+        case XML_EXP_EMPTY:
+	    return(0);
+        case XML_EXP_ATOM:
+	    for (tmp = 0;tmp < nb;tmp++)
+	        if (list[tmp] == exp->exp_str)
+		    return(0);
+            if (nb >= len)
+	        return(-2);
+	    list[nb] = exp->exp_str;
+	    return(1);
+        case XML_EXP_COUNT:
+	    exp = exp->exp_left;
+	    goto tail;
+        case XML_EXP_SEQ:
+        case XML_EXP_OR:
+	    tmp = xmlExpGetLanguageInt(ctxt, exp->exp_left, list, len, nb);
+	    if (tmp < 0)
+	        return(tmp);
+	    tmp2 = xmlExpGetLanguageInt(ctxt, exp->exp_right, list, len,
+	                                nb + tmp);
+	    if (tmp2 < 0)
+	        return(tmp2);
+            return(tmp + tmp2);
+    }
+    return(-1);
+}
+
+/**
+ * xmlExpGetLanguage:
+ * @ctxt: the expression context
+ * @exp: the expression
+ * @langList: where to store the tokens
+ * @len: the allocated lenght of @list
+ *
+ * Find all the strings used in @exp and store them in @list
+ *
+ * Returns the number of unique strings found, -1 in case of errors and
+ *         -2 if there is more than @len strings
+ */
+int
+xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 
+                  const xmlChar**langList, int len) {
+    if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0))
+        return(-1);
+    return(xmlExpGetLanguageInt(ctxt, exp, langList, len, 0));
+}
+
+static int
+xmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 
+                  const xmlChar**list, int len, int nb) {
+    int tmp, tmp2;
+tail:
+    switch (exp->type) {
+        case XML_EXP_FORBID:
+	    return(0);
+        case XML_EXP_EMPTY:
+	    return(0);
+        case XML_EXP_ATOM:
+	    for (tmp = 0;tmp < nb;tmp++)
+	        if (list[tmp] == exp->exp_str)
+		    return(0);
+            if (nb >= len)
+	        return(-2);
+	    list[nb] = exp->exp_str;
+	    return(1);
+        case XML_EXP_COUNT:
+	    exp = exp->exp_left;
+	    goto tail;
+        case XML_EXP_SEQ:
+	    tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb);
+	    if (tmp < 0)
+	        return(tmp);
+	    if (IS_NILLABLE(exp->exp_left)) {
+		tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len,
+					    nb + tmp);
+		if (tmp2 < 0)
+		    return(tmp2);
+		tmp += tmp2;
+	    }
+            return(tmp);
+        case XML_EXP_OR:
+	    tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb);
+	    if (tmp < 0)
+	        return(tmp);
+	    tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len,
+	                                nb + tmp);
+	    if (tmp2 < 0)
+	        return(tmp2);
+            return(tmp + tmp2);
+    }
+    return(-1);
+}
+
+/**
+ * xmlExpGetStart:
+ * @ctxt: the expression context
+ * @exp: the expression
+ * @tokList: where to store the tokens
+ * @len: the allocated lenght of @list
+ *
+ * Find all the strings that appears at the start of the languages
+ * accepted by @exp and store them in @list. E.g. for (a, b) | c
+ * it will return the list [a, c]
+ *
+ * Returns the number of unique strings found, -1 in case of errors and
+ *         -2 if there is more than @len strings
+ */
+int
+xmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 
+               const xmlChar**tokList, int len) {
+    if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0))
+        return(-1);
+    return(xmlExpGetStartInt(ctxt, exp, tokList, len, 0));
+}
+
+/**
+ * xmlExpIsNillable:
+ * @exp: the expression
+ *
+ * Finds if the expression is nillable, i.e. if it accepts the empty sequqnce
+ *
+ * Returns 1 if nillable, 0 if not and -1 in case of error
+ */
+int
+xmlExpIsNillable(xmlExpNodePtr exp) {
+    if (exp == NULL)
+        return(-1);
+    return(IS_NILLABLE(exp) != 0);
+}
+
+static xmlExpNodePtr
+xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
+{
+    xmlExpNodePtr ret;
+
+    switch (exp->type) {
+	case XML_EXP_EMPTY:
+	    return(forbiddenExp);
+	case XML_EXP_FORBID:
+	    return(forbiddenExp);
+	case XML_EXP_ATOM:
+	    if (exp->exp_str == str) {
+#ifdef DEBUG_DERIV
+		printf("deriv atom: equal => Empty\n");
+#endif
+	        ret = emptyExp;
+	    } else {
+#ifdef DEBUG_DERIV
+		printf("deriv atom: mismatch => forbid\n");
+#endif
+	        /* TODO wildcards here */
+		ret = forbiddenExp;
+	    }
+	    return(ret);
+	case XML_EXP_OR: {
+	    xmlExpNodePtr tmp;
+
+#ifdef DEBUG_DERIV
+	    printf("deriv or: => or(derivs)\n");
+#endif
+	    tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
+	    if (tmp == NULL) {
+		return(NULL);
+	    }
+	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str);
+	    if (ret == NULL) {
+	        xmlExpFree(ctxt, tmp);
+		return(NULL);
+	    }
+            ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret,
+			     NULL, 0, 0);
+	    return(ret);
+	}
+	case XML_EXP_SEQ:
+#ifdef DEBUG_DERIV
+	    printf("deriv seq: starting with left\n");
+#endif
+	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
+	    if (ret == NULL) {
+	        return(NULL);
+	    } else if (ret == forbiddenExp) {
+	        if (IS_NILLABLE(exp->exp_left)) {
+#ifdef DEBUG_DERIV
+		    printf("deriv seq: left failed but nillable\n");
+#endif
+		    ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str);
+		}
+	    } else {
+#ifdef DEBUG_DERIV
+		printf("deriv seq: left match => sequence\n");
+#endif
+	        exp->exp_right->ref++;
+	        ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right,
+		                         NULL, 0, 0);
+	    }
+	    return(ret);
+	case XML_EXP_COUNT: {
+	    int min, max;
+	    xmlExpNodePtr tmp;
+
+	    if (exp->exp_max == 0)
+		return(forbiddenExp);
+	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
+	    if (ret == NULL)
+	        return(NULL);
+	    if (ret == forbiddenExp) {
+#ifdef DEBUG_DERIV
+		printf("deriv count: pattern mismatch => forbid\n");
+#endif
+	        return(ret);
+	    }
+	    if (exp->exp_max == 1)
+		return(ret);
+	    if (exp->exp_max < 0) /* unbounded */
+		max = -1;
+	    else
+		max = exp->exp_max - 1;
+	    if (exp->exp_min > 0)
+		min = exp->exp_min - 1;
+	    else
+		min = 0;
+	    exp->exp_left->ref++;
+	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL,
+				     NULL, min, max);
+	    if (ret == emptyExp) {
+#ifdef DEBUG_DERIV
+		printf("deriv count: match to empty => new count\n");
+#endif
+	        return(tmp);
+	    }
+#ifdef DEBUG_DERIV
+	    printf("deriv count: match => sequence with new count\n");
+#endif
+	    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp,
+	                              NULL, 0, 0));
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * xmlExpStringDerive:
+ * @ctxt: the expression context
+ * @exp: the expression
+ * @str: the string
+ * @len: the string len in bytes if available
+ *
+ * Do one step of Brzozowski derivation of the expression @exp with
+ * respect to the input string
+ *
+ * Returns the resulting expression or NULL in case of internal error
+ */
+xmlExpNodePtr
+xmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
+                   const xmlChar *str, int len) {
+    const xmlChar *input;
+
+    if ((exp == NULL) || (ctxt == NULL) || (str == NULL)) {
+        return(NULL);
+    }
+    /*
+     * check the string is in the dictionnary, if yes use an interned
+     * copy, otherwise we know it's not an acceptable input
+     */
+    input = xmlDictExists(ctxt->dict, str, len);
+    if (input == NULL) {
+        return(forbiddenExp);
+    }
+    return(xmlExpStringDeriveInt(ctxt, exp, input));
+}
+
+static int
+xmlExpCheckCard(xmlExpNodePtr exp, xmlExpNodePtr sub) {
+    int ret = 1;
+
+    if (sub->c_max == -1) {
+        if (exp->c_max != -1)
+	    ret = 0;
+    } else if ((exp->c_max >= 0) && (exp->c_max < sub->c_max)) {
+        ret = 0;
+    }
+#if 0
+    if ((IS_NILLABLE(sub)) && (!IS_NILLABLE(exp)))
+        ret = 0;
+#endif
+    return(ret);
+}
+
+static xmlExpNodePtr xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
+                                        xmlExpNodePtr sub);
+/**
+ * xmlExpDivide:
+ * @ctxt: the expressions context
+ * @exp: the englobing expression
+ * @sub: the subexpression
+ * @mult: the multiple expression
+ * @remain: the remain from the derivation of the multiple
+ *
+ * Check if exp is a multiple of sub, i.e. if there is a finite number n
+ * so that sub{n} subsume exp
+ *
+ * Returns the multiple value if successful, 0 if it is not a multiple
+ *         and -1 in case of internel error.
+ */
+
+static int
+xmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub,
+             xmlExpNodePtr *mult, xmlExpNodePtr *remain) {
+    int i;
+    xmlExpNodePtr tmp, tmp2;
+
+    if (mult != NULL) *mult = NULL;
+    if (remain != NULL) *remain = NULL;
+    if (exp->c_max == -1) return(0);
+    if (IS_NILLABLE(exp) && (!IS_NILLABLE(sub))) return(0);
+
+    for (i = 1;i <= exp->c_max;i++) {
+        sub->ref++;
+        tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT,
+				 sub, NULL, NULL, i, i);
+	if (tmp == NULL) {
+	    return(-1);
+	}
+	if (!xmlExpCheckCard(tmp, exp)) {
+	    xmlExpFree(ctxt, tmp);
+	    continue;
+	}
+	tmp2 = xmlExpExpDeriveInt(ctxt, tmp, exp);
+	if (tmp2 == NULL) {
+	    xmlExpFree(ctxt, tmp);
+	    return(-1);
+	}
+	if ((tmp2 != forbiddenExp) && (IS_NILLABLE(tmp2))) {
+	    if (remain != NULL)
+	        *remain = tmp2;
+	    else
+	        xmlExpFree(ctxt, tmp2);
+	    if (mult != NULL)
+	        *mult = tmp;
+	    else
+	        xmlExpFree(ctxt, tmp);
+#ifdef DEBUG_DERIV
+	    printf("Divide succeeded %d\n", i);
+#endif
+	    return(i);
+	}
+	xmlExpFree(ctxt, tmp);
+	xmlExpFree(ctxt, tmp2);
+    }
+#ifdef DEBUG_DERIV
+    printf("Divide failed\n");
+#endif
+    return(0);
+}
+
+/**
+ * xmlExpExpDeriveInt:
+ * @ctxt: the expressions context
+ * @exp: the englobing expression
+ * @sub: the subexpression
+ *
+ * Try to do a step of Brzozowski derivation but at a higher level
+ * the input being a subexpression.
+ *
+ * Returns the resulting expression or NULL in case of internal error
+ */
+static xmlExpNodePtr
+xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
+    xmlExpNodePtr ret, tmp, tmp2, tmp3;
+    const xmlChar **tab;
+    int len, i;
+
+    /*
+     * In case of equality and if the expression can only consume a finite
+     * amount, then the derivation is empty
+     */
+    if ((exp == sub) && (exp->c_max >= 0)) {
+#ifdef DEBUG_DERIV
+        printf("Equal(exp, sub) and finite -> Empty\n");
+#endif
+        return(emptyExp);
+    }
+    /*
+     * decompose sub sequence first
+     */
+    if (sub->type == XML_EXP_EMPTY) {
+#ifdef DEBUG_DERIV
+        printf("Empty(sub) -> Empty\n");
+#endif
+	exp->ref++;
+        return(exp);
+    }
+    if (sub->type == XML_EXP_SEQ) {
+#ifdef DEBUG_DERIV
+        printf("Seq(sub) -> decompose\n");
+#endif
+        tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
+	if (tmp == NULL)
+	    return(NULL);
+	if (tmp == forbiddenExp)
+	    return(tmp);
+	ret = xmlExpExpDeriveInt(ctxt, tmp, sub->exp_right);
+	xmlExpFree(ctxt, tmp);
+	return(ret);
+    }
+    if (sub->type == XML_EXP_OR) {
+#ifdef DEBUG_DERIV
+        printf("Or(sub) -> decompose\n");
+#endif
+        tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
+	if (tmp == forbiddenExp)
+	    return(tmp);
+	if (tmp == NULL)
+	    return(NULL);
+	ret = xmlExpExpDeriveInt(ctxt, exp, sub->exp_right);
+	if ((ret == NULL) || (ret == forbiddenExp)) {
+	    xmlExpFree(ctxt, tmp);
+	    return(ret);
+	}
+	return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0));
+    }
+    if (!xmlExpCheckCard(exp, sub)) {
+#ifdef DEBUG_DERIV
+        printf("CheckCard(exp, sub) failed -> Forbid\n");
+#endif
+        return(forbiddenExp);
+    }
+    switch (exp->type) {
+        case XML_EXP_EMPTY:
+	    if (sub == emptyExp)
+	        return(emptyExp);
+#ifdef DEBUG_DERIV
+	    printf("Empty(exp) -> Forbid\n");
+#endif
+	    return(forbiddenExp);
+        case XML_EXP_FORBID:
+#ifdef DEBUG_DERIV
+	    printf("Forbid(exp) -> Forbid\n");
+#endif
+	    return(forbiddenExp);
+        case XML_EXP_ATOM:
+	    if (sub->type == XML_EXP_ATOM) {
+	        /* TODO: handle wildcards */
+	        if (exp->exp_str == sub->exp_str) {
+#ifdef DEBUG_DERIV
+		    printf("Atom match -> Empty\n");
+#endif
+		    return(emptyExp);
+                }
+#ifdef DEBUG_DERIV
+		printf("Atom mismatch -> Forbid\n");
+#endif
+	        return(forbiddenExp);
+	    }
+	    if ((sub->type == XML_EXP_COUNT) &&
+	        (sub->exp_max == 1) &&
+	        (sub->exp_left->type == XML_EXP_ATOM)) {
+	        /* TODO: handle wildcards */
+	        if (exp->exp_str == sub->exp_left->exp_str) {
+#ifdef DEBUG_DERIV
+		    printf("Atom match -> Empty\n");
+#endif
+		    return(emptyExp);
+		}
+#ifdef DEBUG_DERIV
+		printf("Atom mismatch -> Forbid\n");
+#endif
+	        return(forbiddenExp);
+	    }
+#ifdef DEBUG_DERIV
+	    printf("Compex exp vs Atom -> Forbid\n");
+#endif
+	    return(forbiddenExp);
+        case XML_EXP_SEQ:
+	    /* try to get the sequence consumed only if possible */
+	    if (xmlExpCheckCard(exp->exp_left, sub)) {
+		/* See if the sequence can be consumed directly */
+#ifdef DEBUG_DERIV
+		printf("Seq trying left only\n");
+#endif
+		ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
+		if ((ret != forbiddenExp) && (ret != NULL)) {
+#ifdef DEBUG_DERIV
+		    printf("Seq trying left only worked\n");
+#endif
+		    /*
+		     * TODO: assumption here that we are determinist
+		     *       i.e. we won't get to a nillable exp left
+		     *       subset which could be matched by the right
+		     *       part too.
+		     * e.g.: (a | b)+,(a | c) and 'a+,a'
+		     */
+		    exp->exp_right->ref++;
+		    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret,
+					      exp->exp_right, NULL, 0, 0));
+		}
+#ifdef DEBUG_DERIV
+	    } else {
+		printf("Seq: left too short\n");
+#endif
+	    }
+	    /* Try instead to decompose */
+	    if (sub->type == XML_EXP_COUNT) {
+		int min, max;
+
+#ifdef DEBUG_DERIV
+		printf("Seq: sub is a count\n");
+#endif
+	        ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left);
+		if (ret == NULL)
+		    return(NULL);
+		if (ret != forbiddenExp) {
+#ifdef DEBUG_DERIV
+		    printf("Seq , Count match on left\n");
+#endif
+		    if (sub->exp_max < 0)
+		        max = -1;
+	            else
+		        max = sub->exp_max -1;
+		    if (sub->exp_min > 0)
+		        min = sub->exp_min -1;
+		    else
+		        min = 0;
+		    exp->exp_right->ref++;
+		    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret,
+		                             exp->exp_right, NULL, 0, 0);
+		    if (tmp == NULL)
+		        return(NULL);
+
+		    sub->exp_left->ref++;
+		    tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT,
+				      sub->exp_left, NULL, NULL, min, max);
+		    if (tmp2 == NULL) {
+		        xmlExpFree(ctxt, tmp);
+			return(NULL);
+		    }
+		    ret = xmlExpExpDeriveInt(ctxt, tmp, tmp2);
+		    xmlExpFree(ctxt, tmp);
+		    xmlExpFree(ctxt, tmp2);
+		    return(ret);
+		}
+	    }
+	    /* we made no progress on structured operations */
+	    break;
+        case XML_EXP_OR:
+#ifdef DEBUG_DERIV
+	    printf("Or , trying both side\n");
+#endif
+	    ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
+	    if (ret == NULL)
+	        return(NULL);
+	    tmp = xmlExpExpDeriveInt(ctxt, exp->exp_right, sub);
+	    if (tmp == NULL) {
+		xmlExpFree(ctxt, ret);
+	        return(NULL);
+	    }
+	    return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp, NULL, 0, 0));
+        case XML_EXP_COUNT: {
+	    int min, max;
+
+	    if (sub->type == XML_EXP_COUNT) {
+	        /*
+		 * Try to see if the loop is completely subsumed
+		 */
+	        tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left);
+		if (tmp == NULL)
+		    return(NULL);
+		if (tmp == forbiddenExp) {
+		    int mult;
+
+#ifdef DEBUG_DERIV
+		    printf("Count, Count inner don't subsume\n");
+#endif
+		    mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left,
+		                        NULL, &tmp);
+		    if (mult <= 0) {
+#ifdef DEBUG_DERIV
+			printf("Count, Count not multiple => forbidden\n");
+#endif
+                        return(forbiddenExp);
+		    }
+		    if (sub->exp_max == -1) {
+		        max = -1;
+			if (exp->exp_max == -1) {
+			    if (exp->exp_min <= sub->exp_min * mult)
+			        min = 0;
+			    else
+			        min = exp->exp_min - sub->exp_min * mult;
+			} else {
+#ifdef DEBUG_DERIV
+			    printf("Count, Count finite can't subsume infinite\n");
+#endif
+                            xmlExpFree(ctxt, tmp);
+			    return(forbiddenExp);
+			}
+		    } else {
+			if (exp->exp_max == -1) {
+#ifdef DEBUG_DERIV
+			    printf("Infinite loop consume mult finite loop\n");
+#endif
+			    if (exp->exp_min > sub->exp_min * mult) {
+				max = -1;
+				min = exp->exp_min - sub->exp_min * mult;
+			    } else {
+				max = -1;
+				min = 0;
+			    }
+			} else {
+			    if (exp->exp_max < sub->exp_max * mult) {
+#ifdef DEBUG_DERIV
+				printf("loops max mult mismatch => forbidden\n");
+#endif
+				xmlExpFree(ctxt, tmp);
+				return(forbiddenExp);
+			    }
+			    if (sub->exp_max * mult > exp->exp_min)
+				min = 0;
+			    else
+				min = exp->exp_min - sub->exp_max * mult;
+			    max = exp->exp_max - sub->exp_max * mult;
+			}
+		    }
+		} else if (!IS_NILLABLE(tmp)) {
+		    /*
+		     * TODO: loop here to try to grow if working on finite
+		     *       blocks.
+		     */
+#ifdef DEBUG_DERIV
+		    printf("Count, Count remain not nillable => forbidden\n");
+#endif
+		    xmlExpFree(ctxt, tmp);
+		    return(forbiddenExp);
+		} else if (sub->exp_max == -1) {
+		    if (exp->exp_max == -1) {
+		        if (exp->exp_min <= sub->exp_min) {
+#ifdef DEBUG_DERIV
+			    printf("Infinite loops Okay => COUNT(0,Inf)\n");
+#endif
+                            max = -1;
+			    min = 0;
+			} else {
+#ifdef DEBUG_DERIV
+			    printf("Infinite loops min => Count(X,Inf)\n");
+#endif
+                            max = -1;
+			    min = exp->exp_min - sub->exp_min;
+			}
+		    } else if (exp->exp_min > sub->exp_min) {
+#ifdef DEBUG_DERIV
+			printf("loops min mismatch 1 => forbidden ???\n");
+#endif
+		        xmlExpFree(ctxt, tmp);
+		        return(forbiddenExp);
+		    } else {
+			max = -1;
+			min = 0;
+		    }
+		} else {
+		    if (exp->exp_max == -1) {
+#ifdef DEBUG_DERIV
+			printf("Infinite loop consume finite loop\n");
+#endif
+		        if (exp->exp_min > sub->exp_min) {
+			    max = -1;
+			    min = exp->exp_min - sub->exp_min;
+			} else {
+			    max = -1;
+			    min = 0;
+			}
+		    } else {
+		        if (exp->exp_max < sub->exp_max) {
+#ifdef DEBUG_DERIV
+			    printf("loops max mismatch => forbidden\n");
+#endif
+			    xmlExpFree(ctxt, tmp);
+			    return(forbiddenExp);
+			}
+			if (sub->exp_max > exp->exp_min)
+			    min = 0;
+			else
+			    min = exp->exp_min - sub->exp_max;
+			max = exp->exp_max - sub->exp_max;
+		    }
+		}
+#ifdef DEBUG_DERIV
+		printf("loops match => SEQ(COUNT())\n");
+#endif
+		exp->exp_left->ref++;
+		tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
+		                          NULL, NULL, min, max);
+		if (tmp2 == NULL) {
+		    return(NULL);
+		}
+                ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2,
+		                         NULL, 0, 0);
+		return(ret);
+	    }
+	    tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
+	    if (tmp == NULL)
+		return(NULL);
+	    if (tmp == forbiddenExp) {
+#ifdef DEBUG_DERIV
+		printf("loop mismatch => forbidden\n");
+#endif
+		return(forbiddenExp);
+	    }
+	    if (exp->exp_min > 0)
+		min = exp->exp_min - 1;
+	    else
+		min = 0;
+	    if (exp->exp_max < 0)
+		max = -1;
+	    else
+		max = exp->exp_max - 1;
+
+#ifdef DEBUG_DERIV
+	    printf("loop match => SEQ(COUNT())\n");
+#endif
+	    exp->exp_left->ref++;
+	    tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
+				      NULL, NULL, min, max);
+	    if (tmp2 == NULL)
+		return(NULL);
+	    ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2,
+				     NULL, 0, 0);
+	    return(ret);
+	}
+    }
+
+#ifdef DEBUG_DERIV
+    printf("Fallback to derivative\n");
+#endif
+    if (IS_NILLABLE(sub)) {
+        if (!(IS_NILLABLE(exp)))
+	    return(forbiddenExp);
+	else
+	    ret = emptyExp;
+    } else
+	ret = NULL;
+    /*
+     * here the structured derivation made no progress so
+     * we use the default token based derivation to force one more step
+     */
+    if (ctxt->tabSize == 0)
+        ctxt->tabSize = 40;
+
+    tab = (const xmlChar **) xmlMalloc(ctxt->tabSize *
+	                               sizeof(const xmlChar *));
+    if (tab == NULL) {
+	return(NULL);
+    }
+
+    /*
+     * collect all the strings accepted by the subexpression on input
+     */
+    len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
+    while (len < 0) {
+        const xmlChar **temp;
+	temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 *
+	                                     sizeof(const xmlChar *));
+	if (temp == NULL) {
+	    xmlFree((xmlChar **) tab);
+	    return(NULL);
+	}
+	tab = temp;
+	ctxt->tabSize *= 2;
+	len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
+    }
+    for (i = 0;i < len;i++) {
+        tmp = xmlExpStringDeriveInt(ctxt, exp, tab[i]);
+	if ((tmp == NULL) || (tmp == forbiddenExp)) {
+	    xmlExpFree(ctxt, ret);
+	    xmlFree((xmlChar **) tab);
+	    return(tmp);
+	}
+	tmp2 = xmlExpStringDeriveInt(ctxt, sub, tab[i]);
+	if ((tmp2 == NULL) || (tmp2 == forbiddenExp)) {
+	    xmlExpFree(ctxt, tmp);
+	    xmlExpFree(ctxt, ret);
+	    xmlFree((xmlChar **) tab);
+	    return(tmp);
+	}
+	tmp3 = xmlExpExpDeriveInt(ctxt, tmp, tmp2);
+	xmlExpFree(ctxt, tmp);
+	xmlExpFree(ctxt, tmp2);
+
+	if ((tmp3 == NULL) || (tmp3 == forbiddenExp)) {
+	    xmlExpFree(ctxt, ret);
+	    xmlFree((xmlChar **) tab);
+	    return(tmp3);
+	}
+
+	if (ret == NULL)
+	    ret = tmp3;
+	else {
+	    ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp3, NULL, 0, 0);
+	    if (ret == NULL) {
+		xmlFree((xmlChar **) tab);
+	        return(NULL);
+	    }
+	}
+    }
+    xmlFree((xmlChar **) tab);
+    return(ret);
+}
+    
+/**
+ * xmlExpExpDerive:
+ * @ctxt: the expressions context
+ * @exp: the englobing expression
+ * @sub: the subexpression
+ *
+ * Evaluates the expression resulting from @exp consuming a sub expression @sub
+ * Based on algebraic derivation and sometimes direct Brzozowski derivation
+ * it usually tatkes less than linear time and can handle expressions generating
+ * infinite languages.
+ *
+ * Returns the resulting expression or NULL in case of internal error, the
+ *         result must be freed
+ */
+xmlExpNodePtr
+xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
+    if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))
+        return(NULL);
+
+    /*
+     * O(1) speedups
+     */
+    if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
+#ifdef DEBUG_DERIV
+	printf("Sub nillable and not exp : can't subsume\n");
+#endif
+        return(forbiddenExp);
+    }
+    if (xmlExpCheckCard(exp, sub) == 0) {
+#ifdef DEBUG_DERIV
+	printf("sub generate longuer sequances than exp : can't subsume\n");
+#endif
+        return(forbiddenExp);
+    }
+    return(xmlExpExpDeriveInt(ctxt, exp, sub));
+}
+
+/**
+ * xmlExpSubsume:
+ * @ctxt: the expressions context
+ * @exp: the englobing expression
+ * @sub: the subexpression
+ *
+ * Check whether @exp accepts all the languages accexpted by @sub
+ * the input being a subexpression.
+ *
+ * Returns 1 if true 0 if false and -1 in case of failure.
+ */
+int
+xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
+    xmlExpNodePtr tmp;
+    
+    if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))
+        return(-1);
+
+    /*
+     * TODO: speedup by checking the language of sub is a subset of the
+     *       language of exp
+     */
+    /*
+     * O(1) speedups
+     */
+    if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
+#ifdef DEBUG_DERIV
+	printf("Sub nillable and not exp : can't subsume\n");
+#endif
+        return(0);
+    }
+    if (xmlExpCheckCard(exp, sub) == 0) {
+#ifdef DEBUG_DERIV
+	printf("sub generate longuer sequances than exp : can't subsume\n");
+#endif
+        return(0);
+    }
+    tmp = xmlExpExpDeriveInt(ctxt, exp, sub);
+#ifdef DEBUG_DERIV
+    printf("Result derivation :\n");
+    PRINT_EXP(tmp);
+#endif
+    if (tmp == NULL)
+        return(-1);
+    if (tmp == forbiddenExp)
+	return(0);
+    if (tmp == emptyExp)
+	return(1);
+    if ((tmp != NULL) && (IS_NILLABLE(tmp))) {
+        xmlExpFree(ctxt, tmp);
+        return(1);
+    }
+    xmlExpFree(ctxt, tmp);
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			Parsing expression 				*
+ *									*
+ ************************************************************************/
+
+static xmlExpNodePtr xmlExpParseExpr(xmlExpCtxtPtr ctxt);
+
+#undef CUR
+#define CUR (*ctxt->cur)
+#undef NEXT
+#define NEXT ctxt->cur++;
+#undef IS_BLANK
+#define IS_BLANK(c) ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))
+#define SKIP_BLANKS while (IS_BLANK(*ctxt->cur)) ctxt->cur++;
+
+static int
+xmlExpParseNumber(xmlExpCtxtPtr ctxt) {
+    int ret = 0;
+
+    SKIP_BLANKS
+    if (CUR == '*') {
+	NEXT
+	return(-1);
+    }
+    if ((CUR < '0') || (CUR > '9'))
+        return(-1);
+    while ((CUR >= '0') && (CUR <= '9')) {
+        ret = ret * 10 + (CUR - '0');
+	NEXT
+    }
+    return(ret);
+}
+
+static xmlExpNodePtr
+xmlExpParseOr(xmlExpCtxtPtr ctxt) {
+    const char *base;
+    xmlExpNodePtr ret;
+    const xmlChar *val;
+
+    SKIP_BLANKS
+    base = ctxt->cur;
+    if (*ctxt->cur == '(') {
+        NEXT
+	ret = xmlExpParseExpr(ctxt);
+	SKIP_BLANKS
+	if (*ctxt->cur != ')') {
+	    fprintf(stderr, "unbalanced '(' : %s\n", base);
+	    xmlExpFree(ctxt, ret);
+	    return(NULL);
+	}
+	NEXT;
+	SKIP_BLANKS
+	goto parse_quantifier;
+    }
+    while ((CUR != 0) && (!(IS_BLANK(CUR))) && (CUR != '(') &&
+           (CUR != ')') && (CUR != '|') && (CUR != ',') && (CUR != '{') &&
+	   (CUR != '*') && (CUR != '+') && (CUR != '?') && (CUR != '}'))
+	NEXT;
+    val = xmlDictLookup(ctxt->dict, BAD_CAST base, ctxt->cur - base);
+    if (val == NULL)
+        return(NULL);
+    ret = xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, val, 0, 0);
+    if (ret == NULL)
+        return(NULL);
+    SKIP_BLANKS
+parse_quantifier:
+    if (CUR == '{') {
+        int min, max;
+
+        NEXT
+	min = xmlExpParseNumber(ctxt);
+	if (min < 0) {
+	    xmlExpFree(ctxt, ret);
+	    return(NULL);
+	}
+	SKIP_BLANKS
+	if (CUR == ',') {
+	    NEXT
+	    max = xmlExpParseNumber(ctxt);
+	    SKIP_BLANKS
+	} else
+	    max = min;
+	if (CUR != '}') {
+	    xmlExpFree(ctxt, ret);
+	    return(NULL);
+	}
+        NEXT
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
+	                         min, max);
+	SKIP_BLANKS
+    } else if (CUR == '?') {
+        NEXT
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
+	                         0, 1);
+	SKIP_BLANKS
+    } else if (CUR == '+') {
+        NEXT
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
+	                         1, -1);
+	SKIP_BLANKS
+    } else if (CUR == '*') {
+        NEXT
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
+	                         0, -1);
+	SKIP_BLANKS
+    } 
+    return(ret);
+}
+
+
+static xmlExpNodePtr
+xmlExpParseSeq(xmlExpCtxtPtr ctxt) {
+    xmlExpNodePtr ret, right;
+
+    ret = xmlExpParseOr(ctxt);
+    SKIP_BLANKS
+    while (CUR == '|') {
+        NEXT
+	right = xmlExpParseOr(ctxt);
+	if (right == NULL) {
+	    xmlExpFree(ctxt, ret);
+	    return(NULL);
+	}
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, right, NULL, 0, 0);
+	if (ret == NULL)
+	    return(NULL);
+    }
+    return(ret);
+}
+
+static xmlExpNodePtr
+xmlExpParseExpr(xmlExpCtxtPtr ctxt) {
+    xmlExpNodePtr ret, right;
+
+    ret = xmlExpParseSeq(ctxt);
+    SKIP_BLANKS
+    while (CUR == ',') {
+        NEXT
+	right = xmlExpParseSeq(ctxt);
+	if (right == NULL) {
+	    xmlExpFree(ctxt, ret);
+	    return(NULL);
+	}
+	ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, right, NULL, 0, 0);
+	if (ret == NULL)
+	    return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlExpParse:
+ * @ctxt: the expressions context
+ * @expr: the 0 terminated string
+ *
+ * Minimal parser for regexps, it understand the following constructs
+ *  - string terminals
+ *  - choice operator |
+ *  - sequence operator ,
+ *  - subexpressions (...)
+ *  - usual cardinality operators + * and ?
+ *  - finite sequences  { min, max }
+ *  - infinite sequences { min, * }
+ * There is minimal checkings made especially no checking on strings values
+ *
+ * Returns a new expression or NULL in case of failure
+ */
+xmlExpNodePtr
+xmlExpParse(xmlExpCtxtPtr ctxt, const char *expr) {
+    xmlExpNodePtr ret;
+
+    ctxt->expr = expr;
+    ctxt->cur = expr;
+
+    ret = xmlExpParseExpr(ctxt);
+    SKIP_BLANKS
+    if (*ctxt->cur != 0) {
+        xmlExpFree(ctxt, ret);
+        return(NULL);
+    }
+    return(ret);
+}
+
+static void
+xmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, int glob) {
+    xmlExpNodePtr c;
+
+    if (expr == NULL) return;
+    if (glob) xmlBufferWriteChar(buf, "(");
+    switch (expr->type) {
+        case XML_EXP_EMPTY:
+	    xmlBufferWriteChar(buf, "empty");
+	    break;
+        case XML_EXP_FORBID:
+	    xmlBufferWriteChar(buf, "forbidden");
+	    break;
+        case XML_EXP_ATOM:
+	    xmlBufferWriteCHAR(buf, expr->exp_str);
+	    break;
+        case XML_EXP_SEQ:
+	    c = expr->exp_left;
+	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
+	        xmlExpDumpInt(buf, c, 1);
+	    else
+	        xmlExpDumpInt(buf, c, 0);
+	    xmlBufferWriteChar(buf, " , ");
+	    c = expr->exp_right;
+	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
+	        xmlExpDumpInt(buf, c, 1);
+	    else
+	        xmlExpDumpInt(buf, c, 0);
+            break;
+        case XML_EXP_OR:
+	    c = expr->exp_left;
+	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
+	        xmlExpDumpInt(buf, c, 1);
+	    else
+	        xmlExpDumpInt(buf, c, 0);
+	    xmlBufferWriteChar(buf, " | ");
+	    c = expr->exp_right;
+	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
+	        xmlExpDumpInt(buf, c, 1);
+	    else
+	        xmlExpDumpInt(buf, c, 0);
+            break;
+        case XML_EXP_COUNT: {
+	    char rep[40];
+	    
+	    c = expr->exp_left;
+	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
+	        xmlExpDumpInt(buf, c, 1);
+	    else
+	        xmlExpDumpInt(buf, c, 0);
+	    if ((expr->exp_min == 0) && (expr->exp_max == 1)) {
+		rep[0] = '?';
+		rep[1] = 0;
+	    } else if ((expr->exp_min == 0) && (expr->exp_max == -1)) {
+		rep[0] = '*';
+		rep[1] = 0;
+	    } else if ((expr->exp_min == 1) && (expr->exp_max == -1)) {
+		rep[0] = '+';
+		rep[1] = 0;
+	    } else if (expr->exp_max == expr->exp_min) {
+	        snprintf(rep, 39, "{%d}", expr->exp_min);
+	    } else if (expr->exp_max < 0) {
+	        snprintf(rep, 39, "{%d,inf}", expr->exp_min);
+	    } else {
+	        snprintf(rep, 39, "{%d,%d}", expr->exp_min, expr->exp_max);
+	    }
+	    rep[39] = 0;
+	    xmlBufferWriteChar(buf, rep);
+	    break;
+	}
+	default:
+	    fprintf(stderr, "Error in tree\n");
+    }
+    if (glob)
+        xmlBufferWriteChar(buf, ")");
+}
+/**
+ * xmlExpDump:
+ * @buf:  a buffer to receive the output
+ * @expr:  the compiled expression
+ *
+ * Serialize the expression as compiled to the buffer
+ */
+void
+xmlExpDump(xmlBufferPtr buf, xmlExpNodePtr expr) {
+    if ((buf == NULL) || (expr == NULL))
+        return;
+    xmlExpDumpInt(buf, expr, 0);
+}
+
+/**
+ * xmlExpMaxToken:
+ * @expr: a compiled expression
+ *
+ * Indicate the maximum number of input a expression can accept
+ *
+ * Returns the maximum length or -1 in case of error
+ */
+int
+xmlExpMaxToken(xmlExpNodePtr expr) {
+    if (expr == NULL)
+        return(-1);
+    return(expr->c_max);
+}
+
+/**
+ * xmlExpCtxtNbNodes:
+ * @ctxt: an expression context
+ *
+ * Debugging facility provides the number of allocated nodes at a that point
+ *
+ * Returns the number of nodes in use or -1 in case of error
+ */
+int
+xmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return(-1);
+    return(ctxt->nb_nodes);
+}
+
+/**
+ * xmlExpCtxtNbCons:
+ * @ctxt: an expression context
+ *
+ * Debugging facility provides the number of allocated nodes over lifetime
+ *
+ * Returns the number of nodes ever allocated or -1 in case of error
+ */
+int
+xmlExpCtxtNbCons(xmlExpCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return(-1);
+    return(ctxt->nb_cons);
+}
+
+#endif /* LIBXML_EXPR_ENABLED */
+#define bottom_xmlregexp
+#include "elfgcchack.h"
+#endif /* LIBXML_REGEXP_ENABLED */
diff --git a/src/xmlsave.c b/src/xmlsave.c
new file mode 100644
index 0000000..9b43075
--- /dev/null
+++ b/src/xmlsave.c
@@ -0,0 +1,2549 @@
+/*
+ * xmlsave.c: Implemetation of the document serializer
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/xmlsave.h>
+
+#define MAX_INDENT 60
+
+#include <libxml/HTMLtree.h>
+
+/************************************************************************
+ *									*
+ *			XHTML detection					*
+ *									*
+ ************************************************************************/
+#define XHTML_STRICT_PUBLIC_ID BAD_CAST \
+   "-//W3C//DTD XHTML 1.0 Strict//EN"
+#define XHTML_STRICT_SYSTEM_ID BAD_CAST \
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+#define XHTML_FRAME_PUBLIC_ID BAD_CAST \
+   "-//W3C//DTD XHTML 1.0 Frameset//EN"
+#define XHTML_FRAME_SYSTEM_ID BAD_CAST \
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
+#define XHTML_TRANS_PUBLIC_ID BAD_CAST \
+   "-//W3C//DTD XHTML 1.0 Transitional//EN"
+#define XHTML_TRANS_SYSTEM_ID BAD_CAST \
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
+
+#define XHTML_NS_NAME BAD_CAST "http://www.w3.org/1999/xhtml"
+/**
+ * xmlIsXHTML:
+ * @systemID:  the system identifier
+ * @publicID:  the public identifier
+ *
+ * Try to find if the document correspond to an XHTML DTD
+ *
+ * Returns 1 if true, 0 if not and -1 in case of error
+ */
+int
+xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
+    if ((systemID == NULL) && (publicID == NULL))
+	return(-1);
+    if (publicID != NULL) {
+	if (xmlStrEqual(publicID, XHTML_STRICT_PUBLIC_ID)) return(1);
+	if (xmlStrEqual(publicID, XHTML_FRAME_PUBLIC_ID)) return(1);
+	if (xmlStrEqual(publicID, XHTML_TRANS_PUBLIC_ID)) return(1);
+    }
+    if (systemID != NULL) {
+	if (xmlStrEqual(systemID, XHTML_STRICT_SYSTEM_ID)) return(1);
+	if (xmlStrEqual(systemID, XHTML_FRAME_SYSTEM_ID)) return(1);
+	if (xmlStrEqual(systemID, XHTML_TRANS_SYSTEM_ID)) return(1);
+    }
+    return(0);
+}
+
+#ifdef LIBXML_OUTPUT_ENABLED
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+struct _xmlSaveCtxt {
+    void *_private;
+    int type;
+    int fd;
+    const xmlChar *filename;
+    const xmlChar *encoding;
+    xmlCharEncodingHandlerPtr handler;
+    xmlOutputBufferPtr buf;
+    xmlDocPtr doc;
+    int options;
+    int level;
+    int format;
+    char indent[MAX_INDENT + 1];	/* array for indenting output */
+    int indent_nr;
+    int indent_size;
+    xmlCharEncodingOutputFunc escape;	/* used for element content */
+    xmlCharEncodingOutputFunc escapeAttr;/* used for attribute content */
+};
+
+/************************************************************************
+ *									*
+ * 			Output error handlers				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlSaveErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSaveErrMemory(const char *extra)
+{
+    __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
+}
+
+/**
+ * xmlSaveErr:
+ * @code:  the error number
+ * @node:  the location of the error.
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSaveErr(int code, xmlNodePtr node, const char *extra)
+{
+    const char *msg = NULL;
+
+    switch(code) {
+        case XML_SAVE_NOT_UTF8:
+	    msg = "string is not in UTF-8\n";
+	    break;
+	case XML_SAVE_CHAR_INVALID:
+	    msg = "invalid character value\n";
+	    break;
+	case XML_SAVE_UNKNOWN_ENCODING:
+	    msg = "unknown encoding %s\n";
+	    break;
+	case XML_SAVE_NO_DOCTYPE:
+	    msg = "document has no DOCTYPE\n";
+	    break;
+	default:
+	    msg = "unexpected error number\n";
+    }
+    __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
+}
+
+/************************************************************************
+ *									*
+ *			Special escaping routines			*
+ *									*
+ ************************************************************************/
+static unsigned char *
+xmlSerializeHexCharRef(unsigned char *out, int val) {
+    unsigned char *ptr;
+
+    *out++ = '&';
+    *out++ = '#';
+    *out++ = 'x';
+    if (val < 0x10) ptr = out;
+    else if (val < 0x100) ptr = out + 1;
+    else if (val < 0x1000) ptr = out + 2;
+    else if (val < 0x10000) ptr = out + 3;
+    else if (val < 0x100000) ptr = out + 4;
+    else ptr = out + 5;
+    out = ptr + 1;
+    while (val > 0) {
+	switch (val & 0xF) {
+	    case 0: *ptr-- = '0'; break;
+	    case 1: *ptr-- = '1'; break;
+	    case 2: *ptr-- = '2'; break;
+	    case 3: *ptr-- = '3'; break;
+	    case 4: *ptr-- = '4'; break;
+	    case 5: *ptr-- = '5'; break;
+	    case 6: *ptr-- = '6'; break;
+	    case 7: *ptr-- = '7'; break;
+	    case 8: *ptr-- = '8'; break;
+	    case 9: *ptr-- = '9'; break;
+	    case 0xA: *ptr-- = 'A'; break;
+	    case 0xB: *ptr-- = 'B'; break;
+	    case 0xC: *ptr-- = 'C'; break;
+	    case 0xD: *ptr-- = 'D'; break;
+	    case 0xE: *ptr-- = 'E'; break;
+	    case 0xF: *ptr-- = 'F'; break;
+	    default: *ptr-- = '0'; break;
+	}
+	val >>= 4;
+    }
+    *out++ = ';';
+    *out = 0;
+    return(out);
+}
+
+/**
+ * xmlEscapeEntities:
+ * @out:  a pointer to an array of bytes to store the result
+ * @outlen:  the length of @out
+ * @in:  a pointer to an array of unescaped UTF-8 bytes
+ * @inlen:  the length of @in
+ *
+ * Take a block of UTF-8 chars in and escape them. Used when there is no
+ * encoding specified.
+ *
+ * Returns 0 if success, or -1 otherwise
+ * The value of @inlen after return is the number of octets consumed
+ *     if the return value is positive, else unpredictable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+static int
+xmlEscapeEntities(unsigned char* out, int *outlen,
+                 const xmlChar* in, int *inlen) {
+    unsigned char* outstart = out;
+    const unsigned char* base = in;
+    unsigned char* outend = out + *outlen;
+    const unsigned char* inend;
+    int val;
+
+    inend = in + (*inlen);
+    
+    while ((in < inend) && (out < outend)) {
+    	if (*in == '<') {
+	    if (outend - out < 4) break;
+	    *out++ = '&';
+	    *out++ = 'l';
+	    *out++ = 't';
+	    *out++ = ';';
+	    in++;
+	    continue;
+	} else if (*in == '>') {
+	    if (outend - out < 4) break;
+	    *out++ = '&';
+	    *out++ = 'g';
+	    *out++ = 't';
+	    *out++ = ';';
+	    in++;
+	    continue;
+	} else if (*in == '&') {
+	    if (outend - out < 5) break;
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'm';
+	    *out++ = 'p';
+	    *out++ = ';';
+	    in++;
+	    continue;
+	} else if (((*in >= 0x20) && (*in < 0x80)) ||
+	           (*in == '\n') || (*in == '\t')) {
+	    /*
+	     * default case, just copy !
+	     */
+	    *out++ = *in++;
+	    continue;
+	} else if (*in >= 0x80) {
+	    /*
+	     * We assume we have UTF-8 input.
+	     */
+	    if (outend - out < 11) break;
+
+	    if (*in < 0xC0) {
+		xmlSaveErr(XML_SAVE_NOT_UTF8, NULL, NULL);
+		in++;
+		goto error;
+	    } else if (*in < 0xE0) {
+		if (inend - in < 2) break;
+		val = (in[0]) & 0x1F;
+		val <<= 6;
+		val |= (in[1]) & 0x3F;
+		in += 2;
+	    } else if (*in < 0xF0) {
+		if (inend - in < 3) break;
+		val = (in[0]) & 0x0F;
+		val <<= 6;
+		val |= (in[1]) & 0x3F;
+		val <<= 6;
+		val |= (in[2]) & 0x3F;
+		in += 3;
+	    } else if (*in < 0xF8) {
+		if (inend - in < 4) break;
+		val = (in[0]) & 0x07;
+		val <<= 6;
+		val |= (in[1]) & 0x3F;
+		val <<= 6;
+		val |= (in[2]) & 0x3F;
+		val <<= 6;
+		val |= (in[3]) & 0x3F;
+		in += 4;
+	    } else {
+		xmlSaveErr(XML_SAVE_CHAR_INVALID, NULL, NULL);
+		in++;
+		goto error;
+	    }
+	    if (!IS_CHAR(val)) {
+		xmlSaveErr(XML_SAVE_CHAR_INVALID, NULL, NULL);
+		in++;
+		goto error;
+	    }
+
+	    /*
+	     * We could do multiple things here. Just save as a char ref
+	     */
+	    out = xmlSerializeHexCharRef(out, val);
+	} else if (IS_BYTE_CHAR(*in)) {
+	    if (outend - out < 6) break;
+	    out = xmlSerializeHexCharRef(out, *in++);
+	} else {
+	    xmlGenericError(xmlGenericErrorContext,
+		"xmlEscapeEntities : char out of range\n");
+	    in++;
+	    goto error;
+	}
+    }
+    *outlen = out - outstart;
+    *inlen = in - base;
+    return(0);
+error:
+    *outlen = out - outstart;
+    *inlen = in - base;
+    return(-1);
+}
+
+/************************************************************************
+ *									*
+ *			Allocation and deallocation			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlSaveCtxtInit:
+ * @ctxt: the saving context
+ *
+ * Initialize a saving context
+ */
+static void
+xmlSaveCtxtInit(xmlSaveCtxtPtr ctxt)
+{
+    int i;
+    int len;
+
+    if (ctxt == NULL) return;
+    if ((ctxt->encoding == NULL) && (ctxt->escape == NULL))
+        ctxt->escape = xmlEscapeEntities;
+    len = xmlStrlen((xmlChar *)xmlTreeIndentString);
+    if ((xmlTreeIndentString == NULL) || (len == 0)) {
+        memset(&ctxt->indent[0], 0, MAX_INDENT + 1);
+    } else {
+	ctxt->indent_size = len;
+	ctxt->indent_nr = MAX_INDENT / ctxt->indent_size;
+	for (i = 0;i < ctxt->indent_nr;i++)
+	    memcpy(&ctxt->indent[i * ctxt->indent_size], xmlTreeIndentString,
+		   ctxt->indent_size);
+        ctxt->indent[ctxt->indent_nr * ctxt->indent_size] = 0;
+    }
+
+    if (xmlSaveNoEmptyTags) {
+	ctxt->options |= XML_SAVE_NO_EMPTY;
+    }
+}
+
+/**
+ * xmlFreeSaveCtxt:
+ *
+ * Free a saving context, destroying the ouptut in any remaining buffer
+ */
+static void
+xmlFreeSaveCtxt(xmlSaveCtxtPtr ctxt)
+{
+    if (ctxt == NULL) return;
+    if (ctxt->encoding != NULL)
+        xmlFree((char *) ctxt->encoding);
+    if (ctxt->buf != NULL)
+        xmlOutputBufferClose(ctxt->buf);
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlNewSaveCtxt:
+ *
+ * Create a new saving context
+ *
+ * Returns the new structure or NULL in case of error
+ */
+static xmlSaveCtxtPtr
+xmlNewSaveCtxt(const char *encoding, int options)
+{
+    xmlSaveCtxtPtr ret;
+
+    ret = (xmlSaveCtxtPtr) xmlMalloc(sizeof(xmlSaveCtxt));
+    if (ret == NULL) {
+	xmlSaveErrMemory("creating saving context");
+	return ( NULL );
+    }
+    memset(ret, 0, sizeof(xmlSaveCtxt));
+
+    if (encoding != NULL) {
+        ret->handler = xmlFindCharEncodingHandler(encoding);
+	if (ret->handler == NULL) {
+	    xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
+            xmlFreeSaveCtxt(ret);
+	    return(NULL);
+	}
+        ret->encoding = xmlStrdup((const xmlChar *)encoding);
+	ret->escape = NULL;
+    }
+    xmlSaveCtxtInit(ret);
+
+    /*
+     * Use the options
+     */
+
+    /* Re-check this option as it may already have been set */
+    if ((ret->options & XML_SAVE_NO_EMPTY) && ! (options & XML_SAVE_NO_EMPTY)) {
+	options |= XML_SAVE_NO_EMPTY;
+    }
+
+    ret->options = options;
+    if (options & XML_SAVE_FORMAT)
+        ret->format = 1;
+
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *   		Dumping XML tree content to a simple buffer		*
+ *									*
+ ************************************************************************/
+/**
+ * xmlAttrSerializeContent:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @attr:  the attribute pointer
+ *
+ * Serialize the attribute in the buffer
+ */
+static void
+xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr)
+{
+    xmlNodePtr children;
+
+    children = attr->children;
+    while (children != NULL) {
+        switch (children->type) {
+            case XML_TEXT_NODE:
+	        xmlAttrSerializeTxtContent(buf->buffer, attr->doc,
+		                           attr, children->content);
+		break;
+            case XML_ENTITY_REF_NODE:
+                xmlBufferAdd(buf->buffer, BAD_CAST "&", 1);
+                xmlBufferAdd(buf->buffer, children->name,
+                             xmlStrlen(children->name));
+                xmlBufferAdd(buf->buffer, BAD_CAST ";", 1);
+                break;
+            default:
+                /* should not happen unless we have a badly built tree */
+                break;
+        }
+        children = children->next;
+    }
+}
+
+/************************************************************************
+ *									*
+ *   		Dumping XML tree content to an I/O output buffer	*
+ *									*
+ ************************************************************************/
+
+static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
+    xmlOutputBufferPtr buf = ctxt->buf;
+
+    if ((encoding != NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) {
+	buf->encoder = xmlFindCharEncodingHandler((const char *)encoding);
+	if (buf->encoder == NULL) {
+	    xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL,
+		       (const char *)encoding);
+	    return(-1);
+	}
+	buf->conv = xmlBufferCreate();
+	if (buf->conv == NULL) {
+	    xmlCharEncCloseFunc(buf->encoder);
+	    xmlSaveErrMemory("creating encoding buffer");
+	    return(-1);
+	}
+	/*
+	 * initialize the state, e.g. if outputting a BOM
+	 */
+	xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
+    }
+    return(0);
+}
+
+static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
+    xmlOutputBufferPtr buf = ctxt->buf;
+    xmlOutputBufferFlush(buf);
+    xmlCharEncCloseFunc(buf->encoder);
+    xmlBufferFree(buf->conv);
+    buf->encoder = NULL;
+    buf->conv = NULL;
+    return(0);
+}
+
+#ifdef LIBXML_HTML_ENABLED
+static void
+xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
+#endif
+static void xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
+static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
+void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
+static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
+
+/**
+ * xmlNsDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  a namespace
+ *
+ * Dump a local Namespace definition.
+ * Should be called in the context of attributes dumps.
+ */
+static void
+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    if ((cur == NULL) || (buf == NULL)) return;
+    if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
+	if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
+	    return;
+
+        /* Within the context of an element attributes */
+	if (cur->prefix != NULL) {
+	    xmlOutputBufferWrite(buf, 7, " xmlns:");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
+	} else
+	    xmlOutputBufferWrite(buf, 6, " xmlns");
+	xmlOutputBufferWrite(buf, 1, "=");
+	xmlBufferWriteQuotedString(buf->buffer, cur->href);
+    }
+}
+
+/**
+ * xmlNsListDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  the first namespace
+ *
+ * Dump a list of local Namespace definitions.
+ * Should be called in the context of attributes dumps.
+ */
+void
+xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlNsDumpOutput(buf, cur);
+	cur = cur->next;
+    }
+}
+
+/**
+ * xmlDtdDumpOutput:
+ * @buf:  the XML buffer output
+ * @dtd:  the pointer to the DTD
+ * 
+ * Dump the XML document DTD, if any.
+ */
+static void
+xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
+    xmlOutputBufferPtr buf;
+    int format, level;
+    xmlDocPtr doc;
+
+    if (dtd == NULL) return;
+    if ((ctxt == NULL) || (ctxt->buf == NULL))
+        return;
+    buf = ctxt->buf;
+    xmlOutputBufferWrite(buf, 10, "<!DOCTYPE ");
+    xmlOutputBufferWriteString(buf, (const char *)dtd->name);
+    if (dtd->ExternalID != NULL) {
+	xmlOutputBufferWrite(buf, 8, " PUBLIC ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
+	xmlOutputBufferWrite(buf, 1, " ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
+    }  else if (dtd->SystemID != NULL) {
+	xmlOutputBufferWrite(buf, 8, " SYSTEM ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
+    }
+    if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
+        (dtd->attributes == NULL) && (dtd->notations == NULL) &&
+	(dtd->pentities == NULL)) {
+	xmlOutputBufferWrite(buf, 1, ">");
+	return;
+    }
+    xmlOutputBufferWrite(buf, 3, " [\n");
+    /*
+     * Dump the notations first they are not in the DTD children list
+     * Do this only on a standalone DTD or on the internal subset though.
+     */
+    if ((dtd->notations != NULL) && ((dtd->doc == NULL) ||
+        (dtd->doc->intSubset == dtd))) {
+        xmlDumpNotationTable(buf->buffer, (xmlNotationTablePtr) dtd->notations);
+    }
+    format = ctxt->format;
+    level = ctxt->level;
+    doc = ctxt->doc;
+    ctxt->format = 0;
+    ctxt->level = -1;
+    ctxt->doc = dtd->doc;
+    xmlNodeListDumpOutput(ctxt, dtd->children);
+    ctxt->format = format;
+    ctxt->level = level;
+    ctxt->doc = doc;
+    xmlOutputBufferWrite(buf, 2, "]>");
+}
+
+/**
+ * xmlAttrDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  the attribute pointer
+ *
+ * Dump an XML attribute
+ */
+static void
+xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    buf = ctxt->buf;
+    if (buf == NULL) return;
+    xmlOutputBufferWrite(buf, 1, " ");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWrite(buf, 1, ":");
+    }
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    xmlOutputBufferWrite(buf, 2, "=\"");
+    xmlAttrSerializeContent(buf, cur);
+    xmlOutputBufferWrite(buf, 1, "\"");
+}
+
+/**
+ * xmlAttrListDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the first attribute pointer
+ * @encoding:  an optional encoding string
+ *
+ * Dump a list of XML attributes
+ */
+static void
+xmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
+    if (cur == NULL) return;
+    while (cur != NULL) {
+        xmlAttrDumpOutput(ctxt, cur);
+	cur = cur->next;
+    }
+}
+
+
+
+/**
+ * xmlNodeListDumpOutput:
+ * @cur:  the first node
+ *
+ * Dump an XML node list, recursive behaviour, children are printed too.
+ */
+static void
+xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    buf = ctxt->buf;
+    while (cur != NULL) {
+	if ((ctxt->format) && (xmlIndentTreeOutput) &&
+	    ((cur->type == XML_ELEMENT_NODE) ||
+	     (cur->type == XML_COMMENT_NODE) ||
+	     (cur->type == XML_PI_NODE)))
+	    xmlOutputBufferWrite(buf, ctxt->indent_size *
+	                         (ctxt->level > ctxt->indent_nr ? 
+				  ctxt->indent_nr : ctxt->level),
+				 ctxt->indent);
+        xmlNodeDumpOutputInternal(ctxt, cur);
+	if (ctxt->format) {
+	    xmlOutputBufferWrite(buf, 1, "\n");
+	}
+	cur = cur->next;
+    }
+}
+
+#ifdef LIBXML_HTML_ENABLED
+/**
+ * xmlNodeDumpOutputInternal:
+ * @cur:  the current node
+ *
+ * Dump an HTML node, recursive behaviour, children are printed too.
+ */
+static int
+htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
+    const xmlChar *oldenc = NULL;
+    const xmlChar *oldctxtenc = ctxt->encoding;
+    const xmlChar *encoding = ctxt->encoding;
+    xmlOutputBufferPtr buf = ctxt->buf;
+    int switched_encoding = 0;
+    xmlDocPtr doc;
+
+    xmlInitParser();
+
+    doc = cur->doc;
+    if (doc != NULL) {
+        oldenc = doc->encoding;
+	if (ctxt->encoding != NULL) {
+	    doc->encoding = BAD_CAST ctxt->encoding;
+	} else if (doc->encoding != NULL) {
+	    encoding = doc->encoding;
+	}
+    }
+
+    if ((encoding != NULL) && (doc != NULL))
+	htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
+    if ((encoding == NULL) && (doc != NULL))
+	encoding = htmlGetMetaEncoding(doc);
+    if (encoding == NULL)
+	encoding = BAD_CAST "HTML";
+    if ((encoding != NULL) && (oldctxtenc == NULL) &&
+	(buf->encoder == NULL) && (buf->conv == NULL)) {
+	if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
+	    doc->encoding = oldenc;
+	    return(-1);
+	}
+	switched_encoding = 1;
+    }
+    if (ctxt->options & XML_SAVE_FORMAT)
+	htmlNodeDumpFormatOutput(buf, doc, cur,
+				       (const char *)encoding, 1);
+    else
+	htmlNodeDumpFormatOutput(buf, doc, cur,
+				       (const char *)encoding, 0);
+    /*
+     * Restore the state of the saving context at the end of the document
+     */
+    if ((switched_encoding) && (oldctxtenc == NULL)) {
+	xmlSaveClearEncoding(ctxt);
+    }
+    if (doc != NULL)
+	doc->encoding = oldenc;
+    return(0);
+}
+#endif
+
+/**
+ * xmlNodeDumpOutputInternal:
+ * @cur:  the current node
+ *
+ * Dump an XML node, recursive behaviour, children are printed too.
+ */
+static void
+xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
+    int format;
+    xmlNodePtr tmp;
+    xmlChar *start, *end;
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    buf = ctxt->buf;
+    if (cur->type == XML_XINCLUDE_START)
+	return;
+    if (cur->type == XML_XINCLUDE_END)
+	return;
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+        (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
+	return;
+    }
+#ifdef LIBXML_HTML_ENABLED
+    if (ctxt->options & XML_SAVE_XHTML) {
+        xhtmlNodeDumpOutput(ctxt, cur);
+        return;
+    }
+    if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
+         (cur->doc->type == XML_HTML_DOCUMENT_NODE) &&
+         ((ctxt->options & XML_SAVE_AS_XML) == 0)) ||
+        (ctxt->options & XML_SAVE_AS_HTML)) {
+	htmlNodeDumpOutputInternal(ctxt, cur);
+	return;
+    }
+#endif
+    if (cur->type == XML_DTD_NODE) {
+        xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
+	return;
+    }
+    if (cur->type == XML_DOCUMENT_FRAG_NODE) {
+        xmlNodeListDumpOutput(ctxt, cur->children);
+	return;
+    }
+    if (cur->type == XML_ELEMENT_DECL) {
+        xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_DECL) {
+        xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
+	return;
+    }
+    if (cur->type == XML_ENTITY_DECL) {
+        xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
+	return;
+    }
+    if (cur->type == XML_TEXT_NODE) {
+	if (cur->content != NULL) {
+	    if (cur->name != xmlStringTextNoenc) {
+                xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
+	    } else {
+		/*
+		 * Disable escaping, needed for XSLT
+		 */
+		xmlOutputBufferWriteString(buf, (const char *) cur->content);
+	    }
+	}
+
+	return;
+    }
+    if (cur->type == XML_PI_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWrite(buf, 2, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    if (cur->content != NULL) {
+		xmlOutputBufferWrite(buf, 1, " ");
+		xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    }
+	    xmlOutputBufferWrite(buf, 2, "?>");
+	} else {
+	    xmlOutputBufferWrite(buf, 2, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    xmlOutputBufferWrite(buf, 2, "?>");
+	}
+	return;
+    }
+    if (cur->type == XML_COMMENT_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWrite(buf, 4, "<!--");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    xmlOutputBufferWrite(buf, 3, "-->");
+	}
+	return;
+    }
+    if (cur->type == XML_ENTITY_REF_NODE) {
+        xmlOutputBufferWrite(buf, 1, "&");
+	xmlOutputBufferWriteString(buf, (const char *)cur->name);
+        xmlOutputBufferWrite(buf, 1, ";");
+	return;
+    }
+    if (cur->type == XML_CDATA_SECTION_NODE) {
+	if (cur->content == NULL || *cur->content == '\0') {
+	    xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
+	} else {
+	    start = end = cur->content;
+	    while (*end != '\0') {
+		if ((*end == ']') && (*(end + 1) == ']') &&
+		    (*(end + 2) == '>')) {
+		    end = end + 2;
+		    xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+		    xmlOutputBufferWrite(buf, end - start, (const char *)start);
+		    xmlOutputBufferWrite(buf, 3, "]]>");
+		    start = end;
+		}
+		end++;
+	    }
+	    if (start != end) {
+		xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+		xmlOutputBufferWriteString(buf, (const char *)start);
+		xmlOutputBufferWrite(buf, 3, "]]>");
+	    }
+	}
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+	xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
+	return;
+    }
+    if (cur->type == XML_NAMESPACE_DECL) {
+	xmlNsDumpOutput(buf, (xmlNsPtr) cur);
+	return;
+    }
+
+    format = ctxt->format;
+    if (format == 1) {
+	tmp = cur->children;
+	while (tmp != NULL) {
+	    if ((tmp->type == XML_TEXT_NODE) ||
+		(tmp->type == XML_CDATA_SECTION_NODE) ||
+		(tmp->type == XML_ENTITY_REF_NODE)) {
+		ctxt->format = 0;
+		break;
+	    }
+	    tmp = tmp->next;
+	}
+    }
+    xmlOutputBufferWrite(buf, 1, "<");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWrite(buf, 1, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (cur->nsDef)
+        xmlNsListDumpOutput(buf, 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)) {
+        xmlOutputBufferWrite(buf, 2, "/>");
+	ctxt->format = format;
+	return;
+    }
+    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->level >= 0) ctxt->level++;
+	xmlNodeListDumpOutput(ctxt, cur->children);
+	if (ctxt->level > 0) ctxt->level--;
+	if ((xmlIndentTreeOutput) && (ctxt->format))
+	    xmlOutputBufferWrite(buf, ctxt->indent_size *
+	                         (ctxt->level > ctxt->indent_nr ? 
+				  ctxt->indent_nr : ctxt->level),
+				 ctxt->indent);
+    }
+    xmlOutputBufferWrite(buf, 2, "</");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWrite(buf, 1, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    xmlOutputBufferWrite(buf, 1, ">");
+    ctxt->format = format;
+}
+
+/**
+ * xmlDocContentDumpOutput:
+ * @cur:  the document
+ *
+ * Dump an XML document.
+ */
+static int
+xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
+#ifdef LIBXML_HTML_ENABLED
+    xmlDtdPtr dtd;
+    int is_xhtml = 0;
+#endif
+    const xmlChar *oldenc = cur->encoding;
+    const xmlChar *oldctxtenc = ctxt->encoding;
+    const xmlChar *encoding = ctxt->encoding;
+    xmlCharEncodingOutputFunc oldescape = ctxt->escape;
+    xmlCharEncodingOutputFunc oldescapeAttr = ctxt->escapeAttr;
+    xmlOutputBufferPtr buf = ctxt->buf;
+    xmlCharEncoding enc;
+    int switched_encoding = 0;
+
+    xmlInitParser();
+
+    if ((cur->type != XML_HTML_DOCUMENT_NODE) &&
+        (cur->type != XML_DOCUMENT_NODE))
+	 return(-1);
+
+    if (ctxt->encoding != NULL) {
+        cur->encoding = BAD_CAST ctxt->encoding;
+    } else if (cur->encoding != NULL) {
+	encoding = cur->encoding;
+    } else if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+	encoding = (const xmlChar *)
+		     xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
+    }
+
+    if (((cur->type == XML_HTML_DOCUMENT_NODE) &&
+         ((ctxt->options & XML_SAVE_AS_XML) == 0) &&
+         ((ctxt->options & XML_SAVE_XHTML) == 0)) ||
+        (ctxt->options & XML_SAVE_AS_HTML)) {
+#ifdef LIBXML_HTML_ENABLED
+        if (encoding != NULL)
+	    htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
+        if (encoding == NULL)
+	    encoding = htmlGetMetaEncoding(cur);
+        if (encoding == NULL)
+	    encoding = BAD_CAST "HTML";
+	if ((encoding != NULL) && (oldctxtenc == NULL) &&
+	    (buf->encoder == NULL) && (buf->conv == NULL)) {
+	    if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
+		cur->encoding = oldenc;
+		return(-1);
+	    }
+	}
+        if (ctxt->options & XML_SAVE_FORMAT)
+	    htmlDocContentDumpFormatOutput(buf, cur,
+	                                   (const char *)encoding, 1);
+	else
+	    htmlDocContentDumpFormatOutput(buf, cur,
+	                                   (const char *)encoding, 0);
+	if (ctxt->encoding != NULL)
+	    cur->encoding = oldenc;
+	return(0);
+#else
+        return(-1);
+#endif
+    } else if ((cur->type == XML_DOCUMENT_NODE) ||
+               (ctxt->options & XML_SAVE_AS_XML) ||
+               (ctxt->options & XML_SAVE_XHTML)) {
+	enc = xmlParseCharEncoding((const char*) encoding);
+	if ((encoding != NULL) && (oldctxtenc == NULL) &&
+	    (buf->encoder == NULL) && (buf->conv == NULL) &&
+	    ((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
+	    if ((enc != XML_CHAR_ENCODING_UTF8) &&
+		(enc != XML_CHAR_ENCODING_NONE) &&
+		(enc != XML_CHAR_ENCODING_ASCII)) {
+		/*
+		 * we need to switch to this encoding but just for this
+		 * document since we output the XMLDecl the conversion
+		 * must be done to not generate not well formed documents.
+		 */
+		if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
+		    cur->encoding = oldenc;
+		    return(-1);
+		}
+		switched_encoding = 1;
+	    }
+	    if (ctxt->escape == xmlEscapeEntities)
+		ctxt->escape = NULL;
+	    if (ctxt->escapeAttr == xmlEscapeEntities)
+		ctxt->escapeAttr = NULL;
+	}
+
+
+	/*
+	 * Save the XML declaration
+	 */
+	if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
+	    xmlOutputBufferWrite(buf, 14, "<?xml version=");
+	    if (cur->version != NULL) 
+		xmlBufferWriteQuotedString(buf->buffer, cur->version);
+	    else
+		xmlOutputBufferWrite(buf, 5, "\"1.0\"");
+	    if (encoding != NULL) {
+		xmlOutputBufferWrite(buf, 10, " encoding=");
+		xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
+	    }
+	    switch (cur->standalone) {
+		case 0:
+		    xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
+		    break;
+		case 1:
+		    xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
+		    break;
+	    }
+	    xmlOutputBufferWrite(buf, 3, "?>\n");
+	}
+
+#ifdef LIBXML_HTML_ENABLED
+        if (ctxt->options & XML_SAVE_XHTML)
+            is_xhtml = 1;
+	if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
+	    dtd = xmlGetIntSubset(cur);
+	    if (dtd != NULL) {
+		is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
+		if (is_xhtml < 0) is_xhtml = 0;
+	    }
+	}
+#endif
+	if (cur->children != NULL) {
+	    xmlNodePtr child = cur->children;
+
+	    while (child != NULL) {
+		ctxt->level = 0;
+#ifdef LIBXML_HTML_ENABLED
+		if (is_xhtml)
+		    xhtmlNodeDumpOutput(ctxt, child);
+		else
+#endif
+		    xmlNodeDumpOutputInternal(ctxt, child);
+		xmlOutputBufferWrite(buf, 1, "\n");
+		child = child->next;
+	    }
+	}
+    }
+
+    /*
+     * Restore the state of the saving context at the end of the document
+     */
+    if ((switched_encoding) && (oldctxtenc == NULL)) {
+	xmlSaveClearEncoding(ctxt);
+	ctxt->escape = oldescape;
+	ctxt->escapeAttr = oldescapeAttr;
+    }
+    cur->encoding = oldenc;
+    return(0);
+}
+
+#ifdef LIBXML_HTML_ENABLED
+/************************************************************************
+ *									*
+ *		Functions specific to XHTML serialization		*
+ *									*
+ ************************************************************************/
+
+/**
+ * xhtmlIsEmpty:
+ * @node:  the node
+ *
+ * Check if a node is an empty xhtml node
+ *
+ * Returns 1 if the node is an empty node, 0 if not and -1 in case of error
+ */
+static int
+xhtmlIsEmpty(xmlNodePtr node) {
+    if (node == NULL)
+	return(-1);
+    if (node->type != XML_ELEMENT_NODE)
+	return(0);
+    if ((node->ns != NULL) && (!xmlStrEqual(node->ns->href, XHTML_NS_NAME)))
+	return(0);
+    if (node->children != NULL)
+	return(0);
+    switch (node->name[0]) {
+	case 'a':
+	    if (xmlStrEqual(node->name, BAD_CAST "area"))
+		return(1);
+	    return(0);
+	case 'b':
+	    if (xmlStrEqual(node->name, BAD_CAST "br"))
+		return(1);
+	    if (xmlStrEqual(node->name, BAD_CAST "base"))
+		return(1);
+	    if (xmlStrEqual(node->name, BAD_CAST "basefont"))
+		return(1);
+	    return(0);
+	case 'c':
+	    if (xmlStrEqual(node->name, BAD_CAST "col"))
+		return(1);
+	    return(0);
+	case 'f':
+	    if (xmlStrEqual(node->name, BAD_CAST "frame"))
+		return(1);
+	    return(0);
+	case 'h':
+	    if (xmlStrEqual(node->name, BAD_CAST "hr"))
+		return(1);
+	    return(0);
+	case 'i':
+	    if (xmlStrEqual(node->name, BAD_CAST "img"))
+		return(1);
+	    if (xmlStrEqual(node->name, BAD_CAST "input"))
+		return(1);
+	    if (xmlStrEqual(node->name, BAD_CAST "isindex"))
+		return(1);
+	    return(0);
+	case 'l':
+	    if (xmlStrEqual(node->name, BAD_CAST "link"))
+		return(1);
+	    return(0);
+	case 'm':
+	    if (xmlStrEqual(node->name, BAD_CAST "meta"))
+		return(1);
+	    return(0);
+	case 'p':
+	    if (xmlStrEqual(node->name, BAD_CAST "param"))
+		return(1);
+	    return(0);
+    }
+    return(0);
+}
+
+/**
+ * xhtmlAttrListDumpOutput:
+ * @cur:  the first attribute pointer
+ *
+ * Dump a list of XML attributes
+ */
+static void
+xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
+    xmlAttrPtr xml_lang = NULL;
+    xmlAttrPtr lang = NULL;
+    xmlAttrPtr name = NULL;
+    xmlAttrPtr id = NULL;
+    xmlNodePtr parent;
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    buf = ctxt->buf;
+    parent = cur->parent;
+    while (cur != NULL) {
+	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "id")))
+	    id = cur;
+	else
+	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "name")))
+	    name = cur;
+	else
+	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")))
+	    lang = cur;
+	else
+	if ((cur->ns != NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")) &&
+	    (xmlStrEqual(cur->ns->prefix, BAD_CAST "xml")))
+	    xml_lang = cur;
+	else if ((cur->ns == NULL) && 
+		 ((cur->children == NULL) ||
+		  (cur->children->content == NULL) ||
+		  (cur->children->content[0] == 0)) &&
+		 (htmlIsBooleanAttr(cur->name))) {
+	    if (cur->children != NULL)
+		xmlFreeNode(cur->children);
+	    cur->children = xmlNewText(cur->name);
+	    if (cur->children != NULL)
+		cur->children->parent = (xmlNodePtr) cur;
+	}
+        xmlAttrDumpOutput(ctxt, cur);
+	cur = cur->next;
+    }
+    /*
+     * C.8
+     */
+    if ((name != NULL) && (id == NULL)) {
+	if ((parent != NULL) && (parent->name != NULL) &&
+	    ((xmlStrEqual(parent->name, BAD_CAST "a")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "p")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "div")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "img")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "map")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "applet")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "form")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "frame")) ||
+	     (xmlStrEqual(parent->name, BAD_CAST "iframe")))) {
+	    xmlOutputBufferWrite(buf, 5, " id=\"");
+	    xmlAttrSerializeContent(buf, name);
+	    xmlOutputBufferWrite(buf, 1, "\"");
+	}
+    }
+    /*
+     * C.7.
+     */
+    if ((lang != NULL) && (xml_lang == NULL)) {
+	xmlOutputBufferWrite(buf, 11, " xml:lang=\"");
+	xmlAttrSerializeContent(buf, lang);
+	xmlOutputBufferWrite(buf, 1, "\"");
+    } else 
+    if ((xml_lang != NULL) && (lang == NULL)) {
+	xmlOutputBufferWrite(buf, 7, " lang=\"");
+	xmlAttrSerializeContent(buf, xml_lang);
+	xmlOutputBufferWrite(buf, 1, "\"");
+    }
+}
+
+/**
+ * xhtmlNodeListDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the XHTML document
+ * @cur:  the first node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML node list, recursive behaviour, children are printed too.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+static void
+xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    buf = ctxt->buf;
+    while (cur != NULL) {
+	if ((ctxt->format) && (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) {
+	    xmlOutputBufferWrite(buf, 1, "\n");
+	}
+	cur = cur->next;
+    }
+}
+
+/**
+ * xhtmlNodeDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the XHTML document
+ * @cur:  the current node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XHTML node, recursive behaviour, children are printed too.
+ */
+static void
+xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
+    int format, addmeta = 0;
+    xmlNodePtr tmp;
+    xmlChar *start, *end;
+    xmlOutputBufferPtr buf;
+
+    if (cur == NULL) return;
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+        (cur->type == XML_HTML_DOCUMENT_NODE)) {
+        xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
+	return;
+    }
+    if (cur->type == XML_XINCLUDE_START)
+	return;
+    if (cur->type == XML_XINCLUDE_END)
+	return;
+    if (cur->type == XML_DTD_NODE) {
+        xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
+	return;
+    }
+    if (cur->type == XML_DOCUMENT_FRAG_NODE) {
+        xhtmlNodeListDumpOutput(ctxt, cur->children);
+	return;
+    }
+    buf = ctxt->buf;
+    if (cur->type == XML_ELEMENT_DECL) {
+        xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_DECL) {
+        xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
+	return;
+    }
+    if (cur->type == XML_ENTITY_DECL) {
+        xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
+	return;
+    }
+    if (cur->type == XML_TEXT_NODE) {
+	if (cur->content != NULL) {
+	    if ((cur->name == xmlStringText) ||
+		(cur->name != xmlStringTextNoenc)) {
+                xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
+	    } else {
+		/*
+		 * Disable escaping, needed for XSLT
+		 */
+		xmlOutputBufferWriteString(buf, (const char *) cur->content);
+	    }
+	}
+
+	return;
+    }
+    if (cur->type == XML_PI_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWrite(buf, 2, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    if (cur->content != NULL) {
+		xmlOutputBufferWrite(buf, 1, " ");
+		xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    }
+	    xmlOutputBufferWrite(buf, 2, "?>");
+	} else {
+	    xmlOutputBufferWrite(buf, 2, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    xmlOutputBufferWrite(buf, 2, "?>");
+	}
+	return;
+    }
+    if (cur->type == XML_COMMENT_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWrite(buf, 4, "<!--");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+	    xmlOutputBufferWrite(buf, 3, "-->");
+	}
+	return;
+    }
+    if (cur->type == XML_ENTITY_REF_NODE) {
+        xmlOutputBufferWrite(buf, 1, "&");
+	xmlOutputBufferWriteString(buf, (const char *)cur->name);
+        xmlOutputBufferWrite(buf, 1, ";");
+	return;
+    }
+    if (cur->type == XML_CDATA_SECTION_NODE) {
+	if (cur->content == NULL || *cur->content == '\0') {
+	    xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
+	} else {
+	    start = end = cur->content;
+	    while (*end != '\0') {
+		if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') {
+		    end = end + 2;
+		    xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+		    xmlOutputBufferWrite(buf, end - start, (const char *)start);
+		    xmlOutputBufferWrite(buf, 3, "]]>");
+		    start = end;
+		}
+		end++;
+	    }
+	    if (start != end) {
+		xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+		xmlOutputBufferWriteString(buf, (const char *)start);
+		xmlOutputBufferWrite(buf, 3, "]]>");
+	    }
+	}
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_NODE) {
+        xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
+	return;
+    }
+
+    format = ctxt->format;
+    if (format == 1) {
+	tmp = cur->children;
+	while (tmp != NULL) {
+	    if ((tmp->type == XML_TEXT_NODE) || 
+		(tmp->type == XML_ENTITY_REF_NODE)) {
+		format = 0;
+		break;
+	    }
+	    tmp = tmp->next;
+	}
+    }
+    xmlOutputBufferWrite(buf, 1, "<");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWrite(buf, 1, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (cur->nsDef)
+        xmlNsListDumpOutput(buf, cur->nsDef);
+    if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
+	(cur->ns == NULL) && (cur->nsDef == NULL))) {
+	/*
+	 * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
+	 */
+	xmlOutputBufferWriteString(buf,
+		" xmlns=\"http://www.w3.org/1999/xhtml\"");
+    }
+    if (cur->properties != NULL)
+        xhtmlAttrListDumpOutput(ctxt, cur->properties);
+
+	if ((cur->type == XML_ELEMENT_NODE) && 
+		(cur->parent != NULL) && 
+		(cur->parent->parent == (xmlNodePtr) cur->doc) && 
+		xmlStrEqual(cur->name, BAD_CAST"head") && 
+		xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
+
+		tmp = cur->children;
+		while (tmp != NULL) {
+			if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
+				xmlChar *httpequiv;
+
+				httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
+				if (httpequiv != NULL) {
+					if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) {
+						xmlFree(httpequiv);
+						break;
+					}
+					xmlFree(httpequiv);
+				}
+			}
+			tmp = tmp->next;
+		}
+		if (tmp == NULL)
+			addmeta = 1;
+	}
+
+    if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
+	if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
+	    ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
+	    /*
+	     * C.2. Empty Elements
+	     */
+	    xmlOutputBufferWrite(buf, 3, " />");
+	} else {
+		if (addmeta == 1) {
+			xmlOutputBufferWrite(buf, 1, ">");
+			if (ctxt->format) {
+				xmlOutputBufferWrite(buf, 1, "\n");
+				if (xmlIndentTreeOutput)
+					xmlOutputBufferWrite(buf, ctxt->indent_size *
+					(ctxt->level + 1 > ctxt->indent_nr ? 
+					ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
+			}
+			xmlOutputBufferWriteString(buf,
+				"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
+			if (ctxt->encoding) {
+				xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
+			} else {
+				xmlOutputBufferWrite(buf, 5, "UTF-8");
+			}
+			xmlOutputBufferWrite(buf, 4, "\" />");
+			if (ctxt->format)
+				xmlOutputBufferWrite(buf, 1, "\n");
+		} else {
+			xmlOutputBufferWrite(buf, 1, ">");
+		}
+	    /*
+	     * C.3. Element Minimization and Empty Element Content
+	     */
+	    xmlOutputBufferWrite(buf, 2, "</");
+	    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+		xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+		xmlOutputBufferWrite(buf, 1, ":");
+	    }
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    xmlOutputBufferWrite(buf, 1, ">");
+	}
+	return;
+    }
+    xmlOutputBufferWrite(buf, 1, ">");
+	if (addmeta == 1) {
+		if (ctxt->format) {
+			xmlOutputBufferWrite(buf, 1, "\n");
+			if (xmlIndentTreeOutput)
+				xmlOutputBufferWrite(buf, ctxt->indent_size *
+				(ctxt->level + 1 > ctxt->indent_nr ? 
+				ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
+		}
+		xmlOutputBufferWriteString(buf,
+			"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
+		if (ctxt->encoding) {
+			xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
+		} else {
+			xmlOutputBufferWrite(buf, 5, "UTF-8");
+		}
+		xmlOutputBufferWrite(buf, 4, "\" />");
+	}
+    if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
+	xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
+    }
+
+#if 0
+    /*
+    * This was removed due to problems with HTML processors.
+    * See bug #345147.
+    */
+    /*
+     * 4.8. Script and Style elements
+     */
+    if ((cur->type == XML_ELEMENT_NODE) &&
+	((xmlStrEqual(cur->name, BAD_CAST "script")) ||
+	 (xmlStrEqual(cur->name, BAD_CAST "style"))) &&
+	((cur->ns == NULL) ||
+	 (xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) {
+	xmlNodePtr child = cur->children;
+
+	while (child != NULL) {
+	    if (child->type == XML_TEXT_NODE) {
+		if ((xmlStrchr(child->content, '<') == NULL) &&
+		    (xmlStrchr(child->content, '&') == NULL) &&
+		    (xmlStrstr(child->content, BAD_CAST "]]>") == NULL)) {
+		    /* Nothing to escape, so just output as is... */
+		    /* FIXME: Should we do something about "--" also? */
+		    int level = ctxt->level;
+		    int indent = ctxt->format;
+
+		    ctxt->level = 0;
+		    ctxt->format = 0;
+		    xmlOutputBufferWriteString(buf, (const char *) child->content);
+		    /* (We cannot use xhtmlNodeDumpOutput() here because
+		     * we wish to leave '>' unescaped!) */
+		    ctxt->level = level;
+		    ctxt->format = indent;
+		} else {
+		    /* We must use a CDATA section.  Unfortunately,
+		     * this will break CSS and JavaScript when read by
+		     * a browser in HTML4-compliant mode. :-( */
+		    start = end = child->content;
+		    while (*end != '\0') {
+			if (*end == ']' &&
+			    *(end + 1) == ']' &&
+			    *(end + 2) == '>') {
+			    end = end + 2;
+			    xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+			    xmlOutputBufferWrite(buf, end - start,
+						 (const char *)start);
+			    xmlOutputBufferWrite(buf, 3, "]]>");
+			    start = end;
+			}
+			end++;
+		    }
+		    if (start != end) {
+			xmlOutputBufferWrite(buf, 9, "<![CDATA[");
+			xmlOutputBufferWrite(buf, end - start,
+			                     (const char *)start);
+			xmlOutputBufferWrite(buf, 3, "]]>");
+		    }
+		}
+	    } else {
+		int level = ctxt->level;
+		int indent = ctxt->format;
+
+		ctxt->level = 0;
+		ctxt->format = 0;
+		xhtmlNodeDumpOutput(ctxt, child);
+		ctxt->level = level;
+		ctxt->format = indent;
+	    }
+	    child = child->next;
+	}
+    }
+#endif
+
+    if (cur->children != NULL) {
+	int indent = ctxt->format;
+	
+	if (format) 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))
+	    xmlOutputBufferWrite(buf, ctxt->indent_size *
+	                         (ctxt->level > ctxt->indent_nr ? 
+				  ctxt->indent_nr : ctxt->level),
+				 ctxt->indent);
+    }
+    xmlOutputBufferWrite(buf, 2, "</");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWrite(buf, 1, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    xmlOutputBufferWrite(buf, 1, ">");
+}
+#endif
+
+/************************************************************************
+ *									*
+ *			Public entry points				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSaveToFd:
+ * @fd:  a file descriptor number
+ * @encoding:  the encoding name to use or NULL
+ * @options:  a set of xmlSaveOptions
+ *
+ * Create a document saving context serializing to a file descriptor
+ * with the encoding and the options given.
+ *
+ * Returns a new serialization context or NULL in case of error.
+ */
+xmlSaveCtxtPtr
+xmlSaveToFd(int fd, const char *encoding, int options)
+{
+    xmlSaveCtxtPtr ret;
+
+    ret = xmlNewSaveCtxt(encoding, options);
+    if (ret == NULL) return(NULL);
+    ret->buf = xmlOutputBufferCreateFd(fd, ret->handler);
+    if (ret->buf == NULL) {
+	xmlFreeSaveCtxt(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlSaveToFilename:
+ * @filename:  a file name or an URL
+ * @encoding:  the encoding name to use or NULL
+ * @options:  a set of xmlSaveOptions
+ *
+ * Create a document saving context serializing to a filename or possibly
+ * to an URL (but this is less reliable) with the encoding and the options
+ * given.
+ *
+ * Returns a new serialization context or NULL in case of error.
+ */
+xmlSaveCtxtPtr
+xmlSaveToFilename(const char *filename, const char *encoding, int options)
+{
+    xmlSaveCtxtPtr ret;
+    int compression = 0; /* TODO handle compression option */
+
+    ret = xmlNewSaveCtxt(encoding, options);
+    if (ret == NULL) return(NULL);
+    ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler,
+                                             compression);
+    if (ret->buf == NULL) {
+	xmlFreeSaveCtxt(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlSaveToBuffer:
+ * @buffer:  a buffer
+ * @encoding:  the encoding name to use or NULL
+ * @options:  a set of xmlSaveOptions
+ *
+ * Create a document saving context serializing to a buffer
+ * with the encoding and the options given
+ *
+ * Returns a new serialization context or NULL in case of error.
+ */
+
+xmlSaveCtxtPtr
+xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
+{
+    xmlSaveCtxtPtr ret;
+    xmlOutputBufferPtr out_buff;
+    xmlCharEncodingHandlerPtr handler;
+
+    ret = xmlNewSaveCtxt(encoding, options);
+    if (ret == NULL) return(NULL);
+
+    if (encoding != NULL) {
+        handler = xmlFindCharEncodingHandler(encoding);
+        if (handler == NULL) {
+            xmlFree(ret);
+            return(NULL);
+        }
+    } else
+        handler = NULL;
+    out_buff = xmlOutputBufferCreateBuffer(buffer, handler);
+    if (out_buff == NULL) {
+        xmlFree(ret);
+        if (handler) xmlCharEncCloseFunc(handler);
+        return(NULL);
+    }
+
+    ret->buf = out_buff;
+    return(ret);
+}
+
+/**
+ * xmlSaveToIO:
+ * @iowrite:  an I/O write function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @encoding:  the encoding name to use or NULL
+ * @options:  a set of xmlSaveOptions
+ *
+ * Create a document saving context serializing to a file descriptor
+ * with the encoding and the options given
+ *
+ * Returns a new serialization context or NULL in case of error.
+ */
+xmlSaveCtxtPtr
+xmlSaveToIO(xmlOutputWriteCallback iowrite,
+            xmlOutputCloseCallback ioclose,
+            void *ioctx, const char *encoding, int options)
+{
+    xmlSaveCtxtPtr ret;
+
+    ret = xmlNewSaveCtxt(encoding, options);
+    if (ret == NULL) return(NULL);
+    ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler);
+    if (ret->buf == NULL) {
+	xmlFreeSaveCtxt(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlSaveDoc:
+ * @ctxt:  a document saving context
+ * @doc:  a document
+ *
+ * Save a full document to a saving context
+ * TODO: The function is not fully implemented yet as it does not return the
+ * byte count but 0 instead
+ *
+ * Returns the number of byte written or -1 in case of error
+ */
+long
+xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
+{
+    long ret = 0;
+
+    if ((ctxt == NULL) || (doc == NULL)) return(-1);
+    if (xmlDocContentDumpOutput(ctxt, doc) < 0)
+        return(-1);
+    return(ret);
+}
+
+/**
+ * xmlSaveTree:
+ * @ctxt:  a document saving context
+ * @node:  the top node of the subtree to save
+ *
+ * Save a subtree starting at the node parameter to a saving context
+ * TODO: The function is not fully implemented yet as it does not return the
+ * byte count but 0 instead
+ *
+ * Returns the number of byte written or -1 in case of error
+ */
+long
+xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node)
+{
+    long ret = 0;
+
+    if ((ctxt == NULL) || (node == NULL)) return(-1);
+    xmlNodeDumpOutputInternal(ctxt, node);
+    return(ret);
+}
+
+/**
+ * xmlSaveFlush:
+ * @ctxt:  a document saving context
+ *
+ * Flush a document saving context, i.e. make sure that all bytes have
+ * been output.
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlSaveFlush(xmlSaveCtxtPtr ctxt)
+{
+    if (ctxt == NULL) return(-1);
+    if (ctxt->buf == NULL) return(-1);
+    return(xmlOutputBufferFlush(ctxt->buf));
+}
+
+/**
+ * xmlSaveClose:
+ * @ctxt:  a document saving context
+ *
+ * Close a document saving context, i.e. make sure that all bytes have
+ * been output and free the associated data.
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlSaveClose(xmlSaveCtxtPtr ctxt)
+{
+    int ret;
+
+    if (ctxt == NULL) return(-1);
+    ret = xmlSaveFlush(ctxt);
+    xmlFreeSaveCtxt(ctxt);
+    return(ret);
+}
+
+/**
+ * xmlSaveSetEscape:
+ * @ctxt:  a document saving context
+ * @escape:  the escaping function
+ *
+ * Set a custom escaping function to be used for text in element content
+ *
+ * Returns 0 if successful or -1 in case of error.
+ */
+int
+xmlSaveSetEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape)
+{
+    if (ctxt == NULL) return(-1);
+    ctxt->escape = escape;
+    return(0);
+}
+
+/**
+ * xmlSaveSetAttrEscape:
+ * @ctxt:  a document saving context
+ * @escape:  the escaping function
+ *
+ * Set a custom escaping function to be used for text in attribute content
+ *
+ * Returns 0 if successful or -1 in case of error.
+ */
+int
+xmlSaveSetAttrEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape)
+{
+    if (ctxt == NULL) return(-1);
+    ctxt->escapeAttr = escape;
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *		Public entry points based on buffers			*
+ *									*
+ ************************************************************************/
+/**
+ * xmlAttrSerializeTxtContent:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @attr: the attribute node
+ * @string: the text content
+ *
+ * Serialize text attribute values to an xml simple buffer
+ */
+void
+xmlAttrSerializeTxtContent(xmlBufferPtr buf, xmlDocPtr doc,
+                           xmlAttrPtr attr, const xmlChar * string)
+{
+    xmlChar *base, *cur;
+
+    if (string == NULL)
+        return;
+    base = cur = (xmlChar *) string;
+    while (*cur != 0) {
+        if (*cur == '\n') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&#10;", 5);
+            cur++;
+            base = cur;
+        } else if (*cur == '\r') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&#13;", 5);
+            cur++;
+            base = cur;
+        } else if (*cur == '\t') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&#9;", 4);
+            cur++;
+            base = cur;
+        } else if (*cur == '"') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
+            cur++;
+            base = cur;
+        } else if (*cur == '<') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&lt;", 4);
+            cur++;
+            base = cur;
+        } else if (*cur == '>') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&gt;", 4);
+            cur++;
+            base = cur;
+        } else if (*cur == '&') {
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            xmlBufferAdd(buf, BAD_CAST "&amp;", 5);
+            cur++;
+            base = cur;
+        } else if ((*cur >= 0x80) && ((doc == NULL) ||
+                                      (doc->encoding == NULL))) {
+            /*
+             * We assume we have UTF-8 content.
+             */
+            unsigned char tmp[12];
+            int val = 0, l = 1;
+
+            if (base != cur)
+                xmlBufferAdd(buf, base, cur - base);
+            if (*cur < 0xC0) {
+                xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL);
+                if (doc != NULL)
+                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+		xmlSerializeHexCharRef(tmp, *cur);
+                xmlBufferAdd(buf, (xmlChar *) tmp, -1);
+                cur++;
+                base = cur;
+                continue;
+            } else if (*cur < 0xE0) {
+                val = (cur[0]) & 0x1F;
+                val <<= 6;
+                val |= (cur[1]) & 0x3F;
+                l = 2;
+            } else if (*cur < 0xF0) {
+                val = (cur[0]) & 0x0F;
+                val <<= 6;
+                val |= (cur[1]) & 0x3F;
+                val <<= 6;
+                val |= (cur[2]) & 0x3F;
+                l = 3;
+            } else if (*cur < 0xF8) {
+                val = (cur[0]) & 0x07;
+                val <<= 6;
+                val |= (cur[1]) & 0x3F;
+                val <<= 6;
+                val |= (cur[2]) & 0x3F;
+                val <<= 6;
+                val |= (cur[3]) & 0x3F;
+                l = 4;
+            }
+            if ((l == 1) || (!IS_CHAR(val))) {
+                xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL);
+                if (doc != NULL)
+                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
+		
+		xmlSerializeHexCharRef(tmp, *cur);
+                xmlBufferAdd(buf, (xmlChar *) tmp, -1);
+                cur++;
+                base = cur;
+                continue;
+            }
+            /*
+             * We could do multiple things here. Just save
+             * as a char ref
+             */
+	    xmlSerializeHexCharRef(tmp, val);
+            xmlBufferAdd(buf, (xmlChar *) tmp, -1);
+            cur += l;
+            base = cur;
+        } else {
+            cur++;
+        }
+    }
+    if (base != cur)
+        xmlBufferAdd(buf, base, cur - base);
+}
+
+/**
+ * xmlNodeDump:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ *
+ * Dump an XML node, recursive behaviour,children are printed too.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ *
+ * Returns the number of bytes written to the buffer or -1 in case of error
+ */
+int
+xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
+            int format)
+{
+    unsigned int use;
+    int ret;
+    xmlOutputBufferPtr outbuf;
+
+    xmlInitParser();
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNodeDump : node == NULL\n");
+#endif
+        return (-1);
+    }
+    if (buf == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlNodeDump : buf == NULL\n");
+#endif
+        return (-1);
+    }
+    outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
+    if (outbuf == NULL) {
+        xmlSaveErrMemory("creating buffer");
+        return (-1);
+    }
+    memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
+    outbuf->buffer = buf;
+    outbuf->encoder = NULL;
+    outbuf->writecallback = NULL;
+    outbuf->closecallback = NULL;
+    outbuf->context = NULL;
+    outbuf->written = 0;
+
+    use = buf->use;
+    xmlNodeDumpOutput(outbuf, doc, cur, level, format, NULL);
+    xmlFree(outbuf);
+    ret = buf->use - use;
+    return (ret);
+}
+
+/**
+ * xmlElemDump:
+ * @f:  the FILE * for the output
+ * @doc:  the document
+ * @cur:  the current node
+ *
+ * Dump an XML/HTML node, recursive behaviour, children are printed too.
+ */
+void
+xmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur)
+{
+    xmlOutputBufferPtr outbuf;
+
+    xmlInitParser();
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlElemDump : cur == NULL\n");
+#endif
+        return;
+    }
+#ifdef DEBUG_TREE
+    if (doc == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "xmlElemDump : doc == NULL\n");
+    }
+#endif
+
+    outbuf = xmlOutputBufferCreateFile(f, NULL);
+    if (outbuf == NULL)
+        return;
+    if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
+#ifdef LIBXML_HTML_ENABLED
+        htmlNodeDumpOutput(outbuf, doc, cur, NULL);
+#else
+	xmlSaveErr(XML_ERR_INTERNAL_ERROR, cur, "HTML support not compiled in\n");
+#endif /* LIBXML_HTML_ENABLED */
+    } else
+        xmlNodeDumpOutput(outbuf, doc, cur, 0, 1, NULL);
+    xmlOutputBufferClose(outbuf);
+}
+
+/************************************************************************
+ *									*
+ *		Saving functions front-ends				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlNodeDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML node, recursive behaviour, children are printed too.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+void
+xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+                  int level, int format, const char *encoding)
+{
+    xmlSaveCtxt ctxt;
+#ifdef LIBXML_HTML_ENABLED
+    xmlDtdPtr dtd;
+    int is_xhtml = 0;
+#endif
+
+    xmlInitParser();
+
+    if ((buf == NULL) || (cur == NULL)) return;
+
+    if (encoding == NULL)
+        encoding = "UTF-8";
+
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = doc;
+    ctxt.buf = buf;
+    ctxt.level = level;
+    ctxt.format = format;
+    ctxt.encoding = (const xmlChar *) encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+
+#ifdef LIBXML_HTML_ENABLED
+    dtd = xmlGetIntSubset(doc);
+    if (dtd != NULL) {
+	is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
+	if (is_xhtml < 0)
+	    is_xhtml = 0;
+    }
+
+    if (is_xhtml)
+        xhtmlNodeDumpOutput(&ctxt, cur);
+    else
+#endif
+        xmlNodeDumpOutputInternal(&ctxt, cur);
+}
+
+/**
+ * xmlDocDumpFormatMemoryEnc:
+ * @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 with xmlFree().
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+
+void
+xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
+		int * doc_txt_len, const char * txt_encoding,
+		int format) {
+    xmlSaveCtxt ctxt;
+    int                         dummy = 0;
+    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;
+        return;
+    }
+
+    *doc_txt_ptr = NULL;
+    *doc_txt_len = 0;
+
+    if (out_doc == NULL) {
+        /*  No document, no output  */
+        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) {
+	conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
+	if ( conv_hdlr == NULL ) {
+	    xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, (xmlNodePtr) out_doc,
+		       txt_encoding);
+	    return;
+	}
+    }
+
+    if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
+        xmlSaveErrMemory("creating buffer");
+        return;
+    }
+
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = out_doc;
+    ctxt.buf = out_buff;
+    ctxt.level = 0;
+    ctxt.format = format;
+    ctxt.encoding = (const xmlChar *) txt_encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+    xmlDocContentDumpOutput(&ctxt, out_doc);
+    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;
+        xmlSaveErrMemory("creating output");
+    }
+
+    return;
+}
+
+/**
+ * xmlDocDumpMemory:
+ * @cur:  the document
+ * @mem:  OUT: the memory pointer
+ * @size:  OUT: the memory length
+ *
+ * Dump an XML document in memory and return the #xmlChar * and it's size
+ * in bytes. It's up to the caller to free the memory with xmlFree().
+ * The resulting byte array is zero terminated, though the last 0 is not
+ * included in the returned size.
+ */
+void
+xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
+    xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
+}
+
+/**
+ * xmlDocDumpFormatMemory:
+ * @cur:  the document
+ * @mem:  OUT: the memory pointer
+ * @size:  OUT: the memory length
+ * @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 with xmlFree().
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+void
+xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
+    xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
+}
+
+/**
+ * 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
+ *
+ * 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 with xmlFree().
+ */
+
+void
+xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
+	            int * doc_txt_len, const char * txt_encoding) {
+    xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
+	                      txt_encoding, 0);
+}
+
+/**
+ * xmlDocFormatDump:
+ * @f:  the FILE*
+ * @cur:  the document
+ * @format: should formatting spaces been added
+ *
+ * Dump an XML document to an open FILE.
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+int
+xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
+    xmlSaveCtxt ctxt;
+    xmlOutputBufferPtr buf;
+    const char * encoding;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int ret;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlDocDump : document == NULL\n");
+#endif
+	return(-1);
+    }
+    encoding = (const char *) cur->encoding;
+
+    if (encoding != NULL) {
+	handler = xmlFindCharEncodingHandler(encoding);
+	if (handler == NULL) {
+	    xmlFree((char *) cur->encoding);
+	    cur->encoding = NULL;
+	    encoding = NULL;
+	}
+    }
+    buf = xmlOutputBufferCreateFile(f, handler);
+    if (buf == NULL) return(-1);
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = cur;
+    ctxt.buf = buf;
+    ctxt.level = 0;
+    ctxt.format = format;
+    ctxt.encoding = (const xmlChar *) encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+    xmlDocContentDumpOutput(&ctxt, cur);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * xmlDocDump:
+ * @f:  the FILE*
+ * @cur:  the document
+ *
+ * Dump an XML document to an open FILE.
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlDocDump(FILE *f, xmlDocPtr cur) {
+    return(xmlDocFormatDump (f, cur, 0));
+}
+
+/**
+ * xmlSaveFileTo:
+ * @buf:  an output I/O buffer
+ * @cur:  the document
+ * @encoding:  the encoding if any assuming the I/O layer handles the trancoding
+ *
+ * Dump an XML document to an I/O buffer.
+ * Warning ! This call xmlOutputBufferClose() on buf which is not available
+ * after this call.
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
+    xmlSaveCtxt ctxt;
+    int ret;
+
+    if (buf == NULL) return(-1);
+    if (cur == NULL) {
+        xmlOutputBufferClose(buf);
+	return(-1);
+    }
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = cur;
+    ctxt.buf = buf;
+    ctxt.level = 0;
+    ctxt.format = 0;
+    ctxt.encoding = (const xmlChar *) encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+    xmlDocContentDumpOutput(&ctxt, cur);
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * xmlSaveFormatFileTo:
+ * @buf:  an output I/O buffer
+ * @cur:  the document
+ * @encoding:  the encoding if any assuming the I/O layer handles the trancoding
+ * @format: should formatting spaces been added
+ *
+ * Dump an XML document to an I/O buffer.
+ * Warning ! This call xmlOutputBufferClose() on buf which is not available
+ * after this call.
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur,
+                    const char *encoding, int format)
+{
+    xmlSaveCtxt ctxt;
+    int ret;
+
+    if (buf == NULL) return(-1);
+    if ((cur == NULL) ||
+        ((cur->type != XML_DOCUMENT_NODE) &&
+	 (cur->type != XML_HTML_DOCUMENT_NODE))) {
+        xmlOutputBufferClose(buf);
+	return(-1);
+    }
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = cur;
+    ctxt.buf = buf;
+    ctxt.level = 0;
+    ctxt.format = format;
+    ctxt.encoding = (const xmlChar *) encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+    xmlDocContentDumpOutput(&ctxt, cur);
+    ret = xmlOutputBufferClose(buf);
+    return (ret);
+}
+
+/**
+ * xmlSaveFormatFileEnc:
+ * @filename:  the filename or URL to output
+ * @cur:  the document being saved
+ * @encoding:  the name of the encoding to use or NULL.
+ * @format:  should formatting spaces be added.
+ *
+ * Dump an XML document to a file or an URL.
+ *
+ * Returns the number of bytes written or -1 in case of error.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ */
+int
+xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
+			const char * encoding, int format ) {
+    xmlSaveCtxt ctxt;
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int ret;
+
+    if (cur == NULL)
+	return(-1);
+
+    if (encoding == NULL)
+	encoding = (const char *) cur->encoding;
+
+    if (encoding != NULL) {
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+    }
+
+#ifdef HAVE_ZLIB_H
+    if (cur->compression < 0) cur->compression = xmlGetCompressMode();
+#endif
+    /* 
+     * save the content to a temp buffer.
+     */
+    buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
+    if (buf == NULL) return(-1);
+    memset(&ctxt, 0, sizeof(ctxt));
+    ctxt.doc = cur;
+    ctxt.buf = buf;
+    ctxt.level = 0;
+    ctxt.format = format;
+    ctxt.encoding = (const xmlChar *) encoding;
+    xmlSaveCtxtInit(&ctxt);
+    ctxt.options |= XML_SAVE_AS_XML;
+
+    xmlDocContentDumpOutput(&ctxt, cur);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+
+/**
+ * xmlSaveFileEnc:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ * @encoding:  the name of an encoding (or NULL)
+ *
+ * Dump an XML document, converting it to the given encoding
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
+    return ( xmlSaveFormatFileEnc( filename, cur, encoding, 0 ) );
+}
+
+/**
+ * xmlSaveFormatFile:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ * @format:  should formatting spaces been added
+ *
+ * Dump an XML document to a file. Will use compression if
+ * compiled in and enabled. If @filename is "-" the stdout file is
+ * used. If @format is set then the document will be indented on output.
+ * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
+ * or xmlKeepBlanksDefault(0) was called
+ *
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlSaveFormatFile(const char *filename, xmlDocPtr cur, int format) {
+    return ( xmlSaveFormatFileEnc( filename, cur, NULL, format ) );
+}
+
+/**
+ * xmlSaveFile:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ *
+ * Dump an XML document to a file. Will use compression if
+ * compiled in and enabled. If @filename is "-" the stdout file is
+ * used.
+ * returns: the number of bytes written or -1 in case of failure.
+ */
+int
+xmlSaveFile(const char *filename, xmlDocPtr cur) {
+    return(xmlSaveFormatFileEnc(filename, cur, NULL, 0));
+}
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#define bottom_xmlsave
+#include "elfgcchack.h"
diff --git a/src/xmlschemas.c b/src/xmlschemas.c
new file mode 100644
index 0000000..8be14d8
--- /dev/null
+++ b/src/xmlschemas.c
@@ -0,0 +1,28766 @@
+/*
+ * schemas.c : implementation of the XML Schema handling and
+ *             schema validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+/*
+ * TODO:
+ *   - when types are redefined in includes, check that all
+ *     types in the redef list are equal
+ *     -> need a type equality operation.
+ *   - if we don't intend to use the schema for schemas, we
+ *     need to validate all schema attributes (ref, type, name)
+ *     against their types.
+ *   - Eliminate item creation for: ??
+ *
+ * URGENT TODO:
+ *   - For xsi-driven schema acquisition, augment the IDCs after every
+ *     acquisition episode (xmlSchemaAugmentIDC).
+ *
+ * NOTES:
+ *   - Elimated item creation for: <restriction>, <extension>,
+ *     <simpleContent>, <complexContent>, <list>, <union>
+ *
+ * PROBLEMS:
+ *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
+ *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
+ *     XPath will have trouble to resolve to this namespace, since not known.
+ *
+ *
+ * CONSTRAINTS:
+ *
+ * Schema Component Constraint:
+ *   All Group Limited (cos-all-limited)
+ *   Status: complete
+ *   (1.2)
+ *     In xmlSchemaGroupDefReferenceTermFixup() and
+ *   (2)
+ *     In xmlSchemaParseModelGroup()
+ *     TODO: Actually this should go to component-level checks,
+ *     but is done here due to performance. Move it to an other layer
+ *     is schema construction via an API is implemented.
+ */
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/hash.h>
+#include <libxml/uri.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/schemasInternals.h>
+#include <libxml/xmlschemastypes.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/dict.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
+#ifdef LIBXML_READER_ENABLED
+#include <libxml/xmlreader.h>
+#endif
+
+/* #define DEBUG 1 */
+
+/* #define DEBUG_CONTENT 1 */
+
+/* #define DEBUG_TYPE 1 */
+
+/* #define DEBUG_CONTENT_REGEXP 1 */
+
+/* #define DEBUG_AUTOMATA 1 */
+
+/* #define DEBUG_IDC */
+
+/* #define DEBUG_IDC_NODE_TABLE */
+
+/* #define WXS_ELEM_DECL_CONS_ENABLED */
+
+#ifdef DEBUG_IDC
+ #ifndef DEBUG_IDC_NODE_TABLE
+  #define DEBUG_IDC_NODE_TABLE
+ #endif
+#endif
+
+/* #define ENABLE_PARTICLE_RESTRICTION 1 */
+
+#define ENABLE_REDEFINE
+
+/* #define ENABLE_NAMED_LOCALS */
+
+/* #define ENABLE_IDC_NODE_TABLES_TEST */
+
+#define DUMP_CONTENT_MODEL
+
+#ifdef LIBXML_READER_ENABLED
+/* #define XML_SCHEMA_READER_ENABLED */
+#endif
+
+#define UNBOUNDED (1 << 30)
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
+
+/*
+ * The XML Schemas namespaces
+ */
+static const xmlChar *xmlSchemaNs = (const xmlChar *)
+    "http://www.w3.org/2001/XMLSchema";
+
+static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
+    "http://www.w3.org/2001/XMLSchema-instance";
+
+static const xmlChar *xmlNamespaceNs = (const xmlChar *)
+    "http://www.w3.org/2000/xmlns/";
+
+/*
+* Come casting macros.
+*/
+#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
+#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
+#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
+#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
+#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
+#define WXS_PTC_CAST (xmlSchemaParticlePtr)
+#define WXS_TYPE_CAST (xmlSchemaTypePtr)
+#define WXS_ELEM_CAST (xmlSchemaElementPtr)
+#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
+#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
+#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
+#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
+#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
+#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
+#define WXS_IDC_CAST (xmlSchemaIDCPtr)
+#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
+#define WXS_LIST_CAST (xmlSchemaItemListPtr)
+
+/*
+* Macros to query common properties of components.
+*/
+#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
+
+#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
+/*
+* Macros for element declarations.
+*/
+#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
+
+#define WXS_SUBST_HEAD(item) (item)->refDecl
+/*
+* Macros for attribute declarations.
+*/
+#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
+/*
+* Macros for attribute uses.
+*/
+#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
+
+#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
+
+#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
+
+#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
+/*
+* Macros for attribute groups.
+*/
+#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
+#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
+/*
+* Macros for particles.
+*/
+#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
+
+#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
+
+#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
+
+#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
+/*
+* Macros for model groups definitions.
+*/
+#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
+/*
+* Macros for model groups.
+*/
+#define WXS_IS_MODEL_GROUP(i) \
+    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
+     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
+     ((i)->type == XML_SCHEMA_TYPE_ALL))
+
+#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
+/*
+* Macros for schema buckets.
+*/
+#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
+    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
+
+#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
+    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
+
+#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
+
+#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
+/*
+* Macros for complex/simple types.
+*/
+#define WXS_IS_ANYTYPE(i) \
+     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
+      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
+
+#define WXS_IS_COMPLEX(i) \
+    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
+     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
+
+#define WXS_IS_SIMPLE(item) \
+    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
+     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
+      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
+
+#define WXS_IS_ANY_SIMPLE_TYPE(i) \
+    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
+      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
+
+#define WXS_IS_RESTRICTION(t) \
+    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
+
+#define WXS_IS_EXTENSION(t) \
+    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
+
+#define WXS_IS_TYPE_NOT_FIXED(i) \
+    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
+     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
+
+#define WXS_IS_TYPE_NOT_FIXED_1(item) \
+    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
+     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
+
+#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
+
+#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
+/*
+* Macros for exclusively for complex types.
+*/
+#define WXS_HAS_COMPLEX_CONTENT(item) \
+    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
+     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
+     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
+
+#define WXS_HAS_SIMPLE_CONTENT(item) \
+    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
+     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
+
+#define WXS_HAS_MIXED_CONTENT(item) \
+    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
+
+#define WXS_EMPTIABLE(t) \
+    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
+
+#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
+
+#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
+
+#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
+/*
+* Macros for exclusively for simple types.
+*/
+#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
+
+#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
+
+#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
+
+#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
+/*
+* Misc parser context macros.
+*/
+#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
+
+#define WXS_HAS_BUCKETS(ctx) \
+( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
+(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
+
+#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
+
+#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
+
+#define WXS_SCHEMA(ctx) (ctx)->schema
+
+#define WXS_ADD_LOCAL(ctx, item) \
+    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
+
+#define WXS_ADD_GLOBAL(ctx, item) \
+    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
+
+#define WXS_ADD_PENDING(ctx, item) \
+    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
+/*
+* xmlSchemaItemList macros.
+*/
+#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
+/*
+* Misc macros.
+*/
+#define IS_SCHEMA(node, type) \
+   ((node != NULL) && (node->ns != NULL) && \
+    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
+    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
+
+#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
+
+/*
+* Since we put the default/fixed values into the dict, we can
+* use pointer comparison for those values.
+* REMOVED: (xmlStrEqual((v1), (v2)))
+*/
+#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
+
+#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
+
+#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
+
+#define HFAILURE if (res == -1) goto exit_failure;
+
+#define HERROR if (res != 0) goto exit_error;
+
+#define HSTOP(ctx) if ((ctx)->stop) goto exit;
+/*
+* Some flags used for various schema constraints.
+*/
+#define SUBSET_RESTRICTION  1<<0
+#define SUBSET_EXTENSION    1<<1
+#define SUBSET_SUBSTITUTION 1<<2
+#define SUBSET_LIST         1<<3
+#define SUBSET_UNION        1<<4
+
+typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
+typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
+
+typedef struct _xmlSchemaItemList xmlSchemaItemList;
+typedef xmlSchemaItemList *xmlSchemaItemListPtr;
+struct _xmlSchemaItemList {
+    void **items;  /* used for dynamic addition of schemata */
+    int nbItems; /* used for dynamic addition of schemata */
+    int sizeItems; /* used for dynamic addition of schemata */
+};
+
+#define XML_SCHEMA_CTXT_PARSER 1
+#define XML_SCHEMA_CTXT_VALIDATOR 2
+
+typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
+typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
+struct _xmlSchemaAbstractCtxt {
+    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
+};
+
+typedef struct _xmlSchemaBucket xmlSchemaBucket;
+typedef xmlSchemaBucket *xmlSchemaBucketPtr;
+
+#define XML_SCHEMA_SCHEMA_MAIN 0
+#define XML_SCHEMA_SCHEMA_IMPORT 1
+#define XML_SCHEMA_SCHEMA_INCLUDE 2
+#define XML_SCHEMA_SCHEMA_REDEFINE 3
+
+/**
+ * xmlSchemaSchemaRelation:
+ *
+ * Used to create a graph of schema relationships.
+ */
+typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
+typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
+struct _xmlSchemaSchemaRelation {
+    xmlSchemaSchemaRelationPtr next;
+    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
+    const xmlChar *importNamespace;
+    xmlSchemaBucketPtr bucket;
+};
+
+#define XML_SCHEMA_BUCKET_MARKED 1<<0
+#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
+
+struct _xmlSchemaBucket {
+    int type;
+    int flags;
+    const xmlChar *schemaLocation;
+    const xmlChar *origTargetNamespace;
+    const xmlChar *targetNamespace;
+    xmlDocPtr doc;
+    xmlSchemaSchemaRelationPtr relations;
+    int located;
+    int parsed;
+    int imported;
+    int preserveDoc;
+    xmlSchemaItemListPtr globals; /* Global components. */
+    xmlSchemaItemListPtr locals; /* Local components. */
+};
+
+/**
+ * xmlSchemaImport:
+ * (extends xmlSchemaBucket)
+ *
+ * Reflects a schema. Holds some information
+ * about the schema and its toplevel components. Duplicate
+ * toplevel components are not checked at this level.
+ */
+typedef struct _xmlSchemaImport xmlSchemaImport;
+typedef xmlSchemaImport *xmlSchemaImportPtr;
+struct _xmlSchemaImport {
+    int type; /* Main OR import OR include. */
+    int flags;
+    const xmlChar *schemaLocation; /* The URI of the schema document. */
+    /* For chameleon includes, @origTargetNamespace will be NULL */
+    const xmlChar *origTargetNamespace;
+    /*
+    * For chameleon includes, @targetNamespace will be the
+    * targetNamespace of the including schema.
+    */
+    const xmlChar *targetNamespace;
+    xmlDocPtr doc; /* The schema node-tree. */
+    /* @relations will hold any included/imported/redefined schemas. */
+    xmlSchemaSchemaRelationPtr relations;
+    int located;
+    int parsed;
+    int imported;
+    int preserveDoc;
+    xmlSchemaItemListPtr globals;
+    xmlSchemaItemListPtr locals;
+    /* The imported schema. */
+    xmlSchemaPtr schema;
+};
+
+/*
+* (extends xmlSchemaBucket)
+*/
+typedef struct _xmlSchemaInclude xmlSchemaInclude;
+typedef xmlSchemaInclude *xmlSchemaIncludePtr;
+struct _xmlSchemaInclude {
+    int type;
+    int flags;
+    const xmlChar *schemaLocation;
+    const xmlChar *origTargetNamespace;
+    const xmlChar *targetNamespace;
+    xmlDocPtr doc;
+    xmlSchemaSchemaRelationPtr relations;
+    int located;
+    int parsed;
+    int imported;
+    int preserveDoc;
+    xmlSchemaItemListPtr globals; /* Global components. */
+    xmlSchemaItemListPtr locals; /* Local components. */
+
+    /* The owning main or import schema bucket. */
+    xmlSchemaImportPtr ownerImport;
+};
+
+/**
+ * xmlSchemaBasicItem:
+ *
+ * The abstract base type for schema components.
+ */
+typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
+typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
+struct _xmlSchemaBasicItem {
+    xmlSchemaTypeType type;
+};
+
+/**
+ * xmlSchemaAnnotItem:
+ *
+ * The abstract base type for annotated schema components.
+ * (Extends xmlSchemaBasicItem)
+ */
+typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
+typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
+struct _xmlSchemaAnnotItem {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+};
+
+/**
+ * xmlSchemaTreeItem:
+ *
+ * The abstract base type for tree-like structured schema components.
+ * (Extends xmlSchemaAnnotItem)
+ */
+typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
+typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
+struct _xmlSchemaTreeItem {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next;
+    xmlSchemaTreeItemPtr children;
+};
+
+
+#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
+/**
+ * xmlSchemaAttributeUsePtr:
+ *
+ * The abstract base type for tree-like structured schema components.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
+typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
+struct _xmlSchemaAttributeUse {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
+    /*
+    * The attr. decl. OR a QName-ref. to an attr. decl. OR
+    * a QName-ref. to an attribute group definition.
+    */
+    xmlSchemaAttributePtr attrDecl;
+
+    int flags;
+    xmlNodePtr node;
+    int occurs; /* required, optional */
+    const xmlChar * defValue;
+    xmlSchemaValPtr defVal;
+};
+
+/**
+ * xmlSchemaAttributeUseProhibPtr:
+ *
+ * A helper component to reflect attribute prohibitions.
+ * (Extends xmlSchemaBasicItem)
+ */
+typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
+typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
+struct _xmlSchemaAttributeUseProhib {
+    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
+    xmlNodePtr node;
+    const xmlChar *name;
+    const xmlChar *targetNamespace;
+    int isRef;
+};
+
+/**
+ * xmlSchemaRedef:
+ */
+typedef struct _xmlSchemaRedef xmlSchemaRedef;
+typedef xmlSchemaRedef *xmlSchemaRedefPtr;
+struct _xmlSchemaRedef {
+    xmlSchemaRedefPtr next;
+    xmlSchemaBasicItemPtr item; /* The redefining component. */
+    xmlSchemaBasicItemPtr reference; /* The referencing component. */
+    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
+    const xmlChar *refName; /* The name of the to-be-redefined component. */
+    const xmlChar *refTargetNs; /* The target namespace of the
+                                   to-be-redefined comp. */
+    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
+};
+
+/**
+ * xmlSchemaConstructionCtxt:
+ */
+typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
+typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
+struct _xmlSchemaConstructionCtxt {
+    xmlSchemaPtr mainSchema; /* The main schema. */
+    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
+    xmlDictPtr dict;
+    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
+    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
+    xmlSchemaBucketPtr bucket; /* The current schema bucket */
+    xmlSchemaItemListPtr pending; /* All Components of all schemas that
+                                     need to be fixed. */
+    xmlHashTablePtr substGroups;
+    xmlSchemaRedefPtr redefs;
+    xmlSchemaRedefPtr lastRedef;
+};
+
+#define XML_SCHEMAS_PARSE_ERROR		1
+#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
+
+struct _xmlSchemaParserCtxt {
+    int type;
+    void *errCtxt;             /* user specific error context */
+    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
+    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
+    int err;
+    int nberrors;
+    xmlStructuredErrorFunc serror;
+
+    xmlSchemaConstructionCtxtPtr constructor;
+    int ownsConstructor; /* TODO: Move this to parser *flags*. */
+
+    /* xmlSchemaPtr topschema;	*/
+    /* xmlHashTablePtr namespaces;  */
+
+    xmlSchemaPtr schema;        /* The main schema in use */
+    int counter;
+
+    const xmlChar *URL;
+    xmlDocPtr doc;
+    int preserve;		/* Whether the doc should be freed  */
+
+    const char *buffer;
+    int size;
+
+    /*
+     * Used to build complex element content models
+     */
+    xmlAutomataPtr am;
+    xmlAutomataStatePtr start;
+    xmlAutomataStatePtr end;
+    xmlAutomataStatePtr state;
+
+    xmlDictPtr dict;		/* dictionnary for interned string names */
+    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
+    int options;
+    xmlSchemaValidCtxtPtr vctxt;
+    int isS4S;
+    int isRedefine;
+    int xsiAssemble;
+    int stop; /* If the parser should stop; i.e. a critical error. */
+    const xmlChar *targetNamespace;
+    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
+
+    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
+    int redefCounter; /* Used for redefinitions. */
+    xmlSchemaItemListPtr attrProhibs;
+};
+
+/**
+ * xmlSchemaQNameRef:
+ *
+ * A component reference item (not a schema component)
+ * (Extends xmlSchemaBasicItem)
+ */
+typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
+typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
+struct _xmlSchemaQNameRef {
+    xmlSchemaTypeType type;
+    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
+    xmlSchemaTypeType itemType;
+    const xmlChar *name;
+    const xmlChar *targetNamespace;
+    xmlNodePtr node;
+};
+
+/**
+ * xmlSchemaParticle:
+ *
+ * A particle component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaParticle xmlSchemaParticle;
+typedef xmlSchemaParticle *xmlSchemaParticlePtr;
+struct _xmlSchemaParticle {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next; /* next particle */
+    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
+	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
+        etc.) */
+    int minOccurs;
+    int maxOccurs;
+    xmlNodePtr node;
+};
+
+/**
+ * xmlSchemaModelGroup:
+ *
+ * A model group component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
+typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
+struct _xmlSchemaModelGroup {
+    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next; /* not used */
+    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
+    xmlNodePtr node;
+};
+
+#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
+#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
+/**
+ * xmlSchemaModelGroupDef:
+ *
+ * A model group definition component.
+ * (Extends xmlSchemaTreeItem)
+ */
+typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
+typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
+struct _xmlSchemaModelGroupDef {
+    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next; /* not used */
+    xmlSchemaTreeItemPtr children; /* the "model group" */
+    const xmlChar *name;
+    const xmlChar *targetNamespace;
+    xmlNodePtr node;
+    int flags;
+};
+
+typedef struct _xmlSchemaIDC xmlSchemaIDC;
+typedef xmlSchemaIDC *xmlSchemaIDCPtr;
+
+/**
+ * xmlSchemaIDCSelect:
+ *
+ * The identity-constraint "field" and "selector" item, holding the
+ * XPath expression.
+ */
+typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
+typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
+struct _xmlSchemaIDCSelect {
+    xmlSchemaIDCSelectPtr next;
+    xmlSchemaIDCPtr idc;
+    int index; /* an index position if significant for IDC key-sequences */
+    const xmlChar *xpath; /* the XPath expression */
+    void *xpathComp; /* the compiled XPath expression */
+};
+
+/**
+ * xmlSchemaIDC:
+ *
+ * The identity-constraint definition component.
+ * (Extends xmlSchemaAnnotItem)
+ */
+
+struct _xmlSchemaIDC {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaIDCPtr next;
+    xmlNodePtr node;
+    const xmlChar *name;
+    const xmlChar *targetNamespace;
+    xmlSchemaIDCSelectPtr selector;
+    xmlSchemaIDCSelectPtr fields;
+    int nbFields;
+    xmlSchemaQNameRefPtr ref;
+};
+
+/**
+ * xmlSchemaIDCAug:
+ *
+ * The augmented IDC information used for validation.
+ */
+typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
+typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
+struct _xmlSchemaIDCAug {
+    xmlSchemaIDCAugPtr next; /* next in a list */
+    xmlSchemaIDCPtr def; /* the IDC definition */
+    int keyrefDepth; /* the lowest tree level to which IDC
+                        tables need to be bubbled upwards */
+};
+
+/**
+ * xmlSchemaPSVIIDCKeySequence:
+ *
+ * The key sequence of a node table item.
+ */
+typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
+typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
+struct _xmlSchemaPSVIIDCKey {
+    xmlSchemaTypePtr type;
+    xmlSchemaValPtr val;
+};
+
+/**
+ * xmlSchemaPSVIIDCNode:
+ *
+ * The node table item of a node table.
+ */
+typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
+typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
+struct _xmlSchemaPSVIIDCNode {
+    xmlNodePtr node;
+    xmlSchemaPSVIIDCKeyPtr *keys;
+    int nodeLine;
+    int nodeQNameID;
+
+};
+
+/**
+ * xmlSchemaPSVIIDCBinding:
+ *
+ * The identity-constraint binding item of the [identity-constraint table].
+ */
+typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
+typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
+struct _xmlSchemaPSVIIDCBinding {
+    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
+    xmlSchemaIDCPtr definition; /* the IDC definition */
+    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
+    int nbNodes; /* number of entries in the node table */
+    int sizeNodes; /* size of the node table */
+    xmlSchemaItemListPtr dupls;
+};
+
+
+#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
+#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
+
+#define XPATH_STATE_OBJ_MATCHES -2
+#define XPATH_STATE_OBJ_BLOCKED -3
+
+typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
+typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
+
+/**
+ * xmlSchemaIDCStateObj:
+ *
+ * The state object used to evaluate XPath expressions.
+ */
+typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
+typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
+struct _xmlSchemaIDCStateObj {
+    int type;
+    xmlSchemaIDCStateObjPtr next; /* next if in a list */
+    int depth; /* depth of creation */
+    int *history; /* list of (depth, state-id) tuples */
+    int nbHistory;
+    int sizeHistory;
+    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
+                                       matcher */
+    xmlSchemaIDCSelectPtr sel;
+    void *xpathCtxt;
+};
+
+#define IDC_MATCHER 0
+
+/**
+ * xmlSchemaIDCMatcher:
+ *
+ * Used to evaluate IDC selectors (and fields).
+ */
+struct _xmlSchemaIDCMatcher {
+    int type;
+    int depth; /* the tree depth at creation time */
+    xmlSchemaIDCMatcherPtr next; /* next in the list */
+    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
+    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
+    int idcType;
+    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
+                                         elements */
+    int sizeKeySeqs;
+    xmlSchemaItemListPtr targets; /* list of target-node
+                                     (xmlSchemaPSVIIDCNodePtr) entries */
+};
+
+/*
+* Element info flags.
+*/
+#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
+#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
+#define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
+#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
+
+#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
+#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
+#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
+
+#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
+#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
+#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
+#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
+
+/**
+ * xmlSchemaNodeInfo:
+ *
+ * Holds information of an element node.
+ */
+struct _xmlSchemaNodeInfo {
+    int nodeType;
+    xmlNodePtr node;
+    int nodeLine;
+    const xmlChar *localName;
+    const xmlChar *nsName;
+    const xmlChar *value;
+    xmlSchemaValPtr val; /* the pre-computed value if any */
+    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
+
+    int flags; /* combination of node info flags */
+
+    int valNeeded;
+    int normVal;
+
+    xmlSchemaElementPtr decl; /* the element/attribute declaration */
+    int depth;
+    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
+                                            for the scope element*/
+    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
+                                           element */
+    xmlRegExecCtxtPtr regexCtxt;
+
+    const xmlChar **nsBindings; /* Namespace bindings on this element */
+    int nbNsBindings;
+    int sizeNsBindings;
+
+    int hasKeyrefs;
+    int appliedXPath; /* Indicates that an XPath has been applied. */
+};
+
+#define XML_SCHEMAS_ATTR_UNKNOWN 1
+#define XML_SCHEMAS_ATTR_ASSESSED 2
+#define XML_SCHEMAS_ATTR_PROHIBITED 3
+#define XML_SCHEMAS_ATTR_ERR_MISSING 4
+#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
+#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
+#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
+#define XML_SCHEMAS_ATTR_DEFAULT 8
+#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
+#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
+#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
+#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
+#define XML_SCHEMAS_ATTR_WILD_SKIP 13
+#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
+#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
+#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
+#define XML_SCHEMAS_ATTR_META 17
+/*
+* @metaType values of xmlSchemaAttrInfo.
+*/
+#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
+#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
+#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
+#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
+#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
+
+typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
+typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
+struct _xmlSchemaAttrInfo {
+    int nodeType;
+    xmlNodePtr node;
+    int nodeLine;
+    const xmlChar *localName;
+    const xmlChar *nsName;
+    const xmlChar *value;
+    xmlSchemaValPtr val; /* the pre-computed value if any */
+    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
+    int flags; /* combination of node info flags */
+
+    xmlSchemaAttributePtr decl; /* the attribute declaration */
+    xmlSchemaAttributeUsePtr use;  /* the attribute use */
+    int state;
+    int metaType;
+    const xmlChar *vcValue; /* the value constraint value */
+    xmlSchemaNodeInfoPtr parent;
+};
+
+
+#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
+/**
+ * xmlSchemaValidCtxt:
+ *
+ * A Schemas validation context
+ */
+struct _xmlSchemaValidCtxt {
+    int type;
+    void *errCtxt;             /* user specific data block */
+    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
+    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
+    xmlStructuredErrorFunc serror;
+
+    xmlSchemaPtr schema;        /* The schema in use */
+    xmlDocPtr doc;
+    xmlParserInputBufferPtr input;
+    xmlCharEncoding enc;
+    xmlSAXHandlerPtr sax;
+    xmlParserCtxtPtr parserCtxt;
+    void *user_data; /* TODO: What is this for? */
+
+    int err;
+    int nberrors;
+
+    xmlNodePtr node;
+    xmlNodePtr cur;
+    /* xmlSchemaTypePtr type; */
+
+    xmlRegExecCtxtPtr regexp;
+    xmlSchemaValPtr value;
+
+    int valueWS;
+    int options;
+    xmlNodePtr validationRoot;
+    xmlSchemaParserCtxtPtr pctxt;
+    int xsiAssemble;
+
+    int depth;
+    xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
+    int sizeElemInfos;
+    xmlSchemaNodeInfoPtr inode; /* the current element information */
+
+    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
+
+    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
+    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
+    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
+
+    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
+    int nbIdcNodes;
+    int sizeIdcNodes;
+
+    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
+    int nbIdcKeys;
+    int sizeIdcKeys;
+
+    int flags;
+
+    xmlDictPtr dict;
+
+#ifdef LIBXML_READER_ENABLED
+    xmlTextReaderPtr reader;
+#endif
+
+    xmlSchemaAttrInfoPtr *attrInfos;
+    int nbAttrInfos;
+    int sizeAttrInfos;
+
+    int skipDepth;
+    xmlSchemaItemListPtr nodeQNames;
+    int hasKeyrefs;
+    int createIDCNodeTables;
+    int psviExposeIDCNodeTables;
+};
+
+/**
+ * xmlSchemaSubstGroup:
+ *
+ *
+ */
+typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
+typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
+struct _xmlSchemaSubstGroup {
+    xmlSchemaElementPtr head;
+    xmlSchemaItemListPtr members;
+};
+
+/************************************************************************
+ * 									*
+ * 			Some predeclarations				*
+ * 									*
+ ************************************************************************/
+
+static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
+                                 xmlSchemaPtr schema,
+                                 xmlNodePtr node);
+static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
+                                 xmlSchemaPtr schema,
+                                 xmlNodePtr node);
+static int
+xmlSchemaTypeFixup(xmlSchemaTypePtr type,
+                   xmlSchemaAbstractCtxtPtr ctxt);
+static const xmlChar *
+xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
+static int
+xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                     xmlNodePtr node);
+static int
+xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
+                       xmlSchemaParserCtxtPtr ctxt);
+static void
+xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
+static xmlSchemaWhitespaceValueType
+xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+			 xmlNodePtr node, xmlSchemaTypeType type,
+			 int withParticle);
+static const xmlChar *
+xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
+static xmlSchemaTypeLinkPtr
+xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
+static void
+xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
+		     const char *funcName,
+		     const char *message);
+static int
+xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
+			     xmlSchemaTypePtr type,
+			     xmlSchemaTypePtr baseType,
+			     int subset);
+static void
+xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
+				   xmlSchemaParserCtxtPtr ctxt);
+static void
+xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
+static xmlSchemaQNameRefPtr
+xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
+				xmlSchemaPtr schema,
+				xmlNodePtr node);
+
+/************************************************************************
+ *									*
+ * 			Helper functions			        *
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaItemTypeToStr:
+ * @type: the type of the schema item
+ *
+ * Returns the component name of a schema item.
+ */
+static const xmlChar *
+xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
+{
+    switch (type) {
+	case XML_SCHEMA_TYPE_BASIC:
+	    return(BAD_CAST "simple type definition");
+	case XML_SCHEMA_TYPE_SIMPLE:
+	    return(BAD_CAST "simple type definition");
+	case XML_SCHEMA_TYPE_COMPLEX:
+	    return(BAD_CAST "complex type definition");
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return(BAD_CAST "element declaration");
+	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+	    return(BAD_CAST "attribute use");
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    return(BAD_CAST "attribute declaration");
+	case XML_SCHEMA_TYPE_GROUP:
+	    return(BAD_CAST "model group definition");
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    return(BAD_CAST "attribute group definition");
+	case XML_SCHEMA_TYPE_NOTATION:
+	    return(BAD_CAST "notation declaration");
+	case XML_SCHEMA_TYPE_SEQUENCE:
+	    return(BAD_CAST "model group (sequence)");
+	case XML_SCHEMA_TYPE_CHOICE:
+	    return(BAD_CAST "model group (choice)");
+	case XML_SCHEMA_TYPE_ALL:
+	    return(BAD_CAST "model group (all)");
+	case XML_SCHEMA_TYPE_PARTICLE:
+	    return(BAD_CAST "particle");
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	    return(BAD_CAST "unique identity-constraint");
+	    /* return(BAD_CAST "IDC (unique)"); */
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	    return(BAD_CAST "key identity-constraint");
+	    /* return(BAD_CAST "IDC (key)"); */
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    return(BAD_CAST "keyref identity-constraint");
+	    /* return(BAD_CAST "IDC (keyref)"); */
+	case XML_SCHEMA_TYPE_ANY:
+	    return(BAD_CAST "wildcard (any)");
+	case XML_SCHEMA_EXTRA_QNAMEREF:
+	    return(BAD_CAST "[helper component] QName reference");
+	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
+	    return(BAD_CAST "[helper component] attribute use prohibition");
+	default:
+	    return(BAD_CAST "Not a schema component");
+    }
+}
+
+/**
+ * xmlSchemaGetComponentTypeStr:
+ * @type: the type of the schema item
+ *
+ * Returns the component name of a schema item.
+ */
+static const xmlChar *
+xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_BASIC:
+	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
+		return(BAD_CAST "complex type definition");
+	    else
+		return(BAD_CAST "simple type definition");
+	default:
+	    return(xmlSchemaItemTypeToStr(item->type));
+    }
+}
+
+/**
+ * xmlSchemaGetComponentNode:
+ * @item: a schema component
+ *
+ * Returns node associated with the schema component.
+ * NOTE that such a node need not be available; plus, a component's
+ * node need not to reflect the component directly, since there is no
+ * one-to-one relationship between the XML Schema representation and
+ * the component representation.
+ */
+static xmlNodePtr
+xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return (((xmlSchemaElementPtr) item)->node);
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    return (((xmlSchemaAttributePtr) item)->node);
+	case XML_SCHEMA_TYPE_COMPLEX:
+	case XML_SCHEMA_TYPE_SIMPLE:
+	    return (((xmlSchemaTypePtr) item)->node);
+	case XML_SCHEMA_TYPE_ANY:
+	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+	    return (((xmlSchemaWildcardPtr) item)->node);
+	case XML_SCHEMA_TYPE_PARTICLE:
+	    return (((xmlSchemaParticlePtr) item)->node);
+	case XML_SCHEMA_TYPE_SEQUENCE:
+	case XML_SCHEMA_TYPE_CHOICE:
+	case XML_SCHEMA_TYPE_ALL:
+	    return (((xmlSchemaModelGroupPtr) item)->node);
+	case XML_SCHEMA_TYPE_GROUP:
+	    return (((xmlSchemaModelGroupDefPtr) item)->node);
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    return (((xmlSchemaAttributeGroupPtr) item)->node);
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    return (((xmlSchemaIDCPtr) item)->node);
+	case XML_SCHEMA_EXTRA_QNAMEREF:
+	    return(((xmlSchemaQNameRefPtr) item)->node);
+	/* TODO: What to do with NOTATIONs?
+	case XML_SCHEMA_TYPE_NOTATION:
+	    return (((xmlSchemaNotationPtr) item)->node);
+	*/
+	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+	    return (((xmlSchemaAttributeUsePtr) item)->node);
+	default:
+	    return (NULL);
+    }
+}
+
+#if 0
+/**
+ * xmlSchemaGetNextComponent:
+ * @item: a schema component
+ *
+ * Returns the next sibling of the schema component.
+ */
+static xmlSchemaBasicItemPtr
+xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
+	case XML_SCHEMA_TYPE_COMPLEX:
+	case XML_SCHEMA_TYPE_SIMPLE:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
+	case XML_SCHEMA_TYPE_ANY:
+	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+	    return (NULL);
+	case XML_SCHEMA_TYPE_PARTICLE:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
+	case XML_SCHEMA_TYPE_SEQUENCE:
+	case XML_SCHEMA_TYPE_CHOICE:
+	case XML_SCHEMA_TYPE_ALL:
+	    return (NULL);
+	case XML_SCHEMA_TYPE_GROUP:
+	    return (NULL);
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
+	default:
+	    return (NULL);
+    }
+}
+#endif
+
+
+/**
+ * xmlSchemaFormatQName:
+ * @buf: the string buffer
+ * @namespaceName:  the namespace name
+ * @localName: the local name
+ *
+ * Returns the given QName in the format "{namespaceName}localName" or
+ * just "localName" if @namespaceName is NULL.
+ *
+ * Returns the localName if @namespaceName is NULL, a formatted
+ * string otherwise.
+ */
+static const xmlChar*
+xmlSchemaFormatQName(xmlChar **buf,
+		     const xmlChar *namespaceName,
+		     const xmlChar *localName)
+{
+    FREE_AND_NULL(*buf)
+    if (namespaceName != NULL) {
+	*buf = xmlStrdup(BAD_CAST "{");
+	*buf = xmlStrcat(*buf, namespaceName);
+	*buf = xmlStrcat(*buf, BAD_CAST "}");
+    }
+    if (localName != NULL) {
+	if (namespaceName == NULL)
+	    return(localName);
+	*buf = xmlStrcat(*buf, localName);
+    } else {
+	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
+    }
+    return ((const xmlChar *) *buf);
+}
+
+static const xmlChar*
+xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
+{
+    if (ns != NULL)
+	return (xmlSchemaFormatQName(buf, ns->href, localName));
+    else
+	return (xmlSchemaFormatQName(buf, NULL, localName));
+}
+
+static const xmlChar *
+xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return (((xmlSchemaElementPtr) item)->name);
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    return (((xmlSchemaAttributePtr) item)->name);
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    return (((xmlSchemaAttributeGroupPtr) item)->name);
+	case XML_SCHEMA_TYPE_BASIC:
+	case XML_SCHEMA_TYPE_SIMPLE:
+	case XML_SCHEMA_TYPE_COMPLEX:
+	    return (((xmlSchemaTypePtr) item)->name);
+	case XML_SCHEMA_TYPE_GROUP:
+	    return (((xmlSchemaModelGroupDefPtr) item)->name);
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    return (((xmlSchemaIDCPtr) item)->name);
+	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+	    if (WXS_ATTRUSE_DECL(item) != NULL) {
+		return(xmlSchemaGetComponentName(
+		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
+	    } else
+		return(NULL);
+	case XML_SCHEMA_EXTRA_QNAMEREF:
+	    return (((xmlSchemaQNameRefPtr) item)->name);
+	case XML_SCHEMA_TYPE_NOTATION:
+	    return (((xmlSchemaNotationPtr) item)->name);
+	default:
+	    /*
+	    * Other components cannot have names.
+	    */
+	    break;
+    }
+    return (NULL);
+}
+
+#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
+#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
+/*
+static const xmlChar *
+xmlSchemaGetQNameRefName(void *ref)
+{
+    return(((xmlSchemaQNameRefPtr) ref)->name);
+}
+
+static const xmlChar *
+xmlSchemaGetQNameRefTargetNs(void *ref)
+{
+    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
+}
+*/
+
+static const xmlChar *
+xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return (((xmlSchemaElementPtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_BASIC:
+	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
+	case XML_SCHEMA_TYPE_SIMPLE:
+	case XML_SCHEMA_TYPE_COMPLEX:
+	    return (((xmlSchemaTypePtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_GROUP:
+	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+	    if (WXS_ATTRUSE_DECL(item) != NULL) {
+		return(xmlSchemaGetComponentTargetNs(
+		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
+	    }
+	    /* TODO: Will returning NULL break something? */
+	    break;
+	case XML_SCHEMA_EXTRA_QNAMEREF:
+	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
+	case XML_SCHEMA_TYPE_NOTATION:
+	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
+	default:
+	    /*
+	    * Other components cannot have names.
+	    */
+	    break;
+    }
+    return (NULL);
+}
+
+static const xmlChar*
+xmlSchemaGetComponentQName(xmlChar **buf,
+			   void *item)
+{
+    return (xmlSchemaFormatQName(buf,
+	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
+	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
+}
+
+static const xmlChar*
+xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
+{
+    xmlChar *str = NULL;
+
+    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
+    *buf = xmlStrcat(*buf, BAD_CAST " '");
+    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
+	(xmlSchemaBasicItemPtr) item));
+    *buf = xmlStrcat(*buf, BAD_CAST "'");
+    FREE_AND_NULL(str);
+    return(*buf);
+}
+
+static const xmlChar*
+xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
+{
+    return(xmlSchemaGetComponentDesignation(buf, idc));
+}
+
+/**
+ * xmlSchemaWildcardPCToString:
+ * @pc: the type of processContents
+ *
+ * Returns a string representation of the type of
+ * processContents.
+ */
+static const xmlChar *
+xmlSchemaWildcardPCToString(int pc)
+{
+    switch (pc) {
+	case XML_SCHEMAS_ANY_SKIP:
+	    return (BAD_CAST "skip");
+	case XML_SCHEMAS_ANY_LAX:
+	    return (BAD_CAST "lax");
+	case XML_SCHEMAS_ANY_STRICT:
+	    return (BAD_CAST "strict");
+	default:
+	    return (BAD_CAST "invalid process contents");
+    }
+}
+
+/**
+ * xmlSchemaGetCanonValueWhtspExt:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ * @ws: the whitespace type of the value
+ *
+ * Get a the cononical representation of the value.
+ * The caller has to free the returned retValue.
+ *
+ * Returns 0 if the value could be built and -1 in case of
+ *         API errors or if the value type is not supported yet.
+ */
+static int
+xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
+			       xmlSchemaWhitespaceValueType ws,
+			       xmlChar **retValue)
+{
+    int list;
+    xmlSchemaValType valType;
+    const xmlChar *value, *value2 = NULL;
+
+
+    if ((retValue == NULL) || (val == NULL))
+	return (-1);
+    list = xmlSchemaValueGetNext(val) ? 1 : 0;
+    *retValue = NULL;
+    do {
+	value = NULL;
+	valType = xmlSchemaGetValType(val);
+	switch (valType) {
+	    case XML_SCHEMAS_STRING:
+	    case XML_SCHEMAS_NORMSTRING:
+	    case XML_SCHEMAS_ANYSIMPLETYPE:
+		value = xmlSchemaValueGetAsString(val);
+		if (value != NULL) {
+		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			value2 = xmlSchemaCollapseString(value);
+		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
+			value2 = xmlSchemaWhiteSpaceReplace(value);
+		    if (value2 != NULL)
+			value = value2;
+		}
+		break;
+	    default:
+		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
+		    if (value2 != NULL)
+			xmlFree((xmlChar *) value2);
+		    goto internal_error;
+		}
+		value = value2;
+	}
+	if (*retValue == NULL)
+	    if (value == NULL) {
+		if (! list)
+		    *retValue = xmlStrdup(BAD_CAST "");
+	    } else
+		*retValue = xmlStrdup(value);
+	else if (value != NULL) {
+	    /* List. */
+	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
+	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
+	}
+	FREE_AND_NULL(value2)
+	val = xmlSchemaValueGetNext(val);
+    } while (val != NULL);
+
+    return (0);
+internal_error:
+    if (*retValue != NULL)
+	xmlFree((xmlChar *) (*retValue));
+    if (value2 != NULL)
+	xmlFree((xmlChar *) value2);
+    return (-1);
+}
+
+/**
+ * xmlSchemaFormatItemForReport:
+ * @buf: the string buffer
+ * @itemDes: the designation of the item
+ * @itemName: the name of the item
+ * @item: the item as an object
+ * @itemNode: the node of the item
+ * @local: the local name
+ * @parsing: if the function is used during the parse
+ *
+ * Returns a representation of the given item used
+ * for error reports.
+ *
+ * The following order is used to build the resulting
+ * designation if the arguments are not NULL:
+ * 1a. If itemDes not NULL -> itemDes
+ * 1b. If (itemDes not NULL) and (itemName not NULL)
+ *     -> itemDes + itemName
+ * 2. If the preceding was NULL and (item not NULL) -> item
+ * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
+ *
+ * If the itemNode is an attribute node, the name of the attribute
+ * will be appended to the result.
+ *
+ * Returns the formatted string and sets @buf to the resulting value.
+ */
+static xmlChar*
+xmlSchemaFormatItemForReport(xmlChar **buf,
+		     const xmlChar *itemDes,
+		     xmlSchemaBasicItemPtr item,
+		     xmlNodePtr itemNode)
+{
+    xmlChar *str = NULL;
+    int named = 1;
+
+    if (*buf != NULL) {
+	xmlFree(*buf);
+	*buf = NULL;
+    }
+
+    if (itemDes != NULL) {
+	*buf = xmlStrdup(itemDes);
+    } else if (item != NULL) {
+	switch (item->type) {
+	case XML_SCHEMA_TYPE_BASIC: {
+	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
+
+	    if (WXS_IS_ATOMIC(type))
+		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
+	    else if (WXS_IS_LIST(type))
+		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
+	    else if (WXS_IS_UNION(type))
+		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
+	    else
+		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
+	    *buf = xmlStrcat(*buf, type->name);
+	    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_SIMPLE: {
+	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
+
+	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+		*buf = xmlStrdup(BAD_CAST"");
+	    } else {
+		*buf = xmlStrdup(BAD_CAST "local ");
+	    }
+	    if (WXS_IS_ATOMIC(type))
+		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
+	    else if (WXS_IS_LIST(type))
+		*buf = xmlStrcat(*buf, BAD_CAST "list type");
+	    else if (WXS_IS_UNION(type))
+		*buf = xmlStrcat(*buf, BAD_CAST "union type");
+	    else
+		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
+	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, type->name);
+		*buf = xmlStrcat(*buf, BAD_CAST "'");
+	    }
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_COMPLEX: {
+	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
+
+	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
+		*buf = xmlStrdup(BAD_CAST "");
+	    else
+		*buf = xmlStrdup(BAD_CAST "local ");
+	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
+	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, type->name);
+		*buf = xmlStrcat(*buf, BAD_CAST "'");
+	    }
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
+		xmlSchemaAttributeUsePtr ause;
+
+		ause = WXS_ATTR_USE_CAST item;
+		*buf = xmlStrdup(BAD_CAST "attribute use ");
+		if (WXS_ATTRUSE_DECL(ause) != NULL) {
+		    *buf = xmlStrcat(*buf, BAD_CAST "'");
+		    *buf = xmlStrcat(*buf,
+			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
+		    FREE_AND_NULL(str)
+			*buf = xmlStrcat(*buf, BAD_CAST "'");
+		} else {
+		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
+		}
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTE: {
+		xmlSchemaAttributePtr attr;
+
+		attr = (xmlSchemaAttributePtr) item;
+		*buf = xmlStrdup(BAD_CAST "attribute decl.");
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
+		    attr->targetNamespace, attr->name));
+		FREE_AND_NULL(str)
+		    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    xmlSchemaGetComponentDesignation(buf, item);
+	    break;
+	case XML_SCHEMA_TYPE_ELEMENT: {
+		xmlSchemaElementPtr elem;
+
+		elem = (xmlSchemaElementPtr) item;
+		*buf = xmlStrdup(BAD_CAST "element decl.");
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
+		    elem->targetNamespace, elem->name));
+		*buf = xmlStrcat(*buf, BAD_CAST "'");
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
+		*buf = xmlStrdup(BAD_CAST "unique '");
+	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
+		*buf = xmlStrdup(BAD_CAST "key '");
+	    else
+		*buf = xmlStrdup(BAD_CAST "keyRef '");
+	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
+	    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	    break;
+	case XML_SCHEMA_TYPE_ANY:
+	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
+		    ((xmlSchemaWildcardPtr) item)->processContents));
+	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
+	    break;
+	case XML_SCHEMA_FACET_MININCLUSIVE:
+	case XML_SCHEMA_FACET_MINEXCLUSIVE:
+	case XML_SCHEMA_FACET_MAXINCLUSIVE:
+	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+	case XML_SCHEMA_FACET_TOTALDIGITS:
+	case XML_SCHEMA_FACET_FRACTIONDIGITS:
+	case XML_SCHEMA_FACET_PATTERN:
+	case XML_SCHEMA_FACET_ENUMERATION:
+	case XML_SCHEMA_FACET_WHITESPACE:
+	case XML_SCHEMA_FACET_LENGTH:
+	case XML_SCHEMA_FACET_MAXLENGTH:
+	case XML_SCHEMA_FACET_MINLENGTH:
+	    *buf = xmlStrdup(BAD_CAST "facet '");
+	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
+	    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	    break;
+	case XML_SCHEMA_TYPE_GROUP: {
+		*buf = xmlStrdup(BAD_CAST "model group def.");
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
+		*buf = xmlStrcat(*buf, BAD_CAST "'");
+		FREE_AND_NULL(str)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_SEQUENCE:
+	case XML_SCHEMA_TYPE_CHOICE:
+	case XML_SCHEMA_TYPE_ALL:
+	case XML_SCHEMA_TYPE_PARTICLE:
+	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
+	    break;
+	case XML_SCHEMA_TYPE_NOTATION: {
+		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
+		*buf = xmlStrcat(*buf, BAD_CAST " '");
+		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
+		*buf = xmlStrcat(*buf, BAD_CAST "'");
+		FREE_AND_NULL(str);
+	    }
+	default:
+	    named = 0;
+	}
+    } else
+	named = 0;
+
+    if ((named == 0) && (itemNode != NULL)) {
+	xmlNodePtr elem;
+
+	if (itemNode->type == XML_ATTRIBUTE_NODE)
+	    elem = itemNode->parent;
+	else
+	    elem = itemNode;
+	*buf = xmlStrdup(BAD_CAST "Element '");
+	if (elem->ns != NULL) {
+	    *buf = xmlStrcat(*buf,
+		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
+	    FREE_AND_NULL(str)
+	} else
+	    *buf = xmlStrcat(*buf, elem->name);
+	*buf = xmlStrcat(*buf, BAD_CAST "'");
+
+    }
+    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
+	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
+	if (itemNode->ns != NULL) {
+	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
+		itemNode->ns->href, itemNode->name));
+	    FREE_AND_NULL(str)
+	} else
+	    *buf = xmlStrcat(*buf, itemNode->name);
+	*buf = xmlStrcat(*buf, BAD_CAST "'");
+    }
+    FREE_AND_NULL(str)
+
+    return (*buf);
+}
+
+/**
+ * xmlSchemaFormatFacetEnumSet:
+ * @buf: the string buffer
+ * @type: the type holding the enumeration facets
+ *
+ * Builds a string consisting of all enumeration elements.
+ *
+ * Returns a string of all enumeration elements.
+ */
+static const xmlChar *
+xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
+			    xmlChar **buf, xmlSchemaTypePtr type)
+{
+    xmlSchemaFacetPtr facet;
+    xmlSchemaWhitespaceValueType ws;
+    xmlChar *value = NULL;
+    int res, found = 0;
+
+    if (*buf != NULL)
+	xmlFree(*buf);
+    *buf = NULL;
+
+    do {
+	/*
+	* Use the whitespace type of the base type.
+	*/
+	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
+	for (facet = type->facets; facet != NULL; facet = facet->next) {
+	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
+		continue;
+	    found = 1;
+	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
+		ws, &value);
+	    if (res == -1) {
+		xmlSchemaInternalErr(actxt,
+		    "xmlSchemaFormatFacetEnumSet",
+		    "compute the canonical lexical representation");
+		if (*buf != NULL)
+		    xmlFree(*buf);
+		*buf = NULL;
+		return (NULL);
+	    }
+	    if (*buf == NULL)
+		*buf = xmlStrdup(BAD_CAST "'");
+	    else
+		*buf = xmlStrcat(*buf, BAD_CAST ", '");
+	    *buf = xmlStrcat(*buf, BAD_CAST value);
+	    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	    if (value != NULL) {
+		xmlFree((xmlChar *)value);
+		value = NULL;
+	    }
+	}
+	/*
+	* The enumeration facet of a type restricts the enumeration
+	* facet of the ancestor type; i.e., such restricted enumerations
+	* do not belong to the set of the given type. Thus we break
+	* on the first found enumeration.
+	*/
+	if (found)
+	    break;
+	type = type->baseType;
+    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
+
+    return ((const xmlChar *) *buf);
+}
+
+/************************************************************************
+ *									*
+ * 			Error functions				        *
+ *									*
+ ************************************************************************/
+
+#if 0
+static void
+xmlSchemaErrMemory(const char *msg)
+{
+    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
+                     msg);
+}
+#endif
+
+static void
+xmlSchemaPSimpleErr(const char *msg)
+{
+    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
+                     msg);
+}
+
+/**
+ * xmlSchemaPErrMemory:
+ * @node: a context node
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
+                    const char *extra, xmlNodePtr node)
+{
+    if (ctxt != NULL)
+        ctxt->nberrors++;
+    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
+                     extra);
+}
+
+/**
+ * xmlSchemaPErr:
+ * @ctxt: the parsing context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ *
+ * Handle a parser error
+ */
+static void
+xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
+              const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    xmlGenericErrorFunc channel = NULL;
+    xmlStructuredErrorFunc schannel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        ctxt->nberrors++;
+	ctxt->err = error;
+        channel = ctxt->error;
+        data = ctxt->errCtxt;
+	schannel = ctxt->serror;
+    }
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
+                    error, XML_ERR_ERROR, NULL, 0,
+                    (const char *) str1, (const char *) str2, NULL, 0, 0,
+                    msg, str1, str2);
+}
+
+/**
+ * xmlSchemaPErr2:
+ * @ctxt: the parsing context
+ * @node: the context node
+ * @node: the current child
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ *
+ * Handle a parser error
+ */
+static void
+xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+               xmlNodePtr child, int error,
+               const char *msg, const xmlChar * str1, const xmlChar * str2)
+{
+    if (child != NULL)
+        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
+    else
+        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
+}
+
+
+/**
+ * xmlSchemaPErrExt:
+ * @ctxt: the parsing context
+ * @node: the context node
+ * @error: the error code
+ * @strData1: extra data
+ * @strData2: extra data
+ * @strData3: extra data
+ * @msg: the message
+ * @str1:  extra parameter for the message display
+ * @str2:  extra parameter for the message display
+ * @str3:  extra parameter for the message display
+ * @str4:  extra parameter for the message display
+ * @str5:  extra parameter for the message display
+ *
+ * Handle a parser error
+ */
+static void
+xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
+		const xmlChar * strData1, const xmlChar * strData2,
+		const xmlChar * strData3, const char *msg, const xmlChar * str1,
+		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
+		const xmlChar * str5)
+{
+
+    xmlGenericErrorFunc channel = NULL;
+    xmlStructuredErrorFunc schannel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+        ctxt->nberrors++;
+	ctxt->err = error;
+        channel = ctxt->error;
+        data = ctxt->errCtxt;
+	schannel = ctxt->serror;
+    }
+    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
+                    error, XML_ERR_ERROR, NULL, 0,
+                    (const char *) strData1, (const char *) strData2,
+		    (const char *) strData3, 0, 0, msg, str1, str2,
+		    str3, str4, str5);
+}
+
+/************************************************************************
+ *									*
+ * 			Allround error functions			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaVTypeErrMemory:
+ * @node: a context node
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
+                    const char *extra, xmlNodePtr node)
+{
+    if (ctxt != NULL) {
+        ctxt->nberrors++;
+        ctxt->err = XML_SCHEMAV_INTERNAL;
+    }
+    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
+                     extra);
+}
+
+static void
+xmlSchemaPSimpleInternalErr(xmlNodePtr node,
+			    const char *msg, const xmlChar *str)
+{
+     __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
+	 msg, (const char *) str);
+}
+
+#define WXS_ERROR_TYPE_ERROR 1
+#define WXS_ERROR_TYPE_WARNING 2
+/**
+ * xmlSchemaErr3:
+ * @ctxt: the validation context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ * @str3: extra data
+ *
+ * Handle a validation error
+ */
+static void
+xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
+		  xmlErrorLevel errorLevel,
+		  int error, xmlNodePtr node, int line, const char *msg,
+		  const xmlChar *str1, const xmlChar *str2,
+		  const xmlChar *str3, const xmlChar *str4)
+{
+    xmlStructuredErrorFunc schannel = NULL;
+    xmlGenericErrorFunc channel = NULL;
+    void *data = NULL;
+
+    if (ctxt != NULL) {
+	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
+	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
+	    const char *file = NULL;
+	    if (errorLevel != XML_ERR_WARNING) {
+		vctxt->nberrors++;
+		vctxt->err = error;
+		channel = vctxt->error;
+	    } else {
+		channel = vctxt->warning;
+	    }
+	    schannel = vctxt->serror;
+	    data = vctxt->errCtxt;
+
+	    /*
+	    * Error node. If we specify a line number, then
+	    * do not channel any node to the error function.
+	    */
+	    if (line == 0) {
+		if ((node == NULL) &&
+		    (vctxt->depth >= 0) &&
+		    (vctxt->inode != NULL)) {
+		    node = vctxt->inode->node;
+		}
+		/*
+		* Get filename and line if no node-tree.
+		*/
+		if ((node == NULL) &&
+		    (vctxt->parserCtxt != NULL) &&
+		    (vctxt->parserCtxt->input != NULL)) {
+		    file = vctxt->parserCtxt->input->filename;
+		    line = vctxt->parserCtxt->input->line;
+		}
+	    } else {
+		/*
+		* Override the given node's (if any) position
+		* and channel only the given line number.
+		*/
+		node = NULL;
+		/*
+		* Get filename.
+		*/
+		if (vctxt->doc != NULL)
+		    file = (const char *) vctxt->doc->URL;
+		else if ((vctxt->parserCtxt != NULL) &&
+		    (vctxt->parserCtxt->input != NULL))
+		    file = vctxt->parserCtxt->input->filename;
+	    }
+	    __xmlRaiseError(schannel, channel, data, ctxt,
+		node, XML_FROM_SCHEMASV,
+		error, errorLevel, file, line,
+		(const char *) str1, (const char *) str2,
+		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
+
+	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
+	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
+	    if (errorLevel != XML_ERR_WARNING) {
+		pctxt->nberrors++;
+		pctxt->err = error;
+		channel = pctxt->error;
+	    } else {
+		channel = pctxt->warning;
+	    }
+	    schannel = pctxt->serror;
+	    data = pctxt->errCtxt;
+	    __xmlRaiseError(schannel, channel, data, ctxt,
+		node, XML_FROM_SCHEMASP, error,
+		errorLevel, NULL, 0,
+		(const char *) str1, (const char *) str2,
+		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
+	} else {
+	    TODO
+	}
+    }
+}
+
+/**
+ * xmlSchemaErr3:
+ * @ctxt: the validation context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ * @str3: extra data
+ *
+ * Handle a validation error
+ */
+static void
+xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
+	      int error, xmlNodePtr node, const char *msg,
+	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
+{
+    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
+	msg, str1, str2, str3, NULL);
+}
+
+static void
+xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
+	      int error, xmlNodePtr node, const char *msg,
+	      const xmlChar *str1, const xmlChar *str2,
+	      const xmlChar *str3, const xmlChar *str4)
+{
+    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
+	msg, str1, str2, str3, str4);
+}
+
+static void
+xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
+	     int error, xmlNodePtr node, const char *msg,
+	     const xmlChar *str1, const xmlChar *str2)
+{
+    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
+}
+
+static xmlChar *
+xmlSchemaFormatNodeForError(xmlChar ** msg,
+			    xmlSchemaAbstractCtxtPtr actxt,
+			    xmlNodePtr node)
+{
+    xmlChar *str = NULL;
+
+    *msg = NULL;
+    if ((node != NULL) &&
+	(node->type != XML_ELEMENT_NODE) &&
+	(node->type != XML_ATTRIBUTE_NODE))
+    {
+	/*
+	* Don't try to format other nodes than element and
+	* attribute nodes.
+	* Play save and return an empty string.
+	*/
+	*msg = xmlStrdup(BAD_CAST "");
+	return(*msg);
+    }
+    if (node != NULL) {
+	/*
+	* Work on tree nodes.
+	*/
+	if (node->type == XML_ATTRIBUTE_NODE) {
+	    xmlNodePtr elem = node->parent;
+
+	    *msg = xmlStrdup(BAD_CAST "Element '");
+	    if (elem->ns != NULL)
+		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+		    elem->ns->href, elem->name));
+	    else
+		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+		    NULL, elem->name));
+	    FREE_AND_NULL(str);
+	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
+	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
+	} else {
+	    *msg = xmlStrdup(BAD_CAST "Element '");
+	}
+	if (node->ns != NULL)
+	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+	    node->ns->href, node->name));
+	else
+	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+	    NULL, node->name));
+	FREE_AND_NULL(str);
+	*msg = xmlStrcat(*msg, BAD_CAST "': ");
+    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
+	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
+	/*
+	* Work on node infos.
+	*/
+	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
+	    xmlSchemaNodeInfoPtr ielem =
+		vctxt->elemInfos[vctxt->depth];
+
+	    *msg = xmlStrdup(BAD_CAST "Element '");
+	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+		ielem->nsName, ielem->localName));
+	    FREE_AND_NULL(str);
+	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
+	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
+	} else {
+	    *msg = xmlStrdup(BAD_CAST "Element '");
+	}
+	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
+	    vctxt->inode->nsName, vctxt->inode->localName));
+	FREE_AND_NULL(str);
+	*msg = xmlStrcat(*msg, BAD_CAST "': ");
+    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
+	/*
+	* Hmm, no node while parsing?
+	* Return an empty string, in case NULL will break something.
+	*/
+	*msg = xmlStrdup(BAD_CAST "");
+    } else {
+	TODO
+	return (NULL);
+    }
+    /*
+    * VAL TODO: The output of the given schema component is currently
+    * disabled.
+    */
+#if 0
+    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
+	*msg = xmlStrcat(*msg, BAD_CAST " [");
+	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
+	    NULL, type, NULL, 0));
+	FREE_AND_NULL(str)
+	*msg = xmlStrcat(*msg, BAD_CAST "]");
+    }
+#endif
+    return (*msg);
+}
+
+static void
+xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
+		     const char *funcName,
+		     const char *message,
+		     const xmlChar *str1,
+		     const xmlChar *str2)
+{
+    xmlChar *msg = NULL;
+
+    if (actxt == NULL)
+        return;
+    msg = xmlStrdup(BAD_CAST "Internal error: ");
+    msg = xmlStrcat(msg, BAD_CAST funcName);
+    msg = xmlStrcat(msg, BAD_CAST ", ");
+    msg = xmlStrcat(msg, BAD_CAST message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+
+    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
+	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
+	    (const char *) msg, str1, str2);
+
+    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
+	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
+	    (const char *) msg, str1, str2);
+
+    FREE_AND_NULL(msg)
+}
+
+static void
+xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
+		     const char *funcName,
+		     const char *message)
+{
+    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
+}
+
+#if 0
+static void
+xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
+		     const char *funcName,
+		     const char *message,
+		     const xmlChar *str1,
+		     const xmlChar *str2)
+{
+    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
+	str1, str2);
+}
+#endif
+
+static void
+xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
+		   xmlParserErrors error,
+		   xmlNodePtr node,
+		   xmlSchemaBasicItemPtr item,
+		   const char *message,
+		   const xmlChar *str1, const xmlChar *str2,
+		   const xmlChar *str3, const xmlChar *str4)
+{
+    xmlChar *msg = NULL;
+
+    if ((node == NULL) && (item != NULL) &&
+	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
+	node = WXS_ITEM_NODE(item);
+	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
+	msg = xmlStrcat(msg, BAD_CAST ": ");
+    } else
+	xmlSchemaFormatNodeForError(&msg, actxt, node);
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    xmlSchemaErr4(actxt, error, node,
+	(const char *) msg, str1, str2, str3, str4);
+    FREE_AND_NULL(msg)
+}
+
+static void
+xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
+		   xmlParserErrors error,
+		   xmlNodePtr node,
+		   xmlSchemaBasicItemPtr item,
+		   const char *message,
+		   const xmlChar *str1,
+		   const xmlChar *str2)
+{
+    xmlSchemaCustomErr4(actxt, error, node, item,
+	message, str1, str2, NULL, NULL);
+}
+
+
+
+static void
+xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
+		   xmlParserErrors error,
+		   xmlNodePtr node,
+		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
+		   const char *message,
+		   const xmlChar *str1,
+		   const xmlChar *str2,
+		   const xmlChar *str3)
+{
+    xmlChar *msg = NULL;
+
+    xmlSchemaFormatNodeForError(&msg, actxt, node);
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+
+    /* URGENT TODO: Set the error code to something sane. */
+    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
+	(const char *) msg, str1, str2, str3, NULL);
+
+    FREE_AND_NULL(msg)
+}
+
+
+
+static void
+xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
+		   xmlParserErrors error,
+		   xmlSchemaPSVIIDCNodePtr idcNode,
+		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
+		   const char *message,
+		   const xmlChar *str1,
+		   const xmlChar *str2)
+{
+    xmlChar *msg = NULL, *qname = NULL;
+
+    msg = xmlStrdup(BAD_CAST "Element '%s': ");
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
+	error, NULL, idcNode->nodeLine, (const char *) msg,
+	xmlSchemaFormatQName(&qname,
+	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
+	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
+	str1, str2, NULL);
+    FREE_AND_NULL(qname);
+    FREE_AND_NULL(msg);
+}
+
+static int
+xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
+			   xmlNodePtr node)
+{
+    if (node != NULL)
+	return (node->type);
+    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
+	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
+	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
+    return (-1);
+}
+
+static int
+xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
+{
+    switch (item->type) {
+	case XML_SCHEMA_TYPE_COMPLEX:
+	case XML_SCHEMA_TYPE_SIMPLE:
+	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
+		return(1);
+	    break;
+	case XML_SCHEMA_TYPE_GROUP:
+	    return (1);
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    if ( ((xmlSchemaElementPtr) item)->flags &
+		XML_SCHEMAS_ELEM_GLOBAL)
+		return(1);
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTE:
+	    if ( ((xmlSchemaAttributePtr) item)->flags &
+		XML_SCHEMAS_ATTR_GLOBAL)
+		return(1);
+	    break;
+	/* Note that attribute groups are always global. */
+	default:
+	    return(1);
+    }
+    return (0);
+}
+
+static void
+xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
+		       xmlParserErrors error,
+		       xmlNodePtr node,
+		       const xmlChar *value,
+		       xmlSchemaTypePtr type,
+		       int displayValue)
+{
+    xmlChar *msg = NULL;
+
+    xmlSchemaFormatNodeForError(&msg, actxt, node);
+
+    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
+	    XML_ATTRIBUTE_NODE))
+	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
+    else
+	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
+	    "value of ");
+
+    if (! xmlSchemaIsGlobalItem(type))
+	msg = xmlStrcat(msg, BAD_CAST "the local ");
+    else
+	msg = xmlStrcat(msg, BAD_CAST "the ");
+
+    if (WXS_IS_ATOMIC(type))
+	msg = xmlStrcat(msg, BAD_CAST "atomic type");
+    else if (WXS_IS_LIST(type))
+	msg = xmlStrcat(msg, BAD_CAST "list type");
+    else if (WXS_IS_UNION(type))
+	msg = xmlStrcat(msg, BAD_CAST "union type");
+
+    if (xmlSchemaIsGlobalItem(type)) {
+	xmlChar *str = NULL;
+	msg = xmlStrcat(msg, BAD_CAST " '");
+	if (type->builtInType != 0) {
+	    msg = xmlStrcat(msg, BAD_CAST "xs:");
+	    msg = xmlStrcat(msg, type->name);
+	} else
+	    msg = xmlStrcat(msg,
+		xmlSchemaFormatQName(&str,
+		    type->targetNamespace, type->name));
+	msg = xmlStrcat(msg, BAD_CAST "'");
+	FREE_AND_NULL(str);
+    }
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
+	    XML_ATTRIBUTE_NODE))
+	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
+    else
+	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
+    FREE_AND_NULL(msg)
+}
+
+static const xmlChar *
+xmlSchemaFormatErrorNodeQName(xmlChar ** str,
+			      xmlSchemaNodeInfoPtr ni,
+			      xmlNodePtr node)
+{
+    if (node != NULL) {
+	if (node->ns != NULL)
+	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
+	else
+	    return (xmlSchemaFormatQName(str, NULL, node->name));
+    } else if (ni != NULL)
+	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
+    return (NULL);
+}
+
+static void
+xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
+			xmlParserErrors error,
+			xmlSchemaAttrInfoPtr ni,
+			xmlNodePtr node)
+{
+    xmlChar *msg = NULL, *str = NULL;
+
+    xmlSchemaFormatNodeForError(&msg, actxt, node);
+    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
+    xmlSchemaErr(actxt, error, node, (const char *) msg,
+	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
+	NULL);
+    FREE_AND_NULL(str)
+    FREE_AND_NULL(msg)
+}
+
+static void
+xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
+		        xmlParserErrors error,
+		        xmlNodePtr node,
+			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
+			const char *message,
+			int nbval,
+			int nbneg,
+			xmlChar **values)
+{
+    xmlChar *str = NULL, *msg = NULL;
+    xmlChar *localName, *nsName;
+    const xmlChar *cur, *end;
+    int i;
+
+    xmlSchemaFormatNodeForError(&msg, actxt, node);
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".");
+    /*
+    * Note that is does not make sense to report that we have a
+    * wildcard here, since the wildcard might be unfolded into
+    * multiple transitions.
+    */
+    if (nbval + nbneg > 0) {
+	if (nbval + nbneg > 1) {
+	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
+	} else
+	    str = xmlStrdup(BAD_CAST " Expected is ( ");
+	nsName = NULL;
+
+	for (i = 0; i < nbval + nbneg; i++) {
+	    cur = values[i];
+	    if (cur == NULL)
+	        continue;
+	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
+	        (cur[3] == ' ')) {
+		cur += 4;
+		str = xmlStrcat(str, BAD_CAST "##other");
+	    }
+	    /*
+	    * Get the local name.
+	    */
+	    localName = NULL;
+
+	    end = cur;
+	    if (*end == '*') {
+		localName = xmlStrdup(BAD_CAST "*");
+		end++;
+	    } else {
+		while ((*end != 0) && (*end != '|'))
+		    end++;
+		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
+	    }
+	    if (*end != 0) {
+		end++;
+		/*
+		* Skip "*|*" if they come with negated expressions, since
+		* they represent the same negated wildcard.
+		*/
+		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
+		    /*
+		    * Get the namespace name.
+		    */
+		    cur = end;
+		    if (*end == '*') {
+			nsName = xmlStrdup(BAD_CAST "{*}");
+		    } else {
+			while (*end != 0)
+			    end++;
+
+			if (i >= nbval)
+			    nsName = xmlStrdup(BAD_CAST "{##other:");
+			else
+			    nsName = xmlStrdup(BAD_CAST "{");
+
+			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
+			nsName = xmlStrcat(nsName, BAD_CAST "}");
+		    }
+		    str = xmlStrcat(str, BAD_CAST nsName);
+		    FREE_AND_NULL(nsName)
+		} else {
+		    FREE_AND_NULL(localName);
+		    continue;
+		}
+	    }
+	    str = xmlStrcat(str, BAD_CAST localName);
+	    FREE_AND_NULL(localName);
+
+	    if (i < nbval + nbneg -1)
+		str = xmlStrcat(str, BAD_CAST ", ");
+	}
+	str = xmlStrcat(str, BAD_CAST " ).\n");
+	msg = xmlStrcat(msg, BAD_CAST str);
+	FREE_AND_NULL(str)
+    } else
+      msg = xmlStrcat(msg, BAD_CAST "\n");
+    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
+    xmlFree(msg);
+}
+
+static void
+xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
+		  xmlParserErrors error,
+		  xmlNodePtr node,
+		  const xmlChar *value,
+		  unsigned long length,
+		  xmlSchemaTypePtr type,
+		  xmlSchemaFacetPtr facet,
+		  const char *message,
+		  const xmlChar *str1,
+		  const xmlChar *str2)
+{
+    xmlChar *str = NULL, *msg = NULL;
+    xmlSchemaTypeType facetType;
+    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
+
+    xmlSchemaFormatNodeForError(&msg, actxt, node);
+    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
+	facetType = XML_SCHEMA_FACET_ENUMERATION;
+	/*
+	* If enumerations are validated, one must not expect the
+	* facet to be given.
+	*/
+    } else
+	facetType = facet->type;
+    msg = xmlStrcat(msg, BAD_CAST "[");
+    msg = xmlStrcat(msg, BAD_CAST "facet '");
+    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
+    msg = xmlStrcat(msg, BAD_CAST "'] ");
+    if (message == NULL) {
+	/*
+	* Use a default message.
+	*/
+	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
+	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
+	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
+
+	    char len[25], actLen[25];
+
+	    /* FIXME, TODO: What is the max expected string length of the
+	    * this value?
+	    */
+	    if (nodeType == XML_ATTRIBUTE_NODE)
+		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
+	    else
+		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
+
+	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
+	    snprintf(actLen, 24, "%lu", length);
+
+	    if (facetType == XML_SCHEMA_FACET_LENGTH)
+		msg = xmlStrcat(msg,
+		BAD_CAST "this differs from the allowed length of '%s'.\n");
+	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
+		msg = xmlStrcat(msg,
+		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
+	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
+		msg = xmlStrcat(msg,
+		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
+
+	    if (nodeType == XML_ATTRIBUTE_NODE)
+		xmlSchemaErr3(actxt, error, node, (const char *) msg,
+		    value, (const xmlChar *) actLen, (const xmlChar *) len);
+	    else
+		xmlSchemaErr(actxt, error, node, (const char *) msg,
+		    (const xmlChar *) actLen, (const xmlChar *) len);
+
+	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
+		"of the set {%s}.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
+	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
+		"by the pattern '%s'.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
+		"minimum value allowed ('%s').\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
+		"maximum value allowed ('%s').\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
+		"'%s'.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
+		"'%s'.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
+		"digits than are allowed ('%s').\n");
+	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
+		facet->value);
+	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
+		"digits than are allowed ('%s').\n");
+	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
+		facet->value);
+	} else if (nodeType == XML_ATTRIBUTE_NODE) {
+	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
+	} else {
+	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
+	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
+	}
+    } else {
+	msg = xmlStrcat(msg, (const xmlChar *) message);
+	msg = xmlStrcat(msg, BAD_CAST ".\n");
+	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
+    }
+    FREE_AND_NULL(str)
+    xmlFree(msg);
+}
+
+#define VERROR(err, type, msg) \
+    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
+
+#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
+
+#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
+#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
+
+#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
+
+
+/**
+ * xmlSchemaPMissingAttrErr:
+ * @ctxt: the schema validation context
+ * @ownerDes: the designation of  the owner
+ * @ownerName: the name of the owner
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the owner as an element node
+ * @node: the parent element node of the missing attribute node
+ * @type: the corresponding type of the attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
+			 xmlParserErrors error,
+			 xmlSchemaBasicItemPtr ownerItem,
+			 xmlNodePtr ownerElem,
+			 const char *name,
+			 const char *message)
+{
+    xmlChar *des = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
+
+    if (message != NULL)
+	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
+    else
+	xmlSchemaPErr(ctxt, ownerElem, error,
+	    "%s: The attribute '%s' is required but missing.\n",
+	    BAD_CAST des, BAD_CAST name);
+    FREE_AND_NULL(des);
+}
+
+
+/**
+ * xmlSchemaPResCompAttrErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @ownerDes: the designation of  the owner
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the owner as an element node
+ * @name: the name of the attribute holding the QName
+ * @refName: the referenced local name
+ * @refURI: the referenced namespace URI
+ * @message: optional message
+ *
+ * Used to report QName attribute values that failed to resolve
+ * to schema components.
+ */
+static void
+xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
+			 xmlParserErrors error,
+			 xmlSchemaBasicItemPtr ownerItem,
+			 xmlNodePtr ownerElem,
+			 const char *name,
+			 const xmlChar *refName,
+			 const xmlChar *refURI,
+			 xmlSchemaTypeType refType,
+			 const char *refTypeStr)
+{
+    xmlChar *des = NULL, *strA = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
+    if (refTypeStr == NULL)
+	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
+	xmlSchemaPErrExt(ctxt, ownerElem, error,
+	    NULL, NULL, NULL,
+	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
+	    "%s.\n", BAD_CAST des, BAD_CAST name,
+	    xmlSchemaFormatQName(&strA, refURI, refName),
+	    BAD_CAST refTypeStr, NULL);
+    FREE_AND_NULL(des)
+    FREE_AND_NULL(strA)
+}
+
+/**
+ * xmlSchemaPCustomAttrErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @ownerDes: the designation of the owner
+ * @ownerItem: the owner as a schema object
+ * @attr: the illegal attribute node
+ *
+ * Reports an illegal attribute during the parse.
+ */
+static void
+xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
+			xmlParserErrors error,
+			xmlChar **ownerDes,
+			xmlSchemaBasicItemPtr ownerItem,
+			xmlAttrPtr attr,
+			const char *msg)
+{
+    xmlChar *des = NULL;
+
+    if (ownerDes == NULL)
+	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
+    else if (*ownerDes == NULL) {
+	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
+	des = *ownerDes;
+    } else
+	des = *ownerDes;
+    if (attr == NULL) {
+	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
+	    "%s, attribute '%s': %s.\n",
+	    BAD_CAST des, (const xmlChar *) "Unknown",
+	    (const xmlChar *) msg, NULL, NULL);
+    } else {
+	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
+	    "%s, attribute '%s': %s.\n",
+	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
+    }
+    if (ownerDes == NULL)
+	FREE_AND_NULL(des);
+}
+
+/**
+ * xmlSchemaPIllegalAttrErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @ownerDes: the designation of the attribute's owner
+ * @ownerItem: the attribute's owner item
+ * @attr: the illegal attribute node
+ *
+ * Reports an illegal attribute during the parse.
+ */
+static void
+xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
+			 xmlParserErrors error,
+			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
+			 xmlAttrPtr attr)
+{
+    xmlChar *strA = NULL, *strB = NULL;
+
+    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
+    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
+	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
+	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
+	NULL, NULL);
+    FREE_AND_NULL(strA);
+    FREE_AND_NULL(strB);
+}
+
+/**
+ * xmlSchemaPCustomErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @itemDes: the designation of the schema item
+ * @item: the schema item
+ * @itemElem: the node of the schema item
+ * @message: the error message
+ * @str1: an optional param for the error message
+ * @str2: an optional param for the error message
+ * @str3: an optional param for the error message
+ *
+ * Reports an error during parsing.
+ */
+static void
+xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
+		    xmlParserErrors error,
+		    xmlSchemaBasicItemPtr item,
+		    xmlNodePtr itemElem,
+		    const char *message,
+		    const xmlChar *str1,
+		    const xmlChar *str2,
+		    const xmlChar *str3)
+{
+    xmlChar *des = NULL, *msg = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
+    msg = xmlStrdup(BAD_CAST "%s: ");
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    if ((itemElem == NULL) && (item != NULL))
+	itemElem = WXS_ITEM_NODE(item);
+    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
+	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
+    FREE_AND_NULL(des);
+    FREE_AND_NULL(msg);
+}
+
+/**
+ * xmlSchemaPCustomErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @itemDes: the designation of the schema item
+ * @item: the schema item
+ * @itemElem: the node of the schema item
+ * @message: the error message
+ * @str1: the optional param for the error message
+ *
+ * Reports an error during parsing.
+ */
+static void
+xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
+		    xmlParserErrors error,
+		    xmlSchemaBasicItemPtr item,
+		    xmlNodePtr itemElem,
+		    const char *message,
+		    const xmlChar *str1)
+{
+    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
+	str1, NULL, NULL);
+}
+
+/**
+ * xmlSchemaPAttrUseErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @itemDes: the designation of the schema type
+ * @item: the schema type
+ * @itemElem: the node of the schema type
+ * @attr: the invalid schema attribute
+ * @message: the error message
+ * @str1: the optional param for the error message
+ *
+ * Reports an attribute use error during parsing.
+ */
+static void
+xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
+		    xmlParserErrors error,
+		    xmlNodePtr node,
+		    xmlSchemaBasicItemPtr ownerItem,
+		    const xmlSchemaAttributeUsePtr attruse,
+		    const char *message,
+		    const xmlChar *str1, const xmlChar *str2,
+		    const xmlChar *str3,const xmlChar *str4)
+{
+    xmlChar *str = NULL, *msg = NULL;
+
+    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
+    msg = xmlStrcat(msg, BAD_CAST ", ");
+    msg = xmlStrcat(msg,
+	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
+	WXS_BASIC_CAST attruse, NULL));
+    FREE_AND_NULL(str);
+    msg = xmlStrcat(msg, BAD_CAST ": ");
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
+	(const char *) msg, str1, str2, str3, str4);
+    xmlFree(msg);
+}
+
+/**
+ * xmlSchemaPIllegalFacetAtomicErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @type: the schema type
+ * @baseType: the base type of type
+ * @facet: the illegal facet
+ *
+ * Reports an illegal facet for atomic simple types.
+ */
+static void
+xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
+			  xmlParserErrors error,
+			  xmlSchemaTypePtr type,
+			  xmlSchemaTypePtr baseType,
+			  xmlSchemaFacetPtr facet)
+{
+    xmlChar *des = NULL, *strT = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
+    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
+	"%s: The facet '%s' is not allowed on types derived from the "
+	"type %s.\n",
+	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
+	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
+	NULL, NULL);
+    FREE_AND_NULL(des);
+    FREE_AND_NULL(strT);
+}
+
+/**
+ * xmlSchemaPIllegalFacetListUnionErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @itemDes: the designation of the schema item involved
+ * @item: the schema item involved
+ * @facet: the illegal facet
+ *
+ * Reports an illegal facet for <list> and <union>.
+ */
+static void
+xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
+			  xmlParserErrors error,
+			  xmlSchemaTypePtr type,
+			  xmlSchemaFacetPtr facet)
+{
+    xmlChar *des = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
+	type->node);
+    xmlSchemaPErr(ctxt, type->node, error,
+	"%s: The facet '%s' is not allowed.\n",
+	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
+    FREE_AND_NULL(des);
+}
+
+/**
+ * xmlSchemaPMutualExclAttrErr:
+ * @ctxt: the schema validation context
+ * @error: the error code
+ * @elemDes: the designation of the parent element node
+ * @attr: the bad attribute node
+ * @type: the corresponding type of the attribute node
+ *
+ * Reports an illegal attribute.
+ */
+static void
+xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
+			 xmlParserErrors error,
+			 xmlSchemaBasicItemPtr ownerItem,
+			 xmlAttrPtr attr,
+			 const char *name1,
+			 const char *name2)
+{
+    xmlChar *des = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
+    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
+	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
+	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
+    FREE_AND_NULL(des);
+}
+
+/**
+ * xmlSchemaPSimpleTypeErr:
+ * @ctxt:  the schema validation context
+ * @error: the error code
+ * @type: the type specifier
+ * @ownerDes: the designation of the owner
+ * @ownerItem: the schema object if existent
+ * @node: the validated node
+ * @value: the validated value
+ *
+ * Reports a simple type validation error.
+ * TODO: Should this report the value of an element as well?
+ */
+static void
+xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
+			xmlParserErrors error,
+			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
+			xmlNodePtr node,
+			xmlSchemaTypePtr type,
+			const char *expected,
+			const xmlChar *value,
+			const char *message,
+			const xmlChar *str1,
+			const xmlChar *str2)
+{
+    xmlChar *msg = NULL;
+
+    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
+    if (message == NULL) {
+	/*
+	* Use default messages.
+	*/
+	if (type != NULL) {
+	    if (node->type == XML_ATTRIBUTE_NODE)
+		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
+	    else
+		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
+		"valid value of ");
+	    if (! xmlSchemaIsGlobalItem(type))
+		msg = xmlStrcat(msg, BAD_CAST "the local ");
+	    else
+		msg = xmlStrcat(msg, BAD_CAST "the ");
+
+	    if (WXS_IS_ATOMIC(type))
+		msg = xmlStrcat(msg, BAD_CAST "atomic type");
+	    else if (WXS_IS_LIST(type))
+		msg = xmlStrcat(msg, BAD_CAST "list type");
+	    else if (WXS_IS_UNION(type))
+		msg = xmlStrcat(msg, BAD_CAST "union type");
+
+	    if (xmlSchemaIsGlobalItem(type)) {
+		xmlChar *str = NULL;
+		msg = xmlStrcat(msg, BAD_CAST " '");
+		if (type->builtInType != 0) {
+		    msg = xmlStrcat(msg, BAD_CAST "xs:");
+		    msg = xmlStrcat(msg, type->name);
+		} else
+		    msg = xmlStrcat(msg,
+			xmlSchemaFormatQName(&str,
+			    type->targetNamespace, type->name));
+		msg = xmlStrcat(msg, BAD_CAST "'.");
+		FREE_AND_NULL(str);
+	    }
+	} else {
+	    if (node->type == XML_ATTRIBUTE_NODE)
+		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
+	    else
+		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
+		"valid.");
+	}
+	if (expected) {
+	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
+	    msg = xmlStrcat(msg, BAD_CAST expected);
+	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
+	} else
+	    msg = xmlStrcat(msg, BAD_CAST "\n");
+	if (node->type == XML_ATTRIBUTE_NODE)
+	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
+	else
+	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
+    } else {
+	msg = xmlStrcat(msg, BAD_CAST message);
+	msg = xmlStrcat(msg, BAD_CAST ".\n");
+	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
+	     (const char*) msg, str1, str2, NULL, NULL, NULL);
+    }
+    /* Cleanup. */
+    FREE_AND_NULL(msg)
+}
+
+/**
+ * xmlSchemaPContentErr:
+ * @ctxt: the schema parser context
+ * @error: the error code
+ * @onwerDes: the designation of the holder of the content
+ * @ownerItem: the owner item of the holder of the content
+ * @ownerElem: the node of the holder of the content
+ * @child: the invalid child node
+ * @message: the optional error message
+ * @content: the optional string describing the correct content
+ *
+ * Reports an error concerning the content of a schema element.
+ */
+static void
+xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
+		     xmlParserErrors error,
+		     xmlSchemaBasicItemPtr ownerItem,
+		     xmlNodePtr ownerElem,
+		     xmlNodePtr child,
+		     const char *message,
+		     const char *content)
+{
+    xmlChar *des = NULL;
+
+    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
+    if (message != NULL)
+	xmlSchemaPErr2(ctxt, ownerElem, child, error,
+	    "%s: %s.\n",
+	    BAD_CAST des, BAD_CAST message);
+    else {
+	if (content != NULL) {
+	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
+		"%s: The content is not valid. Expected is %s.\n",
+		BAD_CAST des, BAD_CAST content);
+	} else {
+	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
+		"%s: The content is not valid.\n",
+		BAD_CAST des, NULL);
+	}
+    }
+    FREE_AND_NULL(des)
+}
+
+/************************************************************************
+ * 									*
+ * 			Streamable error functions                      *
+ * 									*
+ ************************************************************************/
+
+
+
+
+/************************************************************************
+ * 									*
+ * 			Validation helper functions			*
+ * 									*
+ ************************************************************************/
+
+
+/************************************************************************
+ * 									*
+ * 			Allocation functions				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaNewSchemaForParserCtxt:
+ * @ctxt:  a schema validation context
+ *
+ * Allocate a new Schema structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlSchemaPtr
+xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
+{
+    xmlSchemaPtr ret;
+
+    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchema));
+    ret->dict = ctxt->dict;
+    xmlDictReference(ret->dict);
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaNewFacet:
+ *
+ * Allocate a new Facet structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+xmlSchemaFacetPtr
+xmlSchemaNewFacet(void)
+{
+    xmlSchemaFacetPtr ret;
+
+    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
+    if (ret == NULL) {
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaFacet));
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaNewAnnot:
+ * @ctxt:  a schema validation context
+ * @node:  a node
+ *
+ * Allocate a new annotation structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static xmlSchemaAnnotPtr
+xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlSchemaAnnotPtr ret;
+
+    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaAnnot));
+    ret->content = node;
+    return (ret);
+}
+
+static xmlSchemaItemListPtr
+xmlSchemaItemListCreate(void)
+{
+    xmlSchemaItemListPtr ret;
+
+    ret = xmlMalloc(sizeof(xmlSchemaItemList));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(NULL,
+	    "allocating an item list structure", NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaItemList));
+    return (ret);
+}
+
+static void
+xmlSchemaItemListClear(xmlSchemaItemListPtr list)
+{
+    if (list->items != NULL) {
+	xmlFree(list->items);
+	list->items = NULL;
+    }
+    list->nbItems = 0;
+    list->sizeItems = 0;
+}
+
+static int
+xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
+{
+    if (list->items == NULL) {
+	list->items = (void **) xmlMalloc(
+	    20 * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
+	    return(-1);
+	}
+	list->sizeItems = 20;
+    } else if (list->sizeItems <= list->nbItems) {
+	list->sizeItems *= 2;
+	list->items = (void **) xmlRealloc(list->items,
+	    list->sizeItems * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
+	    list->sizeItems = 0;
+	    return(-1);
+	}
+    }
+    list->items[list->nbItems++] = item;
+    return(0);
+}
+
+static int
+xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
+			 int initialSize,
+			 void *item)
+{
+    if (list->items == NULL) {
+	if (initialSize <= 0)
+	    initialSize = 1;
+	list->items = (void **) xmlMalloc(
+	    initialSize * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
+	    return(-1);
+	}
+	list->sizeItems = initialSize;
+    } else if (list->sizeItems <= list->nbItems) {
+	list->sizeItems *= 2;
+	list->items = (void **) xmlRealloc(list->items,
+	    list->sizeItems * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
+	    list->sizeItems = 0;
+	    return(-1);
+	}
+    }
+    list->items[list->nbItems++] = item;
+    return(0);
+}
+
+static int
+xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
+{
+    if (list->items == NULL) {
+	list->items = (void **) xmlMalloc(
+	    20 * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
+	    return(-1);
+	}
+	list->sizeItems = 20;
+    } else if (list->sizeItems <= list->nbItems) {
+	list->sizeItems *= 2;
+	list->items = (void **) xmlRealloc(list->items,
+	    list->sizeItems * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
+	    list->sizeItems = 0;
+	    return(-1);
+	}
+    }
+    /*
+    * Just append if the index is greater/equal than the item count.
+    */
+    if (idx >= list->nbItems) {
+	list->items[list->nbItems++] = item;
+    } else {
+	int i;
+	for (i = list->nbItems; i > idx; i--)
+	    list->items[i] = list->items[i-1];
+	list->items[idx] = item;
+	list->nbItems++;
+    }
+    return(0);
+}
+
+#if 0 /* enable if ever needed */
+static int
+xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
+			    int initialSize,
+			    void *item,
+			    int idx)
+{
+    if (list->items == NULL) {
+	if (initialSize <= 0)
+	    initialSize = 1;
+	list->items = (void **) xmlMalloc(
+	    initialSize * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
+	    return(-1);
+	}
+	list->sizeItems = initialSize;
+    } else if (list->sizeItems <= list->nbItems) {
+	list->sizeItems *= 2;
+	list->items = (void **) xmlRealloc(list->items,
+	    list->sizeItems * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
+	    list->sizeItems = 0;
+	    return(-1);
+	}
+    }
+    /*
+    * Just append if the index is greater/equal than the item count.
+    */
+    if (idx >= list->nbItems) {
+	list->items[list->nbItems++] = item;
+    } else {
+	int i;
+	for (i = list->nbItems; i > idx; i--)
+	    list->items[i] = list->items[i-1];
+	list->items[idx] = item;
+	list->nbItems++;
+    }
+    return(0);
+}
+#endif
+
+static int
+xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
+{
+    int i;
+    if ((list->items == NULL) || (idx >= list->nbItems)) {
+	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
+	    "index error.\n");
+	return(-1);
+    }
+
+    if (list->nbItems == 1) {
+	/* TODO: Really free the list? */
+	xmlFree(list->items);
+	list->items = NULL;
+	list->nbItems = 0;
+	list->sizeItems = 0;
+    } else if (list->nbItems -1 == idx) {
+	list->nbItems--;
+    } else {
+	for (i = idx; i < list->nbItems -1; i++)
+	    list->items[i] = list->items[i+1];
+	list->nbItems--;
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaItemListFree:
+ * @annot:  a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaItemListFree(xmlSchemaItemListPtr list)
+{
+    if (list == NULL)
+	return;
+    if (list->items != NULL)
+	xmlFree(list->items);
+    xmlFree(list);
+}
+
+static void
+xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
+{
+    if (bucket == NULL)
+	return;
+    if (bucket->globals != NULL) {
+	xmlSchemaComponentListFree(bucket->globals);
+	xmlSchemaItemListFree(bucket->globals);
+    }
+    if (bucket->locals != NULL) {
+	xmlSchemaComponentListFree(bucket->locals);
+	xmlSchemaItemListFree(bucket->locals);
+    }
+    if (bucket->relations != NULL) {
+	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
+	do {
+	    prev = cur;
+	    cur = cur->next;
+	    xmlFree(prev);
+	} while (cur != NULL);
+    }
+    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
+	xmlFreeDoc(bucket->doc);
+    }
+    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
+	if (WXS_IMPBUCKET(bucket)->schema != NULL)
+	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
+    }
+    xmlFree(bucket);
+}
+
+static xmlSchemaBucketPtr
+xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
+			 int type, const xmlChar *targetNamespace)
+{
+    xmlSchemaBucketPtr ret;
+    int size;
+    xmlSchemaPtr mainSchema;
+
+    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
+	PERROR_INT("xmlSchemaBucketCreate",
+	    "no main schema on constructor");
+	return(NULL);
+    }
+    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
+    /* Create the schema bucket. */
+    if (WXS_IS_BUCKET_INCREDEF(type))
+	size = sizeof(xmlSchemaInclude);
+    else
+	size = sizeof(xmlSchemaImport);
+    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
+	return(NULL);
+    }
+    memset(ret, 0, size);
+    ret->targetNamespace = targetNamespace;
+    ret->type = type;
+    ret->globals = xmlSchemaItemListCreate();
+    if (ret->globals == NULL) {
+	xmlFree(ret);
+	return(NULL);
+    }
+    ret->locals = xmlSchemaItemListCreate();
+    if (ret->locals == NULL) {
+	xmlFree(ret);
+	return(NULL);
+    }
+    /*
+    * The following will assure that only the first bucket is marked as
+    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
+    * For each following import buckets an xmlSchema will be created.
+    * An xmlSchema will be created for every distinct targetNamespace.
+    * We assign the targetNamespace to the schemata here.
+    */
+    if (! WXS_HAS_BUCKETS(pctxt)) {
+	if (WXS_IS_BUCKET_INCREDEF(type)) {
+	    PERROR_INT("xmlSchemaBucketCreate",
+		"first bucket but it's an include or redefine");
+	    xmlSchemaBucketFree(ret);
+	    return(NULL);
+	}
+	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
+	ret->type = XML_SCHEMA_SCHEMA_MAIN;
+	/* Point to the *main* schema. */
+	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
+	WXS_IMPBUCKET(ret)->schema = mainSchema;
+	/*
+	* Ensure that the main schema gets a targetNamespace.
+	*/
+	mainSchema->targetNamespace = targetNamespace;
+    } else {
+	if (type == XML_SCHEMA_SCHEMA_MAIN) {
+	    PERROR_INT("xmlSchemaBucketCreate",
+		"main bucket but it's not the first one");
+	    xmlSchemaBucketFree(ret);
+	    return(NULL);
+	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
+	    /*
+	    * Create a schema for imports and assign the
+	    * targetNamespace.
+	    */
+	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
+	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
+		xmlSchemaBucketFree(ret);
+		return(NULL);
+	    }
+	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
+	}
+    }
+    if (WXS_IS_BUCKET_IMPMAIN(type)) {
+	int res;
+	/*
+	* Imports go into the "schemasImports" slot of the main *schema*.
+	* Note that we create an import entry for the main schema as well; i.e.,
+	* even if there's only one schema, we'll get an import.
+	*/
+	if (mainSchema->schemasImports == NULL) {
+	    mainSchema->schemasImports = xmlHashCreateDict(5,
+		WXS_CONSTRUCTOR(pctxt)->dict);
+	    if (mainSchema->schemasImports == NULL) {
+		xmlSchemaBucketFree(ret);
+		return(NULL);
+	    }
+	}
+	if (targetNamespace == NULL)
+	    res = xmlHashAddEntry(mainSchema->schemasImports,
+		XML_SCHEMAS_NO_NAMESPACE, ret);
+	else
+	    res = xmlHashAddEntry(mainSchema->schemasImports,
+		targetNamespace, ret);
+	if (res != 0) {
+	    PERROR_INT("xmlSchemaBucketCreate",
+		"failed to add the schema bucket to the hash");
+	    xmlSchemaBucketFree(ret);
+	    return(NULL);
+	}
+    } else {
+	/* Set the @ownerImport of an include bucket. */
+	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
+	    WXS_INCBUCKET(ret)->ownerImport =
+		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
+	else
+	    WXS_INCBUCKET(ret)->ownerImport =
+		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
+
+	/* Includes got into the "includes" slot of the *main* schema. */
+	if (mainSchema->includes == NULL) {
+	    mainSchema->includes = xmlSchemaItemListCreate();
+	    if (mainSchema->includes == NULL) {
+		xmlSchemaBucketFree(ret);
+		return(NULL);
+	    }
+	}
+	xmlSchemaItemListAdd(mainSchema->includes, ret);
+    }
+    /*
+    * Add to list of all buckets; this is used for lookup
+    * during schema construction time only.
+    */
+    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
+	return(NULL);
+    return(ret);
+}
+
+static int
+xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
+{
+    if (*list == NULL) {
+	*list = xmlSchemaItemListCreate();
+	if (*list == NULL)
+	    return(-1);
+    }
+    xmlSchemaItemListAddSize(*list, initialSize, item);
+    return(0);
+}
+
+/**
+ * xmlSchemaFreeAnnot:
+ * @annot:  a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
+{
+    if (annot == NULL)
+        return;
+    if (annot->next == NULL) {
+	xmlFree(annot);
+    } else {
+	xmlSchemaAnnotPtr prev;
+
+	do {
+	    prev = annot;
+	    annot = annot->next;
+	    xmlFree(prev);
+	} while (annot != NULL);
+    }
+}
+
+/**
+ * xmlSchemaFreeNotation:
+ * @schema:  a schema notation structure
+ *
+ * Deallocate a Schema Notation structure.
+ */
+static void
+xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
+{
+    if (nota == NULL)
+        return;
+    xmlFree(nota);
+}
+
+/**
+ * xmlSchemaFreeAttribute:
+ * @attr:  an attribute declaration
+ *
+ * Deallocates an attribute declaration structure.
+ */
+static void
+xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
+{
+    if (attr == NULL)
+        return;
+    if (attr->annot != NULL)
+	xmlSchemaFreeAnnot(attr->annot);
+    if (attr->defVal != NULL)
+	xmlSchemaFreeValue(attr->defVal);
+    xmlFree(attr);
+}
+
+/**
+ * xmlSchemaFreeAttributeUse:
+ * @use:  an attribute use
+ *
+ * Deallocates an attribute use structure.
+ */
+static void
+xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
+{
+    if (use == NULL)
+        return;
+    if (use->annot != NULL)
+	xmlSchemaFreeAnnot(use->annot);
+    if (use->defVal != NULL)
+	xmlSchemaFreeValue(use->defVal);
+    xmlFree(use);
+}
+
+/**
+ * xmlSchemaFreeAttributeUseProhib:
+ * @prohib:  an attribute use prohibition
+ *
+ * Deallocates an attribute use structure.
+ */
+static void
+xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
+{
+    if (prohib == NULL)
+        return;
+    xmlFree(prohib);
+}
+
+/**
+ * xmlSchemaFreeWildcardNsSet:
+ * set:  a schema wildcard namespace
+ *
+ * Deallocates a list of wildcard constraint structures.
+ */
+static void
+xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
+{
+    xmlSchemaWildcardNsPtr next;
+
+    while (set != NULL) {
+	next = set->next;
+	xmlFree(set);
+	set = next;
+    }
+}
+
+/**
+ * xmlSchemaFreeWildcard:
+ * @wildcard:  a wildcard structure
+ *
+ * Deallocates a wildcard structure.
+ */
+void
+xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
+{
+    if (wildcard == NULL)
+        return;
+    if (wildcard->annot != NULL)
+        xmlSchemaFreeAnnot(wildcard->annot);
+    if (wildcard->nsSet != NULL)
+	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
+    if (wildcard->negNsSet != NULL)
+	xmlFree(wildcard->negNsSet);
+    xmlFree(wildcard);
+}
+
+/**
+ * xmlSchemaFreeAttributeGroup:
+ * @schema:  a schema attribute group structure
+ *
+ * Deallocate a Schema Attribute Group structure.
+ */
+static void
+xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
+{
+    if (attrGr == NULL)
+        return;
+    if (attrGr->annot != NULL)
+        xmlSchemaFreeAnnot(attrGr->annot);
+    if (attrGr->attrUses != NULL)
+	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
+    xmlFree(attrGr);
+}
+
+/**
+ * xmlSchemaFreeQNameRef:
+ * @item: a QName reference structure
+ *
+ * Deallocatea a QName reference structure.
+ */
+static void
+xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
+{
+    xmlFree(item);
+}
+
+/**
+ * xmlSchemaFreeTypeLinkList:
+ * @alink: a type link
+ *
+ * Deallocate a list of types.
+ */
+static void
+xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
+{
+    xmlSchemaTypeLinkPtr next;
+
+    while (link != NULL) {
+	next = link->next;
+	xmlFree(link);
+	link = next;
+    }
+}
+
+static void
+xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
+{
+    xmlSchemaIDCStateObjPtr next;
+    while (sto != NULL) {
+	next = sto->next;
+	if (sto->history != NULL)
+	    xmlFree(sto->history);
+	if (sto->xpathCtxt != NULL)
+	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
+	xmlFree(sto);
+	sto = next;
+    }
+}
+
+/**
+ * xmlSchemaFreeIDC:
+ * @idc: a identity-constraint definition
+ *
+ * Deallocates an identity-constraint definition.
+ */
+static void
+xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
+{
+    xmlSchemaIDCSelectPtr cur, prev;
+
+    if (idcDef == NULL)
+	return;
+    if (idcDef->annot != NULL)
+        xmlSchemaFreeAnnot(idcDef->annot);
+    /* Selector */
+    if (idcDef->selector != NULL) {
+	if (idcDef->selector->xpathComp != NULL)
+	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
+	xmlFree(idcDef->selector);
+    }
+    /* Fields */
+    if (idcDef->fields != NULL) {
+	cur = idcDef->fields;
+	do {
+	    prev = cur;
+	    cur = cur->next;
+	    if (prev->xpathComp != NULL)
+		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
+	    xmlFree(prev);
+	} while (cur != NULL);
+    }
+    xmlFree(idcDef);
+}
+
+/**
+ * xmlSchemaFreeElement:
+ * @schema:  a schema element structure
+ *
+ * Deallocate a Schema Element structure.
+ */
+static void
+xmlSchemaFreeElement(xmlSchemaElementPtr elem)
+{
+    if (elem == NULL)
+        return;
+    if (elem->annot != NULL)
+        xmlSchemaFreeAnnot(elem->annot);
+    if (elem->contModel != NULL)
+        xmlRegFreeRegexp(elem->contModel);
+    if (elem->defVal != NULL)
+	xmlSchemaFreeValue(elem->defVal);
+    xmlFree(elem);
+}
+
+/**
+ * xmlSchemaFreeFacet:
+ * @facet:  a schema facet structure
+ *
+ * Deallocate a Schema Facet structure.
+ */
+void
+xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
+{
+    if (facet == NULL)
+        return;
+    if (facet->val != NULL)
+        xmlSchemaFreeValue(facet->val);
+    if (facet->regexp != NULL)
+        xmlRegFreeRegexp(facet->regexp);
+    if (facet->annot != NULL)
+        xmlSchemaFreeAnnot(facet->annot);
+    xmlFree(facet);
+}
+
+/**
+ * xmlSchemaFreeType:
+ * @type:  a schema type structure
+ *
+ * Deallocate a Schema Type structure.
+ */
+void
+xmlSchemaFreeType(xmlSchemaTypePtr type)
+{
+    if (type == NULL)
+        return;
+    if (type->annot != NULL)
+        xmlSchemaFreeAnnot(type->annot);
+    if (type->facets != NULL) {
+        xmlSchemaFacetPtr facet, next;
+
+        facet = type->facets;
+        while (facet != NULL) {
+            next = facet->next;
+            xmlSchemaFreeFacet(facet);
+            facet = next;
+        }
+    }
+    if (type->attrUses != NULL)
+	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
+    if (type->memberTypes != NULL)
+	xmlSchemaFreeTypeLinkList(type->memberTypes);
+    if (type->facetSet != NULL) {
+	xmlSchemaFacetLinkPtr next, link;
+
+	link = type->facetSet;
+	do {
+	    next = link->next;
+	    xmlFree(link);
+	    link = next;
+	} while (link != NULL);
+    }
+    if (type->contModel != NULL)
+        xmlRegFreeRegexp(type->contModel);
+    xmlFree(type);
+}
+
+/**
+ * xmlSchemaFreeModelGroupDef:
+ * @item:  a schema model group definition
+ *
+ * Deallocates a schema model group definition.
+ */
+static void
+xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
+{
+    if (item->annot != NULL)
+	xmlSchemaFreeAnnot(item->annot);
+    xmlFree(item);
+}
+
+/**
+ * xmlSchemaFreeModelGroup:
+ * @item:  a schema model group
+ *
+ * Deallocates a schema model group structure.
+ */
+static void
+xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
+{
+    if (item->annot != NULL)
+	xmlSchemaFreeAnnot(item->annot);
+    xmlFree(item);
+}
+
+static void
+xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
+{
+    if ((list == NULL) || (list->nbItems == 0))
+	return;
+    {
+	xmlSchemaTreeItemPtr item;
+	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
+	int i;
+
+	for (i = 0; i < list->nbItems; i++) {
+	    item = items[i];
+	    if (item == NULL)
+		continue;
+	    switch (item->type) {
+		case XML_SCHEMA_TYPE_SIMPLE:
+		case XML_SCHEMA_TYPE_COMPLEX:
+		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_ATTRIBUTE:
+		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
+		    break;
+		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
+		    xmlSchemaFreeAttributeUseProhib(
+			(xmlSchemaAttributeUseProhibPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_ELEMENT:
+		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_PARTICLE:
+		    if (item->annot != NULL)
+			xmlSchemaFreeAnnot(item->annot);
+		    xmlFree(item);
+		    break;
+		case XML_SCHEMA_TYPE_SEQUENCE:
+		case XML_SCHEMA_TYPE_CHOICE:
+		case XML_SCHEMA_TYPE_ALL:
+		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		    xmlSchemaFreeAttributeGroup(
+			(xmlSchemaAttributeGroupPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_GROUP:
+		    xmlSchemaFreeModelGroupDef(
+			(xmlSchemaModelGroupDefPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_ANY:
+		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_IDC_KEY:
+		case XML_SCHEMA_TYPE_IDC_UNIQUE:
+		case XML_SCHEMA_TYPE_IDC_KEYREF:
+		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
+		    break;
+		case XML_SCHEMA_TYPE_NOTATION:
+		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
+		    break;
+		case XML_SCHEMA_EXTRA_QNAMEREF:
+		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
+		    break;
+		default: {
+		    /* TODO: This should never be hit. */
+		    xmlSchemaPSimpleInternalErr(NULL,
+			"Internal error: xmlSchemaComponentListFree, "
+			"unexpected component type '%s'\n",
+			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
+			 }
+		    break;
+	    }
+	}
+	list->nbItems = 0;
+    }
+}
+
+/**
+ * xmlSchemaFree:
+ * @schema:  a schema structure
+ *
+ * Deallocate a Schema structure.
+ */
+void
+xmlSchemaFree(xmlSchemaPtr schema)
+{
+    if (schema == NULL)
+        return;
+    /* @volatiles is not used anymore :-/ */
+    if (schema->volatiles != NULL)
+	TODO
+    /*
+    * Note that those slots are not responsible for freeing
+    * schema components anymore; this will now be done by
+    * the schema buckets.
+    */
+    if (schema->notaDecl != NULL)
+        xmlHashFree(schema->notaDecl, NULL);
+    if (schema->attrDecl != NULL)
+        xmlHashFree(schema->attrDecl, NULL);
+    if (schema->attrgrpDecl != NULL)
+        xmlHashFree(schema->attrgrpDecl, NULL);
+    if (schema->elemDecl != NULL)
+        xmlHashFree(schema->elemDecl, NULL);
+    if (schema->typeDecl != NULL)
+        xmlHashFree(schema->typeDecl, NULL);
+    if (schema->groupDecl != NULL)
+        xmlHashFree(schema->groupDecl, NULL);
+    if (schema->idcDef != NULL)
+        xmlHashFree(schema->idcDef, NULL);
+
+    if (schema->schemasImports != NULL)
+	xmlHashFree(schema->schemasImports,
+		    (xmlHashDeallocator) xmlSchemaBucketFree);
+    if (schema->includes != NULL) {
+	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
+	int i;
+	for (i = 0; i < list->nbItems; i++) {
+	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
+	}
+	xmlSchemaItemListFree(list);
+    }
+    if (schema->annot != NULL)
+        xmlSchemaFreeAnnot(schema->annot);
+    /* Never free the doc here, since this will be done by the buckets. */
+
+    xmlDictFree(schema->dict);
+    xmlFree(schema);
+}
+
+/************************************************************************
+ * 									*
+ * 			Debug functions					*
+ * 									*
+ ************************************************************************/
+
+#ifdef LIBXML_OUTPUT_ENABLED
+
+static void
+xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
+
+/**
+ * xmlSchemaElementDump:
+ * @elem:  an element
+ * @output:  the file output
+ *
+ * Dump the element
+ */
+static void
+xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
+                     const xmlChar * name ATTRIBUTE_UNUSED,
+		     const xmlChar * namespace ATTRIBUTE_UNUSED,
+                     const xmlChar * context ATTRIBUTE_UNUSED)
+{
+    if (elem == NULL)
+        return;
+
+
+    fprintf(output, "Element");
+    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
+	fprintf(output, " (global)");
+    fprintf(output, ": '%s' ", elem->name);
+    if (namespace != NULL)
+	fprintf(output, "ns '%s'", namespace);
+    fprintf(output, "\n");
+#if 0
+    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
+	fprintf(output, "  min %d ", elem->minOccurs);
+        if (elem->maxOccurs >= UNBOUNDED)
+            fprintf(output, "max: unbounded\n");
+        else if (elem->maxOccurs != 1)
+            fprintf(output, "max: %d\n", elem->maxOccurs);
+        else
+            fprintf(output, "\n");
+    }
+#endif
+    /*
+    * Misc other properties.
+    */
+    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
+	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
+	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
+	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
+	fprintf(output, "  props: ");
+	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
+	    fprintf(output, "[fixed] ");
+	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
+	    fprintf(output, "[default] ");
+	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
+	    fprintf(output, "[abstract] ");
+	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
+	    fprintf(output, "[nillable] ");
+	fprintf(output, "\n");
+    }
+    /*
+    * Default/fixed value.
+    */
+    if (elem->value != NULL)
+	fprintf(output, "  value: '%s'\n", elem->value);
+    /*
+    * Type.
+    */
+    if (elem->namedType != NULL) {
+	fprintf(output, "  type: '%s' ", elem->namedType);
+	if (elem->namedTypeNs != NULL)
+	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
+	else
+	    fprintf(output, "\n");
+    } else if (elem->subtypes != NULL) {
+	/*
+	* Dump local types.
+	*/
+	xmlSchemaTypeDump(elem->subtypes, output);
+    }
+    /*
+    * Substitution group.
+    */
+    if (elem->substGroup != NULL) {
+	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
+	if (elem->substGroupNs != NULL)
+	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
+	else
+	    fprintf(output, "\n");
+    }
+}
+
+/**
+ * xmlSchemaAnnotDump:
+ * @output:  the file output
+ * @annot:  a annotation
+ *
+ * Dump the annotation
+ */
+static void
+xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
+{
+    xmlChar *content;
+
+    if (annot == NULL)
+        return;
+
+    content = xmlNodeGetContent(annot->content);
+    if (content != NULL) {
+        fprintf(output, "  Annot: %s\n", content);
+        xmlFree(content);
+    } else
+        fprintf(output, "  Annot: empty\n");
+}
+
+/**
+ * xmlSchemaContentModelDump:
+ * @particle: the schema particle
+ * @output: the file output
+ * @depth: the depth used for intentation
+ *
+ * Dump a SchemaType structure
+ */
+static void
+xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
+{
+    xmlChar *str = NULL;
+    xmlSchemaTreeItemPtr term;
+    char shift[100];
+    int i;
+
+    if (particle == NULL)
+	return;
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+    fprintf(output, "%s", shift);
+    if (particle->children == NULL) {
+	fprintf(output, "MISSING particle term\n");
+	return;
+    }
+    term = particle->children;
+    if (term == NULL) {
+	fprintf(output, "(NULL)");
+    } else {
+	switch (term->type) {
+	    case XML_SCHEMA_TYPE_ELEMENT:
+		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
+		    ((xmlSchemaElementPtr)term)->targetNamespace,
+		    ((xmlSchemaElementPtr)term)->name));
+		FREE_AND_NULL(str);
+		break;
+	    case XML_SCHEMA_TYPE_SEQUENCE:
+		fprintf(output, "SEQUENCE");
+		break;
+	    case XML_SCHEMA_TYPE_CHOICE:
+		fprintf(output, "CHOICE");
+		break;
+	    case XML_SCHEMA_TYPE_ALL:
+		fprintf(output, "ALL");
+		break;
+	    case XML_SCHEMA_TYPE_ANY:
+		fprintf(output, "ANY");
+		break;
+	    default:
+		fprintf(output, "UNKNOWN\n");
+		return;
+	}
+    }
+    if (particle->minOccurs != 1)
+	fprintf(output, " min: %d", particle->minOccurs);
+    if (particle->maxOccurs >= UNBOUNDED)
+	fprintf(output, " max: unbounded");
+    else if (particle->maxOccurs != 1)
+	fprintf(output, " max: %d", particle->maxOccurs);
+    fprintf(output, "\n");
+    if (term &&
+	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
+	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
+	 (term->children != NULL)) {
+	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
+	    output, depth +1);
+    }
+    if (particle->next != NULL)
+	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
+		output, depth);
+}
+
+/**
+ * xmlSchemaAttrUsesDump:
+ * @uses:  attribute uses list
+ * @output:  the file output
+ *
+ * Dumps a list of attribute use components.
+ */
+static void
+xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
+{
+    xmlSchemaAttributeUsePtr use;
+    xmlSchemaAttributeUseProhibPtr prohib;
+    xmlSchemaQNameRefPtr ref;
+    const xmlChar *name, *tns;
+    xmlChar *str = NULL;
+    int i;
+
+    if ((uses == NULL) || (uses->nbItems == 0))
+        return;
+
+    fprintf(output, "  attributes:\n");
+    for (i = 0; i < uses->nbItems; i++) {
+	use = uses->items[i];
+	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
+	    fprintf(output, "  [prohibition] ");
+	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
+	    name = prohib->name;
+	    tns = prohib->targetNamespace;
+	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
+	    fprintf(output, "  [reference] ");
+	    ref = (xmlSchemaQNameRefPtr) use;
+	    name = ref->name;
+	    tns = ref->targetNamespace;
+	} else {
+	    fprintf(output, "  [use] ");
+	    name = WXS_ATTRUSE_DECL_NAME(use);
+	    tns = WXS_ATTRUSE_DECL_TNS(use);
+	}
+	fprintf(output, "'%s'\n",
+	    (const char *) xmlSchemaFormatQName(&str, tns, name));
+	FREE_AND_NULL(str);
+    }
+}
+
+/**
+ * xmlSchemaTypeDump:
+ * @output:  the file output
+ * @type:  a type structure
+ *
+ * Dump a SchemaType structure
+ */
+static void
+xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
+{
+    if (type == NULL) {
+        fprintf(output, "Type: NULL\n");
+        return;
+    }
+    fprintf(output, "Type: ");
+    if (type->name != NULL)
+        fprintf(output, "'%s' ", type->name);
+    else
+        fprintf(output, "(no name) ");
+    if (type->targetNamespace != NULL)
+	fprintf(output, "ns '%s' ", type->targetNamespace);
+    switch (type->type) {
+        case XML_SCHEMA_TYPE_BASIC:
+            fprintf(output, "[basic] ");
+            break;
+        case XML_SCHEMA_TYPE_SIMPLE:
+            fprintf(output, "[simple] ");
+            break;
+        case XML_SCHEMA_TYPE_COMPLEX:
+            fprintf(output, "[complex] ");
+            break;
+        case XML_SCHEMA_TYPE_SEQUENCE:
+            fprintf(output, "[sequence] ");
+            break;
+        case XML_SCHEMA_TYPE_CHOICE:
+            fprintf(output, "[choice] ");
+            break;
+        case XML_SCHEMA_TYPE_ALL:
+            fprintf(output, "[all] ");
+            break;
+        case XML_SCHEMA_TYPE_UR:
+            fprintf(output, "[ur] ");
+            break;
+        case XML_SCHEMA_TYPE_RESTRICTION:
+            fprintf(output, "[restriction] ");
+            break;
+        case XML_SCHEMA_TYPE_EXTENSION:
+            fprintf(output, "[extension] ");
+            break;
+        default:
+            fprintf(output, "[unknown type %d] ", type->type);
+            break;
+    }
+    fprintf(output, "content: ");
+    switch (type->contentType) {
+        case XML_SCHEMA_CONTENT_UNKNOWN:
+            fprintf(output, "[unknown] ");
+            break;
+        case XML_SCHEMA_CONTENT_EMPTY:
+            fprintf(output, "[empty] ");
+            break;
+        case XML_SCHEMA_CONTENT_ELEMENTS:
+            fprintf(output, "[element] ");
+            break;
+        case XML_SCHEMA_CONTENT_MIXED:
+            fprintf(output, "[mixed] ");
+            break;
+        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
+	/* not used. */
+            break;
+        case XML_SCHEMA_CONTENT_BASIC:
+            fprintf(output, "[basic] ");
+            break;
+        case XML_SCHEMA_CONTENT_SIMPLE:
+            fprintf(output, "[simple] ");
+            break;
+        case XML_SCHEMA_CONTENT_ANY:
+            fprintf(output, "[any] ");
+            break;
+    }
+    fprintf(output, "\n");
+    if (type->base != NULL) {
+        fprintf(output, "  base type: '%s'", type->base);
+	if (type->baseNs != NULL)
+	    fprintf(output, " ns '%s'\n", type->baseNs);
+	else
+	    fprintf(output, "\n");
+    }
+    if (type->attrUses != NULL)
+	xmlSchemaAttrUsesDump(type->attrUses, output);
+    if (type->annot != NULL)
+        xmlSchemaAnnotDump(output, type->annot);
+#ifdef DUMP_CONTENT_MODEL
+    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
+	(type->subtypes != NULL)) {
+	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
+	    output, 1);
+    }
+#endif
+}
+
+/**
+ * xmlSchemaDump:
+ * @output:  the file output
+ * @schema:  a schema structure
+ *
+ * Dump a Schema structure.
+ */
+void
+xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
+{
+    if (output == NULL)
+        return;
+    if (schema == NULL) {
+        fprintf(output, "Schemas: NULL\n");
+        return;
+    }
+    fprintf(output, "Schemas: ");
+    if (schema->name != NULL)
+        fprintf(output, "%s, ", schema->name);
+    else
+        fprintf(output, "no name, ");
+    if (schema->targetNamespace != NULL)
+        fprintf(output, "%s", (const char *) schema->targetNamespace);
+    else
+        fprintf(output, "no target namespace");
+    fprintf(output, "\n");
+    if (schema->annot != NULL)
+        xmlSchemaAnnotDump(output, schema->annot);
+    xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
+                output);
+    xmlHashScanFull(schema->elemDecl,
+                    (xmlHashScannerFull) xmlSchemaElementDump, output);
+}
+
+#ifdef DEBUG_IDC_NODE_TABLE
+/**
+ * xmlSchemaDebugDumpIDCTable:
+ * @vctxt: the WXS validation context
+ *
+ * Displays the current IDC table for debug purposes.
+ */
+static void
+xmlSchemaDebugDumpIDCTable(FILE * output,
+			   const xmlChar *namespaceName,
+			   const xmlChar *localName,
+			   xmlSchemaPSVIIDCBindingPtr bind)
+{
+    xmlChar *str = NULL;
+    const xmlChar *value;
+    xmlSchemaPSVIIDCNodePtr tab;
+    xmlSchemaPSVIIDCKeyPtr key;
+    int i, j, res;
+
+    fprintf(output, "IDC: TABLES on '%s'\n",
+	xmlSchemaFormatQName(&str, namespaceName, localName));
+    FREE_AND_NULL(str)
+
+    if (bind == NULL)
+	return;
+    do {
+	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
+	    xmlSchemaGetComponentQName(&str,
+		bind->definition), bind->nbNodes);
+	FREE_AND_NULL(str)
+	for (i = 0; i < bind->nbNodes; i++) {
+	    tab = bind->nodeTable[i];
+	    fprintf(output, "         ( ");
+	    for (j = 0; j < bind->definition->nbFields; j++) {
+		key = tab->keys[j];
+		if ((key != NULL) && (key->val != NULL)) {
+		    res = xmlSchemaGetCanonValue(key->val, &value);
+		    if (res >= 0)
+			fprintf(output, "'%s' ", value);
+		    else
+			fprintf(output, "CANON-VALUE-FAILED ");
+		    if (res == 0)
+			FREE_AND_NULL(value)
+		} else if (key != NULL)
+		    fprintf(output, "(no val), ");
+		else
+		    fprintf(output, "(key missing), ");
+	    }
+	    fprintf(output, ")\n");
+	}
+	if (bind->dupls && bind->dupls->nbItems) {
+	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
+	    for (i = 0; i < bind->dupls->nbItems; i++) {
+		tab = bind->dupls->items[i];
+		fprintf(output, "         ( ");
+		for (j = 0; j < bind->definition->nbFields; j++) {
+		    key = tab->keys[j];
+		    if ((key != NULL) && (key->val != NULL)) {
+			res = xmlSchemaGetCanonValue(key->val, &value);
+			if (res >= 0)
+			    fprintf(output, "'%s' ", value);
+			else
+			    fprintf(output, "CANON-VALUE-FAILED ");
+			if (res == 0)
+			    FREE_AND_NULL(value)
+		    } else if (key != NULL)
+		    fprintf(output, "(no val), ");
+			else
+			    fprintf(output, "(key missing), ");
+		}
+		fprintf(output, ")\n");
+	    }
+	}
+	bind = bind->next;
+    } while (bind != NULL);
+}
+#endif /* DEBUG_IDC */
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/************************************************************************
+ *									*
+ * 			Utilities					*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaGetPropNode:
+ * @node: the element node
+ * @name: the name of the attribute
+ *
+ * Seeks an attribute with a name of @name in
+ * no namespace.
+ *
+ * Returns the attribute or NULL if not present.
+ */
+static xmlAttrPtr
+xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
+{
+    xmlAttrPtr prop;
+
+    if ((node == NULL) || (name == NULL))
+	return(NULL);
+    prop = node->properties;
+    while (prop != NULL) {
+        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
+	    return(prop);
+	prop = prop->next;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaGetPropNodeNs:
+ * @node: the element node
+ * @uri: the uri
+ * @name: the name of the attribute
+ *
+ * Seeks an attribute with a local name of @name and
+ * a namespace URI of @uri.
+ *
+ * Returns the attribute or NULL if not present.
+ */
+static xmlAttrPtr
+xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
+{
+    xmlAttrPtr prop;
+
+    if ((node == NULL) || (name == NULL))
+	return(NULL);
+    prop = node->properties;
+    while (prop != NULL) {
+	if ((prop->ns != NULL) &&
+	    xmlStrEqual(prop->name, BAD_CAST name) &&
+	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
+	    return(prop);
+	prop = prop->next;
+    }
+    return (NULL);
+}
+
+static const xmlChar *
+xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
+{
+    xmlChar *val;
+    const xmlChar *ret;
+
+    val = xmlNodeGetContent(node);
+    if (val == NULL)
+	val = xmlStrdup((xmlChar *)"");
+    ret = xmlDictLookup(ctxt->dict, val, -1);
+    xmlFree(val);
+    return(ret);
+}
+
+static const xmlChar *
+xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
+{
+    return((const xmlChar*) xmlNodeGetContent(node));
+}
+
+/**
+ * xmlSchemaGetProp:
+ * @ctxt: the parser context
+ * @node: the node
+ * @name: the property name
+ *
+ * Read a attribute value and internalize the string
+ *
+ * Returns the string or NULL if not present.
+ */
+static const xmlChar *
+xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+                 const char *name)
+{
+    xmlChar *val;
+    const xmlChar *ret;
+
+    val = xmlGetNoNsProp(node, BAD_CAST name);
+    if (val == NULL)
+        return(NULL);
+    ret = xmlDictLookup(ctxt->dict, val, -1);
+    xmlFree(val);
+    return(ret);
+}
+
+/************************************************************************
+ * 									*
+ * 			Parsing functions				*
+ * 									*
+ ************************************************************************/
+
+#define WXS_FIND_GLOBAL_ITEM(slot)			\
+    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
+	ret = xmlHashLookup(schema->slot, name); \
+	if (ret != NULL) goto exit; \
+    } \
+    if (xmlHashSize(schema->schemasImports) > 1) { \
+	xmlSchemaImportPtr import; \
+	if (nsName == NULL) \
+	    import = xmlHashLookup(schema->schemasImports, \
+		XML_SCHEMAS_NO_NAMESPACE); \
+	else \
+	    import = xmlHashLookup(schema->schemasImports, nsName); \
+	if (import == NULL) \
+	    goto exit; \
+	ret = xmlHashLookup(import->schema->slot, name); \
+    }
+
+/**
+ * xmlSchemaGetElem:
+ * @schema:  the schema context
+ * @name:  the element name
+ * @ns:  the element namespace
+ *
+ * Lookup a global element declaration in the schema.
+ *
+ * Returns the element declaration or NULL if not found.
+ */
+static xmlSchemaElementPtr
+xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * nsName)
+{
+    xmlSchemaElementPtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return(NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(elemDecl)
+    }
+exit:
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (nsName == NULL)
+            fprintf(stderr, "Unable to lookup element decl. %s", name);
+        else
+            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
+                    nsName);
+    }
+#endif
+    return (ret);
+}
+
+/**
+ * xmlSchemaGetType:
+ * @schema:  the main schema
+ * @name:  the type's name
+ * nsName:  the type's namespace
+ *
+ * Lookup a type in the schemas or the predefined types
+ *
+ * Returns the group definition or NULL if not found.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * nsName)
+{
+    xmlSchemaTypePtr ret = NULL;
+
+    if (name == NULL)
+        return (NULL);
+    /* First try the built-in types. */
+    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
+	ret = xmlSchemaGetPredefinedType(name, nsName);
+	if (ret != NULL)
+	    goto exit;
+	/*
+	* Note that we try the parsed schemas as well here
+	* since one might have parsed the S4S, which contain more
+	* than the built-in types.
+	* TODO: Can we optimize this?
+	*/
+    }
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(typeDecl)
+    }
+exit:
+
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (nsName == NULL)
+            fprintf(stderr, "Unable to lookup type %s", name);
+        else
+            fprintf(stderr, "Unable to lookup type %s:%s", name,
+                    nsName);
+    }
+#endif
+    return (ret);
+}
+
+/**
+ * xmlSchemaGetAttributeDecl:
+ * @schema:  the context of the schema
+ * @name:  the name of the attribute
+ * @ns:  the target namespace of the attribute
+ *
+ * Lookup a an attribute in the schema or imported schemas
+ *
+ * Returns the attribute declaration or NULL if not found.
+ */
+static xmlSchemaAttributePtr
+xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * nsName)
+{
+    xmlSchemaAttributePtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(attrDecl)
+    }
+exit:
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (nsName == NULL)
+            fprintf(stderr, "Unable to lookup attribute %s", name);
+        else
+            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
+                    nsName);
+    }
+#endif
+    return (ret);
+}
+
+/**
+ * xmlSchemaGetAttributeGroup:
+ * @schema:  the context of the schema
+ * @name:  the name of the attribute group
+ * @ns:  the target namespace of the attribute group
+ *
+ * Lookup a an attribute group in the schema or imported schemas
+ *
+ * Returns the attribute group definition or NULL if not found.
+ */
+static xmlSchemaAttributeGroupPtr
+xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * nsName)
+{
+    xmlSchemaAttributeGroupPtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
+    }
+exit:
+    /* TODO:
+    if ((ret != NULL) && (ret->redef != NULL)) {
+	* Return the last redefinition. *
+	ret = ret->redef;
+    }
+    */
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (nsName == NULL)
+            fprintf(stderr, "Unable to lookup attribute group %s", name);
+        else
+            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
+                    nsName);
+    }
+#endif
+    return (ret);
+}
+
+/**
+ * xmlSchemaGetGroup:
+ * @schema:  the context of the schema
+ * @name:  the name of the group
+ * @ns:  the target namespace of the group
+ *
+ * Lookup a group in the schema or imported schemas
+ *
+ * Returns the group definition or NULL if not found.
+ */
+static xmlSchemaModelGroupDefPtr
+xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * nsName)
+{
+    xmlSchemaModelGroupDefPtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(groupDecl)
+    }
+exit:
+
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (nsName == NULL)
+            fprintf(stderr, "Unable to lookup group %s", name);
+        else
+            fprintf(stderr, "Unable to lookup group %s:%s", name,
+                    nsName);
+    }
+#endif
+    return (ret);
+}
+
+static xmlSchemaNotationPtr
+xmlSchemaGetNotation(xmlSchemaPtr schema,
+		     const xmlChar *name,
+		     const xmlChar *nsName)
+{
+    xmlSchemaNotationPtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(notaDecl)
+    }
+exit:
+    return (ret);
+}
+
+static xmlSchemaIDCPtr
+xmlSchemaGetIDC(xmlSchemaPtr schema,
+		const xmlChar *name,
+		const xmlChar *nsName)
+{
+    xmlSchemaIDCPtr ret = NULL;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    if (schema != NULL) {
+	WXS_FIND_GLOBAL_ITEM(idcDef)
+    }
+exit:
+    return (ret);
+}
+
+/**
+ * xmlSchemaGetNamedComponent:
+ * @schema:  the schema
+ * @name:  the name of the group
+ * @ns:  the target namespace of the group
+ *
+ * Lookup a group in the schema or imported schemas
+ *
+ * Returns the group definition or NULL if not found.
+ */
+static xmlSchemaBasicItemPtr
+xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
+			   xmlSchemaTypeType itemType,
+			   const xmlChar *name,
+			   const xmlChar *targetNs)
+{
+    switch (itemType) {
+	case XML_SCHEMA_TYPE_GROUP:
+	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
+		name, targetNs));
+	case XML_SCHEMA_TYPE_ELEMENT:
+	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
+		name, targetNs));
+	default:
+	    TODO
+	    return (NULL);
+    }
+}
+
+/************************************************************************
+ * 									*
+ * 			Parsing functions				*
+ * 									*
+ ************************************************************************/
+
+#define IS_BLANK_NODE(n)						\
+    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
+
+/**
+ * xmlSchemaIsBlank:
+ * @str:  a string
+ * @len: the length of the string or -1
+ *
+ * Check if a string is ignorable
+ *
+ * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
+ */
+static int
+xmlSchemaIsBlank(xmlChar * str, int len)
+{
+    if (str == NULL)
+        return (1);
+    if (len < 0) {
+	while (*str != 0) {
+	    if (!(IS_BLANK_CH(*str)))
+		return (0);
+	    str++;
+	}
+    } else while ((*str != 0) && (len != 0)) {
+	if (!(IS_BLANK_CH(*str)))
+	    return (0);
+	str++;
+	len--;
+    }
+
+    return (1);
+}
+
+#define WXS_COMP_NAME(c, t) ((t) (c))->name
+#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
+/*
+* xmlSchemaFindRedefCompInGraph:
+* ATTENTION TODO: This uses pointer comp. for strings.
+*/
+static xmlSchemaBasicItemPtr
+xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
+			      xmlSchemaTypeType type,
+			      const xmlChar *name,
+			      const xmlChar *nsName)
+{
+    xmlSchemaBasicItemPtr ret;
+    int i;
+
+    if ((bucket == NULL) || (name == NULL))
+	return(NULL);
+    if ((bucket->globals == NULL) ||
+	(bucket->globals->nbItems == 0))
+	goto subschemas;
+    /*
+    * Search in global components.
+    */
+    for (i = 0; i < bucket->globals->nbItems; i++) {
+	ret = bucket->globals->items[i];
+	if (ret->type == type) {
+	    switch (type) {
+		case XML_SCHEMA_TYPE_COMPLEX:
+		case XML_SCHEMA_TYPE_SIMPLE:
+		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
+			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
+			nsName))
+		    {
+			return(ret);
+		    }
+		    break;
+		case XML_SCHEMA_TYPE_GROUP:
+		    if ((WXS_COMP_NAME(ret,
+			    xmlSchemaModelGroupDefPtr) == name) &&
+			(WXS_COMP_TNS(ret,
+			    xmlSchemaModelGroupDefPtr) == nsName))
+		    {
+			return(ret);
+		    }
+		    break;
+		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		    if ((WXS_COMP_NAME(ret,
+			    xmlSchemaAttributeGroupPtr) == name) &&
+			(WXS_COMP_TNS(ret,
+			    xmlSchemaAttributeGroupPtr) == nsName))
+		    {
+			return(ret);
+		    }
+		    break;
+		default:
+		    /* Should not be hit. */
+		    return(NULL);
+	    }
+	}
+    }
+subschemas:
+    /*
+    * Process imported/included schemas.
+    */
+    if (bucket->relations != NULL) {
+	xmlSchemaSchemaRelationPtr rel = bucket->relations;
+
+	/*
+	* TODO: Marking the bucket will not avoid multiple searches
+	* in the same schema, but avoids at least circularity.
+	*/
+	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
+	do {
+	    if ((rel->bucket != NULL) &&
+		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
+		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
+		    type, name, nsName);
+		if (ret != NULL)
+		    return(ret);
+	    }
+	    rel = rel->next;
+	} while (rel != NULL);
+	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlSchemaAddNotation:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the item name
+ *
+ * Add an XML schema annotation declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaNotationPtr
+xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                     const xmlChar *name, const xmlChar *nsName,
+		     xmlNodePtr node ATTRIBUTE_UNUSED)
+{
+    xmlSchemaNotationPtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaNotation));
+    ret->type = XML_SCHEMA_TYPE_NOTATION;
+    ret->name = name;
+    ret->targetNamespace = nsName;
+    /* TODO: do we need the node to be set?
+    * ret->node = node;*/
+    WXS_ADD_GLOBAL(ctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddAttribute:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the item name
+ * @namespace:  the namespace
+ *
+ * Add an XML schema Attrribute declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaAttributePtr
+xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                      const xmlChar * name, const xmlChar * nsName,
+		      xmlNodePtr node, int topLevel)
+{
+    xmlSchemaAttributePtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaAttribute));
+    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
+    ret->node = node;
+    ret->name = name;
+    ret->targetNamespace = nsName;
+
+    if (topLevel)
+	WXS_ADD_GLOBAL(ctxt, ret);
+    else
+	WXS_ADD_LOCAL(ctxt, ret);
+    WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddAttributeUse:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the item name
+ * @namespace:  the namespace
+ *
+ * Add an XML schema Attrribute declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaAttributeUsePtr
+xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
+			 xmlNodePtr node)
+{
+    xmlSchemaAttributeUsePtr ret = NULL;
+
+    if (pctxt == NULL)
+        return (NULL);
+
+    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
+    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
+    ret->node = node;
+
+    WXS_ADD_LOCAL(pctxt, ret);
+    return (ret);
+}
+
+/*
+* xmlSchemaAddRedef:
+*
+* Adds a redefinition information. This is used at a later stage to:
+* resolve references to the redefined components and to check constraints.
+*/
+static xmlSchemaRedefPtr
+xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
+		  xmlSchemaBucketPtr targetBucket,
+		  void *item,
+		  const xmlChar *refName,
+		  const xmlChar *refTargetNs)
+{
+    xmlSchemaRedefPtr ret;
+
+    ret = (xmlSchemaRedefPtr)
+	xmlMalloc(sizeof(xmlSchemaRedef));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(pctxt,
+	    "allocating redefinition info", NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaRedef));
+    ret->item = item;
+    ret->targetBucket = targetBucket;
+    ret->refName = refName;
+    ret->refTargetNs = refTargetNs;
+    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
+	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
+    else
+	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
+    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddAttributeGroupDefinition:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the item name
+ * @nsName:  the target namespace
+ * @node: the corresponding node
+ *
+ * Add an XML schema Attrribute Group definition.
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaAttributeGroupPtr
+xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
+                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
+			   const xmlChar *name,
+			   const xmlChar *nsName,
+			   xmlNodePtr node)
+{
+    xmlSchemaAttributeGroupPtr ret = NULL;
+
+    if ((pctxt == NULL) || (name == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaAttributeGroupPtr)
+        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
+    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
+    ret->name = name;
+    ret->targetNamespace = nsName;
+    ret->node = node;
+
+    /* TODO: Remove the flag. */
+    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
+    if (pctxt->isRedefine) {
+	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
+	    ret, name, nsName);
+	if (pctxt->redef == NULL) {
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	pctxt->redefCounter = 0;
+    }
+    WXS_ADD_GLOBAL(pctxt, ret);
+    WXS_ADD_PENDING(pctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddElement:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the type name
+ * @namespace:  the type namespace
+ *
+ * Add an XML schema Element declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaElementPtr
+xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
+                    const xmlChar * name, const xmlChar * nsName,
+		    xmlNodePtr node, int topLevel)
+{
+    xmlSchemaElementPtr ret = NULL;
+
+    if ((ctxt == NULL) || (name == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaElement));
+    ret->type = XML_SCHEMA_TYPE_ELEMENT;
+    ret->name = name;
+    ret->targetNamespace = nsName;
+    ret->node = node;
+
+    if (topLevel)
+	WXS_ADD_GLOBAL(ctxt, ret);
+    else
+	WXS_ADD_LOCAL(ctxt, ret);
+    WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddType:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @name:  the item name
+ * @namespace:  the namespace
+ *
+ * Add an XML schema item
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+		 xmlSchemaTypeType type,
+                 const xmlChar * name, const xmlChar * nsName,
+		 xmlNodePtr node, int topLevel)
+{
+    xmlSchemaTypePtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaType));
+    ret->type = type;
+    ret->name = name;
+    ret->targetNamespace = nsName;
+    ret->node = node;
+    if (topLevel) {
+	if (ctxt->isRedefine) {
+	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
+		ret, name, nsName);
+	    if (ctxt->redef == NULL) {
+		xmlFree(ret);
+		return(NULL);
+	    }
+	    ctxt->redefCounter = 0;
+	}
+	WXS_ADD_GLOBAL(ctxt, ret);
+    } else
+	WXS_ADD_LOCAL(ctxt, ret);
+    WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+static xmlSchemaQNameRefPtr
+xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
+		     xmlSchemaTypeType refType,
+		     const xmlChar *refName,
+		     const xmlChar *refNs)
+{
+    xmlSchemaQNameRefPtr ret;
+
+    ret = (xmlSchemaQNameRefPtr)
+	xmlMalloc(sizeof(xmlSchemaQNameRef));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(pctxt,
+	    "allocating QName reference item", NULL);
+	return (NULL);
+    }
+    ret->node = NULL;
+    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
+    ret->name = refName;
+    ret->targetNamespace = refNs;
+    ret->item = NULL;
+    ret->itemType = refType;
+    /*
+    * Store the reference item in the schema.
+    */
+    WXS_ADD_LOCAL(pctxt, ret);
+    return (ret);
+}
+
+static xmlSchemaAttributeUseProhibPtr
+xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
+{
+    xmlSchemaAttributeUseProhibPtr ret;
+
+    ret = (xmlSchemaAttributeUseProhibPtr)
+	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(pctxt,
+	    "allocating attribute use prohibition", NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
+    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
+    WXS_ADD_LOCAL(pctxt, ret);
+    return (ret);
+}
+
+
+/**
+ * xmlSchemaAddModelGroup:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @type: the "compositor" type of the model group
+ * @node: the node in the schema doc
+ *
+ * Adds a schema model group
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaModelGroupPtr
+xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
+		       xmlSchemaPtr schema,
+		       xmlSchemaTypeType type,
+		       xmlNodePtr node)
+{
+    xmlSchemaModelGroupPtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaModelGroupPtr)
+	xmlMalloc(sizeof(xmlSchemaModelGroup));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(ctxt, "allocating model group component",
+	    NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaModelGroup));
+    ret->type = type;
+    ret->node = node;
+    WXS_ADD_LOCAL(ctxt, ret);
+    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
+	(type == XML_SCHEMA_TYPE_CHOICE))
+	WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+
+/**
+ * xmlSchemaAddParticle:
+ * @ctxt:  a schema parser context
+ * @schema:  the schema being built
+ * @node: the corresponding node in the schema doc
+ * @min: the minOccurs
+ * @max: the maxOccurs
+ *
+ * Adds an XML schema particle component.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaParticlePtr
+xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
+		     xmlNodePtr node, int min, int max)
+{
+    xmlSchemaParticlePtr ret = NULL;
+    if (ctxt == NULL)
+        return (NULL);
+
+#ifdef DEBUG
+    fprintf(stderr, "Adding particle component\n");
+#endif
+    ret = (xmlSchemaParticlePtr)
+	xmlMalloc(sizeof(xmlSchemaParticle));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(ctxt, "allocating particle component",
+	    NULL);
+	return (NULL);
+    }
+    ret->type = XML_SCHEMA_TYPE_PARTICLE;
+    ret->annot = NULL;
+    ret->node = node;
+    ret->minOccurs = min;
+    ret->maxOccurs = max;
+    ret->next = NULL;
+    ret->children = NULL;
+
+    WXS_ADD_LOCAL(ctxt, ret);
+    /*
+    * Note that addition to pending components will be done locally
+    * to the specific parsing function, since the most particles
+    * need not to be fixed up (i.e. the reference to be resolved).
+    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
+    */
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddModelGroupDefinition:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @name:  the group name
+ *
+ * Add an XML schema Group definition
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaModelGroupDefPtr
+xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
+				 xmlSchemaPtr schema,
+				 const xmlChar *name,
+				 const xmlChar *nsName,
+				 xmlNodePtr node)
+{
+    xmlSchemaModelGroupDefPtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaModelGroupDefPtr)
+	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
+    ret->name = name;
+    ret->type = XML_SCHEMA_TYPE_GROUP;
+    ret->node = node;
+    ret->targetNamespace = nsName;
+
+    if (ctxt->isRedefine) {
+	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
+	    ret, name, nsName);
+	if (ctxt->redef == NULL) {
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	ctxt->redefCounter = 0;
+    }
+    WXS_ADD_GLOBAL(ctxt, ret);
+    WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaNewWildcardNs:
+ * @ctxt:  a schema validation context
+ *
+ * Creates a new wildcard namespace constraint.
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaWildcardNsPtr
+xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
+{
+    xmlSchemaWildcardNsPtr ret;
+
+    ret = (xmlSchemaWildcardNsPtr)
+	xmlMalloc(sizeof(xmlSchemaWildcardNs));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
+	return (NULL);
+    }
+    ret->value = NULL;
+    ret->next = NULL;
+    return (ret);
+}
+
+static xmlSchemaIDCPtr
+xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                  const xmlChar *name, const xmlChar *nsName,
+		  int category, xmlNodePtr node)
+{
+    xmlSchemaIDCPtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt,
+	    "allocating an identity-constraint definition", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaIDC));
+    /* The target namespace of the parent element declaration. */
+    ret->targetNamespace = nsName;
+    ret->name = name;
+    ret->type = category;
+    ret->node = node;
+
+    WXS_ADD_GLOBAL(ctxt, ret);
+    /*
+    * Only keyrefs need to be fixup up.
+    */
+    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
+	WXS_ADD_PENDING(ctxt, ret);
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddWildcard:
+ * @ctxt:  a schema validation context
+ * @schema: a schema
+ *
+ * Adds a wildcard.
+ * It corresponds to a xsd:anyAttribute and xsd:any.
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaWildcardPtr
+xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+		     xmlSchemaTypeType type, xmlNodePtr node)
+{
+    xmlSchemaWildcardPtr ret = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL))
+        return (NULL);
+
+    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaWildcard));
+    ret->type = type;
+    ret->node = node;
+    WXS_ADD_LOCAL(ctxt, ret);
+    return (ret);
+}
+
+static void
+xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
+{
+    if (group == NULL)
+	return;
+    if (group->members != NULL)
+	xmlSchemaItemListFree(group->members);
+    xmlFree(group);
+}
+
+static xmlSchemaSubstGroupPtr
+xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
+		       xmlSchemaElementPtr head)
+{
+    xmlSchemaSubstGroupPtr ret;
+
+    /* Init subst group hash. */
+    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
+	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
+	if (WXS_SUBST_GROUPS(pctxt) == NULL)
+	    return(NULL);
+    }
+    /* Create a new substitution group. */
+    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(NULL,
+	    "allocating a substitution group container", NULL);
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
+    ret->head = head;
+    /* Create list of members. */
+    ret->members = xmlSchemaItemListCreate();
+    if (ret->members == NULL) {
+	xmlSchemaSubstGroupFree(ret);
+	return(NULL);
+    }
+    /* Add subst group to hash. */
+    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
+	head->name, head->targetNamespace, ret) != 0) {
+	PERROR_INT("xmlSchemaSubstGroupAdd",
+	    "failed to add a new substitution container");
+	xmlSchemaSubstGroupFree(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+static xmlSchemaSubstGroupPtr
+xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
+		       xmlSchemaElementPtr head)
+{
+    if (WXS_SUBST_GROUPS(pctxt) == NULL)
+	return(NULL);
+    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
+	head->name, head->targetNamespace));
+
+}
+
+/**
+ * xmlSchemaAddElementSubstitutionMember:
+ * @pctxt:  a schema parser context
+ * @head:  the head of the substitution group
+ * @member: the new member of the substitution group
+ *
+ * Allocate a new annotation structure.
+ *
+ * Returns the newly allocated structure or NULL in case or error
+ */
+static int
+xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
+				      xmlSchemaElementPtr head,
+				      xmlSchemaElementPtr member)
+{
+    xmlSchemaSubstGroupPtr substGroup = NULL;
+
+    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
+	return (-1);
+
+    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
+    if (substGroup == NULL)
+	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
+    if (substGroup == NULL)
+	return(-1);
+    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
+	return(-1);
+    return(0);
+}
+
+/************************************************************************
+ * 									*
+ *		Utilities for parsing					*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaPValAttrNodeQNameValue:
+ * @ctxt:  a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the parent as a schema object
+ * @value:  the QName value
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri:  the resulting namespace URI if found
+ *
+ * Extracts the local name and the URI of a QName value and validates it.
+ * This one is intended to be used on attribute values that
+ * should resolve to schema components.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
+				       xmlSchemaPtr schema,
+				       xmlSchemaBasicItemPtr ownerItem,
+				       xmlAttrPtr attr,
+				       const xmlChar *value,
+				       const xmlChar **uri,
+				       const xmlChar **local)
+{
+    const xmlChar *pref;
+    xmlNsPtr ns;
+    int len, ret;
+
+    *uri = NULL;
+    *local = NULL;
+    ret = xmlValidateQName(value, 1);
+    if (ret > 0) {
+	xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    ownerItem, (xmlNodePtr) attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
+	    NULL, value, NULL, NULL, NULL);
+	*local = value;
+	return (ctxt->err);
+    } else if (ret < 0)
+	return (-1);
+
+    if (!strchr((char *) value, ':')) {
+	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
+	if (ns)
+	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
+	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
+	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
+	    * parser context. */
+	    /*
+	    * This one takes care of included schemas with no
+	    * target namespace.
+	    */
+	    *uri = ctxt->targetNamespace;
+	}
+	*local = xmlDictLookup(ctxt->dict, value, -1);
+	return (0);
+    }
+    /*
+    * At this point xmlSplitQName3 has to return a local name.
+    */
+    *local = xmlSplitQName3(value, &len);
+    *local = xmlDictLookup(ctxt->dict, *local, -1);
+    pref = xmlDictLookup(ctxt->dict, value, len);
+    ns = xmlSearchNs(attr->doc, attr->parent, pref);
+    if (ns == NULL) {
+	xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    ownerItem, (xmlNodePtr) attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
+	    "The value '%s' of simple type 'xs:QName' has no "
+	    "corresponding namespace declaration in scope", value, NULL);
+	return (ctxt->err);
+    } else {
+        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaPValAttrNodeQName:
+ * @ctxt:  a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the owner element
+ * @ownerItem: the owner as a schema object
+ * @attr:  the attribute node
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri:  the resulting namespace URI if found
+ *
+ * Extracts and validates the QName of an attribute value.
+ * This one is intended to be used on attribute values that
+ * should resolve to schema components.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
+				       xmlSchemaPtr schema,
+				       xmlSchemaBasicItemPtr ownerItem,
+				       xmlAttrPtr attr,
+				       const xmlChar **uri,
+				       const xmlChar **local)
+{
+    const xmlChar *value;
+
+    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
+	ownerItem, attr, value, uri, local));
+}
+
+/**
+ * xmlSchemaPValAttrQName:
+ * @ctxt:  a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the owner as a schema object
+ * @ownerElem:  the parent node of the attribute
+ * @name:  the name of the attribute
+ * @local: the resulting local part if found, the attribute value otherwise
+ * @uri:  the resulting namespace URI if found
+ *
+ * Extracts and validates the QName of an attribute value.
+ *
+ * Returns 0, in case the QName is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
+				   xmlSchemaPtr schema,
+				   xmlSchemaBasicItemPtr ownerItem,
+				   xmlNodePtr ownerElem,
+				   const char *name,
+				   const xmlChar **uri,
+				   const xmlChar **local)
+{
+    xmlAttrPtr attr;
+
+    attr = xmlSchemaGetPropNode(ownerElem, name);
+    if (attr == NULL) {
+	*local = NULL;
+	*uri = NULL;
+	return (0);
+    }
+    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
+	ownerItem, attr, uri, local));
+}
+
+/**
+ * xmlSchemaPValAttrID:
+ * @ctxt:  a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the owner as a schema object
+ * @ownerElem:  the parent node of the attribute
+ * @name:  the name of the attribute
+ *
+ * Extracts and validates the ID of an attribute value.
+ *
+ * Returns 0, in case the ID is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
+{
+    int ret;
+    const xmlChar *value;
+
+    if (attr == NULL)
+	return(0);
+    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
+    ret = xmlValidateNCName(value, 1);
+    if (ret == 0) {
+	/*
+	* NOTE: the IDness might have already be declared in the DTD
+	*/
+	if (attr->atype != XML_ATTRIBUTE_ID) {
+	    xmlIDPtr res;
+	    xmlChar *strip;
+
+	    /*
+	    * TODO: Use xmlSchemaStrip here; it's not exported at this
+	    * moment.
+	    */
+	    strip = xmlSchemaCollapseString(value);
+	    if (strip != NULL) {
+		xmlFree((xmlChar *) value);
+		value = strip;
+	    }
+    	    res = xmlAddID(NULL, attr->doc, value, attr);
+	    if (res == NULL) {
+		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+		xmlSchemaPSimpleTypeErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		    NULL, (xmlNodePtr) attr,
+		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
+		    NULL, NULL, "Duplicate value '%s' of simple "
+		    "type 'xs:ID'", value, NULL);
+	    } else
+		attr->atype = XML_ATTRIBUTE_ID;
+	}
+    } else if (ret > 0) {
+	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+	xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    NULL, (xmlNodePtr) attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
+	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
+	    "not a valid 'xs:NCName'",
+	    value, NULL);
+    }
+    if (value != NULL)
+	xmlFree((xmlChar *)value);
+
+    return (ret);
+}
+
+static int
+xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
+		    xmlNodePtr ownerElem,
+		    const xmlChar *name)
+{
+    xmlAttrPtr attr;
+
+    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
+    if (attr == NULL)
+	return(0);
+    return(xmlSchemaPValAttrNodeID(ctxt, attr));
+
+}
+
+/**
+ * xmlGetMaxOccurs:
+ * @ctxt:  a schema validation context
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Get the maxOccurs property
+ *
+ * Returns the default if not found, or the value
+ */
+static int
+xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+		int min, int max, int def, const char *expected)
+{
+    const xmlChar *val, *cur;
+    int ret = 0;
+    xmlAttrPtr attr;
+
+    attr = xmlSchemaGetPropNode(node, "maxOccurs");
+    if (attr == NULL)
+	return (def);
+    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+
+    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
+	if (max != UNBOUNDED) {
+	    xmlSchemaPSimpleTypeErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		/* XML_SCHEMAP_INVALID_MINOCCURS, */
+		NULL, (xmlNodePtr) attr, NULL, expected,
+		val, NULL, NULL, NULL);
+	    return (def);
+	} else
+	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
+    }
+
+    cur = val;
+    while (IS_BLANK_CH(*cur))
+        cur++;
+    if (*cur == 0) {
+        xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
+	    NULL, (xmlNodePtr) attr, NULL, expected,
+	    val, NULL, NULL, NULL);
+	return (def);
+    }
+    while ((*cur >= '0') && (*cur <= '9')) {
+        ret = ret * 10 + (*cur - '0');
+        cur++;
+    }
+    while (IS_BLANK_CH(*cur))
+        cur++;
+    /*
+    * TODO: Restrict the maximal value to Integer.
+    */
+    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
+	xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
+	    NULL, (xmlNodePtr) attr, NULL, expected,
+	    val, NULL, NULL, NULL);
+        return (def);
+    }
+    return (ret);
+}
+
+/**
+ * xmlGetMinOccurs:
+ * @ctxt:  a schema validation context
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Get the minOccurs property
+ *
+ * Returns the default if not found, or the value
+ */
+static int
+xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+		int min, int max, int def, const char *expected)
+{
+    const xmlChar *val, *cur;
+    int ret = 0;
+    xmlAttrPtr attr;
+
+    attr = xmlSchemaGetPropNode(node, "minOccurs");
+    if (attr == NULL)
+	return (def);
+    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+    cur = val;
+    while (IS_BLANK_CH(*cur))
+        cur++;
+    if (*cur == 0) {
+        xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
+	    NULL, (xmlNodePtr) attr, NULL, expected,
+	    val, NULL, NULL, NULL);
+        return (def);
+    }
+    while ((*cur >= '0') && (*cur <= '9')) {
+        ret = ret * 10 + (*cur - '0');
+        cur++;
+    }
+    while (IS_BLANK_CH(*cur))
+        cur++;
+    /*
+    * TODO: Restrict the maximal value to Integer.
+    */
+    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
+	xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
+	    NULL, (xmlNodePtr) attr, NULL, expected,
+	    val, NULL, NULL, NULL);
+        return (def);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchemaPGetBoolNodeValue:
+ * @ctxt:  a schema validation context
+ * @ownerDes:  owner designation
+ * @ownerItem:  the owner as a schema item
+ * @node: the node holding the value
+ *
+ * Converts a boolean string value into 1 or 0.
+ *
+ * Returns 0 or 1.
+ */
+static int
+xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
+			   xmlSchemaBasicItemPtr ownerItem,
+			   xmlNodePtr node)
+{
+    xmlChar *value = NULL;
+    int res = 0;
+
+    value = xmlNodeGetContent(node);
+    /*
+    * 3.2.2.1 Lexical representation
+    * An instance of a datatype that is defined as �boolean�
+    * can have the following legal literals {true, false, 1, 0}.
+    */
+    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
+        res = 1;
+    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
+        res = 0;
+    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
+	res = 1;
+    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
+        res = 0;
+    else {
+        xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_INVALID_BOOLEAN,
+	    ownerItem, node,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
+	    NULL, BAD_CAST value,
+	    NULL, NULL, NULL);
+    }
+    if (value != NULL)
+	xmlFree(value);
+    return (res);
+}
+
+/**
+ * xmlGetBooleanProp:
+ * @ctxt:  a schema validation context
+ * @node:  a subtree containing XML Schema informations
+ * @name:  the attribute name
+ * @def:  the default value
+ *
+ * Evaluate if a boolean property is set
+ *
+ * Returns the default if not found, 0 if found to be false,
+ * 1 if found to be true
+ */
+static int
+xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
+		  xmlNodePtr node,
+                  const char *name, int def)
+{
+    const xmlChar *val;
+
+    val = xmlSchemaGetProp(ctxt, node, name);
+    if (val == NULL)
+        return (def);
+    /*
+    * 3.2.2.1 Lexical representation
+    * An instance of a datatype that is defined as �boolean�
+    * can have the following legal literals {true, false, 1, 0}.
+    */
+    if (xmlStrEqual(val, BAD_CAST "true"))
+        def = 1;
+    else if (xmlStrEqual(val, BAD_CAST "false"))
+        def = 0;
+    else if (xmlStrEqual(val, BAD_CAST "1"))
+	def = 1;
+    else if (xmlStrEqual(val, BAD_CAST "0"))
+        def = 0;
+    else {
+        xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_INVALID_BOOLEAN,
+	    NULL,
+	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
+	    NULL, val, NULL, NULL, NULL);
+    }
+    return (def);
+}
+
+/************************************************************************
+ * 									*
+ *		Shema extraction from an Infoset			*
+ * 									*
+ ************************************************************************/
+static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
+                                                 ctxt, xmlSchemaPtr schema,
+                                                 xmlNodePtr node,
+						 int topLevel);
+static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
+                                                  ctxt,
+                                                  xmlSchemaPtr schema,
+                                                  xmlNodePtr node,
+						  int topLevel);
+static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
+                                                  ctxt,
+                                                  xmlSchemaPtr schema,
+                                                  xmlNodePtr node,
+						  xmlSchemaTypeType parentType);
+static xmlSchemaBasicItemPtr
+xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
+			     xmlSchemaPtr schema,
+			     xmlNodePtr node,
+			     xmlSchemaItemListPtr uses,
+			     int parentType);
+static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
+                                           xmlSchemaPtr schema,
+                                           xmlNodePtr node);
+static xmlSchemaWildcardPtr
+xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
+                           xmlSchemaPtr schema, xmlNodePtr node);
+
+/**
+ * xmlSchemaPValAttrNodeValue:
+ *
+ * @ctxt:  a schema parser context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @attr:  the schema attribute node being validated
+ * @value: the value
+ * @type: the built-in type to be validated against
+ *
+ * Validates a value against the given built-in type.
+ * This one is intended to be used internally for validation
+ * of schema attribute values during parsing of the schema.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
+			   xmlSchemaBasicItemPtr ownerItem,
+			   xmlAttrPtr attr,
+			   const xmlChar *value,
+			   xmlSchemaTypePtr type)
+{
+
+    int ret = 0;
+
+    /*
+    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
+    * one is really meant to be used internally, so better not.
+    */
+    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
+	return (-1);
+    if (type->type != XML_SCHEMA_TYPE_BASIC) {
+	PERROR_INT("xmlSchemaPValAttrNodeValue",
+	    "the given type is not a built-in type");
+	return (-1);
+    }
+    switch (type->builtInType) {
+	case XML_SCHEMAS_NCNAME:
+	case XML_SCHEMAS_QNAME:
+	case XML_SCHEMAS_ANYURI:
+	case XML_SCHEMAS_TOKEN:
+	case XML_SCHEMAS_LANGUAGE:
+	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
+		(xmlNodePtr) attr);
+	    break;
+	default: {
+	    PERROR_INT("xmlSchemaPValAttrNodeValue",
+		"validation using the given type is not supported while "
+		"parsing a schema");
+	    return (-1);
+	}
+    }
+    /*
+    * TODO: Should we use the S4S error codes instead?
+    */
+    if (ret < 0) {
+	PERROR_INT("xmlSchemaPValAttrNodeValue",
+	    "failed to validate a schema attribute value");
+	return (-1);
+    } else if (ret > 0) {
+	if (WXS_IS_LIST(type))
+	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
+	else
+	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
+	xmlSchemaPSimpleTypeErr(pctxt,
+	    ret, ownerItem, (xmlNodePtr) attr,
+	    type, NULL, value, NULL, NULL, NULL);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchemaPValAttrNode:
+ *
+ * @ctxt:  a schema parser context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @attr:  the schema attribute node being validated
+ * @type: the built-in type to be validated against
+ * @value: the resulting value if any
+ *
+ * Extracts and validates a value against the given built-in type.
+ * This one is intended to be used internally for validation
+ * of schema attribute values during parsing of the schema.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
+			   xmlSchemaBasicItemPtr ownerItem,
+			   xmlAttrPtr attr,
+			   xmlSchemaTypePtr type,
+			   const xmlChar **value)
+{
+    const xmlChar *val;
+
+    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
+	return (-1);
+
+    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+    if (value != NULL)
+	*value = val;
+
+    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
+	val, type));
+}
+
+/**
+ * xmlSchemaPValAttr:
+ *
+ * @ctxt:  a schema parser context
+ * @node: the element node of the attribute
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the schema object owner if existent
+ * @ownerElem: the owner element node
+ * @name:  the name of the schema attribute node
+ * @type: the built-in type to be validated against
+ * @value: the resulting value if any
+ *
+ * Extracts and validates a value against the given built-in type.
+ * This one is intended to be used internally for validation
+ * of schema attribute values during parsing of the schema.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
+		       xmlSchemaBasicItemPtr ownerItem,
+		       xmlNodePtr ownerElem,
+		       const char *name,
+		       xmlSchemaTypePtr type,
+		       const xmlChar **value)
+{
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (type == NULL)) {
+	if (value != NULL)
+	    *value = NULL;
+	return (-1);
+    }
+    if (type->type != XML_SCHEMA_TYPE_BASIC) {
+	if (value != NULL)
+	    *value = NULL;
+	xmlSchemaPErr(ctxt, ownerElem,
+	    XML_SCHEMAP_INTERNAL,
+	    "Internal error: xmlSchemaPValAttr, the given "
+	    "type '%s' is not a built-in type.\n",
+	    type->name, NULL);
+	return (-1);
+    }
+    attr = xmlSchemaGetPropNode(ownerElem, name);
+    if (attr == NULL) {
+	if (value != NULL)
+	    *value = NULL;
+	return (0);
+    }
+    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
+	type, value));
+}
+
+static int
+xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
+		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
+		  xmlNodePtr node,
+		  xmlAttrPtr attr,
+		  const xmlChar *namespaceName)
+{
+    /* TODO: Pointer comparison instead? */
+    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
+	return (0);
+    if (xmlStrEqual(xmlSchemaNs, namespaceName))
+	return (0);
+    /*
+    * Check if the referenced namespace was <import>ed.
+    */
+    if (WXS_BUCKET(pctxt)->relations != NULL) {
+	xmlSchemaSchemaRelationPtr rel;
+
+	rel = WXS_BUCKET(pctxt)->relations;
+	do {
+	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
+		xmlStrEqual(namespaceName, rel->importNamespace))
+		return (0);
+	    rel = rel->next;
+	} while (rel != NULL);
+    }
+    /*
+    * No matching <import>ed namespace found.
+    */
+    {
+	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
+
+	if (namespaceName == NULL)
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
+		"References from this schema to components in no "
+		"namespace are not allowed, since not indicated by an "
+		"import statement", NULL, NULL);
+	else
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
+		"References from this schema to components in the "
+		"namespace '%s' are not allowed, since not indicated by an "
+		"import statement", namespaceName, NULL);
+    }
+    return (XML_SCHEMAP_SRC_RESOLVE);
+}
+
+/**
+ * xmlSchemaParseLocalAttributes:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ * @type:  the hosting type where the attributes will be anchored
+ *
+ * Parses attribute uses and attribute declarations and
+ * attribute group references.
+ */
+static int
+xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
+			int parentType, int *hasRefs)
+{
+    void *item;
+
+    while ((IS_SCHEMA((*child), "attribute")) ||
+           (IS_SCHEMA((*child), "attributeGroup"))) {
+        if (IS_SCHEMA((*child), "attribute")) {
+	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
+		*list, parentType);
+        } else {
+            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
+	    if ((item != NULL) && (hasRefs != NULL))
+		*hasRefs = 1;
+        }
+	if (item != NULL) {
+	    if (*list == NULL) {
+		/* TODO: Customize grow factor. */
+		*list = xmlSchemaItemListCreate();
+		if (*list == NULL)
+		    return(-1);
+	    }
+	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
+		return(-1);
+	}
+        *child = (*child)->next;
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaParseAnnotation:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Attrribute declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error, 0 if the declaration is improper and
+ *         1 in case of success.
+ */
+static xmlSchemaAnnotPtr
+xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
+{
+    xmlSchemaAnnotPtr ret;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    int barked = 0;
+
+    /*
+    * INFO: S4S completed.
+    */
+    /*
+    * id = ID
+    * {any attributes with non-schema namespace . . .}>
+    * Content: (appinfo | documentation)*
+    */
+    if ((ctxt == NULL) || (node == NULL))
+        return (NULL);
+    if (needed)
+	ret = xmlSchemaNewAnnot(ctxt, node);
+    else
+	ret = NULL;
+    attr = node->properties;
+    while (attr != NULL) {
+	if (((attr->ns == NULL) &&
+	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
+	    ((attr->ns != NULL) &&
+	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
+
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    while (child != NULL) {
+	if (IS_SCHEMA(child, "appinfo")) {
+	    /* TODO: make available the content of "appinfo". */
+	    /*
+	    * source = anyURI
+	    * {any attributes with non-schema namespace . . .}>
+	    * Content: ({any})*
+	    */
+	    attr = child->properties;
+	    while (attr != NULL) {
+		if (((attr->ns == NULL) &&
+		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
+		     ((attr->ns != NULL) &&
+		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
+
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+		attr = attr->next;
+	    }
+	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
+		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "documentation")) {
+	    /* TODO: make available the content of "documentation". */
+	    /*
+	    * source = anyURI
+	    * {any attributes with non-schema namespace . . .}>
+	    * Content: ({any})*
+	    */
+	    attr = child->properties;
+	    while (attr != NULL) {
+		if (attr->ns == NULL) {
+		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
+			xmlSchemaPIllegalAttrErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		    }
+		} else {
+		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
+			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
+			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
+
+			xmlSchemaPIllegalAttrErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		    }
+		}
+		attr = attr->next;
+	    }
+	    /*
+	    * Attribute "xml:lang".
+	    */
+	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
+	    if (attr != NULL)
+		xmlSchemaPValAttrNode(ctxt, NULL, attr,
+		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
+	    child = child->next;
+	} else {
+	    if (!barked)
+		xmlSchemaPContentErr(ctxt,
+		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		    NULL, node, child, NULL, "(appinfo | documentation)*");
+	    barked = 1;
+	    child = child->next;
+	}
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaParseFacet:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Facet declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the new type structure or NULL in case of error
+ */
+static xmlSchemaFacetPtr
+xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                    xmlNodePtr node)
+{
+    xmlSchemaFacetPtr facet;
+    xmlNodePtr child = NULL;
+    const xmlChar *value;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    facet = xmlSchemaNewFacet();
+    if (facet == NULL) {
+        xmlSchemaPErrMemory(ctxt, "allocating facet", node);
+        return (NULL);
+    }
+    facet->node = node;
+    value = xmlSchemaGetProp(ctxt, node, "value");
+    if (value == NULL) {
+        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
+                       "Facet %s has no value\n", node->name, NULL);
+        xmlSchemaFreeFacet(facet);
+        return (NULL);
+    }
+    if (IS_SCHEMA(node, "minInclusive")) {
+        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
+    } else if (IS_SCHEMA(node, "minExclusive")) {
+        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
+    } else if (IS_SCHEMA(node, "maxInclusive")) {
+        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
+    } else if (IS_SCHEMA(node, "maxExclusive")) {
+        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
+    } else if (IS_SCHEMA(node, "totalDigits")) {
+        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
+    } else if (IS_SCHEMA(node, "fractionDigits")) {
+        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
+    } else if (IS_SCHEMA(node, "pattern")) {
+        facet->type = XML_SCHEMA_FACET_PATTERN;
+    } else if (IS_SCHEMA(node, "enumeration")) {
+        facet->type = XML_SCHEMA_FACET_ENUMERATION;
+    } else if (IS_SCHEMA(node, "whiteSpace")) {
+        facet->type = XML_SCHEMA_FACET_WHITESPACE;
+    } else if (IS_SCHEMA(node, "length")) {
+        facet->type = XML_SCHEMA_FACET_LENGTH;
+    } else if (IS_SCHEMA(node, "maxLength")) {
+        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
+    } else if (IS_SCHEMA(node, "minLength")) {
+        facet->type = XML_SCHEMA_FACET_MINLENGTH;
+    } else {
+        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
+                       "Unknown facet type %s\n", node->name, NULL);
+        xmlSchemaFreeFacet(facet);
+        return (NULL);
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    facet->value = value;
+    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
+	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
+	const xmlChar *fixed;
+
+	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
+	if (fixed != NULL) {
+	    if (xmlStrEqual(fixed, BAD_CAST "true"))
+		facet->fixed = 1;
+	}
+    }
+    child = node->children;
+
+    if (IS_SCHEMA(child, "annotation")) {
+        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (child != NULL) {
+        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
+                       "Facet %s has unexpected child content\n",
+                       node->name, NULL);
+    }
+    return (facet);
+}
+
+/**
+ * xmlSchemaParseWildcardNs:
+ * @ctxt:  a schema parser context
+ * @wildc:  the wildcard, already created
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parses the attribute "processContents" and "namespace"
+ * of a xsd:anyAttribute and xsd:any.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns 0 if everything goes fine, a positive error code
+ * if something is not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
+			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
+			 xmlSchemaWildcardPtr wildc,
+			 xmlNodePtr node)
+{
+    const xmlChar *pc, *ns, *dictnsItem;
+    int ret = 0;
+    xmlChar *nsItem;
+    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
+    xmlAttrPtr attr;
+
+    pc = xmlSchemaGetProp(ctxt, node, "processContents");
+    if ((pc == NULL)
+        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
+        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
+    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
+        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
+    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
+        wildc->processContents = XML_SCHEMAS_ANY_LAX;
+    } else {
+        xmlSchemaPSimpleTypeErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    NULL, node,
+	    NULL, "(strict | skip | lax)", pc,
+	    NULL, NULL, NULL);
+        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
+	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+    }
+    /*
+     * Build the namespace constraints.
+     */
+    attr = xmlSchemaGetPropNode(node, "namespace");
+    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
+	wildc->any = 1;
+    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
+	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+	if (wildc->negNsSet == NULL) {
+	    return (-1);
+	}
+	wildc->negNsSet->value = ctxt->targetNamespace;
+    } else {
+	const xmlChar *end, *cur;
+
+	cur = ns;
+	do {
+	    while (IS_BLANK_CH(*cur))
+		cur++;
+	    end = cur;
+	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+		end++;
+	    if (end == cur)
+		break;
+	    nsItem = xmlStrndup(cur, end - cur);
+	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
+		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
+		xmlSchemaPSimpleTypeErr(ctxt,
+		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
+		    NULL, (xmlNodePtr) attr,
+		    NULL,
+		    "((##any | ##other) | List of (xs:anyURI | "
+		    "(##targetNamespace | ##local)))",
+		    nsItem, NULL, NULL, NULL);
+		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
+	    } else {
+		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
+		    dictnsItem = ctxt->targetNamespace;
+		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
+		    dictnsItem = NULL;
+		} else {
+		    /*
+		    * Validate the item (anyURI).
+		    */
+		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
+			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
+		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
+		}
+		/*
+		* Avoid dublicate namespaces.
+		*/
+		tmp = wildc->nsSet;
+		while (tmp != NULL) {
+		    if (dictnsItem == tmp->value)
+			break;
+		    tmp = tmp->next;
+		}
+		if (tmp == NULL) {
+		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
+		    if (tmp == NULL) {
+			xmlFree(nsItem);
+			return (-1);
+		    }
+		    tmp->value = dictnsItem;
+		    tmp->next = NULL;
+		    if (wildc->nsSet == NULL)
+			wildc->nsSet = tmp;
+		    else if (lastNs != NULL)
+			lastNs->next = tmp;
+		    lastNs = tmp;
+		}
+
+	    }
+	    xmlFree(nsItem);
+	    cur = end;
+	} while (*cur != 0);
+    }
+    return (ret);
+}
+
+static int
+xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
+				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
+				 xmlNodePtr node,
+				 int minOccurs,
+				 int maxOccurs) {
+
+    if ((maxOccurs == 0) && ( minOccurs == 0))
+	return (0);
+    if (maxOccurs != UNBOUNDED) {
+	/*
+	* TODO: Maybe we should better not create the particle,
+	* if min/max is invalid, since it could confuse the build of the
+	* content model.
+	*/
+	/*
+	* 3.9.6 Schema Component Constraint: Particle Correct
+	*
+	*/
+	if (maxOccurs < 1) {
+	    /*
+	    * 2.2 {max occurs} must be greater than or equal to 1.
+	    */
+	    xmlSchemaPCustomAttrErr(ctxt,
+		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
+		NULL, NULL,
+		xmlSchemaGetPropNode(node, "maxOccurs"),
+		"The value must be greater than or equal to 1");
+	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
+	} else if (minOccurs > maxOccurs) {
+	    /*
+	    * 2.1 {min occurs} must not be greater than {max occurs}.
+	    */
+	    xmlSchemaPCustomAttrErr(ctxt,
+		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
+		NULL, NULL,
+		xmlSchemaGetPropNode(node, "minOccurs"),
+		"The value must not be greater than the value of 'maxOccurs'");
+	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
+	}
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaParseAny:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parsea a XML schema <any> element. A particle and wildcard
+ * will be created (except if minOccurs==maxOccurs==0, in this case
+ * nothing will be created).
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
+ */
+static xmlSchemaParticlePtr
+xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                  xmlNodePtr node)
+{
+    xmlSchemaParticlePtr particle;
+    xmlNodePtr child = NULL;
+    xmlSchemaWildcardPtr wild;
+    int min, max;
+    xmlAttrPtr attr;
+    xmlSchemaAnnotPtr annot = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * minOccurs/maxOccurs.
+    */
+    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+	"(xs:nonNegativeInteger | unbounded)");
+    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
+	"xs:nonNegativeInteger");
+    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
+    /*
+    * Create & parse the wildcard.
+    */
+    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
+    if (wild == NULL)
+	return (NULL);
+    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?)");
+    }
+    /*
+    * No component if minOccurs==maxOccurs==0.
+    */
+    if ((min == 0) && (max == 0)) {
+	/* Don't free the wildcard, since it's already on the list. */
+	return (NULL);
+    }
+    /*
+    * Create the particle.
+    */
+    particle = xmlSchemaAddParticle(ctxt, node, min, max);
+    if (particle == NULL)
+        return (NULL);
+    particle->annot = annot;
+    particle->children = (xmlSchemaTreeItemPtr) wild;
+
+    return (particle);
+}
+
+/**
+ * xmlSchemaParseNotation:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Notation declaration
+ *
+ * Returns the new structure or NULL in case of error
+ */
+static xmlSchemaNotationPtr
+xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                       xmlNodePtr node)
+{
+    const xmlChar *name;
+    xmlSchemaNotationPtr ret;
+    xmlNodePtr child = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    name = xmlSchemaGetProp(ctxt, node, "name");
+    if (name == NULL) {
+        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
+                       "Notation has no name\n", NULL, NULL);
+        return (NULL);
+    }
+    ret = xmlSchemaAddNotation(ctxt, schema, name,
+	ctxt->targetNamespace, node);
+    if (ret == NULL)
+        return (NULL);
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?)");
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaParseAnyAttribute:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema AnyAttrribute declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns a wildcard or NULL.
+ */
+static xmlSchemaWildcardPtr
+xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
+                           xmlSchemaPtr schema, xmlNodePtr node)
+{
+    xmlSchemaWildcardPtr ret;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+	node);
+    if (ret == NULL) {
+        return (NULL);
+    }
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * Parse the namespace list.
+    */
+    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
+	return (NULL);
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?)");
+    }
+
+    return (ret);
+}
+
+
+/**
+ * xmlSchemaParseAttribute:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Attrribute declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the attribute declaration.
+ */
+static xmlSchemaBasicItemPtr
+xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
+			     xmlSchemaPtr schema,
+			     xmlNodePtr node,
+			     xmlSchemaItemListPtr uses,
+			     int parentType)
+{
+    const xmlChar *attrValue, *name = NULL, *ns = NULL;
+    xmlSchemaAttributeUsePtr use = NULL;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
+    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
+    int	nberrors, hasForm = 0, defValueType = 0;
+
+#define WXS_ATTR_DEF_VAL_DEFAULT 1
+#define WXS_ATTR_DEF_VAL_FIXED 2
+
+    /*
+     * 3.2.3 Constraints on XML Representations of Attribute Declarations
+     */
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    attr = xmlSchemaGetPropNode(node, "ref");
+    if (attr != NULL) {
+	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
+	    NULL, attr, &tmpNs, &tmpName) != 0) {
+	    return (NULL);
+	}
+	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
+	    return(NULL);
+	isRef = 1;
+    }
+    nberrors = pctxt->nberrors;
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if (isRef) {
+		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
+		    xmlSchemaPValAttrNodeID(pctxt, attr);
+		    goto attr_next;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
+		    goto attr_next;
+		}
+	    } else {
+		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
+		    goto attr_next;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
+		    xmlSchemaPValAttrNodeID(pctxt, attr);
+		    goto attr_next;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
+		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
+			attr, &tmpNs, &tmpName);
+		    goto attr_next;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
+		    /*
+		    * Evaluate the target namespace
+		    */
+		    hasForm = 1;
+		    attrValue = xmlSchemaGetNodeContent(pctxt,
+			(xmlNodePtr) attr);
+		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
+			ns = pctxt->targetNamespace;
+		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
+		    {
+			xmlSchemaPSimpleTypeErr(pctxt,
+			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+			    NULL, (xmlNodePtr) attr,
+			    NULL, "(qualified | unqualified)",
+			    attrValue, NULL, NULL, NULL);
+		    }
+		    goto attr_next;
+		}
+	    }
+	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
+
+		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
+		/* TODO: Maybe we need to normalize the value beforehand. */
+		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
+		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
+		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
+		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
+		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
+		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
+		else {
+		    xmlSchemaPSimpleTypeErr(pctxt,
+			XML_SCHEMAP_INVALID_ATTR_USE,
+			NULL, (xmlNodePtr) attr,
+			NULL, "(optional | prohibited | required)",
+			attrValue, NULL, NULL, NULL);
+		}
+		goto attr_next;
+	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
+		/*
+		* 3.2.3 : 1
+		* default and fixed must not both be present.
+		*/
+		if (defValue) {
+		    xmlSchemaPMutualExclAttrErr(pctxt,
+			XML_SCHEMAP_SRC_ATTRIBUTE_1,
+			NULL, attr, "default", "fixed");
+		} else {
+		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
+		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
+		}
+		goto attr_next;
+	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
+		/*
+		* 3.2.3 : 1
+		* default and fixed must not both be present.
+		*/
+		if (defValue) {
+		    xmlSchemaPMutualExclAttrErr(pctxt,
+			XML_SCHEMAP_SRC_ATTRIBUTE_1,
+			NULL, attr, "default", "fixed");
+		} else {
+		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
+		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
+		}
+		goto attr_next;
+	    }
+	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
+	    goto attr_next;
+
+	xmlSchemaPIllegalAttrErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+
+attr_next:
+	attr = attr->next;
+    }
+    /*
+    * 3.2.3 : 2
+    * If default and use are both present, use must have
+    * the actual value optional.
+    */
+    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
+	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
+	xmlSchemaPSimpleTypeErr(pctxt,
+	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
+	    NULL, node, NULL,
+	    "(optional | prohibited | required)", NULL,
+	    "The value of the attribute 'use' must be 'optional' "
+	    "if the attribute 'default' is present",
+	    NULL, NULL);
+    }
+    /*
+    * We want correct attributes.
+    */
+    if (nberrors != pctxt->nberrors)
+	return(NULL);
+    if (! isRef) {
+	xmlSchemaAttributePtr attrDecl;
+
+	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
+	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
+	    ns = pctxt->targetNamespace;
+	/*
+	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
+	* TODO: Move this to the component layer.
+	*/
+	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_NO_XSI,
+		node, NULL,
+		"The target namespace must not match '%s'",
+		xmlSchemaInstanceNs, NULL);
+	}
+	attr = xmlSchemaGetPropNode(node, "name");
+	if (attr == NULL) {
+	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
+		NULL, node, "name", NULL);
+	    return (NULL);
+	}
+	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+	    return (NULL);
+	}
+	/*
+	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
+	* TODO: Move this to the component layer.
+	*/
+	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
+	    xmlSchemaPSimpleTypeErr(pctxt,
+		XML_SCHEMAP_NO_XMLNS,
+		NULL, (xmlNodePtr) attr,
+		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
+		"The value of the attribute must not match 'xmlns'",
+		NULL, NULL);
+	    return (NULL);
+	}
+	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
+	    goto check_children;
+	/*
+	* Create the attribute use component.
+	*/
+	use = xmlSchemaAddAttributeUse(pctxt, node);
+	if (use == NULL)
+	    return(NULL);
+	use->occurs = occurs;
+	/*
+	* Create the attribute declaration.
+	*/
+	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
+	if (attrDecl == NULL)
+	    return (NULL);
+	if (tmpName != NULL) {
+	    attrDecl->typeName = tmpName;
+	    attrDecl->typeNs = tmpNs;
+	}
+	use->attrDecl = attrDecl;
+	/*
+	* Value constraint.
+	*/
+	if (defValue != NULL) {
+	    attrDecl->defValue = defValue;
+	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
+		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
+	}
+    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
+	xmlSchemaQNameRefPtr ref;
+
+	/*
+	* Create the attribute use component.
+	*/
+	use = xmlSchemaAddAttributeUse(pctxt, node);
+	if (use == NULL)
+	    return(NULL);
+	/*
+	* We need to resolve the reference at later stage.
+	*/
+	WXS_ADD_PENDING(pctxt, use);
+	use->occurs = occurs;
+	/*
+	* Create a QName reference to the attribute declaration.
+	*/
+	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
+	    tmpName, tmpNs);
+	if (ref == NULL)
+	    return(NULL);
+	/*
+	* Assign the reference. This will be substituted for the
+	* referenced attribute declaration when the QName is resolved.
+	*/
+	use->attrDecl = WXS_ATTR_CAST ref;
+	/*
+	* Value constraint.
+	*/
+	if (defValue != NULL)
+	    use->defValue = defValue;
+	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
+		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
+    }
+
+check_children:
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
+	xmlSchemaAttributeUseProhibPtr prohib;
+
+	if (IS_SCHEMA(child, "annotation")) {
+	    xmlSchemaParseAnnotation(pctxt, child, 0);
+	    child = child->next;
+	}
+	if (child != NULL) {
+	    xmlSchemaPContentErr(pctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?)");
+	}
+	/*
+	* Check for pointlessness of attribute prohibitions.
+	*/
+	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
+	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
+		node, NULL,
+		"Skipping attribute use prohibition, since it is "
+		"pointless inside an <attributeGroup>",
+		NULL, NULL, NULL);
+	    return(NULL);
+	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
+	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
+		node, NULL,
+		"Skipping attribute use prohibition, since it is "
+		"pointless when extending a type",
+		NULL, NULL, NULL);
+	    return(NULL);
+	}
+	if (! isRef) {
+	    tmpName = name;
+	    tmpNs = ns;
+	}
+	/*
+	* Check for duplicate attribute prohibitions.
+	*/
+	if (uses) {
+	    int i;
+
+	    for (i = 0; i < uses->nbItems; i++) {
+		use = uses->items[i];
+		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
+		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
+		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
+		{
+		    xmlChar *str = NULL;
+
+		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
+			node, NULL,
+			"Skipping duplicate attribute use prohibition '%s'",
+			xmlSchemaFormatQName(&str, tmpNs, tmpName),
+			NULL, NULL);
+		    FREE_AND_NULL(str)
+		    return(NULL);
+		}
+	    }
+	}
+	/*
+	* Create the attribute prohibition helper component.
+	*/
+	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
+	if (prohib == NULL)
+	    return(NULL);
+	prohib->node = node;
+	prohib->name = tmpName;
+	prohib->targetNamespace = tmpNs;
+	if (isRef) {
+	    /*
+	    * We need at least to resolve to the attribute declaration.
+	    */
+	    WXS_ADD_PENDING(pctxt, prohib);
+	}
+	return(WXS_BASIC_CAST prohib);
+    } else {
+	if (IS_SCHEMA(child, "annotation")) {
+	    /*
+	    * TODO: Should this go into the attr decl?
+	    */
+	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
+	    child = child->next;
+	}
+	if (isRef) {
+	    if (child != NULL) {
+		if (IS_SCHEMA(child, "simpleType"))
+		    /*
+		    * 3.2.3 : 3.2
+		    * If ref is present, then all of <simpleType>,
+		    * form and type must be absent.
+		    */
+		    xmlSchemaPContentErr(pctxt,
+			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
+			NULL, node, child, NULL,
+			"(annotation?)");
+		else
+		    xmlSchemaPContentErr(pctxt,
+			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+			NULL, node, child, NULL,
+			"(annotation?)");
+	    }
+	} else {
+	    if (IS_SCHEMA(child, "simpleType")) {
+		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
+		    /*
+		    * 3.2.3 : 4
+		    * type and <simpleType> must not both be present.
+		    */
+		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
+			NULL, node, child,
+			"The attribute 'type' and the <simpleType> child "
+			"are mutually exclusive", NULL);
+		} else
+		    WXS_ATTRUSE_TYPEDEF(use) =
+			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
+		child = child->next;
+	    }
+	    if (child != NULL)
+		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, simpleType?)");
+	}
+    }
+    return (WXS_BASIC_CAST use);
+}
+
+
+static xmlSchemaAttributePtr
+xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
+			      xmlSchemaPtr schema,
+			      xmlNodePtr node)
+{
+    const xmlChar *attrValue;
+    xmlSchemaAttributePtr ret;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    /*
+     * Note that the w3c spec assumes the schema to be validated with schema
+     * for schemas beforehand.
+     *
+     * 3.2.3 Constraints on XML Representations of Attribute Declarations
+     */
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /*
+    * 3.2.3 : 3.1
+    * One of ref or name must be present, but not both
+    */
+    attr = xmlSchemaGetPropNode(node, "name");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "name", NULL);
+	return (NULL);
+    }
+    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
+	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
+	return (NULL);
+    }
+    /*
+    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
+    * TODO: Move this to the component layer.
+    */
+    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
+	xmlSchemaPSimpleTypeErr(pctxt,
+	    XML_SCHEMAP_NO_XMLNS,
+	    NULL, (xmlNodePtr) attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
+	    "The value of the attribute must not match 'xmlns'",
+	    NULL, NULL);
+	return (NULL);
+    }
+    /*
+    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
+    * TODO: Move this to the component layer.
+    *       Or better leave it here and add it to the component layer
+    *       if we have a schema construction API.
+    */
+    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
+	xmlSchemaCustomErr(ACTXT_CAST pctxt,
+	    XML_SCHEMAP_NO_XSI, node, NULL,
+	    "The target namespace must not match '%s'",
+	    xmlSchemaInstanceNs, NULL);
+    }
+
+    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
+	pctxt->targetNamespace, node, 1);
+    if (ret == NULL)
+	return (NULL);
+    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "type")))
+	    {
+		xmlSchemaPIllegalAttrErr(pctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(pctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrQName(pctxt, schema, NULL,
+	node, "type", &ret->typeNs, &ret->typeName);
+
+    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
+    /*
+    * Attribute "fixed".
+    */
+    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
+    if (ret->defValue != NULL)
+	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
+    /*
+    * Attribute "default".
+    */
+    attr = xmlSchemaGetPropNode(node, "default");
+    if (attr != NULL) {
+	/*
+	* 3.2.3 : 1
+	* default and fixed must not both be present.
+	*/
+	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
+	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
+		WXS_BASIC_CAST ret, attr, "default", "fixed");
+	} else
+	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
+        child = child->next;
+    }
+    if (IS_SCHEMA(child, "simpleType")) {
+	if (ret->typeName != NULL) {
+	    /*
+	    * 3.2.3 : 4
+	    * type and <simpleType> must not both be present.
+	    */
+	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
+		NULL, node, child,
+		"The attribute 'type' and the <simpleType> child "
+		"are mutually exclusive", NULL);
+	} else
+	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
+	child = child->next;
+    }
+    if (child != NULL)
+	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?, simpleType?)");
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaParseAttributeGroupRef:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parse an attribute group definition reference.
+ * Note that a reference to an attribute group does not
+ * correspond to any component at all.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the attribute group or NULL in case of error.
+ */
+static xmlSchemaQNameRefPtr
+xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
+				xmlSchemaPtr schema,
+				xmlNodePtr node)
+{
+    xmlSchemaQNameRefPtr ret;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *refNs = NULL, *ref = NULL;
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    attr = xmlSchemaGetPropNode(node, "ref");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "ref", NULL);
+	return (NULL);
+    }
+    xmlSchemaPValAttrNodeQName(pctxt, schema,
+	NULL, attr, &refNs, &ref);
+    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
+	return(NULL);
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "id")))
+	    {
+		xmlSchemaPIllegalAttrErr(pctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(pctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /* Attribute ID */
+    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
+
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* TODO: We do not have a place to store the annotation, do we?
+	*/
+        xmlSchemaParseAnnotation(pctxt, child, 0);
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(pctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?)");
+    }
+
+    /*
+    * Handle attribute group redefinitions.
+    */
+    if (pctxt->isRedefine && pctxt->redef &&
+	(pctxt->redef->item->type ==
+	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
+	(ref == pctxt->redef->refName) &&
+	(refNs == pctxt->redef->refTargetNs))
+    {
+	/*
+	* SPEC src-redefine:
+	* (7.1) "If it has an <attributeGroup> among its contents
+	* the �actual value� of whose ref [attribute] is the same
+	* as the �actual value� of its own name attribute plus
+	* target namespace, then it must have exactly one such group."
+	*/
+	if (pctxt->redefCounter != 0) {
+	    xmlChar *str = NULL;
+
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
+		"The redefining attribute group definition "
+		"'%s' must not contain more than one "
+		"reference to the redefined definition",
+		xmlSchemaFormatQName(&str, refNs, ref), NULL);
+	    FREE_AND_NULL(str);
+	    return(NULL);
+	}
+	pctxt->redefCounter++;
+	/*
+	* URGENT TODO: How to ensure that the reference will not be
+	* handled by the normal component resolution mechanism?
+	*/
+	ret = xmlSchemaNewQNameRef(pctxt,
+	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
+	if (ret == NULL)
+	    return(NULL);
+	ret->node = node;
+	pctxt->redef->reference = WXS_BASIC_CAST ret;
+    } else {
+	/*
+	* Create a QName-reference helper component. We will substitute this
+	* component for the attribute uses of the referenced attribute group
+	* definition.
+	*/
+	ret = xmlSchemaNewQNameRef(pctxt,
+	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
+	if (ret == NULL)
+	    return(NULL);
+	ret->node = node;
+	/* Add to pending items, to be able to resolve the reference. */
+	WXS_ADD_PENDING(pctxt, ret);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchemaParseAttributeGroupDefinition:
+ * @pctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Attribute Group declaration
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the attribute group definition or NULL in case of error.
+ */
+static xmlSchemaAttributeGroupPtr
+xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
+				       xmlSchemaPtr schema,
+				       xmlNodePtr node)
+{
+    const xmlChar *name;
+    xmlSchemaAttributeGroupPtr ret;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    int hasRefs = 0;
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    attr = xmlSchemaGetPropNode(node, "name");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "name", NULL);
+	return (NULL);
+    }
+    /*
+    * The name is crucial, exit if invalid.
+    */
+    if (xmlSchemaPValAttrNode(pctxt,
+	NULL, attr,
+	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+	return (NULL);
+    }
+    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
+	name, pctxt->targetNamespace, node);
+    if (ret == NULL)
+	return (NULL);
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "id")))
+	    {
+		xmlSchemaPIllegalAttrErr(pctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(pctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /* Attribute ID */
+    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
+        child = child->next;
+    }
+    /*
+    * Parse contained attribute decls/refs.
+    */
+    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
+	(xmlSchemaItemListPtr *) &(ret->attrUses),
+	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
+	return(NULL);
+    if (hasRefs)
+	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
+    /*
+    * Parse the attribute wildcard.
+    */
+    if (IS_SCHEMA(child, "anyAttribute")) {
+	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
+	    schema, child);
+	child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(pctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchemaPValAttrFormDefault:
+ * @value:  the value
+ * @flags: the flags to be modified
+ * @flagQualified: the specific flag for "qualified"
+ *
+ * Returns 0 if the value is valid, 1 otherwise.
+ */
+static int
+xmlSchemaPValAttrFormDefault(const xmlChar *value,
+			     int *flags,
+			     int flagQualified)
+{
+    if (xmlStrEqual(value, BAD_CAST "qualified")) {
+	if  ((*flags & flagQualified) == 0)
+	    *flags |= flagQualified;
+    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
+	return (1);
+
+    return (0);
+}
+
+/**
+ * xmlSchemaPValAttrBlockFinal:
+ * @value:  the value
+ * @flags: the flags to be modified
+ * @flagAll: the specific flag for "#all"
+ * @flagExtension: the specific flag for "extension"
+ * @flagRestriction: the specific flag for "restriction"
+ * @flagSubstitution: the specific flag for "substitution"
+ * @flagList: the specific flag for "list"
+ * @flagUnion: the specific flag for "union"
+ *
+ * Validates the value of the attribute "final" and "block". The value
+ * is converted into the specified flag values and returned in @flags.
+ *
+ * Returns 0 if the value is valid, 1 otherwise.
+ */
+
+static int
+xmlSchemaPValAttrBlockFinal(const xmlChar *value,
+			    int *flags,
+			    int flagAll,
+			    int flagExtension,
+			    int flagRestriction,
+			    int flagSubstitution,
+			    int flagList,
+			    int flagUnion)
+{
+    int ret = 0;
+
+    /*
+    * TODO: This does not check for dublicate entries.
+    */
+    if ((flags == NULL) || (value == NULL))
+	return (-1);
+    if (value[0] == 0)
+	return (0);
+    if (xmlStrEqual(value, BAD_CAST "#all")) {
+	if (flagAll != -1)
+	    *flags |= flagAll;
+	else {
+	    if (flagExtension != -1)
+		*flags |= flagExtension;
+	    if (flagRestriction != -1)
+		*flags |= flagRestriction;
+	    if (flagSubstitution != -1)
+		*flags |= flagSubstitution;
+	    if (flagList != -1)
+		*flags |= flagList;
+	    if (flagUnion != -1)
+		*flags |= flagUnion;
+	}
+    } else {
+	const xmlChar *end, *cur = value;
+	xmlChar *item;
+
+	do {
+	    while (IS_BLANK_CH(*cur))
+		cur++;
+	    end = cur;
+	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+		end++;
+	    if (end == cur)
+		break;
+	    item = xmlStrndup(cur, end - cur);
+	    if (xmlStrEqual(item, BAD_CAST "extension")) {
+		if (flagExtension != -1) {
+		    if ((*flags & flagExtension) == 0)
+			*flags |= flagExtension;
+		} else
+		    ret = 1;
+	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
+		if (flagRestriction != -1) {
+		    if ((*flags & flagRestriction) == 0)
+			*flags |= flagRestriction;
+		} else
+		    ret = 1;
+	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
+		if (flagSubstitution != -1) {
+		    if ((*flags & flagSubstitution) == 0)
+			*flags |= flagSubstitution;
+		} else
+		    ret = 1;
+	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
+		if (flagList != -1) {
+		    if ((*flags & flagList) == 0)
+			*flags |= flagList;
+		} else
+		    ret = 1;
+	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
+		if (flagUnion != -1) {
+		    if ((*flags & flagUnion) == 0)
+			*flags |= flagUnion;
+		} else
+		    ret = 1;
+	    } else
+		ret = 1;
+	    if (item != NULL)
+		xmlFree(item);
+	    cur = end;
+	} while ((ret == 0) && (*cur != 0));
+    }
+
+    return (ret);
+}
+
+static int
+xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
+			     xmlSchemaIDCPtr idc,
+			     xmlSchemaIDCSelectPtr selector,
+			     xmlAttrPtr attr,
+			     int isField)
+{
+    xmlNodePtr node;
+
+    /*
+    * c-selector-xpath:
+    * Schema Component Constraint: Selector Value OK
+    *
+    * TODO: 1 The {selector} must be a valid XPath expression, as defined
+    * in [XPath].
+    */
+    if (selector == NULL) {
+	xmlSchemaPErr(ctxt, idc->node,
+	    XML_SCHEMAP_INTERNAL,
+	    "Internal error: xmlSchemaCheckCSelectorXPath, "
+	    "the selector is not specified.\n", NULL, NULL);
+	return (-1);
+    }
+    if (attr == NULL)
+	node = idc->node;
+    else
+	node = (xmlNodePtr) attr;
+    if (selector->xpath == NULL) {
+	xmlSchemaPCustomErr(ctxt,
+	    /* TODO: Adjust error code. */
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    NULL, node,
+	    "The XPath expression of the selector is not valid", NULL);
+	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
+    } else {
+	const xmlChar **nsArray = NULL;
+	xmlNsPtr *nsList = NULL;
+	/*
+	* Compile the XPath expression.
+	*/
+	/*
+	* TODO: We need the array of in-scope namespaces for compilation.
+	* TODO: Call xmlPatterncompile with different options for selector/
+	* field.
+	*/
+	if (attr == NULL)
+	    nsList = NULL;
+	else
+	    nsList = xmlGetNsList(attr->doc, attr->parent);
+	/*
+	* Build an array of prefixes and namespaces.
+	*/
+	if (nsList != NULL) {
+	    int i, count = 0;
+
+	    for (i = 0; nsList[i] != NULL; i++)
+		count++;
+
+	    nsArray = (const xmlChar **) xmlMalloc(
+		(count * 2 + 1) * sizeof(const xmlChar *));
+	    if (nsArray == NULL) {
+		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
+		    NULL);
+		xmlFree(nsList);
+		return (-1);
+	    }
+	    for (i = 0; i < count; i++) {
+		nsArray[2 * i] = nsList[i]->href;
+		nsArray[2 * i + 1] = nsList[i]->prefix;
+	    }
+	    nsArray[count * 2] = NULL;
+	    xmlFree(nsList);
+	}
+	/*
+	* TODO: Differentiate between "selector" and "field".
+	*/
+	if (isField)
+	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
+		NULL, XML_PATTERN_XSFIELD, nsArray);
+	else
+	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
+		NULL, XML_PATTERN_XSSEL, nsArray);
+	if (nsArray != NULL)
+	    xmlFree((xmlChar **) nsArray);
+
+	if (selector->xpathComp == NULL) {
+	    xmlSchemaPCustomErr(ctxt,
+		/* TODO: Adjust error code? */
+		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		NULL, node,
+		"The XPath expression '%s' could not be "
+		"compiled", selector->xpath);
+	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
+	}
+    }
+    return (0);
+}
+
+#define ADD_ANNOTATION(annot)   \
+    xmlSchemaAnnotPtr cur = item->annot; \
+    if (item->annot == NULL) {  \
+	item->annot = annot;    \
+	return (annot);         \
+    }                           \
+    cur = item->annot;          \
+    if (cur->next != NULL) {    \
+	cur = cur->next;	\
+    }                           \
+    cur->next = annot;
+
+/**
+ * xmlSchemaAssignAnnotation:
+ * @item: the schema component
+ * @annot: the annotation
+ *
+ * Adds the annotation to the given schema component.
+ *
+ * Returns the given annotaion.
+ */
+static xmlSchemaAnnotPtr
+xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
+		       xmlSchemaAnnotPtr annot)
+{
+    if ((annItem == NULL) || (annot == NULL))
+	return (NULL);
+    switch (annItem->type) {
+	case XML_SCHEMA_TYPE_ELEMENT: {
+		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTE: {
+		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
+	case XML_SCHEMA_TYPE_ANY: {
+		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_PARTICLE:
+	case XML_SCHEMA_TYPE_IDC_KEY:
+	case XML_SCHEMA_TYPE_IDC_KEYREF:
+	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
+		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
+		xmlSchemaAttributeGroupPtr item =
+		    (xmlSchemaAttributeGroupPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_NOTATION: {
+		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_FACET_MININCLUSIVE:
+	case XML_SCHEMA_FACET_MINEXCLUSIVE:
+	case XML_SCHEMA_FACET_MAXINCLUSIVE:
+	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+	case XML_SCHEMA_FACET_TOTALDIGITS:
+	case XML_SCHEMA_FACET_FRACTIONDIGITS:
+	case XML_SCHEMA_FACET_PATTERN:
+	case XML_SCHEMA_FACET_ENUMERATION:
+	case XML_SCHEMA_FACET_WHITESPACE:
+	case XML_SCHEMA_FACET_LENGTH:
+	case XML_SCHEMA_FACET_MAXLENGTH:
+	case XML_SCHEMA_FACET_MINLENGTH: {
+		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_SIMPLE:
+	case XML_SCHEMA_TYPE_COMPLEX: {
+		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_GROUP: {
+		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	case XML_SCHEMA_TYPE_SEQUENCE:
+	case XML_SCHEMA_TYPE_CHOICE:
+	case XML_SCHEMA_TYPE_ALL: {
+		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
+		ADD_ANNOTATION(annot)
+	    }
+	    break;
+	default:
+	     xmlSchemaPCustomErr(NULL,
+		XML_SCHEMAP_INTERNAL,
+		NULL, NULL,
+		"Internal error: xmlSchemaAddAnnotation, "
+		"The item is not a annotated schema component", NULL);
+	     break;
+    }
+    return (annot);
+}
+
+/**
+ * xmlSchemaParseIDCSelectorAndField:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parses a XML Schema identity-contraint definition's
+ * <selector> and <field> elements.
+ *
+ * Returns the parsed identity-constraint definition.
+ */
+static xmlSchemaIDCSelectPtr
+xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
+			  xmlSchemaIDCPtr idc,
+			  xmlNodePtr node,
+			  int isField)
+{
+    xmlSchemaIDCSelectPtr item;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /*
+    * Create the item.
+    */
+    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
+    if (item == NULL) {
+        xmlSchemaPErrMemory(ctxt,
+	    "allocating a 'selector' of an identity-constraint definition",
+	    NULL);
+        return (NULL);
+    }
+    memset(item, 0, sizeof(xmlSchemaIDCSelect));
+    /*
+    * Attribute "xpath" (mandatory).
+    */
+    attr = xmlSchemaGetPropNode(node, "xpath");
+    if (attr == NULL) {
+    	xmlSchemaPMissingAttrErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node,
+	    "name", NULL);
+    } else {
+	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	/*
+	* URGENT TODO: "field"s have an other syntax than "selector"s.
+	*/
+
+	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
+	    isField) == -1) {
+	    xmlSchemaPErr(ctxt,
+		(xmlNodePtr) attr,
+		XML_SCHEMAP_INTERNAL,
+		"Internal error: xmlSchemaParseIDCSelectorAndField, "
+		"validating the XPath expression of a IDC selector.\n",
+		NULL, NULL);
+	}
+
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the parent IDC.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+	child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?)");
+    }
+
+    return (item);
+}
+
+/**
+ * xmlSchemaParseIDC:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parses a XML Schema identity-contraint definition.
+ *
+ * Returns the parsed identity-constraint definition.
+ */
+static xmlSchemaIDCPtr
+xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
+		  xmlSchemaPtr schema,
+		  xmlNodePtr node,
+		  xmlSchemaTypeType idcCategory,
+		  const xmlChar *targetNamespace)
+{
+    xmlSchemaIDCPtr item = NULL;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *name = NULL;
+    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
+		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /*
+    * Attribute "name" (mandatory).
+    */
+    attr = xmlSchemaGetPropNode(node, "name");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node,
+	    "name", NULL);
+	return (NULL);
+    } else if (xmlSchemaPValAttrNode(ctxt,
+	NULL, attr,
+	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+	return (NULL);
+    }
+    /* Create the component. */
+    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
+	idcCategory, node);
+    if (item == NULL)
+	return(NULL);
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
+	/*
+	* Attribute "refer" (mandatory).
+	*/
+	attr = xmlSchemaGetPropNode(node, "refer");
+	if (attr == NULL) {
+	    xmlSchemaPMissingAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_MISSING,
+		NULL, node,
+		"refer", NULL);
+	} else {
+	    /*
+	    * Create a reference item.
+	    */
+	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
+		NULL, NULL);
+	    if (item->ref == NULL)
+		return (NULL);
+	    xmlSchemaPValAttrNodeQName(ctxt, schema,
+		NULL, attr,
+		&(item->ref->targetNamespace),
+		&(item->ref->name));
+	    xmlSchemaCheckReference(ctxt, schema, node, attr,
+		item->ref->targetNamespace);
+	}
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	child = child->next;
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_MISSING,
+		NULL, node, child,
+		"A child element is missing",
+		"(annotation?, (selector, field+))");
+    }
+    /*
+    * Child element <selector>.
+    */
+    if (IS_SCHEMA(child, "selector")) {
+	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
+	    item, child, 0);
+	child = child->next;
+	/*
+	* Child elements <field>.
+	*/
+	if (IS_SCHEMA(child, "field")) {
+	    do {
+		field = xmlSchemaParseIDCSelectorAndField(ctxt,
+		    item, child, 1);
+		if (field != NULL) {
+		    field->index = item->nbFields;
+		    item->nbFields++;
+		    if (lastField != NULL)
+			lastField->next = field;
+		    else
+			item->fields = field;
+		    lastField = field;
+		}
+		child = child->next;
+	    } while (IS_SCHEMA(child, "field"));
+	} else {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child,
+		NULL, "(annotation?, (selector, field+))");
+	}
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?, (selector, field+))");
+    }
+
+    return (item);
+}
+
+/**
+ * xmlSchemaParseElement:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ * @topLevel: indicates if this is global declaration
+ *
+ * Parses a XML schema element declaration.
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the element declaration or a particle; NULL in case
+ * of an error or if the particle has minOccurs==maxOccurs==0.
+ */
+static xmlSchemaBasicItemPtr
+xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                      xmlNodePtr node, int *isElemRef, int topLevel)
+{
+    xmlSchemaElementPtr decl = NULL;
+    xmlSchemaParticlePtr particle = NULL;
+    xmlSchemaAnnotPtr annot = NULL;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr, nameAttr;
+    int min, max, isRef = 0;
+    xmlChar *des = NULL;
+
+    /* 3.3.3 Constraints on XML Representations of Element Declarations */
+    /* TODO: Complete implementation of 3.3.6 */
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    if (isElemRef != NULL)
+	*isElemRef = 0;
+    /*
+    * If we get a "ref" attribute on a local <element> we will assume it's
+    * a reference - even if there's a "name" attribute; this seems to be more
+    * robust.
+    */
+    nameAttr = xmlSchemaGetPropNode(node, "name");
+    attr = xmlSchemaGetPropNode(node, "ref");
+    if ((topLevel) || (attr == NULL)) {
+	if (nameAttr == NULL) {
+	    xmlSchemaPMissingAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_MISSING,
+		NULL, node, "name", NULL);
+	    return (NULL);
+	}
+    } else
+	isRef = 1;
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	child = child->next;
+    }
+    /*
+    * Skip particle part if a global declaration.
+    */
+    if (topLevel)
+	goto declaration_part;
+    /*
+    * The particle part ==================================================
+    */
+    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
+    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
+    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
+    particle = xmlSchemaAddParticle(ctxt, node, min, max);
+    if (particle == NULL)
+	goto return_null;
+
+    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
+
+    if (isRef) {
+	const xmlChar *refNs = NULL, *ref = NULL;
+	xmlSchemaQNameRefPtr refer = NULL;
+	/*
+	* The reference part =============================================
+	*/
+	if (isElemRef != NULL)
+	    *isElemRef = 1;
+
+	xmlSchemaPValAttrNodeQName(ctxt, schema,
+	    NULL, attr, &refNs, &ref);
+	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
+	/*
+	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
+	*/
+	if (nameAttr != NULL) {
+	    xmlSchemaPMutualExclAttrErr(ctxt,
+		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
+	}
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
+		    xmlStrEqual(attr->name, BAD_CAST "name") ||
+		    xmlStrEqual(attr->name, BAD_CAST "id") ||
+		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
+		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
+		{
+		    attr = attr->next;
+		    continue;
+		} else {
+		    /* SPEC (3.3.3 : 2.2) */
+		    xmlSchemaPCustomAttrErr(ctxt,
+			XML_SCHEMAP_SRC_ELEMENT_2_2,
+			NULL, NULL, attr,
+			"Only the attributes 'minOccurs', 'maxOccurs' and "
+			"'id' are allowed in addition to 'ref'");
+		    break;
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+	/*
+	* No children except <annotation> expected.
+	*/
+	if (child != NULL) {
+	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL, "(annotation?)");
+	}
+	if ((min == 0) && (max == 0))
+	    goto return_null;
+	/*
+	* Create the reference item and attach it to the particle.
+	*/
+	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
+	    ref, refNs);
+	if (refer == NULL)
+	    goto return_null;
+	particle->children = (xmlSchemaTreeItemPtr) refer;
+	particle->annot = annot;
+	/*
+	* Add the particle to pending components, since the reference
+	* need to be resolved.
+	*/
+	WXS_ADD_PENDING(ctxt, particle);
+	return ((xmlSchemaBasicItemPtr) particle);
+    }
+    /*
+    * The declaration part ===============================================
+    */
+declaration_part:
+    {
+	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
+	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
+
+	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
+	    goto return_null;
+	/*
+	* Evaluate the target namespace.
+	*/
+	if (topLevel) {
+	    ns = ctxt->targetNamespace;
+	} else {
+	    attr = xmlSchemaGetPropNode(node, "form");
+	    if (attr != NULL) {
+		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
+		    ns = ctxt->targetNamespace;
+		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
+		    xmlSchemaPSimpleTypeErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+			NULL, (xmlNodePtr) attr,
+			NULL, "(qualified | unqualified)",
+			attrValue, NULL, NULL, NULL);
+		}
+	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
+		ns = ctxt->targetNamespace;
+	}
+	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
+	if (decl == NULL) {
+	    goto return_null;
+	}
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
+		{
+		    if (topLevel == 0) {
+			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
+			{
+			    xmlSchemaPIllegalAttrErr(ctxt,
+				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+			}
+		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
+			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
+			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
+
+			xmlSchemaPIllegalAttrErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		    }
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+	/*
+	* Extract/validate attributes.
+	*/
+	if (topLevel) {
+	    /*
+	    * Process top attributes of global element declarations here.
+	    */
+	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
+	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
+	    xmlSchemaPValAttrQName(ctxt, schema,
+		NULL, node, "substitutionGroup",
+		&(decl->substGroupNs), &(decl->substGroup));
+	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
+		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
+	    /*
+	    * Attribute "final".
+	    */
+	    attr = xmlSchemaGetPropNode(node, "final");
+	    if (attr == NULL) {
+		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
+		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
+		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
+		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
+	    } else {
+		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
+		    -1,
+		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
+		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
+		    xmlSchemaPSimpleTypeErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+			NULL, (xmlNodePtr) attr,
+			NULL, "(#all | List of (extension | restriction))",
+			attrValue, NULL, NULL, NULL);
+		}
+	    }
+	}
+	/*
+	* Attribute "block".
+	*/
+	attr = xmlSchemaGetPropNode(node, "block");
+	if (attr == NULL) {
+	    /*
+	    * Apply default "block" values.
+	    */
+	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
+		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
+	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
+		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
+	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
+		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
+	} else {
+	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
+		-1,
+		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
+		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
+		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
+		xmlSchemaPSimpleTypeErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		    NULL, (xmlNodePtr) attr,
+		    NULL, "(#all | List of (extension | "
+		    "restriction | substitution))", attrValue,
+		    NULL, NULL, NULL);
+	    }
+	}
+	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
+	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
+
+	attr = xmlSchemaGetPropNode(node, "type");
+	if (attr != NULL) {
+	    xmlSchemaPValAttrNodeQName(ctxt, schema,
+		NULL, attr,
+		&(decl->namedTypeNs), &(decl->namedType));
+	    xmlSchemaCheckReference(ctxt, schema, node,
+		attr, decl->namedTypeNs);
+	}
+	decl->value = xmlSchemaGetProp(ctxt, node, "default");
+	attr = xmlSchemaGetPropNode(node, "fixed");
+	if (attr != NULL) {
+	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	    if (decl->value != NULL) {
+		/*
+		* 3.3.3 : 1
+		* default and fixed must not both be present.
+		*/
+		xmlSchemaPMutualExclAttrErr(ctxt,
+		    XML_SCHEMAP_SRC_ELEMENT_1,
+		    NULL, attr, "default", "fixed");
+	    } else {
+		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
+		decl->value = fixed;
+	    }
+	}
+	/*
+	* And now for the children...
+	*/
+	if (IS_SCHEMA(child, "complexType")) {
+	    /*
+	    * 3.3.3 : 3
+	    * "type" and either <simpleType> or <complexType> are mutually
+	    * exclusive
+	    */
+	    if (decl->namedType != NULL) {
+		xmlSchemaPContentErr(ctxt,
+		    XML_SCHEMAP_SRC_ELEMENT_3,
+		    NULL, node, child,
+		    "The attribute 'type' and the <complexType> child are "
+		    "mutually exclusive", NULL);
+	    } else
+		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "simpleType")) {
+	    /*
+	    * 3.3.3 : 3
+	    * "type" and either <simpleType> or <complexType> are
+	    * mutually exclusive
+	    */
+	    if (decl->namedType != NULL) {
+		xmlSchemaPContentErr(ctxt,
+		    XML_SCHEMAP_SRC_ELEMENT_3,
+		    NULL, node, child,
+		    "The attribute 'type' and the <simpleType> child are "
+		    "mutually exclusive", NULL);
+	    } else
+		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+	    child = child->next;
+	}
+	while ((IS_SCHEMA(child, "unique")) ||
+	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
+	    if (IS_SCHEMA(child, "unique")) {
+		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
+	    } else if (IS_SCHEMA(child, "key")) {
+		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
+	    } else if (IS_SCHEMA(child, "keyref")) {
+		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
+	    }
+	    if (lastIDC != NULL)
+		lastIDC->next = curIDC;
+	    else
+		decl->idcs = (void *) curIDC;
+	    lastIDC = curIDC;
+	    child = child->next;
+	}
+	if (child != NULL) {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child,
+		NULL, "(annotation?, ((simpleType | complexType)?, "
+		"(unique | key | keyref)*))");
+	}
+	decl->annot = annot;
+    }
+    /*
+    * NOTE: Element Declaration Representation OK 4. will be checked at a
+    * different layer.
+    */
+    FREE_AND_NULL(des)
+    if (topLevel)
+	return ((xmlSchemaBasicItemPtr) decl);
+    else {
+	particle->children = (xmlSchemaTreeItemPtr) decl;
+	return ((xmlSchemaBasicItemPtr) particle);
+    }
+
+return_null:
+    FREE_AND_NULL(des);
+    if (annot != NULL) {
+	if (particle != NULL)
+	    particle->annot = NULL;
+	if (decl != NULL)
+	    decl->annot = NULL;
+	xmlSchemaFreeAnnot(annot);
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaParseUnion:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Union definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of internal error, 0 in case of success and a positive
+ * error code otherwise.
+ */
+static int
+xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                    xmlNodePtr node)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *cur = NULL;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (-1);
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    /*
+    * Mark the simple type as being of variety "union".
+    */
+    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+    /*
+    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
+    * then the �simple ur-type definition�."
+    */
+    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * Attribute "memberTypes". This is a list of QNames.
+    * TODO: Check the value to contain anything.
+    */
+    attr = xmlSchemaGetPropNode(node, "memberTypes");
+    if (attr != NULL) {
+	const xmlChar *end;
+	xmlChar *tmp;
+	const xmlChar *localName, *nsName;
+	xmlSchemaTypeLinkPtr link, lastLink = NULL;
+	xmlSchemaQNameRefPtr ref;
+
+	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	type->base = cur;
+	do {
+	    while (IS_BLANK_CH(*cur))
+		cur++;
+	    end = cur;
+	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+		end++;
+	    if (end == cur)
+		break;
+	    tmp = xmlStrndup(cur, end - cur);
+	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
+		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
+		/*
+		* Create the member type link.
+		*/
+		link = (xmlSchemaTypeLinkPtr)
+		    xmlMalloc(sizeof(xmlSchemaTypeLink));
+		if (link == NULL) {
+		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
+			"allocating a type link", NULL);
+		    return (-1);
+		}
+		link->type = NULL;
+		link->next = NULL;
+		if (lastLink == NULL)
+		    type->memberTypes = link;
+		else
+		    lastLink->next = link;
+		lastLink = link;
+		/*
+		* Create a reference item.
+		*/
+		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
+		    localName, nsName);
+		if (ref == NULL) {
+		    FREE_AND_NULL(tmp)
+		    return (-1);
+		}
+		/*
+		* Assign the reference to the link, it will be resolved
+		* later during fixup of the union simple type.
+		*/
+		link->type = (xmlSchemaTypePtr) ref;
+	    }
+	    FREE_AND_NULL(tmp)
+	    cur = end;
+	} while (*cur != 0);
+
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the simple type ancestor.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (IS_SCHEMA(child, "simpleType")) {
+	xmlSchemaTypePtr subtype, last = NULL;
+
+	/*
+	* Anchor the member types in the "subtypes" field of the
+	* simple type.
+	*/
+	while (IS_SCHEMA(child, "simpleType")) {
+	    subtype = (xmlSchemaTypePtr)
+		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+	    if (subtype != NULL) {
+		if (last == NULL) {
+		    type->subtypes = subtype;
+		    last = subtype;
+		} else {
+		    last->next = subtype;
+		    last = subtype;
+		}
+		last->next = NULL;
+	    }
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL, "(annotation?, simpleType*)");
+    }
+    if ((attr == NULL) && (type->subtypes == NULL)) {
+	 /*
+	* src-union-memberTypes-or-simpleTypes
+	* Either the memberTypes [attribute] of the <union> element must
+	* be non-empty or there must be at least one simpleType [child].
+	*/
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
+	    NULL, node,
+	    "Either the attribute 'memberTypes' or "
+	    "at least one <simpleType> child must be present", NULL);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaParseList:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema List definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error, 0 if the declaration is improper and
+ *         1 in case of success.
+ */
+static xmlSchemaTypePtr
+xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                   xmlNodePtr node)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    /*
+    * Mark the type as being of variety "list".
+    */
+    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+    /*
+    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
+    * then the �simple ur-type definition�."
+    */
+    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+
+    /*
+    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
+    * fields for holding the reference to the itemType.
+    *
+    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
+    * the "ref" fields.
+    */
+    xmlSchemaPValAttrQName(ctxt, schema, NULL,
+	node, "itemType", &(type->baseNs), &(type->base));
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (IS_SCHEMA(child, "simpleType")) {
+	/*
+	* src-list-itemType-or-simpleType
+	* Either the itemType [attribute] or the <simpleType> [child] of
+	* the <list> element must be present, but not both.
+	*/
+	if (type->base != NULL) {
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+		NULL, node,
+		"The attribute 'itemType' and the <simpleType> child "
+		"are mutually exclusive", NULL);
+	} else {
+	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+	}
+        child = child->next;
+    } else if (type->base == NULL) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+	    NULL, node,
+	    "Either the attribute 'itemType' or the <simpleType> child "
+	    "must be present", NULL);
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL, "(annotation?, simpleType?)");
+    }
+    if ((type->base == NULL) &&
+	(type->subtypes == NULL) &&
+	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+	    NULL, node,
+	    "Either the attribute 'itemType' or the <simpleType> child "
+	    "must be present", NULL);
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaParseSimpleType:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Simple Type definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error, 0 if the declaration is improper and
+ * 1 in case of success.
+ */
+static xmlSchemaTypePtr
+xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                         xmlNodePtr node, int topLevel)
+{
+    xmlSchemaTypePtr type, oldCtxtType;
+    xmlNodePtr child = NULL;
+    const xmlChar *attrValue = NULL;
+    xmlAttrPtr attr;
+    int hasRestriction = 0;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    if (topLevel) {
+	attr = xmlSchemaGetPropNode(node, "name");
+	if (attr == NULL) {
+	    xmlSchemaPMissingAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_MISSING,
+		NULL, node,
+		"name", NULL);
+	    return (NULL);
+	} else {
+	    if (xmlSchemaPValAttrNode(ctxt,
+		NULL, attr,
+		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
+		return (NULL);
+	    /*
+	    * Skip built-in types.
+	    */
+	    if (ctxt->isS4S) {
+		xmlSchemaTypePtr biType;
+
+		if (ctxt->isRedefine) {
+		    /*
+		    * REDEFINE: Disallow redefinition of built-in-types.
+		    * TODO: It seems that the spec does not say anything
+		    * about this case.
+		    */
+		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+			NULL, node,
+			"Redefinition of built-in simple types is not "
+			"supported", NULL);
+		    return(NULL);
+		}
+		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
+		if (biType != NULL)
+		    return (biType);
+	    }
+	}
+    }
+    /*
+    * TargetNamespace:
+    * SPEC "The �actual value� of the targetNamespace [attribute]
+    * of the <schema> ancestor element information item if present,
+    * otherwise �absent�.
+    */
+    if (topLevel == 0) {
+#ifdef ENABLE_NAMED_LOCALS
+        char buf[40];
+#endif
+	/*
+	* Parse as local simple type definition.
+	*/
+#ifdef ENABLE_NAMED_LOCALS
+        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
+	type = xmlSchemaAddType(ctxt, schema,
+	    XML_SCHEMA_TYPE_SIMPLE,
+	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
+	    ctxt->targetNamespace, node, 0);
+#else
+	type = xmlSchemaAddType(ctxt, schema,
+	    XML_SCHEMA_TYPE_SIMPLE,
+	    NULL, ctxt->targetNamespace, node, 0);
+#endif
+	if (type == NULL)
+	    return (NULL);
+	type->type = XML_SCHEMA_TYPE_SIMPLE;
+	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+    } else {
+	/*
+	* Parse as global simple type definition.
+	*
+	* Note that attrValue is the value of the attribute "name" here.
+	*/
+	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
+	    attrValue, ctxt->targetNamespace, node, 1);
+	if (type == NULL)
+	    return (NULL);
+	type->type = XML_SCHEMA_TYPE_SIMPLE;
+	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+	/*
+	* Attribute "final".
+	*/
+	attr = xmlSchemaGetPropNode(node, "final");
+	if (attr == NULL) {
+	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
+		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
+	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
+		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
+	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
+		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
+	} else {
+	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
+	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
+		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
+		XML_SCHEMAS_TYPE_FINAL_LIST,
+		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
+
+		xmlSchemaPSimpleTypeErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
+		    NULL, "(#all | List of (list | union | restriction)",
+		    attrValue, NULL, NULL, NULL);
+	    }
+	}
+    }
+    type->targetNamespace = ctxt->targetNamespace;
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    oldCtxtType = ctxt->ctxtType;
+
+    ctxt->ctxtType = type;
+
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
+	    NULL, node, child, NULL,
+	    "(annotation?, (restriction | list | union))");
+    } else if (IS_SCHEMA(child, "restriction")) {
+        xmlSchemaParseRestriction(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_SIMPLE);
+	hasRestriction = 1;
+        child = child->next;
+    } else if (IS_SCHEMA(child, "list")) {
+        xmlSchemaParseList(ctxt, schema, child);
+        child = child->next;
+    } else if (IS_SCHEMA(child, "union")) {
+        xmlSchemaParseUnion(ctxt, schema, child);
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?, (restriction | list | union))");
+    }
+    /*
+    * REDEFINE: SPEC src-redefine (5)
+    * "Within the [children], each <simpleType> must have a
+    * <restriction> among its [children] ... the �actual value� of whose
+    * base [attribute] must be the same as the �actual value� of its own
+    * name attribute plus target namespace;"
+    */
+    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
+	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+	    NULL, node, "This is a redefinition, thus the "
+	    "<simpleType> must have a <restriction> child", NULL);
+    }
+
+    ctxt->ctxtType = oldCtxtType;
+    return (type);
+}
+
+/**
+ * xmlSchemaParseModelGroupDefRef:
+ * @ctxt:  the parser context
+ * @schema: the schema being built
+ * @node:  the node
+ *
+ * Parses a reference to a model group definition.
+ *
+ * We will return a particle component with a qname-component or
+ * NULL in case of an error.
+ */
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
+			       xmlSchemaPtr schema,
+			       xmlNodePtr node)
+{
+    xmlSchemaParticlePtr item;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *ref = NULL, *refNs = NULL;
+    int min, max;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    attr = xmlSchemaGetPropNode(node, "ref");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "ref", NULL);
+	return (NULL);
+    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
+	attr, &refNs, &ref) != 0) {
+	return (NULL);
+    }
+    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
+    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
+    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+	"(xs:nonNegativeInteger | unbounded)");
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    item = xmlSchemaAddParticle(ctxt, node, min, max);
+    if (item == NULL)
+	return (NULL);
+    /*
+    * Create a qname-reference and set as the term; it will be substituted
+    * for the model group after the reference has been resolved.
+    */
+    item->children = (xmlSchemaTreeItemPtr)
+	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
+    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    /* TODO: Is annotation even allowed for a model group reference? */
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* TODO: What to do exactly with the annotation?
+	*/
+	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?)");
+    }
+    /*
+    * Corresponds to no component at all if minOccurs==maxOccurs==0.
+    */
+    if ((min == 0) && (max == 0))
+	return (NULL);
+
+    return ((xmlSchemaTreeItemPtr) item);
+}
+
+/**
+ * xmlSchemaParseModelGroupDefinition:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parses a XML schema model group definition.
+ *
+ * Note that the contraint src-redefine (6.2) can't be applied until
+ * references have been resolved. So we will do this at the
+ * component fixup level.
+ *
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error, 0 if the declaration is improper and
+ *         1 in case of success.
+ */
+static xmlSchemaModelGroupDefPtr
+xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
+				   xmlSchemaPtr schema,
+				   xmlNodePtr node)
+{
+    xmlSchemaModelGroupDefPtr item;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *name;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    attr = xmlSchemaGetPropNode(node, "name");
+    if (attr == NULL) {
+	xmlSchemaPMissingAttrErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node,
+	    "name", NULL);
+	return (NULL);
+    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
+	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+	return (NULL);
+    }
+    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
+	ctxt->targetNamespace, node);
+    if (item == NULL)
+	return (NULL);
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	child = child->next;
+    }
+    if (IS_SCHEMA(child, "all")) {
+	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_ALL, 0);
+	child = child->next;
+    } else if (IS_SCHEMA(child, "choice")) {
+	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_CHOICE, 0);
+	child = child->next;
+    } else if (IS_SCHEMA(child, "sequence")) {
+	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_SEQUENCE, 0);
+	child = child->next;
+    }
+
+
+
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?, (all | choice | sequence)?)");
+    }
+    return (item);
+}
+
+/**
+ * xmlSchemaCleanupDoc:
+ * @ctxt:  a schema validation context
+ * @node:  the root of the document.
+ *
+ * removes unwanted nodes in a schemas document tree
+ */
+static void
+xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
+{
+    xmlNodePtr delete, cur;
+
+    if ((ctxt == NULL) || (root == NULL)) return;
+
+    /*
+     * Remove all the blank text nodes
+     */
+    delete = NULL;
+    cur = root;
+    while (cur != NULL) {
+        if (delete != NULL) {
+            xmlUnlinkNode(delete);
+            xmlFreeNode(delete);
+            delete = NULL;
+        }
+        if (cur->type == XML_TEXT_NODE) {
+            if (IS_BLANK_NODE(cur)) {
+                if (xmlNodeGetSpacePreserve(cur) != 1) {
+                    delete = cur;
+                }
+            }
+        } else if ((cur->type != XML_ELEMENT_NODE) &&
+                   (cur->type != XML_CDATA_SECTION_NODE)) {
+            delete = cur;
+            goto skip_children;
+        }
+
+        /*
+         * Skip to next node
+         */
+        if (cur->children != NULL) {
+            if ((cur->children->type != XML_ENTITY_DECL) &&
+                (cur->children->type != XML_ENTITY_REF_NODE) &&
+                (cur->children->type != XML_ENTITY_NODE)) {
+                cur = cur->children;
+                continue;
+            }
+        }
+      skip_children:
+        if (cur->next != NULL) {
+            cur = cur->next;
+            continue;
+        }
+
+        do {
+            cur = cur->parent;
+            if (cur == NULL)
+                break;
+            if (cur == root) {
+                cur = NULL;
+                break;
+            }
+            if (cur->next != NULL) {
+                cur = cur->next;
+                break;
+            }
+        } while (cur != NULL);
+    }
+    if (delete != NULL) {
+        xmlUnlinkNode(delete);
+        xmlFreeNode(delete);
+        delete = NULL;
+    }
+}
+
+
+static void
+xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
+{
+    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
+	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
+
+    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
+	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
+
+    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
+	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
+    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
+	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
+    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
+	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
+    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
+	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
+
+    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
+	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
+    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
+	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
+    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
+	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
+}
+
+static int
+xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
+			     xmlSchemaPtr schema,
+			     xmlNodePtr node)
+{
+    xmlAttrPtr attr;
+    const xmlChar *val;
+    int res = 0, oldErrs = ctxt->nberrors;
+
+    /*
+    * Those flags should be moved to the parser context flags,
+    * since they are not visible at the component level. I.e.
+    * they are used if processing schema *documents* only.
+    */
+    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    HFAILURE;
+
+    /*
+    * Since the version is of type xs:token, we won't bother to
+    * check it.
+    */
+    /* REMOVED:
+    attr = xmlSchemaGetPropNode(node, "version");
+    if (attr != NULL) {
+	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
+	HFAILURE;
+    }
+    */
+    attr = xmlSchemaGetPropNode(node, "targetNamespace");
+    if (attr != NULL) {
+	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
+	HFAILURE;
+	if (res != 0) {
+	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+	    goto exit;
+	}
+    }
+    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
+    if (attr != NULL) {
+	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
+	    XML_SCHEMAS_QUALIF_ELEM);
+	HFAILURE;
+	if (res != 0) {
+	    xmlSchemaPSimpleTypeErr(ctxt,
+		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
+		NULL, (xmlNodePtr) attr, NULL,
+		"(qualified | unqualified)", val, NULL, NULL, NULL);
+	}
+    }
+    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
+    if (attr != NULL) {
+	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
+	    XML_SCHEMAS_QUALIF_ATTR);
+	HFAILURE;
+	if (res != 0) {
+	    xmlSchemaPSimpleTypeErr(ctxt,
+		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
+		NULL, (xmlNodePtr) attr, NULL,
+		"(qualified | unqualified)", val, NULL, NULL, NULL);
+	}
+    }
+    attr = xmlSchemaGetPropNode(node, "finalDefault");
+    if (attr != NULL) {
+	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
+	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
+	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
+	    -1,
+	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
+	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
+	HFAILURE;
+	if (res != 0) {
+	    xmlSchemaPSimpleTypeErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		NULL, (xmlNodePtr) attr, NULL,
+		"(#all | List of (extension | restriction | list | union))",
+		val, NULL, NULL, NULL);
+	}
+    }
+    attr = xmlSchemaGetPropNode(node, "blockDefault");
+    if (attr != NULL) {
+	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
+	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
+	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
+	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
+	HFAILURE;
+	if (res != 0) {
+	    xmlSchemaPSimpleTypeErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+		NULL, (xmlNodePtr) attr, NULL,
+		"(#all | List of (extension | restriction | substitution))",
+		val, NULL, NULL, NULL);
+	}
+    }
+
+exit:
+    if (oldErrs != ctxt->nberrors)
+	res = ctxt->err;
+    return(res);
+exit_failure:
+    return(-1);
+}
+
+/**
+ * xmlSchemaParseSchemaTopLevel:
+ * @ctxt:  a schema validation context
+ * @schema:  the schemas
+ * @nodes:  the list of top level nodes
+ *
+ * Returns the internal XML Schema structure built from the resource or
+ *         NULL in case of error
+ */
+static int
+xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
+                             xmlSchemaPtr schema, xmlNodePtr nodes)
+{
+    xmlNodePtr child;
+    xmlSchemaAnnotPtr annot;
+    int res = 0, oldErrs, tmpOldErrs;
+
+    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
+        return(-1);
+
+    oldErrs = ctxt->nberrors;
+    child = nodes;
+    while ((IS_SCHEMA(child, "include")) ||
+	   (IS_SCHEMA(child, "import")) ||
+	   (IS_SCHEMA(child, "redefine")) ||
+	   (IS_SCHEMA(child, "annotation"))) {
+	if (IS_SCHEMA(child, "annotation")) {
+	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	    if (schema->annot == NULL)
+		schema->annot = annot;
+	    else
+		xmlSchemaFreeAnnot(annot);
+	} else if (IS_SCHEMA(child, "import")) {
+	    tmpOldErrs = ctxt->nberrors;
+	    res = xmlSchemaParseImport(ctxt, schema, child);
+	    HFAILURE;
+	    HSTOP(ctxt);
+	    if (tmpOldErrs != ctxt->nberrors)
+		goto exit;
+	} else if (IS_SCHEMA(child, "include")) {
+	    tmpOldErrs = ctxt->nberrors;
+	    res = xmlSchemaParseInclude(ctxt, schema, child);
+	    HFAILURE;
+	    HSTOP(ctxt);
+	    if (tmpOldErrs != ctxt->nberrors)
+		goto exit;
+	} else if (IS_SCHEMA(child, "redefine")) {
+	    tmpOldErrs = ctxt->nberrors;
+	    res = xmlSchemaParseRedefine(ctxt, schema, child);
+	    HFAILURE;
+	    HSTOP(ctxt);
+	    if (tmpOldErrs != ctxt->nberrors)
+		goto exit;
+	}
+	child = child->next;
+    }
+    /*
+    * URGENT TODO: Change the functions to return int results.
+    * We need especially to catch internal errors.
+    */
+    while (child != NULL) {
+	if (IS_SCHEMA(child, "complexType")) {
+	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "simpleType")) {
+	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "element")) {
+	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "attribute")) {
+	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "attributeGroup")) {
+	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "group")) {
+	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "notation")) {
+	    xmlSchemaParseNotation(ctxt, schema, child);
+	    child = child->next;
+	} else {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, child->parent, child,
+		NULL, "((include | import | redefine | annotation)*, "
+		"(((simpleType | complexType | group | attributeGroup) "
+		"| element | attribute | notation), annotation*)*)");
+	    child = child->next;
+	}
+	while (IS_SCHEMA(child, "annotation")) {
+	    /*
+	    * TODO: We should add all annotations.
+	    */
+	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+	    if (schema->annot == NULL)
+		schema->annot = annot;
+	    else
+		xmlSchemaFreeAnnot(annot);
+	    child = child->next;
+	}
+    }
+exit:
+    ctxt->ctxtType = NULL;
+    if (oldErrs != ctxt->nberrors)
+	res = ctxt->err;
+    return(res);
+exit_failure:
+    return(-1);
+}
+
+static xmlSchemaSchemaRelationPtr
+xmlSchemaSchemaRelationCreate(void)
+{
+    xmlSchemaSchemaRelationPtr ret;
+
+    ret = (xmlSchemaSchemaRelationPtr)
+	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
+    if (ret == NULL) {
+	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
+    return(ret);
+}
+
+#if 0
+static void
+xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
+{
+    xmlFree(rel);
+}
+#endif
+
+static void
+xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
+{
+    xmlSchemaRedefPtr prev;
+
+    while (redef != NULL) {
+	prev = redef;
+	redef = redef->next;
+	xmlFree(prev);
+    }
+}
+
+static void
+xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
+{
+    /*
+    * After the construction context has been freed, there will be
+    * no schema graph available any more. Only the schema buckets
+    * will stay alive, which are put into the "schemasImports" and
+    * "includes" slots of the xmlSchema.
+    */
+    if (con->buckets != NULL)
+	xmlSchemaItemListFree(con->buckets);
+    if (con->pending != NULL)
+	xmlSchemaItemListFree(con->pending);
+    if (con->substGroups != NULL)
+	xmlHashFree(con->substGroups,
+	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
+    if (con->redefs != NULL)
+	xmlSchemaRedefListFree(con->redefs);
+    if (con->dict != NULL)
+	xmlDictFree(con->dict);
+    xmlFree(con);
+}
+
+static xmlSchemaConstructionCtxtPtr
+xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
+{
+    xmlSchemaConstructionCtxtPtr ret;
+
+    ret = (xmlSchemaConstructionCtxtPtr)
+	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(NULL,
+	    "allocating schema construction context", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
+
+    ret->buckets = xmlSchemaItemListCreate();
+    if (ret->buckets == NULL) {
+	xmlSchemaPErrMemory(NULL,
+	    "allocating list of schema buckets", NULL);
+	xmlFree(ret);
+        return (NULL);
+    }
+    ret->pending = xmlSchemaItemListCreate();
+    if (ret->pending == NULL) {
+	xmlSchemaPErrMemory(NULL,
+	    "allocating list of pending global components", NULL);
+	xmlSchemaConstructionCtxtFree(ret);
+        return (NULL);
+    }
+    ret->dict = dict;
+    xmlDictReference(dict);
+    return(ret);
+}
+
+static xmlSchemaParserCtxtPtr
+xmlSchemaParserCtxtCreate(void)
+{
+    xmlSchemaParserCtxtPtr ret;
+
+    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
+    if (ret == NULL) {
+        xmlSchemaPErrMemory(NULL, "allocating schema parser context",
+                            NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
+    ret->type = XML_SCHEMA_CTXT_PARSER;
+    ret->attrProhibs = xmlSchemaItemListCreate();
+    if (ret->attrProhibs == NULL) {
+	xmlFree(ret);
+	return(NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlSchemaNewParserCtxtUseDict:
+ * @URL:  the location of the schema
+ * @dict: the dictionary to be used
+ *
+ * Create an XML Schemas parse context for that file/resource expected
+ * to contain an XML Schemas file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+static xmlSchemaParserCtxtPtr
+xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
+{
+    xmlSchemaParserCtxtPtr ret;
+
+    ret = xmlSchemaParserCtxtCreate();
+    if (ret == NULL)
+        return (NULL);
+    ret->dict = dict;
+    xmlDictReference(dict);
+    if (URL != NULL)
+	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
+    return (ret);
+}
+
+static int
+xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
+{
+    if (vctxt->pctxt == NULL) {
+        if (vctxt->schema != NULL)
+	    vctxt->pctxt =
+		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
+	else
+	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
+	if (vctxt->pctxt == NULL) {
+	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
+		"failed to create a temp. parser context");
+	    return (-1);
+	}
+	/* TODO: Pass user data. */
+	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
+	    vctxt->warning, vctxt->errCtxt);
+	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
+	    vctxt->errCtxt);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaGetSchemaBucket:
+ * @pctxt: the schema parser context
+ * @schemaLocation: the URI of the schema document
+ *
+ * Returns a schema bucket if it was already parsed.
+ *
+ * Returns a schema bucket if it was already parsed from
+ *         @schemaLocation, NULL otherwise.
+ */
+static xmlSchemaBucketPtr
+xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
+			    const xmlChar *schemaLocation)
+{
+    xmlSchemaBucketPtr cur;
+    xmlSchemaItemListPtr list;
+
+    list = pctxt->constructor->buckets;
+    if (list->nbItems == 0)
+	return(NULL);
+    else {
+	int i;
+	for (i = 0; i < list->nbItems; i++) {
+	    cur = (xmlSchemaBucketPtr) list->items[i];
+	    /* Pointer comparison! */
+	    if (cur->schemaLocation == schemaLocation)
+		return(cur);
+	}
+    }
+    return(NULL);
+}
+
+static xmlSchemaBucketPtr
+xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
+				     const xmlChar *schemaLocation,
+				     const xmlChar *targetNamespace)
+{
+    xmlSchemaBucketPtr cur;
+    xmlSchemaItemListPtr list;
+
+    list = pctxt->constructor->buckets;
+    if (list->nbItems == 0)
+	return(NULL);
+    else {
+	int i;
+	for (i = 0; i < list->nbItems; i++) {
+	    cur = (xmlSchemaBucketPtr) list->items[i];
+	    /* Pointer comparison! */
+	    if ((cur->origTargetNamespace == NULL) &&
+		(cur->schemaLocation == schemaLocation) &&
+		(cur->targetNamespace == targetNamespace))
+		return(cur);
+	}
+    }
+    return(NULL);
+}
+
+
+#define IS_BAD_SCHEMA_DOC(b) \
+    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
+
+static xmlSchemaBucketPtr
+xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
+				 const xmlChar *targetNamespace,
+				 int imported)
+{
+    xmlSchemaBucketPtr cur;
+    xmlSchemaItemListPtr list;
+
+    list = pctxt->constructor->buckets;
+    if (list->nbItems == 0)
+	return(NULL);
+    else {
+	int i;
+	for (i = 0; i < list->nbItems; i++) {
+	    cur = (xmlSchemaBucketPtr) list->items[i];
+	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
+		(cur->origTargetNamespace == targetNamespace) &&
+		((imported && cur->imported) ||
+		 ((!imported) && (!cur->imported))))
+		return(cur);
+	}
+    }
+    return(NULL);
+}
+
+static int
+xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
+		     xmlSchemaPtr schema,
+		     xmlSchemaBucketPtr bucket)
+{
+    int oldFlags;
+    xmlDocPtr oldDoc;
+    xmlNodePtr node;
+    int ret, oldErrs;
+    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
+
+    /*
+    * Save old values; reset the *main* schema.
+    * URGENT TODO: This is not good; move the per-document information
+    * to the parser. Get rid of passing the main schema to the
+    * parsing functions.
+    */
+    oldFlags = schema->flags;
+    oldDoc = schema->doc;
+    if (schema->flags != 0)
+	xmlSchemaClearSchemaDefaults(schema);
+    schema->doc = bucket->doc;
+    pctxt->schema = schema;
+    /*
+    * Keep the current target namespace on the parser *not* on the
+    * main schema.
+    */
+    pctxt->targetNamespace = bucket->targetNamespace;
+    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
+
+    if ((bucket->targetNamespace != NULL) &&
+	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
+	/*
+	* We are parsing the schema for schemas!
+	*/
+	pctxt->isS4S = 1;
+    }
+    /* Mark it as parsed, even if parsing fails. */
+    bucket->parsed++;
+    /* Compile the schema doc. */
+    node = xmlDocGetRootElement(bucket->doc);
+    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
+    if (ret != 0)
+	goto exit;
+    /* An empty schema; just get out. */
+    if (node->children == NULL)
+	goto exit;
+    oldErrs = pctxt->nberrors;
+    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
+    if (ret != 0)
+	goto exit;
+    /*
+    * TODO: Not nice, but I'm not 100% sure we will get always an error
+    * as a result of the obove functions; so better rely on pctxt->err
+    * as well.
+    */
+    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
+	ret = pctxt->err;
+	goto exit;
+    }
+
+exit:
+    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
+    /* Restore schema values. */
+    schema->doc = oldDoc;
+    schema->flags = oldFlags;
+    return(ret);
+}
+
+static int
+xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
+		     xmlSchemaPtr schema,
+		     xmlSchemaBucketPtr bucket)
+{
+    xmlSchemaParserCtxtPtr newpctxt;
+    int res = 0;
+
+    if (bucket == NULL)
+	return(0);
+    if (bucket->parsed) {
+	PERROR_INT("xmlSchemaParseNewDoc",
+	    "reparsing a schema doc");
+	return(-1);
+    }
+    if (bucket->doc == NULL) {
+	PERROR_INT("xmlSchemaParseNewDoc",
+	    "parsing a schema doc, but there's no doc");
+	return(-1);
+    }
+    if (pctxt->constructor == NULL) {
+	PERROR_INT("xmlSchemaParseNewDoc",
+	    "no constructor");
+	return(-1);
+    }
+    /* Create and init the temporary parser context. */
+    newpctxt = xmlSchemaNewParserCtxtUseDict(
+	(const char *) bucket->schemaLocation, pctxt->dict);
+    if (newpctxt == NULL)
+	return(-1);
+    newpctxt->constructor = pctxt->constructor;
+    /*
+    * TODO: Can we avoid that the parser knows about the main schema?
+    * It would be better if he knows about the current schema bucket
+    * only.
+    */
+    newpctxt->schema = schema;
+    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
+	pctxt->errCtxt);
+    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
+	pctxt->errCtxt);
+    newpctxt->counter = pctxt->counter;
+
+
+    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
+
+    /* Channel back errors and cleanup the temporary parser context. */
+    if (res != 0)
+	pctxt->err = res;
+    pctxt->nberrors += newpctxt->nberrors;
+    pctxt->counter = newpctxt->counter;
+    newpctxt->constructor = NULL;
+    /* Free the parser context. */
+    xmlSchemaFreeParserCtxt(newpctxt);
+    return(res);
+}
+
+static void
+xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
+				xmlSchemaSchemaRelationPtr rel)
+{
+    xmlSchemaSchemaRelationPtr cur = bucket->relations;
+
+    if (cur == NULL) {
+	bucket->relations = rel;
+	return;
+    }
+    while (cur->next != NULL)
+	cur = cur->next;
+    cur->next = rel;
+}
+
+
+static const xmlChar *
+xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
+			  xmlNodePtr ctxtNode)
+{
+    /*
+    * Build an absolue location URI.
+    */
+    if (location != NULL) {
+	if (ctxtNode == NULL)
+	    return(location);
+	else {
+	    xmlChar *base, *URI;
+	    const xmlChar *ret = NULL;
+
+	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
+	    if (base == NULL) {
+		URI = xmlBuildURI(location, ctxtNode->doc->URL);
+	    } else {
+		URI = xmlBuildURI(location, base);
+		xmlFree(base);
+	    }
+	    if (URI != NULL) {
+		ret = xmlDictLookup(dict, URI, -1);
+		xmlFree(URI);
+		return(ret);
+	    }
+	}
+    }
+    return(NULL);
+}
+
+
+
+/**
+ * xmlSchemaAddSchemaDoc:
+ * @pctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parse an included (and to-be-redefined) XML schema document.
+ *
+ * Returns 0 on success, a positive error code on errors and
+ *         -1 in case of an internal or API error.
+ */
+
+static int
+xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
+		int type, /* import or include or redefine */
+		const xmlChar *schemaLocation,
+		xmlDocPtr schemaDoc,
+		const char *schemaBuffer,
+		int schemaBufferLen,
+		xmlNodePtr invokingNode,
+		const xmlChar *sourceTargetNamespace,
+		const xmlChar *importNamespace,
+		xmlSchemaBucketPtr *bucket)
+{
+    const xmlChar *targetNamespace = NULL;
+    xmlSchemaSchemaRelationPtr relation = NULL;
+    xmlDocPtr doc = NULL;
+    int res = 0, err = 0, located = 0, preserveDoc = 0;
+    xmlSchemaBucketPtr bkt = NULL;
+
+    if (bucket != NULL)
+	*bucket = NULL;
+
+    switch (type) {
+	case XML_SCHEMA_SCHEMA_IMPORT:
+	case XML_SCHEMA_SCHEMA_MAIN:
+	    err = XML_SCHEMAP_SRC_IMPORT;
+	    break;
+	case XML_SCHEMA_SCHEMA_INCLUDE:
+	    err = XML_SCHEMAP_SRC_INCLUDE;
+	    break;
+	case XML_SCHEMA_SCHEMA_REDEFINE:
+	    err = XML_SCHEMAP_SRC_REDEFINE;
+	    break;
+    }
+
+
+    /* Special handling for the main schema:
+    * skip the location and relation logic and just parse the doc.
+    * We need just a bucket to be returned in this case.
+    */
+    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
+	goto doc_load;
+
+    /* Note that we expect the location to be an absulute URI. */
+    if (schemaLocation != NULL) {
+	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
+	if ((bkt != NULL) &&
+	    (pctxt->constructor->bucket == bkt)) {
+	    /* Report self-imports/inclusions/redefinitions. */
+
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
+		invokingNode, NULL,
+		"The schema must not import/include/redefine itself",
+		NULL, NULL);
+	    goto exit;
+	}
+    }
+    /*
+    * Create a relation for the graph of schemas.
+    */
+    relation = xmlSchemaSchemaRelationCreate();
+    if (relation == NULL)
+	return(-1);
+    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
+	relation);
+    relation->type = type;
+
+    /*
+    * Save the namespace import information.
+    */
+    if (WXS_IS_BUCKET_IMPMAIN(type)) {
+	relation->importNamespace = importNamespace;
+	if (schemaLocation == NULL) {
+	    /*
+	    * No location; this is just an import of the namespace.
+	    * Note that we don't assign a bucket to the relation
+	    * in this case.
+	    */
+	    goto exit;
+	}
+	targetNamespace = importNamespace;
+    }
+
+    /* Did we already fetch the doc? */
+    if (bkt != NULL) {
+	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
+	    /*
+	    * 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";
+	    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,
+	    * but the new location provided for the include/redefine
+	    * was different.
+	    */
+	    if (schemaLocation == NULL)
+		schemaLocation = BAD_CAST "in_memory_buffer";
+	    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;
+	    }
+	}
+    }
+
+    if (WXS_IS_BUCKET_IMPMAIN(type)) {
+	/*
+	* Given that the schemaLocation [attribute] is only a hint, it is open
+	* to applications to ignore all but the first <import> for a given
+	* namespace, regardless of the �actual value� of schemaLocation, but
+	* such a strategy risks missing useful information when new
+	* schemaLocations are offered.
+	*
+	* We will use the first <import> that comes with a location.
+	* Further <import>s *with* a location, will result in an error.
+	* TODO: Better would be to just report a warning here, but
+	* we'll try it this way until someone complains.
+	*
+	* Schema Document Location Strategy:
+	* 3 Based on the namespace name, identify an existing schema document,
+	* either as a resource which is an XML document or a <schema> element
+	* information item, in some local schema repository;
+	* 5 Attempt to resolve the namespace name to locate such a resource.
+	*
+	* NOTE: (3) and (5) are not supported.
+	*/
+	if (bkt != NULL) {
+	    relation->bucket = bkt;
+	    goto exit;
+	}
+	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
+	    importNamespace, 1);
+
+	if (bkt != NULL) {
+	    relation->bucket = bkt;
+	    if (bkt->schemaLocation == NULL) {
+		/* First given location of the schema; load the doc. */
+		bkt->schemaLocation = schemaLocation;
+	    } else {
+		if (!xmlStrEqual(schemaLocation,
+		    bkt->schemaLocation)) {
+		    /*
+		    * Additional location given; just skip it.
+		    * URGENT TODO: We should report a warning here.
+		    * res = XML_SCHEMAP_SRC_IMPORT;
+		    */
+		    if (schemaLocation == NULL)
+			schemaLocation = BAD_CAST "in_memory_buffer";
+
+		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+			XML_SCHEMAP_WARN_SKIP_SCHEMA,
+			invokingNode, NULL,
+			"Skipping import of schema located at '%s' for the "
+			"namespace '%s', since this namespace was already "
+			"imported with the schema located at '%s'",
+			schemaLocation, importNamespace, bkt->schemaLocation);
+		}
+		goto exit;
+	    }
+	}
+	/*
+	* No bucket + first location: load the doc and create a
+	* bucket.
+	*/
+    } else {
+	/* <include> and <redefine> */
+	if (bkt != NULL) {
+
+	    if ((bkt->origTargetNamespace == NULL) &&
+		(bkt->targetNamespace != sourceTargetNamespace)) {
+		xmlSchemaBucketPtr chamel;
+
+		/*
+		* Chameleon include/redefine: skip loading only if it was
+		* aleady build for the targetNamespace of the including
+		* schema.
+		*/
+		/*
+		* URGENT TODO: If the schema is a chameleon-include then copy
+		* the components into the including schema and modify the
+		* targetNamespace of those components, do nothing otherwise.
+		* NOTE: This is currently worked-around by compiling the
+		* chameleon for every destinct including targetNamespace; thus
+		* not performant at the moment.
+		* TODO: Check when the namespace in wildcards for chameleons
+		* needs to be converted: before we built wildcard intersections
+		* or after.
+		*   Answer: after!
+		*/
+		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
+		    schemaLocation, sourceTargetNamespace);
+		if (chamel != NULL) {
+		    /* A fitting chameleon was already parsed; NOP. */
+		    relation->bucket = chamel;
+		    goto exit;
+		}
+		/*
+		* We need to parse the chameleon again for a different
+		* targetNamespace.
+		* CHAMELEON TODO: Optimize this by only parsing the
+		* chameleon once, and then copying the components to
+		* the new targetNamespace.
+		*/
+		bkt = NULL;
+	    } else {
+		relation->bucket = bkt;
+		goto exit;
+	    }
+	}
+    }
+    if ((bkt != NULL) && (bkt->doc != NULL)) {
+	PERROR_INT("xmlSchemaAddSchemaDoc",
+	    "trying to load a schema doc, but a doc is already "
+	    "assigned to the schema bucket");
+	goto exit_failure;
+    }
+
+doc_load:
+    /*
+    * Load the document.
+    */
+    if (schemaDoc != NULL) {
+	doc = schemaDoc;
+	/* Don' free this one, since it was provided by the caller. */
+	preserveDoc = 1;
+	/* TODO: Does the context or the doc hold the location? */
+	if (schemaDoc->URL != NULL)
+	    schemaLocation = xmlDictLookup(pctxt->dict,
+		schemaDoc->URL, -1);
+        else
+	    schemaLocation = BAD_CAST "in_memory_buffer";
+    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
+	xmlParserCtxtPtr parserCtxt;
+
+	parserCtxt = xmlNewParserCtxt();
+	if (parserCtxt == NULL) {
+	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
+		"allocating a parser context", NULL);
+	    goto exit_failure;
+	}
+	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
+	    /*
+	    * TODO: Do we have to burden the schema parser dict with all
+	    * the content of the schema doc?
+	    */
+	    xmlDictFree(parserCtxt->dict);
+	    parserCtxt->dict = pctxt->dict;
+	    xmlDictReference(parserCtxt->dict);
+	}
+	if (schemaLocation != NULL) {
+	    /* Parse from file. */
+	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
+		NULL, SCHEMAS_PARSE_OPTIONS);
+	} else if (schemaBuffer != NULL) {
+	    /* Parse from memory buffer. */
+	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
+		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
+	    schemaLocation = BAD_CAST "in_memory_buffer";
+	    if (doc != NULL)
+		doc->URL = xmlStrdup(schemaLocation);
+	}
+	/*
+	* For <import>:
+	* 2.1 The referent is (a fragment of) a resource which is an
+	* XML document (see clause 1.1), which in turn corresponds to
+	* a <schema> element information item in a well-formed information
+	* set, which in turn corresponds to a valid schema.
+	* TODO: (2.1) fragments of XML documents are not supported.
+	*
+	* 2.2 The referent is a <schema> element information item in
+	* a well-formed information set, which in turn corresponds
+	* to a valid schema.
+	* TODO: (2.2) is not supported.
+	*/
+	if (doc == NULL) {
+	    xmlErrorPtr lerr;
+	    lerr = xmlGetLastError();
+	    /*
+	    * Check if this a parser error, or if the document could
+	    * just not be located.
+	    * TODO: Try to find specific error codes to react only on
+	    * localisation failures.
+	    */
+	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
+		/*
+		* We assume a parser error here.
+		*/
+		located = 1;
+		/* TODO: Error code ?? */
+		res = XML_SCHEMAP_SRC_IMPORT_2_1;
+		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
+		    invokingNode, NULL,
+		    "Failed to parse the XML resource '%s'",
+		    schemaLocation, NULL);
+	    }
+	}
+	xmlFreeParserCtxt(parserCtxt);
+	if ((doc == NULL) && located)
+	    goto exit_error;
+    } else {
+	xmlSchemaPErr(pctxt, NULL,
+	    XML_SCHEMAP_NOTHING_TO_PARSE,
+	    "No information for parsing was provided with the "
+	    "given schema parser context.\n",
+	    NULL, NULL);
+	goto exit_failure;
+    }
+    /*
+    * Preprocess the document.
+    */
+    if (doc != NULL) {
+	xmlNodePtr docElem = NULL;
+
+	located = 1;
+	docElem = xmlDocGetRootElement(doc);
+	if (docElem == NULL) {
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
+		invokingNode, NULL,
+		"The document '%s' has no document element",
+		schemaLocation, NULL);
+	    goto exit_error;
+	}
+	/*
+	* Remove all the blank text nodes.
+	*/
+	xmlSchemaCleanupDoc(pctxt, docElem);
+	/*
+	* Check the schema's top level element.
+	*/
+	if (!IS_SCHEMA(docElem, "schema")) {
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
+		invokingNode, NULL,
+		"The XML document '%s' is not a schema document",
+		schemaLocation, NULL);
+	    goto exit_error;
+	}
+	/*
+	* Note that we don't apply a type check for the
+	* targetNamespace value here.
+	*/
+	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
+	    "targetNamespace");
+    }
+
+/* after_doc_loading: */
+    if ((bkt == NULL) && located) {
+	/* Only create a bucket if the schema was located. */
+        bkt = xmlSchemaBucketCreate(pctxt, type,
+	    targetNamespace);
+	if (bkt == NULL)
+	    goto exit_failure;
+    }
+    if (bkt != NULL) {
+	bkt->schemaLocation = schemaLocation;
+	bkt->located = located;
+	if (doc != NULL) {
+	    bkt->doc = doc;
+	    bkt->targetNamespace = targetNamespace;
+	    bkt->origTargetNamespace = targetNamespace;
+	    if (preserveDoc)
+		bkt->preserveDoc = 1;
+	}
+	if (WXS_IS_BUCKET_IMPMAIN(type))
+	    bkt->imported++;
+	    /*
+	    * Add it to the graph of schemas.
+	    */
+	if (relation != NULL)
+	    relation->bucket = bkt;
+    }
+
+exit:
+    /*
+    * Return the bucket explicitely; this is needed for the
+    * main schema.
+    */
+    if (bucket != NULL)
+	*bucket = bkt;
+    return (0);
+
+exit_error:
+    if ((doc != NULL) && (! preserveDoc)) {
+	xmlFreeDoc(doc);
+	if (bkt != NULL)
+	    bkt->doc = NULL;
+    }
+    return(pctxt->err);
+
+exit_failure:
+    if ((doc != NULL) && (! preserveDoc)) {
+	xmlFreeDoc(doc);
+	if (bkt != NULL)
+	    bkt->doc = NULL;
+    }
+    return (-1);
+}
+
+/**
+ * xmlSchemaParseImport:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Import definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns 0 in case of success, a positive error code if
+ * not valid and -1 in case of an internal error.
+ */
+static int
+xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+                     xmlNodePtr node)
+{
+    xmlNodePtr child;
+    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
+    const xmlChar *thisTargetNamespace;
+    xmlAttrPtr attr;
+    int ret = 0;
+    xmlSchemaBucketPtr bucket = NULL;
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (-1);
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
+		xmlSchemaPIllegalAttrErr(pctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(pctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /*
+    * Extract and validate attributes.
+    */
+    if (xmlSchemaPValAttr(pctxt, NULL, node,
+	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+	&namespaceName) != 0) {
+	xmlSchemaPSimpleTypeErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    NULL, node,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+	    NULL, namespaceName, NULL, NULL, NULL);
+	return (pctxt->err);
+    }
+
+    if (xmlSchemaPValAttr(pctxt, NULL, node,
+	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+	&schemaLocation) != 0) {
+	xmlSchemaPSimpleTypeErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+	    NULL, node,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+	    NULL, namespaceName, NULL, NULL, NULL);
+	return (pctxt->err);
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        /*
+         * the annotation here is simply discarded ...
+	 * TODO: really?
+         */
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(pctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?)");
+    }
+    /*
+    * Apply additional constraints.
+    *
+    * Note that it is important to use the original @targetNamespace
+    * (or none at all), to rule out imports of schemas _with_ a
+    * @targetNamespace if the importing schema is a chameleon schema
+    * (with no @targetNamespace).
+    */
+    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
+    if (namespaceName != NULL) {
+	/*
+	* 1.1 If the namespace [attribute] is present, then its �actual value�
+	* must not match the �actual value� of the enclosing <schema>'s
+	* targetNamespace [attribute].
+	*/
+	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_SRC_IMPORT_1_1,
+		NULL, node,
+		"The value of the attribute 'namespace' must not match "
+		"the target namespace '%s' of the importing schema",
+		thisTargetNamespace);
+	    return (pctxt->err);
+	}
+    } else {
+	/*
+	* 1.2 If the namespace [attribute] is not present, then the enclosing
+	* <schema> must have a targetNamespace [attribute].
+	*/
+	if (thisTargetNamespace == NULL) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_SRC_IMPORT_1_2,
+		NULL, node,
+		"The attribute 'namespace' must be existent if "
+		"the importing schema has no target namespace",
+		NULL);
+	    return (pctxt->err);
+	}
+    }
+    /*
+    * Locate and acquire the schema document.
+    */
+    if (schemaLocation != NULL)
+	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
+	    schemaLocation, node);
+    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
+	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
+	namespaceName, &bucket);
+
+    if (ret != 0)
+	return(ret);
+
+    /*
+    * For <import>: "It is *not* an error for the application
+    * schema reference strategy to fail."
+    * So just don't parse if no schema document was found.
+    * Note that we will get no bucket if the schema could not be
+    * located or if there was no schemaLocation.
+    */
+    if ((bucket == NULL) && (schemaLocation != NULL)) {
+	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
+	    node, NULL,
+	    "Failed to locate a schema at location '%s'. "
+	    "Skipping the import", schemaLocation, NULL, NULL);
+    }
+
+    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
+	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
+    }
+
+    return (ret);
+}
+
+static int
+xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
+				     xmlSchemaPtr schema,
+				     xmlNodePtr node,
+				     xmlChar **schemaLocation,
+				     int type)
+{
+    xmlAttrPtr attr;
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
+	(schemaLocation == NULL))
+        return (-1);
+
+    *schemaLocation = NULL;
+    /*
+    * Check for illegal attributes.
+    * Applies for both <include> and <redefine>.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
+		xmlSchemaPIllegalAttrErr(pctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(pctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
+    /*
+    * Preliminary step, extract the URI-Reference and make an URI
+    * from the base.
+    */
+    /*
+    * Attribute "schemaLocation" is mandatory.
+    */
+    attr = xmlSchemaGetPropNode(node, "schemaLocation");
+    if (attr != NULL) {
+        xmlChar *base = NULL;
+        xmlChar *uri = NULL;
+
+	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+	    (const xmlChar **) schemaLocation) != 0)
+	    goto exit_error;
+	base = xmlNodeGetBase(node->doc, node);
+	if (base == NULL) {
+	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
+	} else {
+	    uri = xmlBuildURI(*schemaLocation, base);
+	    xmlFree(base);
+	}
+	if (uri == NULL) {
+	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
+		"could not build an URI from the schemaLocation")
+	    goto exit_failure;
+	}
+	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
+	xmlFree(uri);
+    } else {
+	xmlSchemaPMissingAttrErr(pctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "schemaLocation", NULL);
+	goto exit_error;
+    }
+    /*
+    * Report self-inclusion and self-redefinition.
+    */
+    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
+	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_SRC_REDEFINE,
+		NULL, node,
+		"The schema document '%s' cannot redefine itself.",
+		*schemaLocation);
+	} else {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_SRC_INCLUDE,
+		NULL, node,
+		"The schema document '%s' cannot include itself.",
+		*schemaLocation);
+	}
+	goto exit_error;
+    }
+
+    return(0);
+exit_error:
+    return(pctxt->err);
+exit_failure:
+    return(-1);
+}
+
+static int
+xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
+				xmlSchemaPtr schema,
+				xmlNodePtr node,
+				int type)
+{
+    xmlNodePtr child = NULL;
+    const xmlChar *schemaLocation = NULL;
+    int res = 0; /* hasRedefinitions = 0 */
+    int isChameleon = 0, wasChameleon = 0;
+    xmlSchemaBucketPtr bucket = NULL;
+
+    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (-1);
+
+    /*
+    * Parse attributes. Note that the returned schemaLocation will
+    * be already converted to an absolute URI.
+    */
+    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
+	node, (xmlChar **) (&schemaLocation), type);
+    if (res != 0)
+	return(res);
+    /*
+    * Load and add the schema document.
+    */
+    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
+	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
+    if (res != 0)
+	return(res);
+    /*
+    * If we get no schema bucket back, then this means that the schema
+    * document could not be located or was broken XML or was not
+    * a schema document.
+    */
+    if ((bucket == NULL) || (bucket->doc == NULL)) {
+	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
+	    /*
+	    * WARNING for <include>:
+	    * We will raise an error if the schema cannot be located
+	    * for inclusions, since the that was the feedback from the
+	    * schema people. I.e. the following spec piece will *not* be
+	    * satisfied:
+	    * SPEC src-include: "It is not an error for the �actual value� of the
+	    * schemaLocation [attribute] to fail to resolve it all, in which
+	    * case no corresponding inclusion is performed.
+	    * So do we need a warning report here?"
+	    */
+	    res = XML_SCHEMAP_SRC_INCLUDE;
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
+		node, NULL,
+		"Failed to load the document '%s' for inclusion",
+		schemaLocation, NULL);
+	} else {
+	    /*
+	    * NOTE: This was changed to raise an error even if no redefinitions
+	    * are specified.
+	    *
+	    * SPEC src-redefine (1)
+	    * "If there are any element information items among the [children]
+	    * other than <annotation> then the �actual value� of the
+	    * schemaLocation [attribute] must successfully resolve."
+	    * TODO: Ask the WG if a the location has always to resolve
+	    * here as well!
+	    */
+	    res = XML_SCHEMAP_SRC_REDEFINE;
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
+		node, NULL,
+		"Failed to load the document '%s' for redefinition",
+		schemaLocation, NULL);
+	}
+    } else {
+	/*
+	* Check targetNamespace sanity before parsing the new schema.
+	* TODO: Note that we won't check further content if the
+	* targetNamespace was bad.
+	*/
+	if (bucket->origTargetNamespace != NULL) {
+	    /*
+	    * SPEC src-include (2.1)
+	    * "SII has a targetNamespace [attribute], and its �actual
+	    * value� is identical to the �actual value� of the targetNamespace
+	    * [attribute] of SII� (which must have such an [attribute])."
+	    */
+	    if (pctxt->targetNamespace == NULL) {
+		xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_SRC_INCLUDE,
+		    node, NULL,
+		    "The target namespace of the included/redefined schema "
+		    "'%s' has to be absent, since the including/redefining "
+		    "schema has no target namespace",
+		    schemaLocation, NULL);
+		goto exit_error;
+	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
+		pctxt->targetNamespace)) {
+		/* TODO: Change error function. */
+		xmlSchemaPCustomErrExt(pctxt,
+		    XML_SCHEMAP_SRC_INCLUDE,
+		    NULL, node,
+		    "The target namespace '%s' of the included/redefined "
+		    "schema '%s' differs from '%s' of the "
+		    "including/redefining schema",
+		    bucket->origTargetNamespace, schemaLocation,
+		    pctxt->targetNamespace);
+		goto exit_error;
+	    }
+	} else if (pctxt->targetNamespace != NULL) {
+	    /*
+	    * Chameleons: the original target namespace will
+	    * differ from the resulting namespace.
+	    */
+	    isChameleon = 1;
+	    if (bucket->parsed &&
+		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;
+	}
+    }
+    /*
+    * Parse the schema.
+    */
+    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
+	if (isChameleon) {
+	    /* TODO: Get rid of this flag on the schema itself. */
+	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
+		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
+	    } else
+		wasChameleon = 1;
+	}
+	xmlSchemaParseNewDoc(pctxt, schema, bucket);
+	/* Restore chameleon flag. */
+	if (isChameleon && (!wasChameleon))
+	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
+	/*
+	* Parse (simpleType | complexType | group | attributeGroup))*
+	*/
+	pctxt->redefined = bucket;
+	/*
+	* How to proceed if the redefined schema was not located?
+	*/
+	pctxt->isRedefine = 1;
+	while (IS_SCHEMA(child, "annotation") ||
+	    IS_SCHEMA(child, "simpleType") ||
+	    IS_SCHEMA(child, "complexType") ||
+	    IS_SCHEMA(child, "group") ||
+	    IS_SCHEMA(child, "attributeGroup")) {
+	    if (IS_SCHEMA(child, "annotation")) {
+		/*
+		* TODO: discard or not?
+		*/
+	    } else if (IS_SCHEMA(child, "simpleType")) {
+		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
+	    } else if (IS_SCHEMA(child, "complexType")) {
+		xmlSchemaParseComplexType(pctxt, schema, child, 1);
+		/* hasRedefinitions = 1; */
+	    } else if (IS_SCHEMA(child, "group")) {
+		/* hasRedefinitions = 1; */
+		xmlSchemaParseModelGroupDefinition(pctxt,
+		    schema, child);
+	    } else if (IS_SCHEMA(child, "attributeGroup")) {
+		/* hasRedefinitions = 1; */
+		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
+		    child);
+	    }
+	    child = child->next;
+	}
+	pctxt->redefined = NULL;
+	pctxt->isRedefine = 0;
+    } else {
+	if (IS_SCHEMA(child, "annotation")) {
+	    /*
+	    * TODO: discard or not?
+	    */
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
+	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
+	    xmlSchemaPContentErr(pctxt, res,
+		NULL, node, child, NULL,
+		"(annotation | (simpleType | complexType | group | attributeGroup))*");
+	} else {
+	     xmlSchemaPContentErr(pctxt, res,
+		NULL, node, child, NULL,
+		"(annotation?)");
+	}
+    }
+    return(res);
+
+exit_error:
+    return(pctxt->err);
+}
+
+static int
+xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+                       xmlNodePtr node)
+{
+    int res;
+#ifndef ENABLE_REDEFINE
+    TODO
+    return(0);
+#endif
+    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
+	XML_SCHEMA_SCHEMA_REDEFINE);
+    if (res != 0)
+	return(res);
+    return(0);
+}
+
+static int
+xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+                       xmlNodePtr node)
+{
+    int res;
+
+    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
+	XML_SCHEMA_SCHEMA_INCLUDE);
+    if (res != 0)
+	return(res);
+    return(0);
+}
+
+/**
+ * xmlSchemaParseModelGroup:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ * @type: the "compositor" type
+ * @particleNeeded: if a a model group with a particle
+ *
+ * parse a XML schema Sequence definition.
+ * Applies parts of:
+ *   Schema Representation Constraint:
+ *     Redefinition Constraints and Semantics (src-redefine)
+ *     (6.1), (6.1.1), (6.1.2)
+ *
+ *   Schema Component Constraint:
+ *     All Group Limited (cos-all-limited) (2)
+ *     TODO: Actually this should go to component-level checks,
+ *     but is done here due to performance. Move it to an other layer
+ *     is schema construction via an API is implemented.
+ *
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error, 0 if the declaration is improper and
+ *         1 in case of success.
+ */
+static xmlSchemaTreeItemPtr
+xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+			 xmlNodePtr node, xmlSchemaTypeType type,
+			 int withParticle)
+{
+    xmlSchemaModelGroupPtr item;
+    xmlSchemaParticlePtr particle = NULL;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+    int min = 1, max = 1, isElemRef, hasRefs = 0;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /*
+    * Create a model group with the given compositor.
+    */
+    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
+    if (item == NULL)
+	return (NULL);
+
+    if (withParticle) {
+	if (type == XML_SCHEMA_TYPE_ALL) {
+	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
+	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
+	} else {
+	    /* choice + sequence */
+	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
+	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
+		"(xs:nonNegativeInteger | unbounded)");
+	}
+	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
+	/*
+	* Create a particle
+	*/
+	particle = xmlSchemaAddParticle(ctxt, node, min, max);
+	if (particle == NULL)
+	    return (NULL);
+	particle->children = (xmlSchemaTreeItemPtr) item;
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
+		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+    } else {
+	/*
+	* Check for illegal attributes.
+	*/
+	attr = node->properties;
+	while (attr != NULL) {
+	    if (attr->ns == NULL) {
+		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
+		    xmlSchemaPIllegalAttrErr(ctxt,
+			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	    attr = attr->next;
+	}
+    }
+
+    /*
+    * Extract and validate attributes.
+    */
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    if (type == XML_SCHEMA_TYPE_ALL) {
+	xmlSchemaParticlePtr part, last = NULL;
+
+	while (IS_SCHEMA(child, "element")) {
+	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
+		schema, child, &isElemRef, 0);
+	    /*
+	    * SPEC cos-all-limited (2)
+	    * "The {max occurs} of all the particles in the {particles}
+	    * of the ('all') group must be 0 or 1.
+	    */
+	    if (part != NULL) {
+		if (isElemRef)
+		    hasRefs++;
+		if (part->minOccurs > 1) {
+		    xmlSchemaPCustomErr(ctxt,
+			XML_SCHEMAP_COS_ALL_LIMITED,
+			NULL, child,
+			"Invalid value for minOccurs (must be 0 or 1)",
+			NULL);
+		    /* Reset to 1. */
+		    part->minOccurs = 1;
+		}
+		if (part->maxOccurs > 1) {
+		    xmlSchemaPCustomErr(ctxt,
+			XML_SCHEMAP_COS_ALL_LIMITED,
+			NULL, child,
+			"Invalid value for maxOccurs (must be 0 or 1)",
+			NULL);
+		    /* Reset to 1. */
+		    part->maxOccurs = 1;
+		}
+		if (last == NULL)
+		    item->children = (xmlSchemaTreeItemPtr) part;
+		else
+		    last->next = (xmlSchemaTreeItemPtr) part;
+		last = part;
+	    }
+	    child = child->next;
+	}
+	if (child != NULL) {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, (annotation?, element*)");
+	}
+    } else {
+	/* choice + sequence */
+	xmlSchemaTreeItemPtr part = NULL, last = NULL;
+
+	while ((IS_SCHEMA(child, "element")) ||
+	    (IS_SCHEMA(child, "group")) ||
+	    (IS_SCHEMA(child, "any")) ||
+	    (IS_SCHEMA(child, "choice")) ||
+	    (IS_SCHEMA(child, "sequence"))) {
+
+	    if (IS_SCHEMA(child, "element")) {
+		part = (xmlSchemaTreeItemPtr)
+		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
+		if (part && isElemRef)
+		    hasRefs++;
+	    } else if (IS_SCHEMA(child, "group")) {
+		part =
+		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+		if (part != NULL)
+		    hasRefs++;
+		/*
+		* Handle redefinitions.
+		*/
+		if (ctxt->isRedefine && ctxt->redef &&
+		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
+		    part && part->children)
+		{
+		    if ((xmlSchemaGetQNameRefName(part->children) ==
+			    ctxt->redef->refName) &&
+			(xmlSchemaGetQNameRefTargetNs(part->children) ==
+			    ctxt->redef->refTargetNs))
+		    {
+			/*
+			* SPEC src-redefine:
+			* (6.1) "If it has a <group> among its contents at
+			* some level the �actual value� of whose ref
+			* [attribute] is the same as the �actual value� of
+			* its own name attribute plus target namespace, then
+			* all of the following must be true:"
+			* (6.1.1) "It must have exactly one such group."
+			*/
+			if (ctxt->redefCounter != 0) {
+			    xmlChar *str = NULL;
+
+			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
+				"The redefining model group definition "
+				"'%s' must not contain more than one "
+				"reference to the redefined definition",
+				xmlSchemaFormatQName(&str,
+				    ctxt->redef->refTargetNs,
+				    ctxt->redef->refName),
+				NULL);
+			    FREE_AND_NULL(str)
+			    part = NULL;
+			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
+			    ((WXS_PARTICLE(part))->maxOccurs != 1))
+			{
+			    xmlChar *str = NULL;
+			    /*
+			    * SPEC src-redefine:
+			    * (6.1.2) "The �actual value� of both that
+			    * group's minOccurs and maxOccurs [attribute]
+			    * must be 1 (or �absent�).
+			    */
+			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
+				"The redefining model group definition "
+				"'%s' must not contain a reference to the "
+				"redefined definition with a "
+				"maxOccurs/minOccurs other than 1",
+				xmlSchemaFormatQName(&str,
+				    ctxt->redef->refTargetNs,
+				    ctxt->redef->refName),
+				NULL);
+			    FREE_AND_NULL(str)
+			    part = NULL;
+			}
+			ctxt->redef->reference = WXS_BASIC_CAST part;
+			ctxt->redefCounter++;
+		    }
+		}
+	    } else if (IS_SCHEMA(child, "any")) {
+		part = (xmlSchemaTreeItemPtr)
+		    xmlSchemaParseAny(ctxt, schema, child);
+	    } else if (IS_SCHEMA(child, "choice")) {
+		part = xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_CHOICE, 1);
+	    } else if (IS_SCHEMA(child, "sequence")) {
+		part = xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_SEQUENCE, 1);
+	    }
+	    if (part != NULL) {
+		if (last == NULL)
+		    item->children = part;
+		else
+		    last->next = part;
+		last = part;
+	    }
+	    child = child->next;
+	}
+	if (child != NULL) {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, (element | group | choice | sequence | any)*)");
+	}
+    }
+    if ((max == 0) && (min == 0))
+	return (NULL);
+    if (hasRefs) {
+	/*
+	* We need to resolve references.
+	*/
+	WXS_ADD_PENDING(ctxt, item);
+    }
+    if (withParticle)
+	return ((xmlSchemaTreeItemPtr) particle);
+    else
+	return ((xmlSchemaTreeItemPtr) item);
+}
+
+/**
+ * xmlSchemaParseRestriction:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Restriction definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the type definition or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                          xmlNodePtr node, xmlSchemaTypeType parentType)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    /*
+    * Extract and validate attributes.
+    */
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+    /*
+    * Attribute
+    */
+    /*
+    * Extract the base type. The "base" attribute is mandatory if inside
+    * a complex type or if redefining.
+    *
+    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
+    * among its [children]), the simple type definition which is
+    * the {content type} of the type definition �resolved� to by
+    * the �actual value� of the base [attribute]"
+    */
+    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
+	&(type->baseNs), &(type->base)) == 0)
+    {
+	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
+	    xmlSchemaPMissingAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_MISSING,
+		NULL, node, "base", NULL);
+	} else if ((ctxt->isRedefine) &&
+	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
+	{
+	    if (type->base == NULL) {
+		xmlSchemaPMissingAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_MISSING,
+		    NULL, node, "base", NULL);
+	    } else if ((! xmlStrEqual(type->base, type->name)) ||
+		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
+	    {
+		xmlChar *str1 = NULL, *str2 = NULL;
+		/*
+		* REDEFINE: SPEC src-redefine (5)
+		* "Within the [children], each <simpleType> must have a
+		* <restriction> among its [children] ... the �actual value� of
+		* whose base [attribute] must be the same as the �actual value�
+		* of its own name attribute plus target namespace;"
+		*/
+		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+		    NULL, node, "This is a redefinition, but the QName "
+		    "value '%s' of the 'base' attribute does not match the "
+		    "type's designation '%s'",
+		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
+		    xmlSchemaFormatQName(&str2, type->targetNamespace,
+			type->name), NULL);
+		FREE_AND_NULL(str1);
+		FREE_AND_NULL(str2);
+		/* Avoid confusion and erase the values. */
+		type->base = NULL;
+		type->baseNs = NULL;
+	    }
+	}
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the simple type ancestor.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
+	/*
+	* Corresponds to <simpleType><restriction><simpleType>.
+	*/
+	if (IS_SCHEMA(child, "simpleType")) {
+	    if (type->base != NULL) {
+		/*
+		* src-restriction-base-or-simpleType
+		* Either the base [attribute] or the simpleType [child] of the
+		* <restriction> element must be present, but not both.
+		*/
+		xmlSchemaPContentErr(ctxt,
+		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
+		    NULL, node, child,
+		    "The attribute 'base' and the <simpleType> child are "
+		    "mutually exclusive", NULL);
+	    } else {
+		type->baseType = (xmlSchemaTypePtr)
+		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+	    }
+	    child = child->next;
+	} else if (type->base == NULL) {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
+		NULL, node, child,
+		"Either the attribute 'base' or a <simpleType> child "
+		"must be present", NULL);
+	}
+    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+	/*
+	* Corresponds to <complexType><complexContent><restriction>...
+	* followed by:
+	*
+	* Model groups <all>, <choice> and <sequence>.
+	*/
+	if (IS_SCHEMA(child, "all")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_ALL, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "choice")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt,
+		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "sequence")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_SEQUENCE, 1);
+	    child = child->next;
+	/*
+	* Model group reference <group>.
+	*/
+	} else if (IS_SCHEMA(child, "group")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+	    /*
+	    * Note that the reference will be resolved in
+	    * xmlSchemaResolveTypeReferences();
+	    */
+	    child = child->next;
+	}
+    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
+	/*
+	* Corresponds to <complexType><simpleContent><restriction>...
+	*
+	* "1.1 the simple type definition corresponding to the <simpleType>
+	* among the [children] of <restriction> if there is one;"
+	*/
+	if (IS_SCHEMA(child, "simpleType")) {
+	    /*
+	    * We will store the to-be-restricted simple type in
+	    * type->contentTypeDef *temporarily*.
+	    */
+	    type->contentTypeDef = (xmlSchemaTypePtr)
+		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
+	    if ( type->contentTypeDef == NULL)
+		return (NULL);
+	    child = child->next;
+	}
+    }
+
+    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
+	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
+	xmlSchemaFacetPtr facet, lastfacet = NULL;
+	/*
+	* Corresponds to <complexType><simpleContent><restriction>...
+	* <simpleType><restriction>...
+	*/
+
+	/*
+	* Add the facets to the simple type ancestor.
+	*/
+	/*
+	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
+	* Simple Type Definition Schema Representation Constraint:
+	* *Single Facet Value*
+	*/
+	while ((IS_SCHEMA(child, "minInclusive")) ||
+	    (IS_SCHEMA(child, "minExclusive")) ||
+	    (IS_SCHEMA(child, "maxInclusive")) ||
+	    (IS_SCHEMA(child, "maxExclusive")) ||
+	    (IS_SCHEMA(child, "totalDigits")) ||
+	    (IS_SCHEMA(child, "fractionDigits")) ||
+	    (IS_SCHEMA(child, "pattern")) ||
+	    (IS_SCHEMA(child, "enumeration")) ||
+	    (IS_SCHEMA(child, "whiteSpace")) ||
+	    (IS_SCHEMA(child, "length")) ||
+	    (IS_SCHEMA(child, "maxLength")) ||
+	    (IS_SCHEMA(child, "minLength"))) {
+	    facet = xmlSchemaParseFacet(ctxt, schema, child);
+	    if (facet != NULL) {
+		if (lastfacet == NULL)
+		    type->facets = facet;
+		else
+		    lastfacet->next = facet;
+		lastfacet = facet;
+		lastfacet->next = NULL;
+	    }
+	    child = child->next;
+	}
+	/*
+	* Create links for derivation and validation.
+	*/
+	if (type->facets != NULL) {
+	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
+
+	    facet = type->facets;
+	    do {
+		facetLink = (xmlSchemaFacetLinkPtr)
+		    xmlMalloc(sizeof(xmlSchemaFacetLink));
+		if (facetLink == NULL) {
+		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
+		    xmlFree(facetLink);
+		    return (NULL);
+		}
+		facetLink->facet = facet;
+		facetLink->next = NULL;
+		if (lastFacetLink == NULL)
+		    type->facetSet = facetLink;
+		else
+		    lastFacetLink->next = facetLink;
+		lastFacetLink = facetLink;
+		facet = facet->next;
+	    } while (facet != NULL);
+	}
+    }
+    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
+	/*
+	* Attribute uses/declarations.
+	*/
+	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
+	    (xmlSchemaItemListPtr *) &(type->attrUses),
+	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
+	    return(NULL);
+	/*
+	* Attribute wildcard.
+	*/
+	if (IS_SCHEMA(child, "anyAttribute")) {
+	    type->attributeWildcard =
+		xmlSchemaParseAnyAttribute(ctxt, schema, child);
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"annotation?, (group | all | choice | sequence)?, "
+		"((attribute | attributeGroup)*, anyAttribute?))");
+	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
+	     xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
+		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
+		"length | minLength | maxLength | enumeration | whiteSpace | "
+		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
+	} else {
+	    /* Simple type */
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
+		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
+		"length | minLength | maxLength | enumeration | whiteSpace | "
+		"pattern)*))");
+	}
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaParseExtension:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * Parses an <extension>, which is found inside a
+ * <simpleContent> or <complexContent>.
+ * *WARNING* this interface is highly subject to change.
+ *
+ * TODO: Returns the type definition or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                        xmlNodePtr node, xmlSchemaTypeType parentType)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
+
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+
+    /*
+    * Attribute "base" - mandatory.
+    */
+    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
+	"base", &(type->baseNs), &(type->base)) == 0) &&
+	(type->base == NULL)) {
+	xmlSchemaPMissingAttrErr(ctxt,
+	    XML_SCHEMAP_S4S_ATTR_MISSING,
+	    NULL, node, "base", NULL);
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the type ancestor.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+	/*
+	* Corresponds to <complexType><complexContent><extension>... and:
+	*
+	* Model groups <all>, <choice>, <sequence> and <group>.
+	*/
+	if (IS_SCHEMA(child, "all")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema,
+		    child, XML_SCHEMA_TYPE_ALL, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "choice")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema,
+		    child, XML_SCHEMA_TYPE_CHOICE, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "sequence")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema,
+		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
+	    child = child->next;
+	} else if (IS_SCHEMA(child, "group")) {
+	    type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+	    /*
+	    * Note that the reference will be resolved in
+	    * xmlSchemaResolveTypeReferences();
+	    */
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	/*
+	* Attribute uses/declarations.
+	*/
+	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
+	    (xmlSchemaItemListPtr *) &(type->attrUses),
+	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
+	    return(NULL);
+	/*
+	* Attribute wildcard.
+	*/
+	if (IS_SCHEMA(child, "anyAttribute")) {
+	    ctxt->ctxtType->attributeWildcard =
+		xmlSchemaParseAnyAttribute(ctxt, schema, child);
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
+	    /* Complex content extension. */
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, ((group | all | choice | sequence)?, "
+		"((attribute | attributeGroup)*, anyAttribute?)))");
+	} else {
+	    /* Simple content extension. */
+	    xmlSchemaPContentErr(ctxt,
+		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+		NULL, node, child, NULL,
+		"(annotation?, ((attribute | attributeGroup)*, "
+		"anyAttribute?))");
+	}
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaParseSimpleContent:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema SimpleContent definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the type definition or NULL in case of error
+ */
+static int
+xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
+                            xmlSchemaPtr schema, xmlNodePtr node,
+			    int *hasRestrictionOrExtension)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
+	(hasRestrictionOrExtension == NULL))
+        return (-1);
+    *hasRestrictionOrExtension = 0;
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the complex type ancestor.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_MISSING,
+	    NULL, node, NULL, NULL,
+	    "(annotation?, (restriction | extension))");
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_MISSING,
+	    NULL, node, NULL, NULL,
+	    "(annotation?, (restriction | extension))");
+    }
+    if (IS_SCHEMA(child, "restriction")) {
+        xmlSchemaParseRestriction(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
+	(*hasRestrictionOrExtension) = 1;
+        child = child->next;
+    } else if (IS_SCHEMA(child, "extension")) {
+        xmlSchemaParseExtension(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
+	(*hasRestrictionOrExtension) = 1;
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child, NULL,
+	    "(annotation?, (restriction | extension))");
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaParseComplexContent:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema ComplexContent definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the type definition or NULL in case of error
+ */
+static int
+xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
+                             xmlSchemaPtr schema, xmlNodePtr node,
+			     int *hasRestrictionOrExtension)
+{
+    xmlSchemaTypePtr type;
+    xmlNodePtr child = NULL;
+    xmlAttrPtr attr;
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
+	(hasRestrictionOrExtension == NULL))
+        return (-1);
+    *hasRestrictionOrExtension = 0;
+    /* Not a component, don't create it. */
+    type = ctxt->ctxtType;
+    /*
+    * Check for illegal attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
+	    {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+
+    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+
+    /*
+    * Set the 'mixed' on the complex type ancestor.
+    */
+    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
+	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
+	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
+    }
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+	/*
+	* Add the annotation to the complex type ancestor.
+	*/
+	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
+	    xmlSchemaParseAnnotation(ctxt, child, 1));
+        child = child->next;
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_MISSING,
+	    NULL, node, NULL,
+	    NULL, "(annotation?, (restriction | extension))");
+    }
+    if (child == NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_MISSING,
+	    NULL, node, NULL,
+	    NULL, "(annotation?, (restriction | extension))");
+    }
+    if (IS_SCHEMA(child, "restriction")) {
+        xmlSchemaParseRestriction(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
+	(*hasRestrictionOrExtension) = 1;
+        child = child->next;
+    } else if (IS_SCHEMA(child, "extension")) {
+        xmlSchemaParseExtension(ctxt, schema, child,
+	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
+	(*hasRestrictionOrExtension) = 1;
+        child = child->next;
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?, (restriction | extension))");
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaParseComplexType:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @node:  a subtree containing XML Schema informations
+ *
+ * parse a XML schema Complex Type definition
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns the type definition or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                          xmlNodePtr node, int topLevel)
+{
+    xmlSchemaTypePtr type, ctxtType;
+    xmlNodePtr child = NULL;
+    const xmlChar *name = NULL;
+    xmlAttrPtr attr;
+    const xmlChar *attrValue;
+#ifdef ENABLE_NAMED_LOCALS
+    char buf[40];
+#endif
+    int final = 0, block = 0, hasRestrictionOrExtension = 0;
+
+
+    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+        return (NULL);
+
+    ctxtType = ctxt->ctxtType;
+
+    if (topLevel) {
+	attr = xmlSchemaGetPropNode(node, "name");
+	if (attr == NULL) {
+	    xmlSchemaPMissingAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
+	    return (NULL);
+	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
+	    return (NULL);
+	}
+    }
+
+    if (topLevel == 0) {
+	/*
+	* Parse as local complex type definition.
+	*/
+#ifdef ENABLE_NAMED_LOCALS
+        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
+	type = xmlSchemaAddType(ctxt, schema,
+	    XML_SCHEMA_TYPE_COMPLEX,
+	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
+	    ctxt->targetNamespace, node, 0);
+#else
+	type = xmlSchemaAddType(ctxt, schema,
+	    XML_SCHEMA_TYPE_COMPLEX,
+	    NULL, ctxt->targetNamespace, node, 0);
+#endif
+	if (type == NULL)
+	    return (NULL);
+	name = type->name;
+	type->node = node;
+	type->type = XML_SCHEMA_TYPE_COMPLEX;
+	/*
+	* TODO: We need the target namespace.
+	*/
+    } else {
+	/*
+	* Parse as global complex type definition.
+	*/
+	type = xmlSchemaAddType(ctxt, schema,
+	    XML_SCHEMA_TYPE_COMPLEX,
+	    name, ctxt->targetNamespace, node, 1);
+	if (type == NULL)
+	    return (NULL);
+	type->node = node;
+	type->type = XML_SCHEMA_TYPE_COMPLEX;
+	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
+    }
+    type->targetNamespace = ctxt->targetNamespace;
+    /*
+    * Handle attributes.
+    */
+    attr = node->properties;
+    while (attr != NULL) {
+	if (attr->ns == NULL) {
+	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
+		/*
+		* Attribute "id".
+		*/
+		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
+	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
+		/*
+		* Attribute "mixed".
+		*/
+		if (xmlSchemaPGetBoolNodeValue(ctxt,
+			NULL, (xmlNodePtr) attr))
+		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
+	    } else if (topLevel) {
+		/*
+		* Attributes of global complex type definitions.
+		*/
+		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
+		    /* Pass. */
+		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
+		    /*
+		    * Attribute "abstract".
+		    */
+		    if (xmlSchemaPGetBoolNodeValue(ctxt,
+			    NULL, (xmlNodePtr) attr))
+			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
+		    /*
+		    * Attribute "final".
+		    */
+		    attrValue = xmlSchemaGetNodeContent(ctxt,
+			(xmlNodePtr) attr);
+		    if (xmlSchemaPValAttrBlockFinal(attrValue,
+			&(type->flags),
+			-1,
+			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
+			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
+			-1, -1, -1) != 0)
+		    {
+			xmlSchemaPSimpleTypeErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+			    NULL, (xmlNodePtr) attr, NULL,
+			    "(#all | List of (extension | restriction))",
+			    attrValue, NULL, NULL, NULL);
+		    } else
+			final = 1;
+		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
+		    /*
+		    * Attribute "block".
+		    */
+		    attrValue = xmlSchemaGetNodeContent(ctxt,
+			(xmlNodePtr) attr);
+		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
+			-1,
+			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
+			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
+			-1, -1, -1) != 0) {
+			xmlSchemaPSimpleTypeErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+			    NULL, (xmlNodePtr) attr, NULL,
+			    "(#all | List of (extension | restriction)) ",
+			    attrValue, NULL, NULL, NULL);
+		    } else
+			block = 1;
+		} else {
+			xmlSchemaPIllegalAttrErr(ctxt,
+			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+		}
+	    } else {
+		xmlSchemaPIllegalAttrErr(ctxt,
+		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	    }
+	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+	    xmlSchemaPIllegalAttrErr(ctxt,
+		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
+	}
+	attr = attr->next;
+    }
+    if (! block) {
+	/*
+	* Apply default "block" values.
+	*/
+	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
+	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
+	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
+	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
+    }
+    if (! final) {
+	/*
+	* Apply default "block" values.
+	*/
+	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
+	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
+	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
+	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
+    }
+    /*
+    * And now for the children...
+    */
+    child = node->children;
+    if (IS_SCHEMA(child, "annotation")) {
+        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
+        child = child->next;
+    }
+    ctxt->ctxtType = type;
+    if (IS_SCHEMA(child, "simpleContent")) {
+	/*
+	* <complexType><simpleContent>...
+	* 3.4.3 : 2.2
+	* Specifying mixed='true' when the <simpleContent>
+	* alternative is chosen has no effect
+	*/
+	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
+        xmlSchemaParseSimpleContent(ctxt, schema, child,
+	    &hasRestrictionOrExtension);
+        child = child->next;
+    } else if (IS_SCHEMA(child, "complexContent")) {
+	/*
+	* <complexType><complexContent>...
+	*/
+	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
+        xmlSchemaParseComplexContent(ctxt, schema, child,
+	    &hasRestrictionOrExtension);
+        child = child->next;
+    } else {
+	/*
+	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
+	*
+	* SPEC
+	* "...the third alternative (neither <simpleContent> nor
+	* <complexContent>) is chosen. This case is understood as shorthand
+	* for complex content restricting the �ur-type definition�, and the
+	* details of the mappings should be modified as necessary.
+	*/
+	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
+	/*
+	* Parse model groups.
+	*/
+        if (IS_SCHEMA(child, "all")) {
+            type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_ALL, 1);
+            child = child->next;
+        } else if (IS_SCHEMA(child, "choice")) {
+            type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_CHOICE, 1);
+            child = child->next;
+        } else if (IS_SCHEMA(child, "sequence")) {
+            type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroup(ctxt, schema, child,
+		    XML_SCHEMA_TYPE_SEQUENCE, 1);
+            child = child->next;
+        } else if (IS_SCHEMA(child, "group")) {
+            type->subtypes = (xmlSchemaTypePtr)
+		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
+	    /*
+	    * Note that the reference will be resolved in
+	    * xmlSchemaResolveTypeReferences();
+	    */
+            child = child->next;
+        }
+	/*
+	* Parse attribute decls/refs.
+	*/
+        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
+	    (xmlSchemaItemListPtr *) &(type->attrUses),
+	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
+	    return(NULL);
+	/*
+	* Parse attribute wildcard.
+	*/
+	if (IS_SCHEMA(child, "anyAttribute")) {
+	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
+	    child = child->next;
+	}
+    }
+    if (child != NULL) {
+	xmlSchemaPContentErr(ctxt,
+	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
+	    NULL, node, child,
+	    NULL, "(annotation?, (simpleContent | complexContent | "
+	    "((group | all | choice | sequence)?, ((attribute | "
+	    "attributeGroup)*, anyAttribute?))))");
+    }
+    /*
+    * REDEFINE: SPEC src-redefine (5)
+    */
+    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
+	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+	    NULL, node, "This is a redefinition, thus the "
+	    "<complexType> must have a <restriction> or <extension> "
+	    "grand-child", NULL);
+    }
+    ctxt->ctxtType = ctxtType;
+    return (type);
+}
+
+/************************************************************************
+ * 									*
+ * 			Validating using Schemas			*
+ * 									*
+ ************************************************************************/
+
+/************************************************************************
+ * 									*
+ * 			Reading/Writing Schemas				*
+ * 									*
+ ************************************************************************/
+
+#if 0 /* Will be enabled if it is clear what options are needed. */
+/**
+ * xmlSchemaParserCtxtSetOptions:
+ * @ctxt:	a schema parser context
+ * @options: a combination of xmlSchemaParserOption
+ *
+ * Sets the options to be used during the parse.
+ *
+ * Returns 0 in case of success, -1 in case of an
+ * API error.
+ */
+static int
+xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
+			      int options)
+
+{
+    int i;
+
+    if (ctxt == NULL)
+	return (-1);
+    /*
+    * WARNING: Change the start value if adding to the
+    * xmlSchemaParseOption.
+    */
+    for (i = 1; i < (int) sizeof(int) * 8; i++) {
+        if (options & 1<<i) {
+	    return (-1);
+        }
+    }
+    ctxt->options = options;
+    return (0);
+}
+
+/**
+ * xmlSchemaValidCtxtGetOptions:
+ * @ctxt: a schema parser context
+ *
+ * Returns the option combination of the parser context.
+ */
+static int
+xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
+
+{
+    if (ctxt == NULL)
+	return (-1);
+    else
+	return (ctxt->options);
+}
+#endif
+
+/**
+ * xmlSchemaNewParserCtxt:
+ * @URL:  the location of the schema
+ *
+ * Create an XML Schemas parse context for that file/resource expected
+ * to contain an XML Schemas file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchemaParserCtxtPtr
+xmlSchemaNewParserCtxt(const char *URL)
+{
+    xmlSchemaParserCtxtPtr ret;
+
+    if (URL == NULL)
+        return (NULL);
+
+    ret = xmlSchemaParserCtxtCreate();
+    if (ret == NULL)
+	return(NULL);
+    ret->dict = xmlDictCreate();
+    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
+    return (ret);
+}
+
+/**
+ * xmlSchemaNewMemParserCtxt:
+ * @buffer:  a pointer to a char array containing the schemas
+ * @size:  the size of the array
+ *
+ * Create an XML Schemas parse context for that memory buffer expected
+ * to contain an XML Schemas file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchemaParserCtxtPtr
+xmlSchemaNewMemParserCtxt(const char *buffer, int size)
+{
+    xmlSchemaParserCtxtPtr ret;
+
+    if ((buffer == NULL) || (size <= 0))
+        return (NULL);
+    ret = xmlSchemaParserCtxtCreate();
+    if (ret == NULL)
+	return(NULL);
+    ret->buffer = buffer;
+    ret->size = size;
+    ret->dict = xmlDictCreate();
+    return (ret);
+}
+
+/**
+ * xmlSchemaNewDocParserCtxt:
+ * @doc:  a preparsed document tree
+ *
+ * Create an XML Schemas parse context for that document.
+ * NB. The document may be modified during the parsing process.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchemaParserCtxtPtr
+xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
+{
+    xmlSchemaParserCtxtPtr ret;
+
+    if (doc == NULL)
+      return (NULL);
+    ret = xmlSchemaParserCtxtCreate();
+    if (ret == NULL)
+	return(NULL);
+    ret->doc = doc;
+    ret->dict = xmlDictCreate();
+    /* The application has responsibility for the document */
+    ret->preserve = 1;
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaFreeParserCtxt:
+ * @ctxt:  the schema parser context
+ *
+ * Free the resources associated to the schema parser context
+ */
+void
+xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->doc != NULL && !ctxt->preserve)
+        xmlFreeDoc(ctxt->doc);
+    if (ctxt->vctxt != NULL) {
+	xmlSchemaFreeValidCtxt(ctxt->vctxt);
+    }
+    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
+	xmlSchemaConstructionCtxtFree(ctxt->constructor);
+	ctxt->constructor = NULL;
+	ctxt->ownsConstructor = 0;
+    }
+    if (ctxt->attrProhibs != NULL)
+	xmlSchemaItemListFree(ctxt->attrProhibs);
+    xmlDictFree(ctxt->dict);
+    xmlFree(ctxt);
+}
+
+/************************************************************************
+ *									*
+ *			Building the content models			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaBuildContentModelForSubstGroup:
+ *
+ * Returns 1 if nillable, 0 otherwise
+ */
+static int
+xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
+	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
+{
+    xmlAutomataStatePtr start, tmp;
+    xmlSchemaElementPtr elemDecl, member;
+    xmlSchemaSubstGroupPtr substGroup;
+    int i;
+    int ret = 0;
+
+    elemDecl = (xmlSchemaElementPtr) particle->children;
+    /*
+    * Wrap the substitution group with a CHOICE.
+    */
+    start = pctxt->state;
+    if (end == NULL)
+	end = xmlAutomataNewState(pctxt->am);
+    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
+    if (substGroup == NULL) {
+	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
+	    XML_SCHEMAP_INTERNAL,
+	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
+	    "declaration is marked having a subst. group but none "
+	    "available.\n", elemDecl->name, NULL);
+	return(0);
+    }
+    if (counter >= 0) {
+	/*
+	* NOTE that we put the declaration in, even if it's abstract.
+	* However, an error will be raised during *validation* if an element
+	* information item shall be validated against an abstract element
+	* declaration.
+	*/
+	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
+        xmlAutomataNewTransition2(pctxt->am, tmp, end,
+	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
+	/*
+	* Add subst. group members.
+	*/
+	for (i = 0; i < substGroup->members->nbItems; i++) {
+	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
+            xmlAutomataNewTransition2(pctxt->am, tmp, end,
+		               member->name, member->targetNamespace, member);
+	}
+    } else if (particle->maxOccurs == 1) {
+	/*
+	* NOTE that we put the declaration in, even if it's abstract,
+	*/
+	xmlAutomataNewEpsilon(pctxt->am,
+	    xmlAutomataNewTransition2(pctxt->am,
+	    start, NULL,
+	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
+	/*
+	* Add subst. group members.
+	*/
+	for (i = 0; i < substGroup->members->nbItems; i++) {
+	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
+	    /*
+	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
+	    *  was incorrectly used instead of xmlAutomataNewTransition2()
+	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
+	    *  section in xmlSchemaBuildAContentModel() ).
+	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
+	    *  intended for the above "counter" section originally. I.e.,
+	    *  check xs:all with subst-groups.
+	    *
+	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
+	    *	               member->name, member->targetNamespace,
+	    *		       1, 1, member);
+	    */
+	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
+		member->name, member->targetNamespace, member);
+	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
+	}
+    } else {
+	xmlAutomataStatePtr hop;
+	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+	    UNBOUNDED : particle->maxOccurs - 1;
+	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
+
+	counter =
+	    xmlAutomataNewCounter(pctxt->am, minOccurs,
+	    maxOccurs);
+	hop = xmlAutomataNewState(pctxt->am);
+
+	xmlAutomataNewEpsilon(pctxt->am,
+	    xmlAutomataNewTransition2(pctxt->am,
+	    start, NULL,
+	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
+	    hop);
+	/*
+	 * Add subst. group members.
+	 */
+	for (i = 0; i < substGroup->members->nbItems; i++) {
+	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
+	    xmlAutomataNewEpsilon(pctxt->am,
+		xmlAutomataNewTransition2(pctxt->am,
+		start, NULL,
+		member->name, member->targetNamespace, member),
+		hop);
+	}
+	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
+	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+    }
+    if (particle->minOccurs == 0) {
+	xmlAutomataNewEpsilon(pctxt->am, start, end);
+        ret = 1;
+    }
+    pctxt->state = end;
+    return(ret);
+}
+
+/**
+ * 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.
+	*/
+	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
+    } else {
+	xmlSchemaElementPtr elemDecl;
+	xmlAutomataStatePtr start;
+
+	elemDecl = (xmlSchemaElementPtr) particle->children;
+
+	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
+	    return(0);
+	if (particle->maxOccurs == 1) {
+	    start = ctxt->state;
+	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
+	} else if ((particle->maxOccurs >= UNBOUNDED) &&
+	           (particle->minOccurs < 2)) {
+	    /* Special case. */
+	    start = ctxt->state;
+	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+		elemDecl->name, elemDecl->targetNamespace, elemDecl);
+	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
+		elemDecl->name, elemDecl->targetNamespace, elemDecl);
+	} else {
+	    int counter;
+	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+			    UNBOUNDED : particle->maxOccurs - 1;
+	    int minOccurs = particle->minOccurs < 1 ?
+			    0 : particle->minOccurs - 1;
+
+	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
+	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
+	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
+		elemDecl->name, elemDecl->targetNamespace, elemDecl);
+	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
+	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
+		NULL, counter);
+	}
+	if (particle->minOccurs == 0) {
+	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
+            ret = 1;
+        }
+    }
+    return(ret);
+}
+
+/**
+ * xmlSchemaBuildAContentModel:
+ * @ctxt:  the schema parser context
+ * @particle:  the particle component
+ * @name:  the complex type's name whose content is being built
+ *
+ * Create the automaton for the {content type} of a complex type.
+ *
+ * Returns 1 if the content is nillable, 0 otherwise
+ */
+static int
+xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
+			    xmlSchemaParticlePtr particle)
+{
+    int ret = 0, tmp2;
+
+    if (particle == NULL) {
+	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
+	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(1);
+    }
+
+    switch (particle->children->type) {
+	case XML_SCHEMA_TYPE_ANY: {
+	    xmlAutomataStatePtr start, end;
+	    xmlSchemaWildcardPtr wild;
+	    xmlSchemaWildcardNsPtr ns;
+
+	    wild = (xmlSchemaWildcardPtr) particle->children;
+
+	    start = pctxt->state;
+	    end = xmlAutomataNewState(pctxt->am);
+
+	    if (particle->maxOccurs == 1) {
+		if (wild->any == 1) {
+		    /*
+		    * We need to add both transitions:
+		    *
+		    * 1. the {"*", "*"} for elements in a namespace.
+		    */
+		    pctxt->state =
+			xmlAutomataNewTransition2(pctxt->am,
+			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
+		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+		    /*
+		    * 2. the {"*"} for elements in no namespace.
+		    */
+		    pctxt->state =
+			xmlAutomataNewTransition2(pctxt->am,
+			start, NULL, BAD_CAST "*", NULL, wild);
+		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+
+		} else if (wild->nsSet != NULL) {
+		    ns = wild->nsSet;
+		    do {
+			pctxt->state = start;
+			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
+			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
+			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+			ns = ns->next;
+		    } while (ns != NULL);
+
+		} else if (wild->negNsSet != NULL) {
+		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
+			start, end, BAD_CAST "*", wild->negNsSet->value,
+			wild);
+		}
+	    } else {
+		int counter;
+		xmlAutomataStatePtr hop;
+		int maxOccurs =
+		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
+                                           particle->maxOccurs - 1;
+		int minOccurs =
+		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
+
+		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
+		hop = xmlAutomataNewState(pctxt->am);
+		if (wild->any == 1) {
+		    pctxt->state =
+			xmlAutomataNewTransition2(pctxt->am,
+			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
+		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+		    pctxt->state =
+			xmlAutomataNewTransition2(pctxt->am,
+			start, NULL, BAD_CAST "*", NULL, wild);
+		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+		} else if (wild->nsSet != NULL) {
+		    ns = wild->nsSet;
+		    do {
+			pctxt->state =
+			    xmlAutomataNewTransition2(pctxt->am,
+				start, NULL, BAD_CAST "*", ns->value, wild);
+			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+			ns = ns->next;
+		    } while (ns != NULL);
+
+		} else if (wild->negNsSet != NULL) {
+		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
+			start, hop, BAD_CAST "*", wild->negNsSet->value,
+			wild);
+		}
+		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
+		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+	    }
+	    if (particle->minOccurs == 0) {
+		xmlAutomataNewEpsilon(pctxt->am, start, end);
+                ret = 1;
+	    }
+	    pctxt->state = end;
+            break;
+	}
+        case XML_SCHEMA_TYPE_ELEMENT:
+	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
+	    break;
+        case XML_SCHEMA_TYPE_SEQUENCE:{
+            xmlSchemaTreeItemPtr sub;
+
+            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;
+
+                while (sub != NULL) {
+                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                    if (tmp2 != 1) ret = 0;
+                    sub = sub->next;
+                }
+            } else {
+                xmlAutomataStatePtr oldstate = pctxt->state;
+
+                if (particle->maxOccurs >= UNBOUNDED) {
+                    if (particle->minOccurs > 1) {
+                        xmlAutomataStatePtr tmp;
+                        int counter;
+
+                        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) {
+                            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 (ret == 1)
+                            xmlAutomataNewEpsilon(pctxt->am,
+                                                oldstate, pctxt->state);
+
+                    } else {
+                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+                            oldstate, NULL);
+                        oldstate = pctxt->state;
+
+                        sub = particle->children->children;
+                        while (sub != NULL) {
+                            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);
+                            ret = 1;
+                        }
+                    }
+                } else if ((particle->maxOccurs > 1)
+                           || (particle->minOccurs > 1)) {
+                    xmlAutomataStatePtr tmp;
+                    int counter;
+
+                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+                        oldstate, NULL);
+                    oldstate = pctxt->state;
+
+                    counter = xmlAutomataNewCounter(pctxt->am,
+                        particle->minOccurs - 1,
+                        particle->maxOccurs - 1);
+
+                    sub = particle->children->children;
+                    while (sub != NULL) {
+                        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 {
+                    sub = particle->children->children;
+                    while (sub != NULL) {
+                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                        if (tmp2 != 1) ret = 0;
+                        sub = sub->next;
+                    }
+                    if (particle->minOccurs == 0) {
+                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
+                                              pctxt->state);
+                        ret = 1;
+                    }
+                }
+            }
+            break;
+        }
+        case XML_SCHEMA_TYPE_CHOICE:{
+            xmlSchemaTreeItemPtr sub;
+            xmlAutomataStatePtr start, end;
+
+            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;
+                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                    if (tmp2 == 1) ret = 1;
+                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+                    sub = sub->next;
+                }
+            } 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
+	    * it was empty, thus was not substituted for the containing
+	    * model group. Just do nothing in this case.
+	    * 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(ret);
+    }
+    return(ret);
+}
+
+/**
+ * xmlSchemaBuildContentModel:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ * @name:  the element name
+ *
+ * Builds the content model of the complex type.
+ */
+static void
+xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
+			   xmlSchemaParserCtxtPtr ctxt)
+{
+    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
+	(type->contModel != NULL) ||
+	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
+	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
+	return;
+
+#ifdef DEBUG_CONTENT
+    xmlGenericError(xmlGenericErrorContext,
+                    "Building content model for %s\n", name);
+#endif
+    ctxt->am = NULL;
+    ctxt->am = xmlNewAutomata();
+    if (ctxt->am == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+	    "Cannot create automata for complex type %s\n", type->name);
+        return;
+    }
+    ctxt->state = xmlAutomataGetInitState(ctxt->am);
+    /*
+    * Build the automaton.
+    */
+    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
+    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
+    type->contModel = xmlAutomataCompile(ctxt->am);
+    if (type->contModel == NULL) {
+        xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_INTERNAL,
+	    WXS_BASIC_CAST type, type->node,
+	    "Failed to compile the content model", NULL);
+    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
+        xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_NOT_DETERMINISTIC,
+	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
+	    WXS_BASIC_CAST type, type->node,
+	    "The content model is not determinist", NULL);
+    } else {
+#ifdef DEBUG_CONTENT_REGEXP
+        xmlGenericError(xmlGenericErrorContext,
+                        "Content model of %s:\n", type->name);
+        xmlRegexpPrint(stderr, type->contModel);
+#endif
+    }
+    ctxt->state = NULL;
+    xmlFreeAutomata(ctxt->am);
+    ctxt->am = NULL;
+}
+
+/**
+ * xmlSchemaResolveElementReferences:
+ * @elem:  the schema element context
+ * @ctxt:  the schema parser context
+ *
+ * Resolves the references of an element declaration
+ * or particle, which has an element declaration as it's
+ * term.
+ */
+static void
+xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
+				  xmlSchemaParserCtxtPtr ctxt)
+{
+    if ((ctxt == NULL) || (elemDecl == NULL) ||
+	((elemDecl != NULL) &&
+	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
+        return;
+    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
+
+    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
+	xmlSchemaTypePtr type;
+
+	/* (type definition) ... otherwise the type definition �resolved�
+	* to by the �actual value� of the type [attribute] ...
+	*/
+	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
+	    elemDecl->namedTypeNs);
+	if (type == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt,
+		XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST elemDecl, elemDecl->node,
+		"type", elemDecl->namedType, elemDecl->namedTypeNs,
+		XML_SCHEMA_TYPE_BASIC, "type definition");
+	} else
+	    elemDecl->subtypes = type;
+    }
+    if (elemDecl->substGroup != NULL) {
+	xmlSchemaElementPtr substHead;
+
+	/*
+	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
+	* substitutionGroup?
+	*/
+	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
+	    elemDecl->substGroupNs);
+	if (substHead == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt,
+		XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST elemDecl, NULL,
+		"substitutionGroup", elemDecl->substGroup,
+		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
+	} else {
+	    xmlSchemaResolveElementReferences(substHead, ctxt);
+	    /*
+	    * Set the "substitution group affiliation".
+	    * NOTE that now we use the "refDecl" field for this.
+	    */
+	    WXS_SUBST_HEAD(elemDecl) = substHead;
+	    /*
+	    * The type definitions is set to:
+	    * SPEC "...the {type definition} of the element
+	    * declaration �resolved� to by the �actual value�
+	    * of the substitutionGroup [attribute], if present"
+	    */
+	    if (elemDecl->subtypes == NULL)
+		elemDecl->subtypes = substHead->subtypes;
+	}
+    }
+    /*
+    * SPEC "The definition of anyType serves as the default type definition
+    * for element declarations whose XML representation does not specify one."
+    */
+    if ((elemDecl->subtypes == NULL) &&
+	(elemDecl->namedType == NULL) &&
+	(elemDecl->substGroup == NULL))
+	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+}
+
+/**
+ * xmlSchemaResolveUnionMemberTypes:
+ * @ctxt:  the schema parser context
+ * @type:  the schema simple type definition
+ *
+ * Checks and builds the "member type definitions" property of the union
+ * simple type. This handles part (1), part (2) is done in
+ * xmlSchemaFinishMemberTypeDefinitionsProperty()
+ *
+ * Returns -1 in case of an internal error, 0 otherwise.
+ */
+static int
+xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
+				 xmlSchemaTypePtr type)
+{
+
+    xmlSchemaTypeLinkPtr link, lastLink, newLink;
+    xmlSchemaTypePtr memberType;
+
+    /*
+    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
+    * define the explicit members as the type definitions �resolved�
+    * to by the items in the �actual value� of the memberTypes [attribute],
+    * if any, followed by the type definitions corresponding to the
+    * <simpleType>s among the [children] of <union>, if any."
+    */
+    /*
+    * Resolve references.
+    */
+    link = type->memberTypes;
+    lastLink = NULL;
+    while (link != NULL) {
+	const xmlChar *name, *nsName;
+
+	name = ((xmlSchemaQNameRefPtr) link->type)->name;
+	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
+
+	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
+	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
+	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST type, type->node, "memberTypes",
+		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
+	    /*
+	    * Remove the member type link.
+	    */
+	    if (lastLink == NULL)
+		type->memberTypes = link->next;
+	    else
+		lastLink->next = link->next;
+	    newLink = link;
+	    link = link->next;
+	    xmlFree(newLink);
+	} else {
+	    link->type = memberType;
+	    lastLink = link;
+	    link = link->next;
+	}
+    }
+    /*
+    * Add local simple types,
+    */
+    memberType = type->subtypes;
+    while (memberType != NULL) {
+	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
+	if (link == NULL) {
+	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
+	    return (-1);
+	}
+	link->type = memberType;
+	link->next = NULL;
+	if (lastLink == NULL)
+	    type->memberTypes = link;
+	else
+	    lastLink->next = link;
+	lastLink = link;
+	memberType = memberType->next;
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaIsDerivedFromBuiltInType:
+ * @ctxt:  the schema parser context
+ * @type:  the type definition
+ * @valType: the value type
+ *
+ *
+ * Returns 1 if the type has the given value type, or
+ * is derived from such a type.
+ */
+static int
+xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
+{
+    if (type == NULL)
+	return (0);
+    if (WXS_IS_COMPLEX(type))
+	return (0);
+    if (type->type == XML_SCHEMA_TYPE_BASIC) {
+	if (type->builtInType == valType)
+	    return(1);
+	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
+	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
+	    return (0);
+	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
+    }
+    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
+}
+
+#if 0
+/**
+ * xmlSchemaIsDerivedFromBuiltInType:
+ * @ctxt:  the schema parser context
+ * @type:  the type definition
+ * @valType: the value type
+ *
+ *
+ * Returns 1 if the type has the given value type, or
+ * is derived from such a type.
+ */
+static int
+xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
+{
+    if (type == NULL)
+	return (0);
+    if (WXS_IS_COMPLEX(type))
+	return (0);
+    if (type->type == XML_SCHEMA_TYPE_BASIC) {
+	if (type->builtInType == valType)
+	    return(1);
+	return (0);
+    } else
+	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
+
+    return (0);
+}
+
+static xmlSchemaTypePtr
+xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
+{
+    if (type == NULL)
+	return (NULL);
+    if (WXS_IS_COMPLEX(type))
+	return (NULL);
+    if (type->type == XML_SCHEMA_TYPE_BASIC)
+	return(type);
+    return(xmlSchemaQueryBuiltInType(type->subtypes));
+}
+#endif
+
+/**
+ * xmlSchemaGetPrimitiveType:
+ * @type:  the simpleType definition
+ *
+ * Returns the primitive type of the given type or
+ * NULL in case of error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
+{
+
+    while (type != NULL) {
+	/*
+	* Note that anySimpleType is actually not a primitive type
+	* but we need that here.
+	*/
+	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
+	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
+	    return (type);
+	type = type->baseType;
+    }
+
+    return (NULL);
+}
+
+#if 0
+/**
+ * xmlSchemaGetBuiltInTypeAncestor:
+ * @type:  the simpleType definition
+ *
+ * Returns the primitive type of the given type or
+ * NULL in case of error.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
+{
+    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
+	return (0);
+    while (type != NULL) {
+	if (type->type == XML_SCHEMA_TYPE_BASIC)
+	    return (type);
+	type = type->baseType;
+    }
+
+    return (NULL);
+}
+#endif
+
+/**
+ * xmlSchemaCloneWildcardNsConstraints:
+ * @ctxt:  the schema parser context
+ * @dest:  the destination wildcard
+ * @source: the source wildcard
+ *
+ * Clones the namespace constraints of source
+ * and assignes them to dest.
+ * Returns -1 on internal error, 0 otherwise.
+ */
+static int
+xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
+				    xmlSchemaWildcardPtr dest,
+				    xmlSchemaWildcardPtr source)
+{
+    xmlSchemaWildcardNsPtr cur, tmp, last;
+
+    if ((source == NULL) || (dest == NULL))
+	return(-1);
+    dest->any = source->any;
+    cur = source->nsSet;
+    last = NULL;
+    while (cur != NULL) {
+	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
+	if (tmp == NULL)
+	    return(-1);
+	tmp->value = cur->value;
+	if (last == NULL)
+	    dest->nsSet = tmp;
+	else
+	    last->next = tmp;
+	last = tmp;
+	cur = cur->next;
+    }
+    if (dest->negNsSet != NULL)
+	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
+    if (source->negNsSet != NULL) {
+	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+	if (dest->negNsSet == NULL)
+	    return(-1);
+	dest->negNsSet->value = source->negNsSet->value;
+    } else
+	dest->negNsSet = NULL;
+    return(0);
+}
+
+/**
+ * xmlSchemaUnionWildcards:
+ * @ctxt:  the schema parser context
+ * @completeWild:  the first wildcard
+ * @curWild: the second wildcard
+ *
+ * Unions the namespace constraints of the given wildcards.
+ * @completeWild will hold the resulting union.
+ * Returns a positive error code on failure, -1 in case of an
+ * internal error, 0 otherwise.
+ */
+static int
+xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
+			    xmlSchemaWildcardPtr completeWild,
+			    xmlSchemaWildcardPtr curWild)
+{
+    xmlSchemaWildcardNsPtr cur, curB, tmp;
+
+    /*
+    * 1 If O1 and O2 are the same value, then that value must be the
+    * value.
+    */
+    if ((completeWild->any == curWild->any) &&
+	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
+	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
+
+	if ((completeWild->negNsSet == NULL) ||
+	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
+
+	    if (completeWild->nsSet != NULL) {
+		int found = 0;
+
+		/*
+		* Check equality of sets.
+		*/
+		cur = completeWild->nsSet;
+		while (cur != NULL) {
+		    found = 0;
+		    curB = curWild->nsSet;
+		    while (curB != NULL) {
+			if (cur->value == curB->value) {
+			    found = 1;
+			    break;
+			}
+			curB = curB->next;
+		    }
+		    if (!found)
+			break;
+		    cur = cur->next;
+		}
+		if (found)
+		    return(0);
+	    } else
+		return(0);
+	}
+    }
+    /*
+    * 2 If either O1 or O2 is any, then any must be the value
+    */
+    if (completeWild->any != curWild->any) {
+	if (completeWild->any == 0) {
+	    completeWild->any = 1;
+	    if (completeWild->nsSet != NULL) {
+		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		completeWild->nsSet = NULL;
+	    }
+	    if (completeWild->negNsSet != NULL) {
+		xmlFree(completeWild->negNsSet);
+		completeWild->negNsSet = NULL;
+	    }
+	}
+	return (0);
+    }
+    /*
+    * 3 If both O1 and O2 are sets of (namespace names or �absent�),
+    * then the union of those sets must be the value.
+    */
+    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
+	int found;
+	xmlSchemaWildcardNsPtr start;
+
+	cur = curWild->nsSet;
+	start = completeWild->nsSet;
+	while (cur != NULL) {
+	    found = 0;
+	    curB = start;
+	    while (curB != NULL) {
+		if (cur->value == curB->value) {
+		    found = 1;
+		    break;
+		}
+		curB = curB->next;
+	    }
+	    if (!found) {
+		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
+		if (tmp == NULL)
+		    return (-1);
+		tmp->value = cur->value;
+		tmp->next = completeWild->nsSet;
+		completeWild->nsSet = tmp;
+	    }
+	    cur = cur->next;
+	}
+
+	return(0);
+    }
+    /*
+    * 4 If the two are negations of different values (namespace names
+    * or �absent�), then a pair of not and �absent� must be the value.
+    */
+    if ((completeWild->negNsSet != NULL) &&
+	(curWild->negNsSet != NULL) &&
+	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
+	completeWild->negNsSet->value = NULL;
+
+	return(0);
+    }
+    /*
+     * 5.
+     */
+    if (((completeWild->negNsSet != NULL) &&
+	(completeWild->negNsSet->value != NULL) &&
+	(curWild->nsSet != NULL)) ||
+	((curWild->negNsSet != NULL) &&
+	(curWild->negNsSet->value != NULL) &&
+	(completeWild->nsSet != NULL))) {
+
+	int nsFound, absentFound = 0;
+
+	if (completeWild->nsSet != NULL) {
+	    cur = completeWild->nsSet;
+	    curB = curWild->negNsSet;
+	} else {
+	    cur = curWild->nsSet;
+	    curB = completeWild->negNsSet;
+	}
+	nsFound = 0;
+	while (cur != NULL) {
+	    if (cur->value == NULL)
+		absentFound = 1;
+	    else if (cur->value == curB->value)
+		nsFound = 1;
+	    if (nsFound && absentFound)
+		break;
+	    cur = cur->next;
+	}
+
+	if (nsFound && absentFound) {
+	    /*
+	    * 5.1 If the set S includes both the negated namespace
+	    * name and �absent�, then any must be the value.
+	    */
+	    completeWild->any = 1;
+	    if (completeWild->nsSet != NULL) {
+		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		completeWild->nsSet = NULL;
+	    }
+	    if (completeWild->negNsSet != NULL) {
+		xmlFree(completeWild->negNsSet);
+		completeWild->negNsSet = NULL;
+	    }
+	} else if (nsFound && (!absentFound)) {
+	    /*
+	    * 5.2 If the set S includes the negated namespace name
+	    * but not �absent�, then a pair of not and �absent� must
+	    * be the value.
+	    */
+	    if (completeWild->nsSet != NULL) {
+		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		completeWild->nsSet = NULL;
+	    }
+	    if (completeWild->negNsSet == NULL) {
+		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+		if (completeWild->negNsSet == NULL)
+		    return (-1);
+	    }
+	    completeWild->negNsSet->value = NULL;
+	} else if ((!nsFound) && absentFound) {
+	    /*
+	    * 5.3 If the set S includes �absent� but not the negated
+	    * namespace name, then the union is not expressible.
+	    */
+	    xmlSchemaPErr(ctxt, completeWild->node,
+		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
+		"The union of the wilcard is not expressible.\n",
+		NULL, NULL);
+	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
+	} else if ((!nsFound) && (!absentFound)) {
+	    /*
+	    * 5.4 If the set S does not include either the negated namespace
+	    * name or �absent�, then whichever of O1 or O2 is a pair of not
+	    * and a namespace name must be the value.
+	    */
+	    if (completeWild->negNsSet == NULL) {
+		if (completeWild->nsSet != NULL) {
+		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		    completeWild->nsSet = NULL;
+		}
+		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+		if (completeWild->negNsSet == NULL)
+		    return (-1);
+		completeWild->negNsSet->value = curWild->negNsSet->value;
+	    }
+	}
+	return (0);
+    }
+    /*
+     * 6.
+     */
+    if (((completeWild->negNsSet != NULL) &&
+	(completeWild->negNsSet->value == NULL) &&
+	(curWild->nsSet != NULL)) ||
+	((curWild->negNsSet != NULL) &&
+	(curWild->negNsSet->value == NULL) &&
+	(completeWild->nsSet != NULL))) {
+
+	if (completeWild->nsSet != NULL) {
+	    cur = completeWild->nsSet;
+	} else {
+	    cur = curWild->nsSet;
+	}
+	while (cur != NULL) {
+	    if (cur->value == NULL) {
+		/*
+		* 6.1 If the set S includes �absent�, then any must be the
+		* value.
+		*/
+		completeWild->any = 1;
+		if (completeWild->nsSet != NULL) {
+		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		    completeWild->nsSet = NULL;
+		}
+		if (completeWild->negNsSet != NULL) {
+		    xmlFree(completeWild->negNsSet);
+		    completeWild->negNsSet = NULL;
+		}
+		return (0);
+	    }
+	    cur = cur->next;
+	}
+	if (completeWild->negNsSet == NULL) {
+	    /*
+	    * 6.2 If the set S does not include �absent�, then a pair of not
+	    * and �absent� must be the value.
+	    */
+	    if (completeWild->nsSet != NULL) {
+		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
+		completeWild->nsSet = NULL;
+	    }
+	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
+	    if (completeWild->negNsSet == NULL)
+		return (-1);
+	    completeWild->negNsSet->value = NULL;
+	}
+	return (0);
+    }
+    return (0);
+
+}
+
+/**
+ * xmlSchemaIntersectWildcards:
+ * @ctxt:  the schema parser context
+ * @completeWild:  the first wildcard
+ * @curWild: the second wildcard
+ *
+ * Intersects the namespace constraints of the given wildcards.
+ * @completeWild will hold the resulting intersection.
+ * Returns a positive error code on failure, -1 in case of an
+ * internal error, 0 otherwise.
+ */
+static int
+xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
+			    xmlSchemaWildcardPtr completeWild,
+			    xmlSchemaWildcardPtr curWild)
+{
+    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
+
+    /*
+    * 1 If O1 and O2 are the same value, then that value must be the
+    * value.
+    */
+    if ((completeWild->any == curWild->any) &&
+	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
+	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
+
+	if ((completeWild->negNsSet == NULL) ||
+	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
+
+	    if (completeWild->nsSet != NULL) {
+		int found = 0;
+
+		/*
+		* Check equality of sets.
+		*/
+		cur = completeWild->nsSet;
+		while (cur != NULL) {
+		    found = 0;
+		    curB = curWild->nsSet;
+		    while (curB != NULL) {
+			if (cur->value == curB->value) {
+			    found = 1;
+			    break;
+			}
+			curB = curB->next;
+		    }
+		    if (!found)
+			break;
+		    cur = cur->next;
+		}
+		if (found)
+		    return(0);
+	    } else
+		return(0);
+	}
+    }
+    /*
+    * 2 If either O1 or O2 is any, then the other must be the value.
+    */
+    if ((completeWild->any != curWild->any) && (completeWild->any)) {
+	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
+	    return(-1);
+	return(0);
+    }
+    /*
+    * 3 If either O1 or O2 is a pair of not and a value (a namespace
+    * name or �absent�) and the other is a set of (namespace names or
+    * �absent�), then that set, minus the negated value if it was in
+    * the set, minus �absent� if it was in the set, must be the value.
+    */
+    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
+	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
+	const xmlChar *neg;
+
+	if (completeWild->nsSet == NULL) {
+	    neg = completeWild->negNsSet->value;
+	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
+		return(-1);
+	} else
+	    neg = curWild->negNsSet->value;
+	/*
+	* Remove absent and negated.
+	*/
+	prev = NULL;
+	cur = completeWild->nsSet;
+	while (cur != NULL) {
+	    if (cur->value == NULL) {
+		if (prev == NULL)
+		    completeWild->nsSet = cur->next;
+		else
+		    prev->next = cur->next;
+		xmlFree(cur);
+		break;
+	    }
+	    prev = cur;
+	    cur = cur->next;
+	}
+	if (neg != NULL) {
+	    prev = NULL;
+	    cur = completeWild->nsSet;
+	    while (cur != NULL) {
+		if (cur->value == neg) {
+		    if (prev == NULL)
+			completeWild->nsSet = cur->next;
+		    else
+			prev->next = cur->next;
+		    xmlFree(cur);
+		    break;
+		}
+		prev = cur;
+		cur = cur->next;
+	    }
+	}
+
+	return(0);
+    }
+    /*
+    * 4 If both O1 and O2 are sets of (namespace names or �absent�),
+    * then the intersection of those sets must be the value.
+    */
+    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
+	int found;
+
+	cur = completeWild->nsSet;
+	prev = NULL;
+	while (cur != NULL) {
+	    found = 0;
+	    curB = curWild->nsSet;
+	    while (curB != NULL) {
+		if (cur->value == curB->value) {
+		    found = 1;
+		    break;
+		}
+		curB = curB->next;
+	    }
+	    if (!found) {
+		if (prev == NULL)
+		    completeWild->nsSet = cur->next;
+		else
+		    prev->next = cur->next;
+		tmp = cur->next;
+		xmlFree(cur);
+		cur = tmp;
+		continue;
+	    }
+	    prev = cur;
+	    cur = cur->next;
+	}
+
+	return(0);
+    }
+    /* 5 If the two are negations of different namespace names,
+    * then the intersection is not expressible
+    */
+    if ((completeWild->negNsSet != NULL) &&
+	(curWild->negNsSet != NULL) &&
+	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
+	(completeWild->negNsSet->value != NULL) &&
+	(curWild->negNsSet->value != NULL)) {
+
+	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
+	    "The intersection of the wilcard is not expressible.\n",
+	    NULL, NULL);
+	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
+    }
+    /*
+    * 6 If the one is a negation of a namespace name and the other
+    * is a negation of �absent�, then the one which is the negation
+    * of a namespace name must be the value.
+    */
+    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
+	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
+	(completeWild->negNsSet->value == NULL)) {
+	completeWild->negNsSet->value =  curWild->negNsSet->value;
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaIsWildcardNsConstraintSubset:
+ * @ctxt:  the schema parser context
+ * @sub:  the first wildcard
+ * @super: the second wildcard
+ *
+ * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
+ *
+ * Returns 0 if the namespace constraint of @sub is an intensional
+ * subset of @super, 1 otherwise.
+ */
+static int
+xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
+			  xmlSchemaWildcardPtr super)
+{
+    /*
+    * 1 super must be any.
+    */
+    if (super->any)
+	return (0);
+    /*
+    * 2.1 sub must be a pair of not and a namespace name or �absent�.
+    * 2.2 super must be a pair of not and the same value.
+    */
+    if ((sub->negNsSet != NULL) &&
+	(super->negNsSet != NULL) &&
+	(sub->negNsSet->value == super->negNsSet->value))
+	return (0);
+    /*
+    * 3.1 sub must be a set whose members are either namespace names or �absent�.
+    */
+    if (sub->nsSet != NULL) {
+	/*
+	* 3.2.1 super must be the same set or a superset thereof.
+	*/
+	if (super->nsSet != NULL) {
+	    xmlSchemaWildcardNsPtr cur, curB;
+	    int found = 0;
+
+	    cur = sub->nsSet;
+	    while (cur != NULL) {
+		found = 0;
+		curB = super->nsSet;
+		while (curB != NULL) {
+		    if (cur->value == curB->value) {
+			found = 1;
+			break;
+		    }
+		    curB = curB->next;
+		}
+		if (!found)
+		    return (1);
+		cur = cur->next;
+	    }
+	    if (found)
+		return (0);
+	} else if (super->negNsSet != NULL) {
+	    xmlSchemaWildcardNsPtr cur;
+	    /*
+	    * 3.2.2 super must be a pair of not and a namespace name or
+	    * �absent� and that value must not be in sub's set.
+	    */
+	    cur = sub->nsSet;
+	    while (cur != NULL) {
+		if (cur->value == super->negNsSet->value)
+		    return (1);
+		cur = cur->next;
+	    }
+	    return (0);
+	}
+    }
+    return (1);
+}
+
+static int
+xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
+				     int *fixed,
+				     const xmlChar **value,
+				     xmlSchemaValPtr *val)
+{
+    *fixed = 0;
+    *value = NULL;
+    if (val != 0)
+	*val = NULL;
+
+    if (attruse->defValue != NULL) {
+	*value = attruse->defValue;
+	if (val != NULL)
+	    *val = attruse->defVal;
+	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
+	    *fixed = 1;
+	return(1);
+    } else if ((attruse->attrDecl != NULL) &&
+	(attruse->attrDecl->defValue != NULL)) {
+	*value = attruse->attrDecl->defValue;
+	if (val != NULL)
+	    *val = attruse->attrDecl->defVal;
+	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
+	    *fixed = 1;
+	return(1);
+    }
+    return(0);
+}
+/**
+ * xmlSchemaCheckCVCWildcardNamespace:
+ * @wild:  the wildcard
+ * @ns:  the namespace
+ *
+ * Validation Rule: Wildcard allows Namespace Name
+ * (cvc-wildcard-namespace)
+ *
+ * Returns 0 if the given namespace matches the wildcard,
+ * 1 otherwise and -1 on API errors.
+ */
+static int
+xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
+				   const xmlChar* ns)
+{
+    if (wild == NULL)
+	return(-1);
+
+    if (wild->any)
+	return(0);
+    else if (wild->nsSet != NULL) {
+	xmlSchemaWildcardNsPtr cur;
+
+	cur = wild->nsSet;
+	while (cur != NULL) {
+	    if (xmlStrEqual(cur->value, ns))
+		return(0);
+	    cur = cur->next;
+	}
+    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
+	(!xmlStrEqual(wild->negNsSet->value, ns)))
+	return(0);
+
+    return(1);
+}
+
+#define XML_SCHEMA_ACTION_DERIVE 0
+#define XML_SCHEMA_ACTION_REDEFINE 1
+
+#define WXS_ACTION_STR(a) \
+((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
+
+/*
+* Schema Component Constraint:
+*   Derivation Valid (Restriction, Complex)
+*   derivation-ok-restriction (2) - (4)
+*
+* ATTENTION:
+* In XML Schema 1.1 this will be:
+* Validation Rule:
+*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
+*
+*/
+static int
+xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
+				       int action,
+				       xmlSchemaBasicItemPtr item,
+				       xmlSchemaBasicItemPtr baseItem,
+				       xmlSchemaItemListPtr uses,
+				       xmlSchemaItemListPtr baseUses,
+				       xmlSchemaWildcardPtr wild,
+				       xmlSchemaWildcardPtr baseWild)
+{
+    xmlSchemaAttributeUsePtr cur = NULL, bcur;
+    int i, j, found; /* err = 0; */
+    const xmlChar *bEffValue;
+    int effFixed;
+
+    if (uses != NULL) {
+	for (i = 0; i < uses->nbItems; i++) {
+	    cur = uses->items[i];
+	    found = 0;
+	    if (baseUses == NULL)
+		goto not_found;
+	    for (j = 0; j < baseUses->nbItems; j++) {
+		bcur = baseUses->items[j];
+		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
+			WXS_ATTRUSE_DECL_NAME(bcur)) &&
+		    (WXS_ATTRUSE_DECL_TNS(cur) ==
+			WXS_ATTRUSE_DECL_TNS(bcur)))
+		{
+		    /*
+		    * (2.1) "If there is an attribute use in the {attribute
+		    * uses} of the {base type definition} (call this B) whose
+		    * {attribute declaration} has the same {name} and {target
+		    * namespace}, then  all of the following must be true:"
+		    */
+		    found = 1;
+
+		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
+			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
+		    {
+			xmlChar *str = NULL;
+			/*
+			* (2.1.1) "one of the following must be true:"
+			* (2.1.1.1) "B's {required} is false."
+			* (2.1.1.2) "R's {required} is true."
+			*/
+			xmlSchemaPAttrUseErr4(pctxt,
+			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
+			    WXS_ITEM_NODE(item), item, cur,
+			    "The 'optional' attribute use is inconsistent "
+			    "with the corresponding 'required' attribute use of "
+			    "the %s %s",
+			    WXS_ACTION_STR(action),
+			    xmlSchemaGetComponentDesignation(&str, baseItem),
+			    NULL, NULL);
+			FREE_AND_NULL(str);
+			/* err = pctxt->err; */
+		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
+			WXS_ATTRUSE_TYPEDEF(cur),
+			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
+		    {
+			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
+
+			/*
+			* SPEC (2.1.2) "R's {attribute declaration}'s
+			* {type definition} must be validly derived from
+			* B's {type definition} given the empty set as
+			* defined in Type Derivation OK (Simple) (�3.14.6)."
+			*/
+			xmlSchemaPAttrUseErr4(pctxt,
+			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
+			    WXS_ITEM_NODE(item), item, cur,
+			    "The attribute declaration's %s "
+			    "is not validly derived from "
+			    "the corresponding %s of the "
+			    "attribute declaration in the %s %s",
+			    xmlSchemaGetComponentDesignation(&strA,
+				WXS_ATTRUSE_TYPEDEF(cur)),
+			    xmlSchemaGetComponentDesignation(&strB,
+				WXS_ATTRUSE_TYPEDEF(bcur)),
+			    WXS_ACTION_STR(action),
+			    xmlSchemaGetComponentDesignation(&strC, baseItem));
+			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
+			FREE_AND_NULL(strA);
+			FREE_AND_NULL(strB);
+			FREE_AND_NULL(strC);
+			/* err = pctxt->err; */
+		    } else {
+			/*
+			* 2.1.3 [Definition:]  Let the effective value
+			* constraint of an attribute use be its {value
+			* constraint}, if present, otherwise its {attribute
+			* declaration}'s {value constraint} .
+			*/
+			xmlSchemaGetEffectiveValueConstraint(bcur,
+			    &effFixed, &bEffValue, NULL);
+			/*
+			* 2.1.3 ... one of the following must be true
+			*
+			* 2.1.3.1 B's �effective value constraint� is
+			* �absent� or default.
+			*/
+			if ((bEffValue != NULL) &&
+			    (effFixed == 1)) {
+			    const xmlChar *rEffValue = NULL;
+
+			    xmlSchemaGetEffectiveValueConstraint(bcur,
+				&effFixed, &rEffValue, NULL);
+			    /*
+			    * 2.1.3.2 R's �effective value constraint� is
+			    * fixed with the same string as B's.
+			    * MAYBE TODO: Compare the computed values.
+			    *       Hmm, it says "same string" so
+			    *       string-equality might really be sufficient.
+			    */
+			    if ((effFixed == 0) ||
+				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
+			    {
+				xmlChar *str = NULL;
+
+				xmlSchemaPAttrUseErr4(pctxt,
+				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
+				    WXS_ITEM_NODE(item), item, cur,
+				    "The effective value constraint of the "
+				    "attribute use is inconsistent with "
+				    "its correspondent in the %s %s",
+				    WXS_ACTION_STR(action),
+				    xmlSchemaGetComponentDesignation(&str,
+					baseItem),
+				    NULL, NULL);
+				FREE_AND_NULL(str);
+				/* err = pctxt->err; */
+			    }
+			}
+		    }
+		    break;
+		}
+	    }
+not_found:
+	    if (!found) {
+		/*
+		* (2.2) "otherwise the {base type definition} must have an
+		* {attribute wildcard} and the {target namespace} of the
+		* R's {attribute declaration} must be �valid� with respect
+		* to that wildcard, as defined in Wildcard allows Namespace
+		* Name (�3.10.4)."
+		*/
+		if ((baseWild == NULL) ||
+		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
+		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
+		{
+		    xmlChar *str = NULL;
+
+		    xmlSchemaPAttrUseErr4(pctxt,
+			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
+			WXS_ITEM_NODE(item), item, cur,
+			"Neither a matching attribute use, "
+			"nor a matching wildcard exists in the %s %s",
+			WXS_ACTION_STR(action),
+			xmlSchemaGetComponentDesignation(&str, baseItem),
+			NULL, NULL);
+		    FREE_AND_NULL(str);
+		    /* err = pctxt->err; */
+		}
+	    }
+	}
+    }
+    /*
+    * SPEC derivation-ok-restriction (3):
+    * (3) "For each attribute use in the {attribute uses} of the {base type
+    * definition} whose {required} is true, there must be an attribute
+    * use with an {attribute declaration} with the same {name} and
+    * {target namespace} as its {attribute declaration} in the {attribute
+    * uses} of the complex type definition itself whose {required} is true.
+    */
+    if (baseUses != NULL) {
+	for (j = 0; j < baseUses->nbItems; j++) {
+	    bcur = baseUses->items[j];
+	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
+		continue;
+	    found = 0;
+	    if (uses != NULL) {
+		for (i = 0; i < uses->nbItems; i++) {
+		    cur = uses->items[i];
+		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
+			WXS_ATTRUSE_DECL_NAME(bcur)) &&
+			(WXS_ATTRUSE_DECL_TNS(cur) ==
+			WXS_ATTRUSE_DECL_TNS(bcur))) {
+			found = 1;
+			break;
+		    }
+		}
+	    }
+	    if (!found) {
+		xmlChar *strA = NULL, *strB = NULL;
+
+		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
+		    NULL, item,
+		    "A matching attribute use for the "
+		    "'required' %s of the %s %s is missing",
+		    xmlSchemaGetComponentDesignation(&strA, bcur),
+		    WXS_ACTION_STR(action),
+		    xmlSchemaGetComponentDesignation(&strB, baseItem),
+		    NULL);
+		FREE_AND_NULL(strA);
+		FREE_AND_NULL(strB);
+	    }
+	}
+    }
+    /*
+    * derivation-ok-restriction (4)
+    */
+    if (wild != NULL) {
+	/*
+	* (4) "If there is an {attribute wildcard}, all of the
+	* following must be true:"
+	*/
+	if (baseWild == NULL) {
+	    xmlChar *str = NULL;
+
+	    /*
+	    * (4.1) "The {base type definition} must also have one."
+	    */
+	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
+		NULL, item,
+		"The %s has an attribute wildcard, "
+		"but the %s %s '%s' does not have one",
+		WXS_ITEM_TYPE_NAME(item),
+		WXS_ACTION_STR(action),
+		WXS_ITEM_TYPE_NAME(baseItem),
+		xmlSchemaGetComponentQName(&str, baseItem));
+	    FREE_AND_NULL(str);
+	    return(pctxt->err);
+	} else if ((baseWild->any == 0) &&
+		xmlSchemaCheckCOSNSSubset(wild, baseWild))
+	{
+	    xmlChar *str = NULL;
+	    /*
+	    * (4.2) "The complex type definition's {attribute wildcard}'s
+	    * {namespace constraint} must be a subset of the {base type
+	    * definition}'s {attribute wildcard}'s {namespace constraint},
+	    * as defined by Wildcard Subset (�3.10.6)."
+	    */
+	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
+		NULL, item,
+		"The attribute wildcard is not a valid "
+		"subset of the wildcard in the %s %s '%s'",
+		WXS_ACTION_STR(action),
+		WXS_ITEM_TYPE_NAME(baseItem),
+		xmlSchemaGetComponentQName(&str, baseItem),
+		NULL);
+	    FREE_AND_NULL(str);
+	    return(pctxt->err);
+	}
+	/* 4.3 Unless the {base type definition} is the �ur-type
+	* definition�, the complex type definition's {attribute
+	* wildcard}'s {process contents} must be identical to or
+	* stronger than the {base type definition}'s {attribute
+	* wildcard}'s {process contents}, where strict is stronger
+	* than lax is stronger than skip.
+	*/
+	if ((! WXS_IS_ANYTYPE(baseItem)) &&
+	    (wild->processContents < baseWild->processContents)) {
+	    xmlChar *str = NULL;
+	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
+		NULL, baseItem,
+		"The {process contents} of the attribute wildcard is "
+		"weaker than the one in the %s %s '%s'",
+		WXS_ACTION_STR(action),
+		WXS_ITEM_TYPE_NAME(baseItem),
+		xmlSchemaGetComponentQName(&str, baseItem),
+		NULL);
+	    FREE_AND_NULL(str)
+		return(pctxt->err);
+	}
+    }
+    return(0);
+}
+
+
+static int
+xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaBasicItemPtr item,
+				  xmlSchemaWildcardPtr *completeWild,
+				  xmlSchemaItemListPtr list,
+				  xmlSchemaItemListPtr prohibs);
+/**
+ * xmlSchemaFixupTypeAttributeUses:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ *
+ * Builds the wildcard and the attribute uses on the given complex type.
+ * Returns -1 if an internal error occurs, 0 otherwise.
+ *
+ * ATTENTION TODO: Experimantally this uses pointer comparisons for
+ * strings, so recheck this if we start to hardcode some schemata, since
+ * they might not be in the same dict.
+ * NOTE: It is allowed to "extend" the xs:anyType type.
+ */
+static int
+xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr baseType = NULL;
+    xmlSchemaAttributeUsePtr use;
+    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
+
+    if (type->baseType == NULL) {
+	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
+	    "no base type");
+        return (-1);
+    }
+    baseType = type->baseType;
+    if (WXS_IS_TYPE_NOT_FIXED(baseType))
+	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
+	    return(-1);
+
+    uses = type->attrUses;
+    baseUses = baseType->attrUses;
+    /*
+    * Expand attribute group references. And build the 'complete'
+    * wildcard, i.e. intersect multiple wildcards.
+    * Move attribute prohibitions into a separate list.
+    */
+    if (uses != NULL) {
+	if (WXS_IS_RESTRICTION(type)) {
+	    /*
+	    * This one will transfer all attr. prohibitions
+	    * into pctxt->attrProhibs.
+	    */
+	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
+		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
+		pctxt->attrProhibs) == -1)
+	    {
+		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
+		"failed to expand attributes");
+	    }
+	    if (pctxt->attrProhibs->nbItems != 0)
+		prohibs = pctxt->attrProhibs;
+	} else {
+	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
+		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
+		NULL) == -1)
+	    {
+		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
+		"failed to expand attributes");
+	    }
+	}
+    }
+    /*
+    * Inherit the attribute uses of the base type.
+    */
+    if (baseUses != NULL) {
+	int i, j;
+	xmlSchemaAttributeUseProhibPtr pro;
+
+	if (WXS_IS_RESTRICTION(type)) {
+	    int usesCount;
+	    xmlSchemaAttributeUsePtr tmp;
+
+	    if (uses != NULL)
+		usesCount = uses->nbItems;
+	    else
+		usesCount = 0;
+
+	    /* Restriction. */
+	    for (i = 0; i < baseUses->nbItems; i++) {
+		use = baseUses->items[i];
+		if (prohibs) {
+		    /*
+		    * Filter out prohibited uses.
+		    */
+		    for (j = 0; j < prohibs->nbItems; j++) {
+			pro = prohibs->items[j];
+			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
+			    (WXS_ATTRUSE_DECL_TNS(use) ==
+				pro->targetNamespace))
+			{
+			    goto inherit_next;
+			}
+		    }
+		}
+		if (usesCount) {
+		    /*
+		    * Filter out existing uses.
+		    */
+		    for (j = 0; j < usesCount; j++) {
+			tmp = uses->items[j];
+			if ((WXS_ATTRUSE_DECL_NAME(use) ==
+				WXS_ATTRUSE_DECL_NAME(tmp)) &&
+			    (WXS_ATTRUSE_DECL_TNS(use) ==
+				WXS_ATTRUSE_DECL_TNS(tmp)))
+			{
+			    goto inherit_next;
+			}
+		    }
+		}
+		if (uses == NULL) {
+		    type->attrUses = xmlSchemaItemListCreate();
+		    if (type->attrUses == NULL)
+			goto exit_failure;
+		    uses = type->attrUses;
+		}
+		xmlSchemaItemListAddSize(uses, 2, use);
+inherit_next: {}
+	    }
+	} else {
+	    /* Extension. */
+	    for (i = 0; i < baseUses->nbItems; i++) {
+		use = baseUses->items[i];
+		if (uses == NULL) {
+		    type->attrUses = xmlSchemaItemListCreate();
+		    if (type->attrUses == NULL)
+			goto exit_failure;
+		    uses = type->attrUses;
+		}
+		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
+	    }
+	}
+    }
+    /*
+    * Shrink attr. uses.
+    */
+    if (uses) {
+	if (uses->nbItems == 0) {
+	    xmlSchemaItemListFree(uses);
+	    type->attrUses = NULL;
+	}
+	/*
+	* TODO: We could shrink the size of the array
+	* to fit the actual number of items.
+	*/
+    }
+    /*
+    * Compute the complete wildcard.
+    */
+    if (WXS_IS_EXTENSION(type)) {
+	if (baseType->attributeWildcard != NULL) {
+	    /*
+	    * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
+	    * the appropriate case among the following:"
+	    */
+	    if (type->attributeWildcard != NULL) {
+		/*
+		* Union the complete wildcard with the base wildcard.
+		* SPEC {attribute wildcard}
+		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
+		* and {annotation} are those of the �complete wildcard�,
+		* and whose {namespace constraint} is the intensional union
+		* of the {namespace constraint} of the �complete wildcard�
+		* and of the �base wildcard�, as defined in Attribute
+		* Wildcard Union (�3.10.6)."
+		*/
+		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
+		    baseType->attributeWildcard) == -1)
+		    goto exit_failure;
+	    } else {
+		/*
+		* (3.2.2.1.1) "If the �complete wildcard� is �absent�,
+		* then the �base wildcard�."
+		*/
+		type->attributeWildcard = baseType->attributeWildcard;
+	    }
+	} else {
+	    /*
+	    * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
+	    * �complete wildcard"
+	    * NOOP
+	    */
+	}
+    } else {
+	/*
+	* SPEC {attribute wildcard}
+	* (3.1) "If the <restriction> alternative is chosen, then the
+	* �complete wildcard�;"
+	* NOOP
+	*/
+    }
+
+    return (0);
+
+exit_failure:
+    return(-1);
+}
+
+/**
+ * xmlSchemaTypeFinalContains:
+ * @schema:  the schema
+ * @type:  the type definition
+ * @final: the final
+ *
+ * Evaluates if a type definition contains the given "final".
+ * This does take "finalDefault" into account as well.
+ *
+ * Returns 1 if the type does containt the given "final",
+ * 0 otherwise.
+ */
+static int
+xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
+{
+    if (type == NULL)
+	return (0);
+    if (type->flags & final)
+	return (1);
+    else
+	return (0);
+}
+
+/**
+ * xmlSchemaGetUnionSimpleTypeMemberTypes:
+ * @type:  the Union Simple Type
+ *
+ * Returns a list of member types of @type if existing,
+ * returns NULL otherwise.
+ */
+static xmlSchemaTypeLinkPtr
+xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
+{
+    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
+	if (type->memberTypes != NULL)
+	    return (type->memberTypes);
+	else
+	    type = type->baseType;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaGetParticleTotalRangeMin:
+ * @particle: the particle
+ *
+ * Schema Component Constraint: Effective Total Range
+ * (all and sequence) + (choice)
+ *
+ * Returns the minimun Effective Total Range.
+ */
+static int
+xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
+{
+    if ((particle->children == NULL) ||
+	(particle->minOccurs == 0))
+	return (0);
+    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
+	int min = -1, cur;
+	xmlSchemaParticlePtr part =
+	    (xmlSchemaParticlePtr) particle->children->children;
+
+	if (part == NULL)
+	    return (0);
+	while (part != NULL) {
+	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+		(part->children->type == XML_SCHEMA_TYPE_ANY))
+		cur = part->minOccurs;
+	    else
+		cur = xmlSchemaGetParticleTotalRangeMin(part);
+	    if (cur == 0)
+		return (0);
+	    if ((min > cur) || (min == -1))
+		min = cur;
+	    part = (xmlSchemaParticlePtr) part->next;
+	}
+	return (particle->minOccurs * min);
+    } else {
+	/* <all> and <sequence> */
+	int sum = 0;
+	xmlSchemaParticlePtr part =
+	    (xmlSchemaParticlePtr) particle->children->children;
+
+	if (part == NULL)
+	    return (0);
+	do {
+	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+		(part->children->type == XML_SCHEMA_TYPE_ANY))
+		sum += part->minOccurs;
+	    else
+		sum += xmlSchemaGetParticleTotalRangeMin(part);
+	    part = (xmlSchemaParticlePtr) part->next;
+	} while (part != NULL);
+	return (particle->minOccurs * sum);
+    }
+}
+
+#if 0
+/**
+ * xmlSchemaGetParticleTotalRangeMax:
+ * @particle: the particle
+ *
+ * Schema Component Constraint: Effective Total Range
+ * (all and sequence) + (choice)
+ *
+ * Returns the maximum Effective Total Range.
+ */
+static int
+xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
+{
+    if ((particle->children == NULL) ||
+	(particle->children->children == NULL))
+	return (0);
+    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
+	int max = -1, cur;
+	xmlSchemaParticlePtr part =
+	    (xmlSchemaParticlePtr) particle->children->children;
+
+	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
+	    if (part->children == NULL)
+		continue;
+	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+		(part->children->type == XML_SCHEMA_TYPE_ANY))
+		cur = part->maxOccurs;
+	    else
+		cur = xmlSchemaGetParticleTotalRangeMax(part);
+	    if (cur == UNBOUNDED)
+		return (UNBOUNDED);
+	    if ((max < cur) || (max == -1))
+		max = cur;
+	}
+	/* TODO: Handle overflows? */
+	return (particle->maxOccurs * max);
+    } else {
+	/* <all> and <sequence> */
+	int sum = 0, cur;
+	xmlSchemaParticlePtr part =
+	    (xmlSchemaParticlePtr) particle->children->children;
+
+	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
+	    if (part->children == NULL)
+		continue;
+	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
+		(part->children->type == XML_SCHEMA_TYPE_ANY))
+		cur = part->maxOccurs;
+	    else
+		cur = xmlSchemaGetParticleTotalRangeMax(part);
+	    if (cur == UNBOUNDED)
+		return (UNBOUNDED);
+	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
+		return (UNBOUNDED);
+	    sum += cur;
+	}
+	/* TODO: Handle overflows? */
+	return (particle->maxOccurs * sum);
+    }
+}
+#endif
+
+/**
+ * xmlSchemaIsParticleEmptiable:
+ * @particle: the particle
+ *
+ * Schema Component Constraint: Particle Emptiable
+ * Checks whether the given particle is emptiable.
+ *
+ * Returns 1 if emptiable, 0 otherwise.
+ */
+static int
+xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
+{
+    /*
+    * SPEC (1) "Its {min occurs} is 0."
+    */
+    if ((particle == NULL) || (particle->minOccurs == 0) ||
+	(particle->children == NULL))
+	return (1);
+    /*
+    * SPEC (2) "Its {term} is a group and the minimum part of the
+    * effective total range of that group, [...] is 0."
+    */
+    if (WXS_IS_MODEL_GROUP(particle->children)) {
+	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
+	    return (1);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckCOSSTDerivedOK:
+ * @actxt: a context
+ * @type:  the derived simple type definition
+ * @baseType:  the base type definition
+ * @subset: the subset of ('restriction', ect.)
+ *
+ * Schema Component Constraint:
+ * Type Derivation OK (Simple) (cos-st-derived-OK)
+ *
+ * Checks wheter @type can be validly
+ * derived from @baseType.
+ *
+ * Returns 0 on success, an positive error code otherwise.
+ */
+static int
+xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
+			     xmlSchemaTypePtr type,
+			     xmlSchemaTypePtr baseType,
+			     int subset)
+{
+    /*
+    * 1 They are the same type definition.
+    * TODO: The identy check might have to be more complex than this.
+    */
+    if (type == baseType)
+	return (0);
+    /*
+    * 2.1 restriction is not in the subset, or in the {final}
+    * of its own {base type definition};
+    *
+    * NOTE that this will be used also via "xsi:type".
+    *
+    * TODO: Revise this, it looks strange. How can the "type"
+    * not be fixed or *in* fixing?
+    */
+    if (WXS_IS_TYPE_NOT_FIXED(type))
+	if (xmlSchemaTypeFixup(type, actxt) == -1)
+	    return(-1);
+    if (WXS_IS_TYPE_NOT_FIXED(baseType))
+	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
+	    return(-1);
+    if ((subset & SUBSET_RESTRICTION) ||
+	(xmlSchemaTypeFinalContains(type->baseType,
+	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
+	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
+    }
+    /* 2.2 */
+    if (type->baseType == baseType) {
+	/*
+	* 2.2.1 D's �base type definition� is B.
+	*/
+	return (0);
+    }
+    /*
+    * 2.2.2 D's �base type definition� is not the �ur-type definition�
+    * and is validly derived from B given the subset, as defined by this
+    * constraint.
+    */
+    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
+	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
+	    baseType, subset) == 0)) {
+	return (0);
+    }
+    /*
+    * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
+    * definition�.
+    */
+    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
+	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
+	return (0);
+    }
+    /*
+    * 2.2.4 B's {variety} is union and D is validly derived from a type
+    * definition in B's {member type definitions} given the subset, as
+    * defined by this constraint.
+    *
+    * NOTE: This seems not to involve built-in types, since there is no
+    * built-in Union Simple Type.
+    */
+    if (WXS_IS_UNION(baseType)) {
+	xmlSchemaTypeLinkPtr cur;
+
+	cur = baseType->memberTypes;
+	while (cur != NULL) {
+	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
+		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
+		    return(-1);
+	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
+		    type, cur->type, subset) == 0)
+	    {
+		/*
+		* It just has to be validly derived from at least one
+		* member-type.
+		*/
+		return (0);
+	    }
+	    cur = cur->next;
+	}
+    }
+    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
+}
+
+/**
+ * xmlSchemaCheckTypeDefCircularInternal:
+ * @pctxt:  the schema parser context
+ * @ctxtType:  the type definition
+ * @ancestor: an ancestor of @ctxtType
+ *
+ * Checks st-props-correct (2) + ct-props-correct (3).
+ * Circular type definitions are not allowed.
+ *
+ * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
+ * circular, 0 otherwise.
+ */
+static int
+xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
+			   xmlSchemaTypePtr ctxtType,
+			   xmlSchemaTypePtr ancestor)
+{
+    int ret;
+
+    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
+	return (0);
+
+    if (ctxtType == ancestor) {
+	xmlSchemaPCustomErr(pctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
+	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
+	    "The definition is circular", NULL);
+	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
+    }
+    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
+	/*
+	* Avoid inifinite recursion on circular types not yet checked.
+	*/
+	return (0);
+    }
+    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
+    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
+	ancestor->baseType);
+    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
+    return (ret);
+}
+
+/**
+ * xmlSchemaCheckTypeDefCircular:
+ * @item:  the complex/simple type definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Checks for circular type definitions.
+ */
+static void
+xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
+			      xmlSchemaParserCtxtPtr ctxt)
+{
+    if ((item == NULL) ||
+	(item->type == XML_SCHEMA_TYPE_BASIC) ||
+	(item->baseType == NULL))
+	return;
+    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
+	item->baseType);
+}
+
+/*
+* Simple Type Definition Representation OK (src-simple-type) 4
+*
+* "4 Circular union type definition is disallowed. That is, if the
+* <union> alternative is chosen, there must not be any entries in the
+* memberTypes [attribute] at any depth which resolve to the component
+* corresponding to the <simpleType>."
+*
+* Note that this should work on the *representation* of a component,
+* thus assumes any union types in the member types not being yet
+* substituted. At this stage we need the variety of the types
+* to be already computed.
+*/
+static int
+xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
+					xmlSchemaTypePtr ctxType,
+					xmlSchemaTypeLinkPtr members)
+{
+    xmlSchemaTypeLinkPtr member;
+    xmlSchemaTypePtr memberType;
+
+    member = members;
+    while (member != NULL) {
+	memberType = member->type;
+	while ((memberType != NULL) &&
+	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
+	    if (memberType == ctxType) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
+		    WXS_BASIC_CAST ctxType, NULL,
+		    "The union type definition is circular", NULL);
+		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
+	    }
+	    if ((WXS_IS_UNION(memberType)) &&
+		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
+	    {
+		int res;
+		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
+		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
+		    ctxType,
+		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
+		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
+		if (res != 0)
+		    return(res);
+	    }
+	    memberType = memberType->baseType;
+	}
+	member = member->next;
+    }
+    return(0);
+}
+
+static int
+xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
+				   xmlSchemaTypePtr type)
+{
+    if (! WXS_IS_UNION(type))
+	return(0);
+    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
+	type->memberTypes));
+}
+
+/**
+ * xmlSchemaResolveTypeReferences:
+ * @item:  the complex/simple type definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Resolvese type definition references
+ */
+static void
+xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
+			 xmlSchemaParserCtxtPtr ctxt)
+{
+    if (typeDef == NULL)
+	return;
+
+    /*
+    * Resolve the base type.
+    */
+    if (typeDef->baseType == NULL) {
+	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
+	    typeDef->base, typeDef->baseNs);
+	if (typeDef->baseType == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt,
+		XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST typeDef, typeDef->node,
+		"base", typeDef->base, typeDef->baseNs,
+		XML_SCHEMA_TYPE_SIMPLE, NULL);
+	    return;
+	}
+    }
+    if (WXS_IS_SIMPLE(typeDef)) {
+	if (WXS_IS_UNION(typeDef)) {
+	    /*
+	    * Resolve the memberTypes.
+	    */
+	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
+	    return;
+	} else if (WXS_IS_LIST(typeDef)) {
+	    /*
+	    * Resolve the itemType.
+	    */
+	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
+
+		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
+		    typeDef->base, typeDef->baseNs);
+
+		if ((typeDef->subtypes == NULL) ||
+		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
+		{
+		    typeDef->subtypes = NULL;
+		    xmlSchemaPResCompAttrErr(ctxt,
+			XML_SCHEMAP_SRC_RESOLVE,
+			WXS_BASIC_CAST typeDef, typeDef->node,
+			"itemType", typeDef->base, typeDef->baseNs,
+			XML_SCHEMA_TYPE_SIMPLE, NULL);
+		}
+	    }
+	    return;
+	}
+    }
+    /*
+    * The ball of letters below means, that if we have a particle
+    * which has a QName-helper component as its {term}, we want
+    * to resolve it...
+    */
+    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
+	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
+	    XML_SCHEMA_TYPE_PARTICLE) &&
+	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
+	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
+	    XML_SCHEMA_EXTRA_QNAMEREF))
+    {
+	xmlSchemaQNameRefPtr ref =
+	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
+	xmlSchemaModelGroupDefPtr groupDef;
+
+	/*
+	* URGENT TODO: Test this.
+	*/
+	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
+	/*
+	* Resolve the MG definition reference.
+	*/
+	groupDef =
+	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
+		ref->itemType, ref->name, ref->targetNamespace);
+	if (groupDef == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
+		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
+		"ref", ref->name, ref->targetNamespace, ref->itemType,
+		NULL);
+	    /* Remove the particle. */
+	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
+	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
+	    /* Remove the particle. */
+	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
+	else {
+	    /*
+	    * Assign the MG definition's {model group} to the
+	    * particle's {term}.
+	    */
+	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
+
+	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
+		/*
+		* SPEC cos-all-limited (1.2)
+		* "1.2 the {term} property of a particle with
+		* {max occurs}=1 which is part of a pair which constitutes
+		* the {content type} of a complex type definition."
+		*/
+		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
+		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+			/* TODO: error code */
+			XML_SCHEMAP_COS_ALL_LIMITED,
+			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
+			"The particle's {max occurs} must be 1, since the "
+			"reference resolves to an 'all' model group",
+			NULL, NULL);
+		}
+	    }
+	}
+    }
+}
+
+
+
+/**
+ * xmlSchemaCheckSTPropsCorrect:
+ * @ctxt:  the schema parser context
+ * @type:  the simple type definition
+ *
+ * Checks st-props-correct.
+ *
+ * Returns 0 if the properties are correct,
+ * if not, a positive error code and -1 on internal
+ * errors.
+ */
+static int
+xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
+			     xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr baseType = type->baseType;
+    xmlChar *str = NULL;
+
+    /* STATE: error funcs converted. */
+    /*
+    * Schema Component Constraint: Simple Type Definition Properties Correct
+    *
+    * NOTE: This is somehow redundant, since we actually built a simple type
+    * to have all the needed information; this acts as an self test.
+    */
+    /* Base type: If the datatype has been �derived� by �restriction�
+    * then the Simple Type Definition component from which it is �derived�,
+    * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
+    */
+    if (baseType == NULL) {
+	/*
+	* TODO: Think about: "modulo the impact of Missing
+	* Sub-components (�5.3)."
+	*/
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
+	    WXS_BASIC_CAST type, NULL,
+	    "No base type existent", NULL);
+	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+
+    }
+    if (! WXS_IS_SIMPLE(baseType)) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
+	    WXS_BASIC_CAST type, NULL,
+	    "The base type '%s' is not a simple type",
+	    xmlSchemaGetComponentQName(&str, baseType));
+	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))) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
+	    WXS_BASIC_CAST type, NULL,
+	    "A type, derived by list or union, must have "
+	    "the simple ur-type definition as base type, not '%s'",
+	    xmlSchemaGetComponentQName(&str, baseType));
+	FREE_AND_NULL(str)
+	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+    }
+    /*
+    * Variety: One of {atomic, list, union}.
+    */
+    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
+	(! WXS_IS_LIST(type))) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
+	    WXS_BASIC_CAST type, NULL,
+	    "The variety is absent", NULL);
+	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
+    }
+    /* TODO: Finish this. Hmm, is this finished? */
+
+    /*
+    * 3 The {final} of the {base type definition} must not contain restriction.
+    */
+    if (xmlSchemaTypeFinalContains(baseType,
+	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
+	    WXS_BASIC_CAST type, NULL,
+	    "The 'final' of its base type '%s' must not contain "
+	    "'restriction'",
+	    xmlSchemaGetComponentQName(&str, baseType));
+	FREE_AND_NULL(str)
+	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
+    }
+
+    /*
+    * 2 All simple type definitions must be derived ultimately from the �simple
+    * ur-type definition (so� circular definitions are disallowed). That is, it
+    * must be possible to reach a built-in primitive datatype or the �simple
+    * ur-type definition� by repeatedly following the {base type definition}.
+    *
+    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
+    */
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckCOSSTRestricts:
+ * @ctxt:  the schema parser context
+ * @type:  the simple type definition
+ *
+ * Schema Component Constraint:
+ * Derivation Valid (Restriction, Simple) (cos-st-restricts)
+
+ * Checks if the given @type (simpleType) is derived validly by restriction.
+ * STATUS:
+ *
+ * Returns -1 on internal errors, 0 if the type is validly derived,
+ * a positive error code otherwise.
+ */
+static int
+xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
+			     xmlSchemaTypePtr type)
+{
+    xmlChar *str = NULL;
+
+    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
+	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+	    "given type is not a user-derived simpleType");
+	return (-1);
+    }
+
+    if (WXS_IS_ATOMIC(type)) {
+	xmlSchemaTypePtr primitive;
+	/*
+	* 1.1 The {base type definition} must be an atomic simple
+	* type definition or a built-in primitive datatype.
+	*/
+	if (! WXS_IS_ATOMIC(type->baseType)) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
+		WXS_BASIC_CAST type, NULL,
+		"The base type '%s' is not an atomic simple type",
+		xmlSchemaGetComponentQName(&str, type->baseType));
+	    FREE_AND_NULL(str)
+	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
+	}
+	/* 1.2 The {final} of the {base type definition} must not contain
+	* restriction.
+	*/
+	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
+	if (xmlSchemaTypeFinalContains(type->baseType,
+	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
+		WXS_BASIC_CAST type, NULL,
+		"The final of its base type '%s' must not contain 'restriction'",
+		xmlSchemaGetComponentQName(&str, type->baseType));
+	    FREE_AND_NULL(str)
+	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
+	}
+
+	/*
+	* 1.3.1 DF must be an allowed constraining facet for the {primitive
+	* type definition}, as specified in the appropriate subsection of 3.2
+	* Primitive datatypes.
+	*/
+	if (type->facets != NULL) {
+	    xmlSchemaFacetPtr facet;
+	    int ok = 1;
+
+	    primitive = xmlSchemaGetPrimitiveType(type);
+	    if (primitive == NULL) {
+		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+		    "failed to get primitive type");
+		return (-1);
+	    }
+	    facet = type->facets;
+	    do {
+		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
+		    ok = 0;
+		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
+			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
+			type, primitive, facet);
+		}
+		facet = facet->next;
+	    } while (facet != NULL);
+	    if (ok == 0)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
+	}
+	/*
+	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
+	* of the {base type definition} (call this BF),then the DF's {value}
+	* must be a valid restriction of BF's {value} as defined in
+	* [XML Schemas: Datatypes]."
+	*
+	* NOTE (1.3.2) Facet derivation constraints are currently handled in
+	* xmlSchemaDeriveAndValidateFacets()
+	*/
+    } else if (WXS_IS_LIST(type)) {
+	xmlSchemaTypePtr itemType = NULL;
+
+	itemType = type->subtypes;
+	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
+	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+		"failed to evaluate the item type");
+	    return (-1);
+	}
+	if (WXS_IS_TYPE_NOT_FIXED(itemType))
+	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
+	/*
+	* 2.1 The {item type definition} must have a {variety} of atomic or
+	* union (in which case all the {member type definitions}
+	* must be atomic).
+	*/
+	if ((! WXS_IS_ATOMIC(itemType)) &&
+	    (! WXS_IS_UNION(itemType))) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
+		WXS_BASIC_CAST type, NULL,
+		"The item type '%s' does not have a variety of atomic or union",
+		xmlSchemaGetComponentQName(&str, itemType));
+	    FREE_AND_NULL(str)
+	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
+	} else if (WXS_IS_UNION(itemType)) {
+	    xmlSchemaTypeLinkPtr member;
+
+	    member = itemType->memberTypes;
+	    while (member != NULL) {
+		if (! WXS_IS_ATOMIC(member->type)) {
+		    xmlSchemaPCustomErr(pctxt,
+			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
+			WXS_BASIC_CAST type, NULL,
+			"The item type is a union type, but the "
+			"member type '%s' of this item type is not atomic",
+			xmlSchemaGetComponentQName(&str, member->type));
+		    FREE_AND_NULL(str)
+		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
+		}
+		member = member->next;
+	    }
+	}
+
+	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
+	    xmlSchemaFacetPtr facet;
+	    /*
+	    * This is the case if we have: <simpleType><list ..
+	    */
+	    /*
+	    * 2.3.1
+	    * 2.3.1.1 The {final} of the {item type definition} must not
+	    * contain list.
+	    */
+	    if (xmlSchemaTypeFinalContains(itemType,
+		XML_SCHEMAS_TYPE_FINAL_LIST)) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "The final of its item type '%s' must not contain 'list'",
+		    xmlSchemaGetComponentQName(&str, itemType));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
+	    }
+	    /*
+	    * 2.3.1.2 The {facets} must only contain the whiteSpace
+	    * facet component.
+	    * OPTIMIZE TODO: the S4S already disallows any facet
+	    * to be specified.
+	    */
+	    if (type->facets != NULL) {
+		facet = type->facets;
+		do {
+		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
+			xmlSchemaPIllegalFacetListUnionErr(pctxt,
+			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
+			    type, facet);
+			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
+		    }
+		    facet = facet->next;
+		} while (facet != NULL);
+	    }
+	    /*
+	    * MAYBE TODO: (Hmm, not really) Datatypes states:
+	    * A �list� datatype can be �derived� from an �atomic� datatype
+	    * whose �lexical space� allows space (such as string or anyURI)or
+	    * a �union� datatype any of whose {member type definitions}'s
+	    * �lexical space� allows space.
+	    */
+	} else {
+	    /*
+	    * This is the case if we have: <simpleType><restriction ...
+	    * I.e. the variety of "list" is inherited.
+	    */
+	    /*
+	    * 2.3.2
+	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
+	    */
+	    if (! WXS_IS_LIST(type->baseType)) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "The base type '%s' must be a list type",
+		    xmlSchemaGetComponentQName(&str, type->baseType));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
+	    }
+	    /*
+	    * 2.3.2.2 The {final} of the {base type definition} must not
+	    * contain restriction.
+	    */
+	    if (xmlSchemaTypeFinalContains(type->baseType,
+		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
+		    WXS_BASIC_CAST type, NULL,
+		    "The 'final' of the base type '%s' must not contain 'restriction'",
+		    xmlSchemaGetComponentQName(&str, type->baseType));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
+	    }
+	    /*
+	    * 2.3.2.3 The {item type definition} must be validly derived
+	    * from the {base type definition}'s {item type definition} given
+	    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
+	    */
+	    {
+		xmlSchemaTypePtr baseItemType;
+
+		baseItemType = type->baseType->subtypes;
+		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
+		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+			"failed to eval the item type of a base type");
+		    return (-1);
+		}
+		if ((itemType != baseItemType) &&
+		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
+			baseItemType, 0) != 0)) {
+		    xmlChar *strBIT = NULL, *strBT = NULL;
+		    xmlSchemaPCustomErrExt(pctxt,
+			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
+			WXS_BASIC_CAST type, NULL,
+			"The item type '%s' is not validly derived from "
+			"the item type '%s' of the base type '%s'",
+			xmlSchemaGetComponentQName(&str, itemType),
+			xmlSchemaGetComponentQName(&strBIT, baseItemType),
+			xmlSchemaGetComponentQName(&strBT, type->baseType));
+
+		    FREE_AND_NULL(str)
+		    FREE_AND_NULL(strBIT)
+		    FREE_AND_NULL(strBT)
+		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
+		}
+	    }
+
+	    if (type->facets != NULL) {
+		xmlSchemaFacetPtr facet;
+		int ok = 1;
+		/*
+		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
+		* and enumeration facet components are allowed among the {facets}.
+		*/
+		facet = type->facets;
+		do {
+		    switch (facet->type) {
+			case XML_SCHEMA_FACET_LENGTH:
+			case XML_SCHEMA_FACET_MINLENGTH:
+			case XML_SCHEMA_FACET_MAXLENGTH:
+			case XML_SCHEMA_FACET_WHITESPACE:
+			    /*
+			    * TODO: 2.5.1.2 List datatypes
+			    * The value of �whiteSpace� is fixed to the value collapse.
+			    */
+			case XML_SCHEMA_FACET_PATTERN:
+			case XML_SCHEMA_FACET_ENUMERATION:
+			    break;
+			default: {
+			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
+				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
+				type, facet);
+			    /*
+			    * We could return, but it's nicer to report all
+			    * invalid facets.
+			    */
+			    ok = 0;
+			}
+		    }
+		    facet = facet->next;
+		} while (facet != NULL);
+		if (ok == 0)
+		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
+		/*
+		* SPEC (2.3.2.5) (same as 1.3.2)
+		*
+		* NOTE (2.3.2.5) This is currently done in
+		* xmlSchemaDeriveAndValidateFacets()
+		*/
+	    }
+	}
+    } else if (WXS_IS_UNION(type)) {
+	/*
+	* 3.1 The {member type definitions} must all have {variety} of
+	* atomic or list.
+	*/
+	xmlSchemaTypeLinkPtr member;
+
+	member = type->memberTypes;
+	while (member != NULL) {
+	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
+		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
+
+	    if ((! WXS_IS_ATOMIC(member->type)) &&
+		(! WXS_IS_LIST(member->type))) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "The member type '%s' is neither an atomic, nor a list type",
+		    xmlSchemaGetComponentQName(&str, member->type));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
+	    }
+	    member = member->next;
+	}
+	/*
+	* 3.3.1 If the {base type definition} is the �simple ur-type
+	* definition�
+	*/
+	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
+	    /*
+	    * 3.3.1.1 All of the {member type definitions} must have a
+	    * {final} which does not contain union.
+	    */
+	    member = type->memberTypes;
+	    while (member != NULL) {
+		if (xmlSchemaTypeFinalContains(member->type,
+		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
+		    xmlSchemaPCustomErr(pctxt,
+			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
+			WXS_BASIC_CAST type, NULL,
+			"The 'final' of member type '%s' contains 'union'",
+			xmlSchemaGetComponentQName(&str, member->type));
+		    FREE_AND_NULL(str)
+		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
+		}
+		member = member->next;
+	    }
+	    /*
+	    * 3.3.1.2 The {facets} must be empty.
+	    */
+	    if (type->facetSet != NULL) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
+		    WXS_BASIC_CAST type, NULL,
+		    "No facets allowed", NULL);
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
+	    }
+	} else {
+	    /*
+	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
+	    * I.e. the variety of "list" is inherited.
+	    */
+	    if (! WXS_IS_UNION(type->baseType)) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "The base type '%s' is not a union type",
+		    xmlSchemaGetComponentQName(&str, type->baseType));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
+	    }
+	    /*
+	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
+	    */
+	    if (xmlSchemaTypeFinalContains(type->baseType,
+		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
+		    WXS_BASIC_CAST type, NULL,
+		    "The 'final' of its base type '%s' must not contain 'restriction'",
+		    xmlSchemaGetComponentQName(&str, type->baseType));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
+	    }
+	    /*
+	    * 3.3.2.3 The {member type definitions}, in order, must be validly
+	    * derived from the corresponding type definitions in the {base
+	    * type definition}'s {member type definitions} given the empty set,
+	    * as defined in Type Derivation OK (Simple) (�3.14.6).
+	    */
+	    {
+		xmlSchemaTypeLinkPtr baseMember;
+
+		/*
+		* OPTIMIZE: if the type is restricting, it has no local defined
+		* member types and inherits the member types of the base type;
+		* thus a check for equality can be skipped.
+		*/
+		/*
+		* Even worse: I cannot see a scenario where a restricting
+		* union simple type can have other member types as the member
+		* types of it's base type. This check seems not necessary with
+		* respect to the derivation process in libxml2.
+		* But necessary if constructing types with an API.
+		*/
+		if (type->memberTypes != NULL) {
+		    member = type->memberTypes;
+		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
+		    if ((member == NULL) && (baseMember != NULL)) {
+			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+			    "different number of member types in base");
+		    }
+		    while (member != NULL) {
+			if (baseMember == NULL) {
+			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
+			    "different number of member types in base");
+			} else if ((member->type != baseMember->type) &&
+			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
+				member->type, baseMember->type, 0) != 0)) {
+			    xmlChar *strBMT = NULL, *strBT = NULL;
+
+			    xmlSchemaPCustomErrExt(pctxt,
+				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
+				WXS_BASIC_CAST type, NULL,
+				"The member type %s is not validly "
+				"derived from its corresponding member "
+				"type %s of the base type %s",
+				xmlSchemaGetComponentQName(&str, member->type),
+				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
+				xmlSchemaGetComponentQName(&strBT, type->baseType));
+			    FREE_AND_NULL(str)
+			    FREE_AND_NULL(strBMT)
+			    FREE_AND_NULL(strBT)
+			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
+			}
+			member = member->next;
+                        if (baseMember != NULL)
+                            baseMember = baseMember->next;
+		    }
+		}
+	    }
+	    /*
+	    * 3.3.2.4 Only pattern and enumeration facet components are
+	    * allowed among the {facets}.
+	    */
+	    if (type->facets != NULL) {
+		xmlSchemaFacetPtr facet;
+		int ok = 1;
+
+		facet = type->facets;
+		do {
+		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
+			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
+			xmlSchemaPIllegalFacetListUnionErr(pctxt,
+				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
+				type, facet);
+			ok = 0;
+		    }
+		    facet = facet->next;
+		} while (facet != NULL);
+		if (ok == 0)
+		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
+
+	    }
+	    /*
+	    * SPEC (3.3.2.5) (same as 1.3.2)
+	    *
+	    * NOTE (3.3.2.5) This is currently done in
+	    * xmlSchemaDeriveAndValidateFacets()
+	    */
+	}
+    }
+
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckSRCSimpleType:
+ * @ctxt:  the schema parser context
+ * @type:  the simple type definition
+ *
+ * Checks crc-simple-type constraints.
+ *
+ * Returns 0 if the constraints are satisfied,
+ * if not a positive error code and -1 on internal
+ * errors.
+ */
+#if 0
+static int
+xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
+			    xmlSchemaTypePtr type)
+{
+    /*
+    * src-simple-type.1 The corresponding simple type definition, if any,
+    * must satisfy the conditions set out in Constraints on Simple Type
+    * Definition Schema Components (�3.14.6).
+    */
+    if (WXS_IS_RESTRICTION(type)) {
+	/*
+	* src-simple-type.2 "If the <restriction> alternative is chosen,
+	* either it must have a base [attribute] or a <simpleType> among its
+	* [children], but not both."
+	* NOTE: This is checked in the parse function of <restriction>.
+	*/
+	/*
+	*
+	*/
+    } else if (WXS_IS_LIST(type)) {
+	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
+	* an itemType [attribute] or a <simpleType> among its [children],
+	* but not both."
+	*
+	* NOTE: This is checked in the parse function of <list>.
+	*/
+    } else if (WXS_IS_UNION(type)) {
+	/*
+	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
+	*/
+    }
+    return (0);
+}
+#endif
+
+static int
+xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
+{
+   if (ctxt->vctxt == NULL) {
+	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
+	if (ctxt->vctxt == NULL) {
+	    xmlSchemaPErr(ctxt, NULL,
+		XML_SCHEMAP_INTERNAL,
+		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
+		"failed to create a temp. validation context.\n",
+		NULL, NULL);
+	    return (-1);
+	}
+	/* TODO: Pass user data. */
+	xmlSchemaSetValidErrors(ctxt->vctxt,
+	    ctxt->error, ctxt->warning, ctxt->errCtxt);
+	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
+	    ctxt->serror, ctxt->errCtxt);
+    }
+    return (0);
+}
+
+static int
+xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
+			     xmlNodePtr node,
+			     xmlSchemaTypePtr type,
+			     const xmlChar *value,
+			     xmlSchemaValPtr *retVal,
+			     int fireErrors,
+			     int normalize,
+			     int isNormalized);
+
+/**
+ * xmlSchemaParseCheckCOSValidDefault:
+ * @pctxt:  the schema parser context
+ * @type:  the simple type definition
+ * @value: the default value
+ * @node: an optional node (the holder of the value)
+ *
+ * Schema Component Constraint: Element Default Valid (Immediate)
+ * (cos-valid-default)
+ * This will be used by the parser only. For the validator there's
+ * an other version.
+ *
+ * Returns 0 if the constraints are satisfied,
+ * if not, a positive error code and -1 on internal
+ * errors.
+ */
+static int
+xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
+				   xmlNodePtr node,
+				   xmlSchemaTypePtr type,
+				   const xmlChar *value,
+				   xmlSchemaValPtr *val)
+{
+    int ret = 0;
+
+    /*
+    * cos-valid-default:
+    * Schema Component Constraint: Element Default Valid (Immediate)
+    * For a string to be a valid default with respect to a type
+    * definition the appropriate case among the following must be true:
+    */
+    if WXS_IS_COMPLEX(type) {
+	/*
+	* Complex type.
+	*
+	* SPEC (2.1) "its {content type} must be a simple type definition
+	* or mixed."
+	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
+	* type}'s particle must be �emptiable� as defined by
+	* Particle Emptiable (�3.9.6)."
+	*/
+	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
+	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
+	    /* NOTE that this covers (2.2.2) as well. */
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
+		WXS_BASIC_CAST type, type->node,
+		"For a string to be a valid default, the type definition "
+		"must be a simple type or a complex type with mixed content "
+		"and a particle emptiable", NULL);
+	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
+	}
+    }
+    /*
+    * 1 If the type definition is a simple type definition, then the string
+    * must be �valid� with respect to that definition as defined by String
+    * Valid (�3.14.4).
+    *
+    * AND
+    *
+    * 2.2.1 If the {content type} is a simple type definition, then the
+    * string must be �valid� with respect to that simple type definition
+    * as defined by String Valid (�3.14.4).
+    */
+    if (WXS_IS_SIMPLE(type))
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
+	    type, value, val, 1, 1, 0);
+    else if (WXS_HAS_SIMPLE_CONTENT(type))
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
+	    type->contentTypeDef, value, val, 1, 1, 0);
+    else
+	return (ret);
+
+    if (ret < 0) {
+	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
+	    "calling xmlSchemaVCheckCVCSimpleType()");
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaCheckCTPropsCorrect:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ *.(4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Complex Type Definition Properties Correct (ct-props-correct)
+ * STATUS: (seems) complete
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+			     xmlSchemaTypePtr type)
+{
+    /*
+    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
+    *
+    * SPEC (1) "The values of the properties of a complex type definition must
+    * be as described in the property tableau in The Complex Type Definition
+    * Schema Component (�3.4.1), modulo the impact of Missing
+    * Sub-components (�5.3)."
+    */
+    if ((type->baseType != NULL) &&
+	(WXS_IS_SIMPLE(type->baseType)) &&
+	(WXS_IS_EXTENSION(type) == 0)) {
+	/*
+	* SPEC (2) "If the {base type definition} is a simple type definition,
+	* the {derivation method} must be extension."
+	*/
+	xmlSchemaCustomErr(ACTXT_CAST pctxt,
+	    XML_SCHEMAP_SRC_CT_1,
+	    NULL, WXS_BASIC_CAST type,
+	    "If the base type is a simple type, the derivation method must be "
+	    "'extension'", NULL, NULL);
+	return (XML_SCHEMAP_SRC_CT_1);
+    }
+    /*
+    * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
+    * definition�. That is, it must be possible to reach the �ur-type
+    * definition by repeatedly following the {base type definition}."
+    *
+    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
+    */
+    /*
+    * NOTE that (4) and (5) need the following:
+    *   - attribute uses need to be already inherited (apply attr. prohibitions)
+    *   - attribute group references need to be expanded already
+    *   - simple types need to be typefixed already
+    */
+    if (type->attrUses &&
+	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
+    {
+	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
+	xmlSchemaAttributeUsePtr use, tmp;
+	int i, j, hasId = 0;
+
+	for (i = uses->nbItems -1; i >= 0; i--) {
+	    use = uses->items[i];
+
+	    /*
+	    * SPEC ct-props-correct
+	    * (4) "Two distinct attribute declarations in the
+	    * {attribute uses} must not have identical {name}s and
+	    * {target namespace}s."
+	    */
+	    if (i > 0) {
+		for (j = i -1; j >= 0; j--) {
+		    tmp = uses->items[j];
+		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
+			WXS_ATTRUSE_DECL_NAME(tmp)) &&
+			(WXS_ATTRUSE_DECL_TNS(use) ==
+			WXS_ATTRUSE_DECL_TNS(tmp)))
+		    {
+			xmlChar *str = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    XML_SCHEMAP_AG_PROPS_CORRECT,
+			    NULL, WXS_BASIC_CAST type,
+			    "Duplicate %s",
+			    xmlSchemaGetComponentDesignation(&str, use),
+			    NULL);
+			FREE_AND_NULL(str);
+			/*
+			* Remove the duplicate.
+			*/
+			if (xmlSchemaItemListRemove(uses, i) == -1)
+			    goto exit_failure;
+			goto next_use;
+		    }
+		}
+	    }
+	    /*
+	    * SPEC ct-props-correct
+	    * (5) "Two distinct attribute declarations in the
+	    * {attribute uses} must not have {type definition}s which
+	    * are or are derived from ID."
+	    */
+	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
+		if (xmlSchemaIsDerivedFromBuiltInType(
+		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
+		{
+		    if (hasId) {
+			xmlChar *str = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    XML_SCHEMAP_AG_PROPS_CORRECT,
+			    NULL, WXS_BASIC_CAST type,
+			    "There must not exist more than one attribute "
+			    "declaration of type 'xs:ID' "
+			    "(or derived from 'xs:ID'). The %s violates this "
+			    "constraint",
+			    xmlSchemaGetComponentDesignation(&str, use),
+			    NULL);
+			FREE_AND_NULL(str);
+			if (xmlSchemaItemListRemove(uses, i) == -1)
+			    goto exit_failure;
+		    }
+
+		    hasId = 1;
+		}
+	    }
+next_use: {}
+	}
+    }
+    return (0);
+exit_failure:
+    return(-1);
+}
+
+static int
+xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
+		       xmlSchemaTypePtr typeB)
+{
+    /*
+    * TODO: This should implement component-identity
+    * in the future.
+    */
+    if ((typeA == NULL) || (typeB == NULL))
+	return (0);
+    return (typeA == typeB);
+}
+
+/**
+ * xmlSchemaCheckCOSCTDerivedOK:
+ * @ctxt:  the schema parser context
+ * @type:  the to-be derived complex type definition
+ * @baseType:  the base complex type definition
+ * @set: the given set
+ *
+ * Schema Component Constraint:
+ * Type Derivation OK (Complex) (cos-ct-derived-ok)
+ *
+ * STATUS: completed
+ *
+ * Returns 0 if the constraints are satisfied, or 1
+ * if not.
+ */
+static int
+xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
+			     xmlSchemaTypePtr type,
+			     xmlSchemaTypePtr baseType,
+			     int set)
+{
+    int equal = xmlSchemaAreEqualTypes(type, baseType);
+    /* TODO: Error codes. */
+    /*
+    * SPEC "For a complex type definition (call it D, for derived)
+    * to be validly derived from a type definition (call this
+    * B, for base) given a subset of {extension, restriction}
+    * all of the following must be true:"
+    */
+    if (! equal) {
+	/*
+	* SPEC (1) "If B and D are not the same type definition, then the
+	* {derivation method} of D must not be in the subset."
+	*/
+	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
+	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
+	    return (1);
+    } else {
+	/*
+	* SPEC (2.1) "B and D must be the same type definition."
+	*/
+	return (0);
+    }
+    /*
+    * SPEC (2.2) "B must be D's {base type definition}."
+    */
+    if (type->baseType == baseType)
+	return (0);
+    /*
+    * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
+    * definition�."
+    */
+    if (WXS_IS_ANYTYPE(type->baseType))
+	return (1);
+
+    if (WXS_IS_COMPLEX(type->baseType)) {
+	/*
+	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
+	* must be validly derived from B given the subset as defined by this
+	* constraint."
+	*/
+	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
+	    baseType, set));
+    } else {
+	/*
+	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
+	* must be validly derived from B given the subset as defined in Type
+	* Derivation OK (Simple) (�3.14.6).
+	*/
+	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
+	    baseType, set));
+    }
+}
+
+/**
+ * xmlSchemaCheckCOSDerivedOK:
+ * @type:  the derived simple type definition
+ * @baseType:  the base type definition
+ *
+ * Calls:
+ * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
+ *
+ * Checks wheter @type can be validly derived from @baseType.
+ *
+ * Returns 0 on success, an positive error code otherwise.
+ */
+static int
+xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
+			   xmlSchemaTypePtr type,
+			   xmlSchemaTypePtr baseType,
+			   int set)
+{
+    if (WXS_IS_SIMPLE(type))
+	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
+    else
+	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
+}
+
+/**
+ * xmlSchemaCheckCOSCTExtends:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Derivation Valid (Extension) (cos-ct-extends)
+ *
+ * STATUS:
+ *   missing:
+ *     (1.5)
+ *     (1.4.3.2.2.2) "Particle Valid (Extension)"
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
+			   xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr base = type->baseType;
+    /*
+    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
+    * temporarily only.
+    */
+    /*
+    * SPEC (1) "If the {base type definition} is a complex type definition,
+    * then all of the following must be true:"
+    */
+    if (WXS_IS_COMPLEX(base)) {
+	/*
+	* SPEC (1.1) "The {final} of the {base type definition} must not
+	* contain extension."
+	*/
+	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+		WXS_BASIC_CAST type, NULL,
+		"The 'final' of the base type definition "
+		"contains 'extension'", NULL);
+	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+	}
+
+	/*
+	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
+	* since they are automatically satisfied through the
+	* inheriting mechanism.
+	* Note that even if redefining components, the inheriting mechanism
+	* is used.
+	*/
+#if 0
+	/*
+	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
+	* uses}
+	* of the complex type definition itself, that is, for every attribute
+	* use in the {attribute uses} of the {base type definition}, there
+	* must be an attribute use in the {attribute uses} of the complex
+	* type definition itself whose {attribute declaration} has the same
+	* {name}, {target namespace} and {type definition} as its attribute
+	* declaration"
+	*/
+	if (base->attrUses != NULL) {
+	    int i, j, found;
+	    xmlSchemaAttributeUsePtr use, buse;
+
+	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
+		buse = (WXS_LIST_CAST base->attrUses)->items[i];
+		found = 0;
+		if (type->attrUses != NULL) {
+		    use = (WXS_LIST_CAST type->attrUses)->items[j];
+		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
+		    {
+			if ((WXS_ATTRUSE_DECL_NAME(use) ==
+				WXS_ATTRUSE_DECL_NAME(buse)) &&
+			    (WXS_ATTRUSE_DECL_TNS(use) ==
+				WXS_ATTRUSE_DECL_TNS(buse)) &&
+			    (WXS_ATTRUSE_TYPEDEF(use) ==
+				WXS_ATTRUSE_TYPEDEF(buse))
+			{
+			    found = 1;
+			    break;
+			}
+		    }
+		}
+		if (! found) {
+		    xmlChar *str = NULL;
+
+		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
+			NULL, WXS_BASIC_CAST type,
+			/*
+			* TODO: The report does not indicate that also the
+			* type needs to be the same.
+			*/
+			"This type is missing a matching correspondent "
+			"for its {base type}'s %s in its {attribute uses}",
+			xmlSchemaGetComponentDesignation(&str,
+			    buse->children),
+			NULL);
+		    FREE_AND_NULL(str)
+		}
+	    }
+	}
+	/*
+	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
+	* definition must also have one, and the base type definition's
+	* {attribute  wildcard}'s {namespace constraint} must be a subset
+	* of the complex  type definition's {attribute wildcard}'s {namespace
+	* constraint}, as defined by Wildcard Subset (�3.10.6)."
+	*/
+
+	/*
+	* MAYBE TODO: Enable if ever needed. But this will be needed only
+	* if created the type via a schema construction API.
+	*/
+	if (base->attributeWildcard != NULL) {
+	    if (type->attributeWilcard == NULL) {
+		xmlChar *str = NULL;
+
+		xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
+		    NULL, type,
+		    "The base %s has an attribute wildcard, "
+		    "but this type is missing an attribute wildcard",
+		    xmlSchemaGetComponentDesignation(&str, base));
+		FREE_AND_NULL(str)
+
+	    } else if (xmlSchemaCheckCOSNSSubset(
+		base->attributeWildcard, type->attributeWildcard))
+	    {
+		xmlChar *str = NULL;
+
+		xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
+		    NULL, type,
+		    "The attribute wildcard is not a valid "
+		    "superset of the one in the base %s",
+		    xmlSchemaGetComponentDesignation(&str, base));
+		FREE_AND_NULL(str)
+	    }
+	}
+#endif
+	/*
+	* SPEC (1.4) "One of the following must be true:"
+	*/
+	if ((type->contentTypeDef != NULL) &&
+	    (type->contentTypeDef == base->contentTypeDef)) {
+	    /*
+	    * SPEC (1.4.1) "The {content type} of the {base type definition}
+	    * and the {content type} of the complex type definition itself
+	    * must be the same simple type definition"
+	    * PASS
+	    */
+	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
+	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
+	    /*
+	    * SPEC (1.4.2) "The {content type} of both the {base type
+	    * definition} and the complex type definition itself must
+	    * be empty."
+	    * PASS
+	    */
+	} else {
+	    /*
+	    * SPEC (1.4.3) "All of the following must be true:"
+	    */
+	    if (type->subtypes == NULL) {
+		/*
+		* SPEC 1.4.3.1 The {content type} of the complex type
+		* definition itself must specify a particle.
+		*/
+		xmlSchemaPCustomErr(ctxt,
+		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "The content type must specify a particle", NULL);
+		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+	    }
+	    /*
+	    * SPEC (1.4.3.2) "One of the following must be true:"
+	    */
+	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+		/*
+		* SPEC (1.4.3.2.1) "The {content type} of the {base type
+		* definition} must be empty.
+		* PASS
+		*/
+	    } else {
+		/*
+		* SPEC (1.4.3.2.2) "All of the following must be true:"
+		*/
+		if ((type->contentType != base->contentType) ||
+		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
+		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
+		    /*
+		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
+		    * or both must be element-only."
+		    */
+		    xmlSchemaPCustomErr(ctxt,
+			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+			WXS_BASIC_CAST type, NULL,
+			"The content type of both, the type and its base "
+			"type, must either 'mixed' or 'element-only'", NULL);
+		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+		}
+		/*
+		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
+		* complex type definition must be a �valid extension�
+		* of the {base type definition}'s particle, as defined
+		* in Particle Valid (Extension) (�3.9.6)."
+		*
+		* NOTE that we won't check "Particle Valid (Extension)",
+		* since it is ensured by the derivation process in
+		* xmlSchemaTypeFixup(). We need to implement this when heading
+		* for a construction API
+		* TODO: !! This is needed to be checked if redefining a type !!
+		*/
+	    }
+	    /*
+	    * URGENT TODO (1.5)
+	    */
+	}
+    } else {
+	/*
+	* SPEC (2) "If the {base type definition} is a simple type definition,
+	* then all of the following must be true:"
+	*/
+	if (type->contentTypeDef != base) {
+	    /*
+	    * SPEC (2.1) "The {content type} must be the same simple type
+	    * definition."
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+		WXS_BASIC_CAST type, NULL,
+		"The content type must be the simple base type", NULL);
+	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+	}
+	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
+	    /*
+	    * SPEC (2.2) "The {final} of the {base type definition} must not
+	    * contain extension"
+	    * NOTE that this is the same as (1.1).
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
+		WXS_BASIC_CAST type, NULL,
+		"The 'final' of the base type definition "
+		"contains 'extension'", NULL);
+	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
+	}
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckDerivationOKRestriction:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ * Schema Component Constraint:
+ * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
+ *
+ * STATUS:
+ *   missing:
+ *     (5.4.2) ???
+ *
+ * ATTENTION:
+ * In XML Schema 1.1 this will be:
+ * Validation Rule: Checking complex type subsumption
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
+				      xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr base;
+
+    /*
+    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
+    * temporarily only.
+    */
+    base = type->baseType;
+    if (! WXS_IS_COMPLEX(base)) {
+	xmlSchemaCustomErr(ACTXT_CAST ctxt,
+	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+	    type->node, WXS_BASIC_CAST type,
+	    "The base type must be a complex type", NULL, NULL);
+	return(ctxt->err);
+    }
+    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
+	/*
+	* SPEC (1) "The {base type definition} must be a complex type
+	* definition whose {final} does not contain restriction."
+	*/
+	xmlSchemaCustomErr(ACTXT_CAST ctxt,
+	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+	    type->node, WXS_BASIC_CAST type,
+	    "The 'final' of the base type definition "
+	    "contains 'restriction'", NULL, NULL);
+	return (ctxt->err);
+    }
+    /*
+    * SPEC (2), (3) and (4)
+    * Those are handled in a separate function, since the
+    * same constraints are needed for redefinition of
+    * attribute groups as well.
+    */
+    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
+	XML_SCHEMA_ACTION_DERIVE,
+	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
+	type->attrUses, base->attrUses,
+	type->attributeWildcard,
+	base->attributeWildcard) == -1)
+    {
+	return(-1);
+    }
+    /*
+    * SPEC (5) "One of the following must be true:"
+    */
+    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
+	/*
+	* SPEC (5.1) "The {base type definition} must be the
+	* �ur-type definition�."
+	* PASS
+	*/
+    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
+	/*
+	* SPEC (5.2.1) "The {content type} of the complex type definition
+	* must be a simple type definition"
+	*
+	* SPEC (5.2.2) "One of the following must be true:"
+	*/
+	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
+	{
+	    int err;
+	    /*
+	    * SPEC (5.2.2.1) "The {content type} of the {base type
+	    * definition} must be a simple type definition from which
+	    * the {content type} is validly derived given the empty
+	    * set as defined in Type Derivation OK (Simple) (�3.14.6)."
+	    *
+	    * ATTENTION TODO: This seems not needed if the type implicitely
+	    * derived from the base type.
+	    *
+	    */
+	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
+		type->contentTypeDef, base->contentTypeDef, 0);
+	    if (err != 0) {
+		xmlChar *strA = NULL, *strB = NULL;
+
+		if (err == -1)
+		    return(-1);
+		xmlSchemaCustomErr(ACTXT_CAST ctxt,
+		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+		    NULL, WXS_BASIC_CAST type,
+		    "The {content type} %s is not validly derived from the "
+		    "base type's {content type} %s",
+		    xmlSchemaGetComponentDesignation(&strA,
+			type->contentTypeDef),
+		    xmlSchemaGetComponentDesignation(&strB,
+			base->contentTypeDef));
+		FREE_AND_NULL(strA);
+		FREE_AND_NULL(strB);
+		return(ctxt->err);
+	    }
+	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+	    (xmlSchemaIsParticleEmptiable(
+		(xmlSchemaParticlePtr) base->subtypes))) {
+	    /*
+	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
+	    * and have a particle which is �emptiable� as defined in
+	    * Particle Emptiable (�3.9.6)."
+	    * PASS
+	    */
+	} else {
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+		WXS_BASIC_CAST type, NULL,
+		"The content type of the base type must be either "
+		"a simple type or 'mixed' and an emptiable particle", NULL);
+	    return (ctxt->err);
+	}
+    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+	/*
+	* SPEC (5.3.1) "The {content type} of the complex type itself must
+	* be empty"
+	*/
+	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+	    /*
+	    * SPEC (5.3.2.1) "The {content type} of the {base type
+	    * definition} must also be empty."
+	    * PASS
+	    */
+	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
+	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
+	    xmlSchemaIsParticleEmptiable(
+		(xmlSchemaParticlePtr) base->subtypes)) {
+	    /*
+	    * SPEC (5.3.2.2) "The {content type} of the {base type
+	    * definition} must be elementOnly or mixed and have a particle
+	    * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
+	    * PASS
+	    */
+	} else {
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+		WXS_BASIC_CAST type, NULL,
+		"The content type of the base type must be either "
+		"empty or 'mixed' (or 'elements-only') and an emptiable "
+		"particle", NULL);
+	    return (ctxt->err);
+	}
+    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
+	WXS_HAS_MIXED_CONTENT(type)) {
+	/*
+	* SPEC (5.4.1.1) "The {content type} of the complex type definition
+	* itself must be element-only"
+	*/
+	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
+	    /*
+	    * SPEC (5.4.1.2) "The {content type} of the complex type
+	    * definition itself and of the {base type definition} must be
+	    * mixed"
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+		WXS_BASIC_CAST type, NULL,
+		"If the content type is 'mixed', then the content type of the "
+		"base type must also be 'mixed'", NULL);
+	    return (ctxt->err);
+	}
+	/*
+	* SPEC (5.4.2) "The particle of the complex type definition itself
+	* must be a �valid restriction� of the particle of the {content
+	* type} of the {base type definition} as defined in Particle Valid
+	* (Restriction) (�3.9.6).
+	*
+	* URGENT TODO: (5.4.2)
+	*/
+    } else {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
+	    WXS_BASIC_CAST type, NULL,
+	    "The type is not a valid restriction of its base type", NULL);
+	return (ctxt->err);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckCTComponent:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.4.6) Constraints on Complex Type Definition Schema Components
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
+			  xmlSchemaTypePtr type)
+{
+    int ret;
+    /*
+    * Complex Type Definition Properties Correct
+    */
+    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
+    if (ret != 0)
+	return (ret);
+    if (WXS_IS_EXTENSION(type))
+	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
+    else
+	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
+    return (ret);
+}
+
+/**
+ * xmlSchemaCheckSRCCT:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
+ * Schema Representation Constraint:
+ * Complex Type Definition Representation OK (src-ct)
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
+		    xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr base;
+    int ret = 0;
+
+    /*
+    * TODO: Adjust the error codes here, as I used
+    * XML_SCHEMAP_SRC_CT_1 only yet.
+    */
+    base = type->baseType;
+    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
+	/*
+	* 1 If the <complexContent> alternative is chosen, the type definition
+	* �resolved� to by the �actual value� of the base [attribute]
+	* must be a complex type definition;
+	*/
+	if (! WXS_IS_COMPLEX(base)) {
+	    xmlChar *str = NULL;
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_SRC_CT_1,
+		WXS_BASIC_CAST type, type->node,
+		"If using <complexContent>, the base type is expected to be "
+		"a complex type. The base type '%s' is a simple type",
+		xmlSchemaFormatQName(&str, base->targetNamespace,
+		base->name));
+	    FREE_AND_NULL(str)
+	    return (XML_SCHEMAP_SRC_CT_1);
+	}
+    } else {
+	/*
+	* SPEC
+	* 2 If the <simpleContent> alternative is chosen, all of the
+	* following must be true:
+	* 2.1 The type definition �resolved� to by the �actual value� of the
+	* base [attribute] must be one of the following:
+	*/
+	if (WXS_IS_SIMPLE(base)) {
+	    if (WXS_IS_EXTENSION(type) == 0) {
+		xmlChar *str = NULL;
+		/*
+		* 2.1.3 only if the <extension> alternative is also
+		* chosen, a simple type definition.
+		*/
+		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
+		xmlSchemaPCustomErr(ctxt,
+		    XML_SCHEMAP_SRC_CT_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "If using <simpleContent> and <restriction>, the base "
+		    "type must be a complex type. The base type '%s' is "
+		    "a simple type",
+		    xmlSchemaFormatQName(&str, base->targetNamespace,
+			base->name));
+		FREE_AND_NULL(str)
+		return (XML_SCHEMAP_SRC_CT_1);
+	    }
+	} else {
+	    /* Base type is a complex type. */
+	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
+		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
+		/*
+		* 2.1.1 a complex type definition whose {content type} is a
+		* simple type definition;
+		* PASS
+		*/
+		if (base->contentTypeDef == NULL) {
+		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
+			WXS_BASIC_CAST type, NULL,
+			"Internal error: xmlSchemaCheckSRCCT, "
+			"'%s', base type has no content type",
+			type->name);
+		    return (-1);
+		}
+	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+		(WXS_IS_RESTRICTION(type))) {
+
+		/*
+		* 2.1.2 only if the <restriction> alternative is also
+		* chosen, a complex type definition whose {content type}
+		* is mixed and a particle emptiable.
+		*/
+		if (! xmlSchemaIsParticleEmptiable(
+		    (xmlSchemaParticlePtr) base->subtypes)) {
+		    ret = XML_SCHEMAP_SRC_CT_1;
+		} else
+		    /*
+		    * Attention: at this point the <simpleType> child is in
+		    * ->contentTypeDef (put there during parsing).
+		    */
+		    if (type->contentTypeDef == NULL) {
+		    xmlChar *str = NULL;
+		    /*
+		    * 2.2 If clause 2.1.2 above is satisfied, then there
+		    * must be a <simpleType> among the [children] of
+		    * <restriction>.
+		    */
+		    /* TODO: Change error code to ..._SRC_CT_2_2. */
+		    xmlSchemaPCustomErr(ctxt,
+			XML_SCHEMAP_SRC_CT_1,
+			WXS_BASIC_CAST type, NULL,
+			"A <simpleType> is expected among the children "
+			"of <restriction>, if <simpleContent> is used and "
+			"the base type '%s' is a complex type",
+			xmlSchemaFormatQName(&str, base->targetNamespace,
+			base->name));
+		    FREE_AND_NULL(str)
+		    return (XML_SCHEMAP_SRC_CT_1);
+		}
+	    } else {
+		ret = XML_SCHEMAP_SRC_CT_1;
+	    }
+	}
+	if (ret > 0) {
+	    xmlChar *str = NULL;
+	    if (WXS_IS_RESTRICTION(type)) {
+		xmlSchemaPCustomErr(ctxt,
+		    XML_SCHEMAP_SRC_CT_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "If <simpleContent> and <restriction> is used, the "
+		    "base type must be a simple type or a complex type with "
+		    "mixed content and particle emptiable. The base type "
+		    "'%s' is none of those",
+		    xmlSchemaFormatQName(&str, base->targetNamespace,
+		    base->name));
+	    } else {
+		xmlSchemaPCustomErr(ctxt,
+		    XML_SCHEMAP_SRC_CT_1,
+		    WXS_BASIC_CAST type, NULL,
+		    "If <simpleContent> and <extension> is used, the "
+		    "base type must be a simple type. The base type '%s' "
+		    "is a complex type",
+		    xmlSchemaFormatQName(&str, base->targetNamespace,
+		    base->name));
+	    }
+	    FREE_AND_NULL(str)
+	}
+    }
+    /*
+    * SPEC (3) "The corresponding complex type definition component must
+    * satisfy the conditions set out in Constraints on Complex Type
+    * Definition Schema Components (�3.4.6);"
+    * NOTE (3) will be done in xmlSchemaTypeFixup().
+    */
+    /*
+    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
+    * above for {attribute wildcard} is satisfied, the intensional
+    * intersection must be expressible, as defined in Attribute Wildcard
+    * Intersection (�3.10.6).
+    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
+    */
+    return (ret);
+}
+
+#ifdef ENABLE_PARTICLE_RESTRICTION
+/**
+ * xmlSchemaCheckParticleRangeOK:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Occurrence Range OK (range-ok)
+ *
+ * STATUS: complete
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
+			      int bmin, int bmax)
+{
+    if (rmin < bmin)
+	return (1);
+    if ((bmax != UNBOUNDED) &&
+	(rmax > bmax))
+	return (1);
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckRCaseNameAndTypeOK:
+ * @ctxt:  the schema parser context
+ * @r: the restricting element declaration particle
+ * @b: the base element declaration particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
+ * (rcase-NameAndTypeOK)
+ *
+ * STATUS:
+ *   MISSING (3.2.3)
+ *   CLARIFY: (3.2.2)
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
+				 xmlSchemaParticlePtr r,
+				 xmlSchemaParticlePtr b)
+{
+    xmlSchemaElementPtr elemR, elemB;
+
+    /* TODO: Error codes (rcase-NameAndTypeOK). */
+    elemR = (xmlSchemaElementPtr) r->children;
+    elemB = (xmlSchemaElementPtr) b->children;
+    /*
+    * SPEC (1) "The declarations' {name}s and {target namespace}s are
+    * the same."
+    */
+    if ((elemR != elemB) &&
+	((! xmlStrEqual(elemR->name, elemB->name)) ||
+	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
+	return (1);
+    /*
+    * SPEC (2) "R's occurrence range is a valid restriction of B's
+    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    */
+    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
+	    b->minOccurs, b->maxOccurs) != 0)
+	return (1);
+    /*
+    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
+    * {scope} are global."
+    */
+    if (elemR == elemB)
+	return (0);
+    /*
+    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
+    */
+    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
+	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
+	 return (1);
+    /*
+    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
+    * or is not fixed, or R's declaration's {value constraint} is fixed
+    * with the same value."
+    */
+    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
+	((elemR->value == NULL) ||
+	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
+	 /* TODO: Equality of the initial value or normalized or canonical? */
+	 (! xmlStrEqual(elemR->value, elemB->value))))
+	 return (1);
+    /*
+    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
+    * definitions} is a subset of B's declaration's {identity-constraint
+    * definitions}, if any."
+    */
+    if (elemB->idcs != NULL) {
+	/* TODO */
+    }
+    /*
+    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
+    * superset of B's declaration's {disallowed substitutions}."
+    */
+    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
+	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
+	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
+	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
+	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
+	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
+	 return (1);
+    /*
+    * SPEC (3.2.5) "R's {type definition} is validly derived given
+    * {extension, list, union} from B's {type definition}"
+    *
+    * BADSPEC TODO: What's the point of adding "list" and "union" to the
+    * set, if the corresponding constraints handle "restriction" and
+    * "extension" only?
+    *
+    */
+    {
+	int set = 0;
+
+	set |= SUBSET_EXTENSION;
+	set |= SUBSET_LIST;
+	set |= SUBSET_UNION;
+	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
+	    elemB->subtypes, set) != 0)
+	    return (1);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckRCaseNSCompat:
+ * @ctxt:  the schema parser context
+ * @r: the restricting element declaration particle
+ * @b: the base wildcard particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Derivation OK (Elt:Any -- NSCompat)
+ * (rcase-NSCompat)
+ *
+ * STATUS: complete
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
+			    xmlSchemaParticlePtr r,
+			    xmlSchemaParticlePtr b)
+{
+    /* TODO:Error codes (rcase-NSCompat). */
+    /*
+    * SPEC "For an element declaration particle to be a �valid restriction�
+    * of a wildcard particle all of the following must be true:"
+    *
+    * SPEC (1) "The element declaration's {target namespace} is �valid�
+    * with respect to the wildcard's {namespace constraint} as defined by
+    * Wildcard allows Namespace Name (�3.10.4)."
+    */
+    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
+	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
+	return (1);
+    /*
+    * SPEC (2) "R's occurrence range is a valid restriction of B's
+    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    */
+    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
+	    b->minOccurs, b->maxOccurs) != 0)
+	return (1);
+
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckRCaseRecurseAsIfGroup:
+ * @ctxt:  the schema parser context
+ * @r: the restricting element declaration particle
+ * @b: the base model group particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
+ * (rcase-RecurseAsIfGroup)
+ *
+ * STATUS: TODO
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
+				    xmlSchemaParticlePtr r,
+				    xmlSchemaParticlePtr b)
+{
+    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
+    TODO
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckRCaseNSSubset:
+ * @ctxt:  the schema parser context
+ * @r: the restricting wildcard particle
+ * @b: the base wildcard particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Derivation OK (Any:Any -- NSSubset)
+ * (rcase-NSSubset)
+ *
+ * STATUS: complete
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
+				    xmlSchemaParticlePtr r,
+				    xmlSchemaParticlePtr b,
+				    int isAnyTypeBase)
+{
+    /* TODO: Error codes (rcase-NSSubset). */
+    /*
+    * SPEC (1) "R's occurrence range is a valid restriction of B's
+    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    */
+    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
+	    b->minOccurs, b->maxOccurs))
+	return (1);
+    /*
+    * SPEC (2) "R's {namespace constraint} must be an intensional subset
+    * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
+    */
+    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
+	(xmlSchemaWildcardPtr) b->children))
+	return (1);
+    /*
+    * SPEC (3) "Unless B is the content model wildcard of the �ur-type
+    * definition�, R's {process contents} must be identical to or stronger
+    * than B's {process contents}, where strict is stronger than lax is
+    * stronger than skip."
+    */
+    if (! isAnyTypeBase) {
+	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
+	    ((xmlSchemaWildcardPtr) b->children)->processContents)
+	    return (1);
+    }
+
+    return (0);
+}
+
+/**
+ * xmlSchemaCheckCOSParticleRestrict:
+ * @ctxt:  the schema parser context
+ * @type:  the complex type definition
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Valid (Restriction) (cos-particle-restrict)
+ *
+ * STATUS: TODO
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
+				  xmlSchemaParticlePtr r,
+				  xmlSchemaParticlePtr b)
+{
+    int ret = 0;
+
+    /*part = WXS_TYPE_PARTICLE(type);
+    basePart = WXS_TYPE_PARTICLE(base);
+    */
+
+    TODO
+
+    /*
+    * SPEC (1) "They are the same particle."
+    */
+    if (r == b)
+	return (0);
+
+
+    return (0);
+}
+
+#if 0
+/**
+ * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
+ * @ctxt:  the schema parser context
+ * @r: the model group particle
+ * @b: the base wildcard particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Derivation OK (All/Choice/Sequence:Any --
+ *                         NSRecurseCheckCardinality)
+ * (rcase-NSRecurseCheckCardinality)
+ *
+ * STATUS: TODO: subst-groups
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
+					     xmlSchemaParticlePtr r,
+					     xmlSchemaParticlePtr b)
+{
+    xmlSchemaParticlePtr part;
+    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
+    if ((r->children == NULL) || (r->children->children == NULL))
+	return (-1);
+    /*
+    * SPEC "For a group particle to be a �valid restriction� of a
+    * wildcard particle..."
+    *
+    * SPEC (1) "Every member of the {particles} of the group is a �valid
+    * restriction� of the wildcard as defined by
+    * Particle Valid (Restriction) (�3.9.6)."
+    */
+    part = (xmlSchemaParticlePtr) r->children->children;
+    do {
+	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
+	    return (1);
+	part = (xmlSchemaParticlePtr) part->next;
+    } while (part != NULL);
+    /*
+    * SPEC (2) "The effective total range of the group [...] is a
+    * valid restriction of B's occurrence range as defined by
+    * Occurrence Range OK (�3.9.6)."
+    */
+    if (xmlSchemaCheckParticleRangeOK(
+	    xmlSchemaGetParticleTotalRangeMin(r),
+	    xmlSchemaGetParticleTotalRangeMax(r),
+	    b->minOccurs, b->maxOccurs) != 0)
+	return (1);
+    return (0);
+}
+#endif
+
+/**
+ * xmlSchemaCheckRCaseRecurse:
+ * @ctxt:  the schema parser context
+ * @r: the <all> or <sequence> model group particle
+ * @b: the base <all> or <sequence> model group particle
+ *
+ * (3.9.6) Constraints on Particle Schema Components
+ * Schema Component Constraint:
+ * Particle Derivation OK (All:All,Sequence:Sequence --
+                           Recurse)
+ * (rcase-Recurse)
+ *
+ * STATUS:  ?
+ * TODO: subst-groups
+ *
+ * Returns 0 if the constraints are satisfied, a positive
+ * error code if not and -1 if an internal error occured.
+ */
+static int
+xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
+			   xmlSchemaParticlePtr r,
+			   xmlSchemaParticlePtr b)
+{
+    /* xmlSchemaParticlePtr part; */
+    /* TODO: Error codes (rcase-Recurse). */
+    if ((r->children == NULL) || (b->children == NULL) ||
+	(r->children->type != b->children->type))
+	return (-1);
+    /*
+    * SPEC "For an all or sequence group particle to be a �valid
+    * restriction� of another group particle with the same {compositor}..."
+    *
+    * SPEC (1) "R's occurrence range is a valid restriction of B's
+    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    */
+    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
+	    b->minOccurs, b->maxOccurs))
+	return (1);
+
+
+    return (0);
+}
+
+#endif
+
+#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
+    xmlSchemaPCustomErrExt(pctxt,      \
+	XML_SCHEMAP_INVALID_FACET_VALUE, \
+	WXS_BASIC_CAST fac1, fac1->node, \
+	"It is an error for both '%s' and '%s' to be specified on the "\
+	"same type definition", \
+	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
+	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
+
+#define FACET_RESTR_ERR(fac1, msg) \
+    xmlSchemaPCustomErr(pctxt,      \
+	XML_SCHEMAP_INVALID_FACET_VALUE, \
+	WXS_BASIC_CAST fac1, fac1->node, \
+	msg, NULL);
+
+#define FACET_RESTR_FIXED_ERR(fac) \
+    xmlSchemaPCustomErr(pctxt, \
+	XML_SCHEMAP_INVALID_FACET_VALUE, \
+	WXS_BASIC_CAST fac, fac->node, \
+	"The base type's facet is 'fixed', thus the value must not " \
+	"differ", NULL);
+
+static void
+xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
+			xmlSchemaFacetPtr facet1,
+			xmlSchemaFacetPtr facet2,
+			int lessGreater,
+			int orEqual,
+			int ofBase)
+{
+    xmlChar *msg = NULL;
+
+    msg = xmlStrdup(BAD_CAST "'");
+    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
+    msg = xmlStrcat(msg, BAD_CAST "' has to be");
+    if (lessGreater == 0)
+	msg = xmlStrcat(msg, BAD_CAST " equal to");
+    if (lessGreater == 1)
+	msg = xmlStrcat(msg, BAD_CAST " greater than");
+    else
+	msg = xmlStrcat(msg, BAD_CAST " less than");
+
+    if (orEqual)
+	msg = xmlStrcat(msg, BAD_CAST " or equal to");
+    msg = xmlStrcat(msg, BAD_CAST " '");
+    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
+    if (ofBase)
+	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
+    else
+	msg = xmlStrcat(msg, BAD_CAST "'");
+
+    xmlSchemaPCustomErr(pctxt,
+	XML_SCHEMAP_INVALID_FACET_VALUE,
+	WXS_BASIC_CAST facet1, NULL,
+	(const char *) msg, NULL);
+
+    if (msg != NULL)
+	xmlFree(msg);
+}
+
+/*
+* xmlSchemaDeriveAndValidateFacets:
+*
+* Schema Component Constraint: Simple Type Restriction (Facets)
+* (st-restrict-facets)
+*/
+static int
+xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
+				 xmlSchemaTypePtr type)
+{
+    xmlSchemaTypePtr base = type->baseType;
+    xmlSchemaFacetLinkPtr link, cur, last = NULL;
+    xmlSchemaFacetPtr facet, bfacet,
+	flength = NULL, ftotdig = NULL, ffracdig = NULL,
+	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
+	fmininc = NULL, fmaxinc = NULL,
+	fminexc = NULL, fmaxexc = NULL,
+	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
+	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
+	bfmininc = NULL, bfmaxinc = NULL,
+	bfminexc = NULL, bfmaxexc = NULL;
+    int res; /* err = 0, fixedErr; */
+
+    /*
+    * SPEC st-restrict-facets 1:
+    * "The {variety} of R is the same as that of B."
+    */
+    /*
+    * SPEC st-restrict-facets 2:
+    * "If {variety} is atomic, the {primitive type definition}
+    * of R is the same as that of B."
+    *
+    * NOTE: we leave 1 & 2 out for now, since this will be
+    * satisfied by the derivation process.
+    * CONSTRUCTION TODO: Maybe needed if using a construction API.
+    */
+    /*
+    * SPEC st-restrict-facets 3:
+    * "The {facets} of R are the union of S and the {facets}
+    * of B, eliminating duplicates. To eliminate duplicates,
+    * when a facet of the same kind occurs in both S and the
+    * {facets} of B, the one in the {facets} of B is not
+    * included, with the exception of enumeration and pattern
+    * facets, for which multiple occurrences with distinct values
+    * are allowed."
+    */
+
+    if ((type->facetSet == NULL) && (base->facetSet == NULL))
+	return (0);
+
+    last = type->facetSet;
+    if (last != NULL)
+	while (last->next != NULL)
+	    last = last->next;
+
+    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
+	facet = cur->facet;
+	switch (facet->type) {
+	    case XML_SCHEMA_FACET_LENGTH:
+		flength = facet; break;
+	    case XML_SCHEMA_FACET_MINLENGTH:
+		fminlen = facet; break;
+	    case XML_SCHEMA_FACET_MININCLUSIVE:
+		fmininc = facet; break;
+	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
+		fminexc = facet; break;
+	    case XML_SCHEMA_FACET_MAXLENGTH:
+		fmaxlen = facet; break;
+	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
+		fmaxinc = facet; break;
+	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+		fmaxexc = facet; break;
+	    case XML_SCHEMA_FACET_TOTALDIGITS:
+		ftotdig = facet; break;
+	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
+		ffracdig = facet; break;
+	    default:
+		break;
+	}
+    }
+    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
+	facet = cur->facet;
+	switch (facet->type) {
+	    case XML_SCHEMA_FACET_LENGTH:
+		bflength = facet; break;
+	    case XML_SCHEMA_FACET_MINLENGTH:
+		bfminlen = facet; break;
+	    case XML_SCHEMA_FACET_MININCLUSIVE:
+		bfmininc = facet; break;
+	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
+		bfminexc = facet; break;
+	    case XML_SCHEMA_FACET_MAXLENGTH:
+		bfmaxlen = facet; break;
+	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
+		bfmaxinc = facet; break;
+	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+		bfmaxexc = facet; break;
+	    case XML_SCHEMA_FACET_TOTALDIGITS:
+		bftotdig = facet; break;
+	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
+		bffracdig = facet; break;
+	    default:
+		break;
+	}
+    }
+    /*
+    * length and minLength or maxLength (2.2) + (3.2)
+    */
+    if (flength && (fminlen || fmaxlen)) {
+	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
+	    "either of 'minLength' or 'maxLength' to be specified on "
+	    "the same type definition")
+    }
+    /*
+    * Mutual exclusions in the same derivation step.
+    */
+    if ((fmaxinc) && (fmaxexc)) {
+	/*
+	* SCC "maxInclusive and maxExclusive"
+	*/
+	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
+    }
+    if ((fmininc) && (fminexc)) {
+	/*
+	* SCC "minInclusive and minExclusive"
+	*/
+	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
+    }
+
+    if (flength && bflength) {
+	/*
+	* SCC "length valid restriction"
+	* The values have to be equal.
+	*/
+	res = xmlSchemaCompareValues(flength->val, bflength->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res != 0)
+	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
+	if ((res != 0) && (bflength->fixed)) {
+	    FACET_RESTR_FIXED_ERR(flength)
+	}
+
+    }
+    if (fminlen && bfminlen) {
+	/*
+	* SCC "minLength valid restriction"
+	* minLength >= BASE minLength
+	*/
+	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res == -1)
+	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
+	if ((res != 0) && (bfminlen->fixed)) {
+	    FACET_RESTR_FIXED_ERR(fminlen)
+	}
+    }
+    if (fmaxlen && bfmaxlen) {
+	/*
+	* SCC "maxLength valid restriction"
+	* maxLength <= BASE minLength
+	*/
+	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res == 1)
+	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
+	if ((res != 0) && (bfmaxlen->fixed)) {
+	    FACET_RESTR_FIXED_ERR(fmaxlen)
+	}
+    }
+    /*
+    * SCC "length and minLength or maxLength"
+    */
+    if (! flength)
+	flength = bflength;
+    if (flength) {
+	if (! fminlen)
+	    fminlen = bfminlen;
+	if (fminlen) {
+	    /* (1.1) length >= minLength */
+	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1)
+		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
+	}
+	if (! fmaxlen)
+	    fmaxlen = bfmaxlen;
+	if (fmaxlen) {
+	    /* (2.1) length <= maxLength */
+	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1)
+		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
+	}
+    }
+    if (fmaxinc) {
+	/*
+	* "maxInclusive"
+	*/
+	if (fmininc) {
+	    /* SCC "maxInclusive >= minInclusive" */
+	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
+	    }
+	}
+	/*
+	* SCC "maxInclusive valid restriction"
+	*/
+	if (bfmaxinc) {
+	    /* maxInclusive <= BASE maxInclusive */
+	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1)
+		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
+	    if ((res != 0) && (bfmaxinc->fixed)) {
+		FACET_RESTR_FIXED_ERR(fmaxinc)
+	    }
+	}
+	if (bfmaxexc) {
+	    /* maxInclusive < BASE maxExclusive */
+	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
+	    }
+	}
+	if (bfmininc) {
+	    /* maxInclusive >= BASE minInclusive */
+	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
+	    }
+	}
+	if (bfminexc) {
+	    /* maxInclusive > BASE minExclusive */
+	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
+	    }
+	}
+    }
+    if (fmaxexc) {
+	/*
+	* "maxExclusive >= minExclusive"
+	*/
+	if (fminexc) {
+	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
+	    }
+	}
+	/*
+	* "maxExclusive valid restriction"
+	*/
+	if (bfmaxexc) {
+	    /* maxExclusive <= BASE maxExclusive */
+	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
+	    }
+	    if ((res != 0) && (bfmaxexc->fixed)) {
+		FACET_RESTR_FIXED_ERR(fmaxexc)
+	    }
+	}
+	if (bfmaxinc) {
+	    /* maxExclusive <= BASE maxInclusive */
+	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
+	    }
+	}
+	if (bfmininc) {
+	    /* maxExclusive > BASE minInclusive */
+	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
+	    }
+	}
+	if (bfminexc) {
+	    /* maxExclusive > BASE minExclusive */
+	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
+	    }
+	}
+    }
+    if (fminexc) {
+	/*
+	* "minExclusive < maxInclusive"
+	*/
+	if (fmaxinc) {
+	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
+	    }
+	}
+	/*
+	* "minExclusive valid restriction"
+	*/
+	if (bfminexc) {
+	    /* minExclusive >= BASE minExclusive */
+	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
+	    }
+	    if ((res != 0) && (bfminexc->fixed)) {
+		FACET_RESTR_FIXED_ERR(fminexc)
+	    }
+	}
+	if (bfmaxinc) {
+	    /* minExclusive <= BASE maxInclusive */
+	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
+	    }
+	}
+	if (bfmininc) {
+	    /* minExclusive >= BASE minInclusive */
+	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
+	    }
+	}
+	if (bfmaxexc) {
+	    /* minExclusive < BASE maxExclusive */
+	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
+	    }
+	}
+    }
+    if (fmininc) {
+	/*
+	* "minInclusive < maxExclusive"
+	*/
+	if (fmaxexc) {
+	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
+	    }
+	}
+	/*
+	* "minExclusive valid restriction"
+	*/
+	if (bfmininc) {
+	    /* minInclusive >= BASE minInclusive */
+	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == -1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
+	    }
+	    if ((res != 0) && (bfmininc->fixed)) {
+		FACET_RESTR_FIXED_ERR(fmininc)
+	    }
+	}
+	if (bfmaxinc) {
+	    /* minInclusive <= BASE maxInclusive */
+	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res == 1) {
+		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
+	    }
+	}
+	if (bfminexc) {
+	    /* minInclusive > BASE minExclusive */
+	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != 1)
+		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
+	}
+	if (bfmaxexc) {
+	    /* minInclusive < BASE maxExclusive */
+	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
+	    if (res == -2)
+		goto internal_error;
+	    if (res != -1)
+		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
+	}
+    }
+    if (ftotdig && bftotdig) {
+	/*
+	* SCC " totalDigits valid restriction"
+	* totalDigits <= BASE totalDigits
+	*/
+	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res == 1)
+	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
+	    -1, 1, 1);
+	if ((res != 0) && (bftotdig->fixed)) {
+	    FACET_RESTR_FIXED_ERR(ftotdig)
+	}
+    }
+    if (ffracdig && bffracdig) {
+	/*
+	* SCC  "fractionDigits valid restriction"
+	* fractionDigits <= BASE fractionDigits
+	*/
+	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res == 1)
+	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
+	    -1, 1, 1);
+	if ((res != 0) && (bffracdig->fixed)) {
+	    FACET_RESTR_FIXED_ERR(ffracdig)
+	}
+    }
+    /*
+    * SCC "fractionDigits less than or equal to totalDigits"
+    */
+    if (! ftotdig)
+	ftotdig = bftotdig;
+    if (! ffracdig)
+	ffracdig = bffracdig;
+    if (ftotdig && ffracdig) {
+	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
+	if (res == -2)
+	    goto internal_error;
+	if (res == 1)
+	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
+		-1, 1, 0);
+    }
+    /*
+    * *Enumerations* won' be added here, since only the first set
+    * of enumerations in the ancestor-or-self axis is used
+    * for validation, plus we need to use the base type of those
+    * enumerations for whitespace.
+    *
+    * *Patterns*: won't be add here, since they are ORed at
+    * type level and ANDed at ancestor level. This will
+    * happed during validation by walking the base axis
+    * of the type.
+    */
+    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
+	bfacet = cur->facet;
+	/*
+	* Special handling of enumerations and patterns.
+	* TODO: hmm, they should not appear in the set, so remove this.
+	*/
+	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
+	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
+	    continue;
+	/*
+	* Search for a duplicate facet in the current type.
+	*/
+	link = type->facetSet;
+	/* err = 0; */
+	/* fixedErr = 0; */
+	while (link != NULL) {
+	    facet = link->facet;
+	    if (facet->type == bfacet->type) {
+		switch (facet->type) {
+		    case XML_SCHEMA_FACET_WHITESPACE:
+			/*
+			* The whitespace must be stronger.
+			*/
+			if (facet->whitespace < bfacet->whitespace) {
+			    FACET_RESTR_ERR(facet,
+				"The 'whitespace' value has to be equal to "
+				"or stronger than the 'whitespace' value of "
+				"the base type")
+			}
+			if ((bfacet->fixed) &&
+			    (facet->whitespace != bfacet->whitespace)) {
+			    FACET_RESTR_FIXED_ERR(facet)
+			}
+			break;
+		    default:
+			break;
+		}
+		/* Duplicate found. */
+		break;
+	    }
+	    link = link->next;
+	}
+	/*
+	* If no duplicate was found: add the base types's facet
+	* to the set.
+	*/
+	if (link == NULL) {
+	    link = (xmlSchemaFacetLinkPtr)
+		xmlMalloc(sizeof(xmlSchemaFacetLink));
+	    if (link == NULL) {
+		xmlSchemaPErrMemory(pctxt,
+		    "deriving facets, creating a facet link", NULL);
+		return (-1);
+	    }
+	    link->facet = cur->facet;
+	    link->next = NULL;
+	    if (last == NULL)
+		type->facetSet = link;
+	    else
+		last->next = link;
+	    last = link;
+	}
+
+    }
+
+    return (0);
+internal_error:
+    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
+	"an error occured");
+    return (-1);
+}
+
+static int
+xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
+					     xmlSchemaTypePtr type)
+{
+    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
+    /*
+    * The actual value is then formed by replacing any union type
+    * definition in the �explicit members� with the members of their
+    * {member type definitions}, in order.
+    *
+    * TODO: There's a bug entry at
+    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
+    * which indicates that we'll keep the union types the future.
+    */
+    link = type->memberTypes;
+    while (link != NULL) {
+
+	if (WXS_IS_TYPE_NOT_FIXED(link->type))
+	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
+
+	if (WXS_IS_UNION(link->type)) {
+	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
+	    if (subLink != NULL) {
+		link->type = subLink->type;
+		if (subLink->next != NULL) {
+		    lastLink = link->next;
+		    subLink = subLink->next;
+		    prevLink = link;
+		    while (subLink != NULL) {
+			newLink = (xmlSchemaTypeLinkPtr)
+			    xmlMalloc(sizeof(xmlSchemaTypeLink));
+			if (newLink == NULL) {
+			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
+				NULL);
+			    return (-1);
+			}
+			newLink->type = subLink->type;
+			prevLink->next = newLink;
+			prevLink = newLink;
+			newLink->next = lastLink;
+
+			subLink = subLink->next;
+		    }
+		}
+	    }
+	}
+	link = link->next;
+    }
+    return (0);
+}
+
+static void
+xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
+{
+    int has = 0, needVal = 0, normVal = 0;
+
+    has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
+    if (has) {
+	needVal = (type->baseType->flags &
+	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
+	normVal = (type->baseType->flags &
+	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
+    }
+    if (type->facets != NULL) {
+	xmlSchemaFacetPtr fac;
+
+	for (fac = type->facets; fac != NULL; fac = fac->next) {
+	    switch (fac->type) {
+		case XML_SCHEMA_FACET_WHITESPACE:
+		    break;
+		case XML_SCHEMA_FACET_PATTERN:
+		    normVal = 1;
+		    has = 1;
+		    break;
+		case XML_SCHEMA_FACET_ENUMERATION:
+		    needVal = 1;
+		    normVal = 1;
+		    has = 1;
+		    break;
+		default:
+		    has = 1;
+		    break;
+	    }
+	}
+    }
+    if (normVal)
+	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
+    if (needVal)
+	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
+    if (has)
+	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
+
+    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
+	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
+	/*
+	* OPTIMIZE VAL TODO: Some facets need a computed value.
+	*/
+	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
+	    (prim->builtInType != XML_SCHEMAS_STRING)) {
+	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
+	}
+    }
+}
+
+static int
+xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
+{
+
+
+    /*
+    * Evaluate the whitespace-facet value.
+    */
+    if (WXS_IS_LIST(type)) {
+	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
+	return (0);
+    } else if (WXS_IS_UNION(type))
+	return (0);
+
+    if (type->facetSet != NULL) {
+	xmlSchemaFacetLinkPtr lin;
+
+	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
+	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
+		switch (lin->facet->whitespace) {
+		case XML_SCHEMAS_FACET_PRESERVE:
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
+		    break;
+		case XML_SCHEMAS_FACET_REPLACE:
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
+		    break;
+		case XML_SCHEMAS_FACET_COLLAPSE:
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
+		    break;
+		default:
+		    return (-1);
+		}
+		return (0);
+	    }
+	}
+    }
+    /*
+    * For all �atomic� datatypes other than string (and types �derived�
+    * by �restriction� from it) the value of whiteSpace is fixed to
+    * collapse
+    */
+    {
+	xmlSchemaTypePtr anc;
+
+	for (anc = type->baseType; anc != NULL &&
+		anc->builtInType != XML_SCHEMAS_ANYTYPE;
+		anc = anc->baseType) {
+
+	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
+		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
+
+		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
+		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
+
+		} else
+		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
+		break;
+	    }
+	}
+    }
+    return (0);
+}
+
+static int
+xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
+			  xmlSchemaTypePtr type)
+{
+    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
+	return(0);
+    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
+	return(0);
+    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
+
+    if (WXS_IS_LIST(type)) {
+	/*
+	* Corresponds to <simpleType><list>...
+	*/
+	if (type->subtypes == NULL) {
+	    /*
+	    * This one is really needed, so get out.
+	    */
+	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
+		"list type has no item-type assigned");
+	    return(-1);
+	}
+    } else if (WXS_IS_UNION(type)) {
+	/*
+	* Corresponds to <simpleType><union>...
+	*/
+	if (type->memberTypes == NULL) {
+	    /*
+	    * This one is really needed, so get out.
+	    */
+	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
+		"union type has no member-types assigned");
+	    return(-1);
+	}
+    } else {
+	/*
+	* Corresponds to <simpleType><restriction>...
+	*/
+	if (type->baseType == NULL) {
+	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
+		"type has no base-type assigned");
+	    return(-1);
+	}
+	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
+	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
+		return(-1);
+	/*
+	* Variety
+	* If the <restriction> alternative is chosen, then the
+	* {variety} of the {base type definition}.
+	*/
+	if (WXS_IS_ATOMIC(type->baseType))
+	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
+	else if (WXS_IS_LIST(type->baseType)) {
+	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+	    /*
+	    * Inherit the itemType.
+	    */
+	    type->subtypes = type->baseType->subtypes;
+	} else if (WXS_IS_UNION(type->baseType)) {
+	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
+	    /*
+	    * NOTE that we won't assign the memberTypes of the base,
+	    * since this will make trouble when freeing them; we will
+	    * use a lookup function to access them instead.
+	    */
+	}
+    }
+    return(0);
+}
+
+#ifdef DEBUG_TYPE
+static void
+xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
+		       xmlSchemaTypePtr type)
+{
+    if (type->node != NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                        "Type of %s : %s:%d :", name,
+                        type->node->doc->URL,
+                        xmlGetLineNo(type->node));
+    } else {
+        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
+    }
+    if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
+	switch (type->contentType) {
+	    case XML_SCHEMA_CONTENT_SIMPLE:
+		xmlGenericError(xmlGenericErrorContext, "simple\n");
+		break;
+	    case XML_SCHEMA_CONTENT_ELEMENTS:
+		xmlGenericError(xmlGenericErrorContext, "elements\n");
+		break;
+	    case XML_SCHEMA_CONTENT_UNKNOWN:
+		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
+		break;
+	    case XML_SCHEMA_CONTENT_EMPTY:
+		xmlGenericError(xmlGenericErrorContext, "empty\n");
+		break;
+	    case XML_SCHEMA_CONTENT_MIXED:
+		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
+		    type->subtypes))
+		    xmlGenericError(xmlGenericErrorContext,
+			"mixed as emptiable particle\n");
+		else
+		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
+		break;
+		/* Removed, since not used. */
+		/*
+		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
+		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
+		break;
+		*/
+	    case XML_SCHEMA_CONTENT_BASIC:
+		xmlGenericError(xmlGenericErrorContext, "basic\n");
+		break;
+	    default:
+		xmlGenericError(xmlGenericErrorContext,
+		    "not registered !!!\n");
+		break;
+	}
+    }
+}
+#endif
+
+/*
+* 3.14.6 Constraints on Simple Type Definition Schema Components
+*/
+static int
+xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
+				 xmlSchemaTypePtr type)
+{
+    int res, olderrs = pctxt->nberrors;
+
+    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
+	return(-1);
+
+    if (! WXS_IS_TYPE_NOT_FIXED(type))
+	return(0);
+
+    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
+    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+
+    if (type->baseType == NULL) {
+	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
+	    "missing baseType");
+	goto exit_failure;
+    }
+    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
+	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
+    /*
+    * If a member type of a union is a union itself, we need to substitute
+    * that member type for its member types.
+    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
+    * types in WXS 1.1.
+    */
+    if ((type->memberTypes != NULL) &&
+	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
+	return(-1);
+    /*
+    * SPEC src-simple-type 1
+    * "The corresponding simple type definition, if any, must satisfy
+    * the conditions set out in Constraints on Simple Type Definition
+    * Schema Components (�3.14.6)."
+    */
+    /*
+    * Schema Component Constraint: Simple Type Definition Properties Correct
+    * (st-props-correct)
+    */
+    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
+    HFAILURE HERROR
+    /*
+    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
+    * (cos-st-restricts)
+    */
+    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
+    HFAILURE HERROR
+    /*
+    * TODO: Removed the error report, since it got annoying to get an
+    * extra error report, if anything failed until now.
+    * Enable this if needed.
+    *
+    * xmlSchemaPErr(ctxt, type->node,
+    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
+    *    "Simple type '%s' does not satisfy the constraints "
+    *    "on simple type definitions.\n",
+    *    type->name, NULL);
+    */
+    /*
+    * Schema Component Constraint: Simple Type Restriction (Facets)
+    * (st-restrict-facets)
+    */
+    res = xmlSchemaCheckFacetValues(type, pctxt);
+    HFAILURE HERROR
+    if ((type->facetSet != NULL) ||
+	(type->baseType->facetSet != NULL)) {
+	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
+	HFAILURE HERROR
+    }
+    /*
+    * Whitespace value.
+    */
+    res = xmlSchemaTypeFixupWhitespace(type);
+    HFAILURE HERROR
+    xmlSchemaTypeFixupOptimFacets(type);
+
+exit_error:
+#ifdef DEBUG_TYPE
+    xmlSchemaDebugFixedType(pctxt, type);
+#endif
+    if (olderrs != pctxt->nberrors)
+	return(pctxt->err);
+    return(0);
+
+exit_failure:
+#ifdef DEBUG_TYPE
+    xmlSchemaDebugFixedType(pctxt, type);
+#endif
+    return(-1);
+}
+
+static int
+xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
+			  xmlSchemaTypePtr type)
+{
+    int res = 0, olderrs = pctxt->nberrors;
+    xmlSchemaTypePtr baseType = type->baseType;
+
+    if (! WXS_IS_TYPE_NOT_FIXED(type))
+	return(0);
+    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
+    if (baseType == NULL) {
+	PERROR_INT("xmlSchemaFixupComplexType",
+	    "missing baseType");
+	goto exit_failure;
+    }
+    /*
+    * Fixup the base type.
+    */
+    if (WXS_IS_TYPE_NOT_FIXED(baseType))
+	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
+    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
+	/*
+	* Skip fixup if the base type is invalid.
+	* TODO: Generate a warning!
+	*/
+	return(0);
+    }
+    /*
+    * This basically checks if the base type can be derived.
+    */
+    res = xmlSchemaCheckSRCCT(pctxt, type);
+    HFAILURE HERROR
+    /*
+    * Fixup the content type.
+    */
+    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
+	/*
+	* Corresponds to <complexType><simpleContent>...
+	*/
+	if ((WXS_IS_COMPLEX(baseType)) &&
+	    (baseType->contentTypeDef != NULL) &&
+	    (WXS_IS_RESTRICTION(type))) {
+	    xmlSchemaTypePtr contentBase, content;
+#ifdef ENABLE_NAMED_LOCALS
+	    char buf[30];
+	    const xmlChar *tmpname;
+#endif
+	    /*
+	    * SPEC (1) If <restriction> + base type is <complexType>,
+	    * "whose own {content type} is a simple type..."
+	    */
+	    if (type->contentTypeDef != NULL) {
+		/*
+		* SPEC (1.1) "the simple type definition corresponding to the
+		* <simpleType> among the [children] of <restriction> if there
+		* is one;"
+		* Note that this "<simpleType> among the [children]" was put
+		* into ->contentTypeDef during parsing.
+		*/
+		contentBase = type->contentTypeDef;
+		type->contentTypeDef = NULL;
+	    } else {
+		/*
+		* (1.2) "...otherwise (<restriction> has no <simpleType>
+		* among its [children]), the simple type definition which
+		* is the {content type} of the ... base type."
+		*/
+		contentBase = baseType->contentTypeDef;
+	    }
+	    /*
+	    * SPEC
+	    * "... a simple type definition which restricts the simple
+	    * type definition identified in clause 1.1 or clause 1.2
+	    * with a set of facet components"
+	    *
+	    * Create the anonymous simple type, which will be the content
+	    * type of the complex type.
+	    */
+#ifdef ENABLE_NAMED_LOCALS
+	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
+	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
+	    content = xmlSchemaAddType(pctxt, pctxt->schema,
+		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
+		type->node, 0);
+#else
+	    content = xmlSchemaAddType(pctxt, pctxt->schema,
+		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
+		type->node, 0);
+#endif
+	    if (content == NULL)
+		goto exit_failure;
+	    /*
+	    * We will use the same node as for the <complexType>
+	    * to have it somehow anchored in the schema doc.
+	    */
+	    content->type = XML_SCHEMA_TYPE_SIMPLE;
+	    content->baseType = contentBase;
+	    /*
+	    * Move the facets, previously anchored on the
+	    * complexType during parsing.
+	    */
+	    content->facets = type->facets;
+	    type->facets = NULL;
+	    content->facetSet = type->facetSet;
+	    type->facetSet = NULL;
+
+	    type->contentTypeDef = content;
+	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
+		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
+	    /*
+	    * Fixup the newly created type. We don't need to check
+	    * for circularity here.
+	    */
+	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
+	    HFAILURE HERROR
+	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
+	    HFAILURE HERROR
+
+	} else if ((WXS_IS_COMPLEX(baseType)) &&
+	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+	    (WXS_IS_RESTRICTION(type))) {
+	    /*
+	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
+	    * an emptiable particle, then a simple type definition which
+	    * restricts the <restriction>'s <simpleType> child.
+	    */
+	    if ((type->contentTypeDef == NULL) ||
+		(type->contentTypeDef->baseType == NULL)) {
+		/*
+		* TODO: Check if this ever happens.
+		*/
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_INTERNAL,
+		    WXS_BASIC_CAST type, NULL,
+		    "Internal error: xmlSchemaTypeFixup, "
+		    "complex type '%s': the <simpleContent><restriction> "
+		    "is missing a <simpleType> child, but was not catched "
+		    "by xmlSchemaCheckSRCCT()", type->name);
+		goto exit_failure;
+	    }
+	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
+	    /*
+	    * SPEC (3) If <extension> + base is <complexType> with
+	    * <simpleType> content, "...then the {content type} of that
+	    * complex type definition"
+	    */
+	    if (baseType->contentTypeDef == NULL) {
+		/*
+		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
+		* should have catched this already.
+		*/
+		xmlSchemaPCustomErr(pctxt,
+		    XML_SCHEMAP_INTERNAL,
+		    WXS_BASIC_CAST type, NULL,
+		    "Internal error: xmlSchemaTypeFixup, "
+		    "complex type '%s': the <extension>ed base type is "
+		    "a complex type with no simple content type",
+		    type->name);
+		goto exit_failure;
+	    }
+	    type->contentTypeDef = baseType->contentTypeDef;
+	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
+	    /*
+	    * SPEC (4) <extension> + base is <simpleType>
+	    * "... then that simple type definition"
+	    */
+	    type->contentTypeDef = baseType;
+	} else {
+	    /*
+	    * TODO: Check if this ever happens.
+	    */
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_INTERNAL,
+		WXS_BASIC_CAST type, NULL,
+		"Internal error: xmlSchemaTypeFixup, "
+		"complex type '%s' with <simpleContent>: unhandled "
+		"derivation case", type->name);
+	    goto exit_failure;
+	}
+    } else {
+	int dummySequence = 0;
+	xmlSchemaParticlePtr particle =
+	    (xmlSchemaParticlePtr) type->subtypes;
+	/*
+	* Corresponds to <complexType><complexContent>...
+	*
+	* NOTE that the effective mixed was already set during parsing of
+	* <complexType> and <complexContent>; its flag value is
+	* XML_SCHEMAS_TYPE_MIXED.
+	*
+	* Compute the "effective content":
+	* (2.1.1) + (2.1.2) + (2.1.3)
+	*/
+	if ((particle == NULL) ||
+	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
+	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
+	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
+	    (particle->minOccurs == 0))) &&
+	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
+	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
+		/*
+		* SPEC (2.1.4) "If the �effective mixed� is true, then
+		* a particle whose properties are as follows:..."
+		*
+		* Empty sequence model group with
+		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
+		* NOTE that we sill assign it the <complexType> node to
+		* somehow anchor it in the doc.
+		*/
+		if ((particle == NULL) ||
+		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
+		    /*
+		    * Create the particle.
+		    */
+		    particle = xmlSchemaAddParticle(pctxt,
+			type->node, 1, 1);
+		    if (particle == NULL)
+			goto exit_failure;
+		    /*
+		    * Create the model group.
+		    */ /* URGENT TODO: avoid adding to pending items. */
+		    particle->children = (xmlSchemaTreeItemPtr)
+			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
+			XML_SCHEMA_TYPE_SEQUENCE, type->node);
+		    if (particle->children == NULL)
+			goto exit_failure;
+
+		    type->subtypes = (xmlSchemaTypePtr) particle;
+		}
+		dummySequence = 1;
+		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
+	    } else {
+		/*
+		* SPEC (2.1.5) "otherwise empty"
+		*/
+		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
+	    }
+	} else {
+	    /*
+	    * SPEC (2.2) "otherwise the particle corresponding to the
+	    * <all>, <choice>, <group> or <sequence> among the
+	    * [children]."
+	    */
+	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
+	}
+	/*
+	* Compute the "content type".
+	*/
+	if (WXS_IS_RESTRICTION(type)) {
+	    /*
+	    * SPEC (3.1) "If <restriction>..."
+	    * (3.1.1) + (3.1.2) */
+	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
+		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
+	    }
+	} else {
+	    /*
+	    * SPEC (3.2) "If <extension>..."
+	    */
+	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+		/*
+		* SPEC (3.2.1)
+		* "If the �effective content� is empty, then the
+		*  {content type} of the [...] base ..."
+		*/
+		type->contentType = baseType->contentType;
+		type->subtypes = baseType->subtypes;
+		/*
+		* Fixes bug #347316:
+		* This is the case when the base type has a simple
+		* type definition as content.
+		*/
+		type->contentTypeDef = baseType->contentTypeDef;
+		/*
+		* NOTE that the effective mixed is ignored here.
+		*/
+	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
+		/*
+		* SPEC (3.2.2)
+		*/
+		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
+	    } else {
+		/*
+		* SPEC (3.2.3)
+		*/
+		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
+		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
+		    /*
+		    * "A model group whose {compositor} is sequence and whose
+		    * {particles} are..."
+		    */
+		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
+		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
+		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
+			XML_SCHEMA_TYPE_ALL))
+		{
+		    /*
+		    * SPEC cos-all-limited (1)
+		    */
+		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			/* TODO: error code */
+			XML_SCHEMAP_COS_ALL_LIMITED,
+			WXS_ITEM_NODE(type), NULL,
+			"The type has an 'all' model group in its "
+			"{content type} and thus cannot be derived from "
+			"a non-empty type, since this would produce a "
+			"'sequence' model group containing the 'all' "
+			"model group; 'all' model groups are not "
+			"allowed to appear inside other model groups",
+			NULL, NULL);
+
+		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
+		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
+		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
+			XML_SCHEMA_TYPE_ALL))
+		{
+		    /*
+		    * SPEC cos-all-limited (1)
+		    */
+		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			/* TODO: error code */
+			XML_SCHEMAP_COS_ALL_LIMITED,
+			WXS_ITEM_NODE(type), NULL,
+			"A type cannot be derived by extension from a type "
+			"which has an 'all' model group in its "
+			"{content type}, since this would produce a "
+			"'sequence' model group containing the 'all' "
+			"model group; 'all' model groups are not "
+			"allowed to appear inside other model groups",
+			NULL, NULL);
+
+		} else if (! dummySequence) {
+		    xmlSchemaTreeItemPtr effectiveContent =
+			(xmlSchemaTreeItemPtr) type->subtypes;
+		    /*
+		    * Create the particle.
+		    */
+		    particle = xmlSchemaAddParticle(pctxt,
+			type->node, 1, 1);
+		    if (particle == NULL)
+			goto exit_failure;
+		    /*
+		    * Create the "sequence" model group.
+		    */
+		    particle->children = (xmlSchemaTreeItemPtr)
+			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
+			XML_SCHEMA_TYPE_SEQUENCE, type->node);
+		    if (particle->children == NULL)
+			goto exit_failure;
+		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
+		    /*
+		    * SPEC "the particle of the {content type} of
+		    * the ... base ..."
+		    * Create a duplicate of the base type's particle
+		    * and assign its "term" to it.
+		    */
+		    particle->children->children =
+			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
+			type->node,
+			((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
+			((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
+		    if (particle->children->children == NULL)
+			goto exit_failure;
+		    particle = (xmlSchemaParticlePtr)
+			particle->children->children;
+		    particle->children =
+			((xmlSchemaParticlePtr) baseType->subtypes)->children;
+		    /*
+		    * SPEC "followed by the �effective content�."
+		    */
+		    particle->next = effectiveContent;
+		    /*
+		    * This all will result in:
+		    * new-particle
+		    *   --> new-sequence(
+		    *         new-particle
+		    *           --> base-model,
+		    *         this-particle
+		    *	        --> this-model
+		    *	    )
+		    */
+		} else {
+		    /*
+		    * This is the case when there is already an empty
+		    * <sequence> with minOccurs==maxOccurs==1.
+		    * Just add the base types's content type.
+		    * NOTE that, although we miss to add an intermediate
+		    * <sequence>, this should produce no difference to
+		    * neither the regex compilation of the content model,
+		    * nor to the complex type contraints.
+		    */
+		    particle->children->children =
+			(xmlSchemaTreeItemPtr) baseType->subtypes;
+		}
+	    }
+	}
+    }
+    /*
+    * Now fixup attribute uses:
+    *   - expand attr. group references
+    *     - intersect attribute wildcards
+    *   - inherit attribute uses of the base type
+    *   - inherit or union attr. wildcards if extending
+    *   - apply attr. use prohibitions if restricting
+    */
+    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
+    HFAILURE HERROR
+    /*
+    * Apply the complex type component constraints; this will not
+    * check attributes, since this is done in
+    * xmlSchemaFixupTypeAttributeUses().
+    */
+    res = xmlSchemaCheckCTComponent(pctxt, type);
+    HFAILURE HERROR
+
+#ifdef DEBUG_TYPE
+    xmlSchemaDebugFixedType(pctxt, type);
+#endif
+    if (olderrs != pctxt->nberrors)
+	return(pctxt->err);
+    else
+	return(0);
+
+exit_error:
+    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
+#ifdef DEBUG_TYPE
+    xmlSchemaDebugFixedType(pctxt, type);
+#endif
+    return(pctxt->err);
+
+exit_failure:
+    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
+#ifdef DEBUG_TYPE
+    xmlSchemaDebugFixedType(pctxt, type);
+#endif
+    return(-1);
+}
+
+
+/**
+ * xmlSchemaTypeFixup:
+ * @typeDecl:  the schema type definition
+ * @ctxt:  the schema parser context
+ *
+ * Fixes the content model of the type.
+ * URGENT TODO: We need an int result!
+ */
+static int
+xmlSchemaTypeFixup(xmlSchemaTypePtr type,
+                   xmlSchemaAbstractCtxtPtr actxt)
+{
+    if (type == NULL)
+        return(0);
+    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
+	AERROR_INT("xmlSchemaTypeFixup",
+	    "this function needs a parser context");
+	return(-1);
+    }
+    if (! WXS_IS_TYPE_NOT_FIXED(type))
+	return(0);
+    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
+	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
+    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
+	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
+    return(0);
+}
+
+/**
+ * xmlSchemaCheckFacet:
+ * @facet:  the facet
+ * @typeDecl:  the schema type definition
+ * @pctxt:  the schema parser context or NULL
+ * @name: the optional name of the type
+ *
+ * Checks and computes the values of facets.
+ *
+ * Returns 0 if valid, a positive error code if not valid and
+ *         -1 in case of an internal or API error.
+ */
+int
+xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
+                    xmlSchemaTypePtr typeDecl,
+                    xmlSchemaParserCtxtPtr pctxt,
+		    const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    int ret = 0, ctxtGiven;
+
+    if ((facet == NULL) || (typeDecl == NULL))
+        return(-1);
+    /*
+    * TODO: will the parser context be given if used from
+    * the relaxNG module?
+    */
+    if (pctxt == NULL)
+	ctxtGiven = 0;
+    else
+	ctxtGiven = 1;
+
+    switch (facet->type) {
+        case XML_SCHEMA_FACET_MININCLUSIVE:
+        case XML_SCHEMA_FACET_MINEXCLUSIVE:
+        case XML_SCHEMA_FACET_MAXINCLUSIVE:
+        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+	case XML_SCHEMA_FACET_ENUMERATION: {
+                /*
+                 * Okay we need to validate the value
+                 * at that point.
+                 */
+		xmlSchemaTypePtr base;
+
+		/* 4.3.5.5 Constraints on enumeration Schema Components
+		* Schema Component Constraint: enumeration valid restriction
+		* It is an �error� if any member of {value} is not in the
+		* �value space� of {base type definition}.
+		*
+		* minInclusive, maxInclusive, minExclusive, maxExclusive:
+		* The value �must� be in the
+		* �value space� of the �base type�.
+		*/
+		/*
+		* This function is intended to deliver a compiled value
+		* on the facet. In this implementation of XML Schemata the
+		* type holding a facet, won't be a built-in type.
+		* Thus to ensure that other API
+		* calls (relaxng) do work, if the given type is a built-in
+		* type, we will assume that the given built-in type *is
+		* already* the base type.
+		*/
+		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
+		    base = typeDecl->baseType;
+		    if (base == NULL) {
+			PERROR_INT("xmlSchemaCheckFacet",
+			    "a type user derived type has no base type");
+			return (-1);
+		    }
+		} else
+		    base = typeDecl;
+
+		if (! ctxtGiven) {
+		    /*
+		    * A context is needed if called from RelaxNG.
+		    */
+		    pctxt = xmlSchemaNewParserCtxt("*");
+		    if (pctxt == NULL)
+			return (-1);
+		}
+		/*
+		* NOTE: This call does not check the content nodes,
+		* since they are not available:
+		* facet->node is just the node holding the facet
+		* definition, *not* the attribute holding the *value*
+		* of the facet.
+		*/
+		ret = xmlSchemaVCheckCVCSimpleType(
+		    ACTXT_CAST pctxt, facet->node, base,
+		    facet->value, &(facet->val), 1, 1, 0);
+                if (ret != 0) {
+		    if (ret < 0) {
+			/* No error message for RelaxNG. */
+			if (ctxtGiven) {
+			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+				XML_SCHEMAP_INTERNAL, facet->node, NULL,
+				"Internal error: xmlSchemaCheckFacet, "
+				"failed to validate the value '%s' of the "
+				"facet '%s' against the base type",
+				facet->value, xmlSchemaFacetTypeToString(facet->type));
+			}
+			goto internal_error;
+		    }
+		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
+		    /* No error message for RelaxNG. */
+		    if (ctxtGiven) {
+			xmlChar *str = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    ret, facet->node, WXS_BASIC_CAST facet,
+			    "The value '%s' of the facet does not validate "
+			    "against the base type '%s'",
+			    facet->value,
+			    xmlSchemaFormatQName(&str,
+				base->targetNamespace, base->name));
+			FREE_AND_NULL(str);
+		    }
+		    goto exit;
+                } else if (facet->val == NULL) {
+		    if (ctxtGiven) {
+			PERROR_INT("xmlSchemaCheckFacet",
+			    "value was not computed");
+		    }
+		    TODO
+		}
+                break;
+            }
+        case XML_SCHEMA_FACET_PATTERN:
+            facet->regexp = xmlRegexpCompile(facet->value);
+            if (facet->regexp == NULL) {
+		ret = XML_SCHEMAP_REGEXP_INVALID;
+		/* No error message for RelaxNG. */
+		if (ctxtGiven) {
+		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			ret, facet->node, WXS_BASIC_CAST typeDecl,
+			"The value '%s' of the facet 'pattern' is not a "
+			"valid regular expression",
+			facet->value, NULL);
+		}
+            }
+            break;
+        case XML_SCHEMA_FACET_TOTALDIGITS:
+        case XML_SCHEMA_FACET_FRACTIONDIGITS:
+        case XML_SCHEMA_FACET_LENGTH:
+        case XML_SCHEMA_FACET_MAXLENGTH:
+        case XML_SCHEMA_FACET_MINLENGTH:
+
+	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
+		ret = xmlSchemaValidatePredefinedType(
+		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
+		    facet->value, &(facet->val));
+	    } else {
+		ret = xmlSchemaValidatePredefinedType(
+		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
+		    facet->value, &(facet->val));
+	    }
+	    if (ret != 0) {
+		if (ret < 0) {
+		    /* No error message for RelaxNG. */
+		    if (ctxtGiven) {
+			PERROR_INT("xmlSchemaCheckFacet",
+			    "validating facet value");
+		    }
+		    goto internal_error;
+		}
+		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
+		/* No error message for RelaxNG. */
+		if (ctxtGiven) {
+		    /* error code */
+		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
+			ret, facet->node, WXS_BASIC_CAST typeDecl,
+			"The value '%s' of the facet '%s' is not a valid '%s'",
+			facet->value,
+			xmlSchemaFacetTypeToString(facet->type),
+			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
+			    BAD_CAST "nonNegativeInteger" :
+			    BAD_CAST "positiveInteger",
+			NULL);
+		}
+	    }
+	    break;
+
+        case XML_SCHEMA_FACET_WHITESPACE:{
+                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
+                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
+                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
+                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
+                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
+                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
+                } else {
+		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
+                    /* No error message for RelaxNG. */
+		    if (ctxtGiven) {
+			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    ret, facet->node, WXS_BASIC_CAST typeDecl,
+			    "The value '%s' of the facet 'whitespace' is not "
+			    "valid", facet->value, NULL);
+                    }
+                }
+            }
+        default:
+            break;
+    }
+exit:
+    if ((! ctxtGiven) && (pctxt != NULL))
+	xmlSchemaFreeParserCtxt(pctxt);
+    return (ret);
+internal_error:
+    if ((! ctxtGiven) && (pctxt != NULL))
+	xmlSchemaFreeParserCtxt(pctxt);
+    return (-1);
+}
+
+/**
+ * xmlSchemaCheckFacetValues:
+ * @typeDecl:  the schema type definition
+ * @ctxt:  the schema parser context
+ *
+ * Checks the default values types, especially for facets
+ */
+static int
+xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
+			  xmlSchemaParserCtxtPtr pctxt)
+{
+    int res, olderrs = pctxt->nberrors;
+    const xmlChar *name = typeDecl->name;
+    /*
+    * NOTE: It is intended to use the facets list, instead
+    * of facetSet.
+    */
+    if (typeDecl->facets != NULL) {
+	xmlSchemaFacetPtr facet = typeDecl->facets;
+
+	/*
+	* Temporarily assign the "schema" to the validation context
+	* of the parser context. This is needed for NOTATION validation.
+	*/
+	if (pctxt->vctxt == NULL) {
+	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
+		return(-1);
+	}
+	pctxt->vctxt->schema = pctxt->schema;
+	while (facet != NULL) {
+	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
+	    HFAILURE
+	    facet = facet->next;
+	}
+	pctxt->vctxt->schema = NULL;
+    }
+    if (olderrs != pctxt->nberrors)
+	return(pctxt->err);
+    return(0);
+exit_failure:
+    return(-1);
+}
+
+/**
+ * xmlSchemaGetCircModelGrDefRef:
+ * @ctxtMGroup: the searched model group
+ * @selfMGroup: the second searched model group
+ * @particle: the first particle
+ *
+ * This one is intended to be used by
+ * xmlSchemaCheckGroupDefCircular only.
+ *
+ * Returns the particle with the circular model group definition reference,
+ * otherwise NULL.
+ */
+static xmlSchemaTreeItemPtr
+xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
+			      xmlSchemaTreeItemPtr particle)
+{
+    xmlSchemaTreeItemPtr circ = NULL;
+    xmlSchemaTreeItemPtr term;
+    xmlSchemaModelGroupDefPtr gdef;
+
+    for (; particle != NULL; particle = particle->next) {
+	term = particle->children;
+	if (term == NULL)
+	    continue;
+	switch (term->type) {
+	    case XML_SCHEMA_TYPE_GROUP:
+		gdef = (xmlSchemaModelGroupDefPtr) term;
+		if (gdef == groupDef)
+		    return (particle);
+		/*
+		* Mark this model group definition to avoid infinite
+		* recursion on circular references not yet examined.
+		*/
+		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
+		    continue;
+		if (gdef->children != NULL) {
+		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
+		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
+			gdef->children->children);
+		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
+		    if (circ != NULL)
+			return (circ);
+		}
+		break;
+	    case XML_SCHEMA_TYPE_SEQUENCE:
+	    case XML_SCHEMA_TYPE_CHOICE:
+	    case XML_SCHEMA_TYPE_ALL:
+		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
+		if (circ != NULL)
+		    return (circ);
+		break;
+	    default:
+		break;
+	}
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaCheckGroupDefCircular:
+ * @item:  the model group definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Checks for circular references to model group definitions.
+ */
+static void
+xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
+			       xmlSchemaParserCtxtPtr ctxt)
+{
+    /*
+    * Schema Component Constraint: Model Group Correct
+    * 2 Circular groups are disallowed. That is, within the {particles}
+    * of a group there must not be at any depth a particle whose {term}
+    * is the group itself.
+    */
+    if ((item == NULL) ||
+	(item->type != XML_SCHEMA_TYPE_GROUP) ||
+	(item->children == NULL))
+	return;
+    {
+	xmlSchemaTreeItemPtr circ;
+
+	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
+	if (circ != NULL) {
+	    xmlChar *str = NULL;
+	    /*
+	    * TODO: The error report is not adequate: this constraint
+	    * is defined for model groups but not definitions, but since
+	    * there cannot be any circular model groups without a model group
+	    * definition (if not using a construction API), we check those
+	    * defintions only.
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_MG_PROPS_CORRECT_2,
+		NULL, WXS_ITEM_NODE(circ),
+		"Circular reference to the model group definition '%s' "
+		"defined", xmlSchemaFormatQName(&str,
+		    item->targetNamespace, item->name));
+	    FREE_AND_NULL(str)
+	    /*
+	    * NOTE: We will cut the reference to avoid further
+	    * confusion of the processor. This is a fatal error.
+	    */
+	    circ->children = NULL;
+	}
+    }
+}
+
+/**
+ * xmlSchemaModelGroupToModelGroupDefFixup:
+ * @ctxt:  the parser context
+ * @mg:  the model group
+ *
+ * Assigns the model group of model group definitions to the "term"
+ * of the referencing particle.
+ * In xmlSchemaResolveModelGroupParticleReferences the model group
+ * definitions were assigned to the "term", since needed for the
+ * circularity check.
+ *
+ * Schema Component Constraint:
+ *     All Group Limited (cos-all-limited) (1.2)
+ */
+static void
+xmlSchemaModelGroupToModelGroupDefFixup(
+    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+    xmlSchemaModelGroupPtr mg)
+{
+    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
+
+    while (particle != NULL) {
+	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
+	    ((WXS_PARTICLE_TERM(particle))->type !=
+		XML_SCHEMA_TYPE_GROUP))
+	{
+	    particle = WXS_PTC_CAST particle->next;
+	    continue;
+	}
+	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
+	    /*
+	    * TODO: Remove the particle.
+	    */
+	    WXS_PARTICLE_TERM(particle) = NULL;
+	    particle = WXS_PTC_CAST particle->next;
+	    continue;
+	}
+	/*
+	* Assign the model group to the {term} of the particle.
+	*/
+	WXS_PARTICLE_TERM(particle) =
+	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
+
+	particle = WXS_PTC_CAST particle->next;
+    }
+}
+
+/**
+ * xmlSchemaCheckAttrGroupCircularRecur:
+ * @ctxtGr: the searched attribute group
+ * @attr: the current attribute list to be processed
+ *
+ * This one is intended to be used by
+ * xmlSchemaCheckAttrGroupCircular only.
+ *
+ * Returns the circular attribute grou reference, otherwise NULL.
+ */
+static xmlSchemaQNameRefPtr
+xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
+				     xmlSchemaItemListPtr list)
+{
+    xmlSchemaAttributeGroupPtr gr;
+    xmlSchemaQNameRefPtr ref, circ;
+    int i;
+    /*
+    * We will search for an attribute group reference which
+    * references the context attribute group.
+    */
+    for (i = 0; i < list->nbItems; i++) {
+	ref = list->items[i];
+	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
+	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
+	    (ref->item != NULL))
+	{
+	    gr = WXS_ATTR_GROUP_CAST ref->item;
+	    if (gr == ctxtGr)
+		return(ref);
+	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
+		continue;
+	    /*
+	    * Mark as visited to avoid infinite recursion on
+	    * circular references not yet examined.
+	    */
+	    if ((gr->attrUses) &&
+		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
+	    {
+		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
+		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
+		    (xmlSchemaItemListPtr) gr->attrUses);
+		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
+		if (circ != NULL)
+		    return (circ);
+	    }
+
+	}
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaCheckAttrGroupCircular:
+ * attrGr:  the attribute group definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Checks for circular references of attribute groups.
+ */
+static int
+xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
+				xmlSchemaParserCtxtPtr ctxt)
+{
+    /*
+    * Schema Representation Constraint:
+    * Attribute Group Definition Representation OK
+    * 3 Circular group reference is disallowed outside <redefine>.
+    * That is, unless this element information item's parent is
+    * <redefine>, then among the [children], if any, there must
+    * not be an <attributeGroup> with ref [attribute] which resolves
+    * to the component corresponding to this <attributeGroup>. Indirect
+    * circularity is also ruled out. That is, when QName resolution
+    * (Schema Document) (�3.15.3) is applied to a �QName� arising from
+    * any <attributeGroup>s with a ref [attribute] among the [children],
+    * it must not be the case that a �QName� is encountered at any depth
+    * which resolves to the component corresponding to this <attributeGroup>.
+    */
+    if (attrGr->attrUses == NULL)
+	return(0);
+    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
+	return(0);
+    else {
+	xmlSchemaQNameRefPtr circ;
+
+	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
+	    (xmlSchemaItemListPtr) attrGr->attrUses);
+	if (circ != NULL) {
+	    xmlChar *str = NULL;
+	    /*
+	    * TODO: Report the referenced attr group as QName.
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
+		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
+		"Circular reference to the attribute group '%s' "
+		"defined", xmlSchemaGetComponentQName(&str, attrGr));
+	    FREE_AND_NULL(str);
+	    /*
+	    * NOTE: We will cut the reference to avoid further
+	    * confusion of the processor.
+	    * BADSPEC TODO: The spec should define how to process in this case.
+	    */
+	    circ->item = NULL;
+	    return(ctxt->err);
+	}
+    }
+    return(0);
+}
+
+static int
+xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaAttributeGroupPtr attrGr);
+
+/**
+ * xmlSchemaExpandAttributeGroupRefs:
+ * @pctxt: the parser context
+ * @node: the node of the component holding the attribute uses
+ * @completeWild: the intersected wildcard to be returned
+ * @list: the attribute uses
+ *
+ * Substitutes contained attribute group references
+ * for their attribute uses. Wilcards are intersected.
+ * Attribute use prohibitions are removed from the list
+ * and returned via the @prohibs list.
+ * Pointlessness of attr. prohibs, if a matching attr. decl
+ * is existent a well, are checked.
+ */
+static int
+xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaBasicItemPtr item,
+				  xmlSchemaWildcardPtr *completeWild,
+				  xmlSchemaItemListPtr list,
+				  xmlSchemaItemListPtr prohibs)
+{
+    xmlSchemaAttributeGroupPtr gr;
+    xmlSchemaAttributeUsePtr use;
+    xmlSchemaItemListPtr sublist;
+    int i, j;
+    int created = (*completeWild == NULL) ? 0 : 1;
+
+    if (prohibs)
+	prohibs->nbItems = 0;
+
+    for (i = 0; i < list->nbItems; i++) {
+	use = list->items[i];
+
+	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
+	    if (prohibs == NULL) {
+		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
+		    "unexpected attr prohibition found");
+		return(-1);
+	    }
+	    /*
+	    * Remove from attribute uses.
+	    */
+	    if (xmlSchemaItemListRemove(list, i) == -1)
+		return(-1);
+	    i--;
+	    /*
+	    * Note that duplicate prohibitions were already
+	    * handled at parsing time.
+	    */
+	    /*
+	    * Add to list of prohibitions.
+	    */
+	    xmlSchemaItemListAddSize(prohibs, 2, use);
+	    continue;
+	}
+	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
+	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
+	{
+	    if ((WXS_QNAME_CAST use)->item == NULL)
+		return(-1);
+	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
+	    /*
+	    * Expand the referenced attr. group.
+	    * TODO: remove this, this is done in a previous step, so
+	    * already done here.
+	    */
+	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
+		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
+		    return(-1);
+	    }
+	    /*
+	    * Build the 'complete' wildcard; i.e. intersect multiple
+	    * wildcards.
+	    */
+	    if (gr->attributeWildcard != NULL) {
+		if (*completeWild == NULL) {
+		    *completeWild = gr->attributeWildcard;
+		} else {
+		    if (! created) {
+			xmlSchemaWildcardPtr tmpWild;
+
+			 /*
+			* Copy the first encountered wildcard as context,
+			* except for the annotation.
+			*
+			* Although the complete wildcard might not correspond
+			* to any node in the schema, we will anchor it on
+			* the node of the owner component.
+			*/
+			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
+			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+			    WXS_ITEM_NODE(item));
+			if (tmpWild == NULL)
+			    return(-1);
+			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
+			    tmpWild, *completeWild) == -1)
+			    return (-1);
+			tmpWild->processContents = (*completeWild)->processContents;
+			*completeWild = tmpWild;
+			created = 1;
+		    }
+
+		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
+			gr->attributeWildcard) == -1)
+			return(-1);
+		}
+	    }
+	    /*
+	    * Just remove the reference if the referenced group does not
+	    * contain any attribute uses.
+	    */
+	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
+	    if ((sublist == NULL) || sublist->nbItems == 0) {
+		if (xmlSchemaItemListRemove(list, i) == -1)
+		    return(-1);
+		i--;
+		continue;
+	    }
+	    /*
+	    * Add the attribute uses.
+	    */
+	    list->items[i] = sublist->items[0];
+	    if (sublist->nbItems != 1) {
+		for (j = 1; j < sublist->nbItems; j++) {
+		    i++;
+		    if (xmlSchemaItemListInsert(list,
+			    sublist->items[j], i) == -1)
+			return(-1);
+		}
+	    }
+	}
+
+    }
+    /*
+    * Handle pointless prohibitions of declared attributes.
+    */
+    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
+	xmlSchemaAttributeUseProhibPtr prohib;
+
+	for (i = prohibs->nbItems -1; i >= 0; i--) {
+	    prohib = prohibs->items[i];
+	    for (j = 0; j < list->nbItems; j++) {
+		use = list->items[j];
+
+		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
+		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
+		{
+		    xmlChar *str = NULL;
+
+		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
+			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
+			prohib->node, NULL,
+			"Skipping pointless attribute use prohibition "
+			"'%s', since a corresponding attribute use "
+			"exists already in the type definition",
+			xmlSchemaFormatQName(&str,
+			    prohib->targetNamespace, prohib->name),
+			NULL, NULL);
+		    FREE_AND_NULL(str);
+		    /*
+		    * Remove the prohibition.
+		    */
+		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
+			return(-1);
+		    break;
+		}
+	    }
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaAttributeGroupExpandRefs:
+ * @pctxt:  the parser context
+ * @attrGr:  the attribute group definition
+ *
+ * Computation of:
+ * {attribute uses} property
+ * {attribute wildcard} property
+ *
+ * Substitutes contained attribute group references
+ * for their attribute uses. Wilcards are intersected.
+ */
+static int
+xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaAttributeGroupPtr attrGr)
+{
+    if ((attrGr->attrUses == NULL) ||
+	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
+	return(0);
+
+    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
+    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
+	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
+	return(-1);
+    return(0);
+}
+
+/**
+ * xmlSchemaAttributeGroupExpandRefs:
+ * @pctxt:  the parser context
+ * @attrGr:  the attribute group definition
+ *
+ * Substitutes contained attribute group references
+ * for their attribute uses. Wilcards are intersected.
+ *
+ * Schema Component Constraint:
+ *    Attribute Group Definition Properties Correct (ag-props-correct)
+ */
+static int
+xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+				  xmlSchemaAttributeGroupPtr attrGr)
+{
+    /*
+    * SPEC ag-props-correct
+    * (1) "The values of the properties of an attribute group definition
+    * must be as described in the property tableau in The Attribute
+    * Group Definition Schema Component (�3.6.1), modulo the impact of
+    * Missing Sub-components (�5.3);"
+    */
+
+    if ((attrGr->attrUses != NULL) &&
+	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
+    {
+	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
+	xmlSchemaAttributeUsePtr use, tmp;
+	int i, j, hasId = 0;
+
+	for (i = uses->nbItems -1; i >= 0; i--) {
+	    use = uses->items[i];
+	    /*
+	    * SPEC ag-props-correct
+	    * (2) "Two distinct members of the {attribute uses} must not have
+	    * {attribute declaration}s both of whose {name}s match and whose
+	    * {target namespace}s are identical."
+	    */
+	    if (i > 0) {
+		for (j = i -1; j >= 0; j--) {
+		    tmp = uses->items[j];
+		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
+			WXS_ATTRUSE_DECL_NAME(tmp)) &&
+			(WXS_ATTRUSE_DECL_TNS(use) ==
+			WXS_ATTRUSE_DECL_TNS(tmp)))
+		    {
+			xmlChar *str = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    XML_SCHEMAP_AG_PROPS_CORRECT,
+			    attrGr->node, WXS_BASIC_CAST attrGr,
+			    "Duplicate %s",
+			    xmlSchemaGetComponentDesignation(&str, use),
+			    NULL);
+			FREE_AND_NULL(str);
+			/*
+			* Remove the duplicate.
+			*/
+			if (xmlSchemaItemListRemove(uses, i) == -1)
+			    return(-1);
+			goto next_use;
+		    }
+		}
+	    }
+	    /*
+	    * SPEC ag-props-correct
+	    * (3) "Two distinct members of the {attribute uses} must not have
+	    * {attribute declaration}s both of whose {type definition}s are or
+	    * are derived from ID."
+	    * TODO: Does 'derived' include member-types of unions?
+	    */
+	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
+		if (xmlSchemaIsDerivedFromBuiltInType(
+		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
+		{
+		    if (hasId) {
+			xmlChar *str = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    XML_SCHEMAP_AG_PROPS_CORRECT,
+			    attrGr->node, WXS_BASIC_CAST attrGr,
+			    "There must not exist more than one attribute "
+			    "declaration of type 'xs:ID' "
+			    "(or derived from 'xs:ID'). The %s violates this "
+			    "constraint",
+			    xmlSchemaGetComponentDesignation(&str, use),
+			    NULL);
+			FREE_AND_NULL(str);
+			if (xmlSchemaItemListRemove(uses, i) == -1)
+			    return(-1);
+		    }
+		    hasId = 1;
+		}
+	    }
+next_use: {}
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaResolveAttrGroupReferences:
+ * @attrgrpDecl:  the schema attribute definition
+ * @ctxt:  the schema parser context
+ * @name:  the attribute name
+ *
+ * Resolves references to attribute group definitions.
+ */
+static int
+xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
+				    xmlSchemaParserCtxtPtr ctxt)
+{
+    xmlSchemaAttributeGroupPtr group;
+
+    if (ref->item != NULL)
+        return(0);
+    group = xmlSchemaGetAttributeGroup(ctxt->schema,
+	ref->name,
+	ref->targetNamespace);
+    if (group == NULL) {
+	xmlSchemaPResCompAttrErr(ctxt,
+	    XML_SCHEMAP_SRC_RESOLVE,
+	    NULL, ref->node,
+	    "ref", ref->name, ref->targetNamespace,
+	    ref->itemType, NULL);
+	return(ctxt->err);
+    }
+    ref->item = WXS_BASIC_CAST group;
+    return(0);
+}
+
+/**
+ * xmlSchemaCheckAttrPropsCorrect:
+ * @item:  an schema attribute declaration/use
+ * @ctxt:  a schema parser context
+ * @name:  the name of the attribute
+ *
+ *
+ * Schema Component Constraint:
+ *    Attribute Declaration Properties Correct (a-props-correct)
+ *
+ * Validates the value constraints of an attribute declaration/use.
+ * NOTE that this needs the simle type definitions to be already
+ *   builded and checked.
+ */
+static int
+xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+			       xmlSchemaAttributePtr attr)
+{
+
+    /*
+    * SPEC a-props-correct (1)
+    * "The values of the properties of an attribute declaration must
+    * be as described in the property tableau in The Attribute
+    * Declaration Schema Component (�3.2.1), modulo the impact of
+    * Missing Sub-components (�5.3)."
+    */
+
+    if (WXS_ATTR_TYPEDEF(attr) == NULL)
+	return(0);
+
+    if (attr->defValue != NULL) {
+	int ret;
+
+	/*
+	* SPEC a-props-correct (3)
+	* "If the {type definition} is or is derived from ID then there
+	* must not be a {value constraint}."
+	*/
+	if (xmlSchemaIsDerivedFromBuiltInType(
+	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
+	{
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_A_PROPS_CORRECT_3,
+		NULL, WXS_BASIC_CAST attr,
+		"Value constraints are not allowed if the type definition "
+		"is or is derived from xs:ID",
+		NULL, NULL);
+	    return(pctxt->err);
+	}
+	/*
+	* SPEC a-props-correct (2)
+	* "if there is a {value constraint}, the canonical lexical
+	* representation of its value must be �valid� with respect
+	* to the {type definition} as defined in String Valid (�3.14.4)."
+	* TODO: Don't care about the *cononical* stuff here, this requirement
+	* will be removed in WXS 1.1 anyway.
+	*/
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
+	    attr->node, WXS_ATTR_TYPEDEF(attr),
+	    attr->defValue, &(attr->defVal),
+	    1, 1, 0);
+	if (ret != 0) {
+	    if (ret < 0) {
+		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
+		    "calling xmlSchemaVCheckCVCSimpleType()");
+		return(-1);
+	    }
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_A_PROPS_CORRECT_2,
+		NULL, WXS_BASIC_CAST attr,
+		"The value of the value constraint is not valid",
+		NULL, NULL);
+	    return(pctxt->err);
+	}
+    }
+
+    return(0);
+}
+
+static xmlSchemaElementPtr
+xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
+				 xmlSchemaElementPtr ancestor)
+{
+    xmlSchemaElementPtr ret;
+
+    if (WXS_SUBST_HEAD(ancestor) == NULL)
+	return (NULL);
+    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
+	return (ancestor);
+
+    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
+	return (NULL);
+    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
+    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
+	WXS_SUBST_HEAD(ancestor));
+    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaCheckElemPropsCorrect:
+ * @ctxt:  a schema parser context
+ * @decl: the element declaration
+ * @name:  the name of the attribute
+ *
+ * Schema Component Constraint:
+ * Element Declaration Properties Correct (e-props-correct)
+ *
+ * STATUS:
+ *   missing: (6)
+ */
+static int
+xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
+			       xmlSchemaElementPtr elemDecl)
+{
+    int ret = 0;
+    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
+    /*
+    * SPEC (1) "The values of the properties of an element declaration
+    * must be as described in the property tableau in The Element
+    * Declaration Schema Component (�3.3.1), modulo the impact of Missing
+    * Sub-components (�5.3)."
+    */
+    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
+	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
+
+	xmlSchemaCheckElementDeclComponent(head, pctxt);
+	/*
+	* SPEC (3) "If there is a non-�absent� {substitution group
+	* affiliation}, then {scope} must be global."
+	*/
+	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
+	    xmlSchemaPCustomErr(pctxt,
+		XML_SCHEMAP_E_PROPS_CORRECT_3,
+		WXS_BASIC_CAST elemDecl, NULL,
+		"Only global element declarations can have a "
+		"substitution group affiliation", NULL);
+	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
+	}
+	/*
+	* TODO: SPEC (6) "Circular substitution groups are disallowed.
+	* That is, it must not be possible to return to an element declaration
+	* by repeatedly following the {substitution group affiliation}
+	* property."
+	*/
+	if (head == elemDecl)
+	    circ = head;
+	else if (WXS_SUBST_HEAD(head) != NULL)
+	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
+	else
+	    circ = NULL;
+	if (circ != NULL) {
+	    xmlChar *strA = NULL, *strB = NULL;
+
+	    xmlSchemaPCustomErrExt(pctxt,
+		XML_SCHEMAP_E_PROPS_CORRECT_6,
+		WXS_BASIC_CAST circ, NULL,
+		"The element declaration '%s' defines a circular "
+		"substitution group to element declaration '%s'",
+		xmlSchemaGetComponentQName(&strA, circ),
+		xmlSchemaGetComponentQName(&strB, head),
+		NULL);
+	    FREE_AND_NULL(strA)
+	    FREE_AND_NULL(strB)
+	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
+	}
+	/*
+	* SPEC (4) "If there is a {substitution group affiliation},
+	* the {type definition}
+	* of the element declaration must be validly derived from the {type
+	* definition} of the {substitution group affiliation}, given the value
+	* of the {substitution group exclusions} of the {substitution group
+	* affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
+	* (if the {type definition} is complex) or as defined in
+	* Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
+	* simple)."
+	*
+	* NOTE: {substitution group exclusions} means the values of the
+	* attribute "final".
+	*/
+
+	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
+	    int set = 0;
+
+	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
+		set |= SUBSET_EXTENSION;
+	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
+		set |= SUBSET_RESTRICTION;
+
+	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
+		WXS_ELEM_TYPEDEF(head), set) != 0) {
+		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
+
+		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
+		xmlSchemaPCustomErrExt(pctxt,
+		    XML_SCHEMAP_E_PROPS_CORRECT_4,
+		    WXS_BASIC_CAST elemDecl, NULL,
+		    "The type definition '%s' was "
+		    "either rejected by the substitution group "
+		    "affiliation '%s', or not validly derived from its type "
+		    "definition '%s'",
+		    xmlSchemaGetComponentQName(&strA, typeDef),
+		    xmlSchemaGetComponentQName(&strB, head),
+		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
+		FREE_AND_NULL(strA)
+		FREE_AND_NULL(strB)
+		FREE_AND_NULL(strC)
+	    }
+	}
+    }
+    /*
+    * SPEC (5) "If the {type definition} or {type definition}'s
+    * {content type}
+    * is or is derived from ID then there must not be a {value constraint}.
+    * Note: The use of ID as a type definition for elements goes beyond
+    * XML 1.0, and should be avoided if backwards compatibility is desired"
+    */
+    if ((elemDecl->value != NULL) &&
+	((WXS_IS_SIMPLE(typeDef) &&
+	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
+	 (WXS_IS_COMPLEX(typeDef) &&
+	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
+	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
+	    XML_SCHEMAS_ID)))) {
+
+	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
+	xmlSchemaPCustomErr(pctxt,
+	    XML_SCHEMAP_E_PROPS_CORRECT_5,
+	    WXS_BASIC_CAST elemDecl, NULL,
+	    "The type definition (or type definition's content type) is or "
+	    "is derived from ID; value constraints are not allowed in "
+	    "conjunction with such a type definition", NULL);
+    } else if (elemDecl->value != NULL) {
+	int vcret;
+	xmlNodePtr node = NULL;
+
+	/*
+	* SPEC (2) "If there is a {value constraint}, the canonical lexical
+	* representation of its value must be �valid� with respect to the
+	* {type definition} as defined in Element Default Valid (Immediate)
+	* (�3.3.6)."
+	*/
+	if (typeDef == NULL) {
+	    xmlSchemaPErr(pctxt, elemDecl->node,
+		XML_SCHEMAP_INTERNAL,
+		"Internal error: xmlSchemaCheckElemPropsCorrect, "
+		"type is missing... skipping validation of "
+		"the value constraint", NULL, NULL);
+	    return (-1);
+	}
+	if (elemDecl->node != NULL) {
+	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
+		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
+		    BAD_CAST "fixed");
+	    else
+		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
+		    BAD_CAST "default");
+	}
+	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
+	    typeDef, elemDecl->value, &(elemDecl->defVal));
+	if (vcret != 0) {
+	    if (vcret < 0) {
+		PERROR_INT("xmlSchemaElemCheckValConstr",
+		    "failed to validate the value constraint of an "
+		    "element declaration");
+		return (-1);
+	    }
+	    return (vcret);
+	}
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaCheckElemSubstGroup:
+ * @ctxt:  a schema parser context
+ * @decl: the element declaration
+ * @name:  the name of the attribute
+ *
+ * Schema Component Constraint:
+ * Substitution Group (cos-equiv-class)
+ *
+ * In Libxml2 the subst. groups will be precomputed, in terms of that
+ * a list will be built for each subst. group head, holding all direct
+ * referents to this head.
+ * NOTE that this function needs:
+ *   1. circular subst. groups to be checked beforehand
+ *   2. the declaration's type to be derived from the head's type
+ *
+ * STATUS:
+ *
+ */
+static void
+xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
+			     xmlSchemaElementPtr elemDecl)
+{
+    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
+	/* SPEC (1) "Its {abstract} is false." */
+	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
+	return;
+    {
+	xmlSchemaElementPtr head;
+	xmlSchemaTypePtr headType, type;
+	int set, methSet;
+	/*
+	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
+	* {disallowed substitutions} as the blocking constraint, as defined in
+	* Substitution Group OK (Transitive) (�3.3.6)."
+	*/
+	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
+	    head = WXS_SUBST_HEAD(head)) {
+	    set = 0;
+	    methSet = 0;
+	    /*
+	    * The blocking constraints.
+	    */
+	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
+		continue;
+	    headType = head->subtypes;
+	    type = elemDecl->subtypes;
+	    if (headType == type)
+		goto add_member;
+	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
+		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
+	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
+		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
+	    /*
+	    * SPEC: Substitution Group OK (Transitive) (2.3)
+	    * "The set of all {derivation method}s involved in the
+	    * derivation of D's {type definition} from C's {type definition}
+	    * does not intersect with the union of the blocking constraint,
+	    * C's {prohibited substitutions} (if C is complex, otherwise the
+	    * empty set) and the {prohibited substitutions} (respectively the
+	    * empty set) of any intermediate {type definition}s in the
+	    * derivation of D's {type definition} from C's {type definition}."
+	    */
+	    /*
+	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
+	    * subst.head axis, the methSet does not need to be computed for
+	    * the full depth over and over.
+	    */
+	    /*
+	    * The set of all {derivation method}s involved in the derivation
+	    */
+	    while ((type != NULL) && (type != headType)) {
+		if ((WXS_IS_EXTENSION(type)) &&
+		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
+		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
+
+		if (WXS_IS_RESTRICTION(type) &&
+		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
+		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
+
+		type = type->baseType;
+	    }
+	    /*
+	    * The {prohibited substitutions} of all intermediate types +
+	    * the head's type.
+	    */
+	    type = elemDecl->subtypes->baseType;
+	    while (type != NULL) {
+		if (WXS_IS_COMPLEX(type)) {
+		    if ((type->flags &
+			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
+			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
+		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
+		    if ((type->flags &
+			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
+			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
+		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
+		} else
+		    break;
+		if (type == headType)
+		    break;
+		type = type->baseType;
+	    }
+	    if ((set != 0) &&
+		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
+		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
+		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
+		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
+		continue;
+	    }
+add_member:
+	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
+	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
+		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
+	}
+    }
+}
+
+#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
+/**
+ * xmlSchemaCheckElementDeclComponent
+ * @pctxt: the schema parser context
+ * @ctxtComponent: the context component (an element declaration)
+ * @ctxtParticle: the first particle of the context component
+ * @searchParticle: the element declaration particle to be analysed
+ *
+ * Schema Component Constraint: Element Declarations Consistent
+ */
+static int
+xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
+				    xmlSchemaBasicItemPtr ctxtComponent,
+				    xmlSchemaParticlePtr ctxtParticle,
+				    xmlSchemaParticlePtr searchParticle,
+				    xmlSchemaParticlePtr curParticle,
+				    int search)
+{
+    return(0);
+
+    int ret = 0;
+    xmlSchemaParticlePtr cur = curParticle;
+    if (curParticle == NULL) {
+	return(0);
+    }
+    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
+	/*
+	* Just return in this case. A missing "term" of the particle
+	* might arise due to an invalid "term" component.
+	*/
+	return(0);
+    }
+    while (cur != NULL) {
+	switch (WXS_PARTICLE_TERM(cur)->type) {
+	    case XML_SCHEMA_TYPE_ANY:
+		break;
+	    case XML_SCHEMA_TYPE_ELEMENT:
+		if (search == 0) {
+		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
+			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
+		    if (ret != 0)
+			return(ret);
+		} else {
+		    xmlSchemaElementPtr elem =
+			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
+		    /*
+		    * SPEC Element Declarations Consistent:
+		    * "If the {particles} contains, either directly,
+		    * indirectly (that is, within the {particles} of a
+		    * contained model group, recursively) or �implicitly�
+		    * two or more element declaration particles with
+		    * the same {name} and {target namespace}, then
+		    * all their type definitions must be the same
+		    * top-level definition [...]"
+		    */
+		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
+			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
+			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
+			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
+		    {
+			xmlChar *strA = NULL, *strB = NULL;
+
+			xmlSchemaCustomErr(ACTXT_CAST pctxt,
+			    /* TODO: error code */
+			    XML_SCHEMAP_COS_NONAMBIG,
+			    WXS_ITEM_NODE(cur), NULL,
+			    "In the content model of %s, there are multiple "
+			    "element declarations for '%s' with different "
+			    "type definitions",
+			    xmlSchemaGetComponentDesignation(&strA,
+				ctxtComponent),
+			    xmlSchemaFormatQName(&strB,
+				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
+				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
+			FREE_AND_NULL(strA);
+			FREE_AND_NULL(strB);
+			return(XML_SCHEMAP_COS_NONAMBIG);
+		    }
+		}
+		break;
+	    case XML_SCHEMA_TYPE_SEQUENCE: {
+		break;
+		}
+	    case XML_SCHEMA_TYPE_CHOICE:{
+		/*
+		xmlSchemaTreeItemPtr sub;
+
+		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
+		while (sub != NULL) {
+		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
+			ctxtParticle, ctxtElem);
+		    if (ret != 0)
+			return(ret);
+		    sub = sub->next;
+		}
+		*/
+		break;
+		}
+	    case XML_SCHEMA_TYPE_ALL:
+		break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		break;
+	    default:
+		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
+		    "xmlSchemaCheckElementDeclConsistent",
+		    "found unexpected term of type '%s' in content model",
+		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
+		return(-1);
+	}
+	cur = (xmlSchemaParticlePtr) cur->next;
+    }
+
+exit:
+    return(ret);
+}
+#endif
+
+/**
+ * xmlSchemaCheckElementDeclComponent
+ * @item:  an schema element declaration/particle
+ * @ctxt:  a schema parser context
+ * @name:  the name of the attribute
+ *
+ * Validates the value constraints of an element declaration.
+ * Adds substitution group members.
+ */
+static void
+xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
+				   xmlSchemaParserCtxtPtr ctxt)
+{
+    if (elemDecl == NULL)
+	return;
+    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
+	return;
+    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
+    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
+	/*
+	* Adds substitution group members.
+	*/
+	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
+    }
+}
+
+/**
+ * xmlSchemaResolveModelGroupParticleReferences:
+ * @particle:  a particle component
+ * @ctxt:  a parser context
+ *
+ * Resolves references of a model group's {particles} to
+ * model group definitions and to element declarations.
+ */
+static void
+xmlSchemaResolveModelGroupParticleReferences(
+    xmlSchemaParserCtxtPtr ctxt,
+    xmlSchemaModelGroupPtr mg)
+{
+    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
+    xmlSchemaQNameRefPtr ref;
+    xmlSchemaBasicItemPtr refItem;
+
+    /*
+    * URGENT TODO: Test this.
+    */
+    while (particle != NULL) {
+	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
+	    ((WXS_PARTICLE_TERM(particle))->type !=
+		XML_SCHEMA_EXTRA_QNAMEREF))
+	{
+	    goto next_particle;
+	}
+	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
+	/*
+	* Resolve the reference.
+	* NULL the {term} by default.
+	*/
+	particle->children = NULL;
+
+	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
+	    ref->itemType, ref->name, ref->targetNamespace);
+	if (refItem == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
+		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
+		ref->targetNamespace, ref->itemType, NULL);
+	    /* TODO: remove the particle. */
+	    goto next_particle;
+	}
+	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
+	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
+		/* TODO: remove the particle. */
+		goto next_particle;
+	    /*
+	    * NOTE that we will assign the model group definition
+	    * itself to the "term" of the particle. This will ease
+	    * the check for circular model group definitions. After
+	    * that the "term" will be assigned the model group of the
+	    * model group definition.
+	    */
+	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
+		    XML_SCHEMA_TYPE_ALL) {
+		/*
+		* SPEC cos-all-limited (1)
+		* SPEC cos-all-limited (1.2)
+		* "It appears only as the value of one or both of the
+		* following properties:"
+		* (1.1) "the {model group} property of a model group
+		*        definition."
+		* (1.2) "the {term} property of a particle [... of] the "
+		* {content type} of a complex type definition."
+		*/
+		xmlSchemaCustomErr(ACTXT_CAST ctxt,
+		    /* TODO: error code */
+		    XML_SCHEMAP_COS_ALL_LIMITED,
+		    WXS_ITEM_NODE(particle), NULL,
+		    "A model group definition is referenced, but "
+		    "it contains an 'all' model group, which "
+		    "cannot be contained by model groups",
+		    NULL, NULL);
+		/* TODO: remove the particle. */
+		goto next_particle;
+	    }
+	    particle->children = (xmlSchemaTreeItemPtr) refItem;
+	} else {
+	    /*
+	    * TODO: Are referenced element declarations the only
+	    * other components we expect here?
+	    */
+	    particle->children = (xmlSchemaTreeItemPtr) refItem;
+	}
+next_particle:
+	particle = WXS_PTC_CAST particle->next;
+    }
+}
+
+static int
+xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
+		       xmlSchemaValPtr y)
+{
+    xmlSchemaTypePtr tx, ty, ptx, pty;
+    int ret;
+
+    while (x != NULL) {
+	/* Same types. */
+	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
+	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
+	ptx = xmlSchemaGetPrimitiveType(tx);
+	pty = xmlSchemaGetPrimitiveType(ty);
+	/*
+	* (1) if a datatype T' is �derived� by �restriction� from an
+	* atomic datatype T then the �value space� of T' is a subset of
+	* the �value space� of T. */
+	/*
+	* (2) if datatypes T' and T'' are �derived� by �restriction�
+	* from a common atomic ancestor T then the �value space�s of T'
+	* and T'' may overlap.
+	*/
+	if (ptx != pty)
+	    return(0);
+	/*
+	* We assume computed values to be normalized, so do a fast
+	* string comparison for string based types.
+	*/
+	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
+	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
+	    if (! xmlStrEqual(
+		xmlSchemaValueGetAsString(x),
+		xmlSchemaValueGetAsString(y)))
+		return (0);
+	} else {
+	    ret = xmlSchemaCompareValuesWhtsp(
+		x, XML_SCHEMA_WHITESPACE_PRESERVE,
+		y, XML_SCHEMA_WHITESPACE_PRESERVE);
+	    if (ret == -2)
+		return(-1);
+	    if (ret != 0)
+		return(0);
+	}
+	/*
+	* Lists.
+	*/
+	x = xmlSchemaValueGetNext(x);
+	if (x != NULL) {
+	    y = xmlSchemaValueGetNext(y);
+	    if (y == NULL)
+		return (0);
+	} else if (xmlSchemaValueGetNext(y) != NULL)
+	    return (0);
+	else
+	    return (1);
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaResolveAttrUseReferences:
+ * @item:  an attribute use
+ * @ctxt:  a parser context
+ *
+ * Resolves the referenced attribute declaration.
+ */
+static int
+xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
+				  xmlSchemaParserCtxtPtr ctxt)
+{
+    if ((ctxt == NULL) || (ause == NULL))
+	return(-1);
+    if ((ause->attrDecl == NULL) ||
+	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
+	return(0);
+
+    {
+	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
+
+	/*
+	* TODO: Evaluate, what errors could occur if the declaration is not
+	* found.
+	*/
+	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
+	    ref->name, ref->targetNamespace);
+        if (ause->attrDecl == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt,
+	    	XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST ause, ause->node,
+		"ref", ref->name, ref->targetNamespace,
+		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
+            return(ctxt->err);;
+        }
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaCheckAttrUsePropsCorrect:
+ * @ctxt:  a parser context
+ * @use:  an attribute use
+ *
+ * Schema Component Constraint:
+ * Attribute Use Correct (au-props-correct)
+ *
+ */
+static int
+xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
+			     xmlSchemaAttributeUsePtr use)
+{
+    if ((ctxt == NULL) || (use == NULL))
+	return(-1);
+    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
+	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
+	return(0);
+
+    /*
+    * SPEC au-props-correct (1)
+    * "The values of the properties of an attribute use must be as
+    * described in the property tableau in The Attribute Use Schema
+    * Component (�3.5.1), modulo the impact of Missing
+    * Sub-components (�5.3)."
+    */
+
+    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
+	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
+        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
+    {
+	xmlSchemaPCustomErr(ctxt,
+	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
+	    WXS_BASIC_CAST use, NULL,
+	    "The attribute declaration has a 'fixed' value constraint "
+	    ", thus the attribute use must also have a 'fixed' value "
+	    "constraint",
+	    NULL);
+	return(ctxt->err);
+    }
+    /*
+    * Compute and check the value constraint's value.
+    */
+    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
+	int ret;
+	/*
+	* TODO: The spec seems to be missing a check of the
+	* value constraint of the attribute use. We will do it here.
+	*/
+	/*
+	* SPEC a-props-correct (3)
+	*/
+	if (xmlSchemaIsDerivedFromBuiltInType(
+	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
+	{
+	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+		XML_SCHEMAP_AU_PROPS_CORRECT,
+		NULL, WXS_BASIC_CAST use,
+		"Value constraints are not allowed if the type definition "
+		"is or is derived from xs:ID",
+		NULL, NULL);
+	    return(ctxt->err);
+	}
+
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
+	    use->node, WXS_ATTRUSE_TYPEDEF(use),
+	    use->defValue, &(use->defVal),
+	    1, 1, 0);
+	if (ret != 0) {
+	    if (ret < 0) {
+		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
+		    "calling xmlSchemaVCheckCVCSimpleType()");
+		return(-1);
+	    }
+	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
+		XML_SCHEMAP_AU_PROPS_CORRECT,
+		NULL, WXS_BASIC_CAST use,
+		"The value of the value constraint is not valid",
+		NULL, NULL);
+	    return(ctxt->err);
+	}
+    }
+    /*
+    * SPEC au-props-correct (2)
+    * "If the {attribute declaration} has a fixed
+    * {value constraint}, then if the attribute use itself has a
+    * {value constraint}, it must also be fixed and its value must match
+    * that of the {attribute declaration}'s {value constraint}."
+    */
+    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
+	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
+    {
+	if (! xmlSchemaAreValuesEqual(use->defVal,
+		(WXS_ATTRUSE_DECL(use))->defVal))
+	{
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_AU_PROPS_CORRECT_2,
+		WXS_BASIC_CAST use, NULL,
+		"The 'fixed' value constraint of the attribute use "
+		"must match the attribute declaration's value "
+		"constraint '%s'",
+		(WXS_ATTRUSE_DECL(use))->defValue);
+	}
+	return(ctxt->err);
+    }
+    return(0);
+}
+
+
+
+
+/**
+ * xmlSchemaResolveAttrTypeReferences:
+ * @item:  an attribute declaration
+ * @ctxt:  a parser context
+ *
+ * Resolves the referenced type definition component.
+ */
+static int
+xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
+				   xmlSchemaParserCtxtPtr ctxt)
+{
+    /*
+    * The simple type definition corresponding to the <simpleType> element
+    * information item in the [children], if present, otherwise the simple
+    * type definition �resolved� to by the �actual value� of the type
+    * [attribute], if present, otherwise the �simple ur-type definition�.
+    */
+    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
+	return(0);
+    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
+    if (item->subtypes != NULL)
+        return(0);
+    if (item->typeName != NULL) {
+        xmlSchemaTypePtr type;
+
+	type = xmlSchemaGetType(ctxt->schema, item->typeName,
+	    item->typeNs);
+	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
+	    xmlSchemaPResCompAttrErr(ctxt,
+		XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST item, item->node,
+		"type", item->typeName, item->typeNs,
+		XML_SCHEMA_TYPE_SIMPLE, NULL);
+	    return(ctxt->err);
+	} else
+	    item->subtypes = type;
+
+    } else {
+	/*
+	* The type defaults to the xs:anySimpleType.
+	*/
+	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaResolveIDCKeyReferences:
+ * @idc:  the identity-constraint definition
+ * @ctxt:  the schema parser context
+ * @name:  the attribute name
+ *
+ * Resolve keyRef references to key/unique IDCs.
+ * Schema Component Constraint:
+ *   Identity-constraint Definition Properties Correct (c-props-correct)
+ */
+static int
+xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
+			  xmlSchemaParserCtxtPtr pctxt)
+{
+    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
+        return(0);
+    if (idc->ref->name != NULL) {
+	idc->ref->item = (xmlSchemaBasicItemPtr)
+	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
+		idc->ref->targetNamespace);
+        if (idc->ref->item == NULL) {
+	    /*
+	    * TODO: It is actually not an error to fail to resolve
+	    * at this stage. BUT we need to be that strict!
+	    */
+	    xmlSchemaPResCompAttrErr(pctxt,
+		XML_SCHEMAP_SRC_RESOLVE,
+		WXS_BASIC_CAST idc, idc->node,
+		"refer", idc->ref->name,
+		idc->ref->targetNamespace,
+		XML_SCHEMA_TYPE_IDC_KEY, NULL);
+            return(pctxt->err);
+	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
+	    /*
+	    * SPEC c-props-correct (1)
+	    */
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_C_PROPS_CORRECT,
+		NULL, WXS_BASIC_CAST idc,
+		"The keyref references a keyref",
+		NULL, NULL);
+	    idc->ref->item = NULL;
+	    return(pctxt->err);
+	} else {
+	    if (idc->nbFields !=
+		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
+		xmlChar *str = NULL;
+		xmlSchemaIDCPtr refer;
+
+		refer = (xmlSchemaIDCPtr) idc->ref->item;
+		/*
+		* SPEC c-props-correct(2)
+		* "If the {identity-constraint category} is keyref,
+		* the cardinality of the {fields} must equal that of
+		* the {fields} of the {referenced key}.
+		*/
+		xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_C_PROPS_CORRECT,
+		    NULL, WXS_BASIC_CAST idc,
+		    "The cardinality of the keyref differs from the "
+		    "cardinality of the referenced key/unique '%s'",
+		    xmlSchemaFormatQName(&str, refer->targetNamespace,
+			refer->name),
+		    NULL);
+		FREE_AND_NULL(str)
+		return(pctxt->err);
+	    }
+	}
+    }
+    return(0);
+}
+
+static int
+xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
+				       xmlSchemaParserCtxtPtr pctxt)
+{
+    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
+	prohib->targetNamespace) == NULL) {
+
+	xmlSchemaPResCompAttrErr(pctxt,
+	    XML_SCHEMAP_SRC_RESOLVE,
+	    NULL, prohib->node,
+	    "ref", prohib->name, prohib->targetNamespace,
+	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
+	return(XML_SCHEMAP_SRC_RESOLVE);
+    }
+    return(0);
+}
+
+#define WXS_REDEFINED_TYPE(c) \
+(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
+
+#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
+(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
+
+#define WXS_REDEFINED_ATTR_GROUP(c) \
+(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
+
+static int
+xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
+{
+    int err = 0;
+    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
+    xmlSchemaBasicItemPtr prev, item;
+    int wasRedefined;
+
+    if (redef == NULL)
+	return(0);
+
+    do {
+	item = redef->item;
+	/*
+	* First try to locate the redefined component in the
+	* schema graph starting with the redefined schema.
+	* NOTE: According to this schema bug entry:
+	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
+	*   it's not clear if the referenced component needs to originate
+	*   from the <redefine>d schema _document_ or the schema; the latter
+	*   would include all imported and included sub-schemas of the
+	*   <redefine>d schema. Currenlty we latter approach is used.
+	*   SUPPLEMENT: It seems that the WG moves towards the latter
+	*   approach, so we are doing it right.
+	*
+	*/
+	prev = xmlSchemaFindRedefCompInGraph(
+	    redef->targetBucket, item->type,
+	    redef->refName, redef->refTargetNs);
+	if (prev == NULL) {
+	    xmlChar *str = NULL;
+	    xmlNodePtr node;
+
+	    /*
+	    * SPEC src-redefine:
+	    * (6.2.1) "The �actual value� of its own name attribute plus
+	    * target namespace must successfully �resolve� to a model
+	    * group definition in I."
+	    * (7.2.1) "The �actual value� of its own name attribute plus
+	    * target namespace must successfully �resolve� to an attribute
+	    * group definition in I."
+
+	    *
+	    * Note that, if we are redefining with the use of references
+	    * to components, the spec assumes the src-resolve to be used;
+	    * but this won't assure that we search only *inside* the
+	    * redefined schema.
+	    */
+	    if (redef->reference)
+		node = WXS_ITEM_NODE(redef->reference);
+	    else
+		node = WXS_ITEM_NODE(item);
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		/*
+		* TODO: error code.
+		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
+		* reference kind.
+		*/
+		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
+		"The %s '%s' to be redefined could not be found in "
+		"the redefined schema",
+		WXS_ITEM_TYPE_NAME(item),
+		xmlSchemaFormatQName(&str, redef->refTargetNs,
+		    redef->refName));
+	    FREE_AND_NULL(str);
+	    err = pctxt->err;
+	    redef = redef->next;
+	    continue;
+	}
+	/*
+	* TODO: Obtaining and setting the redefinition state is really
+	* clumsy.
+	*/
+	wasRedefined = 0;
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_COMPLEX:
+	    case XML_SCHEMA_TYPE_SIMPLE:
+		if ((WXS_TYPE_CAST prev)->flags &
+		    XML_SCHEMAS_TYPE_REDEFINED)
+		{
+		    wasRedefined = 1;
+		    break;
+		}
+		/* Mark it as redefined. */
+		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
+		/*
+		* Assign the redefined type to the
+		* base type of the redefining type.
+		* TODO: How
+		*/
+		((xmlSchemaTypePtr) item)->baseType =
+		    (xmlSchemaTypePtr) prev;
+		break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
+		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
+		{
+		    wasRedefined = 1;
+		    break;
+		}
+		/* Mark it as redefined. */
+		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
+		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
+		if (redef->reference != NULL) {
+		    /*
+		    * Overwrite the QName-reference with the
+		    * referenced model group def.
+		    */
+		    (WXS_PTC_CAST redef->reference)->children =
+			WXS_TREE_CAST prev;
+		}
+		redef->target = prev;
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		if ((WXS_ATTR_GROUP_CAST prev)->flags &
+		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
+		{
+		    wasRedefined = 1;
+		    break;
+		}
+		(WXS_ATTR_GROUP_CAST prev)->flags |=
+		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
+		if (redef->reference != NULL) {
+		    /*
+		    * Assign the redefined attribute group to the
+		    * QName-reference component.
+		    * This is the easy case, since we will just
+		    * expand the redefined group.
+		    */
+		    (WXS_QNAME_CAST redef->reference)->item = prev;
+		    redef->target = NULL;
+		} else {
+		    /*
+		    * This is the complicated case: we need
+		    * to apply src-redefine (7.2.2) at a later
+		    * stage, i.e. when attribute group references
+		    * have beed expanded and simple types have
+		    * beed fixed.
+		    */
+		    redef->target = prev;
+		}
+		break;
+	    default:
+		PERROR_INT("xmlSchemaResolveRedefReferences",
+		    "Unexpected redefined component type");
+		return(-1);
+	}
+	if (wasRedefined) {
+	    xmlChar *str = NULL;
+	    xmlNodePtr node;
+
+	    if (redef->reference)
+		node = WXS_ITEM_NODE(redef->reference);
+	    else
+		node = WXS_ITEM_NODE(redef->item);
+
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		/* TODO: error code. */
+		XML_SCHEMAP_SRC_REDEFINE,
+		node, NULL,
+		"The referenced %s was already redefined. Multiple "
+		"redefinition of the same component is not supported",
+		xmlSchemaGetComponentDesignation(&str, prev),
+		NULL);
+	    FREE_AND_NULL(str)
+	    err = pctxt->err;
+	    redef = redef->next;
+	    continue;
+	}
+	redef = redef->next;
+    } while (redef != NULL);
+
+    return(err);
+}
+
+static int
+xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
+{
+    int err = 0;
+    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
+    xmlSchemaBasicItemPtr item;
+
+    if (redef == NULL)
+	return(0);
+
+    do {
+	if (redef->target == NULL) {
+	    redef = redef->next;
+	    continue;
+	}
+	item = redef->item;
+
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_SIMPLE:
+	    case XML_SCHEMA_TYPE_COMPLEX:
+		/*
+		* Since the spec wants the {name} of the redefined
+		* type to be 'absent', we'll NULL it.
+		*/
+		(WXS_TYPE_CAST redef->target)->name = NULL;
+
+		/*
+		* TODO: Seems like there's nothing more to do. The normal
+		* inheritance mechanism is used. But not 100% sure.
+		*/
+		break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		/*
+		* URGENT TODO:
+		* SPEC src-redefine:
+		* (6.2.2) "The {model group} of the model group definition
+		* which corresponds to it per XML Representation of Model
+		* Group Definition Schema Components (�3.7.2) must be a
+		* �valid restriction� of the {model group} of that model
+		* group definition in I, as defined in Particle Valid
+		* (Restriction) (�3.9.6)."
+		*/
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		/*
+		* SPEC src-redefine:
+		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
+		* the attribute group definition which corresponds to it
+		* per XML Representation of Attribute Group Definition Schema
+		* Components (�3.6.2) must be �valid restrictions� of the
+		* {attribute uses} and {attribute wildcard} of that attribute
+		* group definition in I, as defined in clause 2, clause 3 and
+		* clause 4 of Derivation Valid (Restriction, Complex)
+		* (�3.4.6) (where references to the base type definition are
+		* understood as references to the attribute group definition
+		* in I)."
+		*/
+		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
+		    XML_SCHEMA_ACTION_REDEFINE,
+		    item, redef->target,
+		    (WXS_ATTR_GROUP_CAST item)->attrUses,
+		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
+		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
+		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
+		if (err == -1)
+		    return(-1);
+		break;
+	    default:
+		break;
+	}
+	redef = redef->next;
+    } while (redef != NULL);
+    return(0);
+}
+
+
+static int
+xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
+		       xmlSchemaBucketPtr bucket)
+{
+    xmlSchemaBasicItemPtr item;
+    int err;
+    xmlHashTablePtr *table;
+    const xmlChar *name;
+    int i;
+
+#define WXS_GET_GLOBAL_HASH(c, slot) { \
+    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
+	table = &(WXS_IMPBUCKET((c))->schema->slot); \
+    else \
+	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
+
+    /*
+    * Add global components to the schema's hash tables.
+    * This is the place where duplicate components will be
+    * detected.
+    * TODO: I think normally we should support imports of the
+    *   same namespace from multiple locations. We don't do currently,
+    *   but if we do then according to:
+    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
+    *   we would need, if imported directly, to import redefined
+    *   components as well to be able to catch clashing components.
+    *   (I hope I'll still know what this means after some months :-()
+    */
+    if (bucket == NULL)
+	return(-1);
+    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
+	return(0);
+    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
+
+    for (i = 0; i < bucket->globals->nbItems; i++) {
+	item = bucket->globals->items[i];
+	table = NULL;
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_COMPLEX:
+	    case XML_SCHEMA_TYPE_SIMPLE:
+		if (WXS_REDEFINED_TYPE(item))
+		    continue;
+		name = (WXS_TYPE_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
+		break;
+	    case XML_SCHEMA_TYPE_ELEMENT:
+		name = (WXS_ELEM_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTE:
+		name = (WXS_ATTR_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
+		break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
+		    continue;
+		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		if (WXS_REDEFINED_ATTR_GROUP(item))
+		    continue;
+		name = (WXS_ATTR_GROUP_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
+		break;
+	    case XML_SCHEMA_TYPE_IDC_KEY:
+	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	    case XML_SCHEMA_TYPE_IDC_KEYREF:
+		name = (WXS_IDC_CAST item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, idcDef)
+		break;
+	    case XML_SCHEMA_TYPE_NOTATION:
+		name = ((xmlSchemaNotationPtr) item)->name;
+		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
+		break;
+	    default:
+		PERROR_INT("xmlSchemaAddComponents",
+		    "Unexpected global component type");
+		continue;
+	}
+	if (*table == NULL) {
+	    *table = xmlHashCreateDict(10, pctxt->dict);
+	    if (*table == NULL) {
+		PERROR_INT("xmlSchemaAddComponents",
+		    "failed to create a component hash table");
+		return(-1);
+	    }
+	}
+	err = xmlHashAddEntry(*table, name, item);
+	if (err != 0) {
+	    xmlChar *str = NULL;
+
+	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		XML_SCHEMAP_REDEFINED_TYPE,
+		WXS_ITEM_NODE(item),
+		WXS_BASIC_CAST item,
+		"A global %s '%s' does already exist",
+		WXS_ITEM_TYPE_NAME(item),
+		xmlSchemaGetComponentQName(&str, item));
+	    FREE_AND_NULL(str);
+	}
+    }
+    /*
+    * Process imported/included schemas.
+    */
+    if (bucket->relations != NULL) {
+	xmlSchemaSchemaRelationPtr rel = bucket->relations;
+	do {
+	    if ((rel->bucket != NULL) &&
+		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
+		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
+		    return(-1);
+	    }
+	    rel = rel->next;
+	} while (rel != NULL);
+    }
+    return(0);
+}
+
+static int
+xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
+			 xmlSchemaBucketPtr rootBucket)
+{
+    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
+    xmlSchemaTreeItemPtr item, *items;
+    int nbItems, i, ret = 0;
+    xmlSchemaBucketPtr oldbucket = con->bucket;
+    xmlSchemaElementPtr elemDecl;
+
+#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
+
+    if ((con->pending == NULL) ||
+	(con->pending->nbItems == 0))
+	return(0);
+
+    /*
+    * Since xmlSchemaFixupComplexType() will create new particles
+    * (local components), and those particle components need a bucket
+    * on the constructor, we'll assure here that the constructor has
+    * a bucket.
+    * TODO: Think about storing locals _only_ on the main bucket.
+    */
+    if (con->bucket == NULL)
+	con->bucket = rootBucket;
+
+    /* TODO:
+    * SPEC (src-redefine):
+    * (6.2) "If it has no such self-reference, then all of the
+    * following must be true:"
+
+    * (6.2.2) The {model group} of the model group definition which
+    * corresponds to it per XML Representation of Model Group
+    * Definition Schema Components (�3.7.2) must be a �valid
+    * restriction� of the {model group} of that model group definition
+    * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
+    */
+    xmlSchemaCheckSRCRedefineFirst(pctxt);
+
+    /*
+    * Add global components to the schemata's hash tables.
+    */
+    xmlSchemaAddComponents(pctxt, rootBucket);
+
+    pctxt->ctxtType = NULL;
+    items = (xmlSchemaTreeItemPtr *) con->pending->items;
+    nbItems = con->pending->nbItems;
+    /*
+    * Now that we have parsed *all* the schema document(s) and converted
+    * them to schema components, we can resolve references, apply component
+    * constraints, create the FSA from the content model, etc.
+    */
+    /*
+    * Resolve references of..
+    *
+    * 1. element declarations:
+    *   - the type definition
+    *   - the substitution group affiliation
+    * 2. simple/complex types:
+    *   - the base type definition
+    *   - the memberTypes of union types
+    *   - the itemType of list types
+    * 3. attributes declarations and attribute uses:
+    *   - the type definition
+    *   - if an attribute use, then the attribute declaration
+    * 4. attribute group references:
+    *   - the attribute group definition
+    * 5. particles:
+    *   - the term of the particle (e.g. a model group)
+    * 6. IDC key-references:
+    *   - the referenced IDC 'key' or 'unique' definition
+    * 7. Attribute prohibitions which had a "ref" attribute.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_ELEMENT:
+		xmlSchemaResolveElementReferences(
+		    (xmlSchemaElementPtr) item, pctxt);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_TYPE_COMPLEX:
+	    case XML_SCHEMA_TYPE_SIMPLE:
+		xmlSchemaResolveTypeReferences(
+		    (xmlSchemaTypePtr) item, pctxt);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTE:
+		xmlSchemaResolveAttrTypeReferences(
+		    (xmlSchemaAttributePtr) item, pctxt);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+		xmlSchemaResolveAttrUseReferences(
+		    (xmlSchemaAttributeUsePtr) item, pctxt);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_EXTRA_QNAMEREF:
+		if ((WXS_QNAME_CAST item)->itemType ==
+		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
+		{
+		    xmlSchemaResolveAttrGroupReferences(
+			WXS_QNAME_CAST item, pctxt);
+		}
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_TYPE_SEQUENCE:
+	    case XML_SCHEMA_TYPE_CHOICE:
+	    case XML_SCHEMA_TYPE_ALL:
+		xmlSchemaResolveModelGroupParticleReferences(pctxt,
+		    WXS_MODEL_GROUP_CAST item);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_TYPE_IDC_KEY:
+	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
+	    case XML_SCHEMA_TYPE_IDC_KEYREF:
+		xmlSchemaResolveIDCKeyReferences(
+		    (xmlSchemaIDCPtr) item, pctxt);
+		FIXHFAILURE;
+		break;
+	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
+		/*
+		* Handle attribue prohibition which had a
+		* "ref" attribute.
+		*/
+		xmlSchemaResolveAttrUseProhibReferences(
+		    WXS_ATTR_PROHIB_CAST item, pctxt);
+		FIXHFAILURE;
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Now that all references are resolved we
+    * can check for circularity of...
+    * 1. the base axis of type definitions
+    * 2. nested model group definitions
+    * 3. nested attribute group definitions
+    * TODO: check for circual substitution groups.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	/*
+	* Let's better stop on the first error here.
+	*/
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_COMPLEX:
+	    case XML_SCHEMA_TYPE_SIMPLE:
+		xmlSchemaCheckTypeDefCircular(
+		    (xmlSchemaTypePtr) item, pctxt);
+		FIXHFAILURE;
+		if (pctxt->nberrors != 0)
+		    goto exit_error;
+		break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		xmlSchemaCheckGroupDefCircular(
+		    (xmlSchemaModelGroupDefPtr) item, pctxt);
+		FIXHFAILURE;
+		if (pctxt->nberrors != 0)
+		    goto exit_error;
+		break;
+	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		xmlSchemaCheckAttrGroupCircular(
+		    (xmlSchemaAttributeGroupPtr) item, pctxt);
+		FIXHFAILURE;
+		if (pctxt->nberrors != 0)
+		    goto exit_error;
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * Model group definition references:
+    * Such a reference is reflected by a particle at the component
+    * level. Until now the 'term' of such particles pointed
+    * to the model group definition; this was done, in order to
+    * ease circularity checks. Now we need to set the 'term' of
+    * such particles to the model group of the model group definition.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_SEQUENCE:
+	    case XML_SCHEMA_TYPE_CHOICE:
+		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
+		    WXS_MODEL_GROUP_CAST item);
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * Expand attribute group references of attribute group definitions.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
+		    WXS_ATTR_GROUP_HAS_REFS(item))
+		{
+		    xmlSchemaAttributeGroupExpandRefs(pctxt,
+			WXS_ATTR_GROUP_CAST item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * First compute the variety of simple types. This is needed as
+    * a seperate step, since otherwise we won't be able to detect
+    * circular union types in all cases.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+            case XML_SCHEMA_TYPE_SIMPLE:
+		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
+		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
+			(xmlSchemaTypePtr) item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * Detect circular union types. Note that this needs the variety to
+    * be already computed.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+            case XML_SCHEMA_TYPE_SIMPLE:
+		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
+		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
+			(xmlSchemaTypePtr) item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Do the complete type fixup for simple types.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+            case XML_SCHEMA_TYPE_SIMPLE:
+		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
+		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * At this point we need build and check all simple types.
+    */
+    /*
+    * Apply contraints for attribute declarations.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_ATTRIBUTE:
+		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
+		FIXHFAILURE;
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * Apply constraints for attribute uses.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
+		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
+		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
+			WXS_ATTR_USE_CAST item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Apply constraints for attribute group definitions.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
+	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
+		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
+	    {
+		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
+		FIXHFAILURE;
+	    }
+	    break;
+	default:
+	    break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Apply constraints for redefinitions.
+    */
+    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
+	xmlSchemaCheckSRCRedefineSecond(pctxt);
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Complex types are builded and checked.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = con->pending->items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_COMPLEX:
+		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
+		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
+		    FIXHFAILURE;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * The list could have changed, since xmlSchemaFixupComplexType()
+    * will create particles and model groups in some cases.
+    */
+    items = (xmlSchemaTreeItemPtr *) con->pending->items;
+    nbItems = con->pending->nbItems;
+
+    /*
+    * Apply some constraints for element declarations.
+    */
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_ELEMENT:
+		elemDecl = (xmlSchemaElementPtr) item;
+
+		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
+		{
+		    xmlSchemaCheckElementDeclComponent(
+			(xmlSchemaElementPtr) elemDecl, pctxt);
+		    FIXHFAILURE;
+		}
+
+#ifdef WXS_ELEM_DECL_CONS_ENABLED
+		/*
+		* Schema Component Constraint: Element Declarations Consistent
+		* Apply this constraint to local types of element declarations.
+		*/
+		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
+		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
+		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
+		{
+		    xmlSchemaCheckElementDeclConsistent(pctxt,
+			WXS_BASIC_CAST elemDecl,
+			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
+			NULL, NULL, 0);
+		}
+#endif
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+
+    /*
+    * Finally we can build the automaton from the content model of
+    * complex types.
+    */
+
+    for (i = 0; i < nbItems; i++) {
+	item = items[i];
+	switch (item->type) {
+	    case XML_SCHEMA_TYPE_COMPLEX:
+		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
+		/* FIXHFAILURE; */
+		break;
+	    default:
+		break;
+	}
+    }
+    if (pctxt->nberrors != 0)
+	goto exit_error;
+    /*
+    * URGENT TODO: cos-element-consistent
+    */
+    goto exit;
+
+exit_error:
+    ret = pctxt->err;
+    goto exit;
+
+exit_failure:
+    ret = -1;
+
+exit:
+    /*
+    * Reset the constructor. This is needed for XSI acquisition, since
+    * those items will be processed over and over again for every XSI
+    * if not cleared here.
+    */
+    con->bucket = oldbucket;
+    con->pending->nbItems = 0;
+    if (con->substGroups != NULL) {
+	xmlHashFree(con->substGroups,
+	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
+	con->substGroups = NULL;
+    }
+    if (con->redefs != NULL) {
+	xmlSchemaRedefListFree(con->redefs);
+	con->redefs = NULL;
+    }
+    return(ret);
+}
+/**
+ * xmlSchemaParse:
+ * @ctxt:  a schema validation context
+ *
+ * parse a schema definition resource and build an internal
+ * XML Shema struture which can be used to validate instances.
+ *
+ * Returns the internal XML Schema structure built from the resource or
+ *         NULL in case of error
+ */
+xmlSchemaPtr
+xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
+{
+    xmlSchemaPtr mainSchema = NULL;
+    xmlSchemaBucketPtr bucket = NULL;
+    int res;
+
+    /*
+    * This one is used if the schema to be parsed was specified via
+    * the API; i.e. not automatically by the validated instance document.
+    */
+
+    xmlSchemaInitTypes();
+
+    if (ctxt == NULL)
+        return (NULL);
+
+    /* TODO: Init the context. Is this all we need?*/
+    ctxt->nberrors = 0;
+    ctxt->err = 0;
+    ctxt->counter = 0;
+
+    /* Create the *main* schema. */
+    mainSchema = xmlSchemaNewSchema(ctxt);
+    if (mainSchema == NULL)
+	goto exit_failure;
+    /*
+    * Create the schema constructor.
+    */
+    if (ctxt->constructor == NULL) {
+	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
+	if (ctxt->constructor == NULL)
+	    return(NULL);
+	/* Take ownership of the constructor to be able to free it. */
+	ctxt->ownsConstructor = 1;
+    }
+    ctxt->constructor->mainSchema = mainSchema;
+    /*
+    * Locate and add the schema document.
+    */
+    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
+	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
+	NULL, NULL, &bucket);
+    if (res == -1)
+	goto exit_failure;
+    if (res != 0)
+	goto exit;
+
+    if (bucket == NULL) {
+	/* TODO: Error code, actually we failed to *locate* the schema. */
+	if (ctxt->URL)
+	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
+		NULL, NULL,
+		"Failed to locate the main schema resource at '%s'",
+		ctxt->URL, NULL);
+	else
+	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
+		NULL, NULL,
+		"Failed to locate the main schema resource",
+		    NULL, NULL);
+	goto exit;
+    }
+    /* Then do the parsing for good. */
+    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
+	goto exit_failure;
+    if (ctxt->nberrors != 0)
+	goto exit;
+
+    mainSchema->doc = bucket->doc;
+    mainSchema->preserve = ctxt->preserve;
+
+    ctxt->schema = mainSchema;
+
+    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
+	goto exit_failure;
+
+    /*
+    * TODO: This is not nice, since we cannot distinguish from the
+    * result if there was an internal error or not.
+    */
+exit:
+    if (ctxt->nberrors != 0) {
+	if (mainSchema) {
+	    xmlSchemaFree(mainSchema);
+	    mainSchema = NULL;
+	}
+	if (ctxt->constructor) {
+	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
+	    ctxt->constructor = NULL;
+	    ctxt->ownsConstructor = 0;
+	}
+    }
+    ctxt->schema = NULL;
+    return(mainSchema);
+exit_failure:
+    /*
+    * Quite verbose, but should catch internal errors, which were
+    * not communitated.
+    */
+    if (mainSchema) {
+        xmlSchemaFree(mainSchema);
+	mainSchema = NULL;
+    }
+    if (ctxt->constructor) {
+	xmlSchemaConstructionCtxtFree(ctxt->constructor);
+	ctxt->constructor = NULL;
+	ctxt->ownsConstructor = 0;
+    }
+    PERROR_INT2("xmlSchemaParse",
+	"An internal error occured");
+    ctxt->schema = NULL;
+    return(NULL);
+}
+
+/**
+ * xmlSchemaSetParserErrors:
+ * @ctxt:  a schema validation context
+ * @err:  the error callback
+ * @warn:  the warning callback
+ * @ctx:  contextual data for the callbacks
+ *
+ * Set the callback functions used to handle errors for a validation context
+ */
+void
+xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
+                         xmlSchemaValidityErrorFunc err,
+                         xmlSchemaValidityWarningFunc warn, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->error = err;
+    ctxt->warning = warn;
+    ctxt->errCtxt = ctx;
+    if (ctxt->vctxt != NULL)
+	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
+}
+
+/**
+ * xmlSchemaSetParserStructuredErrors:
+ * @ctxt:  a schema parser context
+ * @serror:  the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
+				   xmlStructuredErrorFunc serror,
+				   void *ctx)
+{
+    if (ctxt == NULL)
+	return;
+    ctxt->serror = serror;
+    ctxt->errCtxt = ctx;
+    if (ctxt->vctxt != NULL)
+	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
+}
+
+/**
+ * xmlSchemaGetParserErrors:
+ * @ctxt:  a XMl-Schema parser context
+ * @err: the error callback result
+ * @warn: the warning callback result
+ * @ctx: contextual data for the callbacks result
+ *
+ * Get the callback information used to handle errors for a parser context
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+int
+xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
+			 xmlSchemaValidityErrorFunc * err,
+			 xmlSchemaValidityWarningFunc * warn, void **ctx)
+{
+	if (ctxt == NULL)
+		return(-1);
+	if (err != NULL)
+		*err = ctxt->error;
+	if (warn != NULL)
+		*warn = ctxt->warning;
+	if (ctx != NULL)
+		*ctx = ctxt->errCtxt;
+	return(0);
+}
+
+/**
+ * xmlSchemaFacetTypeToString:
+ * @type:  the facet type
+ *
+ * Convert the xmlSchemaTypeType to a char string.
+ *
+ * Returns the char string representation of the facet type if the
+ *     type is a facet and an "Internal Error" string otherwise.
+ */
+static const xmlChar *
+xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
+{
+    switch (type) {
+        case XML_SCHEMA_FACET_PATTERN:
+            return (BAD_CAST "pattern");
+        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+            return (BAD_CAST "maxExclusive");
+        case XML_SCHEMA_FACET_MAXINCLUSIVE:
+            return (BAD_CAST "maxInclusive");
+        case XML_SCHEMA_FACET_MINEXCLUSIVE:
+            return (BAD_CAST "minExclusive");
+        case XML_SCHEMA_FACET_MININCLUSIVE:
+            return (BAD_CAST "minInclusive");
+        case XML_SCHEMA_FACET_WHITESPACE:
+            return (BAD_CAST "whiteSpace");
+        case XML_SCHEMA_FACET_ENUMERATION:
+            return (BAD_CAST "enumeration");
+        case XML_SCHEMA_FACET_LENGTH:
+            return (BAD_CAST "length");
+        case XML_SCHEMA_FACET_MAXLENGTH:
+            return (BAD_CAST "maxLength");
+        case XML_SCHEMA_FACET_MINLENGTH:
+            return (BAD_CAST "minLength");
+        case XML_SCHEMA_FACET_TOTALDIGITS:
+            return (BAD_CAST "totalDigits");
+        case XML_SCHEMA_FACET_FRACTIONDIGITS:
+            return (BAD_CAST "fractionDigits");
+        default:
+            break;
+    }
+    return (BAD_CAST "Internal Error");
+}
+
+static xmlSchemaWhitespaceValueType
+xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
+{
+    /*
+    * The normalization type can be changed only for types which are derived
+    * from xsd:string.
+    */
+    if (type->type == XML_SCHEMA_TYPE_BASIC) {
+	/*
+	* Note that we assume a whitespace of preserve for anySimpleType.
+	*/
+	if ((type->builtInType == XML_SCHEMAS_STRING) ||
+	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
+	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
+	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
+	    return(XML_SCHEMA_WHITESPACE_REPLACE);
+	else {
+	    /*
+	    * For all �atomic� datatypes other than string (and types �derived�
+	    * by �restriction� from it) the value of whiteSpace is fixed to
+	    * collapse
+	    * Note that this includes built-in list datatypes.
+	    */
+	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
+	}
+    } else if (WXS_IS_LIST(type)) {
+	/*
+	* For list types the facet "whiteSpace" is fixed to "collapse".
+	*/
+	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
+    } else if (WXS_IS_UNION(type)) {
+	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
+    } else if (WXS_IS_ATOMIC(type)) {
+	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
+	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
+	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
+	    return (XML_SCHEMA_WHITESPACE_REPLACE);
+	else
+	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
+    }
+    return (-1);
+}
+
+/************************************************************************
+ * 									*
+ * 			Simple type validation				*
+ * 									*
+ ************************************************************************/
+
+
+/************************************************************************
+ * 									*
+ * 			DOM Validation code				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaAssembleByLocation:
+ * @pctxt:  a schema parser context
+ * @vctxt:  a schema validation context
+ * @schema: the existing schema
+ * @node: the node that fired the assembling
+ * @nsName: the namespace name of the new schema
+ * @location: the location of the schema
+ *
+ * Expands an existing schema by an additional schema.
+ *
+ * Returns 0 if the new schema is correct, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
+			    xmlSchemaPtr schema,
+			    xmlNodePtr node,
+			    const xmlChar *nsName,
+			    const xmlChar *location)
+{
+    int ret = 0;
+    xmlSchemaParserCtxtPtr pctxt;
+    xmlSchemaBucketPtr bucket = NULL;
+
+    if ((vctxt == NULL) || (schema == NULL))
+	return (-1);
+
+    if (vctxt->pctxt == NULL) {
+	VERROR_INT("xmlSchemaAssembleByLocation",
+	    "no parser context available");
+	return(-1);
+    }
+    pctxt = vctxt->pctxt;
+    if (pctxt->constructor == NULL) {
+	PERROR_INT("xmlSchemaAssembleByLocation",
+	    "no constructor");
+	return(-1);
+    }
+    /*
+    * Acquire the schema document.
+    */
+    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
+	location, node);
+    /*
+    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
+    * the process will automatically change this to
+    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
+    */
+    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
+	location, NULL, NULL, 0, node, NULL, nsName,
+	&bucket);
+    if (ret != 0)
+	return(ret);
+    if (bucket == NULL) {
+	/*
+	* Generate a warning that the document could not be located.
+	*/
+	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
+	    node, NULL,
+	    "The document at location '%s' could not be acquired",
+	    location, NULL, NULL);
+	return(ret);
+    }
+    /*
+    * The first located schema will be handled as if all other
+    * schemas imported by XSI were imported by this first schema.
+    */
+    if ((bucket != NULL) &&
+	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
+	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
+    /*
+    * TODO: Is this handled like an import? I.e. is it not an error
+    * if the schema cannot be located?
+    */
+    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
+	return(0);
+    /*
+    * We will reuse the parser context for every schema imported
+    * directly via XSI. So reset the context.
+    */
+    pctxt->nberrors = 0;
+    pctxt->err = 0;
+    pctxt->doc = bucket->doc;
+
+    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
+    if (ret == -1) {
+	pctxt->doc = NULL;
+	goto exit_failure;
+    }
+    /* Paranoid error channelling. */
+    if ((ret == 0) && (pctxt->nberrors != 0))
+	ret = pctxt->err;
+    if (pctxt->nberrors == 0) {
+	/*
+	* Only bother to fixup pending components, if there was
+	* no error yet.
+	* For every XSI acquired schema (and its sub-schemata) we will
+	* fixup the components.
+	*/
+	xmlSchemaFixupComponents(pctxt, bucket);
+	ret = pctxt->err;
+	/*
+	* Not nice, but we need somehow to channel the schema parser
+	* error to the validation context.
+	*/
+	if ((ret != 0) && (vctxt->err == 0))
+	    vctxt->err = ret;
+	vctxt->nberrors += pctxt->nberrors;
+    } else {
+	/* Add to validation error sum. */
+	vctxt->nberrors += pctxt->nberrors;
+    }
+    pctxt->doc = NULL;
+    return(ret);
+exit_failure:
+    pctxt->doc = NULL;
+    return (-1);
+}
+
+static xmlSchemaAttrInfoPtr
+xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
+			 int metaType)
+{
+    if (vctxt->nbAttrInfos == 0)
+	return (NULL);
+    {
+	int i;
+	xmlSchemaAttrInfoPtr iattr;
+
+	for (i = 0; i < vctxt->nbAttrInfos; i++) {
+	    iattr = vctxt->attrInfos[i];
+	    if (iattr->metaType == metaType)
+		return (iattr);
+	}
+
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaAssembleByXSI:
+ * @vctxt:  a schema validation context
+ *
+ * Expands an existing schema by an additional schema using
+ * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
+ * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
+ * must be set to 1.
+ *
+ * Returns 0 if the new schema is correct, a positive error code
+ * number otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
+{
+    const xmlChar *cur, *end;
+    const xmlChar *nsname = NULL, *location;
+    int count = 0;
+    int ret = 0;
+    xmlSchemaAttrInfoPtr iattr;
+
+    /*
+    * Parse the value; we will assume an even number of values
+    * to be given (this is how Xerces and XSV work).
+    *
+    * URGENT TODO: !! This needs to work for both
+    * @noNamespaceSchemaLocation AND @schemaLocation on the same
+    * element !!
+    */
+    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
+    if (iattr == NULL)
+	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
+    if (iattr == NULL)
+	return (0);
+    cur = iattr->value;
+    do {
+	/*
+	* TODO: Move the string parsing mechanism away from here.
+	*/
+	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
+	    /*
+	    * Get the namespace name.
+	    */
+	    while (IS_BLANK_CH(*cur))
+		cur++;
+	    end = cur;
+	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+		end++;
+	    if (end == cur)
+		break;
+	    count++; /* TODO: Don't use the schema's dict. */
+	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
+	    cur = end;
+	}
+	/*
+	* Get the URI.
+	*/
+	while (IS_BLANK_CH(*cur))
+	    cur++;
+	end = cur;
+	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+	    end++;
+	if (end == cur) {
+	    if (iattr->metaType ==
+		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
+	    {
+		/*
+		* If using @schemaLocation then tuples are expected.
+		* I.e. the namespace name *and* the document's URI.
+		*/
+		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
+		    iattr->node, NULL,
+		    "The value must consist of tuples: the target namespace "
+		    "name and the document's URI", NULL, NULL, NULL);
+	    }
+	    break;
+	}
+	count++; /* TODO: Don't use the schema's dict. */
+	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
+	cur = end;
+	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
+	    iattr->node, nsname, location);
+	if (ret == -1) {
+	    VERROR_INT("xmlSchemaAssembleByXSI",
+		"assembling schemata");
+	    return (-1);
+	}
+    } while (*cur != 0);
+    return (ret);
+}
+
+static const xmlChar *
+xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
+			 const xmlChar *prefix)
+{
+    if (vctxt->sax != NULL) {
+	int i, j;
+	xmlSchemaNodeInfoPtr inode;
+
+	for (i = vctxt->depth; i >= 0; i--) {
+	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
+		inode = vctxt->elemInfos[i];
+		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
+		    if (((prefix == NULL) &&
+			    (inode->nsBindings[j] == NULL)) ||
+			((prefix != NULL) && xmlStrEqual(prefix,
+			    inode->nsBindings[j]))) {
+
+			/*
+			* Note that the namespace bindings are already
+			* in a string dict.
+			*/
+			return (inode->nsBindings[j+1]);
+		    }
+		}
+	    }
+	}
+	return (NULL);
+#ifdef LIBXML_READER_ENABLED
+    } else if (vctxt->reader != NULL) {
+	xmlChar *nsName;
+
+	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
+	if (nsName != NULL) {
+	    const xmlChar *ret;
+
+	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
+	    xmlFree(nsName);
+	    return (ret);
+	} else
+	    return (NULL);
+#endif
+    } else {
+	xmlNsPtr ns;
+
+	if ((vctxt->inode->node == NULL) ||
+	    (vctxt->inode->node->doc == NULL)) {
+	    VERROR_INT("xmlSchemaLookupNamespace",
+		"no node or node's doc avaliable");
+	    return (NULL);
+	}
+	ns = xmlSearchNs(vctxt->inode->node->doc,
+	    vctxt->inode->node, prefix);
+	if (ns != NULL)
+	    return (ns->href);
+	return (NULL);
+    }
+}
+
+/*
+* This one works on the schema of the validation context.
+*/
+static int
+xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
+			  xmlSchemaPtr schema,
+			  xmlNodePtr node,
+			  const xmlChar *value,
+			  xmlSchemaValPtr *val,
+			  int valNeeded)
+{
+    int ret;
+
+    if (vctxt && (vctxt->schema == NULL)) {
+	VERROR_INT("xmlSchemaValidateNotation",
+	    "a schema is needed on the validation context");
+	return (-1);
+    }
+    ret = xmlValidateQName(value, 1);
+    if (ret != 0)
+	return (ret);
+    {
+	xmlChar *localName = NULL;
+	xmlChar *prefix = NULL;
+
+	localName = xmlSplitQName2(value, &prefix);
+	if (prefix != NULL) {
+	    const xmlChar *nsName = NULL;
+
+	    if (vctxt != NULL)
+		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
+	    else if (node != NULL) {
+		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
+		if (ns != NULL)
+		    nsName = ns->href;
+	    } else {
+		xmlFree(prefix);
+		xmlFree(localName);
+		return (1);
+	    }
+	    if (nsName == NULL) {
+		xmlFree(prefix);
+		xmlFree(localName);
+		return (1);
+	    }
+	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
+		if ((valNeeded) && (val != NULL)) {
+		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
+						       xmlStrdup(nsName));
+		    if (*val == NULL)
+			ret = -1;
+		}
+	    } else
+		ret = 1;
+	    xmlFree(prefix);
+	    xmlFree(localName);
+	} else {
+	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
+		if (valNeeded && (val != NULL)) {
+		    (*val) = xmlSchemaNewNOTATIONValue(
+			BAD_CAST xmlStrdup(value), NULL);
+		    if (*val == NULL)
+			ret = -1;
+		}
+	    } else
+		return (1);
+	}
+    }
+    return (ret);
+}
+
+static int
+xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
+		       const xmlChar* lname,
+		       const xmlChar* nsname)
+{
+    int i;
+
+    lname = xmlDictLookup(vctxt->dict, lname, -1);
+    if (lname == NULL)
+	return(-1);
+    if (nsname != NULL) {
+	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
+	if (nsname == NULL)
+	    return(-1);
+    }
+    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
+	if ((vctxt->nodeQNames->items [i] == lname) &&
+	    (vctxt->nodeQNames->items[i +1] == nsname))
+	    /* Already there */
+	    return(i);
+    }
+    /* Add new entry. */
+    i = vctxt->nodeQNames->nbItems;
+    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
+    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
+    return(i);
+}
+
+/************************************************************************
+ * 									*
+ *  Validation of identity-constraints (IDC)                            *
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaAugmentIDC:
+ * @idcDef: the IDC definition
+ *
+ * Creates an augmented IDC definition item.
+ *
+ * Returns the item, or NULL on internal errors.
+ */
+static void
+xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
+		    xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaIDCAugPtr aidc;
+
+    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
+    if (aidc == NULL) {
+	xmlSchemaVErrMemory(vctxt,
+	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
+	    NULL);
+	return;
+    }
+    aidc->keyrefDepth = -1;
+    aidc->def = idcDef;
+    aidc->next = NULL;
+    if (vctxt->aidcs == NULL)
+	vctxt->aidcs = aidc;
+    else {
+	aidc->next = vctxt->aidcs;
+	vctxt->aidcs = aidc;
+    }
+    /*
+    * Save if we have keyrefs at all.
+    */
+    if ((vctxt->hasKeyrefs == 0) &&
+	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
+	vctxt->hasKeyrefs = 1;
+}
+
+/**
+ * xmlSchemaAugmentImportedIDC:
+ * @imported: the imported schema
+ *
+ * Creates an augmented IDC definition for the imported schema.
+ */
+static void
+xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
+    if (imported->schema->idcDef != NULL) {
+	    xmlHashScan(imported->schema->idcDef ,
+	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
+    }
+}
+
+/**
+ * xmlSchemaIDCNewBinding:
+ * @idcDef: the IDC definition of this binding
+ *
+ * Creates a new IDC binding.
+ *
+ * Returns the new IDC binding, NULL on internal errors.
+ */
+static xmlSchemaPSVIIDCBindingPtr
+xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
+{
+    xmlSchemaPSVIIDCBindingPtr ret;
+
+    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
+	    sizeof(xmlSchemaPSVIIDCBinding));
+    if (ret == NULL) {
+	xmlSchemaVErrMemory(NULL,
+	    "allocating a PSVI IDC binding item", NULL);
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
+    ret->definition = idcDef;
+    return (ret);
+}
+
+/**
+ * xmlSchemaIDCStoreNodeTableItem:
+ * @vctxt: the WXS validation context
+ * @item: the IDC node table item
+ *
+ * The validation context is used to store IDC node table items.
+ * They are stored to avoid copying them if IDC node-tables are merged
+ * with corresponding parent IDC node-tables (bubbling).
+ *
+ * Returns 0 if succeeded, -1 on internal errors.
+ */
+static int
+xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
+			       xmlSchemaPSVIIDCNodePtr item)
+{
+    /*
+    * Add to gobal list.
+    */
+    if (vctxt->idcNodes == NULL) {
+	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
+	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
+	if (vctxt->idcNodes == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"allocating the IDC node table item list", NULL);
+	    return (-1);
+	}
+	vctxt->sizeIdcNodes = 20;
+    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
+	vctxt->sizeIdcNodes *= 2;
+	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
+	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
+	    sizeof(xmlSchemaPSVIIDCNodePtr));
+	if (vctxt->idcNodes == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"re-allocating the IDC node table item list", NULL);
+	    return (-1);
+	}
+    }
+    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
+
+    return (0);
+}
+
+/**
+ * xmlSchemaIDCStoreKey:
+ * @vctxt: the WXS validation context
+ * @item: the IDC key
+ *
+ * The validation context is used to store an IDC key.
+ *
+ * Returns 0 if succeeded, -1 on internal errors.
+ */
+static int
+xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
+		     xmlSchemaPSVIIDCKeyPtr key)
+{
+    /*
+    * Add to gobal list.
+    */
+    if (vctxt->idcKeys == NULL) {
+	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
+	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
+	if (vctxt->idcKeys == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"allocating the IDC key storage list", NULL);
+	    return (-1);
+	}
+	vctxt->sizeIdcKeys = 40;
+    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
+	vctxt->sizeIdcKeys *= 2;
+	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
+	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
+	    sizeof(xmlSchemaPSVIIDCKeyPtr));
+	if (vctxt->idcKeys == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"re-allocating the IDC key storage list", NULL);
+	    return (-1);
+	}
+    }
+    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
+
+    return (0);
+}
+
+/**
+ * xmlSchemaIDCAppendNodeTableItem:
+ * @bind: the IDC binding
+ * @ntItem: the node-table item
+ *
+ * Appends the IDC node-table item to the binding.
+ *
+ * Returns 0 on success and -1 on internal errors.
+ */
+static int
+xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
+				xmlSchemaPSVIIDCNodePtr ntItem)
+{
+    if (bind->nodeTable == NULL) {
+	bind->sizeNodes = 10;
+	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
+	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
+	if (bind->nodeTable == NULL) {
+	    xmlSchemaVErrMemory(NULL,
+		"allocating an array of IDC node-table items", NULL);
+	    return(-1);
+	}
+    } else if (bind->sizeNodes <= bind->nbNodes) {
+	bind->sizeNodes *= 2;
+	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
+	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
+		sizeof(xmlSchemaPSVIIDCNodePtr));
+	if (bind->nodeTable == NULL) {
+	    xmlSchemaVErrMemory(NULL,
+		"re-allocating an array of IDC node-table items", NULL);
+	    return(-1);
+	}
+    }
+    bind->nodeTable[bind->nbNodes++] = ntItem;
+    return(0);
+}
+
+/**
+ * xmlSchemaIDCAcquireBinding:
+ * @vctxt: the WXS validation context
+ * @matcher: the IDC matcher
+ *
+ * Looks up an PSVI IDC binding, for the IDC definition and
+ * of the given matcher. If none found, a new one is created
+ * and added to the IDC table.
+ *
+ * Returns an IDC binding or NULL on internal errors.
+ */
+static xmlSchemaPSVIIDCBindingPtr
+xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
+			  xmlSchemaIDCMatcherPtr matcher)
+{
+    xmlSchemaNodeInfoPtr ielem;
+
+    ielem = vctxt->elemInfos[matcher->depth];
+
+    if (ielem->idcTable == NULL) {
+	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
+	if (ielem->idcTable == NULL)
+	    return (NULL);
+	return(ielem->idcTable);
+    } else {
+	xmlSchemaPSVIIDCBindingPtr bind = NULL;
+
+	bind = ielem->idcTable;
+	do {
+	    if (bind->definition == matcher->aidc->def)
+		return(bind);
+	    if (bind->next == NULL) {
+		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
+		if (bind->next == NULL)
+		    return (NULL);
+		return(bind->next);
+	    }
+	    bind = bind->next;
+	} while (bind != NULL);
+    }
+    return (NULL);
+}
+
+static xmlSchemaItemListPtr
+xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
+			     xmlSchemaIDCMatcherPtr matcher)
+{
+    if (matcher->targets == NULL)
+	matcher->targets = xmlSchemaItemListCreate();
+    return(matcher->targets);
+}
+
+/**
+ * xmlSchemaIDCFreeKey:
+ * @key: the IDC key
+ *
+ * Frees an IDC key together with its compiled value.
+ */
+static void
+xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
+{
+    if (key->val != NULL)
+	xmlSchemaFreeValue(key->val);
+    xmlFree(key);
+}
+
+/**
+ * xmlSchemaIDCFreeBinding:
+ *
+ * Frees an IDC binding. Note that the node table-items
+ * are not freed.
+ */
+static void
+xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
+{
+    if (bind->nodeTable != NULL)
+	xmlFree(bind->nodeTable);
+    if (bind->dupls != NULL)
+	xmlSchemaItemListFree(bind->dupls);
+    xmlFree(bind);
+}
+
+/**
+ * xmlSchemaIDCFreeIDCTable:
+ * @bind: the first IDC binding in the list
+ *
+ * Frees an IDC table, i.e. all the IDC bindings in the list.
+ */
+static void
+xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
+{
+    xmlSchemaPSVIIDCBindingPtr prev;
+
+    while (bind != NULL) {
+	prev = bind;
+	bind = bind->next;
+	xmlSchemaIDCFreeBinding(prev);
+    }
+}
+
+/**
+ * xmlSchemaIDCFreeMatcherList:
+ * @matcher: the first IDC matcher in the list
+ *
+ * Frees a list of IDC matchers.
+ */
+static void
+xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
+{
+    xmlSchemaIDCMatcherPtr next;
+
+    while (matcher != NULL) {
+	next = matcher->next;
+	if (matcher->keySeqs != NULL) {
+	    int i;
+	    for (i = 0; i < matcher->sizeKeySeqs; i++)
+		if (matcher->keySeqs[i] != NULL)
+		    xmlFree(matcher->keySeqs[i]);
+	    xmlFree(matcher->keySeqs);
+	}
+	if (matcher->targets != NULL) {
+	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
+		int i;
+		xmlSchemaPSVIIDCNodePtr idcNode;
+		/*
+		* Node-table items for keyrefs are not stored globally
+		* to the validation context, since they are not bubbled.
+		* We need to free them here.
+		*/
+		for (i = 0; i < matcher->targets->nbItems; i++) {
+		    idcNode =
+			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
+		    xmlFree(idcNode->keys);
+		    xmlFree(idcNode);
+		}
+	    }
+	    xmlSchemaItemListFree(matcher->targets);
+	}
+	xmlFree(matcher);
+	matcher = next;
+    }
+}
+
+/**
+ * xmlSchemaIDCReleaseMatcherList:
+ * @vctxt: the WXS validation context
+ * @matcher: the first IDC matcher in the list
+ *
+ * Caches a list of IDC matchers for reuse.
+ */
+static void
+xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
+			       xmlSchemaIDCMatcherPtr matcher)
+{
+    xmlSchemaIDCMatcherPtr next;
+
+    while (matcher != NULL) {
+	next = matcher->next;
+	if (matcher->keySeqs != NULL) {
+	    int i;
+	    /*
+	    * Don't free the array, but only the content.
+	    */
+	    for (i = 0; i < matcher->sizeKeySeqs; i++)
+		if (matcher->keySeqs[i] != NULL) {
+		    xmlFree(matcher->keySeqs[i]);
+		    matcher->keySeqs[i] = NULL;
+		}
+	}
+	if (matcher->targets) {
+	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
+		int i;
+		xmlSchemaPSVIIDCNodePtr idcNode;
+		/*
+		* Node-table items for keyrefs are not stored globally
+		* to the validation context, since they are not bubbled.
+		* We need to free them here.
+		*/
+		for (i = 0; i < matcher->targets->nbItems; i++) {
+		    idcNode =
+			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
+		    xmlFree(idcNode->keys);
+		    xmlFree(idcNode);
+		}
+	    }
+	    xmlSchemaItemListFree(matcher->targets);
+	    matcher->targets = NULL;
+	}
+	matcher->next = NULL;
+	/*
+	* Cache the matcher.
+	*/
+	if (vctxt->idcMatcherCache != NULL)
+	    matcher->nextCached = vctxt->idcMatcherCache;
+	vctxt->idcMatcherCache = matcher;
+
+	matcher = next;
+    }
+}
+
+/**
+ * xmlSchemaIDCAddStateObject:
+ * @vctxt: the WXS validation context
+ * @matcher: the IDC matcher
+ * @sel: the XPath information
+ * @parent: the parent "selector" state object if any
+ * @type: "selector" or "field"
+ *
+ * Creates/reuses and activates state objects for the given
+ * XPath information; if the XPath expression consists of unions,
+ * multiple state objects are created for every unioned expression.
+ *
+ * Returns 0 on success and -1 on internal errors.
+ */
+static int
+xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
+			xmlSchemaIDCMatcherPtr matcher,
+			xmlSchemaIDCSelectPtr sel,
+			int type)
+{
+    xmlSchemaIDCStateObjPtr sto;
+
+    /*
+    * Reuse the state objects from the pool.
+    */
+    if (vctxt->xpathStatePool != NULL) {
+	sto = vctxt->xpathStatePool;
+	vctxt->xpathStatePool = sto->next;
+	sto->next = NULL;
+    } else {
+	/*
+	* Create a new state object.
+	*/
+	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
+	if (sto == NULL) {
+	    xmlSchemaVErrMemory(NULL,
+		"allocating an IDC state object", NULL);
+	    return (-1);
+	}
+	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
+    }
+    /*
+    * Add to global list.
+    */
+    if (vctxt->xpathStates != NULL)
+	sto->next = vctxt->xpathStates;
+    vctxt->xpathStates = sto;
+
+    /*
+    * Free the old xpath validation context.
+    */
+    if (sto->xpathCtxt != NULL)
+	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
+
+    /*
+    * Create a new XPath (pattern) validation context.
+    */
+    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
+	(xmlPatternPtr) sel->xpathComp);
+    if (sto->xpathCtxt == NULL) {
+	VERROR_INT("xmlSchemaIDCAddStateObject",
+	    "failed to create an XPath validation context");
+	return (-1);
+    }
+    sto->type = type;
+    sto->depth = vctxt->depth;
+    sto->matcher = matcher;
+    sto->sel = sel;
+    sto->nbHistory = 0;
+
+#ifdef DEBUG_IDC
+    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
+	sto->sel->xpath);
+#endif
+    return (0);
+}
+
+/**
+ * xmlSchemaXPathEvaluate:
+ * @vctxt: the WXS validation context
+ * @nodeType: the nodeType of the current node
+ *
+ * Evaluates all active XPath state objects.
+ *
+ * Returns the number of IC "field" state objects which resolved to
+ * this node, 0 if none resolved and -1 on internal errors.
+ */
+static int
+xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
+		       xmlElementType nodeType)
+{
+    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
+    int res, resolved = 0, depth = vctxt->depth;
+
+    if (vctxt->xpathStates == NULL)
+	return (0);
+
+    if (nodeType == XML_ATTRIBUTE_NODE)
+	depth++;
+#ifdef DEBUG_IDC
+    {
+	xmlChar *str = NULL;
+	xmlGenericError(xmlGenericErrorContext,
+	    "IDC: EVAL on %s, depth %d, type %d\n",
+	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
+		vctxt->inode->localName), depth, nodeType);
+	FREE_AND_NULL(str)
+    }
+#endif
+    /*
+    * Process all active XPath state objects.
+    */
+    first = vctxt->xpathStates;
+    sto = first;
+    while (sto != head) {
+#ifdef DEBUG_IDC
+	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
+	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
+		sto->matcher->aidc->def->name, sto->sel->xpath);
+	else
+	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
+		sto->matcher->aidc->def->name, sto->sel->xpath);
+#endif
+	if (nodeType == XML_ELEMENT_NODE)
+	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
+		vctxt->inode->localName, vctxt->inode->nsName);
+	else
+	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
+		vctxt->inode->localName, vctxt->inode->nsName);
+
+	if (res == -1) {
+	    VERROR_INT("xmlSchemaXPathEvaluate",
+		"calling xmlStreamPush()");
+	    return (-1);
+	}
+	if (res == 0)
+	    goto next_sto;
+	/*
+	* Full match.
+	*/
+#ifdef DEBUG_IDC
+	xmlGenericError(xmlGenericErrorContext, "IDC:     "
+	    "MATCH\n");
+#endif
+	/*
+	* Register a match in the state object history.
+	*/
+	if (sto->history == NULL) {
+	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
+	    if (sto->history == NULL) {
+		xmlSchemaVErrMemory(NULL,
+		    "allocating the state object history", NULL);
+		return(-1);
+	    }
+	    sto->sizeHistory = 5;
+	} else if (sto->sizeHistory <= sto->nbHistory) {
+	    sto->sizeHistory *= 2;
+	    sto->history = (int *) xmlRealloc(sto->history,
+		sto->sizeHistory * sizeof(int));
+	    if (sto->history == NULL) {
+		xmlSchemaVErrMemory(NULL,
+		    "re-allocating the state object history", NULL);
+		return(-1);
+	    }
+	}
+	sto->history[sto->nbHistory++] = depth;
+
+#ifdef DEBUG_IDC
+	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
+	    vctxt->depth);
+#endif
+
+	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
+	    xmlSchemaIDCSelectPtr sel;
+	    /*
+	    * Activate state objects for the IDC fields of
+	    * the IDC selector.
+	    */
+#ifdef DEBUG_IDC
+	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
+		"activating field states\n");
+#endif
+	    sel = sto->matcher->aidc->def->fields;
+	    while (sel != NULL) {
+		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
+		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
+		    return (-1);
+		sel = sel->next;
+	    }
+	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
+	    /*
+	    * An IDC key node was found by the IDC field.
+	    */
+#ifdef DEBUG_IDC
+	    xmlGenericError(xmlGenericErrorContext,
+		"IDC:     key found\n");
+#endif
+	    /*
+	    * Notify that the character value of this node is
+	    * needed.
+	    */
+	    if (resolved == 0) {
+		if ((vctxt->inode->flags &
+		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
+		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
+	    }
+	    resolved++;
+	}
+next_sto:
+	if (sto->next == NULL) {
+	    /*
+	    * Evaluate field state objects created on this node as well.
+	    */
+	    head = first;
+	    sto = vctxt->xpathStates;
+	} else
+	    sto = sto->next;
+    }
+    return (resolved);
+}
+
+static const xmlChar *
+xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
+			      xmlChar **buf,
+			      xmlSchemaPSVIIDCKeyPtr *seq,
+			      int count)
+{
+    int i, res;
+    xmlChar *value = NULL;
+
+    *buf = xmlStrdup(BAD_CAST "[");
+    for (i = 0; i < count; i++) {
+	*buf = xmlStrcat(*buf, BAD_CAST "'");
+	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
+	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
+	    &value);
+	if (res == 0)
+	    *buf = xmlStrcat(*buf, BAD_CAST value);
+	else {
+	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
+		"failed to compute a canonical value");
+	    *buf = xmlStrcat(*buf, BAD_CAST "???");
+	}
+	if (i < count -1)
+	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
+	else
+	    *buf = xmlStrcat(*buf, BAD_CAST "'");
+	if (value != NULL) {
+	    xmlFree(value);
+	    value = NULL;
+	}
+    }
+    *buf = xmlStrcat(*buf, BAD_CAST "]");
+
+    return (BAD_CAST *buf);
+}
+
+/**
+ * xmlSchemaXPathPop:
+ * @vctxt: the WXS validation context
+ *
+ * Pops all XPath states.
+ *
+ * Returns 0 on success and -1 on internal errors.
+ */
+static int
+xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaIDCStateObjPtr sto;
+    int res;
+
+    if (vctxt->xpathStates == NULL)
+	return(0);
+    sto = vctxt->xpathStates;
+    do {
+	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
+	if (res == -1)
+	    return (-1);
+	sto = sto->next;
+    } while (sto != NULL);
+    return(0);
+}
+
+/**
+ * xmlSchemaXPathProcessHistory:
+ * @vctxt: the WXS validation context
+ * @type: the simple/complex type of the current node if any at all
+ * @val: the precompiled value
+ *
+ * Processes and pops the history items of the IDC state objects.
+ * IDC key-sequences are validated/created on IDC bindings.
+ *
+ * Returns 0 on success and -1 on internal errors.
+ */
+static int
+xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
+			     int depth)
+{
+    xmlSchemaIDCStateObjPtr sto, nextsto;
+    int res, matchDepth;
+    xmlSchemaPSVIIDCKeyPtr key = NULL;
+    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
+
+    if (vctxt->xpathStates == NULL)
+	return (0);
+    sto = vctxt->xpathStates;
+
+#ifdef DEBUG_IDC
+    {
+	xmlChar *str = NULL;
+	xmlGenericError(xmlGenericErrorContext,
+	    "IDC: BACK on %s, depth %d\n",
+	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
+		vctxt->inode->localName), vctxt->depth);
+	FREE_AND_NULL(str)
+    }
+#endif
+    /*
+    * Evaluate the state objects.
+    */
+    while (sto != NULL) {
+	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
+	if (res == -1) {
+	    VERROR_INT("xmlSchemaXPathProcessHistory",
+		"calling xmlStreamPop()");
+	    return (-1);
+	}
+#ifdef DEBUG_IDC
+	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
+	    sto->sel->xpath);
+#endif
+	if (sto->nbHistory == 0)
+	    goto deregister_check;
+
+	matchDepth = sto->history[sto->nbHistory -1];
+
+	/*
+	* Only matches at the current depth are of interest.
+	*/
+	if (matchDepth != depth) {
+	    sto = sto->next;
+	    continue;
+	}
+	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
+	    /*
+	    * NOTE: According to
+	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
+	    *   ... the simple-content of complex types is also allowed.
+	    */
+
+	    if (WXS_IS_COMPLEX(type)) {
+		if (WXS_HAS_SIMPLE_CONTENT(type)) {
+		    /*
+		    * Sanity check for complex types with simple content.
+		    */
+		    simpleType = type->contentTypeDef;
+		    if (simpleType == NULL) {
+			VERROR_INT("xmlSchemaXPathProcessHistory",
+			    "field resolves to a CT with simple content "
+			    "but the CT is missing the ST definition");
+			return (-1);
+		    }
+		} else
+		    simpleType = NULL;
+	    } else
+		simpleType = type;
+	    if (simpleType == NULL) {
+		xmlChar *str = NULL;
+
+		/*
+		* Not qualified if the field resolves to a node of non
+		* simple type.
+		*/
+		xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_CVC_IDC, NULL,
+		    WXS_BASIC_CAST sto->matcher->aidc->def,
+		    "The XPath '%s' of a field of %s does evaluate to a node of "
+		    "non-simple type",
+		    sto->sel->xpath,
+		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
+		FREE_AND_NULL(str);
+		sto->nbHistory--;
+		goto deregister_check;
+	    }
+
+	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
+		/*
+		* Failed to provide the normalized value; maybe
+		* the value was invalid.
+		*/
+		VERROR(XML_SCHEMAV_CVC_IDC,
+		    WXS_BASIC_CAST sto->matcher->aidc->def,
+		    "Warning: No precomputed value available, the value "
+		    "was either invalid or something strange happend");
+		sto->nbHistory--;
+		goto deregister_check;
+	    } else {
+		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
+		xmlSchemaPSVIIDCKeyPtr *keySeq;
+		int pos, idx;
+
+		/*
+		* The key will be anchored on the matcher's list of
+		* key-sequences. The position in this list is determined
+		* by the target node's depth relative to the matcher's
+		* depth of creation (i.e. the depth of the scope element).
+		*
+		* Element        Depth    Pos   List-entries
+		* <scope>          0              NULL
+		*   <bar>          1              NULL
+		*     <target/>    2       2      target
+		*   <bar>
+                * </scope>
+		*
+		* The size of the list is only dependant on the depth of
+		* the tree.
+		* An entry will be NULLed in selector_leave, i.e. when
+		* we hit the target's
+		*/
+		pos = sto->depth - matcher->depth;
+		idx = sto->sel->index;
+
+		/*
+		* Create/grow the array of key-sequences.
+		*/
+		if (matcher->keySeqs == NULL) {
+		    if (pos > 9)
+			matcher->sizeKeySeqs = pos * 2;
+		    else
+			matcher->sizeKeySeqs = 10;
+		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
+			xmlMalloc(matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));
+		    if (matcher->keySeqs == NULL) {
+			xmlSchemaVErrMemory(NULL,
+			    "allocating an array of key-sequences",
+			    NULL);
+			return(-1);
+		    }
+		    memset(matcher->keySeqs, 0,
+			matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));
+		} else if (pos >= matcher->sizeKeySeqs) {
+		    int i = matcher->sizeKeySeqs;
+
+		    matcher->sizeKeySeqs *= 2;
+		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
+			xmlRealloc(matcher->keySeqs,
+			matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));
+		    if (matcher->keySeqs == NULL) {
+			xmlSchemaVErrMemory(NULL,
+			    "reallocating an array of key-sequences",
+			    NULL);
+			return (-1);
+		    }
+		    /*
+		    * The array needs to be NULLed.
+		    * TODO: Use memset?
+		    */
+		    for (; i < matcher->sizeKeySeqs; i++)
+			matcher->keySeqs[i] = NULL;
+		}
+
+		/*
+		* Get/create the key-sequence.
+		*/
+		keySeq = matcher->keySeqs[pos];
+		if (keySeq == NULL) {
+		    goto create_sequence;
+		} else if (keySeq[idx] != NULL) {
+		    xmlChar *str = NULL;
+		    /*
+		    * cvc-identity-constraint:
+		    * 3 For each node in the �target node set� all
+		    * of the {fields}, with that node as the context
+		    * node, evaluate to either an empty node-set or
+		    * a node-set with exactly one member, which must
+		    * have a simple type.
+		    *
+		    * The key was already set; report an error.
+		    */
+		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
+			XML_SCHEMAV_CVC_IDC, NULL,
+			WXS_BASIC_CAST matcher->aidc->def,
+			"The XPath '%s' of a field of %s evaluates to a "
+			"node-set with more than one member",
+			sto->sel->xpath,
+			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
+		    FREE_AND_NULL(str);
+		    sto->nbHistory--;
+		    goto deregister_check;
+		} else
+		    goto create_key;
+
+create_sequence:
+		/*
+		* Create a key-sequence.
+		*/
+		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
+		    matcher->aidc->def->nbFields *
+		    sizeof(xmlSchemaPSVIIDCKeyPtr));
+		if (keySeq == NULL) {
+		    xmlSchemaVErrMemory(NULL,
+			"allocating an IDC key-sequence", NULL);
+		    return(-1);
+		}
+		memset(keySeq, 0, matcher->aidc->def->nbFields *
+		    sizeof(xmlSchemaPSVIIDCKeyPtr));
+		matcher->keySeqs[pos] = keySeq;
+create_key:
+		/*
+		* Create a key once per node only.
+		*/
+		if (key == NULL) {
+		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
+			sizeof(xmlSchemaPSVIIDCKey));
+		    if (key == NULL) {
+			xmlSchemaVErrMemory(NULL,
+			    "allocating a IDC key", NULL);
+			xmlFree(keySeq);
+			matcher->keySeqs[pos] = NULL;
+			return(-1);
+		    }
+		    /*
+		    * Consume the compiled value.
+		    */
+		    key->type = simpleType;
+		    key->val = vctxt->inode->val;
+		    vctxt->inode->val = NULL;
+		    /*
+		    * Store the key in a global list.
+		    */
+		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
+			xmlSchemaIDCFreeKey(key);
+			return (-1);
+		    }
+		}
+		keySeq[idx] = key;
+	    }
+	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
+
+	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
+	    /* xmlSchemaPSVIIDCBindingPtr bind; */
+	    xmlSchemaPSVIIDCNodePtr ntItem;
+	    xmlSchemaIDCMatcherPtr matcher;
+	    xmlSchemaIDCPtr idc;
+	    xmlSchemaItemListPtr targets;
+	    int pos, i, j, nbKeys;
+	    /*
+	    * Here we have the following scenario:
+	    * An IDC 'selector' state object resolved to a target node,
+	    * during the time this target node was in the
+	    * ancestor-or-self axis, the 'field' state object(s) looked
+	    * out for matching nodes to create a key-sequence for this
+	    * target node. Now we are back to this target node and need
+	    * to put the key-sequence, together with the target node
+	    * itself, into the node-table of the corresponding IDC
+	    * binding.
+	    */
+	    matcher = sto->matcher;
+	    idc = matcher->aidc->def;
+	    nbKeys = idc->nbFields;
+	    pos = depth - matcher->depth;
+	    /*
+	    * Check if the matcher has any key-sequences at all, plus
+	    * if it has a key-sequence for the current target node.
+	    */
+	    if ((matcher->keySeqs == NULL) ||
+		(matcher->sizeKeySeqs <= pos)) {
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
+		    goto selector_key_error;
+		else
+		    goto selector_leave;
+	    }
+
+	    keySeq = &(matcher->keySeqs[pos]);
+	    if (*keySeq == NULL) {
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
+		    goto selector_key_error;
+		else
+		    goto selector_leave;
+	    }
+
+	    for (i = 0; i < nbKeys; i++) {
+		if ((*keySeq)[i] == NULL) {
+		    /*
+		    * Not qualified, if not all fields did resolve.
+		    */
+		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
+			/*
+			* All fields of a "key" IDC must resolve.
+			*/
+			goto selector_key_error;
+		    }
+		    goto selector_leave;
+		}
+	    }
+	    /*
+	    * All fields did resolve.
+	    */
+
+	    /*
+	    * 4.1 If the {identity-constraint category} is unique(/key),
+	    * then no two members of the �qualified node set� have
+	    * �key-sequences� whose members are pairwise equal, as
+	    * defined by Equal in [XML Schemas: Datatypes].
+	    *
+	    * Get the IDC binding from the matcher and check for
+	    * duplicate key-sequences.
+	    */
+#if 0
+	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
+#endif
+	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
+	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
+		(targets->nbItems != 0)) {
+		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
+
+		i = 0;
+		res = 0;
+		/*
+		* Compare the key-sequences, key by key.
+		*/
+		do {
+		    bkeySeq =
+			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
+		    for (j = 0; j < nbKeys; j++) {
+			ckey = (*keySeq)[j];
+			bkey = bkeySeq[j];
+			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
+			if (res == -1) {
+			    return (-1);
+			} else if (res == 0) {
+			    /*
+			    * One of the keys differs, so the key-sequence
+			    * won't be equal; get out.
+			    */
+			    break;
+			}
+		    }
+		    if (res == 1) {
+			/*
+			* Duplicate key-sequence found.
+			*/
+			break;
+		    }
+		    i++;
+		} while (i < targets->nbItems);
+		if (i != targets->nbItems) {
+		    xmlChar *str = NULL, *strB = NULL;
+		    /*
+		    * TODO: Try to report the key-sequence.
+		    */
+		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
+			XML_SCHEMAV_CVC_IDC, NULL,
+			WXS_BASIC_CAST idc,
+			"Duplicate key-sequence %s in %s",
+			xmlSchemaFormatIDCKeySequence(vctxt, &str,
+			    (*keySeq), nbKeys),
+			xmlSchemaGetIDCDesignation(&strB, idc));
+		    FREE_AND_NULL(str);
+		    FREE_AND_NULL(strB);
+		    goto selector_leave;
+		}
+	    }
+	    /*
+	    * Add a node-table item to the IDC binding.
+	    */
+	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
+		sizeof(xmlSchemaPSVIIDCNode));
+	    if (ntItem == NULL) {
+		xmlSchemaVErrMemory(NULL,
+		    "allocating an IDC node-table item", NULL);
+		xmlFree(*keySeq);
+		*keySeq = NULL;
+		return(-1);
+	    }
+	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
+
+	    /*
+	    * Store the node-table item in a global list.
+	    */
+	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
+		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
+		    xmlFree(ntItem);
+		    xmlFree(*keySeq);
+		    *keySeq = NULL;
+		    return (-1);
+		}
+		ntItem->nodeQNameID = -1;
+	    } else {
+		/*
+		* Save a cached QName for this node on the IDC node, to be
+		* able to report it, even if the node is not saved.
+		*/
+		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
+		    vctxt->inode->localName, vctxt->inode->nsName);
+		if (ntItem->nodeQNameID == -1) {
+		    xmlFree(ntItem);
+		    xmlFree(*keySeq);
+		    *keySeq = NULL;
+		    return (-1);
+		}
+	    }
+	    /*
+	    * Init the node-table item: Save the node, position and
+	    * consume the key-sequence.
+	    */
+	    ntItem->node = vctxt->node;
+	    ntItem->nodeLine = vctxt->inode->nodeLine;
+	    ntItem->keys = *keySeq;
+	    *keySeq = NULL;
+#if 0
+	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
+#endif
+	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
+		    /*
+		    * Free the item, since keyref items won't be
+		    * put on a global list.
+		    */
+		    xmlFree(ntItem->keys);
+		    xmlFree(ntItem);
+		}
+		return (-1);
+	    }
+
+	    goto selector_leave;
+selector_key_error:
+	    {
+		xmlChar *str = NULL;
+		/*
+		* 4.2.1 (KEY) The �target node set� and the
+		* �qualified node set� are equal, that is, every
+		* member of the �target node set� is also a member
+		* of the �qualified node set� and vice versa.
+		*/
+		xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_CVC_IDC, NULL,
+		    WXS_BASIC_CAST idc,
+		    "Not all fields of %s evaluate to a node",
+		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
+		FREE_AND_NULL(str);
+	    }
+selector_leave:
+	    /*
+	    * Free the key-sequence if not added to the IDC table.
+	    */
+	    if ((keySeq != NULL) && (*keySeq != NULL)) {
+		xmlFree(*keySeq);
+		*keySeq = NULL;
+	    }
+	} /* if selector */
+
+	sto->nbHistory--;
+
+deregister_check:
+	/*
+	* Deregister state objects if they reach the depth of creation.
+	*/
+	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
+#ifdef DEBUG_IDC
+	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
+		sto->sel->xpath);
+#endif
+	    if (vctxt->xpathStates != sto) {
+		VERROR_INT("xmlSchemaXPathProcessHistory",
+		    "The state object to be removed is not the first "
+		    "in the list");
+	    }
+	    nextsto = sto->next;
+	    /*
+	    * Unlink from the list of active XPath state objects.
+	    */
+	    vctxt->xpathStates = sto->next;
+	    sto->next = vctxt->xpathStatePool;
+	    /*
+	    * Link it to the pool of reusable state objects.
+	    */
+	    vctxt->xpathStatePool = sto;
+	    sto = nextsto;
+	} else
+	    sto = sto->next;
+    } /* while (sto != NULL) */
+    return (0);
+}
+
+/**
+ * xmlSchemaIDCRegisterMatchers:
+ * @vctxt: the WXS validation context
+ * @elemDecl: the element declaration
+ *
+ * Creates helper objects to evaluate IDC selectors/fields
+ * successively.
+ *
+ * Returns 0 if OK and -1 on internal errors.
+ */
+static int
+xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
+			     xmlSchemaElementPtr elemDecl)
+{
+    xmlSchemaIDCMatcherPtr matcher, last = NULL;
+    xmlSchemaIDCPtr idc, refIdc;
+    xmlSchemaIDCAugPtr aidc;
+
+    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
+    if (idc == NULL)
+	return (0);
+
+#ifdef DEBUG_IDC
+    {
+	xmlChar *str = NULL;
+	xmlGenericError(xmlGenericErrorContext,
+	    "IDC: REGISTER on %s, depth %d\n",
+	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
+		vctxt->inode->localName), vctxt->depth);
+	FREE_AND_NULL(str)
+    }
+#endif
+    if (vctxt->inode->idcMatchers != NULL) {
+	VERROR_INT("xmlSchemaIDCRegisterMatchers",
+	    "The chain of IDC matchers is expected to be empty");
+	return (-1);
+    }
+    do {
+	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
+	    /*
+	    * Since IDCs bubbles are expensive we need to know the
+	    * depth at which the bubbles should stop; this will be
+	    * the depth of the top-most keyref IDC. If no keyref
+	    * references a key/unique IDC, the keyrefDepth will
+	    * be -1, indicating that no bubbles are needed.
+	    */
+	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
+	    if (refIdc != NULL) {
+		/*
+		* Remember that we have keyrefs on this node.
+		*/
+		vctxt->inode->hasKeyrefs = 1;
+		/*
+		* Lookup the referenced augmented IDC info.
+		*/
+		aidc = vctxt->aidcs;
+		while (aidc != NULL) {
+		    if (aidc->def == refIdc)
+			break;
+		    aidc = aidc->next;
+		}
+		if (aidc == NULL) {
+		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
+			"Could not find an augmented IDC item for an IDC "
+			"definition");
+		    return (-1);
+		}
+		if ((aidc->keyrefDepth == -1) ||
+		    (vctxt->depth < aidc->keyrefDepth))
+		    aidc->keyrefDepth = vctxt->depth;
+	    }
+	}
+	/*
+	* Lookup the augmented IDC item for the IDC definition.
+	*/
+	aidc = vctxt->aidcs;
+	while (aidc != NULL) {
+	    if (aidc->def == idc)
+		break;
+	    aidc = aidc->next;
+	}
+	if (aidc == NULL) {
+	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
+		"Could not find an augmented IDC item for an IDC definition");
+	    return (-1);
+	}
+	/*
+	* Create an IDC matcher for every IDC definition.
+	*/
+	if (vctxt->idcMatcherCache != NULL) {
+	    /*
+	    * Reuse a cached matcher.
+	    */
+	    matcher = vctxt->idcMatcherCache;
+	    vctxt->idcMatcherCache = matcher->nextCached;
+	    matcher->nextCached = NULL;
+	} else {
+	    matcher = (xmlSchemaIDCMatcherPtr)
+		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
+	    if (matcher == NULL) {
+		xmlSchemaVErrMemory(vctxt,
+		    "allocating an IDC matcher", NULL);
+		return (-1);
+	    }
+	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
+	}
+	if (last == NULL)
+	    vctxt->inode->idcMatchers = matcher;
+	else
+	    last->next = matcher;
+	last = matcher;
+
+	matcher->type = IDC_MATCHER;
+	matcher->depth = vctxt->depth;
+	matcher->aidc = aidc;
+	matcher->idcType = aidc->def->type;
+#ifdef DEBUG_IDC
+	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
+#endif
+	/*
+	* Init the automaton state object.
+	*/
+	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
+	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
+	    return (-1);
+
+	idc = idc->next;
+    } while (idc != NULL);
+    return (0);
+}
+
+static int
+xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
+			   xmlSchemaNodeInfoPtr ielem)
+{
+    xmlSchemaPSVIIDCBindingPtr bind;
+    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
+    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
+    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
+
+    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
+    /* vctxt->createIDCNodeTables */
+    while (matcher != NULL) {
+	/*
+	* Skip keyref IDCs and empty IDC target-lists.
+	*/
+	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
+	    WXS_ILIST_IS_EMPTY(matcher->targets))
+	{
+	    matcher = matcher->next;
+	    continue;
+	}
+	/*
+	* If we _want_ the IDC node-table to be created in any case
+	* then do so. Otherwise create them only if keyrefs need them.
+	*/
+	if ((! vctxt->createIDCNodeTables) &&
+	    ((matcher->aidc->keyrefDepth == -1) ||
+	     (matcher->aidc->keyrefDepth > vctxt->depth)))
+	{
+	    matcher = matcher->next;
+	    continue;
+	}
+	/*
+	* Get/create the IDC binding on this element for the IDC definition.
+	*/
+	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
+
+	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
+	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
+	    nbDupls = bind->dupls->nbItems;
+	} else {
+	    dupls = NULL;
+	    nbDupls = 0;
+	}
+	if (bind->nodeTable != NULL) {
+	    nbNodeTable = bind->nbNodes;
+	} else {
+	    nbNodeTable = 0;
+	}
+
+	if ((nbNodeTable == 0) && (nbDupls == 0)) {
+	    /*
+	    * Transfer all IDC target-nodes to the IDC node-table.
+	    */
+	    bind->nodeTable =
+		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
+	    bind->sizeNodes = matcher->targets->sizeItems;
+	    bind->nbNodes = matcher->targets->nbItems;
+
+	    matcher->targets->items = NULL;
+	    matcher->targets->sizeItems = 0;
+	    matcher->targets->nbItems = 0;
+	} else {
+	    /*
+	    * Compare the key-sequences and add to the IDC node-table.
+	    */
+	    nbTargets = matcher->targets->nbItems;
+	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
+	    nbFields = matcher->aidc->def->nbFields;
+	    i = 0;
+	    do {
+		keys = targets[i]->keys;
+		if (nbDupls) {
+		    /*
+		    * Search in already found duplicates first.
+		    */
+		    j = 0;
+		    do {
+			if (nbFields == 1) {
+			    res = xmlSchemaAreValuesEqual(keys[0]->val,
+				dupls[j]->keys[0]->val);
+			    if (res == -1)
+				goto internal_error;
+			    if (res == 1) {
+				/*
+				* Equal key-sequence.
+				*/
+				goto next_target;
+			    }
+			} else {
+			    res = 0;
+			    ntkeys = dupls[j]->keys;
+			    for (k = 0; k < nbFields; k++) {
+				res = xmlSchemaAreValuesEqual(keys[k]->val,
+				    ntkeys[k]->val);
+				if (res == -1)
+				    goto internal_error;
+				if (res == 0) {
+				    /*
+				    * One of the keys differs.
+				    */
+				    break;
+				}
+			    }
+			    if (res == 1) {
+				/*
+				* Equal key-sequence found.
+				*/
+				goto next_target;
+			    }
+			}
+			j++;
+		    } while (j < nbDupls);
+		}
+		if (nbNodeTable) {
+		    j = 0;
+		    do {
+			if (nbFields == 1) {
+			    res = xmlSchemaAreValuesEqual(keys[0]->val,
+				bind->nodeTable[j]->keys[0]->val);
+			    if (res == -1)
+				goto internal_error;
+			    if (res == 0) {
+				/*
+				* The key-sequence differs.
+				*/
+				goto next_node_table_entry;
+			    }
+			} else {
+			    res = 0;
+			    ntkeys = bind->nodeTable[j]->keys;
+			    for (k = 0; k < nbFields; k++) {
+				res = xmlSchemaAreValuesEqual(keys[k]->val,
+				    ntkeys[k]->val);
+				if (res == -1)
+				    goto internal_error;
+				if (res == 0) {
+				    /*
+				    * One of the keys differs.
+				    */
+				    goto next_node_table_entry;
+				}
+			    }
+			}
+			/*
+			* Add the duplicate to the list of duplicates.
+			*/
+			if (bind->dupls == NULL) {
+			    bind->dupls = xmlSchemaItemListCreate();
+			    if (bind->dupls == NULL)
+				goto internal_error;
+			}
+			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
+			    goto internal_error;
+			/*
+			* Remove the duplicate entry from the IDC node-table.
+			*/
+			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
+			bind->nbNodes--;
+
+			goto next_target;
+
+next_node_table_entry:
+			j++;
+		    } while (j < nbNodeTable);
+		}
+		/*
+		* If everything is fine, then add the IDC target-node to
+		* the IDC node-table.
+		*/
+		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
+		    goto internal_error;
+
+next_target:
+		i++;
+	    } while (i < nbTargets);
+	}
+	matcher = matcher->next;
+    }
+    return(0);
+
+internal_error:
+    return(-1);
+}
+
+/**
+ * xmlSchemaBubbleIDCNodeTables:
+ * @depth: the current tree depth
+ *
+ * Merges IDC bindings of an element at @depth into the corresponding IDC
+ * bindings of its parent element. If a duplicate note-table entry is found,
+ * both, the parent node-table entry and child entry are discarded from the
+ * node-table of the parent.
+ *
+ * Returns 0 if OK and -1 on internal errors.
+ */
+static int
+xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
+    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
+    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
+    xmlSchemaIDCAugPtr aidc;
+    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
+
+    bind = vctxt->inode->idcTable;
+    if (bind == NULL) {
+	/* Fine, no table, no bubbles. */
+	return (0);
+    }
+
+    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
+    /*
+    * Walk all bindings; create new or add to existing bindings.
+    * Remove duplicate key-sequences.
+    */
+    while (bind != NULL) {
+
+	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
+	    goto next_binding;
+	/*
+	* Check if the key/unique IDC table needs to be bubbled.
+	*/
+	if (! vctxt->createIDCNodeTables) {
+	    aidc = vctxt->aidcs;
+	    do {
+		if (aidc->def == bind->definition) {
+		    if ((aidc->keyrefDepth == -1) ||
+			(aidc->keyrefDepth >= vctxt->depth)) {
+			goto next_binding;
+		    }
+		    break;
+		}
+		aidc = aidc->next;
+	    } while (aidc != NULL);
+	}
+
+	if (parTable != NULL)
+	    parBind = *parTable;
+	/*
+	* Search a matching parent binding for the
+	* IDC definition.
+	*/
+	while (parBind != NULL) {
+	    if (parBind->definition == bind->definition)
+		break;
+	    parBind = parBind->next;
+	}
+
+	if (parBind != NULL) {
+	    /*
+	    * Compare every node-table entry of the child node,
+	    * i.e. the key-sequence within, ...
+	    */
+	    oldNum = parBind->nbNodes; /* Skip newly added items. */
+
+	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
+		oldDupls = parBind->dupls->nbItems;
+		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
+	    } else {
+		dupls = NULL;
+		oldDupls = 0;
+	    }
+
+	    parNodes = parBind->nodeTable;
+	    nbFields = bind->definition->nbFields;
+
+	    for (i = 0; i < bind->nbNodes; i++) {
+		node = bind->nodeTable[i];
+		if (node == NULL)
+		    continue;
+		/*
+		* ...with every key-sequence of the parent node, already
+		* evaluated to be a duplicate key-sequence.
+		*/
+		if (oldDupls) {
+		    j = 0;
+		    while (j < oldDupls) {
+			if (nbFields == 1) {
+			    ret = xmlSchemaAreValuesEqual(
+				node->keys[0]->val,
+				dupls[j]->keys[0]->val);
+			    if (ret == -1)
+				goto internal_error;
+			    if (ret == 0) {
+				j++;
+				continue;
+			    }
+			} else {
+			    parNode = dupls[j];
+			    for (k = 0; k < nbFields; k++) {
+				ret = xmlSchemaAreValuesEqual(
+				    node->keys[k]->val,
+				    parNode->keys[k]->val);
+				if (ret == -1)
+				    goto internal_error;
+				if (ret == 0)
+				    break;
+			    }
+			}
+			if (ret == 1)
+			    /* Duplicate found. */
+			    break;
+			j++;
+		    }
+		    if (j != oldDupls) {
+			/* Duplicate found. Skip this entry. */
+			continue;
+		    }
+		}
+		/*
+		* ... and with every key-sequence of the parent node.
+		*/
+		if (oldNum) {
+		    j = 0;
+		    while (j < oldNum) {
+			parNode = parNodes[j];
+			if (nbFields == 1) {
+			    ret = xmlSchemaAreValuesEqual(
+				node->keys[0]->val,
+				parNode->keys[0]->val);
+			    if (ret == -1)
+				goto internal_error;
+			    if (ret == 0) {
+				j++;
+				continue;
+			    }
+			} else {
+			    for (k = 0; k < nbFields; k++) {
+				ret = xmlSchemaAreValuesEqual(
+				    node->keys[k]->val,
+				    parNode->keys[k]->val);
+				if (ret == -1)
+				    goto internal_error;
+				if (ret == 0)
+				    break;
+			    }
+			}
+			if (ret == 1)
+			    /* Duplicate found. */
+			    break;
+			j++;
+		    }
+		    if (j != oldNum) {
+			/*
+			* Handle duplicates. Move the duplicate in
+			* the parent's node-table to the list of
+			* duplicates.
+			*/
+			oldNum--;
+			parBind->nbNodes--;
+			/*
+			* Move last old item to pos of duplicate.
+			*/
+			parNodes[j] = parNodes[oldNum];
+
+			if (parBind->nbNodes != oldNum) {
+			    /*
+			    * If new items exist, move last new item to
+			    * last of old items.
+			    */
+			    parNodes[oldNum] =
+				parNodes[parBind->nbNodes];
+			}
+			if (parBind->dupls == NULL) {
+			    parBind->dupls = xmlSchemaItemListCreate();
+			    if (parBind->dupls == NULL)
+				goto internal_error;
+			}
+			xmlSchemaItemListAdd(parBind->dupls, parNode);
+		    } else {
+			/*
+			* Add the node-table entry (node and key-sequence) of
+			* the child node to the node table of the parent node.
+			*/
+			if (parBind->nodeTable == NULL) {
+			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
+				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
+			    if (parBind->nodeTable == NULL) {
+				xmlSchemaVErrMemory(NULL,
+				    "allocating IDC list of node-table items", NULL);
+				goto internal_error;
+			    }
+			    parBind->sizeNodes = 1;
+			} else if (parBind->nbNodes >= parBind->sizeNodes) {
+			    parBind->sizeNodes *= 2;
+			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
+				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
+				sizeof(xmlSchemaPSVIIDCNodePtr));
+			    if (parBind->nodeTable == NULL) {
+				xmlSchemaVErrMemory(NULL,
+				    "re-allocating IDC list of node-table items", NULL);
+				goto internal_error;
+			    }
+			}
+			parNodes = parBind->nodeTable;
+			/*
+			* Append the new node-table entry to the 'new node-table
+			* entries' section.
+			*/
+			parNodes[parBind->nbNodes++] = node;
+		    }
+
+		}
+
+	    }
+	} else {
+	    /*
+	    * No binding for the IDC was found: create a new one and
+	    * copy all node-tables.
+	    */
+	    parBind = xmlSchemaIDCNewBinding(bind->definition);
+	    if (parBind == NULL)
+		goto internal_error;
+
+	    /*
+	    * TODO: Hmm, how to optimize the initial number of
+	    * allocated entries?
+	    */
+	    if (bind->nbNodes != 0) {
+		/*
+		* Add all IDC node-table entries.
+		*/
+		if (! vctxt->psviExposeIDCNodeTables) {
+		    /*
+		    * Just move the entries.
+		    * NOTE: this is quite save here, since
+		    * all the keyref lookups have already been
+		    * performed.
+		    */
+		    parBind->nodeTable = bind->nodeTable;
+		    bind->nodeTable = NULL;
+		    parBind->sizeNodes = bind->sizeNodes;
+		    bind->sizeNodes = 0;
+		    parBind->nbNodes = bind->nbNodes;
+		    bind->nbNodes = 0;
+		} else {
+		    /*
+		    * Copy the entries.
+		    */
+		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
+			xmlMalloc(bind->nbNodes *
+			sizeof(xmlSchemaPSVIIDCNodePtr));
+		    if (parBind->nodeTable == NULL) {
+			xmlSchemaVErrMemory(NULL,
+			    "allocating an array of IDC node-table "
+			    "items", NULL);
+			xmlSchemaIDCFreeBinding(parBind);
+			goto internal_error;
+		    }
+		    parBind->sizeNodes = bind->nbNodes;
+		    parBind->nbNodes = bind->nbNodes;
+		    memcpy(parBind->nodeTable, bind->nodeTable,
+			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
+		}
+	    }
+	    if (bind->dupls) {
+		/*
+		* Move the duplicates.
+		*/
+		if (parBind->dupls != NULL)
+		    xmlSchemaItemListFree(parBind->dupls);
+		parBind->dupls = bind->dupls;
+		bind->dupls = NULL;
+	    }
+            if (parTable != NULL) {
+                if (*parTable == NULL)
+                    *parTable = parBind;
+                else {
+                    parBind->next = *parTable;
+                    *parTable = parBind;
+                }
+            }
+	}
+
+next_binding:
+	bind = bind->next;
+    }
+    return (0);
+
+internal_error:
+    return(-1);
+}
+
+/**
+ * xmlSchemaCheckCVCIDCKeyRef:
+ * @vctxt: the WXS validation context
+ * @elemDecl: the element declaration
+ *
+ * Check the cvc-idc-keyref constraints.
+ */
+static int
+xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaIDCMatcherPtr matcher;
+    xmlSchemaPSVIIDCBindingPtr bind;
+
+    matcher = vctxt->inode->idcMatchers;
+    /*
+    * Find a keyref.
+    */
+    while (matcher != NULL) {
+	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
+	    matcher->targets &&
+	    matcher->targets->nbItems)
+	{
+	    int i, j, k, res, nbFields, hasDupls;
+	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
+	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
+
+	    nbFields = matcher->aidc->def->nbFields;
+
+	    /*
+	    * Find the IDC node-table for the referenced IDC key/unique.
+	    */
+	    bind = vctxt->inode->idcTable;
+	    while (bind != NULL) {
+		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
+		    bind->definition)
+		    break;
+		bind = bind->next;
+	    }
+	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
+	    /*
+	    * Search for a matching key-sequences.
+	    */
+	    for (i = 0; i < matcher->targets->nbItems; i++) {
+		res = 0;
+		refNode = matcher->targets->items[i];
+		if (bind != NULL) {
+		    refKeys = refNode->keys;
+		    for (j = 0; j < bind->nbNodes; j++) {
+			keys = bind->nodeTable[j]->keys;
+			for (k = 0; k < nbFields; k++) {
+			    res = xmlSchemaAreValuesEqual(keys[k]->val,
+				refKeys[k]->val);
+			    if (res == 0)
+				break;
+			    else if (res == -1) {
+				return (-1);
+			    }
+			}
+			if (res == 1) {
+			    /*
+			    * Match found.
+			    */
+			    break;
+			}
+		    }
+		    if ((res == 0) && hasDupls) {
+			/*
+			* Search in duplicates
+			*/
+			for (j = 0; j < bind->dupls->nbItems; j++) {
+			    keys = ((xmlSchemaPSVIIDCNodePtr)
+				bind->dupls->items[j])->keys;
+			    for (k = 0; k < nbFields; k++) {
+				res = xmlSchemaAreValuesEqual(keys[k]->val,
+				    refKeys[k]->val);
+				if (res == 0)
+				    break;
+				else if (res == -1) {
+				    return (-1);
+				}
+			    }
+			    if (res == 1) {
+				/*
+				* Match in duplicates found.
+				*/
+				xmlChar *str = NULL, *strB = NULL;
+				xmlSchemaKeyrefErr(vctxt,
+				    XML_SCHEMAV_CVC_IDC, refNode,
+				    (xmlSchemaTypePtr) matcher->aidc->def,
+				    "More than one match found for "
+				    "key-sequence %s of keyref '%s'",
+				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
+					refNode->keys, nbFields),
+				    xmlSchemaGetComponentQName(&strB,
+					matcher->aidc->def));
+				FREE_AND_NULL(str);
+				FREE_AND_NULL(strB);
+				break;
+			    }
+			}
+		    }
+		}
+
+		if (res == 0) {
+		    xmlChar *str = NULL, *strB = NULL;
+		    xmlSchemaKeyrefErr(vctxt,
+			XML_SCHEMAV_CVC_IDC, refNode,
+			(xmlSchemaTypePtr) matcher->aidc->def,
+			"No match found for key-sequence %s of keyref '%s'",
+			xmlSchemaFormatIDCKeySequence(vctxt, &str,
+			    refNode->keys, nbFields),
+			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
+		    FREE_AND_NULL(str);
+		    FREE_AND_NULL(strB);
+		}
+	    }
+	}
+	matcher = matcher->next;
+    }
+    /* TODO: Return an error if any error encountered. */
+    return (0);
+}
+
+/************************************************************************
+ * 									*
+ * 			XML Reader validation code                      *
+ * 									*
+ ************************************************************************/
+
+static xmlSchemaAttrInfoPtr
+xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaAttrInfoPtr iattr;
+    /*
+    * Grow/create list of attribute infos.
+    */
+    if (vctxt->attrInfos == NULL) {
+	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
+	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
+	vctxt->sizeAttrInfos = 1;
+	if (vctxt->attrInfos == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"allocating attribute info list", NULL);
+	    return (NULL);
+	}
+    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
+	vctxt->sizeAttrInfos++;
+	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
+	    xmlRealloc(vctxt->attrInfos,
+		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
+	if (vctxt->attrInfos == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"re-allocating attribute info list", NULL);
+	    return (NULL);
+	}
+    } else {
+	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
+	if (iattr->localName != NULL) {
+	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
+		"attr info not cleared");
+	    return (NULL);
+	}
+	iattr->nodeType = XML_ATTRIBUTE_NODE;
+	return (iattr);
+    }
+    /*
+    * Create an attribute info.
+    */
+    iattr = (xmlSchemaAttrInfoPtr)
+	xmlMalloc(sizeof(xmlSchemaAttrInfo));
+    if (iattr == NULL) {
+	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
+	return (NULL);
+    }
+    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
+    iattr->nodeType = XML_ATTRIBUTE_NODE;
+    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
+
+    return (iattr);
+}
+
+static int
+xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
+			xmlNodePtr attrNode,
+			int nodeLine,
+			const xmlChar *localName,
+			const xmlChar *nsName,
+			int ownedNames,
+			xmlChar *value,
+			int ownedValue)
+{
+    xmlSchemaAttrInfoPtr attr;
+
+    attr = xmlSchemaGetFreshAttrInfo(vctxt);
+    if (attr == NULL) {
+	VERROR_INT("xmlSchemaPushAttribute",
+	    "calling xmlSchemaGetFreshAttrInfo()");
+	return (-1);
+    }
+    attr->node = attrNode;
+    attr->nodeLine = nodeLine;
+    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
+    attr->localName = localName;
+    attr->nsName = nsName;
+    if (ownedNames)
+	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
+    /*
+    * Evaluate if it's an XSI attribute.
+    */
+    if (nsName != NULL) {
+	if (xmlStrEqual(localName, BAD_CAST "nil")) {
+	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
+		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
+	    }
+	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
+	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
+		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
+	    }
+	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
+	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
+		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
+	    }
+	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
+	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
+		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
+	    }
+	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
+	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
+	}
+    }
+    attr->value = value;
+    if (ownedValue)
+	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
+    if (attr->metaType != 0)
+	attr->state = XML_SCHEMAS_ATTR_META;
+    return (0);
+}
+
+/**
+ * xmlSchemaClearElemInfo:
+ * @vctxt: the WXS validation context
+ * @ielem: the element information item
+ */
+static void
+xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
+		       xmlSchemaNodeInfoPtr ielem)
+{
+    ielem->hasKeyrefs = 0;
+    ielem->appliedXPath = 0;
+    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
+	FREE_AND_NULL(ielem->localName);
+	FREE_AND_NULL(ielem->nsName);
+    } else {
+	ielem->localName = NULL;
+	ielem->nsName = NULL;
+    }
+    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
+	FREE_AND_NULL(ielem->value);
+    } else {
+	ielem->value = NULL;
+    }
+    if (ielem->val != NULL) {
+	/*
+	* PSVI TODO: Be careful not to free it when the value is
+	* exposed via PSVI.
+	*/
+	xmlSchemaFreeValue(ielem->val);
+	ielem->val = NULL;
+    }
+    if (ielem->idcMatchers != NULL) {
+	/*
+	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
+	*   Does it work?
+	*/
+	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
+#if 0
+	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
+#endif
+	ielem->idcMatchers = NULL;
+    }
+    if (ielem->idcTable != NULL) {
+	/*
+	* OPTIMIZE TODO: Use a pool of IDC tables??.
+	*/
+	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
+	ielem->idcTable = NULL;
+    }
+    if (ielem->regexCtxt != NULL) {
+	xmlRegFreeExecCtxt(ielem->regexCtxt);
+	ielem->regexCtxt = NULL;
+    }
+    if (ielem->nsBindings != NULL) {
+	xmlFree((xmlChar **)ielem->nsBindings);
+	ielem->nsBindings = NULL;
+	ielem->nbNsBindings = 0;
+	ielem->sizeNsBindings = 0;
+    }
+}
+
+/**
+ * xmlSchemaGetFreshElemInfo:
+ * @vctxt: the schema validation context
+ *
+ * Creates/reuses and initializes the element info item for
+ * the currect tree depth.
+ *
+ * Returns the element info item or NULL on API or internal errors.
+ */
+static xmlSchemaNodeInfoPtr
+xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaNodeInfoPtr info = NULL;
+
+    if (vctxt->depth > vctxt->sizeElemInfos) {
+	VERROR_INT("xmlSchemaGetFreshElemInfo",
+	    "inconsistent depth encountered");
+	return (NULL);
+    }
+    if (vctxt->elemInfos == NULL) {
+	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
+	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
+	if (vctxt->elemInfos == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"allocating the element info array", NULL);
+	    return (NULL);
+	}
+	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
+	vctxt->sizeElemInfos = 10;
+    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
+	int i = vctxt->sizeElemInfos;
+
+	vctxt->sizeElemInfos *= 2;
+	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
+	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
+	    sizeof(xmlSchemaNodeInfoPtr));
+	if (vctxt->elemInfos == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"re-allocating the element info array", NULL);
+	    return (NULL);
+	}
+	/*
+	* We need the new memory to be NULLed.
+	* TODO: Use memset instead?
+	*/
+	for (; i < vctxt->sizeElemInfos; i++)
+	    vctxt->elemInfos[i] = NULL;
+    } else
+	info = vctxt->elemInfos[vctxt->depth];
+
+    if (info == NULL) {
+	info = (xmlSchemaNodeInfoPtr)
+	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
+	if (info == NULL) {
+	    xmlSchemaVErrMemory(vctxt,
+		"allocating an element info", NULL);
+	    return (NULL);
+	}
+	vctxt->elemInfos[vctxt->depth] = info;
+    } else {
+	if (info->localName != NULL) {
+	    VERROR_INT("xmlSchemaGetFreshElemInfo",
+		"elem info has not been cleared");
+	    return (NULL);
+	}
+    }
+    memset(info, 0, sizeof(xmlSchemaNodeInfo));
+    info->nodeType = XML_ELEMENT_NODE;
+    info->depth = vctxt->depth;
+
+    return (info);
+}
+
+#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
+#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
+#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
+
+static int
+xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
+			xmlNodePtr node,
+			xmlSchemaTypePtr type,
+			xmlSchemaValType valType,
+			const xmlChar * value,
+			xmlSchemaValPtr val,
+			unsigned long length,
+			int fireErrors)
+{
+    int ret, error = 0;
+
+    xmlSchemaTypePtr tmpType;
+    xmlSchemaFacetLinkPtr facetLink;
+    xmlSchemaFacetPtr facet;
+    unsigned long len = 0;
+    xmlSchemaWhitespaceValueType ws;
+
+    /*
+    * In Libxml2, derived built-in types have currently no explicit facets.
+    */
+    if (type->type == XML_SCHEMA_TYPE_BASIC)
+	return (0);
+
+    /*
+    * NOTE: Do not jump away, if the facetSet of the given type is
+    * empty: until now, "pattern" and "enumeration" facets of the
+    * *base types* need to be checked as well.
+    */
+    if (type->facetSet == NULL)
+	goto pattern_and_enum;
+
+    if (! WXS_IS_ATOMIC(type)) {
+	if (WXS_IS_LIST(type))
+	    goto WXS_IS_LIST;
+	else
+	    goto pattern_and_enum;
+    }
+    /*
+    * Whitespace handling is only of importance for string-based
+    * types.
+    */
+    tmpType = xmlSchemaGetPrimitiveType(type);
+    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
+	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
+	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
+    } else
+	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+    /*
+    * If the value was not computed (for string or
+    * anySimpleType based types), then use the provided
+    * type.
+    */
+    if (val == NULL)
+	valType = valType;
+    else
+	valType = xmlSchemaGetValType(val);
+
+    ret = 0;
+    for (facetLink = type->facetSet; facetLink != NULL;
+	facetLink = facetLink->next) {
+	/*
+	* Skip the pattern "whiteSpace": it is used to
+	* format the character content beforehand.
+	*/
+	switch (facetLink->facet->type) {
+	    case XML_SCHEMA_FACET_WHITESPACE:
+	    case XML_SCHEMA_FACET_PATTERN:
+	    case XML_SCHEMA_FACET_ENUMERATION:
+		continue;
+	    case XML_SCHEMA_FACET_LENGTH:
+	    case XML_SCHEMA_FACET_MINLENGTH:
+	    case XML_SCHEMA_FACET_MAXLENGTH:
+		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
+		    valType, value, val, &len, ws);
+		break;
+	    default:
+		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
+		    valType, value, val, ws);
+		break;
+	}
+	if (ret < 0) {
+	    AERROR_INT("xmlSchemaValidateFacets",
+		"validating against a atomic type facet");
+	    return (-1);
+	} else if (ret > 0) {
+	    if (fireErrors)
+		xmlSchemaFacetErr(actxt, ret, node,
+		value, len, type, facetLink->facet, NULL, NULL, NULL);
+	    else
+		return (ret);
+	    if (error == 0)
+		error = ret;
+	}
+	ret = 0;
+    }
+
+WXS_IS_LIST:
+    if (! WXS_IS_LIST(type))
+	goto pattern_and_enum;
+    /*
+    * "length", "minLength" and "maxLength" of list types.
+    */
+    ret = 0;
+    for (facetLink = type->facetSet; facetLink != NULL;
+	facetLink = facetLink->next) {
+
+	switch (facetLink->facet->type) {
+	    case XML_SCHEMA_FACET_LENGTH:
+	    case XML_SCHEMA_FACET_MINLENGTH:
+	    case XML_SCHEMA_FACET_MAXLENGTH:
+		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
+		    value, length, NULL);
+		break;
+	    default:
+		continue;
+	}
+	if (ret < 0) {
+	    AERROR_INT("xmlSchemaValidateFacets",
+		"validating against a list type facet");
+	    return (-1);
+	} else if (ret > 0) {
+	    if (fireErrors)
+		xmlSchemaFacetErr(actxt, ret, node,
+		value, length, type, facetLink->facet, NULL, NULL, NULL);
+	    else
+		return (ret);
+	    if (error == 0)
+		error = ret;
+	}
+	ret = 0;
+    }
+
+pattern_and_enum:
+    if (error >= 0) {
+	int found = 0;
+	/*
+	* Process enumerations. Facet values are in the value space
+	* of the defining type's base type. This seems to be a bug in the
+	* XML Schema 1.0 spec. Use the whitespace type of the base type.
+	* Only the first set of enumerations in the ancestor-or-self axis
+	* is used for validation.
+	*/
+	ret = 0;
+	tmpType = type;
+	do {
+	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
+		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
+		    continue;
+		found = 1;
+		ret = xmlSchemaAreValuesEqual(facet->val, val);
+		if (ret == 1)
+		    break;
+		else if (ret < 0) {
+		    AERROR_INT("xmlSchemaValidateFacets",
+			"validating against an enumeration facet");
+		    return (-1);
+		}
+	    }
+	    if (ret != 0)
+		break;
+	    /*
+	    * Break on the first set of enumerations. Any additional
+	    *  enumerations which might be existent on the ancestors
+	    *  of the current type are restricted by this set; thus
+	    *  *must* *not* be taken into account.
+	    */
+	    if (found)
+		break;
+	    tmpType = tmpType->baseType;
+	} while ((tmpType != NULL) &&
+	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
+	if (found && (ret == 0)) {
+	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
+	    if (fireErrors) {
+		xmlSchemaFacetErr(actxt, ret, node,
+		    value, 0, type, NULL, NULL, NULL, NULL);
+	    } else
+		return (ret);
+	    if (error == 0)
+		error = ret;
+	}
+    }
+
+    if (error >= 0) {
+	int found;
+	/*
+	* Process patters. Pattern facets are ORed at type level
+	* and ANDed if derived. Walk the base type axis.
+	*/
+	tmpType = type;
+	facet = NULL;
+	do {
+	    found = 0;
+	    for (facetLink = tmpType->facetSet; facetLink != NULL;
+		facetLink = facetLink->next) {
+		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
+		    continue;
+		found = 1;
+		/*
+		* NOTE that for patterns, @value needs to be the
+		* normalized vaule.
+		*/
+		ret = xmlRegexpExec(facetLink->facet->regexp, value);
+		if (ret == 1)
+		    break;
+		else if (ret < 0) {
+		    AERROR_INT("xmlSchemaValidateFacets",
+			"validating against a pattern facet");
+		    return (-1);
+		} else {
+		    /*
+		    * Save the last non-validating facet.
+		    */
+		    facet = facetLink->facet;
+		}
+	    }
+	    if (found && (ret != 1)) {
+		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
+		if (fireErrors) {
+		    xmlSchemaFacetErr(actxt, ret, node,
+			value, 0, type, facet, NULL, NULL, NULL);
+		} else
+		    return (ret);
+		if (error == 0)
+		    error = ret;
+		break;
+	    }
+	    tmpType = tmpType->baseType;
+	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
+    }
+
+    return (error);
+}
+
+static xmlChar *
+xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
+			const xmlChar *value)
+{
+    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
+	case XML_SCHEMA_WHITESPACE_COLLAPSE:
+	    return (xmlSchemaCollapseString(value));
+	case XML_SCHEMA_WHITESPACE_REPLACE:
+	    return (xmlSchemaWhiteSpaceReplace(value));
+	default:
+	    return (NULL);
+    }
+}
+
+static int
+xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
+		       const xmlChar *value,
+		       xmlSchemaValPtr *val,
+		       int valNeeded)
+{
+    int ret;
+    const xmlChar *nsName;
+    xmlChar *local, *prefix = NULL;
+
+    ret = xmlValidateQName(value, 1);
+    if (ret != 0) {
+	if (ret == -1) {
+	    VERROR_INT("xmlSchemaValidateQName",
+		"calling xmlValidateQName()");
+	    return (-1);
+	}
+	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
+    }
+    /*
+    * NOTE: xmlSplitQName2 will always return a duplicated
+    * strings.
+    */
+    local = xmlSplitQName2(value, &prefix);
+    if (local == NULL)
+	local = xmlStrdup(value);
+    /*
+    * OPTIMIZE TODO: Use flags for:
+    *  - is there any namespace binding?
+    *  - is there a default namespace?
+    */
+    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
+
+    if (prefix != NULL) {
+	xmlFree(prefix);
+	/*
+	* A namespace must be found if the prefix is
+	* NOT NULL.
+	*/
+	if (nsName == NULL) {
+	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
+	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
+		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
+		"The QName value '%s' has no "
+		"corresponding namespace declaration in "
+		"scope", value, NULL);
+	    if (local != NULL)
+		xmlFree(local);
+	    return (ret);
+	}
+    }
+    if (valNeeded && val) {
+	if (nsName != NULL)
+	    *val = xmlSchemaNewQNameValue(
+		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
+	else
+	    *val = xmlSchemaNewQNameValue(NULL,
+		BAD_CAST local);
+    } else
+	xmlFree(local);
+    return (0);
+}
+
+/*
+* cvc-simple-type
+*/
+static int
+xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
+			     xmlNodePtr node,
+			     xmlSchemaTypePtr type,
+			     const xmlChar *value,
+			     xmlSchemaValPtr *retVal,
+			     int fireErrors,
+			     int normalize,
+			     int isNormalized)
+{
+    int ret = 0, valNeeded = (retVal) ? 1 : 0;
+    xmlSchemaValPtr val = NULL;
+    /* xmlSchemaWhitespaceValueType ws; */
+    xmlChar *normValue = NULL;
+
+#define NORMALIZE(atype) \
+    if ((! isNormalized) && \
+    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
+	normValue = xmlSchemaNormalizeValue(atype, value); \
+	if (normValue != NULL) \
+	    value = normValue; \
+	isNormalized = 1; \
+    }
+
+    if ((retVal != NULL) && (*retVal != NULL)) {
+	xmlSchemaFreeValue(*retVal);
+	*retVal = NULL;
+    }
+    /*
+    * 3.14.4 Simple Type Definition Validation Rules
+    * Validation Rule: String Valid
+    */
+    /*
+    * 1 It is schema-valid with respect to that definition as defined
+    * by Datatype Valid in [XML Schemas: Datatypes].
+    */
+    /*
+    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
+    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
+    * the string must be a �declared entity name�.
+    */
+    /*
+    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
+    * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
+    * then every whitespace-delimited substring of the string must be a �declared
+    * entity name�.
+    */
+    /*
+    * 2.3 otherwise no further condition applies.
+    */
+    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
+	valNeeded = 1;
+    if (value == NULL)
+	value = BAD_CAST "";
+    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
+	xmlSchemaTypePtr biType; /* The built-in type. */
+	/*
+	* SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
+	* a literal in the �lexical space� of {base type definition}"
+	*/
+	/*
+	* Whitespace-normalize.
+	*/
+	NORMALIZE(type);
+	if (type->type != XML_SCHEMA_TYPE_BASIC) {
+	    /*
+	    * Get the built-in type.
+	    */
+	    biType = type->baseType;
+	    while ((biType != NULL) &&
+		(biType->type != XML_SCHEMA_TYPE_BASIC))
+		biType = biType->baseType;
+
+	    if (biType == NULL) {
+		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+		    "could not get the built-in type");
+		goto internal_error;
+	    }
+	} else
+	    biType = type;
+	/*
+	* NOTATIONs need to be processed here, since they need
+	* to lookup in the hashtable of NOTATION declarations of the schema.
+	*/
+	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
+	    switch (biType->builtInType) {
+		case XML_SCHEMAS_NOTATION:
+		    ret = xmlSchemaValidateNotation(
+			(xmlSchemaValidCtxtPtr) actxt,
+			((xmlSchemaValidCtxtPtr) actxt)->schema,
+			NULL, value, &val, valNeeded);
+		    break;
+		case XML_SCHEMAS_QNAME:
+		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
+			value, &val, valNeeded);
+		    break;
+		default:
+		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
+		    if (valNeeded)
+			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
+			    value, &val, node);
+		    else
+			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
+			    value, NULL, node);
+		    break;
+	    }
+	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
+	    switch (biType->builtInType) {
+		case XML_SCHEMAS_NOTATION:
+		    ret = xmlSchemaValidateNotation(NULL,
+			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
+			value, &val, valNeeded);
+		    break;
+		default:
+		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
+		    if (valNeeded)
+			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
+			    value, &val, node);
+		    else
+			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
+			    value, NULL, node);
+		    break;
+	    }
+	} else {
+	    /*
+	    * Validation via a public API is not implemented yet.
+	    */
+	    TODO
+	    goto internal_error;
+	}
+	if (ret != 0) {
+	    if (ret < 0) {
+		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+		    "validating against a built-in type");
+		goto internal_error;
+	    }
+	    if (WXS_IS_LIST(type))
+		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
+	    else
+		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
+	}
+	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
+	    /*
+	    * Check facets.
+	    */
+	    ret = xmlSchemaValidateFacets(actxt, node, type,
+		(xmlSchemaValType) biType->builtInType, value, val,
+		0, fireErrors);
+	    if (ret != 0) {
+		if (ret < 0) {
+		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+			"validating facets of atomic simple type");
+		    goto internal_error;
+		}
+		if (WXS_IS_LIST(type))
+		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
+		else
+		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
+	    }
+	}
+	if (fireErrors && (ret > 0))
+	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
+    } else if (WXS_IS_LIST(type)) {
+
+	xmlSchemaTypePtr itemType;
+	const xmlChar *cur, *end;
+	xmlChar *tmpValue = NULL;
+	unsigned long len = 0;
+	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
+	/* 1.2.2 if {variety} is �list� then the string must be a sequence
+	* of white space separated tokens, each of which �match�es a literal
+	* in the �lexical space� of {item type definition}
+	*/
+	/*
+	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
+	* the list type has an enum or pattern facet.
+	*/
+	NORMALIZE(type);
+	/*
+	* VAL TODO: Optimize validation of empty values.
+	* VAL TODO: We do not have computed values for lists.
+	*/
+	itemType = WXS_LIST_ITEMTYPE(type);
+	cur = value;
+	do {
+	    while (IS_BLANK_CH(*cur))
+		cur++;
+	    end = cur;
+	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+		end++;
+	    if (end == cur)
+		break;
+	    tmpValue = xmlStrndup(cur, end - cur);
+	    len++;
+
+	    if (valNeeded)
+		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
+		    tmpValue, &curVal, fireErrors, 0, 1);
+	    else
+		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
+		    tmpValue, NULL, fireErrors, 0, 1);
+	    FREE_AND_NULL(tmpValue);
+	    if (curVal != NULL) {
+		/*
+		* Add to list of computed values.
+		*/
+		if (val == NULL)
+		    val = curVal;
+		else
+		    xmlSchemaValueAppend(prevVal, curVal);
+		prevVal = curVal;
+		curVal = NULL;
+	    }
+	    if (ret != 0) {
+		if (ret < 0) {
+		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+			"validating an item of list simple type");
+		    goto internal_error;
+		}
+		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
+		break;
+	    }
+	    cur = end;
+	} while (*cur != 0);
+	FREE_AND_NULL(tmpValue);
+	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
+	    /*
+	    * Apply facets (pattern, enumeration).
+	    */
+	    ret = xmlSchemaValidateFacets(actxt, node, type,
+		XML_SCHEMAS_UNKNOWN, value, val,
+		len, fireErrors);
+	    if (ret != 0) {
+		if (ret < 0) {
+		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+			"validating facets of list simple type");
+		    goto internal_error;
+		}
+		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
+	    }
+	}
+	if (fireErrors && (ret > 0)) {
+	    /*
+	    * Report the normalized value.
+	    */
+	    normalize = 1;
+	    NORMALIZE(type);
+	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
+	}
+    } else if (WXS_IS_UNION(type)) {
+	xmlSchemaTypeLinkPtr memberLink;
+	/*
+	* TODO: For all datatypes �derived� by �union�  whiteSpace does
+	* not apply directly; however, the normalization behavior of �union�
+	* types is controlled by the value of whiteSpace on that one of the
+	* �memberTypes� against which the �union� is successfully validated.
+	*
+	* This means that the value is normalized by the first validating
+	* member type, then the facets of the union type are applied. This
+	* needs changing of the value!
+	*/
+
+	/*
+	* 1.2.3 if {variety} is �union� then the string must �match� a
+	* literal in the �lexical space� of at least one member of
+	* {member type definitions}
+	*/
+	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
+	if (memberLink == NULL) {
+	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+		"union simple type has no member types");
+	    goto internal_error;
+	}
+	/*
+	* Always normalize union type values, since we currently
+	* cannot store the whitespace information with the value
+	* itself; otherwise a later value-comparison would be
+	* not possible.
+	*/
+	while (memberLink != NULL) {
+	    if (valNeeded)
+		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
+		    memberLink->type, value, &val, 0, 1, 0);
+	    else
+		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
+		    memberLink->type, value, NULL, 0, 1, 0);
+	    if (ret <= 0)
+		break;
+	    memberLink = memberLink->next;
+	}
+	if (ret != 0) {
+	    if (ret < 0) {
+		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+		    "validating members of union simple type");
+		goto internal_error;
+	    }
+	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
+	}
+	/*
+	* Apply facets (pattern, enumeration).
+	*/
+	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
+	    /*
+	    * The normalization behavior of �union� types is controlled by
+	    * the value of whiteSpace on that one of the �memberTypes�
+	    * against which the �union� is successfully validated.
+	    */
+	    NORMALIZE(memberLink->type);
+	    ret = xmlSchemaValidateFacets(actxt, node, type,
+		XML_SCHEMAS_UNKNOWN, value, val,
+		0, fireErrors);
+	    if (ret != 0) {
+		if (ret < 0) {
+		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
+			"validating facets of union simple type");
+		    goto internal_error;
+		}
+		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
+	    }
+	}
+	if (fireErrors && (ret > 0))
+	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
+    }
+
+    if (normValue != NULL)
+	xmlFree(normValue);
+    if (ret == 0) {
+	if (retVal != NULL)
+	    *retVal = val;
+	else if (val != NULL)
+	    xmlSchemaFreeValue(val);
+    } else if (val != NULL)
+	xmlSchemaFreeValue(val);
+    return (ret);
+internal_error:
+    if (normValue != NULL)
+	xmlFree(normValue);
+    if (val != NULL)
+	xmlSchemaFreeValue(val);
+    return (-1);
+}
+
+static int
+xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
+			   const xmlChar *value,
+			   const xmlChar **nsName,
+			   const xmlChar **localName)
+{
+    int ret = 0;
+
+    if ((nsName == NULL) || (localName == NULL))
+	return (-1);
+    *nsName = NULL;
+    *localName = NULL;
+
+    ret = xmlValidateQName(value, 1);
+    if (ret == -1)
+	return (-1);
+    if (ret > 0) {
+	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
+	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
+	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
+	return (1);
+    }
+    {
+	xmlChar *local = NULL;
+	xmlChar *prefix;
+
+	/*
+	* NOTE: xmlSplitQName2 will return a duplicated
+	* string.
+	*/
+	local = xmlSplitQName2(value, &prefix);
+	if (local == NULL)
+	    *localName = xmlDictLookup(vctxt->dict, value, -1);
+	else {
+	    *localName = xmlDictLookup(vctxt->dict, local, -1);
+	    xmlFree(local);
+	}
+
+	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
+
+	if (prefix != NULL) {
+	    xmlFree(prefix);
+	    /*
+	    * A namespace must be found if the prefix is NOT NULL.
+	    */
+	    if (*nsName == NULL) {
+		xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
+		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
+		    "The QName value '%s' has no "
+		    "corresponding namespace declaration in scope",
+		    value, NULL);
+		return (2);
+	    }
+	}
+    }
+    return (0);
+}
+
+static int
+xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
+			xmlSchemaAttrInfoPtr iattr,
+			xmlSchemaTypePtr *localType,
+			xmlSchemaElementPtr elemDecl)
+{
+    int ret = 0;
+    /*
+    * cvc-elt (3.3.4) : (4)
+    * AND
+    * Schema-Validity Assessment (Element) (cvc-assess-elt)
+    *   (1.2.1.2.1) - (1.2.1.2.4)
+    * Handle 'xsi:type'.
+    */
+    if (localType == NULL)
+	return (-1);
+    *localType = NULL;
+    if (iattr == NULL)
+	return (0);
+    else {
+	const xmlChar *nsName = NULL, *local = NULL;
+	/*
+	* TODO: We should report a *warning* that the type was overriden
+	* by the instance.
+	*/
+	ACTIVATE_ATTRIBUTE(iattr);
+	/*
+	* (cvc-elt) (3.3.4) : (4.1)
+	* (cvc-assess-elt) (1.2.1.2.2)
+	*/
+	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
+	    &nsName, &local);
+	if (ret != 0) {
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidateElementByDeclaration",
+		    "calling xmlSchemaQNameExpand() to validate the "
+		    "attribute 'xsi:type'");
+		goto internal_error;
+	    }
+	    goto exit;
+	}
+	/*
+	* (cvc-elt) (3.3.4) : (4.2)
+	* (cvc-assess-elt) (1.2.1.2.3)
+	*/
+	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
+	if (*localType == NULL) {
+	    xmlChar *str = NULL;
+
+	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		XML_SCHEMAV_CVC_ELT_4_2, NULL,
+		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
+		"The QName value '%s' of the xsi:type attribute does not "
+		"resolve to a type definition",
+		xmlSchemaFormatQName(&str, nsName, local), NULL);
+	    FREE_AND_NULL(str);
+	    ret = vctxt->err;
+	    goto exit;
+	}
+	if (elemDecl != NULL) {
+	    int set = 0;
+
+	    /*
+	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
+	    * "The �local type definition� must be validly
+	    * derived from the {type definition} given the union of
+	    * the {disallowed substitutions} and the {type definition}'s
+	    * {prohibited substitutions}, as defined in
+	    * Type Derivation OK (Complex) (�3.4.6)
+	    * (if it is a complex type definition),
+	    * or given {disallowed substitutions} as defined in Type
+	    * Derivation OK (Simple) (�3.14.6) (if it is a simple type
+	    * definition)."
+	    *
+	    * {disallowed substitutions}: the "block" on the element decl.
+	    * {prohibited substitutions}: the "block" on the type def.
+	    */
+	    /*
+	    * OPTIMIZE TODO: We could map types already evaluated
+	    * to be validly derived from other types to avoid checking
+	    * this over and over for the same types.
+	    */
+	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
+		(elemDecl->subtypes->flags &
+		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
+		set |= SUBSET_EXTENSION;
+
+	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
+		(elemDecl->subtypes->flags &
+		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
+		set |= SUBSET_RESTRICTION;
+
+	    /*
+	    * REMOVED and CHANGED since this produced a parser context
+	    * which adds to the string dict of the schema. So this would
+	    * change the schema and we don't want this. We don't need
+	    * the parser context anymore.
+	    *
+	    * if ((vctxt->pctxt == NULL) &&
+	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
+	    *	    return (-1);
+	    */
+
+	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
+		elemDecl->subtypes, set) != 0) {
+		xmlChar *str = NULL;
+
+		xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
+		    "The type definition '%s', specified by xsi:type, is "
+		    "blocked or not validly derived from the type definition "
+		    "of the element declaration",
+		    xmlSchemaFormatQName(&str,
+			(*localType)->targetNamespace,
+			(*localType)->name),
+		    NULL);
+		FREE_AND_NULL(str);
+		ret = vctxt->err;
+		*localType = NULL;
+	    }
+	}
+    }
+exit:
+    ACTIVATE_ELEM;
+    return (ret);
+internal_error:
+    ACTIVATE_ELEM;
+    return (-1);
+}
+
+static int
+xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
+    xmlSchemaTypePtr actualType;
+
+    /*
+    * cvc-elt (3.3.4) : 1
+    */
+    if (elemDecl == NULL) {
+	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
+	    "No matching declaration available");
+        return (vctxt->err);
+    }
+    actualType = WXS_ELEM_TYPEDEF(elemDecl);
+    /*
+    * cvc-elt (3.3.4) : 2
+    */
+    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
+	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
+	    "The element declaration is abstract");
+        return (vctxt->err);
+    }
+    if (actualType == NULL) {
+    	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
+    	    "The type definition is absent");
+    	return (XML_SCHEMAV_CVC_TYPE_1);
+    }
+    if (vctxt->nbAttrInfos != 0) {
+	int ret;
+	xmlSchemaAttrInfoPtr iattr;
+	/*
+	* cvc-elt (3.3.4) : 3
+	* Handle 'xsi:nil'.
+	*/
+	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
+	if (iattr) {
+	    ACTIVATE_ATTRIBUTE(iattr);
+	    /*
+	    * Validate the value.
+	    */
+	    ret = xmlSchemaVCheckCVCSimpleType(
+		ACTXT_CAST vctxt, NULL,
+		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
+		iattr->value, &(iattr->val), 1, 0, 0);
+	    ACTIVATE_ELEM;
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidateElemDecl",
+		    "calling xmlSchemaVCheckCVCSimpleType() to "
+		    "validate the attribute 'xsi:nil'");
+		return (-1);
+	    }
+	    if (ret == 0) {
+		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
+		    /*
+		    * cvc-elt (3.3.4) : 3.1
+		    */
+		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
+			"The element is not 'nillable'");
+		    /* Does not return an error on purpose. */
+		} else {
+		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
+			/*
+			* cvc-elt (3.3.4) : 3.2.2
+			*/
+			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
+			    (elemDecl->value != NULL)) {
+			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
+				"The element cannot be 'nilled' because "
+				"there is a fixed value constraint defined "
+				"for it");
+			     /* Does not return an error on purpose. */
+			} else
+			    vctxt->inode->flags |=
+				XML_SCHEMA_ELEM_INFO_NILLED;
+		    }
+		}
+	    }
+	}
+	/*
+	* cvc-elt (3.3.4) : 4
+	* Handle 'xsi:type'.
+	*/
+	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
+	if (iattr) {
+	    xmlSchemaTypePtr localType = NULL;
+
+	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
+		elemDecl);
+	    if (ret != 0) {
+		if (ret == -1) {
+		    VERROR_INT("xmlSchemaValidateElemDecl",
+			"calling xmlSchemaProcessXSIType() to "
+			"process the attribute 'xsi:type'");
+		    return (-1);
+		}
+		/* Does not return an error on purpose. */
+	    }
+	    if (localType != NULL) {
+		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
+		actualType = localType;
+	    }
+	}
+    }
+    /*
+    * IDC: Register identity-constraint XPath matchers.
+    */
+    if ((elemDecl->idcs != NULL) &&
+	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
+	    return (-1);
+    /*
+    * No actual type definition.
+    */
+    if (actualType == NULL) {
+    	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
+    	    "The type definition is absent");
+    	return (XML_SCHEMAV_CVC_TYPE_1);
+    }
+    /*
+    * Remember the actual type definition.
+    */
+    vctxt->inode->typeDef = actualType;
+
+    return (0);
+}
+
+static int
+xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaAttrInfoPtr iattr;
+    int ret = 0, i;
+
+    /*
+    * SPEC cvc-type (3.1.1)
+    * "The attributes of must be empty, excepting those whose namespace
+    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
+    * whose local name is one of type, nil, schemaLocation or
+    * noNamespaceSchemaLocation."
+    */
+    if (vctxt->nbAttrInfos == 0)
+	return (0);
+    for (i = 0; i < vctxt->nbAttrInfos; i++) {
+	iattr = vctxt->attrInfos[i];
+	if (! iattr->metaType) {
+	    ACTIVATE_ATTRIBUTE(iattr)
+	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
+		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
+	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
+        }
+    }
+    ACTIVATE_ELEM
+    return (ret);
+}
+
+/*
+* Cleanup currently used attribute infos.
+*/
+static void
+xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
+{
+    int i;
+    xmlSchemaAttrInfoPtr attr;
+
+    if (vctxt->nbAttrInfos == 0)
+	return;
+    for (i = 0; i < vctxt->nbAttrInfos; i++) {
+	attr = vctxt->attrInfos[i];
+	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
+	    if (attr->localName != NULL)
+		xmlFree((xmlChar *) attr->localName);
+	    if (attr->nsName != NULL)
+		xmlFree((xmlChar *) attr->nsName);
+	}
+	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
+	    if (attr->value != NULL)
+		xmlFree((xmlChar *) attr->value);
+	}
+	if (attr->val != NULL) {
+	    xmlSchemaFreeValue(attr->val);
+	    attr->val = NULL;
+	}
+	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
+    }
+    vctxt->nbAttrInfos = 0;
+}
+
+/*
+* 3.4.4 Complex Type Definition Validation Rules
+*   Element Locally Valid (Complex Type) (cvc-complex-type)
+* 3.2.4 Attribute Declaration Validation Rules
+*   Validation Rule: Attribute Locally Valid (cvc-attribute)
+*   Attribute Locally Valid (Use) (cvc-au)
+*
+* Only "assessed" attribute information items will be visible to
+* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
+*/
+static int
+xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaTypePtr type = vctxt->inode->typeDef;
+    xmlSchemaItemListPtr attrUseList;
+    xmlSchemaAttributeUsePtr attrUse = NULL;
+    xmlSchemaAttributePtr attrDecl = NULL;
+    xmlSchemaAttrInfoPtr iattr, tmpiattr;
+    int i, j, found, nbAttrs, nbUses;
+    int xpathRes = 0, res, wildIDs = 0, fixed;
+    xmlNodePtr defAttrOwnerElem = NULL;
+
+    /*
+    * SPEC (cvc-attribute)
+    * (1) "The declaration must not be �absent� (see Missing
+    * Sub-components (�5.3) for how this can fail to be
+    * the case)."
+    * (2) "Its {type definition} must not be absent."
+    *
+    * NOTE (1) + (2): This is not handled here, since we currently do not
+    * allow validation against schemas which have missing sub-components.
+    *
+    * SPEC (cvc-complex-type)
+    * (3) "For each attribute information item in the element information
+    * item's [attributes] excepting those whose [namespace name] is
+    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
+    * [local name] is one of type, nil, schemaLocation or
+    * noNamespaceSchemaLocation, the appropriate case among the following
+    * must be true:
+    *
+    */
+    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
+    /*
+    * @nbAttrs is the number of attributes present in the instance.
+    */
+    nbAttrs = vctxt->nbAttrInfos;
+    if (attrUseList != NULL)
+	nbUses = attrUseList->nbItems;
+    else
+	nbUses = 0;
+    for (i = 0; i < nbUses; i++) {
+        found = 0;
+	attrUse = attrUseList->items[i];
+	attrDecl = WXS_ATTRUSE_DECL(attrUse);
+        for (j = 0; j < nbAttrs; j++) {
+	    iattr = vctxt->attrInfos[j];
+	    /*
+	    * SPEC (cvc-complex-type) (3)
+	    * Skip meta attributes.
+	    */
+	    if (iattr->metaType)
+		continue;
+	    if (iattr->localName[0] != attrDecl->name[0])
+		continue;
+	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
+		continue;
+	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
+		continue;
+	    found = 1;
+	    /*
+	    * SPEC (cvc-complex-type)
+	    * (3.1) "If there is among the {attribute uses} an attribute
+	    * use with an {attribute declaration} whose {name} matches
+	    * the attribute information item's [local name] and whose
+	    * {target namespace} is identical to the attribute information
+	    * item's [namespace name] (where an �absent� {target namespace}
+	    * is taken to be identical to a [namespace name] with no value),
+	    * then the attribute information must be �valid� with respect
+	    * to that attribute use as per Attribute Locally Valid (Use)
+	    * (�3.5.4). In this case the {attribute declaration} of that
+	    * attribute use is the �context-determined declaration� for the
+	    * attribute information item with respect to Schema-Validity
+	    * Assessment (Attribute) (�3.2.4) and
+	    * Assessment Outcome (Attribute) (�3.2.5).
+	    */
+	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
+	    iattr->use = attrUse;
+	    /*
+	    * Context-determined declaration.
+	    */
+	    iattr->decl = attrDecl;
+	    iattr->typeDef = attrDecl->subtypes;
+	    break;
+	}
+
+	if (found)
+	    continue;
+
+	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
+	    /*
+	    * Handle non-existent, required attributes.
+	    *
+	    * SPEC (cvc-complex-type)
+	    * (4) "The {attribute declaration} of each attribute use in
+	    * the {attribute uses} whose {required} is true matches one
+	    * of the attribute information items in the element information
+	    * item's [attributes] as per clause 3.1 above."
+	    */
+	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
+	    if (tmpiattr == NULL) {
+		VERROR_INT(
+		    "xmlSchemaVAttributesComplex",
+		    "calling xmlSchemaGetFreshAttrInfo()");
+		return (-1);
+	    }
+	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
+	    tmpiattr->use = attrUse;
+	    tmpiattr->decl = attrDecl;
+	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
+	    ((attrUse->defValue != NULL) ||
+	     (attrDecl->defValue != NULL))) {
+	    /*
+	    * Handle non-existent, optional, default/fixed attributes.
+	    */
+	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
+	    if (tmpiattr == NULL) {
+		VERROR_INT(
+		    "xmlSchemaVAttributesComplex",
+		    "calling xmlSchemaGetFreshAttrInfo()");
+		return (-1);
+	    }
+	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
+	    tmpiattr->use = attrUse;
+	    tmpiattr->decl = attrDecl;
+	    tmpiattr->typeDef = attrDecl->subtypes;
+	    tmpiattr->localName = attrDecl->name;
+	    tmpiattr->nsName = attrDecl->targetNamespace;
+	}
+    }
+
+    if (vctxt->nbAttrInfos == 0)
+	return (0);
+    /*
+    * Validate against the wildcard.
+    */
+    if (type->attributeWildcard != NULL) {
+	/*
+	* SPEC (cvc-complex-type)
+	* (3.2.1) "There must be an {attribute wildcard}."
+	*/
+	for (i = 0; i < nbAttrs; i++) {
+	    iattr = vctxt->attrInfos[i];
+	    /*
+	    * SPEC (cvc-complex-type) (3)
+	    * Skip meta attributes.
+	    */
+	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
+		continue;
+	    /*
+	    * SPEC (cvc-complex-type)
+	    * (3.2.2) "The attribute information item must be �valid� with
+	    * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
+	    *
+	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
+	    * "... its [namespace name] must be �valid� with respect to
+	    * the wildcard constraint, as defined in Wildcard allows
+	    * Namespace Name (�3.10.4)."
+	    */
+	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
+		    iattr->nsName) == 0) {
+		/*
+		* Handle processContents.
+		*
+		* SPEC (cvc-wildcard):
+		* processContents | context-determined declaration:
+		* "strict"          "mustFind"
+		* "lax"             "none"
+		* "skip"            "skip"
+		*/
+		if (type->attributeWildcard->processContents ==
+		    XML_SCHEMAS_ANY_SKIP) {
+		     /*
+		    * context-determined declaration = "skip"
+		    *
+		    * SPEC PSVI Assessment Outcome (Attribute)
+		    * [validity] = "notKnown"
+		    * [validation attempted] = "none"
+		    */
+		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
+		    continue;
+		}
+		/*
+		* Find an attribute declaration.
+		*/
+		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
+		    iattr->localName, iattr->nsName);
+		if (iattr->decl != NULL) {
+		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
+		    /*
+		    * SPEC (cvc-complex-type)
+		    * (5) "Let [Definition:]  the wild IDs be the set of
+		    * all attribute information item to which clause 3.2
+		    * applied and whose �validation� resulted in a
+		    * �context-determined declaration� of mustFind or no
+		    * �context-determined declaration� at all, and whose
+		    * [local name] and [namespace name] resolve (as
+		    * defined by QName resolution (Instance) (�3.15.4)) to
+		    * an attribute declaration whose {type definition} is
+		    * or is derived from ID. Then all of the following
+		    * must be true:"
+		    */
+		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
+		    if (xmlSchemaIsDerivedFromBuiltInType(
+			iattr->typeDef, XML_SCHEMAS_ID)) {
+			/*
+			* SPEC (5.1) "There must be no more than one
+			* item in �wild IDs�."
+			*/
+			if (wildIDs != 0) {
+			    /* VAL TODO */
+			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
+			    TODO
+			    continue;
+			}
+			wildIDs++;
+			/*
+			* SPEC (cvc-complex-type)
+			* (5.2) "If �wild IDs� is non-empty, there must not
+			* be any attribute uses among the {attribute uses}
+			* whose {attribute declaration}'s {type definition}
+			* is or is derived from ID."
+			*/
+                        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) {
+		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
+		    /*
+		    * SPEC PSVI Assessment Outcome (Attribute)
+		    * [validity] = "notKnown"
+		    * [validation attempted] = "none"
+		    */
+		} else {
+		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
+		}
+	    }
+	}
+    }
+
+    if (vctxt->nbAttrInfos == 0)
+	return (0);
+
+    /*
+    * Get the owner element; needed for creation of default attributes.
+    * This fixes bug #341337, reported by David Grohmann.
+    */
+    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
+	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
+	if (ielem && ielem->node && ielem->node->doc)
+	    defAttrOwnerElem = ielem->node;
+    }
+    /*
+    * Validate values, create default attributes, evaluate IDCs.
+    */
+    for (i = 0; i < vctxt->nbAttrInfos; i++) {
+	iattr = vctxt->attrInfos[i];
+	/*
+	* VAL TODO: Note that we won't try to resolve IDCs to
+	* "lax" and "skip" validated attributes. Check what to
+	* do in this case.
+	*/
+	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
+	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
+	    continue;
+	/*
+	* VAL TODO: What to do if the type definition is missing?
+	*/
+	if (iattr->typeDef == NULL) {
+	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
+	    continue;
+	}
+
+	ACTIVATE_ATTRIBUTE(iattr);
+	fixed = 0;
+	xpathRes = 0;
+
+	if (vctxt->xpathStates != NULL) {
+	    /*
+	    * Evaluate IDCs.
+	    */
+	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
+		XML_ATTRIBUTE_NODE);
+	    if (xpathRes == -1) {
+		VERROR_INT("xmlSchemaVAttributesComplex",
+		    "calling xmlSchemaXPathEvaluate()");
+		goto internal_error;
+	    }
+	}
+
+	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
+	    /*
+	    * Default/fixed attributes.
+	    * We need the value only if we need to resolve IDCs or
+	    * will create default attributes.
+	    */
+	    if ((xpathRes) || (defAttrOwnerElem)) {
+		if (iattr->use->defValue != NULL) {
+		    iattr->value = (xmlChar *) iattr->use->defValue;
+		    iattr->val = iattr->use->defVal;
+		} else {
+		    iattr->value = (xmlChar *) iattr->decl->defValue;
+		    iattr->val = iattr->decl->defVal;
+		}
+		/*
+		* IDCs will consume the precomputed default value,
+		* so we need to clone it.
+		*/
+		if (iattr->val == NULL) {
+		    VERROR_INT("xmlSchemaVAttributesComplex",
+			"default/fixed value on an attribute use was "
+			"not precomputed");
+		    goto internal_error;
+		}
+		iattr->val = xmlSchemaCopyValue(iattr->val);
+		if (iattr->val == NULL) {
+		    VERROR_INT("xmlSchemaVAttributesComplex",
+			"calling xmlSchemaCopyValue()");
+		    goto internal_error;
+		}
+	    }
+	    /*
+	    * PSVI: Add the default attribute to the current element.
+	    * VAL TODO: Should we use the *normalized* value? This currently
+	    *   uses the *initial* value.
+	    */
+
+	    if (defAttrOwnerElem) {
+		xmlChar *normValue;
+		const xmlChar *value;
+
+		value = iattr->value;
+		/*
+		* Normalize the value.
+		*/
+		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
+		    iattr->value);
+		if (normValue != NULL)
+		    value = BAD_CAST normValue;
+
+		if (iattr->nsName == NULL) {
+		    if (xmlNewProp(defAttrOwnerElem,
+			iattr->localName, value) == NULL) {
+			VERROR_INT("xmlSchemaVAttributesComplex",
+			    "callling xmlNewProp()");
+			if (normValue != NULL)
+			    xmlFree(normValue);
+			goto internal_error;
+		    }
+		} else {
+		    xmlNsPtr ns;
+
+		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
+			defAttrOwnerElem, iattr->nsName);
+		    if (ns == NULL) {
+			xmlChar prefix[12];
+			int counter = 0;
+
+			/*
+			* Create a namespace declaration on the validation
+			* root node if no namespace declaration is in scope.
+			*/
+			do {
+			    snprintf((char *) prefix, 12, "p%d", counter++);
+			    ns = xmlSearchNs(defAttrOwnerElem->doc,
+				defAttrOwnerElem, BAD_CAST prefix);
+			    if (counter > 1000) {
+				VERROR_INT(
+				    "xmlSchemaVAttributesComplex",
+				    "could not compute a ns prefix for a "
+				    "default/fixed attribute");
+				if (normValue != NULL)
+				    xmlFree(normValue);
+				goto internal_error;
+			    }
+			} while (ns != NULL);
+			ns = xmlNewNs(vctxt->validationRoot,
+			    iattr->nsName, BAD_CAST prefix);
+		    }
+		    /*
+		    * TODO:
+		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
+		    * If we have QNames: do we need to ensure there's a
+		    * prefix defined for the QName?
+		    */
+		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
+		}
+		if (normValue != NULL)
+		    xmlFree(normValue);
+	    }
+	    /*
+	    * Go directly to IDC evaluation.
+	    */
+	    goto eval_idcs;
+	}
+	/*
+	* Validate the value.
+	*/
+	if (vctxt->value != NULL) {
+	    /*
+	    * Free last computed value; just for safety reasons.
+	    */
+	    xmlSchemaFreeValue(vctxt->value);
+	    vctxt->value = NULL;
+	}
+	/*
+	* Note that the attribute *use* can be unavailable, if
+	* the attribute was a wild attribute.
+	*/
+	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
+	    ((iattr->use != NULL) &&
+	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
+	    fixed = 1;
+	else
+	    fixed = 0;
+	/*
+	* SPEC (cvc-attribute)
+	* (3) "The item's �normalized value� must be locally �valid�
+	* with respect to that {type definition} as per
+	* String Valid (�3.14.4)."
+	*
+	* VAL TODO: Do we already have the
+	* "normalized attribute value" here?
+	*/
+	if (xpathRes || fixed) {
+	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
+	    /*
+	    * Request a computed value.
+	    */
+	    res = xmlSchemaVCheckCVCSimpleType(
+		ACTXT_CAST vctxt,
+		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
+		1, 1, 0);
+	} else {
+	    res = xmlSchemaVCheckCVCSimpleType(
+		ACTXT_CAST vctxt,
+		iattr->node, iattr->typeDef, iattr->value, NULL,
+		1, 0, 0);
+	}
+
+	if (res != 0) {
+	    if (res == -1) {
+		VERROR_INT("xmlSchemaVAttributesComplex",
+		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
+		goto internal_error;
+	    }
+	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
+	    /*
+	    * SPEC PSVI Assessment Outcome (Attribute)
+	    * [validity] = "invalid"
+	    */
+	    goto eval_idcs;
+	}
+
+	if (fixed) {
+	    /*
+	    * SPEC Attribute Locally Valid (Use) (cvc-au)
+	    * "For an attribute information item to be�valid�
+	    * with respect to an attribute use its *normalized*
+	    * value� must match the *canonical* lexical
+	    * representation of the attribute use's {value
+	    * constraint}value, if it is present and fixed."
+	    *
+	    * VAL TODO: The requirement for the *canonical* value
+	    * will be removed in XML Schema 1.1.
+	    */
+	    /*
+	    * SPEC Attribute Locally Valid (cvc-attribute)
+	    * (4) "The item's *actual* value� must match the *value* of
+	    * the {value constraint}, if it is present and fixed."
+	    */
+	    if (iattr->val == NULL) {
+		/* VAL TODO: A value was not precomputed. */
+		TODO
+		goto eval_idcs;
+	    }
+	    if ((iattr->use != NULL) &&
+		(iattr->use->defValue != NULL)) {
+		if (iattr->use->defVal == NULL) {
+		    /* VAL TODO: A default value was not precomputed. */
+		    TODO
+		    goto eval_idcs;
+		}
+		iattr->vcValue = iattr->use->defValue;
+		/*
+		if (xmlSchemaCompareValuesWhtsp(attr->val,
+		    (xmlSchemaWhitespaceValueType) ws,
+		    attr->use->defVal,
+		    (xmlSchemaWhitespaceValueType) ws) != 0) {
+		*/
+		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
+		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
+	    } else {
+		if (iattr->decl->defVal == NULL) {
+		    /* VAL TODO: A default value was not precomputed. */
+		    TODO
+		    goto eval_idcs;
+		}
+		iattr->vcValue = iattr->decl->defValue;
+		/*
+		if (xmlSchemaCompareValuesWhtsp(attr->val,
+		    (xmlSchemaWhitespaceValueType) ws,
+		    attrDecl->defVal,
+		    (xmlSchemaWhitespaceValueType) ws) != 0) {
+		*/
+		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
+		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
+	    }
+	    /*
+	    * [validity] = "valid"
+	    */
+	}
+eval_idcs:
+	/*
+	* Evaluate IDCs.
+	*/
+	if (xpathRes) {
+	    if (xmlSchemaXPathProcessHistory(vctxt,
+		vctxt->depth +1) == -1) {
+		VERROR_INT("xmlSchemaVAttributesComplex",
+		    "calling xmlSchemaXPathEvaluate()");
+		goto internal_error;
+	    }
+	} else if (vctxt->xpathStates != NULL)
+	    xmlSchemaXPathPop(vctxt);
+    }
+
+    /*
+    * Report errors.
+    */
+    for (i = 0; i < vctxt->nbAttrInfos; i++) {
+	iattr = vctxt->attrInfos[i];
+	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
+	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
+	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
+	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
+	    continue;
+	ACTIVATE_ATTRIBUTE(iattr);
+	switch (iattr->state) {
+	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
+		    xmlChar *str = NULL;
+		    ACTIVATE_ELEM;
+		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
+			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
+			"The attribute '%s' is required but missing",
+			xmlSchemaFormatQName(&str,
+			    iattr->decl->targetNamespace,
+			    iattr->decl->name),
+			NULL);
+		    FREE_AND_NULL(str)
+		    break;
+		}
+	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
+		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
+		    "The type definition is absent");
+		break;
+	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
+		xmlSchemaCustomErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_CVC_AU, NULL, NULL,
+		    "The value '%s' does not match the fixed "
+		    "value constraint '%s'",
+		    iattr->value, iattr->vcValue);
+		break;
+	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
+		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
+		    "No matching global attribute declaration available, but "
+		    "demanded by the strict wildcard");
+		break;
+	    case XML_SCHEMAS_ATTR_UNKNOWN:
+		if (iattr->metaType)
+		    break;
+		/*
+		* MAYBE VAL TODO: One might report different error messages
+		* for the following errors.
+		*/
+		if (type->attributeWildcard == NULL) {
+		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
+			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
+		} else {
+		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
+			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+
+    ACTIVATE_ELEM;
+    return (0);
+internal_error:
+    ACTIVATE_ELEM;
+    return (-1);
+}
+
+static int
+xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
+			      int *skip)
+{
+    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
+    /*
+    * The namespace of the element was already identified to be
+    * matching the wildcard.
+    */
+    if ((skip == NULL) || (wild == NULL) ||
+	(wild->type != XML_SCHEMA_TYPE_ANY)) {
+	VERROR_INT("xmlSchemaValidateElemWildcard",
+	    "bad arguments");
+	return (-1);
+    }
+    *skip = 0;
+    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
+	/*
+	* URGENT VAL TODO: Either we need to position the stream to the
+	* next sibling, or walk the whole subtree.
+	*/
+	*skip = 1;
+	return (0);
+    }
+    {
+	xmlSchemaElementPtr decl = NULL;
+
+	decl = xmlSchemaGetElem(vctxt->schema,
+	    vctxt->inode->localName, vctxt->inode->nsName);
+	if (decl != NULL) {
+	    vctxt->inode->decl = decl;
+	    return (0);
+	}
+    }
+    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
+	/* VAL TODO: Change to proper error code. */
+	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
+	    "No matching global element declaration available, but "
+	    "demanded by the strict wildcard");
+	return (vctxt->err);
+    }
+    if (vctxt->nbAttrInfos != 0) {
+	xmlSchemaAttrInfoPtr iattr;
+	/*
+	* SPEC Validation Rule: Schema-Validity Assessment (Element)
+	* (1.2.1.2.1) - (1.2.1.2.3 )
+	*
+	* Use the xsi:type attribute for the type definition.
+	*/
+	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
+	if (iattr != NULL) {
+	    if (xmlSchemaProcessXSIType(vctxt, iattr,
+		&(vctxt->inode->typeDef), NULL) == -1) {
+		VERROR_INT("xmlSchemaValidateElemWildcard",
+		    "calling xmlSchemaProcessXSIType() to "
+		    "process the attribute 'xsi:nil'");
+		return (-1);
+	    }
+	    /*
+	    * Don't return an error on purpose.
+	    */
+	    return (0);
+	}
+    }
+    /*
+    * SPEC Validation Rule: Schema-Validity Assessment (Element)
+    *
+    * Fallback to "anyType".
+    */
+    vctxt->inode->typeDef =
+	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+    return (0);
+}
+
+/*
+* xmlSchemaCheckCOSValidDefault:
+*
+* This will be called if: not nilled, no content and a default/fixed
+* value is provided.
+*/
+
+static int
+xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
+			      const xmlChar *value,
+			      xmlSchemaValPtr *val)
+{
+    int ret = 0;
+    xmlSchemaNodeInfoPtr inode = vctxt->inode;
+
+    /*
+    * cos-valid-default:
+    * Schema Component Constraint: Element Default Valid (Immediate)
+    * For a string to be a valid default with respect to a type
+    * definition the appropriate case among the following must be true:
+    */
+    if WXS_IS_COMPLEX(inode->typeDef) {
+	/*
+	* Complex type.
+	*
+	* SPEC (2.1) "its {content type} must be a simple type definition
+	* or mixed."
+	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
+	* type}'s particle must be �emptiable� as defined by
+	* Particle Emptiable (�3.9.6)."
+	*/
+	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
+	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
+	     (! WXS_EMPTIABLE(inode->typeDef)))) {
+	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
+	    /* NOTE that this covers (2.2.2) as well. */
+	    VERROR(ret, NULL,
+		"For a string to be a valid default, the type definition "
+		"must be a simple type or a complex type with simple content "
+		"or mixed content and a particle emptiable");
+	    return(ret);
+	}
+    }
+    /*
+    * 1 If the type definition is a simple type definition, then the string
+    * must be �valid� with respect to that definition as defined by String
+    * Valid (�3.14.4).
+    *
+    * AND
+    *
+    * 2.2.1 If the {content type} is a simple type definition, then the
+    * string must be �valid� with respect to that simple type definition
+    * as defined by String Valid (�3.14.4).
+    */
+    if (WXS_IS_SIMPLE(inode->typeDef)) {
+
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
+	    NULL, inode->typeDef, value, val, 1, 1, 0);
+
+    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
+
+	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
+	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
+    }
+    if (ret < 0) {
+	VERROR_INT("xmlSchemaCheckCOSValidDefault",
+	    "calling xmlSchemaVCheckCVCSimpleType()");
+    }
+    return (ret);
+}
+
+static void
+xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
+			       const xmlChar * name ATTRIBUTE_UNUSED,
+			       xmlSchemaElementPtr item,
+			       xmlSchemaNodeInfoPtr inode)
+{
+    inode->decl = item;
+#ifdef DEBUG_CONTENT
+    {
+	xmlChar *str = NULL;
+
+	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
+	    xmlGenericError(xmlGenericErrorContext,
+		"AUTOMATON callback for '%s' [declaration]\n",
+		xmlSchemaFormatQName(&str,
+		inode->localName, inode->nsName));
+	} else {
+	    xmlGenericError(xmlGenericErrorContext,
+		    "AUTOMATON callback for '%s' [wildcard]\n",
+		    xmlSchemaFormatQName(&str,
+		    inode->localName, inode->nsName));
+
+	}
+	FREE_AND_NULL(str)
+    }
+#endif
+}
+
+static int
+xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
+{
+    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
+    if (vctxt->inode == NULL) {
+	VERROR_INT("xmlSchemaValidatorPushElem",
+	    "calling xmlSchemaGetFreshElemInfo()");
+	return (-1);
+    }
+    vctxt->nbAttrInfos = 0;
+    return (0);
+}
+
+static int
+xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
+			     xmlSchemaNodeInfoPtr inode,
+			     xmlSchemaTypePtr type,
+			     const xmlChar *value)
+{
+    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
+	return (xmlSchemaVCheckCVCSimpleType(
+	    ACTXT_CAST vctxt, NULL,
+	    type, value, &(inode->val), 1, 1, 0));
+    else
+	return (xmlSchemaVCheckCVCSimpleType(
+	    ACTXT_CAST vctxt, NULL,
+	    type, value, NULL, 1, 0, 0));
+}
+
+
+
+/*
+* Process END of element.
+*/
+static int
+xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
+{
+    int ret = 0;
+    xmlSchemaNodeInfoPtr inode = vctxt->inode;
+
+    if (vctxt->nbAttrInfos != 0)
+	xmlSchemaClearAttrInfos(vctxt);
+    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
+	/*
+	* This element was not expected;
+	* we will not validate child elements of broken parents.
+	* Skip validation of all content of the parent.
+	*/
+	vctxt->skipDepth = vctxt->depth -1;
+	goto end_elem;
+    }
+    if ((inode->typeDef == NULL) ||
+	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
+	/*
+	* 1. the type definition might be missing if the element was
+	*    error prone
+	* 2. it might be abstract.
+	*/
+	goto end_elem;
+    }
+    /*
+    * Check the content model.
+    */
+    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
+	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
+
+	/*
+	* Workaround for "anyType".
+	*/
+	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
+	    goto character_content;
+
+	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
+	    xmlChar *values[10];
+	    int terminal, nbval = 10, nbneg;
+
+	    if (inode->regexCtxt == NULL) {
+		/*
+		* Create the regex context.
+		*/
+		inode->regexCtxt =
+		    xmlRegNewExecCtxt(inode->typeDef->contModel,
+		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
+		    vctxt);
+		if (inode->regexCtxt == NULL) {
+		    VERROR_INT("xmlSchemaValidatorPopElem",
+			"failed to create a regex context");
+		    goto internal_error;
+		}
+#ifdef DEBUG_AUTOMATA
+		xmlGenericError(xmlGenericErrorContext,
+		    "AUTOMATON create on '%s'\n", inode->localName);
+#endif
+	    }
+	    /*
+	    * Get hold of the still expected content, since a further
+	    * call to xmlRegExecPushString() will loose this information.
+	    */
+	    xmlRegExecNextValues(inode->regexCtxt,
+		&nbval, &nbneg, &values[0], &terminal);
+	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
+	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
+		/*
+		* Still missing something.
+		*/
+		ret = 1;
+		inode->flags |=
+		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
+		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
+		    "Missing child element(s)",
+		    nbval, nbneg, values);
+#ifdef DEBUG_AUTOMATA
+		xmlGenericError(xmlGenericErrorContext,
+		    "AUTOMATON missing ERROR on '%s'\n",
+		    inode->localName);
+#endif
+	    } else {
+		/*
+		* Content model is satisfied.
+		*/
+		ret = 0;
+#ifdef DEBUG_AUTOMATA
+		xmlGenericError(xmlGenericErrorContext,
+		    "AUTOMATON succeeded on '%s'\n",
+		    inode->localName);
+#endif
+	    }
+
+	}
+    }
+    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
+	goto end_elem;
+
+character_content:
+
+    if (vctxt->value != NULL) {
+	xmlSchemaFreeValue(vctxt->value);
+	vctxt->value = NULL;
+    }
+    /*
+    * Check character content.
+    */
+    if (inode->decl == NULL) {
+	/*
+	* Speedup if no declaration exists.
+	*/
+	if (WXS_IS_SIMPLE(inode->typeDef)) {
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		inode, inode->typeDef, inode->value);
+	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		inode, inode->typeDef->contentTypeDef,
+		inode->value);
+	}
+	if (ret < 0) {
+	    VERROR_INT("xmlSchemaValidatorPopElem",
+		"calling xmlSchemaVCheckCVCSimpleType()");
+	    goto internal_error;
+	}
+	goto end_elem;
+    }
+    /*
+    * cvc-elt (3.3.4) : 5
+    * The appropriate case among the following must be true:
+    */
+    /*
+    * cvc-elt (3.3.4) : 5.1
+    * If the declaration has a {value constraint},
+    * the item has neither element nor character [children] and
+    * clause 3.2 has not applied, then all of the following must be true:
+    */
+    if ((inode->decl->value != NULL) &&
+	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
+	(! INODE_NILLED(inode))) {
+	/*
+	* cvc-elt (3.3.4) : 5.1.1
+	* If the �actual type definition� is a �local type definition�
+	* then the canonical lexical representation of the {value constraint}
+	* value must be a valid default for the �actual type definition� as
+	* defined in Element Default Valid (Immediate) (�3.3.6).
+	*/
+	/*
+	* NOTE: 'local' above means types acquired by xsi:type.
+	* NOTE: Although the *canonical* value is stated, it is not
+	* relevant if canonical or not. Additionally XML Schema 1.1
+	* will removed this requirement as well.
+	*/
+	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
+
+	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
+		inode->decl->value, &(inode->val));
+	    if (ret != 0) {
+		if (ret < 0) {
+		    VERROR_INT("xmlSchemaValidatorPopElem",
+			"calling xmlSchemaCheckCOSValidDefault()");
+		    goto internal_error;
+		}
+		goto end_elem;
+	    }
+	    /*
+	    * Stop here, to avoid redundant validation of the value
+	    * (see following).
+	    */
+	    goto default_psvi;
+	}
+	/*
+	* cvc-elt (3.3.4) : 5.1.2
+	* The element information item with the canonical lexical
+	* representation of the {value constraint} value used as its
+	* �normalized value� must be �valid� with respect to the
+	* �actual type definition� as defined by Element Locally Valid (Type)
+	* (�3.3.4).
+	*/
+	if (WXS_IS_SIMPLE(inode->typeDef)) {
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		inode, inode->typeDef, inode->decl->value);
+	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		inode, inode->typeDef->contentTypeDef,
+		inode->decl->value);
+	}
+	if (ret != 0) {
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidatorPopElem",
+		    "calling xmlSchemaVCheckCVCSimpleType()");
+		goto internal_error;
+	    }
+	    goto end_elem;
+	}
+
+default_psvi:
+	/*
+	* PSVI: Create a text node on the instance element.
+	*/
+	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
+	    (inode->node != NULL)) {
+	    xmlNodePtr textChild;
+	    xmlChar *normValue;
+	    /*
+	    * VAL TODO: Normalize the value.
+	    */
+	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
+		inode->decl->value);
+	    if (normValue != NULL) {
+		textChild = xmlNewText(BAD_CAST normValue);
+		xmlFree(normValue);
+	    } else
+		textChild = xmlNewText(inode->decl->value);
+	    if (textChild == NULL) {
+		VERROR_INT("xmlSchemaValidatorPopElem",
+		    "calling xmlNewText()");
+		goto internal_error;
+	    } else
+		xmlAddChild(inode->node, textChild);
+	}
+
+    } else if (! INODE_NILLED(inode)) {
+	/*
+	* 5.2.1 The element information item must be �valid� with respect
+	* to the �actual type definition� as defined by Element Locally
+	* Valid (Type) (�3.3.4).
+	*/
+	if (WXS_IS_SIMPLE(inode->typeDef)) {
+	     /*
+	    * SPEC (cvc-type) (3.1)
+	    * "If the type definition is a simple type definition, ..."
+	    * (3.1.3) "If clause 3.2 of Element Locally Valid
+	    * (Element) (�3.3.4) did not apply, then the �normalized value�
+	    * must be �valid� with respect to the type definition as defined
+	    * by String Valid (�3.14.4).
+	    */
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		    inode, inode->typeDef, inode->value);
+	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
+	    /*
+	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
+	    * definition, then the element information item must be
+	    * �valid� with respect to the type definition as per
+	    * Element Locally Valid (Complex Type) (�3.4.4);"
+	    *
+	    * SPEC (cvc-complex-type) (2.2)
+	    * "If the {content type} is a simple type definition, ...
+	    * the �normalized value� of the element information item is
+	    * �valid� with respect to that simple type definition as
+	    * defined by String Valid (�3.14.4)."
+	    */
+	    ret = xmlSchemaVCheckINodeDataType(vctxt,
+		inode, inode->typeDef->contentTypeDef, inode->value);
+	}
+	if (ret != 0) {
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidatorPopElem",
+		    "calling xmlSchemaVCheckCVCSimpleType()");
+		goto internal_error;
+	    }
+	    goto end_elem;
+	}
+	/*
+	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
+	* not applied, all of the following must be true:
+	*/
+	if ((inode->decl->value != NULL) &&
+	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
+
+	    /*
+	    * TODO: We will need a computed value, when comparison is
+	    * done on computed values.
+	    */
+	    /*
+	    * 5.2.2.1 The element information item must have no element
+	    * information item [children].
+	    */
+	    if (inode->flags &
+		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
+		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
+		VERROR(ret, NULL,
+		    "The content must not containt element nodes since "
+		    "there is a fixed value constraint");
+		goto end_elem;
+	    } else {
+		/*
+		* 5.2.2.2 The appropriate case among the following must
+		* be true:
+		*/
+		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
+		    /*
+		    * 5.2.2.2.1 If the {content type} of the �actual type
+		    * definition� is mixed, then the *initial value* of the
+		    * item must match the canonical lexical representation
+		    * of the {value constraint} value.
+		    *
+		    * ... the *initial value* of an element information
+		    * item is the string composed of, in order, the
+		    * [character code] of each character information item in
+		    * the [children] of that element information item.
+		    */
+		    if (! xmlStrEqual(inode->value, inode->decl->value)){
+			/*
+			* VAL TODO: Report invalid & expected values as well.
+			* VAL TODO: Implement the canonical stuff.
+			*/
+			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
+			xmlSchemaCustomErr(ACTXT_CAST vctxt,
+			    ret, NULL, NULL,
+			    "The initial value '%s' does not match the fixed "
+			    "value constraint '%s'",
+			    inode->value, inode->decl->value);
+			goto end_elem;
+		    }
+		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
+		    /*
+		    * 5.2.2.2.2 If the {content type} of the �actual type
+		    * definition� is a simple type definition, then the
+		    * *actual value* of the item must match the canonical
+		    * lexical representation of the {value constraint} value.
+		    */
+		    /*
+		    * VAL TODO: *actual value* is the normalized value, impl.
+		    *           this.
+		    * VAL TODO: Report invalid & expected values as well.
+		    * VAL TODO: Implement a comparison with the computed values.
+		    */
+		    if (! xmlStrEqual(inode->value,
+			    inode->decl->value)) {
+			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
+			xmlSchemaCustomErr(ACTXT_CAST vctxt,
+			    ret, NULL, NULL,
+			    "The actual value '%s' does not match the fixed "
+			    "value constraint '%s'",
+			    inode->value,
+			    inode->decl->value);
+			goto end_elem;
+		    }
+		}
+	    }
+	}
+    }
+
+end_elem:
+    if (vctxt->depth < 0) {
+	/* TODO: raise error? */
+	return (0);
+    }
+    if (vctxt->depth == vctxt->skipDepth)
+	vctxt->skipDepth = -1;
+    /*
+    * Evaluate the history of XPath state objects.
+    */
+    if (inode->appliedXPath &&
+	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
+	goto internal_error;
+    /*
+    * MAYBE TODO:
+    * SPEC (6) "The element information item must be �valid� with
+    * respect to each of the {identity-constraint definitions} as per
+    * Identity-constraint Satisfied (�3.11.4)."
+    */
+    /*
+    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
+    *   need to be built in any case.
+    *   We will currently build IDC node-tables and bubble them only if
+    *   keyrefs do exist.
+    */
+
+    /*
+    * Add the current IDC target-nodes to the IDC node-tables.
+    */
+    if ((inode->idcMatchers != NULL) &&
+	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
+    {
+	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
+	    goto internal_error;
+    }
+    /*
+    * Validate IDC keyrefs.
+    */
+    if (vctxt->inode->hasKeyrefs)
+	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
+	    goto internal_error;
+    /*
+    * Merge/free the IDC table.
+    */
+    if (inode->idcTable != NULL) {
+#ifdef DEBUG_IDC_NODE_TABLE
+	xmlSchemaDebugDumpIDCTable(stdout,
+	    inode->nsName,
+	    inode->localName,
+	    inode->idcTable);
+#endif
+	if ((vctxt->depth > 0) &&
+	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
+	{
+	    /*
+	    * Merge the IDC node table with the table of the parent node.
+	    */
+	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
+		goto internal_error;
+	}
+    }
+    /*
+    * Clear the current ielem.
+    * VAL TODO: Don't free the PSVI IDC tables if they are
+    * requested for the PSVI.
+    */
+    xmlSchemaClearElemInfo(vctxt, inode);
+    /*
+    * Skip further processing if we are on the validation root.
+    */
+    if (vctxt->depth == 0) {
+	vctxt->depth--;
+	vctxt->inode = NULL;
+	return (0);
+    }
+    /*
+    * Reset the keyrefDepth if needed.
+    */
+    if (vctxt->aidcs != NULL) {
+	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
+	do {
+	    if (aidc->keyrefDepth == vctxt->depth) {
+		/*
+		* A 'keyrefDepth' of a key/unique IDC matches the current
+		* depth, this means that we are leaving the scope of the
+		* top-most keyref IDC which refers to this IDC.
+		*/
+		aidc->keyrefDepth = -1;
+	    }
+	    aidc = aidc->next;
+	} while (aidc != NULL);
+    }
+    vctxt->depth--;
+    vctxt->inode = vctxt->elemInfos[vctxt->depth];
+    /*
+    * VAL TODO: 7 If the element information item is the �validation root�, it must be
+    * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
+    */
+    return (ret);
+
+internal_error:
+    vctxt->err = -1;
+    return (-1);
+}
+
+/*
+* 3.4.4 Complex Type Definition Validation Rules
+* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
+*/
+static int
+xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaNodeInfoPtr pielem;
+    xmlSchemaTypePtr ptype;
+    int ret = 0;
+
+    if (vctxt->depth <= 0) {
+	VERROR_INT("xmlSchemaValidateChildElem",
+	    "not intended for the validation root");
+	return (-1);
+    }
+    pielem = vctxt->elemInfos[vctxt->depth -1];
+    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
+	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
+    /*
+    * Handle 'nilled' elements.
+    */
+    if (INODE_NILLED(pielem)) {
+	/*
+	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
+	*/
+	ACTIVATE_PARENT_ELEM;
+	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
+	VERROR(ret, NULL,
+	    "Neither character nor element content is allowed, "
+	    "because the element was 'nilled'");
+	ACTIVATE_ELEM;
+	goto unexpected_elem;
+    }
+
+    ptype = pielem->typeDef;
+
+    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
+	/*
+	* Workaround for "anyType": we have currently no content model
+	* assigned for "anyType", so handle it explicitely.
+	* "anyType" has an unbounded, lax "any" wildcard.
+	*/
+	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
+	    vctxt->inode->localName,
+	    vctxt->inode->nsName);
+
+	if (vctxt->inode->decl == NULL) {
+	    xmlSchemaAttrInfoPtr iattr;
+	    /*
+	    * Process "xsi:type".
+	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
+	    */
+	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
+		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
+	    if (iattr != NULL) {
+		ret = xmlSchemaProcessXSIType(vctxt, iattr,
+		    &(vctxt->inode->typeDef), NULL);
+		if (ret != 0) {
+		    if (ret == -1) {
+			VERROR_INT("xmlSchemaValidateChildElem",
+			    "calling xmlSchemaProcessXSIType() to "
+			    "process the attribute 'xsi:nil'");
+			return (-1);
+		    }
+		    return (ret);
+		}
+	    } else {
+		 /*
+		 * Fallback to "anyType".
+		 *
+		 * SPEC (cvc-assess-elt)
+		 * "If the item cannot be �strictly assessed�, [...]
+		 * an element information item's schema validity may be laxly
+		 * assessed if its �context-determined declaration� is not
+		 * skip by �validating� with respect to the �ur-type
+		 * definition� as per Element Locally Valid (Type) (�3.3.4)."
+		*/
+		vctxt->inode->typeDef =
+		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
+	    }
+	}
+	return (0);
+    }
+
+    switch (ptype->contentType) {
+	case XML_SCHEMA_CONTENT_EMPTY:
+	    /*
+	    * SPEC (2.1) "If the {content type} is empty, then the
+	    * element information item has no character or element
+	    * information item [children]."
+	    */
+	    ACTIVATE_PARENT_ELEM
+	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
+	    VERROR(ret, NULL,
+		"Element content is not allowed, "
+		"because the content type is empty");
+	    ACTIVATE_ELEM
+	    goto unexpected_elem;
+	    break;
+
+	case XML_SCHEMA_CONTENT_MIXED:
+        case XML_SCHEMA_CONTENT_ELEMENTS: {
+	    xmlRegExecCtxtPtr regexCtxt;
+	    xmlChar *values[10];
+	    int terminal, nbval = 10, nbneg;
+
+	    /* VAL TODO: Optimized "anyType" validation.*/
+
+	    if (ptype->contModel == NULL) {
+		VERROR_INT("xmlSchemaValidateChildElem",
+		    "type has elem content but no content model");
+		return (-1);
+	    }
+	    /*
+	    * Safety belf for evaluation if the cont. model was already
+	    * examined to be invalid.
+	    */
+	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
+		VERROR_INT("xmlSchemaValidateChildElem",
+		    "validating elem, but elem content is already invalid");
+		return (-1);
+	    }
+
+	    regexCtxt = pielem->regexCtxt;
+	    if (regexCtxt == NULL) {
+		/*
+		* Create the regex context.
+		*/
+		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
+		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
+		    vctxt);
+		if (regexCtxt == NULL) {
+		    VERROR_INT("xmlSchemaValidateChildElem",
+			"failed to create a regex context");
+		    return (-1);
+		}
+		pielem->regexCtxt = regexCtxt;
+#ifdef DEBUG_AUTOMATA
+		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
+		    pielem->localName);
+#endif
+	    }
+
+	    /*
+	    * SPEC (2.4) "If the {content type} is element-only or mixed,
+	    * then the sequence of the element information item's
+	    * element information item [children], if any, taken in
+	    * order, is �valid� with respect to the {content type}'s
+	    * particle, as defined in Element Sequence Locally Valid
+	    * (Particle) (�3.9.4)."
+	    */
+	    ret = xmlRegExecPushString2(regexCtxt,
+		vctxt->inode->localName,
+		vctxt->inode->nsName,
+		vctxt->inode);
+#ifdef DEBUG_AUTOMATA
+	    if (ret < 0)
+		xmlGenericError(xmlGenericErrorContext,
+		"AUTOMATON push ERROR for '%s' on '%s'\n",
+		vctxt->inode->localName, pielem->localName);
+	    else
+		xmlGenericError(xmlGenericErrorContext,
+		"AUTOMATON push OK for '%s' on '%s'\n",
+		vctxt->inode->localName, pielem->localName);
+#endif
+	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
+		VERROR_INT("xmlSchemaValidateChildElem",
+		    "calling xmlRegExecPushString2()");
+		return (-1);
+	    }
+	    if (ret < 0) {
+		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
+		    &values[0], &terminal);
+		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
+		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
+		    "This element is not expected",
+		    nbval, nbneg, values);
+		ret = vctxt->err;
+		goto unexpected_elem;
+	    } else
+		ret = 0;
+	}
+	    break;
+	case XML_SCHEMA_CONTENT_SIMPLE:
+	case XML_SCHEMA_CONTENT_BASIC:
+	    ACTIVATE_PARENT_ELEM
+	    if (WXS_IS_COMPLEX(ptype)) {
+		/*
+		* SPEC (cvc-complex-type) (2.2)
+		* "If the {content type} is a simple type definition, then
+		* the element information item has no element information
+		* item [children], ..."
+		*/
+		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
+		VERROR(ret, NULL, "Element content is not allowed, "
+		    "because the content type is a simple type definition");
+	    } else {
+		/*
+		* SPEC (cvc-type) (3.1.2) "The element information item must
+		* have no element information item [children]."
+		*/
+		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
+		VERROR(ret, NULL, "Element content is not allowed, "
+		    "because the type definition is simple");
+	    }
+	    ACTIVATE_ELEM
+	    ret = vctxt->err;
+	    goto unexpected_elem;
+	    break;
+
+	default:
+	    break;
+    }
+    return (ret);
+unexpected_elem:
+    /*
+    * Pop this element and set the skipDepth to skip
+    * all further content of the parent element.
+    */
+    vctxt->skipDepth = vctxt->depth;
+    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
+    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
+    return (ret);
+}
+
+#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
+#define XML_SCHEMA_PUSH_TEXT_CREATED 2
+#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
+
+static int
+xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
+		  int nodeType, const xmlChar *value, int len,
+		  int mode, int *consumed)
+{
+    /*
+    * Unfortunately we have to duplicate the text sometimes.
+    * OPTIMIZE: Maybe we could skip it, if:
+    *   1. content type is simple
+    *   2. whitespace is "collapse"
+    *   3. it consists of whitespace only
+    *
+    * Process character content.
+    */
+    if (consumed != NULL)
+	*consumed = 0;
+    if (INODE_NILLED(vctxt->inode)) {
+	/*
+	* SPEC cvc-elt (3.3.4 - 3.2.1)
+	* "The element information item must have no character or
+	* element information item [children]."
+	*/
+	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
+	    "Neither character nor element content is allowed "
+	    "because the element is 'nilled'");
+	return (vctxt->err);
+    }
+    /*
+    * SPEC (2.1) "If the {content type} is empty, then the
+    * element information item has no character or element
+    * information item [children]."
+    */
+    if (vctxt->inode->typeDef->contentType ==
+	    XML_SCHEMA_CONTENT_EMPTY) {
+	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
+	    "Character content is not allowed, "
+	    "because the content type is empty");
+	return (vctxt->err);
+    }
+
+    if (vctxt->inode->typeDef->contentType ==
+	    XML_SCHEMA_CONTENT_ELEMENTS) {
+	if ((nodeType != XML_TEXT_NODE) ||
+	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
+	    /*
+	    * SPEC cvc-complex-type (2.3)
+	    * "If the {content type} is element-only, then the
+	    * element information item has no character information
+	    * item [children] other than those whose [character
+	    * code] is defined as a white space in [XML 1.0 (Second
+	    * Edition)]."
+	    */
+	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
+		"Character content other than whitespace is not allowed "
+		"because the content type is 'element-only'");
+	    return (vctxt->err);
+	}
+	return (0);
+    }
+
+    if ((value == NULL) || (value[0] == 0))
+	return (0);
+    /*
+    * Save the value.
+    * NOTE that even if the content type is *mixed*, we need the
+    * *initial value* for default/fixed value constraints.
+    */
+    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
+	((vctxt->inode->decl == NULL) ||
+	(vctxt->inode->decl->value == NULL)))
+	return (0);
+
+    if (vctxt->inode->value == NULL) {
+	/*
+	* Set the value.
+	*/
+	switch (mode) {
+	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
+		/*
+		* When working on a tree.
+		*/
+		vctxt->inode->value = value;
+		break;
+	    case XML_SCHEMA_PUSH_TEXT_CREATED:
+		/*
+		* When working with the reader.
+		* The value will be freed by the element info.
+		*/
+		vctxt->inode->value = value;
+		if (consumed != NULL)
+		    *consumed = 1;
+		vctxt->inode->flags |=
+		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
+		break;
+	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
+		/*
+		* When working with SAX.
+		* The value will be freed by the element info.
+		*/
+		if (len != -1)
+		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
+		else
+		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
+		vctxt->inode->flags |=
+		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
+		break;
+	    default:
+		break;
+	}
+    } else {
+	if (len < 0)
+	    len = xmlStrlen(value);
+	/*
+	* Concat the value.
+	*/
+	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
+	    vctxt->inode->value = BAD_CAST xmlStrncat(
+		(xmlChar *) vctxt->inode->value, value, len);
+	} else {
+	    vctxt->inode->value =
+		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
+	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
+	}
+    }
+
+    return (0);
+}
+
+static int
+xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
+{
+    int ret = 0;
+
+    if ((vctxt->skipDepth != -1) &&
+	(vctxt->depth >= vctxt->skipDepth)) {
+	VERROR_INT("xmlSchemaValidateElem",
+	    "in skip-state");
+	goto internal_error;
+    }
+    if (vctxt->xsiAssemble) {
+	/*
+	* We will stop validation if there was an error during
+	* dynamic schema construction.
+	* Note that we simply set @skipDepth to 0, this could
+	* mean that a streaming document via SAX would be
+	* still read to the end but it won't be validated any more.
+	* TODO: If we are sure how to stop the validation at once
+	*   for all input scenarios, then this should be changed to
+	*   instantly stop the validation.
+	*/
+	ret = xmlSchemaAssembleByXSI(vctxt);
+	if (ret != 0) {
+	    if (ret == -1)
+		goto internal_error;
+	    vctxt->skipDepth = 0;
+	    return(ret);
+	}
+    }
+    if (vctxt->depth > 0) {
+	/*
+	* Validate this element against the content model
+	* of the parent.
+	*/
+	ret = xmlSchemaValidateChildElem(vctxt);
+	if (ret != 0) {
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidateElem",
+		    "calling xmlSchemaStreamValidateChildElement()");
+		goto internal_error;
+	    }
+	    goto exit;
+	}
+	if (vctxt->depth == vctxt->skipDepth)
+	    goto exit;
+	if ((vctxt->inode->decl == NULL) &&
+	    (vctxt->inode->typeDef == NULL)) {
+	    VERROR_INT("xmlSchemaValidateElem",
+		"the child element was valid but neither the "
+		"declaration nor the type was set");
+	    goto internal_error;
+	}
+    } else {
+	/*
+	* Get the declaration of the validation root.
+	*/
+	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
+	    vctxt->inode->localName,
+	    vctxt->inode->nsName);
+	if (vctxt->inode->decl == NULL) {
+	    ret = XML_SCHEMAV_CVC_ELT_1;
+	    VERROR(ret, NULL,
+		"No matching global declaration available "
+		"for the validation root");
+	    goto exit;
+	}
+    }
+
+    if (vctxt->inode->decl == NULL)
+	goto type_validation;
+
+    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
+	int skip;
+	/*
+	* Wildcards.
+	*/
+	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
+	if (ret != 0) {
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaValidateElem",
+		    "calling xmlSchemaValidateElemWildcard()");
+		goto internal_error;
+	    }
+	    goto exit;
+	}
+	if (skip) {
+	    vctxt->skipDepth = vctxt->depth;
+	    goto exit;
+	}
+	/*
+	* The declaration might be set by the wildcard validation,
+	* when the processContents is "lax" or "strict".
+	*/
+	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
+	    /*
+	    * Clear the "decl" field to not confuse further processing.
+	    */
+	    vctxt->inode->decl = NULL;
+	    goto type_validation;
+	}
+    }
+    /*
+    * Validate against the declaration.
+    */
+    ret = xmlSchemaValidateElemDecl(vctxt);
+    if (ret != 0) {
+	if (ret < 0) {
+	    VERROR_INT("xmlSchemaValidateElem",
+		"calling xmlSchemaValidateElemDecl()");
+	    goto internal_error;
+	}
+	goto exit;
+    }
+    /*
+    * Validate against the type definition.
+    */
+type_validation:
+
+    if (vctxt->inode->typeDef == NULL) {
+	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
+	ret = XML_SCHEMAV_CVC_TYPE_1;
+    	VERROR(ret, NULL,
+    	    "The type definition is absent");
+	goto exit;
+    }
+    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
+	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
+	ret = XML_SCHEMAV_CVC_TYPE_2;
+    	    VERROR(ret, NULL,
+    	    "The type definition is abstract");
+	goto exit;
+    }
+    /*
+    * Evaluate IDCs. Do it here, since new IDC matchers are registered
+    * during validation against the declaration. This must be done
+    * _before_ attribute validation.
+    */
+    if (vctxt->xpathStates != NULL) {
+	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
+	vctxt->inode->appliedXPath = 1;
+	if (ret == -1) {
+	    VERROR_INT("xmlSchemaValidateElem",
+		"calling xmlSchemaXPathEvaluate()");
+	    goto internal_error;
+	}
+    }
+    /*
+    * Validate attributes.
+    */
+    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
+	if ((vctxt->nbAttrInfos != 0) ||
+	    (vctxt->inode->typeDef->attrUses != NULL)) {
+
+	    ret = xmlSchemaVAttributesComplex(vctxt);
+	}
+    } else if (vctxt->nbAttrInfos != 0) {
+
+	ret = xmlSchemaVAttributesSimple(vctxt);
+    }
+    /*
+    * Clear registered attributes.
+    */
+    if (vctxt->nbAttrInfos != 0)
+	xmlSchemaClearAttrInfos(vctxt);
+    if (ret == -1) {
+	VERROR_INT("xmlSchemaValidateElem",
+	    "calling attributes validation");
+	goto internal_error;
+    }
+    /*
+    * Don't return an error if attributes are invalid on purpose.
+    */
+    ret = 0;
+
+exit:
+    if (ret != 0)
+	vctxt->skipDepth = vctxt->depth;
+    return (ret);
+internal_error:
+    return (-1);
+}
+
+#ifdef XML_SCHEMA_READER_ENABLED
+static int
+xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
+{
+    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
+    int depth, nodeType, ret = 0, consumed;
+    xmlSchemaNodeInfoPtr ielem;
+
+    vctxt->depth = -1;
+    ret = xmlTextReaderRead(vctxt->reader);
+    /*
+    * Move to the document element.
+    */
+    while (ret == 1) {
+	nodeType = xmlTextReaderNodeType(vctxt->reader);
+	if (nodeType == XML_ELEMENT_NODE)
+	    goto root_found;
+	ret = xmlTextReaderRead(vctxt->reader);
+    }
+    goto exit;
+
+root_found:
+
+    do {
+	depth = xmlTextReaderDepth(vctxt->reader);
+	nodeType = xmlTextReaderNodeType(vctxt->reader);
+
+	if (nodeType == XML_ELEMENT_NODE) {
+
+	    vctxt->depth++;
+	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
+		VERROR_INT("xmlSchemaVReaderWalk",
+		    "calling xmlSchemaValidatorPushElem()");
+		goto internal_error;
+	    }
+	    ielem = vctxt->inode;
+	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
+	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
+	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
+	    /*
+	    * Is the element empty?
+	    */
+	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
+	    if (ret == -1) {
+		VERROR_INT("xmlSchemaVReaderWalk",
+		    "calling xmlTextReaderIsEmptyElement()");
+		goto internal_error;
+	    }
+	    if (ret) {
+		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
+	    }
+	    /*
+	    * Register attributes.
+	    */
+	    vctxt->nbAttrInfos = 0;
+	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
+	    if (ret == -1) {
+		VERROR_INT("xmlSchemaVReaderWalk",
+		    "calling xmlTextReaderMoveToFirstAttribute()");
+		goto internal_error;
+	    }
+	    if (ret == 1) {
+		do {
+		    /*
+		    * VAL TODO: How do we know that the reader works on a
+		    * node tree, to be able to pass a node here?
+		    */
+		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
+			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
+			xmlTextReaderNamespaceUri(vctxt->reader), 1,
+			xmlTextReaderValue(vctxt->reader), 1) == -1) {
+
+			VERROR_INT("xmlSchemaVReaderWalk",
+			    "calling xmlSchemaValidatorPushAttribute()");
+			goto internal_error;
+		    }
+		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
+		    if (ret == -1) {
+			VERROR_INT("xmlSchemaVReaderWalk",
+			    "calling xmlTextReaderMoveToFirstAttribute()");
+			goto internal_error;
+		    }
+		} while (ret == 1);
+		/*
+		* Back to element position.
+		*/
+		ret = xmlTextReaderMoveToElement(vctxt->reader);
+		if (ret == -1) {
+		    VERROR_INT("xmlSchemaVReaderWalk",
+			"calling xmlTextReaderMoveToElement()");
+		    goto internal_error;
+		}
+	    }
+	    /*
+	    * Validate the element.
+	    */
+	    ret= xmlSchemaValidateElem(vctxt);
+	    if (ret != 0) {
+		if (ret == -1) {
+		    VERROR_INT("xmlSchemaVReaderWalk",
+			"calling xmlSchemaValidateElem()");
+		    goto internal_error;
+		}
+		goto exit;
+	    }
+	    if (vctxt->depth == vctxt->skipDepth) {
+		int curDepth;
+		/*
+		* Skip all content.
+		*/
+		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
+		    ret = xmlTextReaderRead(vctxt->reader);
+		    curDepth = xmlTextReaderDepth(vctxt->reader);
+		    while ((ret == 1) && (curDepth != depth)) {
+			ret = xmlTextReaderRead(vctxt->reader);
+			curDepth = xmlTextReaderDepth(vctxt->reader);
+		    }
+		    if (ret < 0) {
+			/*
+			* VAL TODO: A reader error occured; what to do here?
+			*/
+			ret = 1;
+			goto exit;
+		    }
+		}
+		goto leave_elem;
+	    }
+	    /*
+	    * READER VAL TODO: Is an END_ELEM really never called
+	    * if the elem is empty?
+	    */
+	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
+		goto leave_elem;
+	} else if (nodeType == END_ELEM) {
+	    /*
+	    * Process END of element.
+	    */
+leave_elem:
+	    ret = xmlSchemaValidatorPopElem(vctxt);
+	    if (ret != 0) {
+		if (ret < 0) {
+		    VERROR_INT("xmlSchemaVReaderWalk",
+			"calling xmlSchemaValidatorPopElem()");
+		    goto internal_error;
+		}
+		goto exit;
+	    }
+	    if (vctxt->depth >= 0)
+		ielem = vctxt->inode;
+	    else
+		ielem = NULL;
+	} else if ((nodeType == XML_TEXT_NODE) ||
+	    (nodeType == XML_CDATA_SECTION_NODE) ||
+	    (nodeType == WHTSP) ||
+	    (nodeType == SIGN_WHTSP)) {
+	    /*
+	    * Process character content.
+	    */
+	    xmlChar *value;
+
+	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
+		nodeType = XML_TEXT_NODE;
+
+	    value = xmlTextReaderValue(vctxt->reader);
+	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
+		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
+	    if (! consumed)
+		xmlFree(value);
+	    if (ret == -1) {
+		VERROR_INT("xmlSchemaVReaderWalk",
+		    "calling xmlSchemaVPushText()");
+		goto internal_error;
+	    }
+	} else if ((nodeType == XML_ENTITY_NODE) ||
+	    (nodeType == XML_ENTITY_REF_NODE)) {
+	    /*
+	    * VAL TODO: What to do with entities?
+	    */
+	    TODO
+	}
+	/*
+	* Read next node.
+	*/
+	ret = xmlTextReaderRead(vctxt->reader);
+    } while (ret == 1);
+
+exit:
+    return (ret);
+internal_error:
+    return (-1);
+}
+#endif
+
+/************************************************************************
+ * 									*
+ * 			SAX validation handlers				*
+ * 									*
+ ************************************************************************/
+
+/*
+* Process text content.
+*/
+static void
+xmlSchemaSAXHandleText(void *ctx,
+		       const xmlChar * ch,
+		       int len)
+{
+    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
+
+    if (vctxt->depth < 0)
+	return;
+    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
+	return;
+    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
+	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
+    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
+	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
+	VERROR_INT("xmlSchemaSAXHandleCDataSection",
+	    "calling xmlSchemaVPushText()");
+	vctxt->err = -1;
+	xmlStopParser(vctxt->parserCtxt);
+    }
+}
+
+/*
+* Process CDATA content.
+*/
+static void
+xmlSchemaSAXHandleCDataSection(void *ctx,
+			     const xmlChar * ch,
+			     int len)
+{
+    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
+
+    if (vctxt->depth < 0)
+	return;
+    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
+	return;
+    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
+	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
+    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
+	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
+	VERROR_INT("xmlSchemaSAXHandleCDataSection",
+	    "calling xmlSchemaVPushText()");
+	vctxt->err = -1;
+	xmlStopParser(vctxt->parserCtxt);
+    }
+}
+
+static void
+xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
+			    const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
+
+    if (vctxt->depth < 0)
+	return;
+    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
+	return;
+    /* SAX VAL TODO: What to do here? */
+    TODO
+}
+
+static void
+xmlSchemaSAXHandleStartElementNs(void *ctx,
+				 const xmlChar * localname,
+				 const xmlChar * prefix ATTRIBUTE_UNUSED,
+				 const xmlChar * URI,
+				 int nb_namespaces,
+				 const xmlChar ** namespaces,
+				 int nb_attributes,
+				 int nb_defaulted ATTRIBUTE_UNUSED,
+				 const xmlChar ** attributes)
+{
+    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
+    int ret;
+    xmlSchemaNodeInfoPtr ielem;
+    int i, j;
+
+    /*
+    * SAX VAL TODO: What to do with nb_defaulted?
+    */
+    /*
+    * Skip elements if inside a "skip" wildcard or invalid.
+    */
+    vctxt->depth++;
+    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
+	return;
+    /*
+    * Push the element.
+    */
+    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
+	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
+	    "calling xmlSchemaValidatorPushElem()");
+	goto internal_error;
+    }
+    ielem = vctxt->inode;
+    /*
+    * TODO: Is this OK?
+    */
+    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
+    ielem->localName = localname;
+    ielem->nsName = URI;
+    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
+    /*
+    * Register namespaces on the elem info.
+    */
+    if (nb_namespaces != 0) {
+	/*
+	* Although the parser builds its own namespace list,
+	* we have no access to it, so we'll use an own one.
+	*/
+        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
+	    /*
+	    * Store prefix and namespace name.
+	    */
+	    if (ielem->nsBindings == NULL) {
+		ielem->nsBindings =
+		    (const xmlChar **) xmlMalloc(10 *
+			sizeof(const xmlChar *));
+		if (ielem->nsBindings == NULL) {
+		    xmlSchemaVErrMemory(vctxt,
+			"allocating namespace bindings for SAX validation",
+			NULL);
+		    goto internal_error;
+		}
+		ielem->nbNsBindings = 0;
+		ielem->sizeNsBindings = 5;
+	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
+		ielem->sizeNsBindings *= 2;
+		ielem->nsBindings =
+		    (const xmlChar **) xmlRealloc(
+			(void *) ielem->nsBindings,
+			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
+		if (ielem->nsBindings == NULL) {
+		    xmlSchemaVErrMemory(vctxt,
+			"re-allocating namespace bindings for SAX validation",
+			NULL);
+		    goto internal_error;
+		}
+	    }
+
+	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
+	    if (namespaces[j+1][0] == 0) {
+		/*
+		* Handle xmlns="".
+		*/
+		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
+	    } else
+		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
+		    namespaces[j+1];
+	    ielem->nbNsBindings++;
+	}
+    }
+    /*
+    * Register attributes.
+    * SAX VAL TODO: We are not adding namespace declaration
+    * attributes yet.
+    */
+    if (nb_attributes != 0) {
+	xmlChar *value;
+
+        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
+	    /*
+	    * Duplicate the value.
+	    */
+	    value = xmlStrndup(attributes[j+3],
+		attributes[j+4] - attributes[j+3]);
+	    /*
+	    * TODO: Set the node line.
+	    */
+	    ret = xmlSchemaValidatorPushAttribute(vctxt,
+		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
+		value, 1);
+	    if (ret == -1) {
+		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
+		    "calling xmlSchemaValidatorPushAttribute()");
+		goto internal_error;
+	    }
+	}
+    }
+    /*
+    * Validate the element.
+    */
+    ret = xmlSchemaValidateElem(vctxt);
+    if (ret != 0) {
+	if (ret == -1) {
+	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
+		"calling xmlSchemaValidateElem()");
+	    goto internal_error;
+	}
+	goto exit;
+    }
+
+exit:
+    return;
+internal_error:
+    vctxt->err = -1;
+    xmlStopParser(vctxt->parserCtxt);
+    return;
+}
+
+static void
+xmlSchemaSAXHandleEndElementNs(void *ctx,
+			       const xmlChar * localname ATTRIBUTE_UNUSED,
+			       const xmlChar * prefix ATTRIBUTE_UNUSED,
+			       const xmlChar * URI ATTRIBUTE_UNUSED)
+{
+    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
+    int res;
+
+    /*
+    * Skip elements if inside a "skip" wildcard or if invalid.
+    */
+    if (vctxt->skipDepth != -1) {
+	if (vctxt->depth > vctxt->skipDepth) {
+	    vctxt->depth--;
+	    return;
+	} else
+	    vctxt->skipDepth = -1;
+    }
+    /*
+    * SAX VAL TODO: Just a temporary check.
+    */
+    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
+	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
+	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
+	    "elem pop mismatch");
+    }
+    res = xmlSchemaValidatorPopElem(vctxt);
+    if (res != 0) {
+	if (res < 0) {
+	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
+		"calling xmlSchemaValidatorPopElem()");
+	    goto internal_error;
+	}
+	goto exit;
+    }
+exit:
+    return;
+internal_error:
+    vctxt->err = -1;
+    xmlStopParser(vctxt->parserCtxt);
+    return;
+}
+
+/************************************************************************
+ * 									*
+ * 			Validation interfaces				*
+ * 									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaNewValidCtxt:
+ * @schema:  a precompiled XML Schemas
+ *
+ * Create an XML Schemas validation context based on the given schema.
+ *
+ * Returns the validation context or NULL in case of error
+ */
+xmlSchemaValidCtxtPtr
+xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
+{
+    xmlSchemaValidCtxtPtr ret;
+
+    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
+    if (ret == NULL) {
+        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
+    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
+    ret->dict = xmlDictCreate();
+    ret->nodeQNames = xmlSchemaItemListCreate();
+    ret->schema = schema;
+    return (ret);
+}
+
+/**
+ * xmlSchemaClearValidCtxt:
+ * @ctxt: the schema validation context
+ *
+ * Free the resources associated to the schema validation context;
+ * leaves some fields alive intended for reuse of the context.
+ */
+static void
+xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
+{
+    if (vctxt == NULL)
+        return;
+
+    /*
+    * TODO: Should we clear the flags?
+    *   Might be problematic if one reuses the context
+    *   and assumes that the options remain the same.
+    */
+    vctxt->flags = 0;
+    vctxt->validationRoot = NULL;
+    vctxt->doc = NULL;
+#ifdef LIBXML_READER_ENABLED
+    vctxt->reader = NULL;
+#endif
+    vctxt->hasKeyrefs = 0;
+
+    if (vctxt->value != NULL) {
+        xmlSchemaFreeValue(vctxt->value);
+	vctxt->value = NULL;
+    }
+    /*
+    * Augmented IDC information.
+    */
+    if (vctxt->aidcs != NULL) {
+	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
+	do {
+	    next = cur->next;
+	    xmlFree(cur);
+	    cur = next;
+	} while (cur != NULL);
+	vctxt->aidcs = NULL;
+    }
+    if (vctxt->idcMatcherCache != NULL) {
+	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
+
+	while (matcher) {
+	    tmp = matcher;
+	    matcher = matcher->nextCached;
+	    xmlSchemaIDCFreeMatcherList(tmp);
+	}
+	vctxt->idcMatcherCache = NULL;
+    }
+
+
+    if (vctxt->idcNodes != NULL) {
+	int i;
+	xmlSchemaPSVIIDCNodePtr item;
+
+	for (i = 0; i < vctxt->nbIdcNodes; i++) {
+	    item = vctxt->idcNodes[i];
+	    xmlFree(item->keys);
+	    xmlFree(item);
+	}
+	xmlFree(vctxt->idcNodes);
+	vctxt->idcNodes = NULL;
+	vctxt->nbIdcNodes = 0;
+	vctxt->sizeIdcNodes = 0;
+    }
+    /*
+    * Note that we won't delete the XPath state pool here.
+    */
+    if (vctxt->xpathStates != NULL) {
+	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
+	vctxt->xpathStates = NULL;
+    }
+    /*
+    * Attribute info.
+    */
+    if (vctxt->nbAttrInfos != 0) {
+	xmlSchemaClearAttrInfos(vctxt);
+    }
+    /*
+    * Element info.
+    */
+    if (vctxt->elemInfos != NULL) {
+	int i;
+	xmlSchemaNodeInfoPtr ei;
+
+	for (i = 0; i < vctxt->sizeElemInfos; i++) {
+	    ei = vctxt->elemInfos[i];
+	    if (ei == NULL)
+		break;
+	    xmlSchemaClearElemInfo(vctxt, ei);
+	}
+    }
+    xmlSchemaItemListClear(vctxt->nodeQNames);
+    /* Recreate the dict. */
+    xmlDictFree(vctxt->dict);
+    /*
+    * TODO: Is is save to recreate it? Do we have a scenario
+    * where the user provides the dict?
+    */
+    vctxt->dict = xmlDictCreate();
+}
+
+/**
+ * xmlSchemaFreeValidCtxt:
+ * @ctxt:  the schema validation context
+ *
+ * Free the resources associated to the schema validation context
+ */
+void
+xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return;
+    if (ctxt->value != NULL)
+        xmlSchemaFreeValue(ctxt->value);
+    if (ctxt->pctxt != NULL)
+	xmlSchemaFreeParserCtxt(ctxt->pctxt);
+    if (ctxt->idcNodes != NULL) {
+	int i;
+	xmlSchemaPSVIIDCNodePtr item;
+
+	for (i = 0; i < ctxt->nbIdcNodes; i++) {
+	    item = ctxt->idcNodes[i];
+	    xmlFree(item->keys);
+	    xmlFree(item);
+	}
+	xmlFree(ctxt->idcNodes);
+    }
+    if (ctxt->idcKeys != NULL) {
+	int i;
+	for (i = 0; i < ctxt->nbIdcKeys; i++)
+	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
+	xmlFree(ctxt->idcKeys);
+    }
+
+    if (ctxt->xpathStates != NULL) {
+	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
+	ctxt->xpathStates = NULL;
+    }
+    if (ctxt->xpathStatePool != NULL) {
+	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
+	ctxt->xpathStatePool = NULL;
+    }
+
+    /*
+    * Augmented IDC information.
+    */
+    if (ctxt->aidcs != NULL) {
+	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
+	do {
+	    next = cur->next;
+	    xmlFree(cur);
+	    cur = next;
+	} while (cur != NULL);
+    }
+    if (ctxt->attrInfos != NULL) {
+	int i;
+	xmlSchemaAttrInfoPtr attr;
+
+	/* Just a paranoid call to the cleanup. */
+	if (ctxt->nbAttrInfos != 0)
+	    xmlSchemaClearAttrInfos(ctxt);
+	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
+	    attr = ctxt->attrInfos[i];
+	    xmlFree(attr);
+	}
+	xmlFree(ctxt->attrInfos);
+    }
+    if (ctxt->elemInfos != NULL) {
+	int i;
+	xmlSchemaNodeInfoPtr ei;
+
+	for (i = 0; i < ctxt->sizeElemInfos; i++) {
+	    ei = ctxt->elemInfos[i];
+	    if (ei == NULL)
+		break;
+	    xmlSchemaClearElemInfo(ctxt, ei);
+	    xmlFree(ei);
+	}
+	xmlFree(ctxt->elemInfos);
+    }
+    if (ctxt->nodeQNames != NULL)
+	xmlSchemaItemListFree(ctxt->nodeQNames);
+    if (ctxt->dict != NULL)
+	xmlDictFree(ctxt->dict);
+    xmlFree(ctxt);
+}
+
+/**
+ * xmlSchemaIsValid:
+ * @ctxt: the schema validation context
+ *
+ * Check if any error was detected during validation.
+ *
+ * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
+ *         of internal error.
+ */
+int
+xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return(-1);
+    return(ctxt->err == 0);
+}
+
+/**
+ * xmlSchemaSetValidErrors:
+ * @ctxt:  a schema validation context
+ * @err:  the error function
+ * @warn: the warning function
+ * @ctx: the functions context
+ *
+ * Set the error and warning callback informations
+ */
+void
+xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
+                        xmlSchemaValidityErrorFunc err,
+                        xmlSchemaValidityWarningFunc warn, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+    ctxt->error = err;
+    ctxt->warning = warn;
+    ctxt->errCtxt = ctx;
+    if (ctxt->pctxt != NULL)
+	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
+}
+
+/**
+ * xmlSchemaSetValidStructuredErrors:
+ * @ctxt:  a schema validation context
+ * @serror:  the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
+				  xmlStructuredErrorFunc serror, void *ctx)
+{
+    if (ctxt == NULL)
+        return;
+	ctxt->serror = serror;
+    ctxt->error = NULL;
+    ctxt->warning = NULL;
+    ctxt->errCtxt = ctx;
+    if (ctxt->pctxt != NULL)
+	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
+}
+
+/**
+ * xmlSchemaGetValidErrors:
+ * @ctxt: a XML-Schema validation context
+ * @err: the error function result
+ * @warn: the warning function result
+ * @ctx: the functions context result
+ *
+ * Get the error and warning callback informations
+ *
+ * Returns -1 in case of error and 0 otherwise
+ */
+int
+xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
+			xmlSchemaValidityErrorFunc * err,
+			xmlSchemaValidityWarningFunc * warn, void **ctx)
+{
+	if (ctxt == NULL)
+		return (-1);
+	if (err != NULL)
+		*err = ctxt->error;
+	if (warn != NULL)
+		*warn = ctxt->warning;
+	if (ctx != NULL)
+		*ctx = ctxt->errCtxt;
+	return (0);
+}
+
+
+/**
+ * xmlSchemaSetValidOptions:
+ * @ctxt:	a schema validation context
+ * @options: a combination of xmlSchemaValidOption
+ *
+ * Sets the options to be used during the validation.
+ *
+ * Returns 0 in case of success, -1 in case of an
+ * API error.
+ */
+int
+xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
+			 int options)
+
+{
+    int i;
+
+    if (ctxt == NULL)
+	return (-1);
+    /*
+    * WARNING: Change the start value if adding to the
+    * xmlSchemaValidOption.
+    * TODO: Is there an other, more easy to maintain,
+    * way?
+    */
+    for (i = 1; i < (int) sizeof(int) * 8; i++) {
+        if (options & 1<<i)
+	    return (-1);
+    }
+    ctxt->options = options;
+    return (0);
+}
+
+/**
+ * xmlSchemaValidCtxtGetOptions:
+ * @ctxt: a schema validation context
+ *
+ * Get the validation context options.
+ *
+ * Returns the option combination or -1 on error.
+ */
+int
+xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
+
+{
+    if (ctxt == NULL)
+	return (-1);
+    else
+	return (ctxt->options);
+}
+
+static int
+xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlAttrPtr attr;
+    int ret = 0;
+    xmlSchemaNodeInfoPtr ielem = NULL;
+    xmlNodePtr node, valRoot;
+    const xmlChar *nsName;
+
+    /* DOC VAL TODO: Move this to the start function. */
+    valRoot = xmlDocGetRootElement(vctxt->doc);
+    if (valRoot == NULL) {
+	/* VAL TODO: Error code? */
+	VERROR(1, NULL, "The document has no document element");
+	return (1);
+    }
+    vctxt->depth = -1;
+    vctxt->validationRoot = valRoot;
+    node = valRoot;
+    while (node != NULL) {
+	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
+	    goto next_sibling;
+	if (node->type == XML_ELEMENT_NODE) {
+
+	    /*
+	    * Init the node-info.
+	    */
+	    vctxt->depth++;
+	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
+		goto internal_error;
+	    ielem = vctxt->inode;
+	    ielem->node = node;
+	    ielem->nodeLine = node->line;
+	    ielem->localName = node->name;
+	    if (node->ns != NULL)
+		ielem->nsName = node->ns->href;
+	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
+	    /*
+	    * Register attributes.
+	    * DOC VAL TODO: We do not register namespace declaration
+	    * attributes yet.
+	    */
+	    vctxt->nbAttrInfos = 0;
+	    if (node->properties != NULL) {
+		attr = node->properties;
+		do {
+		    if (attr->ns != NULL)
+			nsName = attr->ns->href;
+		    else
+			nsName = NULL;
+		    ret = xmlSchemaValidatorPushAttribute(vctxt,
+			(xmlNodePtr) attr,
+			/*
+			* Note that we give it the line number of the
+			* parent element.
+			*/
+			ielem->nodeLine,
+			attr->name, nsName, 0,
+			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
+		    if (ret == -1) {
+			VERROR_INT("xmlSchemaDocWalk",
+			    "calling xmlSchemaValidatorPushAttribute()");
+			goto internal_error;
+		    }
+		    attr = attr->next;
+		} while (attr);
+	    }
+	    /*
+	    * Validate the element.
+	    */
+	    ret = xmlSchemaValidateElem(vctxt);
+	    if (ret != 0) {
+		if (ret == -1) {
+		    VERROR_INT("xmlSchemaDocWalk",
+			"calling xmlSchemaValidateElem()");
+		    goto internal_error;
+		}
+		/*
+		* Don't stop validation; just skip the content
+		* of this element.
+		*/
+		goto leave_node;
+	    }
+	    if ((vctxt->skipDepth != -1) &&
+		(vctxt->depth >= vctxt->skipDepth))
+		goto leave_node;
+	} else if ((node->type == XML_TEXT_NODE) ||
+	    (node->type == XML_CDATA_SECTION_NODE)) {
+	    /*
+	    * Process character content.
+	    */
+	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
+		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
+	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
+		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
+	    if (ret < 0) {
+		VERROR_INT("xmlSchemaVDocWalk",
+		    "calling xmlSchemaVPushText()");
+		goto internal_error;
+	    }
+	    /*
+	    * DOC VAL TODO: Should we skip further validation of the
+	    * element content here?
+	    */
+	} else if ((node->type == XML_ENTITY_NODE) ||
+	    (node->type == XML_ENTITY_REF_NODE)) {
+	    /*
+	    * DOC VAL TODO: What to do with entities?
+	    */
+	    VERROR_INT("xmlSchemaVDocWalk",
+		"there is at least one entity reference in the node-tree "
+		"currently being validated. Processing of entities with "
+		"this XML Schema processor is not supported (yet). Please "
+		"substitute entities before validation.");
+	    goto internal_error;
+	} else {
+	    goto leave_node;
+	    /*
+	    * DOC VAL TODO: XInclude nodes, etc.
+	    */
+	}
+	/*
+	* Walk the doc.
+	*/
+	if (node->children != NULL) {
+	    node = node->children;
+	    continue;
+	}
+leave_node:
+	if (node->type == XML_ELEMENT_NODE) {
+	    /*
+	    * Leaving the scope of an element.
+	    */
+	    if (node != vctxt->inode->node) {
+		VERROR_INT("xmlSchemaVDocWalk",
+		    "element position mismatch");
+		goto internal_error;
+	    }
+	    ret = xmlSchemaValidatorPopElem(vctxt);
+	    if (ret != 0) {
+		if (ret < 0) {
+		    VERROR_INT("xmlSchemaVDocWalk",
+			"calling xmlSchemaValidatorPopElem()");
+		    goto internal_error;
+		}
+	    }
+	    if (node == valRoot)
+		goto exit;
+	}
+next_sibling:
+	if (node->next != NULL)
+	    node = node->next;
+	else {
+	    node = node->parent;
+	    goto leave_node;
+	}
+    }
+
+exit:
+    return (ret);
+internal_error:
+    return (-1);
+}
+
+static int
+xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
+    /*
+    * Some initialization.
+    */
+    vctxt->err = 0;
+    vctxt->nberrors = 0;
+    vctxt->depth = -1;
+    vctxt->skipDepth = -1;
+    vctxt->xsiAssemble = 0;
+    vctxt->hasKeyrefs = 0;
+#ifdef ENABLE_IDC_NODE_TABLES_TEST
+    vctxt->createIDCNodeTables = 1;
+#else
+    vctxt->createIDCNodeTables = 0;
+#endif
+    /*
+    * Create a schema + parser if necessary.
+    */
+    if (vctxt->schema == NULL) {
+	xmlSchemaParserCtxtPtr pctxt;
+
+	vctxt->xsiAssemble = 1;
+	/*
+	* If not schema was given then we will create a schema
+	* dynamically using XSI schema locations.
+	*
+	* Create the schema parser context.
+	*/
+	if ((vctxt->pctxt == NULL) &&
+	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
+	   return (-1);
+	pctxt = vctxt->pctxt;
+	pctxt->xsiAssemble = 1;
+	/*
+	* Create the schema.
+	*/
+	vctxt->schema = xmlSchemaNewSchema(pctxt);
+	if (vctxt->schema == NULL)
+	    return (-1);
+	/*
+	* Create the schema construction context.
+	*/
+	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
+	if (pctxt->constructor == NULL)
+	    return(-1);
+	pctxt->constructor->mainSchema = vctxt->schema;
+	/*
+	* Take ownership of the constructor to be able to free it.
+	*/
+	pctxt->ownsConstructor = 1;
+    }
+    /*
+    * Augment the IDC definitions for the main schema and all imported ones
+    * NOTE: main schema if the first in the imported list
+    */
+    xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
+
+    return(0);
+}
+
+static void
+xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
+    if (vctxt->xsiAssemble) {
+	if (vctxt->schema != NULL) {
+	    xmlSchemaFree(vctxt->schema);
+	    vctxt->schema = NULL;
+	}
+    }
+    xmlSchemaClearValidCtxt(vctxt);
+}
+
+static int
+xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
+{
+    int ret = 0;
+
+    if (xmlSchemaPreRun(vctxt) < 0)
+        return(-1);
+
+    if (vctxt->doc != NULL) {
+	/*
+	 * Tree validation.
+	 */
+	ret = xmlSchemaVDocWalk(vctxt);
+#ifdef LIBXML_READER_ENABLED
+    } else if (vctxt->reader != NULL) {
+	/*
+	 * XML Reader validation.
+	 */
+#ifdef XML_SCHEMA_READER_ENABLED
+	ret = xmlSchemaVReaderWalk(vctxt);
+#endif
+#endif
+    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
+	/*
+	 * SAX validation.
+	 */
+	ret = xmlParseDocument(vctxt->parserCtxt);
+    } else {
+	VERROR_INT("xmlSchemaVStart",
+	    "no instance to validate");
+	ret = -1;
+    }
+
+    xmlSchemaPostRun(vctxt);
+    if (ret == 0)
+	ret = vctxt->err;
+    return (ret);
+}
+
+/**
+ * xmlSchemaValidateOneElement:
+ * @ctxt:  a schema validation context
+ * @elem:  an element node
+ *
+ * Validate a branch of a tree, starting with the given @elem.
+ *
+ * Returns 0 if the element and its subtree is valid, a positive error
+ * code number otherwise and -1 in case of an internal or API error.
+ */
+int
+xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
+{
+    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
+	return (-1);
+
+    if (ctxt->schema == NULL)
+	return (-1);
+
+    ctxt->doc = elem->doc;
+    ctxt->node = elem;
+    ctxt->validationRoot = elem;
+    return(xmlSchemaVStart(ctxt));
+}
+
+/**
+ * xmlSchemaValidateDoc:
+ * @ctxt:  a schema validation context
+ * @doc:  a parsed document tree
+ *
+ * Validate a document tree in memory.
+ *
+ * Returns 0 if the document is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
+{
+    if ((ctxt == NULL) || (doc == NULL))
+        return (-1);
+
+    ctxt->doc = doc;
+    ctxt->node = xmlDocGetRootElement(doc);
+    if (ctxt->node == NULL) {
+        xmlSchemaCustomErr(ACTXT_CAST ctxt,
+	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
+	    (xmlNodePtr) doc, NULL,
+	    "The document has no document element", NULL, NULL);
+        return (ctxt->err);
+    }
+    ctxt->validationRoot = ctxt->node;
+    return (xmlSchemaVStart(ctxt));
+}
+
+
+/************************************************************************
+ * 									*
+ * 		Function and data for SAX streaming API			*
+ * 									*
+ ************************************************************************/
+typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
+typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
+
+struct _xmlSchemaSplitSAXData {
+    xmlSAXHandlerPtr      user_sax;
+    void                 *user_data;
+    xmlSchemaValidCtxtPtr ctxt;
+    xmlSAXHandlerPtr      schemas_sax;
+};
+
+#define XML_SAX_PLUG_MAGIC 0xdc43ba21
+
+struct _xmlSchemaSAXPlug {
+    unsigned int magic;
+
+    /* the original callbacks informations */
+    xmlSAXHandlerPtr     *user_sax_ptr;
+    xmlSAXHandlerPtr      user_sax;
+    void                **user_data_ptr;
+    void                 *user_data;
+
+    /* the block plugged back and validation informations */
+    xmlSAXHandler         schemas_sax;
+    xmlSchemaValidCtxtPtr ctxt;
+};
+
+/* All those functions just bounces to the user provided SAX handlers */
+static void
+internalSubsetSplit(void *ctx, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->internalSubset != NULL))
+	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
+	                               SystemID);
+}
+
+static int
+isStandaloneSplit(void *ctx)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->isStandalone != NULL))
+	return(ctxt->user_sax->isStandalone(ctxt->user_data));
+    return(0);
+}
+
+static int
+hasInternalSubsetSplit(void *ctx)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->hasInternalSubset != NULL))
+	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
+    return(0);
+}
+
+static int
+hasExternalSubsetSplit(void *ctx)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->hasExternalSubset != NULL))
+	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
+    return(0);
+}
+
+static void
+externalSubsetSplit(void *ctx, const xmlChar *name,
+	       const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->externalSubset != NULL))
+	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
+	                               SystemID);
+}
+
+static xmlParserInputPtr
+resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->resolveEntity != NULL))
+	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
+	                                     systemId));
+    return(NULL);
+}
+
+static xmlEntityPtr
+getEntitySplit(void *ctx, const xmlChar *name)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->getEntity != NULL))
+	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
+    return(NULL);
+}
+
+static xmlEntityPtr
+getParameterEntitySplit(void *ctx, const xmlChar *name)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->getParameterEntity != NULL))
+	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
+    return(NULL);
+}
+
+
+static void
+entityDeclSplit(void *ctx, const xmlChar *name, int type,
+          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->entityDecl != NULL))
+	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
+	                           systemId, content);
+}
+
+static void
+attributeDeclSplit(void *ctx, const xmlChar * elem,
+                   const xmlChar * name, int type, int def,
+                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->attributeDecl != NULL)) {
+	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
+	                              def, defaultValue, tree);
+    } else {
+	xmlFreeEnumeration(tree);
+    }
+}
+
+static void
+elementDeclSplit(void *ctx, const xmlChar *name, int type,
+	    xmlElementContentPtr content)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->elementDecl != NULL))
+	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
+}
+
+static void
+notationDeclSplit(void *ctx, const xmlChar *name,
+	     const xmlChar *publicId, const xmlChar *systemId)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->notationDecl != NULL))
+	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
+	                             systemId);
+}
+
+static void
+unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
+		   const xmlChar *publicId, const xmlChar *systemId,
+		   const xmlChar *notationName)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->unparsedEntityDecl != NULL))
+	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
+	                                   systemId, notationName);
+}
+
+static void
+setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->setDocumentLocator != NULL))
+	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
+}
+
+static void
+startDocumentSplit(void *ctx)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->startDocument != NULL))
+	ctxt->user_sax->startDocument(ctxt->user_data);
+}
+
+static void
+endDocumentSplit(void *ctx)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->endDocument != NULL))
+	ctxt->user_sax->endDocument(ctxt->user_data);
+}
+
+static void
+processingInstructionSplit(void *ctx, const xmlChar *target,
+                      const xmlChar *data)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->processingInstruction != NULL))
+	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
+}
+
+static void
+commentSplit(void *ctx, const xmlChar *value)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->comment != NULL))
+	ctxt->user_sax->comment(ctxt->user_data, value);
+}
+
+/*
+ * Varargs error callbacks to the user application, harder ...
+ */
+
+static void XMLCDECL
+warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->warning != NULL)) {
+	TODO
+    }
+}
+static void XMLCDECL
+errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->error != NULL)) {
+	TODO
+    }
+}
+static void XMLCDECL
+fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->fatalError != NULL)) {
+	TODO
+    }
+}
+
+/*
+ * Those are function where both the user handler and the schemas handler
+ * need to be called.
+ */
+static void
+charactersSplit(void *ctx, const xmlChar *ch, int len)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
+	ctxt->user_sax->characters(ctxt->user_data, ch, len);
+    if (ctxt->ctxt != NULL)
+	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
+}
+
+static void
+ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->ignorableWhitespace != NULL))
+	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
+    if (ctxt->ctxt != NULL)
+	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
+}
+
+static void
+cdataBlockSplit(void *ctx, const xmlChar *value, int len)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->cdataBlock != NULL))
+	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
+    if (ctxt->ctxt != NULL)
+	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
+}
+
+static void
+referenceSplit(void *ctx, const xmlChar *name)
+{
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->reference != NULL))
+	ctxt->user_sax->reference(ctxt->user_data, name);
+    if (ctxt->ctxt != NULL)
+        xmlSchemaSAXHandleReference(ctxt->user_data, name);
+}
+
+static void
+startElementNsSplit(void *ctx, const xmlChar * localname,
+		    const xmlChar * prefix, const xmlChar * URI,
+		    int nb_namespaces, const xmlChar ** namespaces,
+		    int nb_attributes, int nb_defaulted,
+		    const xmlChar ** attributes) {
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->startElementNs != NULL))
+	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
+	                               URI, nb_namespaces, namespaces,
+				       nb_attributes, nb_defaulted,
+				       attributes);
+    if (ctxt->ctxt != NULL)
+	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
+	                                 URI, nb_namespaces, namespaces,
+					 nb_attributes, nb_defaulted,
+					 attributes);
+}
+
+static void
+endElementNsSplit(void *ctx, const xmlChar * localname,
+		    const xmlChar * prefix, const xmlChar * URI) {
+    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
+    if (ctxt == NULL)
+        return;
+    if ((ctxt->user_sax != NULL) &&
+        (ctxt->user_sax->endElementNs != NULL))
+	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
+    if (ctxt->ctxt != NULL)
+	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
+}
+
+/**
+ * xmlSchemaSAXPlug:
+ * @ctxt:  a schema validation context
+ * @sax:  a pointer to the original xmlSAXHandlerPtr
+ * @user_data:  a pointer to the original SAX user data pointer
+ *
+ * Plug a SAX based validation layer in a SAX parsing event flow.
+ * The original @saxptr and @dataptr data are replaced by new pointers
+ * but the calls to the original will be maintained.
+ *
+ * Returns a pointer to a data structure needed to unplug the validation layer
+ *         or NULL in case of errors.
+ */
+xmlSchemaSAXPlugPtr
+xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
+		 xmlSAXHandlerPtr *sax, void **user_data)
+{
+    xmlSchemaSAXPlugPtr ret;
+    xmlSAXHandlerPtr old_sax;
+
+    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
+        return(NULL);
+
+    /*
+     * We only allow to plug into SAX2 event streams
+     */
+    old_sax = *sax;
+    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
+        return(NULL);
+    if ((old_sax != NULL) &&
+        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
+        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
+        return(NULL);
+
+    /*
+     * everything seems right allocate the local data needed for that layer
+     */
+    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
+    if (ret == NULL) {
+        return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
+    ret->magic = XML_SAX_PLUG_MAGIC;
+    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
+    ret->ctxt = ctxt;
+    ret->user_sax_ptr = sax;
+    ret->user_sax = old_sax;
+    if (old_sax == NULL) {
+        /*
+	 * go direct, no need for the split block and functions.
+	 */
+	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
+	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
+	/*
+	 * Note that we use the same text-function for both, to prevent
+	 * the parser from testing for ignorable whitespace.
+	 */
+	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
+	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
+
+	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
+	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
+
+	ret->user_data = ctxt;
+	*user_data = ctxt;
+    } else {
+       /*
+        * for each callback unused by Schemas initialize it to the Split
+	* routine only if non NULL in the user block, this can speed up
+	* things at the SAX level.
+	*/
+        if (old_sax->internalSubset != NULL)
+            ret->schemas_sax.internalSubset = internalSubsetSplit;
+        if (old_sax->isStandalone != NULL)
+            ret->schemas_sax.isStandalone = isStandaloneSplit;
+        if (old_sax->hasInternalSubset != NULL)
+            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
+        if (old_sax->hasExternalSubset != NULL)
+            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
+        if (old_sax->resolveEntity != NULL)
+            ret->schemas_sax.resolveEntity = resolveEntitySplit;
+        if (old_sax->getEntity != NULL)
+            ret->schemas_sax.getEntity = getEntitySplit;
+        if (old_sax->entityDecl != NULL)
+            ret->schemas_sax.entityDecl = entityDeclSplit;
+        if (old_sax->notationDecl != NULL)
+            ret->schemas_sax.notationDecl = notationDeclSplit;
+        if (old_sax->attributeDecl != NULL)
+            ret->schemas_sax.attributeDecl = attributeDeclSplit;
+        if (old_sax->elementDecl != NULL)
+            ret->schemas_sax.elementDecl = elementDeclSplit;
+        if (old_sax->unparsedEntityDecl != NULL)
+            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
+        if (old_sax->setDocumentLocator != NULL)
+            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
+        if (old_sax->startDocument != NULL)
+            ret->schemas_sax.startDocument = startDocumentSplit;
+        if (old_sax->endDocument != NULL)
+            ret->schemas_sax.endDocument = endDocumentSplit;
+        if (old_sax->processingInstruction != NULL)
+            ret->schemas_sax.processingInstruction = processingInstructionSplit;
+        if (old_sax->comment != NULL)
+            ret->schemas_sax.comment = commentSplit;
+        if (old_sax->warning != NULL)
+            ret->schemas_sax.warning = warningSplit;
+        if (old_sax->error != NULL)
+            ret->schemas_sax.error = errorSplit;
+        if (old_sax->fatalError != NULL)
+            ret->schemas_sax.fatalError = fatalErrorSplit;
+        if (old_sax->getParameterEntity != NULL)
+            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
+        if (old_sax->externalSubset != NULL)
+            ret->schemas_sax.externalSubset = externalSubsetSplit;
+
+	/*
+	 * the 6 schemas callback have to go to the splitter functions
+	 * Note that we use the same text-function for ignorableWhitespace
+	 * if possible, to prevent the parser from testing for ignorable
+	 * whitespace.
+	 */
+        ret->schemas_sax.characters = charactersSplit;
+	if ((old_sax->ignorableWhitespace != NULL) &&
+	    (old_sax->ignorableWhitespace != old_sax->characters))
+	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
+	else
+	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
+        ret->schemas_sax.cdataBlock = cdataBlockSplit;
+        ret->schemas_sax.reference = referenceSplit;
+        ret->schemas_sax.startElementNs = startElementNsSplit;
+        ret->schemas_sax.endElementNs = endElementNsSplit;
+
+	ret->user_data_ptr = user_data;
+	ret->user_data = *user_data;
+	*user_data = ret;
+    }
+
+    /*
+     * plug the pointers back.
+     */
+    *sax = &(ret->schemas_sax);
+    ctxt->sax = *sax;
+    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
+    xmlSchemaPreRun(ctxt);
+    return(ret);
+}
+
+/**
+ * xmlSchemaSAXUnplug:
+ * @plug:  a data structure returned by xmlSchemaSAXPlug
+ *
+ * Unplug a SAX based validation layer in a SAX parsing event flow.
+ * The original pointers used in the call are restored.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
+{
+    xmlSAXHandlerPtr *sax;
+    void **user_data;
+
+    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
+        return(-1);
+    plug->magic = 0;
+
+    xmlSchemaPostRun(plug->ctxt);
+    /* restore the data */
+    sax = plug->user_sax_ptr;
+    *sax = plug->user_sax;
+    if (plug->user_sax != NULL) {
+	user_data = plug->user_data_ptr;
+	*user_data = plug->user_data;
+    }
+
+    /* free and return */
+    xmlFree(plug);
+    return(0);
+}
+
+/**
+ * xmlSchemaValidateStream:
+ * @ctxt:  a schema validation context
+ * @input:  the input to use for reading the data
+ * @enc:  an optional encoding information
+ * @sax:  a SAX handler for the resulting events
+ * @user_data:  the context to provide to the SAX handler.
+ *
+ * Validate an input based on a flow of SAX event from the parser
+ * and forward the events to the @sax handler with the provided @user_data
+ * the user provided @sax handler must be a SAX2 one.
+ *
+ * Returns 0 if the document is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
+                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
+                        xmlSAXHandlerPtr sax, void *user_data)
+{
+    xmlSchemaSAXPlugPtr plug = NULL;
+    xmlSAXHandlerPtr old_sax = NULL;
+    xmlParserCtxtPtr pctxt = NULL;
+    xmlParserInputPtr inputStream = NULL;
+    int ret;
+
+    if ((ctxt == NULL) || (input == NULL))
+        return (-1);
+
+    /*
+     * prepare the parser
+     */
+    pctxt = xmlNewParserCtxt();
+    if (pctxt == NULL)
+        return (-1);
+    old_sax = pctxt->sax;
+    pctxt->sax = sax;
+    pctxt->userData = user_data;
+#if 0
+    if (options)
+        xmlCtxtUseOptions(pctxt, options);
+#endif
+    pctxt->linenumbers = 1;
+
+    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
+    if (inputStream == NULL) {
+        ret = -1;
+	goto done;
+    }
+    inputPush(pctxt, inputStream);
+    ctxt->parserCtxt = pctxt;
+    ctxt->input = input;
+
+    /*
+     * Plug the validation and launch the parsing
+     */
+    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
+    if (plug == NULL) {
+        ret = -1;
+	goto done;
+    }
+    ctxt->input = input;
+    ctxt->enc = enc;
+    ctxt->sax = pctxt->sax;
+    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
+    ret = xmlSchemaVStart(ctxt);
+
+    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
+	ret = ctxt->parserCtxt->errNo;
+	if (ret == 0)
+	    ret = 1;
+    }
+
+done:
+    ctxt->parserCtxt = NULL;
+    ctxt->sax = NULL;
+    ctxt->input = NULL;
+    if (plug != NULL) {
+        xmlSchemaSAXUnplug(plug);
+    }
+    /* cleanup */
+    if (pctxt != NULL) {
+	pctxt->sax = old_sax;
+	xmlFreeParserCtxt(pctxt);
+    }
+    return (ret);
+}
+
+/**
+ * xmlSchemaValidateFile:
+ * @ctxt: a schema validation context
+ * @filename: the URI of the instance
+ * @options: a future set of options, currently unused
+ *
+ * Do a schemas validation of the given resource, it will use the
+ * SAX streamable validation internally.
+ *
+ * Returns 0 if the document is valid, a positive error code
+ *     number otherwise and -1 in case of an internal or API error.
+ */
+int
+xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
+                      const char * filename,
+		      int options ATTRIBUTE_UNUSED)
+{
+    int ret;
+    xmlParserInputBufferPtr input;
+
+    if ((ctxt == NULL) || (filename == NULL))
+        return (-1);
+
+    input = xmlParserInputBufferCreateFilename(filename,
+	XML_CHAR_ENCODING_NONE);
+    if (input == NULL)
+	return (-1);
+    ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
+	NULL, NULL);
+    return (ret);
+}
+
+/**
+ * xmlSchemaValidCtxtGetParserCtxt:
+ * @ctxt: a schema validation context
+ *
+ * allow access to the parser context of the schema validation context
+ *
+ * Returns the parser context of the schema validation context or NULL
+ *         in case of error.
+ */
+xmlParserCtxtPtr
+xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
+{
+    if (ctxt == NULL)
+        return(NULL);
+    return (ctxt->parserCtxt);
+}
+
+#define bottom_xmlschemas
+#include "elfgcchack.h"
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/xmlschemastypes.c b/src/xmlschemastypes.c
new file mode 100644
index 0000000..d0ee8a2
--- /dev/null
+++ b/src/xmlschemastypes.c
@@ -0,0 +1,6127 @@
+/*
+ * schemastypes.c : implementation of the XML Schema Datatypes
+ *             definition and validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/hash.h>
+#include <libxml/valid.h>
+#include <libxml/xpath.h>
+#include <libxml/uri.h>
+
+#include <libxml/xmlschemas.h>
+#include <libxml/schemasInternals.h>
+#include <libxml/xmlschemastypes.h>
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#define DEBUG
+
+#ifndef LIBXML_XPATH_ENABLED
+extern double xmlXPathNAN;
+extern double xmlXPathPINF;
+extern double xmlXPathNINF;
+#endif
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define XML_SCHEMAS_NAMESPACE_NAME \
+    (const xmlChar *)"http://www.w3.org/2001/XMLSchema"
+
+#define IS_WSP_REPLACE_CH(c)	((((c) == 0x9) || ((c) == 0xa)) || \
+				 ((c) == 0xd))
+
+#define IS_WSP_SPACE_CH(c)	((c) == 0x20)
+
+#define IS_WSP_BLANK_CH(c) IS_BLANK_CH(c)
+
+/* Date value */
+typedef struct _xmlSchemaValDate xmlSchemaValDate;
+typedef xmlSchemaValDate *xmlSchemaValDatePtr;
+struct _xmlSchemaValDate {
+    long		year;
+    unsigned int	mon	:4;	/* 1 <=  mon    <= 12   */
+    unsigned int	day	:5;	/* 1 <=  day    <= 31   */
+    unsigned int	hour	:5;	/* 0 <=  hour   <= 23   */
+    unsigned int	min	:6;	/* 0 <=  min    <= 59	*/
+    double		sec;
+    unsigned int	tz_flag	:1;	/* is tzo explicitely set? */
+    signed int		tzo	:12;	/* -1440 <= tzo <= 1440;
+					   currently only -840 to +840 are needed */
+};
+
+/* Duration value */
+typedef struct _xmlSchemaValDuration xmlSchemaValDuration;
+typedef xmlSchemaValDuration *xmlSchemaValDurationPtr;
+struct _xmlSchemaValDuration {
+    long	        mon;		/* mon stores years also */
+    long        	day;
+    double		sec;            /* sec stores min and hour also */
+};
+
+typedef struct _xmlSchemaValDecimal xmlSchemaValDecimal;
+typedef xmlSchemaValDecimal *xmlSchemaValDecimalPtr;
+struct _xmlSchemaValDecimal {
+    /* would use long long but not portable */
+    unsigned long lo;
+    unsigned long mi;
+    unsigned long hi;
+    unsigned int extra;
+    unsigned int sign:1;
+    unsigned int frac:7;
+    unsigned int total:8;
+};
+
+typedef struct _xmlSchemaValQName xmlSchemaValQName;
+typedef xmlSchemaValQName *xmlSchemaValQNamePtr;
+struct _xmlSchemaValQName {
+    xmlChar *name;
+    xmlChar *uri;
+};
+
+typedef struct _xmlSchemaValHex xmlSchemaValHex;
+typedef xmlSchemaValHex *xmlSchemaValHexPtr;
+struct _xmlSchemaValHex {
+    xmlChar     *str;
+    unsigned int total;
+};
+
+typedef struct _xmlSchemaValBase64 xmlSchemaValBase64;
+typedef xmlSchemaValBase64 *xmlSchemaValBase64Ptr;
+struct _xmlSchemaValBase64 {
+    xmlChar     *str;
+    unsigned int total;
+};
+
+struct _xmlSchemaVal {
+    xmlSchemaValType type;
+    struct _xmlSchemaVal *next;
+    union {
+	xmlSchemaValDecimal     decimal;
+        xmlSchemaValDate        date;
+        xmlSchemaValDuration    dur;
+	xmlSchemaValQName	qname;
+	xmlSchemaValHex		hex;
+	xmlSchemaValBase64	base64;
+	float			f;
+	double			d;
+	int			b;
+	xmlChar                *str;
+    } value;
+};
+
+static int xmlSchemaTypesInitialized = 0;
+static xmlHashTablePtr xmlSchemaTypesBank = NULL;
+
+/*
+ * Basic types
+ */
+static xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL;
+
+/*
+ * Derived types
+ */
+static xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNonPositiveIntegerDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNegativeIntegerDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeIntegerDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeLongDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeIntDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeShortDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeByteDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeUnsignedLongDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeUnsignedIntDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeUnsignedShortDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeUnsignedByteDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNormStringDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeTokenDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeLanguageDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeEntityDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeEntitiesDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNotationDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL;
+
+/************************************************************************
+ *									*
+ * 			Datatype error handlers				*
+ *									*
+ ************************************************************************/
+/**
+ * xmlSchemaTypeErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle an out of memory condition
+ */
+static void
+xmlSchemaTypeErrMemory(xmlNodePtr node, const char *extra)
+{
+    __xmlSimpleError(XML_FROM_DATATYPE, XML_ERR_NO_MEMORY, node, NULL, extra);
+}
+
+/************************************************************************
+ *									*
+ * 			Base types support				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSchemaNewValue:
+ * @type:  the value type
+ *
+ * Allocate a new simple type value
+ *
+ * Returns a pointer to the new value or NULL in case of error
+ */
+static xmlSchemaValPtr
+xmlSchemaNewValue(xmlSchemaValType type) {
+    xmlSchemaValPtr value;
+
+    value = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
+    if (value == NULL) {
+	return(NULL);
+    }
+    memset(value, 0, sizeof(xmlSchemaVal));
+    value->type = type;
+    return(value);
+}
+
+static xmlSchemaFacetPtr
+xmlSchemaNewMinLengthFacet(int value)
+{
+    xmlSchemaFacetPtr ret;
+
+    ret = xmlSchemaNewFacet();
+    if (ret == NULL) {
+        return(NULL);
+    }
+    ret->type = XML_SCHEMA_FACET_MINLENGTH;
+    ret->val = xmlSchemaNewValue(XML_SCHEMAS_NNINTEGER);
+    ret->val->value.decimal.lo = value;
+    return (ret);
+}
+
+/*
+ * xmlSchemaInitBasicType:
+ * @name:  the type name
+ * @type:  the value type associated
+ *
+ * Initialize one primitive built-in type
+ */
+static xmlSchemaTypePtr
+xmlSchemaInitBasicType(const char *name, xmlSchemaValType type, 
+		       xmlSchemaTypePtr baseType) {
+    xmlSchemaTypePtr ret;
+
+    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+    if (ret == NULL) {
+        xmlSchemaTypeErrMemory(NULL, "could not initialize basic types");
+	return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaType));
+    ret->name = (const xmlChar *)name;
+    ret->targetNamespace = XML_SCHEMAS_NAMESPACE_NAME;
+    ret->type = XML_SCHEMA_TYPE_BASIC;
+    ret->baseType = baseType;	
+    ret->contentType = XML_SCHEMA_CONTENT_BASIC;
+    /*
+    * Primitive types.
+    */
+    switch (type) {		
+	case XML_SCHEMAS_STRING:            
+	case XML_SCHEMAS_DECIMAL:    
+	case XML_SCHEMAS_DATE:    
+	case XML_SCHEMAS_DATETIME:    
+	case XML_SCHEMAS_TIME:    
+	case XML_SCHEMAS_GYEAR:    
+	case XML_SCHEMAS_GYEARMONTH:    
+	case XML_SCHEMAS_GMONTH:    
+	case XML_SCHEMAS_GMONTHDAY:    
+	case XML_SCHEMAS_GDAY:    
+	case XML_SCHEMAS_DURATION:    
+	case XML_SCHEMAS_FLOAT:    
+	case XML_SCHEMAS_DOUBLE:    
+	case XML_SCHEMAS_BOOLEAN:    
+	case XML_SCHEMAS_ANYURI:    
+	case XML_SCHEMAS_HEXBINARY:    
+	case XML_SCHEMAS_BASE64BINARY:	
+	case XML_SCHEMAS_QNAME:	
+	case XML_SCHEMAS_NOTATION:	
+	    ret->flags |= XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE;
+	    break;
+	default:
+	    break;
+    }
+    /*
+    * Set variety.
+    */
+    switch (type) {
+	case XML_SCHEMAS_ANYTYPE:
+	case XML_SCHEMAS_ANYSIMPLETYPE:
+	    break;
+	case XML_SCHEMAS_IDREFS:
+	case XML_SCHEMAS_NMTOKENS:
+	case XML_SCHEMAS_ENTITIES:
+	    ret->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
+	    ret->facets = xmlSchemaNewMinLengthFacet(1);
+	    ret->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;	    
+	    break;
+	default:
+	    ret->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
+	    break;
+    }
+    xmlHashAddEntry2(xmlSchemaTypesBank, ret->name,
+	             XML_SCHEMAS_NAMESPACE_NAME, ret);
+    ret->builtInType = type;
+    return(ret);
+}
+
+/*
+* WARNING: Those type reside normally in xmlschemas.c but are
+* redefined here locally in oder of being able to use them for xs:anyType-
+* TODO: Remove those definition if we move the types to a header file.
+* TODO: Always keep those structs up-to-date with the originals.
+*/
+#define UNBOUNDED (1 << 30)
+
+typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
+typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
+struct _xmlSchemaTreeItem {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next;
+    xmlSchemaTreeItemPtr children;
+};
+
+typedef struct _xmlSchemaParticle xmlSchemaParticle;
+typedef xmlSchemaParticle *xmlSchemaParticlePtr;
+struct _xmlSchemaParticle {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next;
+    xmlSchemaTreeItemPtr children;
+    int minOccurs;
+    int maxOccurs;
+    xmlNodePtr node;
+};
+
+typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
+typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
+struct _xmlSchemaModelGroup {
+    xmlSchemaTypeType type;
+    xmlSchemaAnnotPtr annot;
+    xmlSchemaTreeItemPtr next;
+    xmlSchemaTreeItemPtr children;
+    xmlNodePtr node;
+};
+
+static xmlSchemaParticlePtr
+xmlSchemaAddParticle(void)
+{
+    xmlSchemaParticlePtr ret = NULL;
+
+    ret = (xmlSchemaParticlePtr)
+	xmlMalloc(sizeof(xmlSchemaParticle));
+    if (ret == NULL) {
+	xmlSchemaTypeErrMemory(NULL, "allocating particle component");
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaParticle));
+    ret->type = XML_SCHEMA_TYPE_PARTICLE;
+    ret->minOccurs = 1;
+    ret->maxOccurs = 1;
+    return (ret);
+}
+
+/*
+ * xmlSchemaInitTypes:
+ *
+ * Initialize the default XML Schemas type library
+ */
+void
+xmlSchemaInitTypes(void)
+{
+    if (xmlSchemaTypesInitialized != 0)
+        return;
+    xmlSchemaTypesBank = xmlHashCreate(40);
+
+    
+    /*
+    * 3.4.7 Built-in Complex Type Definition
+    */
+    xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType",
+                                                     XML_SCHEMAS_ANYTYPE, 
+						     NULL);
+    xmlSchemaTypeAnyTypeDef->baseType = xmlSchemaTypeAnyTypeDef;
+    xmlSchemaTypeAnyTypeDef->contentType = XML_SCHEMA_CONTENT_MIXED;
+    /*
+    * Init the content type.
+    */
+    xmlSchemaTypeAnyTypeDef->contentType = XML_SCHEMA_CONTENT_MIXED;    
+    {
+	xmlSchemaParticlePtr particle;
+	xmlSchemaModelGroupPtr sequence;
+	xmlSchemaWildcardPtr wild;
+	/* First particle. */
+	particle = xmlSchemaAddParticle();
+	if (particle == NULL)
+	    return;
+	xmlSchemaTypeAnyTypeDef->subtypes = (xmlSchemaTypePtr) particle;
+	/* Sequence model group. */
+	sequence = (xmlSchemaModelGroupPtr)
+	    xmlMalloc(sizeof(xmlSchemaModelGroup));
+	if (sequence == NULL) {
+	    xmlSchemaTypeErrMemory(NULL, "allocating model group component");
+	    return;
+	}
+	memset(sequence, 0, sizeof(xmlSchemaModelGroup));
+	sequence->type = XML_SCHEMA_TYPE_SEQUENCE;	
+	particle->children = (xmlSchemaTreeItemPtr) sequence;
+	/* Second particle. */
+	particle = xmlSchemaAddParticle();
+	if (particle == NULL)
+	    return;
+	particle->minOccurs = 0;
+	particle->maxOccurs = UNBOUNDED;
+	sequence->children = (xmlSchemaTreeItemPtr) particle;
+	/* The wildcard */
+	wild = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
+	if (wild == NULL) {
+	    xmlSchemaTypeErrMemory(NULL, "allocating wildcard component");
+	    return;
+	}
+	memset(wild, 0, sizeof(xmlSchemaWildcard));
+	wild->type = XML_SCHEMA_TYPE_ANY;
+	wild->any = 1;	
+	wild->processContents = XML_SCHEMAS_ANY_LAX;	
+	particle->children = (xmlSchemaTreeItemPtr) wild;    
+	/*
+	* Create the attribute wildcard.
+	*/
+	wild = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
+	if (wild == NULL) {
+	    xmlSchemaTypeErrMemory(NULL, "could not create an attribute "
+		"wildcard on anyType");
+	    return;
+	}
+	memset(wild, 0, sizeof(xmlSchemaWildcard));
+	wild->any = 1;
+	wild->processContents = XML_SCHEMAS_ANY_LAX;	
+	xmlSchemaTypeAnyTypeDef->attributeWildcard = wild;
+    }
+    xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType", 
+                                                           XML_SCHEMAS_ANYSIMPLETYPE,
+							   xmlSchemaTypeAnyTypeDef);
+    /*
+    * primitive datatypes
+    */
+    xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string",
+                                                    XML_SCHEMAS_STRING,
+						    xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal",
+                                                     XML_SCHEMAS_DECIMAL,
+						     xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date",
+                                                  XML_SCHEMAS_DATE,
+						  xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime",
+                                                      XML_SCHEMAS_DATETIME,
+						      xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time",
+                                                  XML_SCHEMAS_TIME,
+						  xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear",
+                                                   XML_SCHEMAS_GYEAR,
+						   xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth",
+                                                        XML_SCHEMAS_GYEARMONTH,
+							xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth",
+                                                    XML_SCHEMAS_GMONTH,
+						    xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay",
+                                                       XML_SCHEMAS_GMONTHDAY,
+						       xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay",
+                                                  XML_SCHEMAS_GDAY,
+						  xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration",
+                                                      XML_SCHEMAS_DURATION,
+						      xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float",
+                                                   XML_SCHEMAS_FLOAT,
+						   xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double",
+                                                    XML_SCHEMAS_DOUBLE,
+						    xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType("boolean",
+                                                     XML_SCHEMAS_BOOLEAN,
+						     xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType("anyURI",
+                                                    XML_SCHEMAS_ANYURI,
+						    xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType("hexBinary",
+                                                     XML_SCHEMAS_HEXBINARY,
+						     xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeBase64BinaryDef
+        = xmlSchemaInitBasicType("base64Binary", XML_SCHEMAS_BASE64BINARY,
+	xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeNotationDef = xmlSchemaInitBasicType("NOTATION",
+                                                    XML_SCHEMAS_NOTATION,
+						    xmlSchemaTypeAnySimpleTypeDef);    
+    xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName",
+                                                   XML_SCHEMAS_QNAME,
+						   xmlSchemaTypeAnySimpleTypeDef);
+
+    /*
+     * derived datatypes
+     */
+    xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType("integer",
+                                                     XML_SCHEMAS_INTEGER,
+						     xmlSchemaTypeDecimalDef);
+    xmlSchemaTypeNonPositiveIntegerDef =
+        xmlSchemaInitBasicType("nonPositiveInteger",
+                               XML_SCHEMAS_NPINTEGER,
+			       xmlSchemaTypeIntegerDef);
+    xmlSchemaTypeNegativeIntegerDef =
+        xmlSchemaInitBasicType("negativeInteger", XML_SCHEMAS_NINTEGER,
+	xmlSchemaTypeNonPositiveIntegerDef);
+    xmlSchemaTypeLongDef =
+        xmlSchemaInitBasicType("long", XML_SCHEMAS_LONG,
+	xmlSchemaTypeIntegerDef);
+    xmlSchemaTypeIntDef = xmlSchemaInitBasicType("int", XML_SCHEMAS_INT,
+	xmlSchemaTypeLongDef);
+    xmlSchemaTypeShortDef = xmlSchemaInitBasicType("short",
+                                                   XML_SCHEMAS_SHORT,
+						   xmlSchemaTypeIntDef);
+    xmlSchemaTypeByteDef = xmlSchemaInitBasicType("byte",
+                                                  XML_SCHEMAS_BYTE,
+						  xmlSchemaTypeShortDef);
+    xmlSchemaTypeNonNegativeIntegerDef =
+        xmlSchemaInitBasicType("nonNegativeInteger",
+                               XML_SCHEMAS_NNINTEGER,
+			       xmlSchemaTypeIntegerDef);
+    xmlSchemaTypeUnsignedLongDef =
+        xmlSchemaInitBasicType("unsignedLong", XML_SCHEMAS_ULONG,
+	xmlSchemaTypeNonNegativeIntegerDef);
+    xmlSchemaTypeUnsignedIntDef =
+        xmlSchemaInitBasicType("unsignedInt", XML_SCHEMAS_UINT,
+	xmlSchemaTypeUnsignedLongDef);
+    xmlSchemaTypeUnsignedShortDef =
+        xmlSchemaInitBasicType("unsignedShort", XML_SCHEMAS_USHORT,
+	xmlSchemaTypeUnsignedIntDef);
+    xmlSchemaTypeUnsignedByteDef =
+        xmlSchemaInitBasicType("unsignedByte", XML_SCHEMAS_UBYTE,
+	xmlSchemaTypeUnsignedShortDef);
+    xmlSchemaTypePositiveIntegerDef =
+        xmlSchemaInitBasicType("positiveInteger", XML_SCHEMAS_PINTEGER,
+	xmlSchemaTypeNonNegativeIntegerDef);
+    xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType("normalizedString",
+                                                        XML_SCHEMAS_NORMSTRING,
+							xmlSchemaTypeStringDef);
+    xmlSchemaTypeTokenDef = xmlSchemaInitBasicType("token",
+                                                   XML_SCHEMAS_TOKEN,
+						   xmlSchemaTypeNormStringDef);
+    xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType("language",
+                                                      XML_SCHEMAS_LANGUAGE,
+						      xmlSchemaTypeTokenDef);
+    xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name",
+                                                  XML_SCHEMAS_NAME,
+						  xmlSchemaTypeTokenDef);
+    xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType("NMTOKEN",
+                                                     XML_SCHEMAS_NMTOKEN,
+						     xmlSchemaTypeTokenDef);
+    xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType("NCName",
+                                                    XML_SCHEMAS_NCNAME,
+						    xmlSchemaTypeNameDef);
+    xmlSchemaTypeIdDef = xmlSchemaInitBasicType("ID", XML_SCHEMAS_ID,
+						    xmlSchemaTypeNCNameDef);
+    xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType("IDREF",
+                                                   XML_SCHEMAS_IDREF,
+						   xmlSchemaTypeNCNameDef);        
+    xmlSchemaTypeEntityDef = xmlSchemaInitBasicType("ENTITY",
+                                                    XML_SCHEMAS_ENTITY,
+						    xmlSchemaTypeNCNameDef);
+    /*
+    * Derived list types.
+    */
+    /* ENTITIES */
+    xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType("ENTITIES",
+                                                      XML_SCHEMAS_ENTITIES,
+						      xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeEntitiesDef->subtypes = xmlSchemaTypeEntityDef;
+    /* IDREFS */
+    xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType("IDREFS",
+                                                    XML_SCHEMAS_IDREFS,
+						    xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeIdrefsDef->subtypes = xmlSchemaTypeIdrefDef;
+
+    /* NMTOKENS */
+    xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType("NMTOKENS",
+                                                      XML_SCHEMAS_NMTOKENS,
+						      xmlSchemaTypeAnySimpleTypeDef);
+    xmlSchemaTypeNmtokensDef->subtypes = xmlSchemaTypeNmtokenDef;
+
+    xmlSchemaTypesInitialized = 1;
+}
+
+/**
+ * xmlSchemaCleanupTypes:
+ *
+ * Cleanup the default XML Schemas type library
+ */
+void	
+xmlSchemaCleanupTypes(void) {
+    if (xmlSchemaTypesInitialized == 0)
+	return;
+    /*
+    * Free xs:anyType.
+    */
+    {
+	xmlSchemaParticlePtr particle;
+	/* Attribute wildcard. */
+	xmlSchemaFreeWildcard(xmlSchemaTypeAnyTypeDef->attributeWildcard);
+	/* Content type. */
+	particle = (xmlSchemaParticlePtr) xmlSchemaTypeAnyTypeDef->subtypes;
+	/* Wildcard. */
+	xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) 
+	    particle->children->children->children);
+	xmlFree((xmlSchemaParticlePtr) particle->children->children);
+	/* Sequence model group. */
+	xmlFree((xmlSchemaModelGroupPtr) particle->children);
+	xmlFree((xmlSchemaParticlePtr) particle);
+	xmlSchemaTypeAnyTypeDef->subtypes = NULL;	
+    }
+    xmlHashFree(xmlSchemaTypesBank, (xmlHashDeallocator) xmlSchemaFreeType);
+    xmlSchemaTypesInitialized = 0;
+}
+
+/**
+ * xmlSchemaIsBuiltInTypeFacet:
+ * @type: the built-in type
+ * @facetType:  the facet type
+ *
+ * Evaluates if a specific facet can be
+ * used in conjunction with a type.
+ *
+ * Returns 1 if the facet can be used with the given built-in type,
+ * 0 otherwise and -1 in case the type is not a built-in type.
+ */
+int
+xmlSchemaIsBuiltInTypeFacet(xmlSchemaTypePtr type, int facetType)
+{
+    if (type == NULL)
+	return (-1);
+    if (type->type != XML_SCHEMA_TYPE_BASIC)
+	return (-1);
+    switch (type->builtInType) {
+	case XML_SCHEMAS_BOOLEAN:
+	    if ((facetType == XML_SCHEMA_FACET_PATTERN) ||
+		(facetType == XML_SCHEMA_FACET_WHITESPACE))
+		return (1);
+	    else
+		return (0);	
+	case XML_SCHEMAS_STRING:
+	case XML_SCHEMAS_NOTATION:
+	case XML_SCHEMAS_QNAME:
+	case XML_SCHEMAS_ANYURI:	    
+	case XML_SCHEMAS_BASE64BINARY:    
+	case XML_SCHEMAS_HEXBINARY:
+	    if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
+		(facetType == XML_SCHEMA_FACET_MINLENGTH) ||
+		(facetType == XML_SCHEMA_FACET_MAXLENGTH) ||
+		(facetType == XML_SCHEMA_FACET_PATTERN) ||
+		(facetType == XML_SCHEMA_FACET_ENUMERATION) ||
+		(facetType == XML_SCHEMA_FACET_WHITESPACE))
+		return (1);
+	    else
+		return (0);
+	case XML_SCHEMAS_DECIMAL:
+	    if ((facetType == XML_SCHEMA_FACET_TOTALDIGITS) ||
+		(facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) ||
+		(facetType == XML_SCHEMA_FACET_PATTERN) ||
+		(facetType == XML_SCHEMA_FACET_WHITESPACE) ||
+		(facetType == XML_SCHEMA_FACET_ENUMERATION) ||
+		(facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MININCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MINEXCLUSIVE))
+		return (1);
+	    else
+		return (0); 
+	case XML_SCHEMAS_TIME:
+	case XML_SCHEMAS_GDAY: 
+	case XML_SCHEMAS_GMONTH:
+	case XML_SCHEMAS_GMONTHDAY: 
+	case XML_SCHEMAS_GYEAR: 
+	case XML_SCHEMAS_GYEARMONTH:
+	case XML_SCHEMAS_DATE:
+	case XML_SCHEMAS_DATETIME:
+	case XML_SCHEMAS_DURATION:
+	case XML_SCHEMAS_FLOAT:
+	case XML_SCHEMAS_DOUBLE:
+	    if ((facetType == XML_SCHEMA_FACET_PATTERN) ||
+		(facetType == XML_SCHEMA_FACET_ENUMERATION) ||
+		(facetType == XML_SCHEMA_FACET_WHITESPACE) ||
+		(facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MININCLUSIVE) ||
+		(facetType == XML_SCHEMA_FACET_MINEXCLUSIVE))
+		return (1);
+	    else
+		return (0);	    				 
+	default:
+	    break;
+    }
+    return (0);
+}
+
+/**
+ * xmlSchemaGetBuiltInType:
+ * @type:  the type of the built in type
+ *
+ * Gives you the type struct for a built-in
+ * type by its type id.
+ *
+ * Returns the type if found, NULL otherwise.
+ */
+xmlSchemaTypePtr
+xmlSchemaGetBuiltInType(xmlSchemaValType type)
+{
+    if (xmlSchemaTypesInitialized == 0)
+	xmlSchemaInitTypes();
+    switch (type) {
+	
+	case XML_SCHEMAS_ANYSIMPLETYPE:
+	    return (xmlSchemaTypeAnySimpleTypeDef);
+	case XML_SCHEMAS_STRING:
+	    return (xmlSchemaTypeStringDef);
+	case XML_SCHEMAS_NORMSTRING:
+	    return (xmlSchemaTypeNormStringDef);
+	case XML_SCHEMAS_DECIMAL:
+	    return (xmlSchemaTypeDecimalDef);
+	case XML_SCHEMAS_TIME:
+	    return (xmlSchemaTypeTimeDef);
+	case XML_SCHEMAS_GDAY:
+	    return (xmlSchemaTypeGDayDef);
+	case XML_SCHEMAS_GMONTH:
+	    return (xmlSchemaTypeGMonthDef);
+	case XML_SCHEMAS_GMONTHDAY:
+    	    return (xmlSchemaTypeGMonthDayDef);
+	case XML_SCHEMAS_GYEAR:
+	    return (xmlSchemaTypeGYearDef);
+	case XML_SCHEMAS_GYEARMONTH:
+	    return (xmlSchemaTypeGYearMonthDef);
+	case XML_SCHEMAS_DATE:
+	    return (xmlSchemaTypeDateDef);
+	case XML_SCHEMAS_DATETIME:
+	    return (xmlSchemaTypeDatetimeDef);
+	case XML_SCHEMAS_DURATION:
+	    return (xmlSchemaTypeDurationDef);
+	case XML_SCHEMAS_FLOAT:
+	    return (xmlSchemaTypeFloatDef);
+	case XML_SCHEMAS_DOUBLE:
+	    return (xmlSchemaTypeDoubleDef);
+	case XML_SCHEMAS_BOOLEAN:
+	    return (xmlSchemaTypeBooleanDef);
+	case XML_SCHEMAS_TOKEN:
+	    return (xmlSchemaTypeTokenDef);
+	case XML_SCHEMAS_LANGUAGE:
+	    return (xmlSchemaTypeLanguageDef);
+	case XML_SCHEMAS_NMTOKEN:
+	    return (xmlSchemaTypeNmtokenDef);
+	case XML_SCHEMAS_NMTOKENS:
+	    return (xmlSchemaTypeNmtokensDef);
+	case XML_SCHEMAS_NAME:
+	    return (xmlSchemaTypeNameDef);
+	case XML_SCHEMAS_QNAME:
+	    return (xmlSchemaTypeQNameDef);
+	case XML_SCHEMAS_NCNAME:
+	    return (xmlSchemaTypeNCNameDef);
+	case XML_SCHEMAS_ID:
+	    return (xmlSchemaTypeIdDef);
+	case XML_SCHEMAS_IDREF:
+	    return (xmlSchemaTypeIdrefDef);
+	case XML_SCHEMAS_IDREFS:
+	    return (xmlSchemaTypeIdrefsDef);
+	case XML_SCHEMAS_ENTITY:
+	    return (xmlSchemaTypeEntityDef);
+	case XML_SCHEMAS_ENTITIES:
+	    return (xmlSchemaTypeEntitiesDef);
+	case XML_SCHEMAS_NOTATION:
+	    return (xmlSchemaTypeNotationDef);
+	case XML_SCHEMAS_ANYURI:
+	    return (xmlSchemaTypeAnyURIDef);
+	case XML_SCHEMAS_INTEGER:
+	    return (xmlSchemaTypeIntegerDef);
+	case XML_SCHEMAS_NPINTEGER:
+	    return (xmlSchemaTypeNonPositiveIntegerDef);
+	case XML_SCHEMAS_NINTEGER:
+	    return (xmlSchemaTypeNegativeIntegerDef);
+	case XML_SCHEMAS_NNINTEGER:
+	    return (xmlSchemaTypeNonNegativeIntegerDef);
+	case XML_SCHEMAS_PINTEGER:
+	    return (xmlSchemaTypePositiveIntegerDef);
+	case XML_SCHEMAS_INT:
+	    return (xmlSchemaTypeIntDef);
+	case XML_SCHEMAS_UINT:
+	    return (xmlSchemaTypeUnsignedIntDef);
+	case XML_SCHEMAS_LONG:
+	    return (xmlSchemaTypeLongDef);
+	case XML_SCHEMAS_ULONG:
+	    return (xmlSchemaTypeUnsignedLongDef);
+	case XML_SCHEMAS_SHORT:
+	    return (xmlSchemaTypeShortDef);
+	case XML_SCHEMAS_USHORT:
+	    return (xmlSchemaTypeUnsignedShortDef);
+	case XML_SCHEMAS_BYTE:
+	    return (xmlSchemaTypeByteDef);
+	case XML_SCHEMAS_UBYTE:
+	    return (xmlSchemaTypeUnsignedByteDef);
+	case XML_SCHEMAS_HEXBINARY:
+	    return (xmlSchemaTypeHexBinaryDef);
+	case XML_SCHEMAS_BASE64BINARY:
+	    return (xmlSchemaTypeBase64BinaryDef);
+	case XML_SCHEMAS_ANYTYPE:
+	    return (xmlSchemaTypeAnyTypeDef);	    
+	default:
+	    return (NULL);
+    }
+}
+
+/**
+ * xmlSchemaValueAppend:
+ * @prev: the value
+ * @cur: the value to be appended
+ *
+ * Appends a next sibling to a list of computed values.
+ *
+ * Returns 0 if succeeded and -1 on API errors.
+ */
+int
+xmlSchemaValueAppend(xmlSchemaValPtr prev, xmlSchemaValPtr cur) {
+
+    if ((prev == NULL) || (cur == NULL))
+	return (-1);
+    prev->next = cur;
+    return (0);
+}
+
+/**
+ * xmlSchemaValueGetNext:
+ * @cur: the value
+ *
+ * Accessor for the next sibling of a list of computed values.
+ *
+ * Returns the next value or NULL if there was none, or on
+ *         API errors.
+ */
+xmlSchemaValPtr
+xmlSchemaValueGetNext(xmlSchemaValPtr cur) {
+
+    if (cur == NULL)
+	return (NULL);
+    return (cur->next);
+}
+
+/**
+ * xmlSchemaValueGetAsString:
+ * @val: the value
+ *
+ * Accessor for the string value of a computed value.
+ *
+ * Returns the string value or NULL if there was none, or on
+ *         API errors.
+ */
+const xmlChar *
+xmlSchemaValueGetAsString(xmlSchemaValPtr val)
+{    
+    if (val == NULL)
+	return (NULL);
+    switch (val->type) {
+	case XML_SCHEMAS_STRING:
+	case XML_SCHEMAS_NORMSTRING:
+	case XML_SCHEMAS_ANYSIMPLETYPE:
+	case XML_SCHEMAS_TOKEN:
+        case XML_SCHEMAS_LANGUAGE:
+        case XML_SCHEMAS_NMTOKEN:
+        case XML_SCHEMAS_NAME:
+        case XML_SCHEMAS_NCNAME:
+        case XML_SCHEMAS_ID:
+        case XML_SCHEMAS_IDREF:
+        case XML_SCHEMAS_ENTITY:
+        case XML_SCHEMAS_ANYURI:
+	    return (BAD_CAST val->value.str);
+	default:
+	    break;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaValueGetAsBoolean:
+ * @val: the value
+ *
+ * Accessor for the boolean value of a computed value.
+ *
+ * Returns 1 if true and 0 if false, or in case of an error. Hmm.
+ */
+int
+xmlSchemaValueGetAsBoolean(xmlSchemaValPtr val)
+{    
+    if ((val == NULL) || (val->type != XML_SCHEMAS_BOOLEAN))
+	return (0);
+    return (val->value.b);
+}
+
+/**
+ * xmlSchemaNewStringValue:
+ * @type:  the value type
+ * @value:  the value
+ *
+ * Allocate a new simple type value. The type can be 
+ * of XML_SCHEMAS_STRING. 
+ * WARNING: This one is intended to be expanded for other
+ * string based types. We need this for anySimpleType as well.
+ * The given value is consumed and freed with the struct.
+ *
+ * Returns a pointer to the new value or NULL in case of error
+ */
+xmlSchemaValPtr
+xmlSchemaNewStringValue(xmlSchemaValType type,
+			const xmlChar *value)
+{
+    xmlSchemaValPtr val;
+
+    if (type != XML_SCHEMAS_STRING)
+	return(NULL);
+    val = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
+    if (val == NULL) {
+	return(NULL);
+    }
+    memset(val, 0, sizeof(xmlSchemaVal));
+    val->type = type;
+    val->value.str = (xmlChar *) value;
+    return(val);
+}
+
+/**
+ * xmlSchemaNewNOTATIONValue:
+ * @name:  the notation name
+ * @ns: the notation namespace name or NULL
+ *
+ * Allocate a new NOTATION value.
+ * The given values are consumed and freed with the struct.
+ *
+ * Returns a pointer to the new value or NULL in case of error
+ */
+xmlSchemaValPtr
+xmlSchemaNewNOTATIONValue(const xmlChar *name,
+			  const xmlChar *ns)
+{
+    xmlSchemaValPtr val;
+
+    val = xmlSchemaNewValue(XML_SCHEMAS_NOTATION);
+    if (val == NULL)
+	return (NULL);
+
+    val->value.qname.name = (xmlChar *)name;
+    if (ns != NULL)
+	val->value.qname.uri = (xmlChar *)ns;
+    return(val);
+}
+
+/**
+ * xmlSchemaNewQNameValue:
+ * @namespaceName: the namespace name
+ * @localName: the local name
+ *
+ * Allocate a new QName value.
+ * The given values are consumed and freed with the struct.
+ *
+ * Returns a pointer to the new value or NULL in case of an error.
+ */
+xmlSchemaValPtr
+xmlSchemaNewQNameValue(const xmlChar *namespaceName,
+		       const xmlChar *localName)
+{
+    xmlSchemaValPtr val;
+
+    val = xmlSchemaNewValue(XML_SCHEMAS_QNAME);
+    if (val == NULL)
+	return (NULL);
+
+    val->value.qname.name = (xmlChar *) localName;
+    val->value.qname.uri = (xmlChar *) namespaceName;
+    return(val);
+}
+
+/**
+ * xmlSchemaFreeValue:
+ * @value:  the value to free
+ *
+ * Cleanup the default XML Schemas type library
+ */
+void	
+xmlSchemaFreeValue(xmlSchemaValPtr value) {
+    xmlSchemaValPtr prev;
+
+    while (value != NULL) {	
+	switch (value->type) {
+	    case XML_SCHEMAS_STRING:
+	    case XML_SCHEMAS_NORMSTRING:
+	    case XML_SCHEMAS_TOKEN:
+	    case XML_SCHEMAS_LANGUAGE:
+	    case XML_SCHEMAS_NMTOKEN:
+	    case XML_SCHEMAS_NMTOKENS:
+	    case XML_SCHEMAS_NAME:
+	    case XML_SCHEMAS_NCNAME:
+	    case XML_SCHEMAS_ID:
+	    case XML_SCHEMAS_IDREF:
+	    case XML_SCHEMAS_IDREFS:
+	    case XML_SCHEMAS_ENTITY:
+	    case XML_SCHEMAS_ENTITIES:        
+	    case XML_SCHEMAS_ANYURI:
+	    case XML_SCHEMAS_ANYSIMPLETYPE:
+		if (value->value.str != NULL)
+		    xmlFree(value->value.str);
+		break;
+	    case XML_SCHEMAS_NOTATION:
+	    case XML_SCHEMAS_QNAME:
+		if (value->value.qname.uri != NULL)
+		    xmlFree(value->value.qname.uri);
+		if (value->value.qname.name != NULL)
+		    xmlFree(value->value.qname.name);
+		break;
+	    case XML_SCHEMAS_HEXBINARY:
+		if (value->value.hex.str != NULL)
+		    xmlFree(value->value.hex.str);
+		break;
+	    case XML_SCHEMAS_BASE64BINARY:
+		if (value->value.base64.str != NULL)
+		    xmlFree(value->value.base64.str);
+		break;
+	    default:
+		break;
+	}
+	prev = value;
+	value = value->next;
+	xmlFree(prev);
+    }    
+}
+
+/**
+ * xmlSchemaGetPredefinedType:
+ * @name: the type name
+ * @ns:  the URI of the namespace usually "http://www.w3.org/2001/XMLSchema"
+ *
+ * Lookup a type in the default XML Schemas type library
+ *
+ * Returns the type if found, NULL otherwise
+ */
+xmlSchemaTypePtr
+xmlSchemaGetPredefinedType(const xmlChar *name, const xmlChar *ns) {
+    if (xmlSchemaTypesInitialized == 0)
+	xmlSchemaInitTypes();
+    if (name == NULL)
+	return(NULL);
+    return((xmlSchemaTypePtr) xmlHashLookup2(xmlSchemaTypesBank, name, ns));
+}
+
+/**
+ * xmlSchemaGetBuiltInListSimpleTypeItemType:
+ * @type: the built-in simple type.
+ *
+ * Lookup function
+ *
+ * Returns the item type of @type as defined by the built-in datatype
+ * hierarchy of XML Schema Part 2: Datatypes, or NULL in case of an error.
+ */
+xmlSchemaTypePtr
+xmlSchemaGetBuiltInListSimpleTypeItemType(xmlSchemaTypePtr type)
+{
+    if ((type == NULL) || (type->type != XML_SCHEMA_TYPE_BASIC))
+	return (NULL);
+    switch (type->builtInType) {
+	case XML_SCHEMAS_NMTOKENS: 
+	    return (xmlSchemaTypeNmtokenDef );
+	case XML_SCHEMAS_IDREFS: 
+	    return (xmlSchemaTypeIdrefDef);
+	case XML_SCHEMAS_ENTITIES:
+	    return (xmlSchemaTypeEntityDef);
+	default:
+	    return (NULL);
+    }
+}
+
+/****************************************************************
+ *								*
+ *		Convenience macros and functions		*
+ *								*
+ ****************************************************************/
+
+#define IS_TZO_CHAR(c)						\
+	((c == 0) || (c == 'Z') || (c == '+') || (c == '-'))
+
+#define VALID_YEAR(yr)          (yr != 0)
+#define VALID_MONTH(mon)        ((mon >= 1) && (mon <= 12))
+/* VALID_DAY should only be used when month is unknown */
+#define VALID_DAY(day)          ((day >= 1) && (day <= 31))
+#define VALID_HOUR(hr)          ((hr >= 0) && (hr <= 23))
+#define VALID_MIN(min)          ((min >= 0) && (min <= 59))
+#define VALID_SEC(sec)          ((sec >= 0) && (sec < 60))
+#define VALID_TZO(tzo)          ((tzo > -840) && (tzo < 840))
+#define IS_LEAP(y)						\
+	(((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
+
+static const unsigned int daysInMonth[12] =
+	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static const unsigned int daysInMonthLeap[12] =
+	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+#define MAX_DAYINMONTH(yr,mon)                                  \
+        (IS_LEAP(yr) ? daysInMonthLeap[mon - 1] : daysInMonth[mon - 1])
+
+#define VALID_MDAY(dt)						\
+	(IS_LEAP(dt->year) ?				        \
+	    (dt->day <= daysInMonthLeap[dt->mon - 1]) :	        \
+	    (dt->day <= daysInMonth[dt->mon - 1]))
+
+#define VALID_DATE(dt)						\
+	(VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
+
+#define VALID_TIME(dt)						\
+	(VALID_HOUR(dt->hour) && VALID_MIN(dt->min) &&		\
+	 VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
+
+#define VALID_DATETIME(dt)					\
+	(VALID_DATE(dt) && VALID_TIME(dt))
+
+#define SECS_PER_MIN            (60)
+#define SECS_PER_HOUR           (60 * SECS_PER_MIN)
+#define SECS_PER_DAY            (24 * SECS_PER_HOUR)
+
+static const long dayInYearByMonth[12] =
+	{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+static const long dayInLeapYearByMonth[12] =
+	{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+#define DAY_IN_YEAR(day, month, year)				\
+        ((IS_LEAP(year) ?					\
+                dayInLeapYearByMonth[month - 1] :		\
+                dayInYearByMonth[month - 1]) + day)
+
+#ifdef DEBUG
+#define DEBUG_DATE(dt)                                                  \
+    xmlGenericError(xmlGenericErrorContext,                             \
+        "type=%o %04ld-%02u-%02uT%02u:%02u:%03f",                       \
+        dt->type,dt->value.date.year,dt->value.date.mon,                \
+        dt->value.date.day,dt->value.date.hour,dt->value.date.min,      \
+        dt->value.date.sec);                                            \
+    if (dt->value.date.tz_flag)                                         \
+        if (dt->value.date.tzo != 0)                                    \
+            xmlGenericError(xmlGenericErrorContext,                     \
+                "%+05d\n",dt->value.date.tzo);                          \
+        else                                                            \
+            xmlGenericError(xmlGenericErrorContext, "Z\n");             \
+    else                                                                \
+        xmlGenericError(xmlGenericErrorContext,"\n")
+#else
+#define DEBUG_DATE(dt)
+#endif
+
+/**
+ * _xmlSchemaParseGYear:
+ * @dt:  pointer to a date structure
+ * @str: pointer to the string to analyze
+ *
+ * Parses a xs:gYear without time zone and fills in the appropriate
+ * field of the @dt structure. @str is updated to point just after the
+ * xs:gYear. It is supposed that @dt->year is big enough to contain
+ * the year.
+ *
+ * Returns 0 or the error code
+ */
+static int
+_xmlSchemaParseGYear (xmlSchemaValDatePtr dt, const xmlChar **str) {
+    const xmlChar *cur = *str, *firstChar;
+    int isneg = 0, digcnt = 0;
+
+    if (((*cur < '0') || (*cur > '9')) &&
+	(*cur != '-') && (*cur != '+'))
+	return -1;
+
+    if (*cur == '-') {
+	isneg = 1;
+	cur++;
+    }
+
+    firstChar = cur;
+
+    while ((*cur >= '0') && (*cur <= '9')) {
+	dt->year = dt->year * 10 + (*cur - '0');
+	cur++;
+	digcnt++;
+    }
+
+    /* year must be at least 4 digits (CCYY); over 4
+     * digits cannot have a leading zero. */
+    if ((digcnt < 4) || ((digcnt > 4) && (*firstChar == '0')))
+	return 1;
+
+    if (isneg)
+	dt->year = - dt->year;
+
+    if (!VALID_YEAR(dt->year))
+	return 2;
+
+    *str = cur;
+    return 0;
+}
+
+/**
+ * PARSE_2_DIGITS:
+ * @num:  the integer to fill in
+ * @cur:  an #xmlChar *
+ * @invalid: an integer
+ *
+ * Parses a 2-digits integer and updates @num with the value. @cur is
+ * updated to point just after the integer.
+ * In case of error, @invalid is set to %TRUE, values of @num and
+ * @cur are undefined.
+ */
+#define PARSE_2_DIGITS(num, cur, invalid)			\
+	if ((cur[0] < '0') || (cur[0] > '9') ||			\
+	    (cur[1] < '0') || (cur[1] > '9'))			\
+	    invalid = 1;					\
+	else							\
+	    num = (cur[0] - '0') * 10 + (cur[1] - '0');		\
+	cur += 2;
+
+/**
+ * PARSE_FLOAT:
+ * @num:  the double to fill in
+ * @cur:  an #xmlChar *
+ * @invalid: an integer
+ *
+ * Parses a float and updates @num with the value. @cur is
+ * updated to point just after the float. The float must have a
+ * 2-digits integer part and may or may not have a decimal part.
+ * In case of error, @invalid is set to %TRUE, values of @num and
+ * @cur are undefined.
+ */
+#define PARSE_FLOAT(num, cur, invalid)				\
+	PARSE_2_DIGITS(num, cur, invalid);			\
+	if (!invalid && (*cur == '.')) {			\
+	    double mult = 1;				        \
+	    cur++;						\
+	    if ((*cur < '0') || (*cur > '9'))			\
+		invalid = 1;					\
+	    while ((*cur >= '0') && (*cur <= '9')) {		\
+		mult /= 10;					\
+		num += (*cur - '0') * mult;			\
+		cur++;						\
+	    }							\
+	}
+
+/**
+ * _xmlSchemaParseGMonth:
+ * @dt:  pointer to a date structure
+ * @str: pointer to the string to analyze
+ *
+ * Parses a xs:gMonth without time zone and fills in the appropriate
+ * field of the @dt structure. @str is updated to point just after the
+ * xs:gMonth.
+ *
+ * Returns 0 or the error code
+ */
+static int
+_xmlSchemaParseGMonth (xmlSchemaValDatePtr dt, const xmlChar **str) {
+    const xmlChar *cur = *str;
+    int ret = 0;
+    unsigned int value = 0;
+
+    PARSE_2_DIGITS(value, cur, ret);
+    if (ret != 0)
+	return ret;
+
+    if (!VALID_MONTH(value))
+	return 2;
+
+    dt->mon = value;
+
+    *str = cur;
+    return 0;
+}
+
+/**
+ * _xmlSchemaParseGDay:
+ * @dt:  pointer to a date structure
+ * @str: pointer to the string to analyze
+ *
+ * Parses a xs:gDay without time zone and fills in the appropriate
+ * field of the @dt structure. @str is updated to point just after the
+ * xs:gDay.
+ *
+ * Returns 0 or the error code
+ */
+static int
+_xmlSchemaParseGDay (xmlSchemaValDatePtr dt, const xmlChar **str) {
+    const xmlChar *cur = *str;
+    int ret = 0;
+    unsigned int value = 0;
+
+    PARSE_2_DIGITS(value, cur, ret);
+    if (ret != 0)
+	return ret;
+
+    if (!VALID_DAY(value))
+	return 2;
+
+    dt->day = value;
+    *str = cur;
+    return 0;
+}
+
+/**
+ * _xmlSchemaParseTime:
+ * @dt:  pointer to a date structure
+ * @str: pointer to the string to analyze
+ *
+ * Parses a xs:time without time zone and fills in the appropriate
+ * fields of the @dt structure. @str is updated to point just after the
+ * xs:time.
+ * In case of error, values of @dt fields are undefined.
+ *
+ * Returns 0 or the error code
+ */
+static int
+_xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) {
+    const xmlChar *cur = *str;    
+    int ret = 0;
+    int value = 0;
+
+    PARSE_2_DIGITS(value, cur, ret);
+    if (ret != 0)
+	return ret;    
+    if (*cur != ':')
+	return 1;
+    if (!VALID_HOUR(value))
+	return 2;
+    cur++;
+
+    /* the ':' insures this string is xs:time */
+    dt->hour = value;
+
+    PARSE_2_DIGITS(value, cur, ret);
+    if (ret != 0)
+	return ret;
+    if (!VALID_MIN(value))
+	return 2;
+    dt->min = value;
+
+    if (*cur != ':')
+	return 1;
+    cur++;
+
+    PARSE_FLOAT(dt->sec, cur, ret);
+    if (ret != 0)
+	return ret;
+
+    if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo)))
+	return 2;
+
+    *str = cur;
+    return 0;
+}
+
+/**
+ * _xmlSchemaParseTimeZone:
+ * @dt:  pointer to a date structure
+ * @str: pointer to the string to analyze
+ *
+ * Parses a time zone without time zone and fills in the appropriate
+ * field of the @dt structure. @str is updated to point just after the
+ * time zone.
+ *
+ * Returns 0 or the error code
+ */
+static int
+_xmlSchemaParseTimeZone (xmlSchemaValDatePtr dt, const xmlChar **str) {
+    const xmlChar *cur;
+    int ret = 0;
+
+    if (str == NULL)
+	return -1;
+    cur = *str;
+
+    switch (*cur) {
+    case 0:
+	dt->tz_flag = 0;
+	dt->tzo = 0;
+	break;
+
+    case 'Z':
+	dt->tz_flag = 1;
+	dt->tzo = 0;
+	cur++;
+	break;
+
+    case '+':
+    case '-': {
+	int isneg = 0, tmp = 0;
+	isneg = (*cur == '-');
+
+	cur++;
+
+	PARSE_2_DIGITS(tmp, cur, ret);
+	if (ret != 0)
+	    return ret;
+	if (!VALID_HOUR(tmp))
+	    return 2;
+
+	if (*cur != ':')
+	    return 1;
+	cur++;
+
+	dt->tzo = tmp * 60;
+
+	PARSE_2_DIGITS(tmp, cur, ret);
+	if (ret != 0)
+	    return ret;
+	if (!VALID_MIN(tmp))
+	    return 2;
+
+	dt->tzo += tmp;
+	if (isneg)
+	    dt->tzo = - dt->tzo;
+
+	if (!VALID_TZO(dt->tzo))
+	    return 2;
+
+	dt->tz_flag = 1;
+	break;
+      }
+    default:
+	return 1;
+    }
+
+    *str = cur;
+    return 0;
+}
+
+/**
+ * _xmlSchemaBase64Decode:
+ * @ch: a character
+ *
+ * Converts a base64 encoded character to its base 64 value.
+ *
+ * Returns 0-63 (value), 64 (pad), or -1 (not recognized)
+ */
+static int
+_xmlSchemaBase64Decode (const xmlChar ch) {
+    if (('A' <= ch) && (ch <= 'Z')) return ch - 'A';
+    if (('a' <= ch) && (ch <= 'z')) return ch - 'a' + 26;
+    if (('0' <= ch) && (ch <= '9')) return ch - '0' + 52;
+    if ('+' == ch) return 62;
+    if ('/' == ch) return 63;
+    if ('=' == ch) return 64;
+    return -1;
+}
+
+/****************************************************************
+ *								*
+ *	XML Schema Dates/Times Datatypes Handling		*
+ *								*
+ ****************************************************************/
+
+/**
+ * PARSE_DIGITS:
+ * @num:  the integer to fill in
+ * @cur:  an #xmlChar *
+ * @num_type: an integer flag
+ *
+ * Parses a digits integer and updates @num with the value. @cur is
+ * updated to point just after the integer.
+ * In case of error, @num_type is set to -1, values of @num and
+ * @cur are undefined.
+ */
+#define PARSE_DIGITS(num, cur, num_type)	                \
+	if ((*cur < '0') || (*cur > '9'))			\
+	    num_type = -1;					\
+        else                                                    \
+	    while ((*cur >= '0') && (*cur <= '9')) {		\
+	        num = num * 10 + (*cur - '0');		        \
+	        cur++;                                          \
+            }
+
+/**
+ * PARSE_NUM:
+ * @num:  the double to fill in
+ * @cur:  an #xmlChar *
+ * @num_type: an integer flag
+ *
+ * Parses a float or integer and updates @num with the value. @cur is
+ * updated to point just after the number. If the number is a float,
+ * then it must have an integer part and a decimal part; @num_type will
+ * be set to 1. If there is no decimal part, @num_type is set to zero.
+ * In case of error, @num_type is set to -1, values of @num and
+ * @cur are undefined.
+ */
+#define PARSE_NUM(num, cur, num_type)				\
+        num = 0;                                                \
+	PARSE_DIGITS(num, cur, num_type);	                \
+	if (!num_type && (*cur == '.')) {			\
+	    double mult = 1;				        \
+	    cur++;						\
+	    if ((*cur < '0') || (*cur > '9'))			\
+		num_type = -1;					\
+            else                                                \
+                num_type = 1;                                   \
+	    while ((*cur >= '0') && (*cur <= '9')) {		\
+		mult /= 10;					\
+		num += (*cur - '0') * mult;			\
+		cur++;						\
+	    }							\
+	}
+
+/**
+ * xmlSchemaValidateDates:
+ * @type: the expected type or XML_SCHEMAS_UNKNOWN
+ * @dateTime:  string to analyze
+ * @val:  the return computed value
+ *
+ * Check that @dateTime conforms to the lexical space of one of the date types.
+ * if true a value is computed and returned in @val.
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateDates (xmlSchemaValType type,
+	                const xmlChar *dateTime, xmlSchemaValPtr *val,
+			int collapse) {
+    xmlSchemaValPtr dt;
+    int ret;
+    const xmlChar *cur = dateTime;
+
+#define RETURN_TYPE_IF_VALID(t)					\
+    if (IS_TZO_CHAR(*cur)) {					\
+	ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur);	\
+	if (ret == 0) {						\
+	    if (*cur != 0)					\
+		goto error;					\
+	    dt->type = t;					\
+	    goto done;						\
+	}							\
+    }
+
+    if (dateTime == NULL)
+	return -1;
+
+    if (collapse)
+	while IS_WSP_BLANK_CH(*cur) cur++;
+
+    if ((*cur != '-') && (*cur < '0') && (*cur > '9'))
+	return 1;
+
+    dt = xmlSchemaNewValue(XML_SCHEMAS_UNKNOWN);
+    if (dt == NULL)
+	return -1;
+
+    if ((cur[0] == '-') && (cur[1] == '-')) {
+	/*
+	 * It's an incomplete date (xs:gMonthDay, xs:gMonth or
+	 * xs:gDay)
+	 */
+	cur += 2;
+
+	/* is it an xs:gDay? */
+	if (*cur == '-') {
+	    if (type == XML_SCHEMAS_GMONTH)
+		goto error;
+	  ++cur;
+	    ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
+	    if (ret != 0)
+		goto error;
+
+	    RETURN_TYPE_IF_VALID(XML_SCHEMAS_GDAY);
+
+	    goto error;
+	}
+
+	/*
+	 * it should be an xs:gMonthDay or xs:gMonth
+	 */
+	ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
+	if (ret != 0)
+	    goto error;
+
+        /*
+         * a '-' char could indicate this type is xs:gMonthDay or
+         * a negative time zone offset. Check for xs:gMonthDay first.
+         * Also the first three char's of a negative tzo (-MM:SS) can
+         * appear to be a valid day; so even if the day portion
+         * of the xs:gMonthDay verifies, we must insure it was not
+         * a tzo.
+         */
+        if (*cur == '-') {
+            const xmlChar *rewnd = cur;
+            cur++;
+
+  	    ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
+            if ((ret == 0) && ((*cur == 0) || (*cur != ':'))) {
+
+                /*
+                 * we can use the VALID_MDAY macro to validate the month
+                 * and day because the leap year test will flag year zero
+                 * as a leap year (even though zero is an invalid year).
+		 * FUTURE TODO: Zero will become valid in XML Schema 1.1
+		 * probably.
+                 */
+                if (VALID_MDAY((&(dt->value.date)))) {
+
+	            RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTHDAY);
+
+                    goto error;
+                }
+            }
+
+            /*
+             * not xs:gMonthDay so rewind and check if just xs:gMonth
+             * with an optional time zone.
+             */
+            cur = rewnd;
+        }
+
+	RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTH);
+
+	goto error;
+    }
+
+    /*
+     * It's a right-truncated date or an xs:time.
+     * Try to parse an xs:time then fallback on right-truncated dates.
+     */
+    if ((*cur >= '0') && (*cur <= '9')) {
+	ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
+	if (ret == 0) {
+	    /* it's an xs:time */
+	    RETURN_TYPE_IF_VALID(XML_SCHEMAS_TIME);
+	}
+    }
+
+    /* fallback on date parsing */
+    cur = dateTime;
+
+    ret = _xmlSchemaParseGYear(&(dt->value.date), &cur);
+    if (ret != 0)
+	goto error;
+
+    /* is it an xs:gYear? */
+    RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEAR);
+
+    if (*cur != '-')
+	goto error;
+    cur++;
+
+    ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
+    if (ret != 0)
+	goto error;
+
+    /* is it an xs:gYearMonth? */
+    RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEARMONTH);
+
+    if (*cur != '-')
+	goto error;
+    cur++;
+
+    ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
+    if ((ret != 0) || !VALID_DATE((&(dt->value.date))))
+	goto error;
+
+    /* is it an xs:date? */
+    RETURN_TYPE_IF_VALID(XML_SCHEMAS_DATE);
+
+    if (*cur != 'T')
+	goto error;
+    cur++;
+
+    /* it should be an xs:dateTime */
+    ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
+    if (ret != 0)
+	goto error;
+
+    ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur);
+    if (collapse)
+	while IS_WSP_BLANK_CH(*cur) cur++;
+    if ((ret != 0) || (*cur != 0) || (!(VALID_DATETIME((&(dt->value.date))))))
+	goto error;
+
+
+    dt->type = XML_SCHEMAS_DATETIME;
+
+done:
+#if 1
+    if ((type != XML_SCHEMAS_UNKNOWN) && (type != dt->type))
+        goto error;
+#else
+    /*
+     * insure the parsed type is equal to or less significant (right
+     * truncated) than the desired type.
+     */
+    if ((type != XML_SCHEMAS_UNKNOWN) && (type != dt->type)) {
+
+        /* time only matches time */
+        if ((type == XML_SCHEMAS_TIME) && (dt->type == XML_SCHEMAS_TIME))
+            goto error;
+
+        if ((type == XML_SCHEMAS_DATETIME) &&
+            ((dt->type != XML_SCHEMAS_DATE) ||
+             (dt->type != XML_SCHEMAS_GYEARMONTH) ||
+             (dt->type != XML_SCHEMAS_GYEAR)))
+            goto error;
+
+        if ((type == XML_SCHEMAS_DATE) &&
+            ((dt->type != XML_SCHEMAS_GYEAR) ||
+             (dt->type != XML_SCHEMAS_GYEARMONTH)))
+            goto error;
+
+        if ((type == XML_SCHEMAS_GYEARMONTH) && (dt->type != XML_SCHEMAS_GYEAR))
+            goto error;
+
+        if ((type == XML_SCHEMAS_GMONTHDAY) && (dt->type != XML_SCHEMAS_GMONTH))
+            goto error;
+    }
+#endif
+
+    if (val != NULL)
+        *val = dt;
+    else
+	xmlSchemaFreeValue(dt);
+
+    return 0;
+
+error:
+    if (dt != NULL)
+	xmlSchemaFreeValue(dt);
+    return 1;
+}
+
+/**
+ * xmlSchemaValidateDuration:
+ * @type: the predefined type
+ * @duration:  string to analyze
+ * @val:  the return computed value
+ *
+ * Check that @duration conforms to the lexical space of the duration type.
+ * if true a value is computed and returned in @val.
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
+	                   const xmlChar *duration, xmlSchemaValPtr *val,
+			   int collapse) {
+    const xmlChar  *cur = duration;
+    xmlSchemaValPtr dur;
+    int isneg = 0;
+    unsigned int seq = 0;
+    double         num;
+    int            num_type = 0;  /* -1 = invalid, 0 = int, 1 = floating */
+    const xmlChar  desig[]  = {'Y', 'M', 'D', 'H', 'M', 'S'};
+    const double   multi[]  = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0};
+
+    if (duration == NULL)
+	return -1;
+
+    if (collapse)
+	while IS_WSP_BLANK_CH(*cur) cur++;
+
+    if (*cur == '-') {
+        isneg = 1;
+        cur++;
+    }
+
+    /* duration must start with 'P' (after sign) */
+    if (*cur++ != 'P')
+	return 1;
+
+    if (*cur == 0)
+	return 1;
+
+    dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
+    if (dur == NULL)
+	return -1;
+
+    while (*cur != 0) {
+
+        /* input string should be empty or invalid date/time item */
+        if (seq >= sizeof(desig))
+            goto error;
+
+        /* T designator must be present for time items */
+        if (*cur == 'T') {
+            if (seq <= 3) {
+                seq = 3;
+                cur++;
+            } else
+                return 1;
+        } else if (seq == 3)
+            goto error;
+
+        /* parse the number portion of the item */
+        PARSE_NUM(num, cur, num_type);
+
+        if ((num_type == -1) || (*cur == 0))
+            goto error;
+
+        /* update duration based on item type */
+        while (seq < sizeof(desig)) {
+            if (*cur == desig[seq]) {
+
+                /* verify numeric type; only seconds can be float */
+                if ((num_type != 0) && (seq < (sizeof(desig)-1)))
+                    goto error;
+
+                switch (seq) {
+                    case 0:
+                        dur->value.dur.mon = (long)num * 12;
+                        break;
+                    case 1:
+                        dur->value.dur.mon += (long)num;
+                        break;
+                    default:
+                        /* convert to seconds using multiplier */
+                        dur->value.dur.sec += num * multi[seq];
+                        seq++;
+                        break;
+                }
+
+                break;          /* exit loop */
+            }
+            /* no date designators found? */
+            if ((++seq == 3) || (seq == 6))
+                goto error;
+        }
+	cur++;
+	if (collapse)
+	    while IS_WSP_BLANK_CH(*cur) cur++;        
+    }
+
+    if (isneg) {
+        dur->value.dur.mon = -dur->value.dur.mon;
+        dur->value.dur.day = -dur->value.dur.day;
+        dur->value.dur.sec = -dur->value.dur.sec;
+    }
+
+    if (val != NULL)
+        *val = dur;
+    else
+	xmlSchemaFreeValue(dur);
+
+    return 0;
+
+error:
+    if (dur != NULL)
+	xmlSchemaFreeValue(dur);
+    return 1;
+}
+
+/**
+ * xmlSchemaStrip:
+ * @value: a value
+ *
+ * Removes the leading and ending spaces of a string
+ *
+ * Returns the new string or NULL if no change was required.
+ */
+static xmlChar *
+xmlSchemaStrip(const xmlChar *value) {
+    const xmlChar *start = value, *end, *f;
+
+    if (value == NULL) return(NULL);
+    while ((*start != 0) && (IS_BLANK_CH(*start))) start++;
+    end = start;
+    while (*end != 0) end++;
+    f = end;
+    end--;
+    while ((end > start) && (IS_BLANK_CH(*end))) end--;
+    end++;
+    if ((start == value) && (f == end)) return(NULL);
+    return(xmlStrndup(start, end - start));
+}
+
+/**
+ * xmlSchemaWhiteSpaceReplace:
+ * @value: a value
+ *
+ * Replaces 0xd, 0x9 and 0xa with a space.
+ *
+ * Returns the new string or NULL if no change was required.
+ */
+xmlChar *
+xmlSchemaWhiteSpaceReplace(const xmlChar *value) {
+    const xmlChar *cur = value;    
+    xmlChar *ret = NULL, *mcur; 
+
+    if (value == NULL) 
+	return(NULL);
+    
+    while ((*cur != 0) && 
+	(((*cur) != 0xd) && ((*cur) != 0x9) && ((*cur) != 0xa))) {
+	cur++;
+    }
+    if (*cur == 0)
+	return (NULL);
+    ret = xmlStrdup(value);
+    /* TODO FIXME: I guess gcc will bark at this. */
+    mcur = (xmlChar *)  (ret + (cur - value));
+    do {
+	if ( ((*mcur) == 0xd) || ((*mcur) == 0x9) || ((*mcur) == 0xa) )
+	    *mcur = ' ';
+	mcur++;
+    } while (*mcur != 0);	    
+    return(ret);
+}
+
+/**
+ * xmlSchemaCollapseString:
+ * @value: a value
+ *
+ * Removes and normalize white spaces in the string
+ *
+ * Returns the new string or NULL if no change was required.
+ */
+xmlChar *
+xmlSchemaCollapseString(const xmlChar *value) {
+    const xmlChar *start = value, *end, *f;
+    xmlChar *g;
+    int col = 0;
+
+    if (value == NULL) return(NULL);
+    while ((*start != 0) && (IS_BLANK_CH(*start))) start++;
+    end = start;
+    while (*end != 0) {
+	if ((*end == ' ') && (IS_BLANK_CH(end[1]))) {
+	    col = end - start;
+	    break;
+	} else if ((*end == 0xa) || (*end == 0x9) || (*end == 0xd)) {
+	    col = end - start;
+	    break;
+	}
+	end++;
+    }
+    if (col == 0) {
+	f = end;
+	end--;
+	while ((end > start) && (IS_BLANK_CH(*end))) end--;
+	end++;
+	if ((start == value) && (f == end)) return(NULL);
+	return(xmlStrndup(start, end - start));
+    }
+    start = xmlStrdup(start);
+    if (start == NULL) return(NULL);
+    g = (xmlChar *) (start + col);
+    end = g;
+    while (*end != 0) {
+	if (IS_BLANK_CH(*end)) {
+	    end++;
+	    while (IS_BLANK_CH(*end)) end++;
+	    if (*end != 0)
+		*g++ = ' ';
+	} else
+	    *g++ = *end++;
+    }
+    *g = 0;
+    return((xmlChar *) start);
+}
+
+/**
+ * xmlSchemaValAtomicListNode:
+ * @type: the predefined atomic type for a token in the list
+ * @value: the list value to check
+ * @ret:  the return computed value
+ * @node:  the node containing the value
+ *
+ * Check that a value conforms to the lexical space of the predefined
+ * list type. if true a value is computed and returned in @ret.
+ *
+ * Returns the number of items if this validates, a negative error code
+ *         number otherwise
+ */
+static int
+xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value,
+	                   xmlSchemaValPtr *ret, xmlNodePtr node) {
+    xmlChar *val, *cur, *endval;
+    int nb_values = 0;
+    int tmp = 0;
+
+    if (value == NULL) {
+	return(-1);
+    }
+    val = xmlStrdup(value);
+    if (val == NULL) {
+	return(-1);
+    }
+    if (ret != NULL) {
+        *ret = NULL;
+    }
+    cur = val;
+    /*
+     * Split the list
+     */
+    while (IS_BLANK_CH(*cur)) *cur++ = 0;
+    while (*cur != 0) {
+	if (IS_BLANK_CH(*cur)) {
+	    *cur = 0;
+	    cur++;
+	    while (IS_BLANK_CH(*cur)) *cur++ = 0;
+	} else {
+	    nb_values++;
+	    cur++;
+	    while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
+	}
+    }
+    if (nb_values == 0) {
+	xmlFree(val);
+	return(nb_values);
+    }
+    endval = cur;
+    cur = val;
+    while ((*cur == 0) && (cur != endval)) cur++;
+    while (cur != endval) {
+	tmp = xmlSchemaValPredefTypeNode(type, cur, NULL, node);
+	if (tmp != 0)
+	    break;
+	while (*cur != 0) cur++;
+	while ((*cur == 0) && (cur != endval)) cur++;
+    }
+    /* TODO what return value ? c.f. bug #158628
+    if (ret != NULL) {
+	TODO
+    } */
+    xmlFree(val);
+    if (tmp == 0)
+	return(nb_values);
+    return(-1);
+}
+
+/**
+ * xmlSchemaParseUInt:
+ * @str: pointer to the string R/W
+ * @llo: pointer to the low result
+ * @lmi: pointer to the mid result
+ * @lhi: pointer to the high result
+ *
+ * Parse an unsigned long into 3 fields.
+ *
+ * Returns the number of significant digits in the number or
+ * -1 if overflow of the capacity and -2 if it's not a number.
+ */
+static int
+xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo,
+                   unsigned long *lmi, unsigned long *lhi) {
+    unsigned long lo = 0, mi = 0, hi = 0;
+    const xmlChar *tmp, *cur = *str;
+    int ret = 0, i = 0;
+
+    if (!((*cur >= '0') && (*cur <= '9'))) 
+        return(-2);
+
+    while (*cur == '0') {        /* ignore leading zeroes */
+        cur++;
+    }
+    tmp = cur;
+    while ((*tmp != 0) && (*tmp >= '0') && (*tmp <= '9')) {
+        i++;tmp++;ret++;
+    }
+    if (i > 24) {
+        *str = tmp;
+        return(-1);
+    }
+    while (i > 16) {
+        hi = hi * 10 + (*cur++ - '0');
+        i--;
+    }
+    while (i > 8) {
+        mi = mi * 10 + (*cur++ - '0');
+        i--;
+    }
+    while (i > 0) {
+        lo = lo * 10 + (*cur++ - '0');
+        i--;
+    }
+
+    *str = cur;
+    *llo = lo;
+    *lmi = mi;
+    *lhi = hi;
+    return(ret);
+}
+
+/**
+ * xmlSchemaValAtomicType:
+ * @type: the predefined type
+ * @value: the value to check
+ * @val:  the return computed value
+ * @node:  the node containing the value
+ * flags:  flags to control the vlidation
+ *
+ * Check that a value conforms to the lexical space of the atomic type.
+ * if true a value is computed and returned in @val.
+ * This checks the value space for list types as well (IDREFS, NMTOKENS).
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
+                       xmlSchemaValPtr * val, xmlNodePtr node, int flags,
+		       xmlSchemaWhitespaceValueType ws,
+		       int normOnTheFly, int applyNorm, int createStringValue)
+{
+    xmlSchemaValPtr v;
+    xmlChar *norm = NULL;
+    int ret = 0;
+
+    if (xmlSchemaTypesInitialized == 0)
+        xmlSchemaInitTypes();
+    if (type == NULL)
+        return (-1);
+
+    /*
+     * validating a non existant text node is similar to validating
+     * an empty one.
+     */
+    if (value == NULL)
+        value = BAD_CAST "";
+
+    if (val != NULL)
+        *val = NULL;
+    if ((flags == 0) && (value != NULL)) {
+
+        if ((type->builtInType != XML_SCHEMAS_STRING) &&
+	  (type->builtInType != XML_SCHEMAS_ANYTYPE) && 
+	  (type->builtInType != XML_SCHEMAS_ANYSIMPLETYPE)) {
+	    if (type->builtInType == XML_SCHEMAS_NORMSTRING)
+		norm = xmlSchemaWhiteSpaceReplace(value);
+            else
+		norm = xmlSchemaCollapseString(value);
+            if (norm != NULL)
+                value = norm;
+        }
+    }
+
+    switch (type->builtInType) {
+        case XML_SCHEMAS_UNKNOWN:            
+            goto error;
+	case XML_SCHEMAS_ANYTYPE:
+	case XML_SCHEMAS_ANYSIMPLETYPE:
+	    if ((createStringValue) && (val != NULL)) {
+		v = xmlSchemaNewValue(XML_SCHEMAS_ANYSIMPLETYPE);
+		if (v != NULL) {
+		    v->value.str = xmlStrdup(value);
+		    *val = v;
+		} else {
+		    goto error;
+		}		
+	    }
+	    goto return0;
+        case XML_SCHEMAS_STRING:		
+	    if (! normOnTheFly) {
+		const xmlChar *cur = value;
+
+		if (ws == XML_SCHEMA_WHITESPACE_REPLACE) {
+		    while (*cur != 0) {
+			if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
+			    goto return1;
+			} else {
+			    cur++;
+			}
+		    }
+		} else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
+		    while (*cur != 0) {
+			if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
+			    goto return1;
+			} else if IS_WSP_SPACE_CH(*cur) {
+			    cur++;
+			    if IS_WSP_SPACE_CH(*cur)
+				goto return1;
+			} else {
+			    cur++;
+			}
+		    }
+		}
+	    }
+	    if (createStringValue && (val != NULL)) {
+		if (applyNorm) {
+		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			norm = xmlSchemaCollapseString(value);
+		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
+			norm = xmlSchemaWhiteSpaceReplace(value);
+		    if (norm != NULL)
+			value = norm;
+		}
+		v = xmlSchemaNewValue(XML_SCHEMAS_STRING);
+		if (v != NULL) {
+		    v->value.str = xmlStrdup(value);
+		    *val = v;
+		} else {
+		    goto error;
+		}
+	    }
+            goto return0;
+        case XML_SCHEMAS_NORMSTRING:{
+		if (normOnTheFly) {
+		    if (applyNorm) {
+			if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			    norm = xmlSchemaCollapseString(value);
+			else
+			    norm = xmlSchemaWhiteSpaceReplace(value);
+			if (norm != NULL)
+			    value = norm;
+		    }
+		} else {
+		    const xmlChar *cur = value;
+		    while (*cur != 0) {
+			if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
+			    goto return1;
+			} else {
+			    cur++;
+			}
+		    }
+		}
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_NORMSTRING);
+                    if (v != NULL) {
+                        v->value.str = xmlStrdup(value);
+                        *val = v;
+                    } else {
+                        goto error;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_DECIMAL:{
+                const xmlChar *cur = value;
+                unsigned int len, neg, integ, hasLeadingZeroes;
+		xmlChar cval[25];
+		xmlChar *cptr = cval;		
+
+                if ((cur == NULL) || (*cur == 0))
+                    goto return1;
+
+		/*
+		* xs:decimal has a whitespace-facet value of 'collapse'.
+		*/
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+
+		/*
+		* First we handle an optional sign.
+		*/
+		neg = 0;
+                if (*cur == '-') {
+		    neg = 1;
+                    cur++;
+		} else if (*cur == '+')
+                    cur++;
+		/*
+		* Disallow: "", "-", "- "
+		*/
+		if (*cur == 0)
+		    goto return1;
+		/*
+		 * Next we "pre-parse" the number, in preparation for calling
+		 * the common routine xmlSchemaParseUInt.  We get rid of any
+		 * leading zeroes (because we have reserved only 25 chars),
+		 * and note the position of a decimal point.
+		 */
+		len = 0;
+		integ = ~0u;
+		hasLeadingZeroes = 0;
+		/*
+		* Skip leading zeroes.
+		*/
+		while (*cur == '0') {
+		    cur++;
+		    hasLeadingZeroes = 1;
+		}
+		if (*cur != 0) {
+		    do {
+			if ((*cur >= '0') && (*cur <= '9')) {
+			    *cptr++ = *cur++;
+			    len++;
+			} else if (*cur == '.') {
+			    cur++;
+			    integ = len;
+			    do {
+				if ((*cur >= '0') && (*cur <= '9')) {
+				    *cptr++ = *cur++;
+				    len++;
+				} else
+				    break;
+			    } while (len < 24);
+			    /*
+			    * Disallow "." but allow "00."
+			    */
+			    if ((len == 0) && (!hasLeadingZeroes))
+				goto return1;
+			    break;
+			} else
+			    break;
+		    } while (len < 24);
+		}
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+		if (*cur != 0)
+		    goto return1; /* error if any extraneous chars */
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
+                    if (v != NULL) {
+			/*
+		 	* Now evaluate the significant digits of the number
+		 	*/
+			if (len != 0) {
+			    
+			    if (integ != ~0u) {
+				/*
+				* Get rid of trailing zeroes in the
+				* fractional part.
+				*/
+				while ((len != integ) && (*(cptr-1) == '0')) {
+				    cptr--;
+				    len--;
+				}
+			    }
+			    /*
+			    * Terminate the (preparsed) string.
+			    */
+			    if (len != 0) {
+				*cptr = 0;
+				cptr = cval;
+
+				xmlSchemaParseUInt((const xmlChar **)&cptr,
+				    &v->value.decimal.lo,
+				    &v->value.decimal.mi,
+				    &v->value.decimal.hi);
+			    }
+			}
+			/*
+			* Set the total digits to 1 if a zero value.
+			*/
+                        v->value.decimal.sign = neg;
+			if (len == 0) {
+			    /* Speedup for zero values. */
+			    v->value.decimal.total = 1;
+			} else {
+			    v->value.decimal.total = len;
+			    if (integ == ~0u)
+				v->value.decimal.frac = 0;
+			    else
+				v->value.decimal.frac = len - integ;
+			}
+                        *val = v;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_TIME:
+        case XML_SCHEMAS_GDAY:
+        case XML_SCHEMAS_GMONTH:
+        case XML_SCHEMAS_GMONTHDAY:
+        case XML_SCHEMAS_GYEAR:
+        case XML_SCHEMAS_GYEARMONTH:
+        case XML_SCHEMAS_DATE:
+        case XML_SCHEMAS_DATETIME:
+            ret = xmlSchemaValidateDates(type->builtInType, value, val,
+		normOnTheFly);
+            break;
+        case XML_SCHEMAS_DURATION:
+            ret = xmlSchemaValidateDuration(type, value, val,
+		normOnTheFly);
+            break;
+        case XML_SCHEMAS_FLOAT:
+        case XML_SCHEMAS_DOUBLE:{
+                const xmlChar *cur = value;
+                int neg = 0;
+
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+
+                if ((cur[0] == 'N') && (cur[1] == 'a') && (cur[2] == 'N')) {
+                    cur += 3;
+                    if (*cur != 0)
+                        goto return1;
+                    if (val != NULL) {
+                        if (type == xmlSchemaTypeFloatDef) {
+                            v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
+                            if (v != NULL) {
+                                v->value.f = (float) xmlXPathNAN;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto error;
+                            }
+                        } else {
+                            v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
+                            if (v != NULL) {
+                                v->value.d = xmlXPathNAN;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto error;
+                            }
+                        }
+                        *val = v;
+                    }
+                    goto return0;
+                }
+                if (*cur == '-') {
+                    neg = 1;
+                    cur++;
+                }
+                if ((cur[0] == 'I') && (cur[1] == 'N') && (cur[2] == 'F')) {
+                    cur += 3;
+                    if (*cur != 0)
+                        goto return1;
+                    if (val != NULL) {
+                        if (type == xmlSchemaTypeFloatDef) {
+                            v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
+                            if (v != NULL) {
+                                if (neg)
+                                    v->value.f = (float) xmlXPathNINF;
+                                else
+                                    v->value.f = (float) xmlXPathPINF;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto error;
+                            }
+                        } else {
+                            v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
+                            if (v != NULL) {
+                                if (neg)
+                                    v->value.d = xmlXPathNINF;
+                                else
+                                    v->value.d = xmlXPathPINF;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto error;
+                            }
+                        }
+                        *val = v;
+                    }
+                    goto return0;
+                }
+                if ((neg == 0) && (*cur == '+'))
+                    cur++;
+                if ((cur[0] == 0) || (cur[0] == '+') || (cur[0] == '-'))
+                    goto return1;
+                while ((*cur >= '0') && (*cur <= '9')) {
+                    cur++;
+                }
+                if (*cur == '.') {
+                    cur++;
+                    while ((*cur >= '0') && (*cur <= '9'))
+                        cur++;
+                }
+                if ((*cur == 'e') || (*cur == 'E')) {
+                    cur++;
+                    if ((*cur == '-') || (*cur == '+'))
+                        cur++;
+                    while ((*cur >= '0') && (*cur <= '9'))
+                        cur++;
+                }
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+
+                if (*cur != 0)
+                    goto return1;
+                if (val != NULL) {
+                    if (type == xmlSchemaTypeFloatDef) {
+                        v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
+                        if (v != NULL) {
+			    /*
+			    * TODO: sscanf seems not to give the correct
+			    * value for extremely high/low values.
+			    * E.g. "1E-149" results in zero.
+			    */
+                            if (sscanf((const char *) value, "%f",
+                                 &(v->value.f)) == 1) {
+                                *val = v;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto return1;
+                            }
+                        } else {
+                            goto error;
+                        }
+                    } else {
+                        v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
+                        if (v != NULL) {
+			    /*
+			    * TODO: sscanf seems not to give the correct
+			    * value for extremely high/low values.
+			    */
+                            if (sscanf((const char *) value, "%lf",
+                                 &(v->value.d)) == 1) {
+                                *val = v;
+                            } else {
+                                xmlSchemaFreeValue(v);
+                                goto return1;
+                            }
+                        } else {
+                            goto error;
+                        }
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_BOOLEAN:{
+                const xmlChar *cur = value;
+
+		if (normOnTheFly) {
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+		    if (*cur == '0') {
+			ret = 0;
+			cur++;
+		    } else if (*cur == '1') {
+			ret = 1;
+			cur++;
+		    } else if (*cur == 't') {
+			cur++;
+			if ((*cur++ == 'r') && (*cur++ == 'u') &&
+			    (*cur++ == 'e')) {
+			    ret = 1;
+			} else
+			    goto return1;
+		    } else if (*cur == 'f') {
+			cur++;
+			if ((*cur++ == 'a') && (*cur++ == 'l') &&
+			    (*cur++ == 's') && (*cur++ == 'e')) {
+			    ret = 0;
+			} else
+			    goto return1;
+		    } else
+			goto return1;
+		    if (*cur != 0) {
+			while IS_WSP_BLANK_CH(*cur) cur++;
+			if (*cur != 0)
+			    goto return1;
+		    }
+		} else {
+		    if ((cur[0] == '0') && (cur[1] == 0))
+			ret = 0;
+		    else if ((cur[0] == '1') && (cur[1] == 0))
+			ret = 1;
+		    else if ((cur[0] == 't') && (cur[1] == 'r')
+			&& (cur[2] == 'u') && (cur[3] == 'e')
+			&& (cur[4] == 0))
+			ret = 1;
+		    else if ((cur[0] == 'f') && (cur[1] == 'a')
+			&& (cur[2] == 'l') && (cur[3] == 's')
+			&& (cur[4] == 'e') && (cur[5] == 0))
+			ret = 0;
+		    else
+			goto return1;
+		}
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_BOOLEAN);
+                    if (v != NULL) {
+                        v->value.b = ret;
+                        *val = v;
+                    } else {
+                        goto error;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_TOKEN:{
+                const xmlChar *cur = value;
+
+		if (! normOnTheFly) {
+		    while (*cur != 0) {
+			if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
+			    goto return1;
+			} else if (*cur == ' ') {
+			    cur++;
+			    if (*cur == 0)
+				goto return1;
+			    if (*cur == ' ')
+				goto return1;
+			} else {
+			    cur++;
+			}
+		    }		    
+		}                
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_TOKEN);
+                    if (v != NULL) {
+                        v->value.str = xmlStrdup(value);
+                        *val = v;
+                    } else {
+                        goto error;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_LANGUAGE:
+	    if (normOnTheFly) {		    
+		norm = xmlSchemaCollapseString(value);
+		if (norm != NULL)
+		    value = norm;
+	    }
+            if (xmlCheckLanguageID(value) == 1) {
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_LANGUAGE);
+                    if (v != NULL) {
+                        v->value.str = xmlStrdup(value);
+                        *val = v;
+                    } else {
+                        goto error;
+                    }
+                }
+                goto return0;
+            }
+            goto return1;
+        case XML_SCHEMAS_NMTOKEN:
+            if (xmlValidateNMToken(value, 1) == 0) {
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_NMTOKEN);
+                    if (v != NULL) {
+                        v->value.str = xmlStrdup(value);
+                        *val = v;
+                    } else {
+                        goto error;
+                    }
+                }
+                goto return0;
+            }
+            goto return1;
+        case XML_SCHEMAS_NMTOKENS:
+            ret = xmlSchemaValAtomicListNode(xmlSchemaTypeNmtokenDef,
+                                             value, val, node);
+            if (ret > 0)
+                ret = 0;
+            else
+                ret = 1;
+            goto done;
+        case XML_SCHEMAS_NAME:
+            ret = xmlValidateName(value, 1);
+            if ((ret == 0) && (val != NULL) && (value != NULL)) {
+		v = xmlSchemaNewValue(XML_SCHEMAS_NAME);
+		if (v != NULL) {
+		     const xmlChar *start = value, *end;
+		     while (IS_BLANK_CH(*start)) start++;
+		     end = start;
+		     while ((*end != 0) && (!IS_BLANK_CH(*end))) end++;
+		     v->value.str = xmlStrndup(start, end - start);
+		    *val = v;
+		} else {
+		    goto error;
+		}
+            }
+            goto done;
+        case XML_SCHEMAS_QNAME:{
+                const xmlChar *uri = NULL;
+                xmlChar *local = NULL;
+
+                ret = xmlValidateQName(value, 1);
+		if (ret != 0)
+		    goto done;
+                if (node != NULL) {
+                    xmlChar *prefix;
+		    xmlNsPtr ns;
+
+                    local = xmlSplitQName2(value, &prefix);
+		    ns = xmlSearchNs(node->doc, node, prefix);
+		    if ((ns == NULL) && (prefix != NULL)) {
+			xmlFree(prefix);
+			if (local != NULL)
+			    xmlFree(local);
+			goto return1;
+		    }
+		    if (ns != NULL)
+			uri = ns->href;
+                    if (prefix != NULL)
+                        xmlFree(prefix);
+                }
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_QNAME);
+                    if (v == NULL) {
+			if (local != NULL)
+			    xmlFree(local);
+			goto error;
+		    }
+		    if (local != NULL)
+			v->value.qname.name = local;
+		    else
+			v->value.qname.name = xmlStrdup(value);
+		    if (uri != NULL)
+			v->value.qname.uri = xmlStrdup(uri);
+		    *val = v;
+                } else
+		    if (local != NULL)
+			xmlFree(local);
+                goto done;
+            }
+        case XML_SCHEMAS_NCNAME:
+            ret = xmlValidateNCName(value, 1);
+            if ((ret == 0) && (val != NULL)) {
+                v = xmlSchemaNewValue(XML_SCHEMAS_NCNAME);
+                if (v != NULL) {
+                    v->value.str = xmlStrdup(value);
+                    *val = v;
+                } else {
+                    goto error;
+                }
+            }
+            goto done;
+        case XML_SCHEMAS_ID:
+            ret = xmlValidateNCName(value, 1);
+            if ((ret == 0) && (val != NULL)) {
+                v = xmlSchemaNewValue(XML_SCHEMAS_ID);
+                if (v != NULL) {
+                    v->value.str = xmlStrdup(value);
+                    *val = v;
+                } else {
+                    goto error;
+                }
+            }
+            if ((ret == 0) && (node != NULL) &&
+                (node->type == XML_ATTRIBUTE_NODE)) {
+                xmlAttrPtr attr = (xmlAttrPtr) node;
+
+                /*
+                 * NOTE: the IDness might have already be declared in the DTD
+                 */
+                if (attr->atype != XML_ATTRIBUTE_ID) {
+                    xmlIDPtr res;
+                    xmlChar *strip;
+
+                    strip = xmlSchemaStrip(value);
+                    if (strip != NULL) {
+                        res = xmlAddID(NULL, node->doc, strip, attr);
+                        xmlFree(strip);
+                    } else
+                        res = xmlAddID(NULL, node->doc, value, attr);
+                    if (res == NULL) {
+                        ret = 2;
+                    } else {
+                        attr->atype = XML_ATTRIBUTE_ID;
+                    }
+                }
+            }
+            goto done;
+        case XML_SCHEMAS_IDREF:
+            ret = xmlValidateNCName(value, 1);
+            if ((ret == 0) && (val != NULL)) {
+		v = xmlSchemaNewValue(XML_SCHEMAS_IDREF);
+		if (v == NULL)
+		    goto error;
+		v->value.str = xmlStrdup(value);
+		*val = v;
+            }
+            if ((ret == 0) && (node != NULL) &&
+                (node->type == XML_ATTRIBUTE_NODE)) {
+                xmlAttrPtr attr = (xmlAttrPtr) node;
+                xmlChar *strip;
+
+                strip = xmlSchemaStrip(value);
+                if (strip != NULL) {
+                    xmlAddRef(NULL, node->doc, strip, attr);
+                    xmlFree(strip);
+                } else
+                    xmlAddRef(NULL, node->doc, value, attr);
+                attr->atype = XML_ATTRIBUTE_IDREF;
+            }
+            goto done;
+        case XML_SCHEMAS_IDREFS:
+            ret = xmlSchemaValAtomicListNode(xmlSchemaTypeIdrefDef,
+                                             value, val, node);
+            if (ret < 0)
+                ret = 2;
+            else
+                ret = 0;
+            if ((ret == 0) && (node != NULL) &&
+                (node->type == XML_ATTRIBUTE_NODE)) {
+                xmlAttrPtr attr = (xmlAttrPtr) node;
+
+                attr->atype = XML_ATTRIBUTE_IDREFS;
+            }
+            goto done;
+        case XML_SCHEMAS_ENTITY:{
+                xmlChar *strip;
+
+                ret = xmlValidateNCName(value, 1);
+                if ((node == NULL) || (node->doc == NULL))
+                    ret = 3;
+                if (ret == 0) {
+                    xmlEntityPtr ent;
+
+                    strip = xmlSchemaStrip(value);
+                    if (strip != NULL) {
+                        ent = xmlGetDocEntity(node->doc, strip);
+                        xmlFree(strip);
+                    } else {
+                        ent = xmlGetDocEntity(node->doc, value);
+                    }
+                    if ((ent == NULL) ||
+                        (ent->etype !=
+                         XML_EXTERNAL_GENERAL_UNPARSED_ENTITY))
+                        ret = 4;
+                }
+                if ((ret == 0) && (val != NULL)) {
+                    TODO;
+                }
+                if ((ret == 0) && (node != NULL) &&
+                    (node->type == XML_ATTRIBUTE_NODE)) {
+                    xmlAttrPtr attr = (xmlAttrPtr) node;
+
+                    attr->atype = XML_ATTRIBUTE_ENTITY;
+                }
+                goto done;
+            }
+        case XML_SCHEMAS_ENTITIES:
+            if ((node == NULL) || (node->doc == NULL))
+                goto return3;
+            ret = xmlSchemaValAtomicListNode(xmlSchemaTypeEntityDef,
+                                             value, val, node);
+            if (ret <= 0)
+                ret = 1;
+            else
+                ret = 0;
+            if ((ret == 0) && (node != NULL) &&
+                (node->type == XML_ATTRIBUTE_NODE)) {
+                xmlAttrPtr attr = (xmlAttrPtr) node;
+
+                attr->atype = XML_ATTRIBUTE_ENTITIES;
+            }
+            goto done;
+        case XML_SCHEMAS_NOTATION:{
+                xmlChar *uri = NULL;
+                xmlChar *local = NULL;
+
+                ret = xmlValidateQName(value, 1);
+                if ((ret == 0) && (node != NULL)) {
+                    xmlChar *prefix;
+
+                    local = xmlSplitQName2(value, &prefix);
+                    if (prefix != NULL) {
+                        xmlNsPtr ns;
+
+                        ns = xmlSearchNs(node->doc, node, prefix);
+                        if (ns == NULL)
+                            ret = 1;
+                        else if (val != NULL)
+                            uri = xmlStrdup(ns->href);
+                    }
+                    if ((local != NULL) && ((val == NULL) || (ret != 0)))
+                        xmlFree(local);
+                    if (prefix != NULL)
+                        xmlFree(prefix);
+                }
+                if ((node == NULL) || (node->doc == NULL))
+                    ret = 3;
+                if (ret == 0) {
+                    ret = xmlValidateNotationUse(NULL, node->doc, value);
+                    if (ret == 1)
+                        ret = 0;
+                    else
+                        ret = 1;
+                }
+                if ((ret == 0) && (val != NULL)) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_NOTATION);
+                    if (v != NULL) {
+                        if (local != NULL)
+                            v->value.qname.name = local;
+                        else
+                            v->value.qname.name = xmlStrdup(value);
+                        if (uri != NULL)
+                            v->value.qname.uri = uri;
+
+                        *val = v;
+                    } else {
+                        if (local != NULL)
+                            xmlFree(local);
+                        if (uri != NULL)
+                            xmlFree(uri);
+                        goto error;
+                    }
+                }
+                goto done;
+            }
+        case XML_SCHEMAS_ANYURI:{		
+                if (*value != 0) {
+		    xmlURIPtr uri;
+		    xmlChar *tmpval, *cur;
+		    if (normOnTheFly) {		    
+			norm = xmlSchemaCollapseString(value);
+			if (norm != NULL)
+			    value = norm;
+		    }
+		    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);
+                }
+
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_ANYURI);
+                    if (v == NULL)
+                        goto error;
+                    v->value.str = xmlStrdup(value);
+                    *val = v;
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_HEXBINARY:{
+                const xmlChar *cur = value, *start;
+                xmlChar *base;
+                int total, i = 0;
+
+                if (cur == NULL)
+                    goto return1;
+
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+
+		start = cur;
+                while (((*cur >= '0') && (*cur <= '9')) ||
+                       ((*cur >= 'A') && (*cur <= 'F')) ||
+                       ((*cur >= 'a') && (*cur <= 'f'))) {
+                    i++;
+                    cur++;
+                }
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+
+                if (*cur != 0)
+                    goto return1;
+                if ((i % 2) != 0)
+                    goto return1;
+
+                if (val != NULL) {
+
+                    v = xmlSchemaNewValue(XML_SCHEMAS_HEXBINARY);
+                    if (v == NULL)
+                        goto error;
+		    /*
+		    * Copy only the normalized piece.
+		    * CRITICAL TODO: Check this.
+		    */
+                    cur = xmlStrndup(start, i);
+                    if (cur == NULL) {
+		        xmlSchemaTypeErrMemory(node, "allocating hexbin data");
+                        xmlFree(v);
+                        goto return1;
+                    }
+
+                    total = i / 2;      /* number of octets */
+
+                    base = (xmlChar *) cur;
+                    while (i-- > 0) {
+                        if (*base >= 'a')
+                            *base = *base - ('a' - 'A');
+                        base++;
+                    }
+
+                    v->value.hex.str = (xmlChar *) cur;
+                    v->value.hex.total = total;
+                    *val = v;
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_BASE64BINARY:{
+                /* ISSUE:
+                 * 
+                 * Ignore all stray characters? (yes, currently)
+                 * Worry about long lines? (no, currently)
+                 * 
+                 * rfc2045.txt:
+                 * 
+                 * "The encoded output stream must be represented in lines of
+                 * no more than 76 characters each.  All line breaks or other
+                 * characters not found in Table 1 must be ignored by decoding
+                 * software.  In base64 data, characters other than those in
+                 * Table 1, line breaks, and other white space probably
+                 * indicate a transmission error, about which a warning
+                 * message or even a message rejection might be appropriate
+                 * under some circumstances." */
+                const xmlChar *cur = value;
+                xmlChar *base;
+                int total, i = 0, pad = 0;
+
+                if (cur == NULL)
+                    goto return1;
+
+                for (; *cur; ++cur) {
+                    int decc;
+
+                    decc = _xmlSchemaBase64Decode(*cur);
+                    if (decc < 0) ;
+                    else if (decc < 64)
+                        i++;
+                    else
+                        break;
+                }
+                for (; *cur; ++cur) {
+                    int decc;
+
+                    decc = _xmlSchemaBase64Decode(*cur);
+                    if (decc < 0) ;
+                    else if (decc < 64)
+                        goto return1;
+                    if (decc == 64)
+                        pad++;
+                }
+
+                /* rfc2045.txt: "Special processing is performed if fewer than
+                 * 24 bits are available at the end of the data being encoded.
+                 * A full encoding quantum is always completed at the end of a
+                 * body.  When fewer than 24 input bits are available in an
+                 * input group, zero bits are added (on the right) to form an
+                 * integral number of 6-bit groups.  Padding at the end of the
+                 * data is performed using the "=" character.  Since all
+                 * base64 input is an integral number of octets, only the
+                 * following cases can arise: (1) the final quantum of
+                 * encoding input is an integral multiple of 24 bits; here,
+                 * the final unit of encoded output will be an integral
+                 * multiple ofindent: Standard input:701: Warning:old style
+		 * assignment ambiguity in "=*".  Assuming "= *" 4 characters
+		 * with no "=" padding, (2) the final
+                 * quantum of encoding input is exactly 8 bits; here, the
+                 * final unit of encoded output will be two characters
+                 * followed by two "=" padding characters, or (3) the final
+                 * quantum of encoding input is exactly 16 bits; here, the
+                 * final unit of encoded output will be three characters
+                 * followed by one "=" padding character." */
+
+                total = 3 * (i / 4);
+                if (pad == 0) {
+                    if (i % 4 != 0)
+                        goto return1;
+                } else if (pad == 1) {
+                    int decc;
+
+                    if (i % 4 != 3)
+                        goto return1;
+                    for (decc = _xmlSchemaBase64Decode(*cur);
+                         (decc < 0) || (decc > 63);
+                         decc = _xmlSchemaBase64Decode(*cur))
+                        --cur;
+                    /* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00*/
+                    /* 00111100 -> 0x3c */
+                    if (decc & ~0x3c)
+                        goto return1;
+                    total += 2;
+                } else if (pad == 2) {
+                    int decc;
+
+                    if (i % 4 != 2)
+                        goto return1;
+                    for (decc = _xmlSchemaBase64Decode(*cur);
+                         (decc < 0) || (decc > 63);
+                         decc = _xmlSchemaBase64Decode(*cur))
+                        --cur;
+                    /* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
+                    /* 00110000 -> 0x30 */
+                    if (decc & ~0x30)
+                        goto return1;
+                    total += 1;
+                } else
+                    goto return1;
+
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(XML_SCHEMAS_BASE64BINARY);
+                    if (v == NULL)
+                        goto error;
+                    base =
+                        (xmlChar *) xmlMallocAtomic((i + pad + 1) *
+                                                    sizeof(xmlChar));
+                    if (base == NULL) {
+		        xmlSchemaTypeErrMemory(node, "allocating base64 data");
+                        xmlFree(v);
+                        goto return1;
+                    }
+                    v->value.base64.str = base;
+                    for (cur = value; *cur; ++cur)
+                        if (_xmlSchemaBase64Decode(*cur) >= 0) {
+                            *base = *cur;
+                            ++base;
+                        }
+                    *base = 0;
+                    v->value.base64.total = total;
+                    *val = v;
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_INTEGER:
+        case XML_SCHEMAS_PINTEGER:
+        case XML_SCHEMAS_NPINTEGER:
+        case XML_SCHEMAS_NINTEGER:
+        case XML_SCHEMAS_NNINTEGER:{
+                const xmlChar *cur = value;
+                unsigned long lo, mi, hi;
+                int sign = 0;
+
+                if (cur == NULL)
+                    goto return1;
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+                if (*cur == '-') {
+                    sign = 1;
+                    cur++;
+                } else if (*cur == '+')
+                    cur++;
+                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+                if (ret < 0)
+                    goto return1;
+		if (normOnTheFly)
+		    while IS_WSP_BLANK_CH(*cur) cur++;
+                if (*cur != 0)
+                    goto return1;
+                if (type->builtInType == XML_SCHEMAS_NPINTEGER) {
+                    if ((sign == 0) &&
+                        ((hi != 0) || (mi != 0) || (lo != 0)))
+                        goto return1;
+                } else if (type->builtInType == XML_SCHEMAS_PINTEGER) {
+                    if (sign == 1)
+                        goto return1;
+                    if ((hi == 0) && (mi == 0) && (lo == 0))
+                        goto return1;
+                } else if (type->builtInType == XML_SCHEMAS_NINTEGER) {
+                    if (sign == 0)
+                        goto return1;
+                    if ((hi == 0) && (mi == 0) && (lo == 0))
+                        goto return1;
+                } else if (type->builtInType == XML_SCHEMAS_NNINTEGER) {
+                    if ((sign == 1) &&
+                        ((hi != 0) || (mi != 0) || (lo != 0)))
+                        goto return1;
+                }
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(type->builtInType);
+                    if (v != NULL) {
+			if (ret == 0)
+			    ret++;
+                        v->value.decimal.lo = lo;
+                        v->value.decimal.mi = mi;
+                        v->value.decimal.hi = hi;
+                        v->value.decimal.sign = sign;
+                        v->value.decimal.frac = 0;
+                        v->value.decimal.total = ret;
+                        *val = v;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_LONG:
+        case XML_SCHEMAS_BYTE:
+        case XML_SCHEMAS_SHORT:
+        case XML_SCHEMAS_INT:{
+                const xmlChar *cur = value;
+                unsigned long lo, mi, hi;
+                int sign = 0;
+
+                if (cur == NULL)
+                    goto return1;
+                if (*cur == '-') {
+                    sign = 1;
+                    cur++;
+                } else if (*cur == '+')
+                    cur++;
+                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+                if (ret < 0)
+                    goto return1;
+                if (*cur != 0)
+                    goto return1;
+                if (type->builtInType == XML_SCHEMAS_LONG) {
+                    if (hi >= 922) {
+                        if (hi > 922)
+                            goto return1;
+                        if (mi >= 33720368) {
+                            if (mi > 33720368)
+                                goto return1;
+                            if ((sign == 0) && (lo > 54775807))
+                                goto return1;
+                            if ((sign == 1) && (lo > 54775808))
+                                goto return1;
+                        }
+                    }
+                } else if (type->builtInType == XML_SCHEMAS_INT) {
+                    if (hi != 0)
+                        goto return1;
+                    if (mi >= 21) {
+                        if (mi > 21)
+                            goto return1;
+                        if ((sign == 0) && (lo > 47483647))
+                            goto return1;
+                        if ((sign == 1) && (lo > 47483648))
+                            goto return1;
+                    }
+                } else if (type->builtInType == XML_SCHEMAS_SHORT) {
+                    if ((mi != 0) || (hi != 0))
+                        goto return1;
+                    if ((sign == 1) && (lo > 32768))
+                        goto return1;
+                    if ((sign == 0) && (lo > 32767))
+                        goto return1;
+                } else if (type->builtInType == XML_SCHEMAS_BYTE) {
+                    if ((mi != 0) || (hi != 0))
+                        goto return1;
+                    if ((sign == 1) && (lo > 128))
+                        goto return1;
+                    if ((sign == 0) && (lo > 127))
+                        goto return1;
+                }
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(type->builtInType);
+                    if (v != NULL) {
+                        v->value.decimal.lo = lo;
+                        v->value.decimal.mi = mi;
+                        v->value.decimal.hi = hi;
+                        v->value.decimal.sign = sign;
+                        v->value.decimal.frac = 0;
+                        v->value.decimal.total = ret;
+                        *val = v;
+                    }
+                }
+                goto return0;
+            }
+        case XML_SCHEMAS_UINT:
+        case XML_SCHEMAS_ULONG:
+        case XML_SCHEMAS_USHORT:
+        case XML_SCHEMAS_UBYTE:{
+                const xmlChar *cur = value;
+                unsigned long lo, mi, hi;
+
+                if (cur == NULL)
+                    goto return1;
+                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+                if (ret < 0)
+                    goto return1;
+                if (*cur != 0)
+                    goto return1;
+                if (type->builtInType == XML_SCHEMAS_ULONG) {
+                    if (hi >= 1844) {
+                        if (hi > 1844)
+                            goto return1;
+                        if (mi >= 67440737) {
+                            if (mi > 67440737)
+                                goto return1;
+                            if (lo > 9551615)
+                                goto return1;
+                        }
+                    }
+                } else if (type->builtInType == XML_SCHEMAS_UINT) {
+                    if (hi != 0)
+                        goto return1;
+                    if (mi >= 42) {
+                        if (mi > 42)
+                            goto return1;
+                        if (lo > 94967295)
+                            goto return1;
+                    }
+                } else if (type->builtInType == XML_SCHEMAS_USHORT) {
+                    if ((mi != 0) || (hi != 0))
+                        goto return1;
+                    if (lo > 65535)
+                        goto return1;
+                } else if (type->builtInType == XML_SCHEMAS_UBYTE) {
+                    if ((mi != 0) || (hi != 0))
+                        goto return1;
+                    if (lo > 255)
+                        goto return1;
+                }
+                if (val != NULL) {
+                    v = xmlSchemaNewValue(type->builtInType);
+                    if (v != NULL) {
+                        v->value.decimal.lo = lo;
+                        v->value.decimal.mi = mi;
+                        v->value.decimal.hi = hi;
+                        v->value.decimal.sign = 0;
+                        v->value.decimal.frac = 0;
+                        v->value.decimal.total = ret;
+                        *val = v;
+                    }
+                }
+                goto return0;
+            }
+    }
+
+  done:
+    if (norm != NULL)
+        xmlFree(norm);
+    return (ret);
+  return3:
+    if (norm != NULL)
+        xmlFree(norm);
+    return (3);
+  return1:
+    if (norm != NULL)
+        xmlFree(norm);
+    return (1);
+  return0:
+    if (norm != NULL)
+        xmlFree(norm);
+    return (0);
+  error:
+    if (norm != NULL)
+        xmlFree(norm);
+    return (-1);
+}
+
+/**
+ * xmlSchemaValPredefTypeNode:
+ * @type: the predefined type
+ * @value: the value to check
+ * @val:  the return computed value
+ * @node:  the node containing the value
+ *
+ * Check that a value conforms to the lexical space of the predefined type.
+ * if true a value is computed and returned in @val.
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value,
+	                   xmlSchemaValPtr *val, xmlNodePtr node) {
+    return(xmlSchemaValAtomicType(type, value, val, node, 0,
+	XML_SCHEMA_WHITESPACE_UNKNOWN, 1, 1, 0));
+}
+
+/**
+ * xmlSchemaValPredefTypeNodeNoNorm:
+ * @type: the predefined type
+ * @value: the value to check
+ * @val:  the return computed value
+ * @node:  the node containing the value
+ *
+ * Check that a value conforms to the lexical space of the predefined type.
+ * if true a value is computed and returned in @val.
+ * This one does apply any normalization to the value.
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaTypePtr type, const xmlChar *value,
+				 xmlSchemaValPtr *val, xmlNodePtr node) {
+    return(xmlSchemaValAtomicType(type, value, val, node, 1,
+	XML_SCHEMA_WHITESPACE_UNKNOWN, 1, 0, 1));
+}
+
+/**
+ * xmlSchemaValidatePredefinedType:
+ * @type: the predefined type
+ * @value: the value to check
+ * @val:  the return computed value
+ *
+ * Check that a value conforms to the lexical space of the predefined type.
+ * if true a value is computed and returned in @val.
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ *         and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value,
+	                        xmlSchemaValPtr *val) {
+    return(xmlSchemaValPredefTypeNode(type, value, val, NULL));
+}
+
+/**
+ * xmlSchemaCompareDecimals:
+ * @x:  a first decimal value
+ * @y:  a second decimal value
+ *
+ * Compare 2 decimals
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y and -2 in case of error
+ */
+static int
+xmlSchemaCompareDecimals(xmlSchemaValPtr x, xmlSchemaValPtr y)
+{
+    xmlSchemaValPtr swp;
+    int order = 1, integx, integy, dlen;
+    unsigned long hi, mi, lo;
+
+    /*
+     * First test: If x is -ve and not zero
+     */
+    if ((x->value.decimal.sign) && 
+	((x->value.decimal.lo != 0) ||
+	 (x->value.decimal.mi != 0) ||
+	 (x->value.decimal.hi != 0))) {
+	/*
+	 * Then if y is -ve and not zero reverse the compare
+	 */
+	if ((y->value.decimal.sign) &&
+	    ((y->value.decimal.lo != 0) ||
+	     (y->value.decimal.mi != 0) ||
+	     (y->value.decimal.hi != 0)))
+	    order = -1;
+	/*
+	 * Otherwise (y >= 0) we have the answer
+	 */
+	else
+	    return (-1);
+    /*
+     * If x is not -ve and y is -ve we have the answer
+     */
+    } else if ((y->value.decimal.sign) &&
+	       ((y->value.decimal.lo != 0) ||
+		(y->value.decimal.mi != 0) ||
+		(y->value.decimal.hi != 0))) {
+        return (1);
+    }
+    /*
+     * If it's not simply determined by a difference in sign,
+     * then we need to compare the actual values of the two nums.
+     * To do this, we start by looking at the integral parts.
+     * If the number of integral digits differ, then we have our
+     * answer.
+     */
+    integx = x->value.decimal.total - x->value.decimal.frac;
+    integy = y->value.decimal.total - y->value.decimal.frac;
+    /*
+    * NOTE: We changed the "total" for values like "0.1"
+    *   (or "-0.1" or ".1") to be 1, which was 2 previously.
+    *   Therefore the special case, when such values are
+    *   compared with 0, needs to be handled separately;
+    *   otherwise a zero would be recognized incorrectly as
+    *   greater than those values. This has the nice side effect
+    *   that we gain an overall optimized comparison with zeroes.
+    * Note that a "0" has a "total" of 1 already.
+    */
+    if (integx == 1) {
+	if (x->value.decimal.lo == 0) {
+	    if (integy != 1)
+		return -order;
+	    else if (y->value.decimal.lo != 0)
+		return -order;
+	    else
+		return(0);
+	}
+    }
+    if (integy == 1) {
+	if (y->value.decimal.lo == 0) {
+	    if (integx != 1)
+		return order;
+	    else if (x->value.decimal.lo != 0)
+		return order;
+	    else
+		return(0);
+	}
+    }
+
+    if (integx > integy)
+	return order;
+    else if (integy > integx)
+	return -order;
+
+    /*
+     * If the number of integral digits is the same for both numbers,
+     * then things get a little more complicated.  We need to "normalize"
+     * the numbers in order to properly compare them.  To do this, we
+     * look at the total length of each number (length => number of
+     * significant digits), and divide the "shorter" by 10 (decreasing
+     * the length) until they are of equal length.
+     */
+    dlen = x->value.decimal.total - y->value.decimal.total;
+    if (dlen < 0) {	/* y has more digits than x */
+	swp = x;
+	hi = y->value.decimal.hi;
+	mi = y->value.decimal.mi;
+	lo = y->value.decimal.lo;
+	dlen = -dlen;
+	order = -order;
+    } else {		/* x has more digits than y */
+	swp = y;
+	hi = x->value.decimal.hi;
+	mi = x->value.decimal.mi;
+	lo = x->value.decimal.lo;
+    }
+    while (dlen > 8) {	/* in effect, right shift by 10**8 */
+	lo = mi;
+	mi = hi;
+	hi = 0;
+	dlen -= 8;
+    }
+    while (dlen > 0) {
+	unsigned long rem1, rem2;
+	rem1 = (hi % 10) * 100000000L;
+	hi = hi / 10;
+	rem2 = (mi % 10) * 100000000L;
+	mi = (mi + rem1) / 10;
+	lo = (lo + rem2) / 10;
+	dlen--;
+    }
+    if (hi > swp->value.decimal.hi) {
+	return order;
+    } else if (hi == swp->value.decimal.hi) {
+	if (mi > swp->value.decimal.mi) {
+	    return order;
+	} else if (mi == swp->value.decimal.mi) {
+	    if (lo > swp->value.decimal.lo) {
+		return order;
+	    } else if (lo == swp->value.decimal.lo) {
+		if (x->value.decimal.total == y->value.decimal.total) {
+		    return 0;
+		} else {
+		    return order;
+		}
+	    }
+	}
+    }
+    return -order;
+}
+
+/**
+ * xmlSchemaCompareDurations:
+ * @x:  a first duration value
+ * @y:  a second duration value
+ *
+ * Compare 2 durations
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareDurations(xmlSchemaValPtr x, xmlSchemaValPtr y)
+{
+    long carry, mon, day;
+    double sec;
+    int invert = 1;
+    long xmon, xday, myear, minday, maxday;
+    static const long dayRange [2][12] = {
+        { 0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334, },
+        { 0, 31, 62, 92, 123, 153, 184, 215, 245, 276, 306, 337} };
+
+    if ((x == NULL) || (y == NULL))
+        return -2;
+
+    /* months */
+    mon = x->value.dur.mon - y->value.dur.mon;
+
+    /* seconds */
+    sec = x->value.dur.sec - y->value.dur.sec;
+    carry = (long)sec / SECS_PER_DAY;
+    sec -= (double)(carry * SECS_PER_DAY);
+
+    /* days */
+    day = x->value.dur.day - y->value.dur.day + carry;
+
+    /* easy test */
+    if (mon == 0) {
+        if (day == 0)
+            if (sec == 0.0)
+                return 0;
+            else if (sec < 0.0)
+                return -1;
+            else
+                return 1;
+        else if (day < 0)
+            return -1;
+        else
+            return 1;
+    }
+
+    if (mon > 0) {
+        if ((day >= 0) && (sec >= 0.0))
+            return 1;
+        else {
+            xmon = mon;
+            xday = -day;
+        }
+    } else if ((day <= 0) && (sec <= 0.0)) {
+        return -1;
+    } else {
+	invert = -1;
+        xmon = -mon;
+        xday = day;
+    }
+
+    myear = xmon / 12;
+    if (myear == 0) {
+	minday = 0;
+	maxday = 0;
+    } else {
+	maxday = 366 * ((myear + 3) / 4) +
+	         365 * ((myear - 1) % 4);
+	minday = maxday - 1;
+    }
+
+    xmon = xmon % 12;
+    minday += dayRange[0][xmon];
+    maxday += dayRange[1][xmon];
+
+    if ((maxday == minday) && (maxday == xday))
+	return(0); /* can this really happen ? */
+    if (maxday < xday)
+        return(-invert);
+    if (minday > xday)
+        return(invert);
+
+    /* indeterminate */
+    return 2;
+}
+
+/*
+ * macros for adding date/times and durations
+ */
+#define FQUOTIENT(a,b)                  (floor(((double)a/(double)b)))
+#define MODULO(a,b)                     (a - FQUOTIENT(a,b) * b)
+#define FQUOTIENT_RANGE(a,low,high)     (FQUOTIENT((a-low),(high-low)))
+#define MODULO_RANGE(a,low,high)        ((MODULO((a-low),(high-low)))+low)
+
+/**
+ * xmlSchemaDupVal:
+ * @v: the #xmlSchemaValPtr value to duplicate
+ *
+ * Makes a copy of @v. The calling program is responsible for freeing
+ * the returned value.
+ *
+ * returns a pointer to a duplicated #xmlSchemaValPtr or NULL if error.
+ */
+static xmlSchemaValPtr
+xmlSchemaDupVal (xmlSchemaValPtr v)
+{
+    xmlSchemaValPtr ret = xmlSchemaNewValue(v->type);
+    if (ret == NULL)
+        return NULL;
+    
+    memcpy(ret, v, sizeof(xmlSchemaVal));
+    ret->next = NULL;
+    return ret;
+}
+
+/**
+ * xmlSchemaCopyValue:
+ * @val:  the precomputed value to be copied
+ *
+ * Copies the precomputed value. This duplicates any string within.
+ *
+ * Returns the copy or NULL if a copy for a data-type is not implemented.
+ */
+xmlSchemaValPtr
+xmlSchemaCopyValue(xmlSchemaValPtr val)
+{
+    xmlSchemaValPtr ret = NULL, prev = NULL, cur;
+
+    /*
+    * Copy the string values.
+    */
+    while (val != NULL) {
+	switch (val->type) {
+	    case XML_SCHEMAS_ANYTYPE:
+	    case XML_SCHEMAS_IDREFS:
+	    case XML_SCHEMAS_ENTITIES:
+	    case XML_SCHEMAS_NMTOKENS:
+		xmlSchemaFreeValue(ret);
+		return (NULL);
+	    case XML_SCHEMAS_ANYSIMPLETYPE:
+	    case XML_SCHEMAS_STRING:
+	    case XML_SCHEMAS_NORMSTRING:
+	    case XML_SCHEMAS_TOKEN:
+	    case XML_SCHEMAS_LANGUAGE:
+	    case XML_SCHEMAS_NAME:
+	    case XML_SCHEMAS_NCNAME:
+	    case XML_SCHEMAS_ID:
+	    case XML_SCHEMAS_IDREF:
+	    case XML_SCHEMAS_ENTITY:
+	    case XML_SCHEMAS_NMTOKEN:
+	    case XML_SCHEMAS_ANYURI:
+		cur = xmlSchemaDupVal(val);
+		if (val->value.str != NULL)
+		    cur->value.str = xmlStrdup(BAD_CAST val->value.str);
+		break;
+	    case XML_SCHEMAS_QNAME:        
+	    case XML_SCHEMAS_NOTATION:
+		cur = xmlSchemaDupVal(val);
+		if (val->value.qname.name != NULL)
+		    cur->value.qname.name =
+                    xmlStrdup(BAD_CAST val->value.qname.name);
+		if (val->value.qname.uri != NULL)
+		    cur->value.qname.uri =
+                    xmlStrdup(BAD_CAST val->value.qname.uri);
+		break;
+	    case XML_SCHEMAS_HEXBINARY:
+		cur = xmlSchemaDupVal(val);
+		if (val->value.hex.str != NULL)
+		    cur->value.hex.str = xmlStrdup(BAD_CAST val->value.hex.str);
+		break;
+	    case XML_SCHEMAS_BASE64BINARY:
+		cur = xmlSchemaDupVal(val);
+		if (val->value.base64.str != NULL)
+		    cur->value.base64.str =
+                    xmlStrdup(BAD_CAST val->value.base64.str);
+		break;
+	    default:
+		cur = xmlSchemaDupVal(val);
+		break;
+	}
+	if (ret == NULL)
+	    ret = cur;
+	else
+	    prev->next = cur;
+	prev = cur;
+	val = val->next;
+    }
+    return (ret);
+}
+
+/**
+ * _xmlSchemaDateAdd:
+ * @dt: an #xmlSchemaValPtr
+ * @dur: an #xmlSchemaValPtr of type #XS_DURATION
+ *
+ * Compute a new date/time from @dt and @dur. This function assumes @dt
+ * is either #XML_SCHEMAS_DATETIME, #XML_SCHEMAS_DATE, #XML_SCHEMAS_GYEARMONTH,
+ * or #XML_SCHEMAS_GYEAR. The returned #xmlSchemaVal is the same type as
+ * @dt. The calling program is responsible for freeing the returned value.
+ *
+ * Returns a pointer to a new #xmlSchemaVal or NULL if error.
+ */
+static xmlSchemaValPtr
+_xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur)
+{
+    xmlSchemaValPtr ret, tmp;
+    long carry, tempdays, temp;
+    xmlSchemaValDatePtr r, d;
+    xmlSchemaValDurationPtr u;
+
+    if ((dt == NULL) || (dur == NULL))
+        return NULL;
+
+    ret = xmlSchemaNewValue(dt->type);
+    if (ret == NULL)
+        return NULL;
+
+    /* make a copy so we don't alter the original value */
+    tmp = xmlSchemaDupVal(dt);
+    if (tmp == NULL) {
+        xmlSchemaFreeValue(ret);
+        return NULL;
+    }
+
+    r = &(ret->value.date);
+    d = &(tmp->value.date);
+    u = &(dur->value.dur);
+
+    /* normalization */
+    if (d->mon == 0)
+        d->mon = 1;
+
+    /* normalize for time zone offset */
+    u->sec -= (d->tzo * 60);
+    d->tzo = 0;
+
+    /* normalization */
+    if (d->day == 0)
+        d->day = 1;
+
+    /* month */
+    carry  = d->mon + u->mon;
+    r->mon = (unsigned int) MODULO_RANGE(carry, 1, 13);
+    carry  = (long) FQUOTIENT_RANGE(carry, 1, 13);
+
+    /* year (may be modified later) */
+    r->year = d->year + carry;
+    if (r->year == 0) {
+        if (d->year > 0)
+            r->year--;
+        else
+            r->year++;
+    }
+
+    /* time zone */
+    r->tzo     = d->tzo;
+    r->tz_flag = d->tz_flag;
+
+    /* seconds */
+    r->sec = d->sec + u->sec;
+    carry  = (long) FQUOTIENT((long)r->sec, 60);
+    if (r->sec != 0.0) {
+        r->sec = MODULO(r->sec, 60.0);
+    }
+
+    /* minute */
+    carry += d->min;
+    r->min = (unsigned int) MODULO(carry, 60);
+    carry  = (long) FQUOTIENT(carry, 60);
+
+    /* hours */
+    carry  += d->hour;
+    r->hour = (unsigned int) MODULO(carry, 24);
+    carry   = (long)FQUOTIENT(carry, 24);
+
+    /*
+     * days
+     * Note we use tempdays because the temporary values may need more
+     * than 5 bits
+     */
+    if ((VALID_YEAR(r->year)) && (VALID_MONTH(r->mon)) &&
+                  (d->day > MAX_DAYINMONTH(r->year, r->mon)))
+        tempdays = MAX_DAYINMONTH(r->year, r->mon);
+    else if (d->day < 1)
+        tempdays = 1;
+    else
+        tempdays = d->day;
+
+    tempdays += u->day + carry;
+
+    while (1) {
+        if (tempdays < 1) {
+            long tmon = (long) MODULO_RANGE((int)r->mon-1, 1, 13);
+            long tyr  = r->year + (long)FQUOTIENT_RANGE((int)r->mon-1, 1, 13);
+            if (tyr == 0)
+                tyr--;
+	    /*
+	     * Coverity detected an overrun in daysInMonth 
+	     * of size 12 at position 12 with index variable "((r)->mon - 1)"
+	     */
+	    if (tmon < 0)
+	        tmon = 0;
+	    if (tmon > 12)
+	        tmon = 12;
+            tempdays += MAX_DAYINMONTH(tyr, tmon);
+            carry = -1;
+        } else if (tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
+            tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
+            carry = 1;
+        } else
+            break;
+
+        temp = r->mon + carry;
+        r->mon = (unsigned int) MODULO_RANGE(temp, 1, 13);
+        r->year = r->year + (unsigned int) FQUOTIENT_RANGE(temp, 1, 13);
+        if (r->year == 0) {
+            if (temp < 1)
+                r->year--;
+            else
+                r->year++;
+	}
+    }
+    
+    r->day = tempdays;
+
+    /*
+     * adjust the date/time type to the date values
+     */
+    if (ret->type != XML_SCHEMAS_DATETIME) {
+        if ((r->hour) || (r->min) || (r->sec))
+            ret->type = XML_SCHEMAS_DATETIME;
+        else if (ret->type != XML_SCHEMAS_DATE) {
+            if ((r->mon != 1) && (r->day != 1))
+                ret->type = XML_SCHEMAS_DATE;
+            else if ((ret->type != XML_SCHEMAS_GYEARMONTH) && (r->mon != 1))
+                ret->type = XML_SCHEMAS_GYEARMONTH;
+        }
+    }
+
+    xmlSchemaFreeValue(tmp);
+
+    return ret;
+}
+
+/**
+ * xmlSchemaDateNormalize:
+ * @dt: an #xmlSchemaValPtr of a date/time type value.
+ * @offset: number of seconds to adjust @dt by.
+ *
+ * Normalize @dt to GMT time. The @offset parameter is subtracted from
+ * the return value is a time-zone offset is present on @dt.
+ *
+ * Returns a normalized copy of @dt or NULL if error.
+ */
+static xmlSchemaValPtr
+xmlSchemaDateNormalize (xmlSchemaValPtr dt, double offset)
+{
+    xmlSchemaValPtr dur, ret;
+
+    if (dt == NULL)
+        return NULL;
+
+    if (((dt->type != XML_SCHEMAS_TIME) &&
+         (dt->type != XML_SCHEMAS_DATETIME) &&
+	 (dt->type != XML_SCHEMAS_DATE)) || (dt->value.date.tzo == 0))
+        return xmlSchemaDupVal(dt);
+
+    dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
+    if (dur == NULL)
+        return NULL;
+
+    dur->value.date.sec -= offset;
+
+    ret = _xmlSchemaDateAdd(dt, dur);
+    if (ret == NULL)
+        return NULL;
+
+    xmlSchemaFreeValue(dur);
+
+    /* ret->value.date.tzo = 0; */
+    return ret;
+}
+
+/**
+ * _xmlSchemaDateCastYMToDays:
+ * @dt: an #xmlSchemaValPtr
+ *
+ * Convert mon and year of @dt to total number of days. Take the 
+ * number of years since (or before) 1 AD and add the number of leap
+ * years. This is a function  because negative
+ * years must be handled a little differently and there is no zero year.
+ *
+ * Returns number of days.
+ */
+static long
+_xmlSchemaDateCastYMToDays (const xmlSchemaValPtr dt)
+{
+    long ret;
+    int mon;
+
+    mon = dt->value.date.mon;
+    if (mon <= 0) mon = 1; /* normalization */
+
+    if (dt->value.date.year <= 0)
+        ret = (dt->value.date.year * 365) +
+              (((dt->value.date.year+1)/4)-((dt->value.date.year+1)/100)+
+               ((dt->value.date.year+1)/400)) +
+              DAY_IN_YEAR(0, mon, dt->value.date.year);
+    else
+        ret = ((dt->value.date.year-1) * 365) +
+              (((dt->value.date.year-1)/4)-((dt->value.date.year-1)/100)+
+               ((dt->value.date.year-1)/400)) +
+              DAY_IN_YEAR(0, mon, dt->value.date.year);
+
+    return ret;
+}
+
+/**
+ * TIME_TO_NUMBER:
+ * @dt:  an #xmlSchemaValPtr
+ *
+ * Calculates the number of seconds in the time portion of @dt.
+ *
+ * Returns seconds.
+ */
+#define TIME_TO_NUMBER(dt)                              \
+    ((double)((dt->value.date.hour * SECS_PER_HOUR) +   \
+              (dt->value.date.min * SECS_PER_MIN) +	\
+              (dt->value.date.tzo * SECS_PER_MIN)) +	\
+               dt->value.date.sec)
+
+/**
+ * xmlSchemaCompareDates:
+ * @x:  a first date/time value
+ * @y:  a second date/time value
+ *
+ * Compare 2 date/times
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
+{
+    unsigned char xmask, ymask, xor_mask, and_mask;
+    xmlSchemaValPtr p1, p2, q1, q2;
+    long p1d, p2d, q1d, q2d;
+
+    if ((x == NULL) || (y == NULL))
+        return -2;
+
+    if (x->value.date.tz_flag) {
+
+        if (!y->value.date.tz_flag) {
+            p1 = xmlSchemaDateNormalize(x, 0);
+            p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
+            /* normalize y + 14:00 */
+            q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
+
+            q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
+            if (p1d < q1d) {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+                return -1;
+	    } else if (p1d == q1d) {
+                double sec;
+
+                sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
+                if (sec < 0.0) {
+		    xmlSchemaFreeValue(p1);
+		    xmlSchemaFreeValue(q1);
+                    return -1;
+		} else {
+		    int ret = 0;
+                    /* normalize y - 14:00 */
+                    q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
+                    q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
+                    if (p1d > q2d)
+                        ret = 1;
+                    else if (p1d == q2d) {
+                        sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q2);
+                        if (sec > 0.0)
+                            ret = 1;
+                        else
+                            ret = 2; /* indeterminate */
+                    }
+		    xmlSchemaFreeValue(p1);
+		    xmlSchemaFreeValue(q1);
+		    xmlSchemaFreeValue(q2);
+		    if (ret != 0)
+		        return(ret);
+                }
+            } else {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+	    }
+        }
+    } else if (y->value.date.tz_flag) {
+        q1 = xmlSchemaDateNormalize(y, 0);
+        q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
+
+        /* normalize x - 14:00 */
+        p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
+        p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
+
+        if (p1d < q1d) {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
+            return -1;
+	} else if (p1d == q1d) {
+            double sec;
+
+            sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
+            if (sec < 0.0) {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+                return -1;
+	    } else {
+	        int ret = 0;
+                /* normalize x + 14:00 */
+                p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
+                p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
+
+                if (p2d > q1d) {
+                    ret = 1;
+		} else if (p2d == q1d) {
+                    sec = TIME_TO_NUMBER(p2) - TIME_TO_NUMBER(q1);
+                    if (sec > 0.0)
+                        ret = 1;
+                    else
+                        ret = 2; /* indeterminate */
+                }
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+		xmlSchemaFreeValue(p2);
+		if (ret != 0)
+		    return(ret);
+            }
+	} else {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
+        }
+    }
+
+    /*
+     * if the same type then calculate the difference
+     */
+    if (x->type == y->type) {
+        int ret = 0;
+        q1 = xmlSchemaDateNormalize(y, 0);
+        q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
+
+        p1 = xmlSchemaDateNormalize(x, 0);
+        p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
+
+        if (p1d < q1d) {
+            ret = -1;
+	} else if (p1d > q1d) {
+            ret = 1;
+	} else {
+            double sec;
+
+            sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
+            if (sec < 0.0)
+                ret = -1;
+            else if (sec > 0.0)
+                ret = 1;
+            
+        }
+	xmlSchemaFreeValue(p1);
+	xmlSchemaFreeValue(q1);
+        return(ret);
+    }
+
+    switch (x->type) {
+        case XML_SCHEMAS_DATETIME:
+            xmask = 0xf;
+            break;
+        case XML_SCHEMAS_DATE:
+            xmask = 0x7;
+            break;
+        case XML_SCHEMAS_GYEAR:
+            xmask = 0x1;
+            break;
+        case XML_SCHEMAS_GMONTH:
+            xmask = 0x2;
+            break;
+        case XML_SCHEMAS_GDAY:
+            xmask = 0x3;
+            break;
+        case XML_SCHEMAS_GYEARMONTH:
+            xmask = 0x3;
+            break;
+        case XML_SCHEMAS_GMONTHDAY:
+            xmask = 0x6;
+            break;
+        case XML_SCHEMAS_TIME:
+            xmask = 0x8;
+            break;
+        default:
+            xmask = 0;
+            break;
+    }
+
+    switch (y->type) {
+        case XML_SCHEMAS_DATETIME:
+            ymask = 0xf;
+            break;
+        case XML_SCHEMAS_DATE:
+            ymask = 0x7;
+            break;
+        case XML_SCHEMAS_GYEAR:
+            ymask = 0x1;
+            break;
+        case XML_SCHEMAS_GMONTH:
+            ymask = 0x2;
+            break;
+        case XML_SCHEMAS_GDAY:
+            ymask = 0x3;
+            break;
+        case XML_SCHEMAS_GYEARMONTH:
+            ymask = 0x3;
+            break;
+        case XML_SCHEMAS_GMONTHDAY:
+            ymask = 0x6;
+            break;
+        case XML_SCHEMAS_TIME:
+            ymask = 0x8;
+            break;
+        default:
+            ymask = 0;
+            break;
+    }
+
+    xor_mask = xmask ^ ymask;           /* mark type differences */
+    and_mask = xmask & ymask;           /* mark field specification */
+
+    /* year */
+    if (xor_mask & 1)
+        return 2; /* indeterminate */
+    else if (and_mask & 1) {
+        if (x->value.date.year < y->value.date.year)
+            return -1;
+        else if (x->value.date.year > y->value.date.year)
+            return 1;
+    }
+
+    /* month */
+    if (xor_mask & 2)
+        return 2; /* indeterminate */
+    else if (and_mask & 2) {
+        if (x->value.date.mon < y->value.date.mon)
+            return -1;
+        else if (x->value.date.mon > y->value.date.mon)
+            return 1;
+    }
+
+    /* day */
+    if (xor_mask & 4)
+        return 2; /* indeterminate */
+    else if (and_mask & 4) {
+        if (x->value.date.day < y->value.date.day)
+            return -1;
+        else if (x->value.date.day > y->value.date.day)
+            return 1;
+    }
+
+    /* time */
+    if (xor_mask & 8)
+        return 2; /* indeterminate */
+    else if (and_mask & 8) {
+        if (x->value.date.hour < y->value.date.hour)
+            return -1;
+        else if (x->value.date.hour > y->value.date.hour)
+            return 1;
+        else if (x->value.date.min < y->value.date.min)
+            return -1;
+        else if (x->value.date.min > y->value.date.min)
+            return 1;
+        else if (x->value.date.sec < y->value.date.sec)
+            return -1;
+        else if (x->value.date.sec > y->value.date.sec)
+            return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * xmlSchemaComparePreserveReplaceStrings:
+ * @x:  a first string value
+ * @y:  a second string value
+ * @invert: inverts the result if x < y or x > y.
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "replace". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaComparePreserveReplaceStrings(const xmlChar *x,
+				       const xmlChar *y,
+				       int invert)
+{
+    int tmp;
+    
+    while ((*x != 0) && (*y != 0)) {
+	if (IS_WSP_REPLACE_CH(*y)) {
+	    if (! IS_WSP_SPACE_CH(*x)) {
+		if ((*x - 0x20) < 0) {
+		    if (invert)
+			return(1);
+		    else
+			return(-1);
+		} else {
+		    if (invert)
+			return(-1);
+		    else
+			return(1);
+		}
+	    }	    
+	} else {
+	    tmp = *x - *y;
+	    if (tmp < 0) {
+		if (invert)
+		    return(1);
+		else
+		    return(-1);
+	    }
+	    if (tmp > 0) {
+		if (invert)
+		    return(-1);
+		else
+		    return(1);
+	    }
+	}
+	x++;
+	y++;
+    }
+    if (*x != 0) {
+	if (invert)
+	    return(-1);
+	else
+	    return(1);
+    }
+    if (*y != 0) {
+	if (invert)
+	    return(1);
+	else
+	    return(-1);
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaComparePreserveCollapseStrings:
+ * @x:  a first string value
+ * @y:  a second string value
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "collapse". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaComparePreserveCollapseStrings(const xmlChar *x,
+				        const xmlChar *y,
+					int invert)
+{
+    int tmp;
+
+    /* 
+    * Skip leading blank chars of the collapsed string.
+    */
+    while IS_WSP_BLANK_CH(*y)
+	y++;
+
+    while ((*x != 0) && (*y != 0)) {
+	if IS_WSP_BLANK_CH(*y) {
+	    if (! IS_WSP_SPACE_CH(*x)) {
+		/*
+		* The yv character would have been replaced to 0x20.
+		*/
+		if ((*x - 0x20) < 0) {
+		    if (invert)
+			return(1);
+		    else
+			return(-1);
+		} else {
+		    if (invert)
+			return(-1);
+		    else
+			return(1);
+		}
+	    }
+	    x++;
+	    y++;
+	    /*
+	    * Skip contiguous blank chars of the collapsed string.
+	    */
+	    while IS_WSP_BLANK_CH(*y)
+		y++;
+	} else {
+	    tmp = *x++ - *y++;
+	    if (tmp < 0) {
+		if (invert)
+		    return(1);
+		else
+		    return(-1);
+	    }
+	    if (tmp > 0) {
+		if (invert)
+		    return(-1);
+		else
+		    return(1);
+	    }
+	}
+    }
+    if (*x != 0) {
+	 if (invert)
+	     return(-1);
+	 else
+	     return(1);
+    }
+    if (*y != 0) {
+	/*
+	* Skip trailing blank chars of the collapsed string.
+	*/
+	while IS_WSP_BLANK_CH(*y)
+	    y++;
+	if (*y != 0) {
+	    if (invert)
+		return(1);
+	    else
+		return(-1);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaComparePreserveCollapseStrings:
+ * @x:  a first string value
+ * @y:  a second string value
+ *
+ * Compare 2 string for their normalized values.
+ * @x is a string with whitespace of "preserve", @y is
+ * a string with a whitespace of "collapse". I.e. @x could
+ * be an "xsd:string" and @y an "xsd:normalizedString".
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareReplaceCollapseStrings(const xmlChar *x,
+				       const xmlChar *y,
+				       int invert)
+{
+    int tmp;
+
+    /* 
+    * Skip leading blank chars of the collapsed string.
+    */
+    while IS_WSP_BLANK_CH(*y)
+	y++;
+    
+    while ((*x != 0) && (*y != 0)) {
+	if IS_WSP_BLANK_CH(*y) {
+	    if (! IS_WSP_BLANK_CH(*x)) {
+		/*
+		* The yv character would have been replaced to 0x20.
+		*/
+		if ((*x - 0x20) < 0) {
+		    if (invert)
+			return(1);
+		    else
+			return(-1);
+		} else {
+		    if (invert)
+			return(-1);
+		    else
+			return(1);
+		}
+	    }
+	    x++;
+	    y++;	    
+	    /* 
+	    * Skip contiguous blank chars of the collapsed string.
+	    */
+	    while IS_WSP_BLANK_CH(*y)
+		y++;
+	} else {
+	    if IS_WSP_BLANK_CH(*x) {
+		/*
+		* The xv character would have been replaced to 0x20.
+		*/
+		if ((0x20 - *y) < 0) {
+		    if (invert)
+			return(1);
+		    else
+			return(-1);
+		} else {
+		    if (invert)
+			return(-1);
+		    else
+			return(1);
+		}
+	    }
+	    tmp = *x++ - *y++;
+	    if (tmp < 0)
+		return(-1);
+	    if (tmp > 0)
+		return(1);
+	}
+    }
+    if (*x != 0) {
+	 if (invert)
+	     return(-1);
+	 else
+	     return(1);
+    }   
+    if (*y != 0) {
+	/*
+	* Skip trailing blank chars of the collapsed string.
+	*/
+	while IS_WSP_BLANK_CH(*y)
+	    y++;
+	if (*y != 0) {
+	    if (invert)
+		return(1);
+	    else
+		return(-1);
+	}
+    }
+    return(0);
+}
+
+
+/**
+ * xmlSchemaCompareReplacedStrings:
+ * @x:  a first string value
+ * @y:  a second string value
+ *
+ * Compare 2 string for their normalized values.
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareReplacedStrings(const xmlChar *x,
+				const xmlChar *y)
+{
+    int tmp;
+   
+    while ((*x != 0) && (*y != 0)) {
+	if IS_WSP_BLANK_CH(*y) {
+	    if (! IS_WSP_BLANK_CH(*x)) {
+		if ((*x - 0x20) < 0)
+    		    return(-1);
+		else
+		    return(1);
+	    }	    
+	} else {
+	    if IS_WSP_BLANK_CH(*x) {
+		if ((0x20 - *y) < 0)
+    		    return(-1);
+		else
+		    return(1);
+	    }
+	    tmp = *x - *y;
+	    if (tmp < 0)
+    		return(-1);
+	    if (tmp > 0)
+    		return(1);
+	}
+	x++;
+	y++;
+    }
+    if (*x != 0)
+        return(1);
+    if (*y != 0)
+        return(-1);
+    return(0);
+}
+
+/**
+ * xmlSchemaCompareNormStrings:
+ * @x:  a first string value
+ * @y:  a second string value
+ *
+ * Compare 2 string for their normalized values.
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareNormStrings(const xmlChar *x,
+			    const xmlChar *y) {
+    int tmp;
+    
+    while (IS_BLANK_CH(*x)) x++;
+    while (IS_BLANK_CH(*y)) y++;
+    while ((*x != 0) && (*y != 0)) {
+	if (IS_BLANK_CH(*x)) {
+	    if (!IS_BLANK_CH(*y)) {
+		tmp = *x - *y;
+		return(tmp);
+	    }
+	    while (IS_BLANK_CH(*x)) x++;
+	    while (IS_BLANK_CH(*y)) y++;
+	} else {
+	    tmp = *x++ - *y++;
+	    if (tmp < 0)
+		return(-1);
+	    if (tmp > 0)
+		return(1);
+	}
+    }
+    if (*x != 0) {
+	while (IS_BLANK_CH(*x)) x++;
+	if (*x != 0)
+	    return(1);
+    }
+    if (*y != 0) {
+	while (IS_BLANK_CH(*y)) y++;
+	if (*y != 0)
+	    return(-1);
+    }
+    return(0);
+}
+
+/**
+ * xmlSchemaCompareFloats:
+ * @x:  a first float or double value
+ * @y:  a second float or double value
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareFloats(xmlSchemaValPtr x, xmlSchemaValPtr y) {
+    double d1, d2;
+
+    if ((x == NULL) || (y == NULL))
+	return(-2);
+
+    /*
+     * Cast everything to doubles.
+     */
+    if (x->type == XML_SCHEMAS_DOUBLE)
+	d1 = x->value.d;
+    else if (x->type == XML_SCHEMAS_FLOAT)
+	d1 = x->value.f;
+    else
+	return(-2);
+
+    if (y->type == XML_SCHEMAS_DOUBLE)
+	d2 = y->value.d;
+    else if (y->type == XML_SCHEMAS_FLOAT)
+	d2 = y->value.f;
+    else
+	return(-2);
+
+    /*
+     * Check for special cases.
+     */
+    if (xmlXPathIsNaN(d1)) {
+	if (xmlXPathIsNaN(d2))
+	    return(0);
+	return(1);
+    }
+    if (xmlXPathIsNaN(d2))
+	return(-1);
+    if (d1 == xmlXPathPINF) {
+	if (d2 == xmlXPathPINF)
+	    return(0);
+        return(1);
+    }
+    if (d2 == xmlXPathPINF)
+        return(-1);
+    if (d1 == xmlXPathNINF) {
+	if (d2 == xmlXPathNINF)
+	    return(0);
+        return(-1);
+    }
+    if (d2 == xmlXPathNINF)
+        return(1);
+
+    /*
+     * basic tests, the last one we should have equality, but
+     * portability is more important than speed and handling
+     * NaN or Inf in a portable way is always a challenge, so ...
+     */
+    if (d1 < d2)
+	return(-1);
+    if (d1 > d2)
+	return(1);
+    if (d1 == d2)
+	return(0);
+    return(2);
+}
+
+/**
+ * xmlSchemaCompareValues:
+ * @x:  a first value
+ * @xvalue: the first value as a string (optional)
+ * @xwtsp: the whitespace type
+ * @y:  a second value
+ * @xvalue: the second value as a string (optional)
+ * @ywtsp: the whitespace type
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, 3 if not
+ * comparable and -2 in case of error
+ */
+static int
+xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
+			       xmlSchemaValPtr x,
+			       const xmlChar *xvalue,
+			       xmlSchemaWhitespaceValueType xws,
+			       xmlSchemaValType ytype,
+			       xmlSchemaValPtr y,
+			       const xmlChar *yvalue,
+			       xmlSchemaWhitespaceValueType yws)
+{
+    switch (xtype) {
+	case XML_SCHEMAS_UNKNOWN:
+	case XML_SCHEMAS_ANYTYPE:
+	    return(-2);
+        case XML_SCHEMAS_INTEGER:
+        case XML_SCHEMAS_NPINTEGER:
+        case XML_SCHEMAS_NINTEGER:
+        case XML_SCHEMAS_NNINTEGER:
+        case XML_SCHEMAS_PINTEGER:
+        case XML_SCHEMAS_INT:
+        case XML_SCHEMAS_UINT:
+        case XML_SCHEMAS_LONG:
+        case XML_SCHEMAS_ULONG:
+        case XML_SCHEMAS_SHORT:
+        case XML_SCHEMAS_USHORT:
+        case XML_SCHEMAS_BYTE:
+        case XML_SCHEMAS_UBYTE:
+	case XML_SCHEMAS_DECIMAL:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+	    if (ytype == xtype)
+		return(xmlSchemaCompareDecimals(x, y));
+	    if ((ytype == XML_SCHEMAS_DECIMAL) ||
+		(ytype == XML_SCHEMAS_INTEGER) ||
+		(ytype == XML_SCHEMAS_NPINTEGER) ||
+		(ytype == XML_SCHEMAS_NINTEGER) ||
+		(ytype == XML_SCHEMAS_NNINTEGER) ||
+		(ytype == XML_SCHEMAS_PINTEGER) ||
+		(ytype == XML_SCHEMAS_INT) ||
+		(ytype == XML_SCHEMAS_UINT) ||
+		(ytype == XML_SCHEMAS_LONG) ||
+		(ytype == XML_SCHEMAS_ULONG) ||
+		(ytype == XML_SCHEMAS_SHORT) ||
+		(ytype == XML_SCHEMAS_USHORT) ||
+		(ytype == XML_SCHEMAS_BYTE) ||
+		(ytype == XML_SCHEMAS_UBYTE))
+		return(xmlSchemaCompareDecimals(x, y));
+	    return(-2);
+        case XML_SCHEMAS_DURATION:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+	    if (ytype == XML_SCHEMAS_DURATION)
+                return(xmlSchemaCompareDurations(x, y));
+            return(-2);
+        case XML_SCHEMAS_TIME:
+        case XML_SCHEMAS_GDAY:
+        case XML_SCHEMAS_GMONTH:
+        case XML_SCHEMAS_GMONTHDAY:
+        case XML_SCHEMAS_GYEAR:
+        case XML_SCHEMAS_GYEARMONTH:
+        case XML_SCHEMAS_DATE:
+        case XML_SCHEMAS_DATETIME:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if ((ytype == XML_SCHEMAS_DATETIME)  ||
+                (ytype == XML_SCHEMAS_TIME)      ||
+                (ytype == XML_SCHEMAS_GDAY)      ||
+                (ytype == XML_SCHEMAS_GMONTH)    ||
+                (ytype == XML_SCHEMAS_GMONTHDAY) ||
+                (ytype == XML_SCHEMAS_GYEAR)     ||
+                (ytype == XML_SCHEMAS_DATE)      ||
+                (ytype == XML_SCHEMAS_GYEARMONTH))
+                return (xmlSchemaCompareDates(x, y));
+            return (-2);
+	/* 
+	* Note that we will support comparison of string types against
+	* anySimpleType as well.
+	*/
+	case XML_SCHEMAS_ANYSIMPLETYPE:
+	case XML_SCHEMAS_STRING:
+        case XML_SCHEMAS_NORMSTRING:		
+        case XML_SCHEMAS_TOKEN:
+        case XML_SCHEMAS_LANGUAGE:
+        case XML_SCHEMAS_NMTOKEN:
+        case XML_SCHEMAS_NAME:
+        case XML_SCHEMAS_NCNAME:
+        case XML_SCHEMAS_ID:
+        case XML_SCHEMAS_IDREF:
+        case XML_SCHEMAS_ENTITY:
+        case XML_SCHEMAS_ANYURI:
+	{
+	    const xmlChar *xv, *yv;
+
+	    if (x == NULL)
+		xv = xvalue;
+	    else
+		xv = x->value.str;
+	    if (y == NULL)
+		yv = yvalue;
+	    else
+		yv = y->value.str;
+	    /*
+	    * TODO: Compare those against QName.
+	    */
+	    if (ytype == XML_SCHEMAS_QNAME) {		
+		TODO
+		if (y == NULL)
+		    return(-2);    
+		return (-2);
+	    }
+            if ((ytype == XML_SCHEMAS_ANYSIMPLETYPE) ||
+		(ytype == XML_SCHEMAS_STRING) ||
+		(ytype == XML_SCHEMAS_NORMSTRING) ||
+                (ytype == XML_SCHEMAS_TOKEN) ||
+                (ytype == XML_SCHEMAS_LANGUAGE) ||
+                (ytype == XML_SCHEMAS_NMTOKEN) ||
+                (ytype == XML_SCHEMAS_NAME) ||
+                (ytype == XML_SCHEMAS_NCNAME) ||
+                (ytype == XML_SCHEMAS_ID) ||
+                (ytype == XML_SCHEMAS_IDREF) ||
+                (ytype == XML_SCHEMAS_ENTITY) ||
+                (ytype == XML_SCHEMAS_ANYURI)) {
+
+		if (xws == XML_SCHEMA_WHITESPACE_PRESERVE) {
+
+		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE) {
+			/* TODO: What about x < y or x > y. */
+			if (xmlStrEqual(xv, yv))
+			    return (0);
+			else 
+			    return (2);
+		    } else if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+			return (xmlSchemaComparePreserveReplaceStrings(xv, yv, 0));
+		    else if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			return (xmlSchemaComparePreserveCollapseStrings(xv, yv, 0));
+
+		} else if (xws == XML_SCHEMA_WHITESPACE_REPLACE) {
+
+		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
+			return (xmlSchemaComparePreserveReplaceStrings(yv, xv, 1));
+		    if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+			return (xmlSchemaCompareReplacedStrings(xv, yv));
+		    if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			return (xmlSchemaCompareReplaceCollapseStrings(xv, yv, 0));
+
+		} else if (xws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
+
+		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
+			return (xmlSchemaComparePreserveCollapseStrings(yv, xv, 1));
+		    if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
+			return (xmlSchemaCompareReplaceCollapseStrings(yv, xv, 1));
+		    if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			return (xmlSchemaCompareNormStrings(xv, yv));
+		} else
+		    return (-2);
+                
+	    }
+            return (-2);
+	}
+        case XML_SCHEMAS_QNAME:
+	case XML_SCHEMAS_NOTATION:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if ((ytype == XML_SCHEMAS_QNAME) ||
+		(ytype == XML_SCHEMAS_NOTATION)) {
+		if ((xmlStrEqual(x->value.qname.name, y->value.qname.name)) &&
+		    (xmlStrEqual(x->value.qname.uri, y->value.qname.uri)))
+		    return(0);
+		return(2);
+	    }
+	    return (-2);
+        case XML_SCHEMAS_FLOAT:
+        case XML_SCHEMAS_DOUBLE:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if ((ytype == XML_SCHEMAS_FLOAT) ||
+                (ytype == XML_SCHEMAS_DOUBLE))
+                return (xmlSchemaCompareFloats(x, y));
+            return (-2);
+        case XML_SCHEMAS_BOOLEAN:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_BOOLEAN) {
+		if (x->value.b == y->value.b)
+		    return(0);
+		if (x->value.b == 0)
+		    return(-1);
+		return(1);
+	    }
+	    return (-2);
+        case XML_SCHEMAS_HEXBINARY:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_HEXBINARY) {
+	        if (x->value.hex.total == y->value.hex.total) {
+		    int ret = xmlStrcmp(x->value.hex.str, y->value.hex.str);
+		    if (ret > 0)
+			return(1);
+		    else if (ret == 0)
+			return(0);
+		}
+		else if (x->value.hex.total > y->value.hex.total)
+		    return(1);
+
+		return(-1);
+            }
+            return (-2);
+        case XML_SCHEMAS_BASE64BINARY:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_BASE64BINARY) {
+                if (x->value.base64.total == y->value.base64.total) {
+                    int ret = xmlStrcmp(x->value.base64.str,
+		                        y->value.base64.str);
+                    if (ret > 0)
+                        return(1);
+                    else if (ret == 0)
+                        return(0);
+		    else
+		        return(-1);
+                }
+                else if (x->value.base64.total > y->value.base64.total)
+                    return(1);
+                else
+                    return(-1);
+            }
+            return (-2);    
+        case XML_SCHEMAS_IDREFS:
+        case XML_SCHEMAS_ENTITIES:
+        case XML_SCHEMAS_NMTOKENS:
+	    TODO
+	    break;
+    }
+    return -2;
+}
+
+/**
+ * xmlSchemaCompareValues:
+ * @x:  a first value
+ * @y:  a second value
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+int
+xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
+    xmlSchemaWhitespaceValueType xws, yws;
+
+    if ((x == NULL) || (y == NULL))
+        return(-2);
+    if (x->type == XML_SCHEMAS_STRING)
+	xws = XML_SCHEMA_WHITESPACE_PRESERVE;
+    else if (x->type == XML_SCHEMAS_NORMSTRING)
+        xws = XML_SCHEMA_WHITESPACE_REPLACE;
+    else
+        xws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
+    if (y->type == XML_SCHEMAS_STRING)
+	yws = XML_SCHEMA_WHITESPACE_PRESERVE;
+    else if (x->type == XML_SCHEMAS_NORMSTRING)
+        yws = XML_SCHEMA_WHITESPACE_REPLACE;
+    else
+        yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
+    return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
+	y, NULL, yws));
+}
+
+/**
+ * xmlSchemaCompareValuesWhtsp:
+ * @x:  a first value
+ * @xws: the whitespace value of x
+ * @y:  a second value
+ * @yws: the whitespace value of y
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+int
+xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
+			    xmlSchemaWhitespaceValueType xws,
+			    xmlSchemaValPtr y,
+			    xmlSchemaWhitespaceValueType yws)
+{
+    if ((x == NULL) || (y == NULL))
+	return(-2);
+    return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
+	y, NULL, yws));
+}
+
+/**
+ * xmlSchemaCompareValuesWhtspExt:
+ * @x:  a first value
+ * @xws: the whitespace value of x
+ * @y:  a second value
+ * @yws: the whitespace value of y
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareValuesWhtspExt(xmlSchemaValType xtype,
+			       xmlSchemaValPtr x,
+			       const xmlChar *xvalue,
+			       xmlSchemaWhitespaceValueType xws,
+			       xmlSchemaValType ytype,
+			       xmlSchemaValPtr y,
+			       const xmlChar *yvalue,
+			       xmlSchemaWhitespaceValueType yws)
+{
+    return(xmlSchemaCompareValuesInternal(xtype, x, xvalue, xws, ytype, y,
+	yvalue, yws));
+}
+
+/**
+ * xmlSchemaNormLen:
+ * @value:  a string
+ *
+ * Computes the UTF8 length of the normalized value of the string
+ *
+ * Returns the length or -1 in case of error.
+ */
+static int
+xmlSchemaNormLen(const xmlChar *value) {
+    const xmlChar *utf;
+    int ret = 0;
+
+    if (value == NULL)
+	return(-1);
+    utf = value;
+    while (IS_BLANK_CH(*utf)) utf++;
+    while (*utf != 0) {
+	if (utf[0] & 0x80) {
+	    if ((utf[1] & 0xc0) != 0x80)
+		return(-1);
+	    if ((utf[0] & 0xe0) == 0xe0) {
+		if ((utf[2] & 0xc0) != 0x80)
+		    return(-1);
+		if ((utf[0] & 0xf0) == 0xf0) {
+		    if ((utf[0] & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+			return(-1);
+		    utf += 4;
+		} else {
+		    utf += 3;
+		}
+	    } else {
+		utf += 2;
+	    }
+	} else if (IS_BLANK_CH(*utf)) {
+	    while (IS_BLANK_CH(*utf)) utf++;
+	    if (*utf == 0)
+		break;
+	} else {
+	    utf++;
+	}
+	ret++;
+    }
+    return(ret);
+}
+
+/**
+ * xmlSchemaGetFacetValueAsULong:
+ * @facet: an schemas type facet
+ *
+ * Extract the value of a facet
+ *
+ * Returns the value as a long
+ */
+unsigned long
+xmlSchemaGetFacetValueAsULong(xmlSchemaFacetPtr facet)
+{
+    /*
+    * TODO: Check if this is a decimal.
+    */
+    if (facet == NULL)
+        return 0;
+    return ((unsigned long) facet->val->value.decimal.lo);
+}
+
+/**
+ * xmlSchemaValidateListSimpleTypeFacet:
+ * @facet:  the facet to check
+ * @value:  the lexical repr of the value to validate
+ * @actualLen:  the number of list items
+ * @expectedLen: the resulting expected number of list items
+ *
+ * Checks the value of a list simple type against a facet.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * number otherwise and -1 in case of an internal error.
+ */
+int
+xmlSchemaValidateListSimpleTypeFacet(xmlSchemaFacetPtr facet,
+				     const xmlChar *value,
+				     unsigned long actualLen,
+				     unsigned long *expectedLen)
+{
+    if (facet == NULL)
+        return(-1);
+    /*
+    * TODO: Check if this will work with large numbers.
+    * (compare value.decimal.mi and value.decimal.hi as well?).
+    */
+    if (facet->type == XML_SCHEMA_FACET_LENGTH) {
+	if (actualLen != facet->val->value.decimal.lo) {
+	    if (expectedLen != NULL)
+		*expectedLen = facet->val->value.decimal.lo;
+	    return (XML_SCHEMAV_CVC_LENGTH_VALID);
+	}	
+    } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
+	if (actualLen < facet->val->value.decimal.lo) {
+	    if (expectedLen != NULL)
+		*expectedLen = facet->val->value.decimal.lo;
+	    return (XML_SCHEMAV_CVC_MINLENGTH_VALID);
+	}
+    } else if (facet->type == XML_SCHEMA_FACET_MAXLENGTH) {
+	if (actualLen > facet->val->value.decimal.lo) {
+	    if (expectedLen != NULL)
+		*expectedLen = facet->val->value.decimal.lo;
+	    return (XML_SCHEMAV_CVC_MAXLENGTH_VALID);
+	}
+    } else
+	/* 
+	* NOTE: That we can pass NULL as xmlSchemaValPtr to 
+	* xmlSchemaValidateFacet, since the remaining facet types
+	* are: XML_SCHEMA_FACET_PATTERN, XML_SCHEMA_FACET_ENUMERATION. 
+	*/
+	return(xmlSchemaValidateFacet(NULL, facet, value, NULL));   
+    return (0);
+}
+
+/**
+ * xmlSchemaValidateLengthFacet:
+ * @type:  the built-in type
+ * @facet:  the facet to check
+ * @value:  the lexical repr. of the value to be validated
+ * @val:  the precomputed value
+ * @ws: the whitespace type of the value
+ * @length: the actual length of the value
+ *
+ * Checka a value against a "length", "minLength" and "maxLength" 
+ * facet; sets @length to the computed length of @value.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * otherwise and -1 in case of an internal or API error.
+ */
+static int
+xmlSchemaValidateLengthFacetInternal(xmlSchemaFacetPtr facet,
+				     xmlSchemaValType valType,
+				     const xmlChar *value,
+				     xmlSchemaValPtr val,
+				     unsigned long *length,
+				     xmlSchemaWhitespaceValueType ws)  
+{
+    unsigned int len = 0;
+
+    if ((length == NULL) || (facet == NULL))
+        return (-1);
+    *length = 0;
+    if ((facet->type != XML_SCHEMA_FACET_LENGTH) &&
+	(facet->type != XML_SCHEMA_FACET_MAXLENGTH) &&
+	(facet->type != XML_SCHEMA_FACET_MINLENGTH))
+	return (-1);
+	
+    /*
+    * TODO: length, maxLength and minLength must be of type
+    * nonNegativeInteger only. Check if decimal is used somehow.
+    */
+    if ((facet->val == NULL) ||
+	((facet->val->type != XML_SCHEMAS_DECIMAL) &&
+	 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
+	(facet->val->value.decimal.frac != 0)) {
+	return(-1);
+    }
+    if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
+	len = val->value.hex.total;
+    else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
+	len = val->value.base64.total;
+    else {
+	switch (valType) {
+	    case XML_SCHEMAS_STRING:
+	    case XML_SCHEMAS_NORMSTRING:
+		if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
+		    /*
+		    * This is to ensure API compatibility with the old
+		    * xmlSchemaValidateLengthFacet(). Anyway, this was and
+		    * is not the correct handling.
+		    * TODO: Get rid of this case somehow.
+		    */
+		    if (valType == XML_SCHEMAS_STRING)
+			len = xmlUTF8Strlen(value);
+		    else
+			len = xmlSchemaNormLen(value);
+		} else if (value != NULL) {
+		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+			len = xmlSchemaNormLen(value);
+		    else
+		    /* 
+		    * Should be OK for "preserve" as well.
+		    */
+		    len = xmlUTF8Strlen(value);
+		}
+		break;
+	    case XML_SCHEMAS_IDREF:
+	    case XML_SCHEMAS_TOKEN:
+	    case XML_SCHEMAS_LANGUAGE:
+	    case XML_SCHEMAS_NMTOKEN:
+	    case XML_SCHEMAS_NAME:
+	    case XML_SCHEMAS_NCNAME:
+	    case XML_SCHEMAS_ID:		
+		/*
+		* FIXME: What exactly to do with anyURI?
+		*/
+	    case XML_SCHEMAS_ANYURI:
+		if (value != NULL)
+		    len = xmlSchemaNormLen(value);
+		break;
+	    case XML_SCHEMAS_QNAME:
+ 	    case XML_SCHEMAS_NOTATION:
+ 		/*
+		* For QName and NOTATION, those facets are
+		* deprecated and should be ignored.
+ 		*/
+		return (0);
+	    default:
+		TODO
+	}
+    }
+    *length = (unsigned long) len;
+    /*
+    * TODO: Return the whole expected value, i.e. "lo", "mi" and "hi".
+    */
+    if (facet->type == XML_SCHEMA_FACET_LENGTH) {
+	if (len != facet->val->value.decimal.lo)
+	    return(XML_SCHEMAV_CVC_LENGTH_VALID);
+    } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
+	if (len < facet->val->value.decimal.lo)
+	    return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
+    } else {
+	if (len > facet->val->value.decimal.lo)
+	    return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
+    }
+    
+    return (0);
+}
+
+/**
+ * xmlSchemaValidateLengthFacet:
+ * @type:  the built-in type
+ * @facet:  the facet to check
+ * @value:  the lexical repr. of the value to be validated
+ * @val:  the precomputed value
+ * @length: the actual length of the value
+ *
+ * Checka a value against a "length", "minLength" and "maxLength" 
+ * facet; sets @length to the computed length of @value.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * otherwise and -1 in case of an internal or API error.
+ */
+int
+xmlSchemaValidateLengthFacet(xmlSchemaTypePtr type, 
+			     xmlSchemaFacetPtr facet,
+			     const xmlChar *value,
+			     xmlSchemaValPtr val,
+			     unsigned long *length)  
+{
+    if (type == NULL)
+        return(-1);
+    return (xmlSchemaValidateLengthFacetInternal(facet,
+	type->builtInType, value, val, length,
+	XML_SCHEMA_WHITESPACE_UNKNOWN));
+}
+
+/**
+ * xmlSchemaValidateLengthFacetWhtsp: 
+ * @facet:  the facet to check
+ * @valType:  the built-in type
+ * @value:  the lexical repr. of the value to be validated
+ * @val:  the precomputed value
+ * @ws: the whitespace type of the value
+ * @length: the actual length of the value
+ *
+ * Checka a value against a "length", "minLength" and "maxLength" 
+ * facet; sets @length to the computed length of @value.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ * otherwise and -1 in case of an internal or API error.
+ */
+int
+xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet,
+				  xmlSchemaValType valType,
+				  const xmlChar *value,
+				  xmlSchemaValPtr val,
+				  unsigned long *length,
+				  xmlSchemaWhitespaceValueType ws)
+{
+    return (xmlSchemaValidateLengthFacetInternal(facet, valType, value, val,
+	length, ws));
+}
+
+/**
+ * xmlSchemaValidateFacetInternal:
+ * @facet:  the facet to check
+ * @fws: the whitespace type of the facet's value
+ * @valType: the built-in type of the value
+ * @value:  the lexical repr of the value to validate
+ * @val:  the precomputed value
+ * @ws: the whitespace type of the value
+ *
+ * Check a value against a facet condition
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
+			       xmlSchemaWhitespaceValueType fws,
+			       xmlSchemaValType valType,			       
+			       const xmlChar *value,
+			       xmlSchemaValPtr val,
+			       xmlSchemaWhitespaceValueType ws)
+{
+    int ret;
+
+    if (facet == NULL)
+	return(-1);
+
+    switch (facet->type) {
+	case XML_SCHEMA_FACET_PATTERN:
+	    /* 
+	    * NOTE that for patterns, the @value needs to be the normalized
+	    * value, *not* the lexical initial value or the canonical value.
+	    */
+	    if (value == NULL)
+		return(-1);
+	    ret = xmlRegexpExec(facet->regexp, value);
+	    if (ret == 1)
+		return(0);
+	    if (ret == 0)
+		return(XML_SCHEMAV_CVC_PATTERN_VALID);
+	    return(ret);
+	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+	    ret = xmlSchemaCompareValues(val, facet->val);
+	    if (ret == -2)
+		return(-1);
+	    if (ret == -1)
+		return(0);
+	    return(XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID);
+	case XML_SCHEMA_FACET_MAXINCLUSIVE:
+	    ret = xmlSchemaCompareValues(val, facet->val);
+	    if (ret == -2)
+		return(-1);
+	    if ((ret == -1) || (ret == 0))
+		return(0);
+	    return(XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID);
+	case XML_SCHEMA_FACET_MINEXCLUSIVE:
+	    ret = xmlSchemaCompareValues(val, facet->val);
+	    if (ret == -2)
+		return(-1);
+	    if (ret == 1)
+		return(0);
+	    return(XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID);
+	case XML_SCHEMA_FACET_MININCLUSIVE:
+	    ret = xmlSchemaCompareValues(val, facet->val);
+	    if (ret == -2)
+		return(-1);
+	    if ((ret == 1) || (ret == 0))
+		return(0);
+	    return(XML_SCHEMAV_CVC_MININCLUSIVE_VALID);
+	case XML_SCHEMA_FACET_WHITESPACE:
+	    /* TODO whitespaces */
+	    /*
+	    * NOTE: Whitespace should be handled to normalize
+	    * the value to be validated against a the facets;
+	    * not to normalize the value in-between.
+	    */
+	    return(0);
+	case  XML_SCHEMA_FACET_ENUMERATION:
+	    if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
+		/*
+		* This is to ensure API compatibility with the old
+		* xmlSchemaValidateFacet().
+		* TODO: Get rid of this case.
+		*/
+		if ((facet->value != NULL) &&
+		    (xmlStrEqual(facet->value, value)))
+		    return(0);
+	    } else {
+		ret = xmlSchemaCompareValuesWhtspExt(facet->val->type,
+		    facet->val, facet->value, fws, valType, val,
+		    value, ws);
+		if (ret == -2)
+		    return(-1);
+		if (ret == 0)
+		    return(0);
+	    }
+	    return(XML_SCHEMAV_CVC_ENUMERATION_VALID);
+	case XML_SCHEMA_FACET_LENGTH:
+	    /*
+	    * SPEC (1.3) "if {primitive type definition} is QName or NOTATION,
+	    * then any {value} is facet-valid."
+	    */
+	    if ((valType == XML_SCHEMAS_QNAME) ||
+		(valType == XML_SCHEMAS_NOTATION))
+		return (0);
+	    /* No break on purpose. */
+	case XML_SCHEMA_FACET_MAXLENGTH:
+	case XML_SCHEMA_FACET_MINLENGTH: {
+	    unsigned int len = 0;
+
+	    if ((valType == XML_SCHEMAS_QNAME) ||
+		(valType == XML_SCHEMAS_NOTATION))
+		return (0);
+	    /*
+	    * TODO: length, maxLength and minLength must be of type
+	    * nonNegativeInteger only. Check if decimal is used somehow.
+	    */
+	    if ((facet->val == NULL) ||
+		((facet->val->type != XML_SCHEMAS_DECIMAL) &&
+		 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
+		(facet->val->value.decimal.frac != 0)) {
+		return(-1);
+	    }
+	    if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
+		len = val->value.hex.total;
+	    else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
+		len = val->value.base64.total;
+	    else {
+		switch (valType) {
+		    case XML_SCHEMAS_STRING:
+		    case XML_SCHEMAS_NORMSTRING:			
+			if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
+			    /*
+			    * This is to ensure API compatibility with the old
+			    * xmlSchemaValidateFacet(). Anyway, this was and
+			    * is not the correct handling.
+			    * TODO: Get rid of this case somehow.
+			    */
+			    if (valType == XML_SCHEMAS_STRING)
+				len = xmlUTF8Strlen(value);
+			    else
+				len = xmlSchemaNormLen(value);
+			} else if (value != NULL) {
+			    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+				len = xmlSchemaNormLen(value);
+			    else
+				/* 
+				* Should be OK for "preserve" as well.
+				*/
+				len = xmlUTF8Strlen(value);
+			}
+			break;
+	    	    case XML_SCHEMAS_IDREF:		    
+		    case XML_SCHEMAS_TOKEN:
+		    case XML_SCHEMAS_LANGUAGE:
+		    case XML_SCHEMAS_NMTOKEN:
+		    case XML_SCHEMAS_NAME:
+		    case XML_SCHEMAS_NCNAME:
+		    case XML_SCHEMAS_ID:
+		    case XML_SCHEMAS_ANYURI:
+			if (value != NULL)
+		    	    len = xmlSchemaNormLen(value);
+		    	break;		   
+		    default:
+		        TODO
+	    	}
+	    }
+	    if (facet->type == XML_SCHEMA_FACET_LENGTH) {
+		if (len != facet->val->value.decimal.lo)
+		    return(XML_SCHEMAV_CVC_LENGTH_VALID);
+	    } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
+		if (len < facet->val->value.decimal.lo)
+		    return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
+	    } else {
+		if (len > facet->val->value.decimal.lo)
+		    return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
+	    }
+	    break;
+	}
+	case XML_SCHEMA_FACET_TOTALDIGITS:
+	case XML_SCHEMA_FACET_FRACTIONDIGITS:
+
+	    if ((facet->val == NULL) ||
+		((facet->val->type != XML_SCHEMAS_PINTEGER) &&
+		 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
+		(facet->val->value.decimal.frac != 0)) {
+		return(-1);
+	    }
+	    if ((val == NULL) ||
+		((val->type != XML_SCHEMAS_DECIMAL) &&
+		 (val->type != XML_SCHEMAS_INTEGER) &&
+		 (val->type != XML_SCHEMAS_NPINTEGER) &&
+		 (val->type != XML_SCHEMAS_NINTEGER) &&
+		 (val->type != XML_SCHEMAS_NNINTEGER) &&
+		 (val->type != XML_SCHEMAS_PINTEGER) &&
+		 (val->type != XML_SCHEMAS_INT) &&
+		 (val->type != XML_SCHEMAS_UINT) &&
+		 (val->type != XML_SCHEMAS_LONG) &&
+		 (val->type != XML_SCHEMAS_ULONG) &&
+		 (val->type != XML_SCHEMAS_SHORT) &&
+		 (val->type != XML_SCHEMAS_USHORT) &&
+		 (val->type != XML_SCHEMAS_BYTE) &&
+		 (val->type != XML_SCHEMAS_UBYTE))) {
+		return(-1);
+	    }
+	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
+	        if (val->value.decimal.total > facet->val->value.decimal.lo)
+	            return(XML_SCHEMAV_CVC_TOTALDIGITS_VALID);
+
+	    } else if (facet->type == XML_SCHEMA_FACET_FRACTIONDIGITS) {
+	        if (val->value.decimal.frac > facet->val->value.decimal.lo)
+		    return(XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID);
+	    }
+	    break;
+	default:
+	    TODO
+    }
+    return(0);
+
+}
+
+/**
+ * xmlSchemaValidateFacet:
+ * @base:  the base type
+ * @facet:  the facet to check
+ * @value:  the lexical repr of the value to validate
+ * @val:  the precomputed value
+ *
+ * Check a value against a facet condition
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidateFacet(xmlSchemaTypePtr base,
+	               xmlSchemaFacetPtr facet,
+	               const xmlChar *value,
+		       xmlSchemaValPtr val)
+{
+    /*
+    * This tries to ensure API compatibility regarding the old
+    * xmlSchemaValidateFacet() and the new xmlSchemaValidateFacetInternal() and
+    * xmlSchemaValidateFacetWhtsp().
+    */
+    if (val != NULL)
+	return(xmlSchemaValidateFacetInternal(facet,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN, val->type, value, val,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN));
+    else if (base != NULL)
+	return(xmlSchemaValidateFacetInternal(facet,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN, base->builtInType, value, val,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN));
+    return(-1);
+}
+
+/**
+ * xmlSchemaValidateFacetWhtsp:
+ * @facet:  the facet to check
+ * @fws: the whitespace type of the facet's value
+ * @valType: the built-in type of the value
+ * @value:  the lexical (or normalized for pattern) repr of the value to validate
+ * @val:  the precomputed value
+ * @ws: the whitespace type of the value
+ *
+ * Check a value against a facet condition. This takes value normalization
+ * according to the specified whitespace types into account.
+ * Note that @value needs to be the *normalized* value if the facet
+ * is of type "pattern".
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidateFacetWhtsp(xmlSchemaFacetPtr facet,
+			    xmlSchemaWhitespaceValueType fws,
+			    xmlSchemaValType valType,			    
+			    const xmlChar *value,
+			    xmlSchemaValPtr val,
+			    xmlSchemaWhitespaceValueType ws)
+{
+     return(xmlSchemaValidateFacetInternal(facet, fws, valType,
+	 value, val, ws));
+}
+
+#if 0
+#ifndef DBL_DIG
+#define DBL_DIG 16
+#endif
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 1E-9
+#endif
+
+#define INTEGER_DIGITS DBL_DIG
+#define FRACTION_DIGITS (DBL_DIG + 1)
+#define EXPONENT_DIGITS (3 + 2)
+
+/**
+ * xmlXPathFormatNumber:
+ * @number:     number to format
+ * @buffer:     output buffer
+ * @buffersize: size of output buffer
+ *
+ * Convert the number into a string representation.
+ */
+static void
+xmlSchemaFormatFloat(double number, char buffer[], int buffersize)
+{
+    switch (xmlXPathIsInf(number)) {
+    case 1:
+	if (buffersize > (int)sizeof("INF"))
+	    snprintf(buffer, buffersize, "INF");
+	break;
+    case -1:
+	if (buffersize > (int)sizeof("-INF"))
+	    snprintf(buffer, buffersize, "-INF");
+	break;
+    default:
+	if (xmlXPathIsNaN(number)) {
+	    if (buffersize > (int)sizeof("NaN"))
+		snprintf(buffer, buffersize, "NaN");
+	} else if (number == 0) {
+	    snprintf(buffer, buffersize, "0.0E0");
+	} else {
+	    /* 3 is sign, decimal point, and terminating zero */
+	    char work[DBL_DIG + EXPONENT_DIGITS + 3];
+	    int integer_place, fraction_place;
+	    char *ptr;
+	    char *after_fraction;
+	    double absolute_value;
+	    int size;
+
+	    absolute_value = fabs(number);
+
+	    /*
+	     * Result is in work, and after_fraction points
+	     * just past the fractional part.
+	     * Use scientific notation 
+	    */
+	    integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
+	    fraction_place = DBL_DIG - 1;
+	    snprintf(work, sizeof(work),"%*.*e",
+		integer_place, fraction_place, number);
+	    after_fraction = strchr(work + DBL_DIG, 'e');	    
+	    /* Remove fractional trailing zeroes */
+	    ptr = after_fraction;
+	    while (*(--ptr) == '0')
+		;
+	    if (*ptr != '.')
+	        ptr++;
+	    while ((*ptr++ = *after_fraction++) != 0);
+
+	    /* Finally copy result back to caller */
+	    size = strlen(work) + 1;
+	    if (size > buffersize) {
+		work[buffersize - 1] = 0;
+		size = buffersize;
+	    }
+	    memmove(buffer, work, size);
+	}
+	break;
+    }
+}
+#endif
+
+/**
+ * xmlSchemaGetCanonValue:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ *
+ * Get a the cononical lexical representation of the value.
+ * The caller has to FREE the returned retValue.
+ *
+ * WARNING: Some value types are not supported yet, resulting
+ * in a @retValue of "???".
+ * 
+ * TODO: XML Schema 1.0 does not define canonical representations
+ * for: duration, gYearMonth, gYear, gMonthDay, gMonth, gDay,
+ * anyURI, QName, NOTATION. This will be fixed in XML Schema 1.1.
+ *
+ *
+ * Returns 0 if the value could be built, 1 if the value type is
+ * not supported yet and -1 in case of API errors.
+ */
+int
+xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
+{
+    if ((retValue == NULL) || (val == NULL))
+	return (-1);
+    *retValue = NULL;
+    switch (val->type) {
+	case XML_SCHEMAS_STRING:
+	    if (val->value.str == NULL)
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+	    else
+		*retValue = 
+		    BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
+	    break;
+	case XML_SCHEMAS_NORMSTRING:
+	    if (val->value.str == NULL)
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+	    else {
+		*retValue = xmlSchemaWhiteSpaceReplace(
+		    (const xmlChar *) val->value.str);
+		if ((*retValue) == NULL)
+		    *retValue = BAD_CAST xmlStrdup(
+			(const xmlChar *) val->value.str);
+	    }
+	    break;
+	case XML_SCHEMAS_TOKEN:
+	case XML_SCHEMAS_LANGUAGE:
+	case XML_SCHEMAS_NMTOKEN:
+	case XML_SCHEMAS_NAME:	
+	case XML_SCHEMAS_NCNAME:
+	case XML_SCHEMAS_ID:
+	case XML_SCHEMAS_IDREF:
+	case XML_SCHEMAS_ENTITY:
+	case XML_SCHEMAS_NOTATION: /* Unclear */
+	case XML_SCHEMAS_ANYURI:   /* Unclear */
+	    if (val->value.str == NULL)
+		return (-1);
+	    *retValue = 
+		BAD_CAST xmlSchemaCollapseString(BAD_CAST val->value.str);
+	    if (*retValue == NULL)
+		*retValue = 
+		    BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
+	    break;
+	case XML_SCHEMAS_QNAME:
+	    /* TODO: Unclear in XML Schema 1.0. */
+	    if (val->value.qname.uri == NULL) {
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.qname.name);
+		return (0);
+	    } else {
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "{");
+		*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
+		    BAD_CAST val->value.qname.uri);
+		*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
+		    BAD_CAST "}");
+		*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
+		    BAD_CAST val->value.qname.uri);
+	    }
+	    break;
+	case XML_SCHEMAS_DECIMAL:
+	    /*
+	    * TODO: Lookout for a more simple implementation.
+	    */
+	    if ((val->value.decimal.total == 1) && 
+		(val->value.decimal.lo == 0)) {
+		*retValue = xmlStrdup(BAD_CAST "0.0");
+	    } else {
+		xmlSchemaValDecimal dec = val->value.decimal;
+		int bufsize;
+		char *buf = NULL, *offs;
+
+		/* Add room for the decimal point as well. */
+		bufsize = dec.total + 2;
+		if (dec.sign)
+		    bufsize++;
+		/* Add room for leading/trailing zero. */
+		if ((dec.frac == 0) || (dec.frac == dec.total))
+		    bufsize++;
+		buf = xmlMalloc(bufsize);
+		if (buf == NULL)
+		    return(-1);
+		offs = buf;
+		if (dec.sign)
+		    *offs++ = '-';
+		if (dec.frac == dec.total) {
+		    *offs++ = '0';
+		    *offs++ = '.';
+		}
+		if (dec.hi != 0)
+		    snprintf(offs, bufsize - (offs - buf),
+			"%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+		else if (dec.mi != 0)
+		    snprintf(offs, bufsize - (offs - buf),
+			"%lu%lu", dec.mi, dec.lo);
+		else
+		    snprintf(offs, bufsize - (offs - buf),
+			"%lu", dec.lo);
+			
+		if (dec.frac != 0) {
+		    if (dec.frac != dec.total) {
+			int diff = dec.total - dec.frac;
+			/*
+			* Insert the decimal point.
+			*/
+			memmove(offs + diff + 1, offs + diff, dec.frac +1);
+			offs[diff] = '.';
+		    } else {
+			unsigned int i = 0;
+			/*
+			* Insert missing zeroes behind the decimal point.
+			*/			
+			while (*(offs + i) != 0)
+			    i++;
+			if (i < dec.total) {
+			    memmove(offs + (dec.total - i), offs, i +1);
+			    memset(offs, '0', dec.total - i);
+			}
+		    }
+		} else {
+		    /*
+		    * Append decimal point and zero.
+		    */
+		    offs = buf + bufsize - 1;
+		    *offs-- = 0;
+		    *offs-- = '0';
+		    *offs-- = '.';
+		}
+		*retValue = BAD_CAST buf;
+	    }
+	    break;
+	case XML_SCHEMAS_INTEGER:
+        case XML_SCHEMAS_PINTEGER:
+        case XML_SCHEMAS_NPINTEGER:
+        case XML_SCHEMAS_NINTEGER:
+        case XML_SCHEMAS_NNINTEGER:
+	case XML_SCHEMAS_LONG:
+        case XML_SCHEMAS_BYTE:
+        case XML_SCHEMAS_SHORT:
+        case XML_SCHEMAS_INT:
+	case XML_SCHEMAS_UINT:
+        case XML_SCHEMAS_ULONG:
+        case XML_SCHEMAS_USHORT:
+        case XML_SCHEMAS_UBYTE:
+	    if ((val->value.decimal.total == 1) &&
+		(val->value.decimal.lo == 0))
+		*retValue = xmlStrdup(BAD_CAST "0");
+	    else {
+		xmlSchemaValDecimal dec = val->value.decimal;
+		int bufsize = dec.total + 1;
+
+		/* Add room for the decimal point as well. */
+		if (dec.sign)
+		    bufsize++;
+		*retValue = xmlMalloc(bufsize);
+		if (*retValue == NULL)
+		    return(-1);
+		if (dec.hi != 0) {
+		    if (dec.sign)
+			snprintf((char *) *retValue, bufsize,
+			    "-%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+		    else
+			snprintf((char *) *retValue, bufsize,
+			    "%lu%lu%lu", dec.hi, dec.mi, dec.lo);
+		} else if (dec.mi != 0) {
+		    if (dec.sign)
+			snprintf((char *) *retValue, bufsize,
+			    "-%lu%lu", dec.mi, dec.lo);
+		    else
+			snprintf((char *) *retValue, bufsize,
+			    "%lu%lu", dec.mi, dec.lo);
+		} else {
+		    if (dec.sign)
+			snprintf((char *) *retValue, bufsize, "-%lu", dec.lo);
+		    else
+			snprintf((char *) *retValue, bufsize, "%lu", dec.lo);
+		}
+	    }
+	    break;
+	case XML_SCHEMAS_BOOLEAN:
+	    if (val->value.b)
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "true");
+	    else
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "false");
+	    break;
+	case XML_SCHEMAS_DURATION: {
+		char buf[100];
+		unsigned long year;
+		unsigned long mon, day, hour = 0, min = 0;
+		double sec = 0, left;
+
+		/* TODO: Unclear in XML Schema 1.0 */
+		/*
+		* TODO: This results in a normalized output of the value
+		* - which is NOT conformant to the spec -
+		* since the exact values of each property are not
+		* recoverable. Think about extending the structure to
+		* provide a field for every property.
+		*/
+		year = (unsigned long) FQUOTIENT(labs(val->value.dur.mon), 12);
+		mon = labs(val->value.dur.mon) - 12 * year;
+
+		day = (unsigned long) FQUOTIENT(fabs(val->value.dur.sec), 86400);
+		left = fabs(val->value.dur.sec) - day * 86400;
+		if (left > 0) {
+		    hour = (unsigned long) FQUOTIENT(left, 3600);
+		    left = left - (hour * 3600);
+		    if (left > 0) {
+			min = (unsigned long) FQUOTIENT(left, 60);
+			sec = left - (min * 60);
+		    }
+		}
+		if ((val->value.dur.mon < 0) || (val->value.dur.sec < 0))
+		    snprintf(buf, 100, "P%luY%luM%luDT%luH%luM%.14gS",
+			year, mon, day, hour, min, sec);
+		else
+		    snprintf(buf, 100, "-P%luY%luM%luDT%luH%luM%.14gS",
+			year, mon, day, hour, min, sec);
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;
+	case XML_SCHEMAS_GYEAR: {
+		char buf[30];
+		/* TODO: Unclear in XML Schema 1.0 */
+		/* TODO: What to do with the timezone? */
+		snprintf(buf, 30, "%04ld", val->value.date.year);
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;
+	case XML_SCHEMAS_GMONTH: {
+		/* TODO: Unclear in XML Schema 1.0 */
+		/* TODO: What to do with the timezone? */
+		*retValue = xmlMalloc(6);
+		if (*retValue == NULL)
+		    return(-1);
+		snprintf((char *) *retValue, 6, "--%02u",
+		    val->value.date.mon);
+	    }
+	    break;
+        case XML_SCHEMAS_GDAY: {
+		/* TODO: Unclear in XML Schema 1.0 */
+		/* TODO: What to do with the timezone? */
+		*retValue = xmlMalloc(6);
+		if (*retValue == NULL)
+		    return(-1);
+		snprintf((char *) *retValue, 6, "---%02u",
+		    val->value.date.day);
+	    }
+	    break;        
+        case XML_SCHEMAS_GMONTHDAY: {
+		/* TODO: Unclear in XML Schema 1.0 */
+		/* TODO: What to do with the timezone? */
+		*retValue = xmlMalloc(8);
+		if (*retValue == NULL)
+		    return(-1);
+		snprintf((char *) *retValue, 8, "--%02u-%02u",
+		    val->value.date.mon, val->value.date.day);
+	    }
+	    break;
+        case XML_SCHEMAS_GYEARMONTH: {
+		char buf[35];
+		/* TODO: Unclear in XML Schema 1.0 */
+		/* TODO: What to do with the timezone? */
+		if (val->value.date.year < 0)
+		    snprintf(buf, 35, "-%04ld-%02u",
+			labs(val->value.date.year), 
+			val->value.date.mon);
+		else
+		    snprintf(buf, 35, "%04ld-%02u",
+			val->value.date.year, val->value.date.mon);
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;		
+	case XML_SCHEMAS_TIME:
+	    {
+		char buf[30];
+
+		if (val->value.date.tz_flag) {
+		    xmlSchemaValPtr norm;
+
+		    norm = xmlSchemaDateNormalize(val, 0);
+		    if (norm == NULL)
+			return (-1);
+		    /* 
+		    * TODO: Check if "%.14g" is portable.		    
+		    */
+		    snprintf(buf, 30,
+			"%02u:%02u:%02.14gZ",
+			norm->value.date.hour,
+			norm->value.date.min,
+			norm->value.date.sec);
+		    xmlSchemaFreeValue(norm);
+		} else {
+		    snprintf(buf, 30,
+			"%02u:%02u:%02.14g",
+			val->value.date.hour,
+			val->value.date.min,
+			val->value.date.sec);
+		}
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }	    
+	    break;
+        case XML_SCHEMAS_DATE:
+	    {
+		char buf[30];
+
+		if (val->value.date.tz_flag) {
+		    xmlSchemaValPtr norm;
+
+		    norm = xmlSchemaDateNormalize(val, 0);
+		    if (norm == NULL)
+			return (-1);
+		    /*
+		    * TODO: Append the canonical value of the
+		    * recoverable timezone and not "Z".
+		    */
+		    snprintf(buf, 30,
+			"%04ld:%02u:%02uZ",
+			norm->value.date.year, norm->value.date.mon,
+			norm->value.date.day);
+		    xmlSchemaFreeValue(norm);
+		} else {
+		    snprintf(buf, 30,
+			"%04ld:%02u:%02u",
+			val->value.date.year, val->value.date.mon,
+			val->value.date.day);
+		}
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }	    
+	    break;
+        case XML_SCHEMAS_DATETIME:
+	    {
+		char buf[50];
+
+		if (val->value.date.tz_flag) {
+		    xmlSchemaValPtr norm;
+
+		    norm = xmlSchemaDateNormalize(val, 0);
+		    if (norm == NULL)
+			return (-1);
+		    /*
+		    * TODO: Check if "%.14g" is portable.
+		    */
+		    snprintf(buf, 50,
+			"%04ld:%02u:%02uT%02u:%02u:%02.14gZ",
+			norm->value.date.year, norm->value.date.mon,
+			norm->value.date.day, norm->value.date.hour,
+			norm->value.date.min, norm->value.date.sec);
+		    xmlSchemaFreeValue(norm);
+		} else {
+		    snprintf(buf, 50,
+			"%04ld:%02u:%02uT%02u:%02u:%02.14g",
+			val->value.date.year, val->value.date.mon,
+			val->value.date.day, val->value.date.hour,
+			val->value.date.min, val->value.date.sec);
+		}
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;
+	case XML_SCHEMAS_HEXBINARY:
+	    *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.hex.str);
+	    break;
+	case XML_SCHEMAS_BASE64BINARY:
+	    /*
+	    * TODO: Is the following spec piece implemented?:
+	    * SPEC: "Note: For some values the canonical form defined
+	    * above does not conform to [RFC 2045], which requires breaking
+	    * with linefeeds at appropriate intervals."
+	    */
+	    *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.base64.str);
+	    break;
+	case XML_SCHEMAS_FLOAT: {
+		char buf[30];		
+		/* 
+		* |m| < 16777216, -149 <= e <= 104.
+		* TODO: Handle, NaN, INF, -INF. The format is not
+		* yet conformant. The c type float does not cover
+		* the whole range.
+		*/
+		snprintf(buf, 30, "%01.14e", val->value.f);
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;
+	case XML_SCHEMAS_DOUBLE: {
+		char buf[40];
+		/* |m| < 9007199254740992, -1075 <= e <= 970 */
+		/*
+		* TODO: Handle, NaN, INF, -INF. The format is not
+		* yet conformant. The c type float does not cover
+		* the whole range.
+		*/
+		snprintf(buf, 40, "%01.14e", val->value.d);
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
+	    }
+	    break;	
+	default:
+	    *retValue = BAD_CAST xmlStrdup(BAD_CAST "???");
+	    return (1);
+    }
+    if (*retValue == NULL)
+	return(-1);
+    return (0);
+}
+
+/**
+ * xmlSchemaGetCanonValueWhtsp:
+ * @val: the precomputed value
+ * @retValue: the returned value
+ * @ws: the whitespace type of the value
+ *
+ * Get a the cononical representation of the value.
+ * The caller has to free the returned @retValue.
+ *
+ * Returns 0 if the value could be built, 1 if the value type is
+ * not supported yet and -1 in case of API errors.
+ */
+int
+xmlSchemaGetCanonValueWhtsp(xmlSchemaValPtr val,
+			    const xmlChar **retValue,
+			    xmlSchemaWhitespaceValueType ws)
+{
+    if ((retValue == NULL) || (val == NULL))
+	return (-1);
+    if ((ws == XML_SCHEMA_WHITESPACE_UNKNOWN) ||
+	(ws > XML_SCHEMA_WHITESPACE_COLLAPSE))
+	return (-1);
+
+    *retValue = NULL;
+    switch (val->type) {
+	case XML_SCHEMAS_STRING:
+	    if (val->value.str == NULL)
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+	    else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+		*retValue = xmlSchemaCollapseString(val->value.str);
+	    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
+		*retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
+	    if ((*retValue) == NULL)
+		*retValue = BAD_CAST xmlStrdup(val->value.str);
+	    break;
+	case XML_SCHEMAS_NORMSTRING:
+	    if (val->value.str == NULL)
+		*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
+	    else {
+		if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
+		    *retValue = xmlSchemaCollapseString(val->value.str);
+		else
+		    *retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
+		if ((*retValue) == NULL)
+		    *retValue = BAD_CAST xmlStrdup(val->value.str);
+	    }
+	    break;
+	default:
+	    return (xmlSchemaGetCanonValue(val, retValue));
+    }    
+    return (0);
+}
+
+/**
+ * xmlSchemaGetValType:
+ * @val: a schemas value
+ *
+ * Accessor for the type of a value
+ *
+ * Returns the xmlSchemaValType of the value
+ */
+xmlSchemaValType
+xmlSchemaGetValType(xmlSchemaValPtr val)
+{
+    if (val == NULL)
+        return(XML_SCHEMAS_UNKNOWN);
+    return (val->type);
+}
+
+#define bottom_xmlschemastypes
+#include "elfgcchack.h"
+#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/src/xmlstring.c b/src/xmlstring.c
new file mode 100644
index 0000000..910f244
--- /dev/null
+++ b/src/xmlstring.c
@@ -0,0 +1,984 @@
+/*
+ * string.c : an XML string utilities module
+ *
+ * This module provides various utility functions for manipulating
+ * the xmlChar* type. All functions named xmlStr* have been moved here
+ * from the parser.c file (their original home). 
+ *
+ * See Copyright for the status of this software.
+ *
+ * UTF8 string routines from:
+ * William Brack <wbrack@mmm.com.hk>
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlstring.h>
+
+/************************************************************************
+ *                                                                      *
+ *                Commodity functions to handle xmlChars                *
+ *                                                                      *
+ ************************************************************************/
+
+/**
+ * xmlStrndup:
+ * @cur:  the input xmlChar *
+ * @len:  the len of @cur
+ *
+ * a strndup for array of xmlChar's
+ *
+ * Returns a new xmlChar * or NULL
+ */
+xmlChar *
+xmlStrndup(const xmlChar *cur, int len) {
+    xmlChar *ret;
+    
+    if ((cur == NULL) || (len < 0)) return(NULL);
+    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlErrMemory(NULL, NULL);
+        return(NULL);
+    }
+    memcpy(ret, cur, len * sizeof(xmlChar));
+    ret[len] = 0;
+    return(ret);
+}
+
+/**
+ * xmlStrdup:
+ * @cur:  the input xmlChar *
+ *
+ * a strdup for array of xmlChar's. Since they are supposed to be
+ * encoded in UTF-8 or an encoding with 8bit based chars, we assume
+ * a termination mark of '0'.
+ *
+ * Returns a new xmlChar * or NULL
+ */
+xmlChar *
+xmlStrdup(const xmlChar *cur) {
+    const xmlChar *p = cur;
+
+    if (cur == NULL) return(NULL);
+    while (*p != 0) p++; /* non input consuming */
+    return(xmlStrndup(cur, p - cur));
+}
+
+/**
+ * xmlCharStrndup:
+ * @cur:  the input char *
+ * @len:  the len of @cur
+ *
+ * a strndup for char's to xmlChar's
+ *
+ * Returns a new xmlChar * or NULL
+ */
+
+xmlChar *
+xmlCharStrndup(const char *cur, int len) {
+    int i;
+    xmlChar *ret;
+    
+    if ((cur == NULL) || (len < 0)) return(NULL);
+    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlErrMemory(NULL, NULL);
+        return(NULL);
+    }
+    for (i = 0;i < len;i++) {
+        ret[i] = (xmlChar) cur[i];
+        if (ret[i] == 0) return(ret);
+    }
+    ret[len] = 0;
+    return(ret);
+}
+
+/**
+ * xmlCharStrdup:
+ * @cur:  the input char *
+ *
+ * a strdup for char's to xmlChar's
+ *
+ * Returns a new xmlChar * or NULL
+ */
+
+xmlChar *
+xmlCharStrdup(const char *cur) {
+    const char *p = cur;
+
+    if (cur == NULL) return(NULL);
+    while (*p != '\0') p++; /* non input consuming */
+    return(xmlCharStrndup(cur, p - cur));
+}
+
+/**
+ * xmlStrcmp:
+ * @str1:  the first xmlChar *
+ * @str2:  the second xmlChar *
+ *
+ * a strcmp for xmlChar's
+ *
+ * Returns the integer result of the comparison
+ */
+
+int
+xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
+    register int tmp;
+
+    if (str1 == str2) return(0);
+    if (str1 == NULL) return(-1);
+    if (str2 == NULL) return(1);
+    do {
+        tmp = *str1++ - *str2;
+        if (tmp != 0) return(tmp);
+    } while (*str2++ != 0);
+    return 0;
+}
+
+/**
+ * xmlStrEqual:
+ * @str1:  the first xmlChar *
+ * @str2:  the second xmlChar *
+ *
+ * Check if both strings are equal of have same content.
+ * Should be a bit more readable and faster than xmlStrcmp()
+ *
+ * Returns 1 if they are equal, 0 if they are different
+ */
+
+int
+xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
+    if (str1 == str2) return(1);
+    if (str1 == NULL) return(0);
+    if (str2 == NULL) return(0);
+    do {
+        if (*str1++ != *str2) return(0);
+    } while (*str2++);
+    return(1);
+}
+
+/**
+ * xmlStrQEqual:
+ * @pref:  the prefix of the QName
+ * @name:  the localname of the QName
+ * @str:  the second xmlChar *
+ *
+ * Check if a QName is Equal to a given string 
+ *
+ * Returns 1 if they are equal, 0 if they are different
+ */
+
+int
+xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str) {
+    if (pref == NULL) return(xmlStrEqual(name, str));
+    if (name == NULL) return(0);
+    if (str == NULL) return(0);
+
+    do {
+        if (*pref++ != *str) return(0);
+    } while ((*str++) && (*pref));
+    if (*str++ != ':') return(0);
+    do {
+        if (*name++ != *str) return(0);
+    } while (*str++);
+    return(1);
+}
+
+/**
+ * xmlStrncmp:
+ * @str1:  the first xmlChar *
+ * @str2:  the second xmlChar *
+ * @len:  the max comparison length
+ *
+ * a strncmp for xmlChar's
+ *
+ * Returns the integer result of the comparison
+ */
+
+int
+xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
+    register int tmp;
+
+    if (len <= 0) return(0);
+    if (str1 == str2) return(0);
+    if (str1 == NULL) return(-1);
+    if (str2 == NULL) return(1);
+#ifdef __GNUC__
+    tmp = strncmp((const char *)str1, (const char *)str2, len);
+    return tmp;
+#else
+    do {
+        tmp = *str1++ - *str2;
+        if (tmp != 0 || --len == 0) return(tmp);
+    } while (*str2++ != 0);
+    return 0;
+#endif
+}
+
+static const xmlChar casemap[256] = {
+    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+    0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
+    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+    0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
+    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+    0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
+    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
+    0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
+    0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+    0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
+    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+    0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
+    0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+    0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
+    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+    0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
+    0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+    0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
+    0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+    0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
+    0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
+    0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
+    0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
+    0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
+    0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
+    0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
+    0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
+    0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
+    0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
+    0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
+    0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
+    0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
+};
+
+/**
+ * xmlStrcasecmp:
+ * @str1:  the first xmlChar *
+ * @str2:  the second xmlChar *
+ *
+ * a strcasecmp for xmlChar's
+ *
+ * Returns the integer result of the comparison
+ */
+
+int
+xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) {
+    register int tmp;
+
+    if (str1 == str2) return(0);
+    if (str1 == NULL) return(-1);
+    if (str2 == NULL) return(1);
+    do {
+        tmp = casemap[*str1++] - casemap[*str2];
+        if (tmp != 0) return(tmp);
+    } while (*str2++ != 0);
+    return 0;
+}
+
+/**
+ * xmlStrncasecmp:
+ * @str1:  the first xmlChar *
+ * @str2:  the second xmlChar *
+ * @len:  the max comparison length
+ *
+ * a strncasecmp for xmlChar's
+ *
+ * Returns the integer result of the comparison
+ */
+
+int
+xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len) {
+    register int tmp;
+
+    if (len <= 0) return(0);
+    if (str1 == str2) return(0);
+    if (str1 == NULL) return(-1);
+    if (str2 == NULL) return(1);
+    do {
+        tmp = casemap[*str1++] - casemap[*str2];
+        if (tmp != 0 || --len == 0) return(tmp);
+    } while (*str2++ != 0);
+    return 0;
+}
+
+/**
+ * xmlStrchr:
+ * @str:  the xmlChar * array
+ * @val:  the xmlChar to search
+ *
+ * a strchr for xmlChar's
+ *
+ * Returns the xmlChar * for the first occurrence or NULL.
+ */
+
+const xmlChar *
+xmlStrchr(const xmlChar *str, xmlChar val) {
+    if (str == NULL) return(NULL);
+    while (*str != 0) { /* non input consuming */
+        if (*str == val) return((xmlChar *) str);
+        str++;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlStrstr:
+ * @str:  the xmlChar * array (haystack)
+ * @val:  the xmlChar to search (needle)
+ *
+ * a strstr for xmlChar's
+ *
+ * Returns the xmlChar * for the first occurrence or NULL.
+ */
+
+const xmlChar *
+xmlStrstr(const xmlChar *str, const xmlChar *val) {
+    int n;
+    
+    if (str == NULL) return(NULL);
+    if (val == NULL) return(NULL);
+    n = xmlStrlen(val);
+
+    if (n == 0) return(str);
+    while (*str != 0) { /* non input consuming */
+        if (*str == *val) {
+            if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
+        }
+        str++;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlStrcasestr:
+ * @str:  the xmlChar * array (haystack)
+ * @val:  the xmlChar to search (needle)
+ *
+ * a case-ignoring strstr for xmlChar's
+ *
+ * Returns the xmlChar * for the first occurrence or NULL.
+ */
+
+const xmlChar *
+xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
+    int n;
+    
+    if (str == NULL) return(NULL);
+    if (val == NULL) return(NULL);
+    n = xmlStrlen(val);
+
+    if (n == 0) return(str);
+    while (*str != 0) { /* non input consuming */
+        if (casemap[*str] == casemap[*val])
+            if (!xmlStrncasecmp(str, val, n)) return(str);
+        str++;
+    }
+    return(NULL);
+}
+
+/**
+ * xmlStrsub:
+ * @str:  the xmlChar * array (haystack)
+ * @start:  the index of the first char (zero based)
+ * @len:  the length of the substring
+ *
+ * Extract a substring of a given string
+ *
+ * Returns the xmlChar * for the first occurrence or NULL.
+ */
+
+xmlChar *
+xmlStrsub(const xmlChar *str, int start, int len) {
+    int i;
+    
+    if (str == NULL) return(NULL);
+    if (start < 0) return(NULL);
+    if (len < 0) return(NULL);
+
+    for (i = 0;i < start;i++) {
+        if (*str == 0) return(NULL);
+        str++;
+    }
+    if (*str == 0) return(NULL);
+    return(xmlStrndup(str, len));
+}
+
+/**
+ * xmlStrlen:
+ * @str:  the xmlChar * array
+ *
+ * length of a xmlChar's string
+ *
+ * Returns the number of xmlChar contained in the ARRAY.
+ */
+
+int
+xmlStrlen(const xmlChar *str) {
+    int len = 0;
+
+    if (str == NULL) return(0);
+    while (*str != 0) { /* non input consuming */
+        str++;
+        len++;
+    }
+    return(len);
+}
+
+/**
+ * xmlStrncat:
+ * @cur:  the original xmlChar * array
+ * @add:  the xmlChar * array added
+ * @len:  the length of @add
+ *
+ * a strncat for array of xmlChar's, it will extend @cur with the len
+ * first bytes of @add. Note that if @len < 0 then this is an API error
+ * and NULL will be returned.
+ *
+ * Returns a new xmlChar *, the original @cur is reallocated if needed
+ * and should not be freed
+ */
+
+xmlChar *
+xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
+    int size;
+    xmlChar *ret;
+
+    if ((add == NULL) || (len == 0))
+        return(cur);
+    if (len < 0)
+	return(NULL);
+    if (cur == NULL)
+        return(xmlStrndup(add, len));
+
+    size = xmlStrlen(cur);
+    ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlErrMemory(NULL, NULL);
+        return(cur);
+    }
+    memcpy(&ret[size], add, len * sizeof(xmlChar));
+    ret[size + len] = 0;
+    return(ret);
+}
+
+/**
+ * xmlStrncatNew:
+ * @str1:  first xmlChar string
+ * @str2:  second xmlChar string
+ * @len:  the len of @str2 or < 0
+ *
+ * same as xmlStrncat, but creates a new string.  The original
+ * two strings are not freed. If @len is < 0 then the length
+ * will be calculated automatically.
+ *
+ * Returns a new xmlChar * or NULL
+ */
+xmlChar *
+xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
+    int size;
+    xmlChar *ret;
+
+    if (len < 0)
+        len = xmlStrlen(str2);
+    if ((str2 == NULL) || (len == 0))
+        return(xmlStrdup(str1));
+    if (str1 == NULL)
+        return(xmlStrndup(str2, len));
+
+    size = xmlStrlen(str1);
+    ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlErrMemory(NULL, NULL);
+        return(xmlStrndup(str1, size));
+    }
+    memcpy(ret, str1, size * sizeof(xmlChar));
+    memcpy(&ret[size], str2, len * sizeof(xmlChar));
+    ret[size + len] = 0;
+    return(ret);
+}
+
+/**
+ * xmlStrcat:
+ * @cur:  the original xmlChar * array
+ * @add:  the xmlChar * array added
+ *
+ * a strcat for array of xmlChar's. Since they are supposed to be
+ * encoded in UTF-8 or an encoding with 8bit based chars, we assume
+ * a termination mark of '0'.
+ *
+ * Returns a new xmlChar * containing the concatenated string.
+ */
+xmlChar *
+xmlStrcat(xmlChar *cur, const xmlChar *add) {
+    const xmlChar *p = add;
+
+    if (add == NULL) return(cur);
+    if (cur == NULL) 
+        return(xmlStrdup(add));
+
+    while (*p != 0) p++; /* non input consuming */
+    return(xmlStrncat(cur, add, p - add));
+}
+
+/**
+ * xmlStrPrintf:
+ * @buf:   the result buffer.
+ * @len:   the result buffer length.
+ * @msg:   the message with printf formatting.
+ * @...:   extra parameters for the message.
+ *
+ * Formats @msg and places result into @buf.
+ *
+ * Returns the number of characters written to @buf or -1 if an error occurs.
+ */
+int XMLCDECL 
+xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
+    va_list args;
+    int ret;
+    
+    if((buf == NULL) || (msg == NULL)) {
+        return(-1);
+    }
+    
+    va_start(args, msg);
+    ret = vsnprintf((char *) buf, len, (const char *) msg, args);
+    va_end(args);
+    buf[len - 1] = 0; /* be safe ! */
+    
+    return(ret);
+}
+
+/**
+ * xmlStrVPrintf:
+ * @buf:   the result buffer.
+ * @len:   the result buffer length.
+ * @msg:   the message with printf formatting.
+ * @ap:    extra parameters for the message.
+ *
+ * Formats @msg and places result into @buf.
+ *
+ * Returns the number of characters written to @buf or -1 if an error occurs.
+ */
+int 
+xmlStrVPrintf(xmlChar *buf, int len, const xmlChar *msg, va_list ap) {
+    int ret;
+    
+    if((buf == NULL) || (msg == NULL)) {
+        return(-1);
+    }
+    
+    ret = vsnprintf((char *) buf, len, (const char *) msg, ap);
+    buf[len - 1] = 0; /* be safe ! */
+    
+    return(ret);
+}
+
+/************************************************************************
+ *                                                                      *
+ *              Generic UTF8 handling routines                          *
+ *                                                                      *
+ * From rfc2044: encoding of the Unicode values on UTF-8:               *
+ *                                                                      *
+ * 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                     *
+ *                                                                      *
+ * I hope we won't use values > 0xFFFF anytime soon !                   *
+ *                                                                      *
+ ************************************************************************/
+
+
+/**
+ * xmlUTF8Size:
+ * @utf: pointer to the UTF8 character
+ *
+ * calculates the internal size of a UTF8 character
+ *
+ * returns the numbers of bytes in the character, -1 on format error
+ */
+int
+xmlUTF8Size(const xmlChar *utf) {
+    xmlChar mask;
+    int len;
+
+    if (utf == NULL)
+        return -1;
+    if (*utf < 0x80)
+        return 1;
+    /* check valid UTF8 character */
+    if (!(*utf & 0x40))
+        return -1;
+    /* determine number of bytes in char */
+    len = 2;
+    for (mask=0x20; mask != 0; mask>>=1) {
+        if (!(*utf & mask))
+            return len;
+        len++;
+    }
+    return -1;
+}
+
+/**
+ * xmlUTF8Charcmp:
+ * @utf1: pointer to first UTF8 char
+ * @utf2: pointer to second UTF8 char
+ *
+ * compares the two UCS4 values
+ *
+ * returns result of the compare as with xmlStrncmp
+ */
+int
+xmlUTF8Charcmp(const xmlChar *utf1, const xmlChar *utf2) {
+
+    if (utf1 == NULL ) {
+        if (utf2 == NULL)
+            return 0;
+        return -1;
+    }
+    return xmlStrncmp(utf1, utf2, xmlUTF8Size(utf1));
+}
+
+/**
+ * xmlUTF8Strlen:
+ * @utf:  a sequence of UTF-8 encoded bytes
+ *
+ * compute the length of an UTF8 string, it doesn't do a full UTF8
+ * checking of the content of the string.
+ *
+ * Returns the number of characters in the string or -1 in case of error
+ */
+int
+xmlUTF8Strlen(const xmlChar *utf) {
+    int ret = 0;
+
+    if (utf == NULL)
+        return(-1);
+
+    while (*utf != 0) {
+        if (utf[0] & 0x80) {
+            if ((utf[1] & 0xc0) != 0x80)
+                return(-1);
+            if ((utf[0] & 0xe0) == 0xe0) {
+                if ((utf[2] & 0xc0) != 0x80)
+                    return(-1);
+                if ((utf[0] & 0xf0) == 0xf0) {
+                    if ((utf[0] & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+                        return(-1);
+                    utf += 4;
+                } else {
+                    utf += 3;
+                }
+            } else {
+                utf += 2;
+            }
+        } else {
+            utf++;
+        }
+        ret++;
+    }
+    return(ret);
+}
+
+/**
+ * xmlGetUTF8Char:
+ * @utf:  a sequence of UTF-8 encoded bytes
+ * @len:  a pointer to the minimum number of bytes present in
+ *        the sequence.  This is used to assure the next character
+ *        is completely contained within the sequence.
+ *
+ * Read the first UTF8 character from @utf
+ *
+ * Returns the char value or -1 in case of error, and sets *len to
+ *        the actual number of bytes consumed (0 in case of error)
+ */
+int
+xmlGetUTF8Char(const unsigned char *utf, int *len) {
+    unsigned int c;
+
+    if (utf == NULL)
+        goto error;
+    if (len == NULL)
+        goto error;
+    if (*len < 1)
+        goto error;
+
+    c = utf[0];
+    if (c & 0x80) {
+        if (*len < 2)
+            goto error;
+        if ((utf[1] & 0xc0) != 0x80)
+            goto error;
+        if ((c & 0xe0) == 0xe0) {
+            if (*len < 3)
+                goto error;
+            if ((utf[2] & 0xc0) != 0x80)
+                goto error;
+            if ((c & 0xf0) == 0xf0) {
+                if (*len < 4)
+                    goto error;
+                if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+                    goto error;
+                *len = 4;
+                /* 4-byte code */
+                c = (utf[0] & 0x7) << 18;
+                c |= (utf[1] & 0x3f) << 12;
+                c |= (utf[2] & 0x3f) << 6;
+                c |= utf[3] & 0x3f;
+            } else {
+              /* 3-byte code */
+                *len = 3;
+                c = (utf[0] & 0xf) << 12;
+                c |= (utf[1] & 0x3f) << 6;
+                c |= utf[2] & 0x3f;
+            }
+        } else {
+          /* 2-byte code */
+            *len = 2;
+            c = (utf[0] & 0x1f) << 6;
+            c |= utf[1] & 0x3f;
+        }
+    } else {
+        /* 1-byte code */
+        *len = 1;
+    }
+    return(c);
+
+error:
+    if (len != NULL)
+	*len = 0;
+    return(-1);
+}
+
+/**
+ * xmlCheckUTF8:
+ * @utf: Pointer to putative UTF-8 encoded string.
+ *
+ * Checks @utf for being valid UTF-8. @utf is assumed to be
+ * null-terminated. This function is not super-strict, as it will
+ * allow longer UTF-8 sequences than necessary. Note that Java is
+ * capable of producing these sequences if provoked. Also note, this
+ * routine checks for the 4-byte maximum size, but does not check for
+ * 0x10ffff maximum value.
+ *
+ * Return value: true if @utf is valid.
+ **/
+int
+xmlCheckUTF8(const unsigned char *utf)
+{
+    int ix;
+    unsigned char c;
+
+    if (utf == NULL)
+        return(0);
+    /*
+     * utf is a string of 1, 2, 3 or 4 bytes.  The valid strings
+     * are as follows (in "bit format"):
+     *    0xxxxxxx                                      valid 1-byte
+     *    110xxxxx 10xxxxxx                             valid 2-byte
+     *    1110xxxx 10xxxxxx 10xxxxxx                    valid 3-byte
+     *    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx           valid 4-byte
+     */
+    for (ix = 0; (c = utf[ix]);) {      /* string is 0-terminated */
+        if ((c & 0x80) == 0x00) {	/* 1-byte code, starts with 10 */
+            ix++;
+	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
+	    if ((utf[ix+1] & 0xc0 ) != 0x80)
+	        return 0;
+	    ix += 2;
+	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
+	    if (((utf[ix+1] & 0xc0) != 0x80) ||
+	        ((utf[ix+2] & 0xc0) != 0x80))
+		    return 0;
+	    ix += 3;
+	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
+	    if (((utf[ix+1] & 0xc0) != 0x80) ||
+	        ((utf[ix+2] & 0xc0) != 0x80) ||
+		((utf[ix+3] & 0xc0) != 0x80))
+		    return 0;
+	    ix += 4;
+	} else				/* unknown encoding */
+	    return 0;
+      }
+      return(1);
+}
+
+/**
+ * xmlUTF8Strsize:
+ * @utf:  a sequence of UTF-8 encoded bytes
+ * @len:  the number of characters in the array
+ *
+ * storage size of an UTF8 string
+ * the behaviour is not garanteed if the input string is not UTF-8
+ *
+ * Returns the storage size of
+ * the first 'len' characters of ARRAY
+ */
+
+int
+xmlUTF8Strsize(const xmlChar *utf, int len) {
+    const xmlChar   *ptr=utf;
+    xmlChar         ch;
+
+    if (utf == NULL)
+        return(0);
+
+    if (len <= 0)
+        return(0);
+
+    while ( len-- > 0) {
+        if ( !*ptr )
+            break;
+        if ( (ch = *ptr++) & 0x80)
+            while ((ch<<=1) & 0x80 ) {
+                ptr++;
+		if (*ptr == 0) break;
+	    }
+    }
+    return (ptr - utf);
+}
+
+
+/**
+ * xmlUTF8Strndup:
+ * @utf:  the input UTF8 *
+ * @len:  the len of @utf (in chars)
+ *
+ * a strndup for array of UTF8's
+ *
+ * Returns a new UTF8 * or NULL
+ */
+xmlChar *
+xmlUTF8Strndup(const xmlChar *utf, int len) {
+    xmlChar *ret;
+    int i;
+    
+    if ((utf == NULL) || (len < 0)) return(NULL);
+    i = xmlUTF8Strsize(utf, len);
+    ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlGenericError(xmlGenericErrorContext,
+                "malloc of %ld byte failed\n",
+                (len + 1) * (long)sizeof(xmlChar));
+        return(NULL);
+    }
+    memcpy(ret, utf, i * sizeof(xmlChar));
+    ret[i] = 0;
+    return(ret);
+}
+
+/**
+ * xmlUTF8Strpos:
+ * @utf:  the input UTF8 *
+ * @pos:  the position of the desired UTF8 char (in chars)
+ *
+ * a function to provide the equivalent of fetching a
+ * character from a string array
+ *
+ * Returns a pointer to the UTF8 character or NULL
+ */
+const xmlChar *
+xmlUTF8Strpos(const xmlChar *utf, int pos) {
+    xmlChar ch;
+
+    if (utf == NULL) return(NULL);
+    if (pos < 0)
+        return(NULL);
+    while (pos--) {
+        if ((ch=*utf++) == 0) return(NULL);
+        if ( ch & 0x80 ) {
+            /* if not simple ascii, verify proper format */
+            if ( (ch & 0xc0) != 0xc0 )
+                return(NULL);
+            /* then skip over remaining bytes for this char */
+            while ( (ch <<= 1) & 0x80 )
+                if ( (*utf++ & 0xc0) != 0x80 )
+                    return(NULL);
+        }
+    }
+    return((xmlChar *)utf);
+}
+
+/**
+ * xmlUTF8Strloc:
+ * @utf:  the input UTF8 *
+ * @utfchar:  the UTF8 character to be found
+ *
+ * a function to provide the relative location of a UTF8 char
+ *
+ * Returns the relative character position of the desired char
+ * or -1 if not found
+ */
+int
+xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) {
+    int i, size;
+    xmlChar ch;
+
+    if (utf==NULL || utfchar==NULL) return -1;
+    size = xmlUTF8Strsize(utfchar, 1);
+        for(i=0; (ch=*utf) != 0; i++) {
+            if (xmlStrncmp(utf, utfchar, size)==0)
+                return(i);
+            utf++;
+            if ( ch & 0x80 ) {
+                /* if not simple ascii, verify proper format */
+                if ( (ch & 0xc0) != 0xc0 )
+                    return(-1);
+                /* then skip over remaining bytes for this char */
+                while ( (ch <<= 1) & 0x80 )
+                    if ( (*utf++ & 0xc0) != 0x80 )
+                        return(-1);
+            }
+        }
+
+    return(-1);
+}
+/**
+ * xmlUTF8Strsub:
+ * @utf:  a sequence of UTF-8 encoded bytes
+ * @start: relative pos of first char
+ * @len:   total number to copy
+ *
+ * Create a substring from a given UTF-8 string
+ * Note:  positions are given in units of UTF-8 chars
+ *
+ * Returns a pointer to a newly created string
+ * or NULL if any problem
+ */
+
+xmlChar *
+xmlUTF8Strsub(const xmlChar *utf, int start, int len) {
+    int            i;
+    xmlChar ch;
+
+    if (utf == NULL) return(NULL);
+    if (start < 0) return(NULL);
+    if (len < 0) return(NULL);
+
+    /*
+     * Skip over any leading chars
+     */
+    for (i = 0;i < start;i++) {
+        if ((ch=*utf++) == 0) return(NULL);
+        if ( ch & 0x80 ) {
+            /* if not simple ascii, verify proper format */
+            if ( (ch & 0xc0) != 0xc0 )
+                return(NULL);
+            /* then skip over remaining bytes for this char */
+            while ( (ch <<= 1) & 0x80 )
+                if ( (*utf++ & 0xc0) != 0x80 )
+                    return(NULL);
+        }
+    }
+
+    return(xmlUTF8Strndup(utf, len));
+}
+
+#define bottom_xmlstring
+#include "elfgcchack.h"
diff --git a/src/xmlunicode.c b/src/xmlunicode.c
new file mode 100644
index 0000000..450d0f0
--- /dev/null
+++ b/src/xmlunicode.c
@@ -0,0 +1,3179 @@
+/*
+ * xmlunicode.c: this module implements the Unicode character APIs
+ *
+ * This file is automatically generated from the
+ * UCS description files of the Unicode Character Database
+ * http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html
+ * using the genUnicode.py Python script.
+ *
+ * Generation date: Mon Mar 27 11:09:52 2006
+ * Sources: Blocks-4.0.1.txt UnicodeData-4.0.1.txt
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#ifdef LIBXML_UNICODE_ENABLED
+
+#include <string.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/chvalid.h>
+
+typedef int (xmlIntFunc)(int);	/* just to keep one's mind untwisted */
+
+typedef struct {
+    const char *rangename;
+    xmlIntFunc *func;
+} xmlUnicodeRange;
+
+typedef struct {
+    xmlUnicodeRange *table;
+    int		    numentries;
+} xmlUnicodeNameTable;
+
+
+static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname);
+
+static xmlUnicodeRange xmlUnicodeBlocks[] = {
+  {"AegeanNumbers", xmlUCSIsAegeanNumbers},
+  {"AlphabeticPresentationForms", xmlUCSIsAlphabeticPresentationForms},
+  {"Arabic", xmlUCSIsArabic},
+  {"ArabicPresentationForms-A", xmlUCSIsArabicPresentationFormsA},
+  {"ArabicPresentationForms-B", xmlUCSIsArabicPresentationFormsB},
+  {"Armenian", xmlUCSIsArmenian},
+  {"Arrows", xmlUCSIsArrows},
+  {"BasicLatin", xmlUCSIsBasicLatin},
+  {"Bengali", xmlUCSIsBengali},
+  {"BlockElements", xmlUCSIsBlockElements},
+  {"Bopomofo", xmlUCSIsBopomofo},
+  {"BopomofoExtended", xmlUCSIsBopomofoExtended},
+  {"BoxDrawing", xmlUCSIsBoxDrawing},
+  {"BraillePatterns", xmlUCSIsBraillePatterns},
+  {"Buhid", xmlUCSIsBuhid},
+  {"ByzantineMusicalSymbols", xmlUCSIsByzantineMusicalSymbols},
+  {"CJKCompatibility", xmlUCSIsCJKCompatibility},
+  {"CJKCompatibilityForms", xmlUCSIsCJKCompatibilityForms},
+  {"CJKCompatibilityIdeographs", xmlUCSIsCJKCompatibilityIdeographs},
+  {"CJKCompatibilityIdeographsSupplement", xmlUCSIsCJKCompatibilityIdeographsSupplement},
+  {"CJKRadicalsSupplement", xmlUCSIsCJKRadicalsSupplement},
+  {"CJKSymbolsandPunctuation", xmlUCSIsCJKSymbolsandPunctuation},
+  {"CJKUnifiedIdeographs", xmlUCSIsCJKUnifiedIdeographs},
+  {"CJKUnifiedIdeographsExtensionA", xmlUCSIsCJKUnifiedIdeographsExtensionA},
+  {"CJKUnifiedIdeographsExtensionB", xmlUCSIsCJKUnifiedIdeographsExtensionB},
+  {"Cherokee", xmlUCSIsCherokee},
+  {"CombiningDiacriticalMarks", xmlUCSIsCombiningDiacriticalMarks},
+  {"CombiningDiacriticalMarksforSymbols", xmlUCSIsCombiningDiacriticalMarksforSymbols},
+  {"CombiningHalfMarks", xmlUCSIsCombiningHalfMarks},
+  {"CombiningMarksforSymbols", xmlUCSIsCombiningMarksforSymbols},
+  {"ControlPictures", xmlUCSIsControlPictures},
+  {"CurrencySymbols", xmlUCSIsCurrencySymbols},
+  {"CypriotSyllabary", xmlUCSIsCypriotSyllabary},
+  {"Cyrillic", xmlUCSIsCyrillic},
+  {"CyrillicSupplement", xmlUCSIsCyrillicSupplement},
+  {"Deseret", xmlUCSIsDeseret},
+  {"Devanagari", xmlUCSIsDevanagari},
+  {"Dingbats", xmlUCSIsDingbats},
+  {"EnclosedAlphanumerics", xmlUCSIsEnclosedAlphanumerics},
+  {"EnclosedCJKLettersandMonths", xmlUCSIsEnclosedCJKLettersandMonths},
+  {"Ethiopic", xmlUCSIsEthiopic},
+  {"GeneralPunctuation", xmlUCSIsGeneralPunctuation},
+  {"GeometricShapes", xmlUCSIsGeometricShapes},
+  {"Georgian", xmlUCSIsGeorgian},
+  {"Gothic", xmlUCSIsGothic},
+  {"Greek", xmlUCSIsGreek},
+  {"GreekExtended", xmlUCSIsGreekExtended},
+  {"GreekandCoptic", xmlUCSIsGreekandCoptic},
+  {"Gujarati", xmlUCSIsGujarati},
+  {"Gurmukhi", xmlUCSIsGurmukhi},
+  {"HalfwidthandFullwidthForms", xmlUCSIsHalfwidthandFullwidthForms},
+  {"HangulCompatibilityJamo", xmlUCSIsHangulCompatibilityJamo},
+  {"HangulJamo", xmlUCSIsHangulJamo},
+  {"HangulSyllables", xmlUCSIsHangulSyllables},
+  {"Hanunoo", xmlUCSIsHanunoo},
+  {"Hebrew", xmlUCSIsHebrew},
+  {"HighPrivateUseSurrogates", xmlUCSIsHighPrivateUseSurrogates},
+  {"HighSurrogates", xmlUCSIsHighSurrogates},
+  {"Hiragana", xmlUCSIsHiragana},
+  {"IPAExtensions", xmlUCSIsIPAExtensions},
+  {"IdeographicDescriptionCharacters", xmlUCSIsIdeographicDescriptionCharacters},
+  {"Kanbun", xmlUCSIsKanbun},
+  {"KangxiRadicals", xmlUCSIsKangxiRadicals},
+  {"Kannada", xmlUCSIsKannada},
+  {"Katakana", xmlUCSIsKatakana},
+  {"KatakanaPhoneticExtensions", xmlUCSIsKatakanaPhoneticExtensions},
+  {"Khmer", xmlUCSIsKhmer},
+  {"KhmerSymbols", xmlUCSIsKhmerSymbols},
+  {"Lao", xmlUCSIsLao},
+  {"Latin-1Supplement", xmlUCSIsLatin1Supplement},
+  {"LatinExtended-A", xmlUCSIsLatinExtendedA},
+  {"LatinExtended-B", xmlUCSIsLatinExtendedB},
+  {"LatinExtendedAdditional", xmlUCSIsLatinExtendedAdditional},
+  {"LetterlikeSymbols", xmlUCSIsLetterlikeSymbols},
+  {"Limbu", xmlUCSIsLimbu},
+  {"LinearBIdeograms", xmlUCSIsLinearBIdeograms},
+  {"LinearBSyllabary", xmlUCSIsLinearBSyllabary},
+  {"LowSurrogates", xmlUCSIsLowSurrogates},
+  {"Malayalam", xmlUCSIsMalayalam},
+  {"MathematicalAlphanumericSymbols", xmlUCSIsMathematicalAlphanumericSymbols},
+  {"MathematicalOperators", xmlUCSIsMathematicalOperators},
+  {"MiscellaneousMathematicalSymbols-A", xmlUCSIsMiscellaneousMathematicalSymbolsA},
+  {"MiscellaneousMathematicalSymbols-B", xmlUCSIsMiscellaneousMathematicalSymbolsB},
+  {"MiscellaneousSymbols", xmlUCSIsMiscellaneousSymbols},
+  {"MiscellaneousSymbolsandArrows", xmlUCSIsMiscellaneousSymbolsandArrows},
+  {"MiscellaneousTechnical", xmlUCSIsMiscellaneousTechnical},
+  {"Mongolian", xmlUCSIsMongolian},
+  {"MusicalSymbols", xmlUCSIsMusicalSymbols},
+  {"Myanmar", xmlUCSIsMyanmar},
+  {"NumberForms", xmlUCSIsNumberForms},
+  {"Ogham", xmlUCSIsOgham},
+  {"OldItalic", xmlUCSIsOldItalic},
+  {"OpticalCharacterRecognition", xmlUCSIsOpticalCharacterRecognition},
+  {"Oriya", xmlUCSIsOriya},
+  {"Osmanya", xmlUCSIsOsmanya},
+  {"PhoneticExtensions", xmlUCSIsPhoneticExtensions},
+  {"PrivateUse", xmlUCSIsPrivateUse},
+  {"PrivateUseArea", xmlUCSIsPrivateUseArea},
+  {"Runic", xmlUCSIsRunic},
+  {"Shavian", xmlUCSIsShavian},
+  {"Sinhala", xmlUCSIsSinhala},
+  {"SmallFormVariants", xmlUCSIsSmallFormVariants},
+  {"SpacingModifierLetters", xmlUCSIsSpacingModifierLetters},
+  {"Specials", xmlUCSIsSpecials},
+  {"SuperscriptsandSubscripts", xmlUCSIsSuperscriptsandSubscripts},
+  {"SupplementalArrows-A", xmlUCSIsSupplementalArrowsA},
+  {"SupplementalArrows-B", xmlUCSIsSupplementalArrowsB},
+  {"SupplementalMathematicalOperators", xmlUCSIsSupplementalMathematicalOperators},
+  {"SupplementaryPrivateUseArea-A", xmlUCSIsSupplementaryPrivateUseAreaA},
+  {"SupplementaryPrivateUseArea-B", xmlUCSIsSupplementaryPrivateUseAreaB},
+  {"Syriac", xmlUCSIsSyriac},
+  {"Tagalog", xmlUCSIsTagalog},
+  {"Tagbanwa", xmlUCSIsTagbanwa},
+  {"Tags", xmlUCSIsTags},
+  {"TaiLe", xmlUCSIsTaiLe},
+  {"TaiXuanJingSymbols", xmlUCSIsTaiXuanJingSymbols},
+  {"Tamil", xmlUCSIsTamil},
+  {"Telugu", xmlUCSIsTelugu},
+  {"Thaana", xmlUCSIsThaana},
+  {"Thai", xmlUCSIsThai},
+  {"Tibetan", xmlUCSIsTibetan},
+  {"Ugaritic", xmlUCSIsUgaritic},
+  {"UnifiedCanadianAboriginalSyllabics", xmlUCSIsUnifiedCanadianAboriginalSyllabics},
+  {"VariationSelectors", xmlUCSIsVariationSelectors},
+  {"VariationSelectorsSupplement", xmlUCSIsVariationSelectorsSupplement},
+  {"YiRadicals", xmlUCSIsYiRadicals},
+  {"YiSyllables", xmlUCSIsYiSyllables},
+  {"YijingHexagramSymbols", xmlUCSIsYijingHexagramSymbols}};
+
+static xmlUnicodeRange xmlUnicodeCats[] = {
+  {"C", xmlUCSIsCatC},
+  {"Cc", xmlUCSIsCatCc},
+  {"Cf", xmlUCSIsCatCf},
+  {"Co", xmlUCSIsCatCo},
+  {"Cs", xmlUCSIsCatCs},
+  {"L", xmlUCSIsCatL},
+  {"Ll", xmlUCSIsCatLl},
+  {"Lm", xmlUCSIsCatLm},
+  {"Lo", xmlUCSIsCatLo},
+  {"Lt", xmlUCSIsCatLt},
+  {"Lu", xmlUCSIsCatLu},
+  {"M", xmlUCSIsCatM},
+  {"Mc", xmlUCSIsCatMc},
+  {"Me", xmlUCSIsCatMe},
+  {"Mn", xmlUCSIsCatMn},
+  {"N", xmlUCSIsCatN},
+  {"Nd", xmlUCSIsCatNd},
+  {"Nl", xmlUCSIsCatNl},
+  {"No", xmlUCSIsCatNo},
+  {"P", xmlUCSIsCatP},
+  {"Pc", xmlUCSIsCatPc},
+  {"Pd", xmlUCSIsCatPd},
+  {"Pe", xmlUCSIsCatPe},
+  {"Pf", xmlUCSIsCatPf},
+  {"Pi", xmlUCSIsCatPi},
+  {"Po", xmlUCSIsCatPo},
+  {"Ps", xmlUCSIsCatPs},
+  {"S", xmlUCSIsCatS},
+  {"Sc", xmlUCSIsCatSc},
+  {"Sk", xmlUCSIsCatSk},
+  {"Sm", xmlUCSIsCatSm},
+  {"So", xmlUCSIsCatSo},
+  {"Z", xmlUCSIsCatZ},
+  {"Zl", xmlUCSIsCatZl},
+  {"Zp", xmlUCSIsCatZp},
+  {"Zs", xmlUCSIsCatZs}};
+
+static const xmlChSRange xmlCS[] = {{0x0, 0x1f}, {0x7f, 0x9f}, 
+    {0xad, 0xad}, {0x600, 0x603}, {0x6dd, 0x6dd}, {0x70f, 0x70f}, 
+    {0x17b4, 0x17b5}, {0x200b, 0x200f}, {0x202a, 0x202e}, {0x2060, 0x2063}, 
+    {0x206a, 0x206f}, {0xd800, 0xd800}, {0xdb7f, 0xdb80}, {0xdbff, 0xdc00}, 
+    {0xdfff, 0xe000}, {0xf8ff, 0xf8ff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb} };
+static const xmlChLRange xmlCL[] = {{0x1d173, 0x1d17a}, {0xe0001, 0xe0001}, 
+    {0xe0020, 0xe007f}, {0xf0000, 0xf0000}, {0xffffd, 0xffffd}, 
+    {0x100000, 0x100000}, {0x10fffd, 0x10fffd} };
+static xmlChRangeGroup xmlCG = {18,7,xmlCS,xmlCL};
+
+static const xmlChSRange xmlCfS[] = {{0xad, 0xad}, {0x600, 0x603}, 
+    {0x6dd, 0x6dd}, {0x70f, 0x70f}, {0x17b4, 0x17b5}, {0x200b, 0x200f}, 
+    {0x202a, 0x202e}, {0x2060, 0x2063}, {0x206a, 0x206f}, {0xfeff, 0xfeff}, 
+    {0xfff9, 0xfffb} };
+static const xmlChLRange xmlCfL[] = {{0x1d173, 0x1d17a}, {0xe0001, 0xe0001}, 
+    {0xe0020, 0xe007f} };
+static xmlChRangeGroup xmlCfG = {11,3,xmlCfS,xmlCfL};
+
+static const xmlChSRange xmlLS[] = {{0x41, 0x5a}, {0x61, 0x7a}, 
+    {0xaa, 0xaa}, {0xb5, 0xb5}, {0xba, 0xba}, {0xc0, 0xd6}, {0xd8, 0xf6}, 
+    {0xf8, 0x236}, {0x250, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, 
+    {0x2ee, 0x2ee}, {0x37a, 0x37a}, {0x386, 0x386}, {0x388, 0x38a}, 
+    {0x38c, 0x38c}, {0x38e, 0x3a1}, {0x3a3, 0x3ce}, {0x3d0, 0x3f5}, 
+    {0x3f7, 0x3fb}, {0x400, 0x481}, {0x48a, 0x4ce}, {0x4d0, 0x4f5}, 
+    {0x4f8, 0x4f9}, {0x500, 0x50f}, {0x531, 0x556}, {0x559, 0x559}, 
+    {0x561, 0x587}, {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x621, 0x63a}, 
+    {0x640, 0x64a}, {0x66e, 0x66f}, {0x671, 0x6d3}, {0x6d5, 0x6d5}, 
+    {0x6e5, 0x6e6}, {0x6ee, 0x6ef}, {0x6fa, 0x6fc}, {0x6ff, 0x6ff}, 
+    {0x710, 0x710}, {0x712, 0x72f}, {0x74d, 0x74f}, {0x780, 0x7a5}, 
+    {0x7b1, 0x7b1}, {0x904, 0x939}, {0x93d, 0x93d}, {0x950, 0x950}, 
+    {0x958, 0x961}, {0x985, 0x98c}, {0x98f, 0x990}, {0x993, 0x9a8}, 
+    {0x9aa, 0x9b0}, {0x9b2, 0x9b2}, {0x9b6, 0x9b9}, {0x9bd, 0x9bd}, 
+    {0x9dc, 0x9dd}, {0x9df, 0x9e1}, {0x9f0, 0x9f1}, {0xa05, 0xa0a}, 
+    {0xa0f, 0xa10}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa32, 0xa33}, 
+    {0xa35, 0xa36}, {0xa38, 0xa39}, {0xa59, 0xa5c}, {0xa5e, 0xa5e}, 
+    {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, 
+    {0xaaa, 0xab0}, {0xab2, 0xab3}, {0xab5, 0xab9}, {0xabd, 0xabd}, 
+    {0xad0, 0xad0}, {0xae0, 0xae1}, {0xb05, 0xb0c}, {0xb0f, 0xb10}, 
+    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb32, 0xb33}, {0xb35, 0xb39}, 
+    {0xb3d, 0xb3d}, {0xb5c, 0xb5d}, {0xb5f, 0xb61}, {0xb71, 0xb71}, 
+    {0xb83, 0xb83}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, 
+    {0xb99, 0xb9a}, {0xb9c, 0xb9c}, {0xb9e, 0xb9f}, {0xba3, 0xba4}, 
+    {0xba8, 0xbaa}, {0xbae, 0xbb5}, {0xbb7, 0xbb9}, {0xc05, 0xc0c}, 
+    {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc33}, {0xc35, 0xc39}, 
+    {0xc60, 0xc61}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, 
+    {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbd, 0xcbd}, {0xcde, 0xcde}, 
+    {0xce0, 0xce1}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd28}, 
+    {0xd2a, 0xd39}, {0xd60, 0xd61}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, 
+    {0xdb3, 0xdbb}, {0xdbd, 0xdbd}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, 
+    {0xe32, 0xe33}, {0xe40, 0xe46}, {0xe81, 0xe82}, {0xe84, 0xe84}, 
+    {0xe87, 0xe88}, {0xe8a, 0xe8a}, {0xe8d, 0xe8d}, {0xe94, 0xe97}, 
+    {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xea5, 0xea5}, {0xea7, 0xea7}, 
+    {0xeaa, 0xeab}, {0xead, 0xeb0}, {0xeb2, 0xeb3}, {0xebd, 0xebd}, 
+    {0xec0, 0xec4}, {0xec6, 0xec6}, {0xedc, 0xedd}, {0xf00, 0xf00}, 
+    {0xf40, 0xf47}, {0xf49, 0xf6a}, {0xf88, 0xf8b}, {0x1000, 0x1021}, 
+    {0x1023, 0x1027}, {0x1029, 0x102a}, {0x1050, 0x1055}, {0x10a0, 0x10c5}, 
+    {0x10d0, 0x10f8}, {0x1100, 0x1159}, {0x115f, 0x11a2}, {0x11a8, 0x11f9}, 
+    {0x1200, 0x1206}, {0x1208, 0x1246}, {0x1248, 0x1248}, {0x124a, 0x124d}, 
+    {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125a, 0x125d}, {0x1260, 0x1286}, 
+    {0x1288, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12ae}, {0x12b0, 0x12b0}, 
+    {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c0, 0x12c0}, {0x12c2, 0x12c5}, 
+    {0x12c8, 0x12ce}, {0x12d0, 0x12d6}, {0x12d8, 0x12ee}, {0x12f0, 0x130e}, 
+    {0x1310, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x131e}, {0x1320, 0x1346}, 
+    {0x1348, 0x135a}, {0x13a0, 0x13f4}, {0x1401, 0x166c}, {0x166f, 0x1676}, 
+    {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x1700, 0x170c}, {0x170e, 0x1711}, 
+    {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, 
+    {0x1780, 0x17b3}, {0x17d7, 0x17d7}, {0x17dc, 0x17dc}, {0x1820, 0x1877}, 
+    {0x1880, 0x18a8}, {0x1900, 0x191c}, {0x1950, 0x196d}, {0x1970, 0x1974}, 
+    {0x1d00, 0x1d6b}, {0x1e00, 0x1e9b}, {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15}, 
+    {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, 
+    {0x1f59, 0x1f59}, {0x1f5b, 0x1f5b}, {0x1f5d, 0x1f5d}, {0x1f5f, 0x1f7d}, 
+    {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fbe, 0x1fbe}, {0x1fc2, 0x1fc4}, 
+    {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, 
+    {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2071, 0x2071}, {0x207f, 0x207f}, 
+    {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210a, 0x2113}, {0x2115, 0x2115}, 
+    {0x2119, 0x211d}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, 
+    {0x212a, 0x212d}, {0x212f, 0x2131}, {0x2133, 0x2139}, {0x213d, 0x213f}, 
+    {0x2145, 0x2149}, {0x3005, 0x3006}, {0x3031, 0x3035}, {0x303b, 0x303c}, 
+    {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, 
+    {0x3105, 0x312c}, {0x3131, 0x318e}, {0x31a0, 0x31b7}, {0x31f0, 0x31ff}, 
+    {0x3400, 0x3400}, {0x4db5, 0x4db5}, {0x4e00, 0x4e00}, {0x9fa5, 0x9fa5}, 
+    {0xa000, 0xa48c}, {0xac00, 0xac00}, {0xd7a3, 0xd7a3}, {0xf900, 0xfa2d}, 
+    {0xfa30, 0xfa6a}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb1d}, 
+    {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb3e, 0xfb3e}, 
+    {0xfb40, 0xfb41}, {0xfb43, 0xfb44}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, 
+    {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, 
+    {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, 
+    {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc} };
+static const xmlChLRange xmlLL[] = {{0x10000, 0x1000b}, {0x1000d, 0x10026}, 
+    {0x10028, 0x1003a}, {0x1003c, 0x1003d}, {0x1003f, 0x1004d}, 
+    {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10300, 0x1031e}, 
+    {0x10330, 0x10349}, {0x10380, 0x1039d}, {0x10400, 0x1049d}, 
+    {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080a, 0x10835}, 
+    {0x10837, 0x10838}, {0x1083c, 0x1083c}, {0x1083f, 0x1083f}, 
+    {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d49e, 0x1d49f}, 
+    {0x1d4a2, 0x1d4a2}, {0x1d4a5, 0x1d4a6}, {0x1d4a9, 0x1d4ac}, 
+    {0x1d4ae, 0x1d4b9}, {0x1d4bb, 0x1d4bb}, {0x1d4bd, 0x1d4c3}, 
+    {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, 
+    {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, 
+    {0x1d540, 0x1d544}, {0x1d546, 0x1d546}, {0x1d54a, 0x1d550}, 
+    {0x1d552, 0x1d6a3}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da}, 
+    {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, 
+    {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, 
+    {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, 
+    {0x20000, 0x20000}, {0x2a6d6, 0x2a6d6}, {0x2f800, 0x2fa1d} };
+static xmlChRangeGroup xmlLG = {279,50,xmlLS,xmlLL};
+
+static const xmlChSRange xmlLlS[] = {{0x61, 0x7a}, {0xaa, 0xaa}, 
+    {0xb5, 0xb5}, {0xba, 0xba}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x101, 0x101}, 
+    {0x103, 0x103}, {0x105, 0x105}, {0x107, 0x107}, {0x109, 0x109}, 
+    {0x10b, 0x10b}, {0x10d, 0x10d}, {0x10f, 0x10f}, {0x111, 0x111}, 
+    {0x113, 0x113}, {0x115, 0x115}, {0x117, 0x117}, {0x119, 0x119}, 
+    {0x11b, 0x11b}, {0x11d, 0x11d}, {0x11f, 0x11f}, {0x121, 0x121}, 
+    {0x123, 0x123}, {0x125, 0x125}, {0x127, 0x127}, {0x129, 0x129}, 
+    {0x12b, 0x12b}, {0x12d, 0x12d}, {0x12f, 0x12f}, {0x131, 0x131}, 
+    {0x133, 0x133}, {0x135, 0x135}, {0x137, 0x138}, {0x13a, 0x13a}, 
+    {0x13c, 0x13c}, {0x13e, 0x13e}, {0x140, 0x140}, {0x142, 0x142}, 
+    {0x144, 0x144}, {0x146, 0x146}, {0x148, 0x149}, {0x14b, 0x14b}, 
+    {0x14d, 0x14d}, {0x14f, 0x14f}, {0x151, 0x151}, {0x153, 0x153}, 
+    {0x155, 0x155}, {0x157, 0x157}, {0x159, 0x159}, {0x15b, 0x15b}, 
+    {0x15d, 0x15d}, {0x15f, 0x15f}, {0x161, 0x161}, {0x163, 0x163}, 
+    {0x165, 0x165}, {0x167, 0x167}, {0x169, 0x169}, {0x16b, 0x16b}, 
+    {0x16d, 0x16d}, {0x16f, 0x16f}, {0x171, 0x171}, {0x173, 0x173}, 
+    {0x175, 0x175}, {0x177, 0x177}, {0x17a, 0x17a}, {0x17c, 0x17c}, 
+    {0x17e, 0x180}, {0x183, 0x183}, {0x185, 0x185}, {0x188, 0x188}, 
+    {0x18c, 0x18d}, {0x192, 0x192}, {0x195, 0x195}, {0x199, 0x19b}, 
+    {0x19e, 0x19e}, {0x1a1, 0x1a1}, {0x1a3, 0x1a3}, {0x1a5, 0x1a5}, 
+    {0x1a8, 0x1a8}, {0x1aa, 0x1ab}, {0x1ad, 0x1ad}, {0x1b0, 0x1b0}, 
+    {0x1b4, 0x1b4}, {0x1b6, 0x1b6}, {0x1b9, 0x1ba}, {0x1bd, 0x1bf}, 
+    {0x1c6, 0x1c6}, {0x1c9, 0x1c9}, {0x1cc, 0x1cc}, {0x1ce, 0x1ce}, 
+    {0x1d0, 0x1d0}, {0x1d2, 0x1d2}, {0x1d4, 0x1d4}, {0x1d6, 0x1d6}, 
+    {0x1d8, 0x1d8}, {0x1da, 0x1da}, {0x1dc, 0x1dd}, {0x1df, 0x1df}, 
+    {0x1e1, 0x1e1}, {0x1e3, 0x1e3}, {0x1e5, 0x1e5}, {0x1e7, 0x1e7}, 
+    {0x1e9, 0x1e9}, {0x1eb, 0x1eb}, {0x1ed, 0x1ed}, {0x1ef, 0x1f0}, 
+    {0x1f3, 0x1f3}, {0x1f5, 0x1f5}, {0x1f9, 0x1f9}, {0x1fb, 0x1fb}, 
+    {0x1fd, 0x1fd}, {0x1ff, 0x1ff}, {0x201, 0x201}, {0x203, 0x203}, 
+    {0x205, 0x205}, {0x207, 0x207}, {0x209, 0x209}, {0x20b, 0x20b}, 
+    {0x20d, 0x20d}, {0x20f, 0x20f}, {0x211, 0x211}, {0x213, 0x213}, 
+    {0x215, 0x215}, {0x217, 0x217}, {0x219, 0x219}, {0x21b, 0x21b}, 
+    {0x21d, 0x21d}, {0x21f, 0x21f}, {0x221, 0x221}, {0x223, 0x223}, 
+    {0x225, 0x225}, {0x227, 0x227}, {0x229, 0x229}, {0x22b, 0x22b}, 
+    {0x22d, 0x22d}, {0x22f, 0x22f}, {0x231, 0x231}, {0x233, 0x236}, 
+    {0x250, 0x2af}, {0x390, 0x390}, {0x3ac, 0x3ce}, {0x3d0, 0x3d1}, 
+    {0x3d5, 0x3d7}, {0x3d9, 0x3d9}, {0x3db, 0x3db}, {0x3dd, 0x3dd}, 
+    {0x3df, 0x3df}, {0x3e1, 0x3e1}, {0x3e3, 0x3e3}, {0x3e5, 0x3e5}, 
+    {0x3e7, 0x3e7}, {0x3e9, 0x3e9}, {0x3eb, 0x3eb}, {0x3ed, 0x3ed}, 
+    {0x3ef, 0x3f3}, {0x3f5, 0x3f5}, {0x3f8, 0x3f8}, {0x3fb, 0x3fb}, 
+    {0x430, 0x45f}, {0x461, 0x461}, {0x463, 0x463}, {0x465, 0x465}, 
+    {0x467, 0x467}, {0x469, 0x469}, {0x46b, 0x46b}, {0x46d, 0x46d}, 
+    {0x46f, 0x46f}, {0x471, 0x471}, {0x473, 0x473}, {0x475, 0x475}, 
+    {0x477, 0x477}, {0x479, 0x479}, {0x47b, 0x47b}, {0x47d, 0x47d}, 
+    {0x47f, 0x47f}, {0x481, 0x481}, {0x48b, 0x48b}, {0x48d, 0x48d}, 
+    {0x48f, 0x48f}, {0x491, 0x491}, {0x493, 0x493}, {0x495, 0x495}, 
+    {0x497, 0x497}, {0x499, 0x499}, {0x49b, 0x49b}, {0x49d, 0x49d}, 
+    {0x49f, 0x49f}, {0x4a1, 0x4a1}, {0x4a3, 0x4a3}, {0x4a5, 0x4a5}, 
+    {0x4a7, 0x4a7}, {0x4a9, 0x4a9}, {0x4ab, 0x4ab}, {0x4ad, 0x4ad}, 
+    {0x4af, 0x4af}, {0x4b1, 0x4b1}, {0x4b3, 0x4b3}, {0x4b5, 0x4b5}, 
+    {0x4b7, 0x4b7}, {0x4b9, 0x4b9}, {0x4bb, 0x4bb}, {0x4bd, 0x4bd}, 
+    {0x4bf, 0x4bf}, {0x4c2, 0x4c2}, {0x4c4, 0x4c4}, {0x4c6, 0x4c6}, 
+    {0x4c8, 0x4c8}, {0x4ca, 0x4ca}, {0x4cc, 0x4cc}, {0x4ce, 0x4ce}, 
+    {0x4d1, 0x4d1}, {0x4d3, 0x4d3}, {0x4d5, 0x4d5}, {0x4d7, 0x4d7}, 
+    {0x4d9, 0x4d9}, {0x4db, 0x4db}, {0x4dd, 0x4dd}, {0x4df, 0x4df}, 
+    {0x4e1, 0x4e1}, {0x4e3, 0x4e3}, {0x4e5, 0x4e5}, {0x4e7, 0x4e7}, 
+    {0x4e9, 0x4e9}, {0x4eb, 0x4eb}, {0x4ed, 0x4ed}, {0x4ef, 0x4ef}, 
+    {0x4f1, 0x4f1}, {0x4f3, 0x4f3}, {0x4f5, 0x4f5}, {0x4f9, 0x4f9}, 
+    {0x501, 0x501}, {0x503, 0x503}, {0x505, 0x505}, {0x507, 0x507}, 
+    {0x509, 0x509}, {0x50b, 0x50b}, {0x50d, 0x50d}, {0x50f, 0x50f}, 
+    {0x561, 0x587}, {0x1d00, 0x1d2b}, {0x1d62, 0x1d6b}, {0x1e01, 0x1e01}, 
+    {0x1e03, 0x1e03}, {0x1e05, 0x1e05}, {0x1e07, 0x1e07}, {0x1e09, 0x1e09}, 
+    {0x1e0b, 0x1e0b}, {0x1e0d, 0x1e0d}, {0x1e0f, 0x1e0f}, {0x1e11, 0x1e11}, 
+    {0x1e13, 0x1e13}, {0x1e15, 0x1e15}, {0x1e17, 0x1e17}, {0x1e19, 0x1e19}, 
+    {0x1e1b, 0x1e1b}, {0x1e1d, 0x1e1d}, {0x1e1f, 0x1e1f}, {0x1e21, 0x1e21}, 
+    {0x1e23, 0x1e23}, {0x1e25, 0x1e25}, {0x1e27, 0x1e27}, {0x1e29, 0x1e29}, 
+    {0x1e2b, 0x1e2b}, {0x1e2d, 0x1e2d}, {0x1e2f, 0x1e2f}, {0x1e31, 0x1e31}, 
+    {0x1e33, 0x1e33}, {0x1e35, 0x1e35}, {0x1e37, 0x1e37}, {0x1e39, 0x1e39}, 
+    {0x1e3b, 0x1e3b}, {0x1e3d, 0x1e3d}, {0x1e3f, 0x1e3f}, {0x1e41, 0x1e41}, 
+    {0x1e43, 0x1e43}, {0x1e45, 0x1e45}, {0x1e47, 0x1e47}, {0x1e49, 0x1e49}, 
+    {0x1e4b, 0x1e4b}, {0x1e4d, 0x1e4d}, {0x1e4f, 0x1e4f}, {0x1e51, 0x1e51}, 
+    {0x1e53, 0x1e53}, {0x1e55, 0x1e55}, {0x1e57, 0x1e57}, {0x1e59, 0x1e59}, 
+    {0x1e5b, 0x1e5b}, {0x1e5d, 0x1e5d}, {0x1e5f, 0x1e5f}, {0x1e61, 0x1e61}, 
+    {0x1e63, 0x1e63}, {0x1e65, 0x1e65}, {0x1e67, 0x1e67}, {0x1e69, 0x1e69}, 
+    {0x1e6b, 0x1e6b}, {0x1e6d, 0x1e6d}, {0x1e6f, 0x1e6f}, {0x1e71, 0x1e71}, 
+    {0x1e73, 0x1e73}, {0x1e75, 0x1e75}, {0x1e77, 0x1e77}, {0x1e79, 0x1e79}, 
+    {0x1e7b, 0x1e7b}, {0x1e7d, 0x1e7d}, {0x1e7f, 0x1e7f}, {0x1e81, 0x1e81}, 
+    {0x1e83, 0x1e83}, {0x1e85, 0x1e85}, {0x1e87, 0x1e87}, {0x1e89, 0x1e89}, 
+    {0x1e8b, 0x1e8b}, {0x1e8d, 0x1e8d}, {0x1e8f, 0x1e8f}, {0x1e91, 0x1e91}, 
+    {0x1e93, 0x1e93}, {0x1e95, 0x1e9b}, {0x1ea1, 0x1ea1}, {0x1ea3, 0x1ea3}, 
+    {0x1ea5, 0x1ea5}, {0x1ea7, 0x1ea7}, {0x1ea9, 0x1ea9}, {0x1eab, 0x1eab}, 
+    {0x1ead, 0x1ead}, {0x1eaf, 0x1eaf}, {0x1eb1, 0x1eb1}, {0x1eb3, 0x1eb3}, 
+    {0x1eb5, 0x1eb5}, {0x1eb7, 0x1eb7}, {0x1eb9, 0x1eb9}, {0x1ebb, 0x1ebb}, 
+    {0x1ebd, 0x1ebd}, {0x1ebf, 0x1ebf}, {0x1ec1, 0x1ec1}, {0x1ec3, 0x1ec3}, 
+    {0x1ec5, 0x1ec5}, {0x1ec7, 0x1ec7}, {0x1ec9, 0x1ec9}, {0x1ecb, 0x1ecb}, 
+    {0x1ecd, 0x1ecd}, {0x1ecf, 0x1ecf}, {0x1ed1, 0x1ed1}, {0x1ed3, 0x1ed3}, 
+    {0x1ed5, 0x1ed5}, {0x1ed7, 0x1ed7}, {0x1ed9, 0x1ed9}, {0x1edb, 0x1edb}, 
+    {0x1edd, 0x1edd}, {0x1edf, 0x1edf}, {0x1ee1, 0x1ee1}, {0x1ee3, 0x1ee3}, 
+    {0x1ee5, 0x1ee5}, {0x1ee7, 0x1ee7}, {0x1ee9, 0x1ee9}, {0x1eeb, 0x1eeb}, 
+    {0x1eed, 0x1eed}, {0x1eef, 0x1eef}, {0x1ef1, 0x1ef1}, {0x1ef3, 0x1ef3}, 
+    {0x1ef5, 0x1ef5}, {0x1ef7, 0x1ef7}, {0x1ef9, 0x1ef9}, {0x1f00, 0x1f07}, 
+    {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, 
+    {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, 
+    {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fb6, 0x1fb7}, 
+    {0x1fbe, 0x1fbe}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fc7}, {0x1fd0, 0x1fd3}, 
+    {0x1fd6, 0x1fd7}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ff7}, 
+    {0x2071, 0x2071}, {0x207f, 0x207f}, {0x210a, 0x210a}, {0x210e, 0x210f}, 
+    {0x2113, 0x2113}, {0x212f, 0x212f}, {0x2134, 0x2134}, {0x2139, 0x2139}, 
+    {0x213d, 0x213d}, {0x2146, 0x2149}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, 
+    {0xff41, 0xff5a} };
+static const xmlChLRange xmlLlL[] = {{0x10428, 0x1044f}, {0x1d41a, 0x1d433}, 
+    {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, 
+    {0x1d4b6, 0x1d4b9}, {0x1d4bb, 0x1d4bb}, {0x1d4bd, 0x1d4c3}, 
+    {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, 
+    {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, 
+    {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, 
+    {0x1d68a, 0x1d6a3}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, 
+    {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, 
+    {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, 
+    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9} };
+static xmlChRangeGroup xmlLlG = {396,28,xmlLlS,xmlLlL};
+
+static const xmlChSRange xmlLmS[] = {{0x2b0, 0x2c1}, {0x2c6, 0x2d1}, 
+    {0x2e0, 0x2e4}, {0x2ee, 0x2ee}, {0x37a, 0x37a}, {0x559, 0x559}, 
+    {0x640, 0x640}, {0x6e5, 0x6e6}, {0xe46, 0xe46}, {0xec6, 0xec6}, 
+    {0x17d7, 0x17d7}, {0x1843, 0x1843}, {0x1d2c, 0x1d61}, {0x3005, 0x3005}, 
+    {0x3031, 0x3035}, {0x303b, 0x303b}, {0x309d, 0x309e}, {0x30fc, 0x30fe}, 
+    {0xff70, 0xff70}, {0xff9e, 0xff9f} };
+static xmlChRangeGroup xmlLmG = {20,0,xmlLmS,NULL};
+
+static const xmlChSRange xmlLoS[] = {{0x1bb, 0x1bb}, {0x1c0, 0x1c3}, 
+    {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x621, 0x63a}, {0x641, 0x64a}, 
+    {0x66e, 0x66f}, {0x671, 0x6d3}, {0x6d5, 0x6d5}, {0x6ee, 0x6ef}, 
+    {0x6fa, 0x6fc}, {0x6ff, 0x6ff}, {0x710, 0x710}, {0x712, 0x72f}, 
+    {0x74d, 0x74f}, {0x780, 0x7a5}, {0x7b1, 0x7b1}, {0x904, 0x939}, 
+    {0x93d, 0x93d}, {0x950, 0x950}, {0x958, 0x961}, {0x985, 0x98c}, 
+    {0x98f, 0x990}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b2, 0x9b2}, 
+    {0x9b6, 0x9b9}, {0x9bd, 0x9bd}, {0x9dc, 0x9dd}, {0x9df, 0x9e1}, 
+    {0x9f0, 0x9f1}, {0xa05, 0xa0a}, {0xa0f, 0xa10}, {0xa13, 0xa28}, 
+    {0xa2a, 0xa30}, {0xa32, 0xa33}, {0xa35, 0xa36}, {0xa38, 0xa39}, 
+    {0xa59, 0xa5c}, {0xa5e, 0xa5e}, {0xa72, 0xa74}, {0xa85, 0xa8d}, 
+    {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab2, 0xab3}, 
+    {0xab5, 0xab9}, {0xabd, 0xabd}, {0xad0, 0xad0}, {0xae0, 0xae1}, 
+    {0xb05, 0xb0c}, {0xb0f, 0xb10}, {0xb13, 0xb28}, {0xb2a, 0xb30}, 
+    {0xb32, 0xb33}, {0xb35, 0xb39}, {0xb3d, 0xb3d}, {0xb5c, 0xb5d}, 
+    {0xb5f, 0xb61}, {0xb71, 0xb71}, {0xb83, 0xb83}, {0xb85, 0xb8a}, 
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xb99, 0xb9a}, {0xb9c, 0xb9c}, 
+    {0xb9e, 0xb9f}, {0xba3, 0xba4}, {0xba8, 0xbaa}, {0xbae, 0xbb5}, 
+    {0xbb7, 0xbb9}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, 
+    {0xc2a, 0xc33}, {0xc35, 0xc39}, {0xc60, 0xc61}, {0xc85, 0xc8c}, 
+    {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, 
+    {0xcbd, 0xcbd}, {0xcde, 0xcde}, {0xce0, 0xce1}, {0xd05, 0xd0c}, 
+    {0xd0e, 0xd10}, {0xd12, 0xd28}, {0xd2a, 0xd39}, {0xd60, 0xd61}, 
+    {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdbd, 0xdbd}, 
+    {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe32, 0xe33}, {0xe40, 0xe45}, 
+    {0xe81, 0xe82}, {0xe84, 0xe84}, {0xe87, 0xe88}, {0xe8a, 0xe8a}, 
+    {0xe8d, 0xe8d}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, 
+    {0xea5, 0xea5}, {0xea7, 0xea7}, {0xeaa, 0xeab}, {0xead, 0xeb0}, 
+    {0xeb2, 0xeb3}, {0xebd, 0xebd}, {0xec0, 0xec4}, {0xedc, 0xedd}, 
+    {0xf00, 0xf00}, {0xf40, 0xf47}, {0xf49, 0xf6a}, {0xf88, 0xf8b}, 
+    {0x1000, 0x1021}, {0x1023, 0x1027}, {0x1029, 0x102a}, {0x1050, 0x1055}, 
+    {0x10d0, 0x10f8}, {0x1100, 0x1159}, {0x115f, 0x11a2}, {0x11a8, 0x11f9}, 
+    {0x1200, 0x1206}, {0x1208, 0x1246}, {0x1248, 0x1248}, {0x124a, 0x124d}, 
+    {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125a, 0x125d}, {0x1260, 0x1286}, 
+    {0x1288, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12ae}, {0x12b0, 0x12b0}, 
+    {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c0, 0x12c0}, {0x12c2, 0x12c5}, 
+    {0x12c8, 0x12ce}, {0x12d0, 0x12d6}, {0x12d8, 0x12ee}, {0x12f0, 0x130e}, 
+    {0x1310, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x131e}, {0x1320, 0x1346}, 
+    {0x1348, 0x135a}, {0x13a0, 0x13f4}, {0x1401, 0x166c}, {0x166f, 0x1676}, 
+    {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x1700, 0x170c}, {0x170e, 0x1711}, 
+    {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, 
+    {0x1780, 0x17b3}, {0x17dc, 0x17dc}, {0x1820, 0x1842}, {0x1844, 0x1877}, 
+    {0x1880, 0x18a8}, {0x1900, 0x191c}, {0x1950, 0x196d}, {0x1970, 0x1974}, 
+    {0x2135, 0x2138}, {0x3006, 0x3006}, {0x303c, 0x303c}, {0x3041, 0x3096}, 
+    {0x309f, 0x309f}, {0x30a1, 0x30fa}, {0x30ff, 0x30ff}, {0x3105, 0x312c}, 
+    {0x3131, 0x318e}, {0x31a0, 0x31b7}, {0x31f0, 0x31ff}, {0x3400, 0x3400}, 
+    {0x4db5, 0x4db5}, {0x4e00, 0x4e00}, {0x9fa5, 0x9fa5}, {0xa000, 0xa48c}, 
+    {0xac00, 0xac00}, {0xd7a3, 0xd7a3}, {0xf900, 0xfa2d}, {0xfa30, 0xfa6a}, 
+    {0xfb1d, 0xfb1d}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, 
+    {0xfb3e, 0xfb3e}, {0xfb40, 0xfb41}, {0xfb43, 0xfb44}, {0xfb46, 0xfbb1}, 
+    {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, 
+    {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff66, 0xff6f}, {0xff71, 0xff9d}, 
+    {0xffa0, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, 
+    {0xffda, 0xffdc} };
+static const xmlChLRange xmlLoL[] = {{0x10000, 0x1000b}, {0x1000d, 0x10026}, 
+    {0x10028, 0x1003a}, {0x1003c, 0x1003d}, {0x1003f, 0x1004d}, 
+    {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10300, 0x1031e}, 
+    {0x10330, 0x10349}, {0x10380, 0x1039d}, {0x10450, 0x1049d}, 
+    {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080a, 0x10835}, 
+    {0x10837, 0x10838}, {0x1083c, 0x1083c}, {0x1083f, 0x1083f}, 
+    {0x20000, 0x20000}, {0x2a6d6, 0x2a6d6}, {0x2f800, 0x2fa1d} };
+static xmlChRangeGroup xmlLoG = {211,20,xmlLoS,xmlLoL};
+
+static const xmlChSRange xmlLtS[] = {{0x1c5, 0x1c5}, {0x1c8, 0x1c8}, 
+    {0x1cb, 0x1cb}, {0x1f2, 0x1f2}, {0x1f88, 0x1f8f}, {0x1f98, 0x1f9f}, 
+    {0x1fa8, 0x1faf}, {0x1fbc, 0x1fbc}, {0x1fcc, 0x1fcc}, {0x1ffc, 0x1ffc} };
+static xmlChRangeGroup xmlLtG = {10,0,xmlLtS,NULL};
+
+static const xmlChSRange xmlLuS[] = {{0x41, 0x5a}, {0xc0, 0xd6}, 
+    {0xd8, 0xde}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, 
+    {0x106, 0x106}, {0x108, 0x108}, {0x10a, 0x10a}, {0x10c, 0x10c}, 
+    {0x10e, 0x10e}, {0x110, 0x110}, {0x112, 0x112}, {0x114, 0x114}, 
+    {0x116, 0x116}, {0x118, 0x118}, {0x11a, 0x11a}, {0x11c, 0x11c}, 
+    {0x11e, 0x11e}, {0x120, 0x120}, {0x122, 0x122}, {0x124, 0x124}, 
+    {0x126, 0x126}, {0x128, 0x128}, {0x12a, 0x12a}, {0x12c, 0x12c}, 
+    {0x12e, 0x12e}, {0x130, 0x130}, {0x132, 0x132}, {0x134, 0x134}, 
+    {0x136, 0x136}, {0x139, 0x139}, {0x13b, 0x13b}, {0x13d, 0x13d}, 
+    {0x13f, 0x13f}, {0x141, 0x141}, {0x143, 0x143}, {0x145, 0x145}, 
+    {0x147, 0x147}, {0x14a, 0x14a}, {0x14c, 0x14c}, {0x14e, 0x14e}, 
+    {0x150, 0x150}, {0x152, 0x152}, {0x154, 0x154}, {0x156, 0x156}, 
+    {0x158, 0x158}, {0x15a, 0x15a}, {0x15c, 0x15c}, {0x15e, 0x15e}, 
+    {0x160, 0x160}, {0x162, 0x162}, {0x164, 0x164}, {0x166, 0x166}, 
+    {0x168, 0x168}, {0x16a, 0x16a}, {0x16c, 0x16c}, {0x16e, 0x16e}, 
+    {0x170, 0x170}, {0x172, 0x172}, {0x174, 0x174}, {0x176, 0x176}, 
+    {0x178, 0x179}, {0x17b, 0x17b}, {0x17d, 0x17d}, {0x181, 0x182}, 
+    {0x184, 0x184}, {0x186, 0x187}, {0x189, 0x18b}, {0x18e, 0x191}, 
+    {0x193, 0x194}, {0x196, 0x198}, {0x19c, 0x19d}, {0x19f, 0x1a0}, 
+    {0x1a2, 0x1a2}, {0x1a4, 0x1a4}, {0x1a6, 0x1a7}, {0x1a9, 0x1a9}, 
+    {0x1ac, 0x1ac}, {0x1ae, 0x1af}, {0x1b1, 0x1b3}, {0x1b5, 0x1b5}, 
+    {0x1b7, 0x1b8}, {0x1bc, 0x1bc}, {0x1c4, 0x1c4}, {0x1c7, 0x1c7}, 
+    {0x1ca, 0x1ca}, {0x1cd, 0x1cd}, {0x1cf, 0x1cf}, {0x1d1, 0x1d1}, 
+    {0x1d3, 0x1d3}, {0x1d5, 0x1d5}, {0x1d7, 0x1d7}, {0x1d9, 0x1d9}, 
+    {0x1db, 0x1db}, {0x1de, 0x1de}, {0x1e0, 0x1e0}, {0x1e2, 0x1e2}, 
+    {0x1e4, 0x1e4}, {0x1e6, 0x1e6}, {0x1e8, 0x1e8}, {0x1ea, 0x1ea}, 
+    {0x1ec, 0x1ec}, {0x1ee, 0x1ee}, {0x1f1, 0x1f1}, {0x1f4, 0x1f4}, 
+    {0x1f6, 0x1f8}, {0x1fa, 0x1fa}, {0x1fc, 0x1fc}, {0x1fe, 0x1fe}, 
+    {0x200, 0x200}, {0x202, 0x202}, {0x204, 0x204}, {0x206, 0x206}, 
+    {0x208, 0x208}, {0x20a, 0x20a}, {0x20c, 0x20c}, {0x20e, 0x20e}, 
+    {0x210, 0x210}, {0x212, 0x212}, {0x214, 0x214}, {0x216, 0x216}, 
+    {0x218, 0x218}, {0x21a, 0x21a}, {0x21c, 0x21c}, {0x21e, 0x21e}, 
+    {0x220, 0x220}, {0x222, 0x222}, {0x224, 0x224}, {0x226, 0x226}, 
+    {0x228, 0x228}, {0x22a, 0x22a}, {0x22c, 0x22c}, {0x22e, 0x22e}, 
+    {0x230, 0x230}, {0x232, 0x232}, {0x386, 0x386}, {0x388, 0x38a}, 
+    {0x38c, 0x38c}, {0x38e, 0x38f}, {0x391, 0x3a1}, {0x3a3, 0x3ab}, 
+    {0x3d2, 0x3d4}, {0x3d8, 0x3d8}, {0x3da, 0x3da}, {0x3dc, 0x3dc}, 
+    {0x3de, 0x3de}, {0x3e0, 0x3e0}, {0x3e2, 0x3e2}, {0x3e4, 0x3e4}, 
+    {0x3e6, 0x3e6}, {0x3e8, 0x3e8}, {0x3ea, 0x3ea}, {0x3ec, 0x3ec}, 
+    {0x3ee, 0x3ee}, {0x3f4, 0x3f4}, {0x3f7, 0x3f7}, {0x3f9, 0x3fa}, 
+    {0x400, 0x42f}, {0x460, 0x460}, {0x462, 0x462}, {0x464, 0x464}, 
+    {0x466, 0x466}, {0x468, 0x468}, {0x46a, 0x46a}, {0x46c, 0x46c}, 
+    {0x46e, 0x46e}, {0x470, 0x470}, {0x472, 0x472}, {0x474, 0x474}, 
+    {0x476, 0x476}, {0x478, 0x478}, {0x47a, 0x47a}, {0x47c, 0x47c}, 
+    {0x47e, 0x47e}, {0x480, 0x480}, {0x48a, 0x48a}, {0x48c, 0x48c}, 
+    {0x48e, 0x48e}, {0x490, 0x490}, {0x492, 0x492}, {0x494, 0x494}, 
+    {0x496, 0x496}, {0x498, 0x498}, {0x49a, 0x49a}, {0x49c, 0x49c}, 
+    {0x49e, 0x49e}, {0x4a0, 0x4a0}, {0x4a2, 0x4a2}, {0x4a4, 0x4a4}, 
+    {0x4a6, 0x4a6}, {0x4a8, 0x4a8}, {0x4aa, 0x4aa}, {0x4ac, 0x4ac}, 
+    {0x4ae, 0x4ae}, {0x4b0, 0x4b0}, {0x4b2, 0x4b2}, {0x4b4, 0x4b4}, 
+    {0x4b6, 0x4b6}, {0x4b8, 0x4b8}, {0x4ba, 0x4ba}, {0x4bc, 0x4bc}, 
+    {0x4be, 0x4be}, {0x4c0, 0x4c1}, {0x4c3, 0x4c3}, {0x4c5, 0x4c5}, 
+    {0x4c7, 0x4c7}, {0x4c9, 0x4c9}, {0x4cb, 0x4cb}, {0x4cd, 0x4cd}, 
+    {0x4d0, 0x4d0}, {0x4d2, 0x4d2}, {0x4d4, 0x4d4}, {0x4d6, 0x4d6}, 
+    {0x4d8, 0x4d8}, {0x4da, 0x4da}, {0x4dc, 0x4dc}, {0x4de, 0x4de}, 
+    {0x4e0, 0x4e0}, {0x4e2, 0x4e2}, {0x4e4, 0x4e4}, {0x4e6, 0x4e6}, 
+    {0x4e8, 0x4e8}, {0x4ea, 0x4ea}, {0x4ec, 0x4ec}, {0x4ee, 0x4ee}, 
+    {0x4f0, 0x4f0}, {0x4f2, 0x4f2}, {0x4f4, 0x4f4}, {0x4f8, 0x4f8}, 
+    {0x500, 0x500}, {0x502, 0x502}, {0x504, 0x504}, {0x506, 0x506}, 
+    {0x508, 0x508}, {0x50a, 0x50a}, {0x50c, 0x50c}, {0x50e, 0x50e}, 
+    {0x531, 0x556}, {0x10a0, 0x10c5}, {0x1e00, 0x1e00}, {0x1e02, 0x1e02}, 
+    {0x1e04, 0x1e04}, {0x1e06, 0x1e06}, {0x1e08, 0x1e08}, {0x1e0a, 0x1e0a}, 
+    {0x1e0c, 0x1e0c}, {0x1e0e, 0x1e0e}, {0x1e10, 0x1e10}, {0x1e12, 0x1e12}, 
+    {0x1e14, 0x1e14}, {0x1e16, 0x1e16}, {0x1e18, 0x1e18}, {0x1e1a, 0x1e1a}, 
+    {0x1e1c, 0x1e1c}, {0x1e1e, 0x1e1e}, {0x1e20, 0x1e20}, {0x1e22, 0x1e22}, 
+    {0x1e24, 0x1e24}, {0x1e26, 0x1e26}, {0x1e28, 0x1e28}, {0x1e2a, 0x1e2a}, 
+    {0x1e2c, 0x1e2c}, {0x1e2e, 0x1e2e}, {0x1e30, 0x1e30}, {0x1e32, 0x1e32}, 
+    {0x1e34, 0x1e34}, {0x1e36, 0x1e36}, {0x1e38, 0x1e38}, {0x1e3a, 0x1e3a}, 
+    {0x1e3c, 0x1e3c}, {0x1e3e, 0x1e3e}, {0x1e40, 0x1e40}, {0x1e42, 0x1e42}, 
+    {0x1e44, 0x1e44}, {0x1e46, 0x1e46}, {0x1e48, 0x1e48}, {0x1e4a, 0x1e4a}, 
+    {0x1e4c, 0x1e4c}, {0x1e4e, 0x1e4e}, {0x1e50, 0x1e50}, {0x1e52, 0x1e52}, 
+    {0x1e54, 0x1e54}, {0x1e56, 0x1e56}, {0x1e58, 0x1e58}, {0x1e5a, 0x1e5a}, 
+    {0x1e5c, 0x1e5c}, {0x1e5e, 0x1e5e}, {0x1e60, 0x1e60}, {0x1e62, 0x1e62}, 
+    {0x1e64, 0x1e64}, {0x1e66, 0x1e66}, {0x1e68, 0x1e68}, {0x1e6a, 0x1e6a}, 
+    {0x1e6c, 0x1e6c}, {0x1e6e, 0x1e6e}, {0x1e70, 0x1e70}, {0x1e72, 0x1e72}, 
+    {0x1e74, 0x1e74}, {0x1e76, 0x1e76}, {0x1e78, 0x1e78}, {0x1e7a, 0x1e7a}, 
+    {0x1e7c, 0x1e7c}, {0x1e7e, 0x1e7e}, {0x1e80, 0x1e80}, {0x1e82, 0x1e82}, 
+    {0x1e84, 0x1e84}, {0x1e86, 0x1e86}, {0x1e88, 0x1e88}, {0x1e8a, 0x1e8a}, 
+    {0x1e8c, 0x1e8c}, {0x1e8e, 0x1e8e}, {0x1e90, 0x1e90}, {0x1e92, 0x1e92}, 
+    {0x1e94, 0x1e94}, {0x1ea0, 0x1ea0}, {0x1ea2, 0x1ea2}, {0x1ea4, 0x1ea4}, 
+    {0x1ea6, 0x1ea6}, {0x1ea8, 0x1ea8}, {0x1eaa, 0x1eaa}, {0x1eac, 0x1eac}, 
+    {0x1eae, 0x1eae}, {0x1eb0, 0x1eb0}, {0x1eb2, 0x1eb2}, {0x1eb4, 0x1eb4}, 
+    {0x1eb6, 0x1eb6}, {0x1eb8, 0x1eb8}, {0x1eba, 0x1eba}, {0x1ebc, 0x1ebc}, 
+    {0x1ebe, 0x1ebe}, {0x1ec0, 0x1ec0}, {0x1ec2, 0x1ec2}, {0x1ec4, 0x1ec4}, 
+    {0x1ec6, 0x1ec6}, {0x1ec8, 0x1ec8}, {0x1eca, 0x1eca}, {0x1ecc, 0x1ecc}, 
+    {0x1ece, 0x1ece}, {0x1ed0, 0x1ed0}, {0x1ed2, 0x1ed2}, {0x1ed4, 0x1ed4}, 
+    {0x1ed6, 0x1ed6}, {0x1ed8, 0x1ed8}, {0x1eda, 0x1eda}, {0x1edc, 0x1edc}, 
+    {0x1ede, 0x1ede}, {0x1ee0, 0x1ee0}, {0x1ee2, 0x1ee2}, {0x1ee4, 0x1ee4}, 
+    {0x1ee6, 0x1ee6}, {0x1ee8, 0x1ee8}, {0x1eea, 0x1eea}, {0x1eec, 0x1eec}, 
+    {0x1eee, 0x1eee}, {0x1ef0, 0x1ef0}, {0x1ef2, 0x1ef2}, {0x1ef4, 0x1ef4}, 
+    {0x1ef6, 0x1ef6}, {0x1ef8, 0x1ef8}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, 
+    {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f59, 0x1f59}, 
+    {0x1f5b, 0x1f5b}, {0x1f5d, 0x1f5d}, {0x1f5f, 0x1f5f}, {0x1f68, 0x1f6f}, 
+    {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, 
+    {0x1ff8, 0x1ffb}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210b, 0x210d}, 
+    {0x2110, 0x2112}, {0x2115, 0x2115}, {0x2119, 0x211d}, {0x2124, 0x2124}, 
+    {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212a, 0x212d}, {0x2130, 0x2131}, 
+    {0x2133, 0x2133}, {0x213e, 0x213f}, {0x2145, 0x2145}, {0xff21, 0xff3a} };
+static const xmlChLRange xmlLuL[] = {{0x10400, 0x10427}, {0x1d400, 0x1d419}, 
+    {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d49c, 0x1d49c}, 
+    {0x1d49e, 0x1d49f}, {0x1d4a2, 0x1d4a2}, {0x1d4a5, 0x1d4a6}, 
+    {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, 
+    {0x1d504, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, 
+    {0x1d516, 0x1d51c}, {0x1d538, 0x1d539}, {0x1d53b, 0x1d53e}, 
+    {0x1d540, 0x1d544}, {0x1d546, 0x1d546}, {0x1d54a, 0x1d550}, 
+    {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, 
+    {0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, 
+    {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, 
+    {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8} };
+static xmlChRangeGroup xmlLuG = {390,31,xmlLuS,xmlLuL};
+
+static const xmlChSRange xmlMS[] = {{0x300, 0x357}, {0x35d, 0x36f}, 
+    {0x483, 0x486}, {0x488, 0x489}, {0x591, 0x5a1}, {0x5a3, 0x5b9}, 
+    {0x5bb, 0x5bd}, {0x5bf, 0x5bf}, {0x5c1, 0x5c2}, {0x5c4, 0x5c4}, 
+    {0x610, 0x615}, {0x64b, 0x658}, {0x670, 0x670}, {0x6d6, 0x6dc}, 
+    {0x6de, 0x6e4}, {0x6e7, 0x6e8}, {0x6ea, 0x6ed}, {0x711, 0x711}, 
+    {0x730, 0x74a}, {0x7a6, 0x7b0}, {0x901, 0x903}, {0x93c, 0x93c}, 
+    {0x93e, 0x94d}, {0x951, 0x954}, {0x962, 0x963}, {0x981, 0x983}, 
+    {0x9bc, 0x9bc}, {0x9be, 0x9c4}, {0x9c7, 0x9c8}, {0x9cb, 0x9cd}, 
+    {0x9d7, 0x9d7}, {0x9e2, 0x9e3}, {0xa01, 0xa03}, {0xa3c, 0xa3c}, 
+    {0xa3e, 0xa42}, {0xa47, 0xa48}, {0xa4b, 0xa4d}, {0xa70, 0xa71}, 
+    {0xa81, 0xa83}, {0xabc, 0xabc}, {0xabe, 0xac5}, {0xac7, 0xac9}, 
+    {0xacb, 0xacd}, {0xae2, 0xae3}, {0xb01, 0xb03}, {0xb3c, 0xb3c}, 
+    {0xb3e, 0xb43}, {0xb47, 0xb48}, {0xb4b, 0xb4d}, {0xb56, 0xb57}, 
+    {0xb82, 0xb82}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, 
+    {0xbd7, 0xbd7}, {0xc01, 0xc03}, {0xc3e, 0xc44}, {0xc46, 0xc48}, 
+    {0xc4a, 0xc4d}, {0xc55, 0xc56}, {0xc82, 0xc83}, {0xcbc, 0xcbc}, 
+    {0xcbe, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xcd5, 0xcd6}, 
+    {0xd02, 0xd03}, {0xd3e, 0xd43}, {0xd46, 0xd48}, {0xd4a, 0xd4d}, 
+    {0xd57, 0xd57}, {0xd82, 0xd83}, {0xdca, 0xdca}, {0xdcf, 0xdd4}, 
+    {0xdd6, 0xdd6}, {0xdd8, 0xddf}, {0xdf2, 0xdf3}, {0xe31, 0xe31}, 
+    {0xe34, 0xe3a}, {0xe47, 0xe4e}, {0xeb1, 0xeb1}, {0xeb4, 0xeb9}, 
+    {0xebb, 0xebc}, {0xec8, 0xecd}, {0xf18, 0xf19}, {0xf35, 0xf35}, 
+    {0xf37, 0xf37}, {0xf39, 0xf39}, {0xf3e, 0xf3f}, {0xf71, 0xf84}, 
+    {0xf86, 0xf87}, {0xf90, 0xf97}, {0xf99, 0xfbc}, {0xfc6, 0xfc6}, 
+    {0x102c, 0x1032}, {0x1036, 0x1039}, {0x1056, 0x1059}, {0x1712, 0x1714}, 
+    {0x1732, 0x1734}, {0x1752, 0x1753}, {0x1772, 0x1773}, {0x17b6, 0x17d3}, 
+    {0x17dd, 0x17dd}, {0x180b, 0x180d}, {0x18a9, 0x18a9}, {0x1920, 0x192b}, 
+    {0x1930, 0x193b}, {0x20d0, 0x20ea}, {0x302a, 0x302f}, {0x3099, 0x309a}, 
+    {0xfb1e, 0xfb1e}, {0xfe00, 0xfe0f}, {0xfe20, 0xfe23} };
+static const xmlChLRange xmlML[] = {{0x1d165, 0x1d169}, {0x1d16d, 0x1d172}, 
+    {0x1d17b, 0x1d182}, {0x1d185, 0x1d18b}, {0x1d1aa, 0x1d1ad}, 
+    {0xe0100, 0xe01ef} };
+static xmlChRangeGroup xmlMG = {113,6,xmlMS,xmlML};
+
+static const xmlChSRange xmlMcS[] = {{0x903, 0x903}, {0x93e, 0x940}, 
+    {0x949, 0x94c}, {0x982, 0x983}, {0x9be, 0x9c0}, {0x9c7, 0x9c8}, 
+    {0x9cb, 0x9cc}, {0x9d7, 0x9d7}, {0xa03, 0xa03}, {0xa3e, 0xa40}, 
+    {0xa83, 0xa83}, {0xabe, 0xac0}, {0xac9, 0xac9}, {0xacb, 0xacc}, 
+    {0xb02, 0xb03}, {0xb3e, 0xb3e}, {0xb40, 0xb40}, {0xb47, 0xb48}, 
+    {0xb4b, 0xb4c}, {0xb57, 0xb57}, {0xbbe, 0xbbf}, {0xbc1, 0xbc2}, 
+    {0xbc6, 0xbc8}, {0xbca, 0xbcc}, {0xbd7, 0xbd7}, {0xc01, 0xc03}, 
+    {0xc41, 0xc44}, {0xc82, 0xc83}, {0xcbe, 0xcbe}, {0xcc0, 0xcc4}, 
+    {0xcc7, 0xcc8}, {0xcca, 0xccb}, {0xcd5, 0xcd6}, {0xd02, 0xd03}, 
+    {0xd3e, 0xd40}, {0xd46, 0xd48}, {0xd4a, 0xd4c}, {0xd57, 0xd57}, 
+    {0xd82, 0xd83}, {0xdcf, 0xdd1}, {0xdd8, 0xddf}, {0xdf2, 0xdf3}, 
+    {0xf3e, 0xf3f}, {0xf7f, 0xf7f}, {0x102c, 0x102c}, {0x1031, 0x1031}, 
+    {0x1038, 0x1038}, {0x1056, 0x1057}, {0x17b6, 0x17b6}, {0x17be, 0x17c5}, 
+    {0x17c7, 0x17c8}, {0x1923, 0x1926}, {0x1929, 0x192b}, {0x1930, 0x1931}, 
+    {0x1933, 0x1938} };
+static const xmlChLRange xmlMcL[] = {{0x1d165, 0x1d166}, {0x1d16d, 0x1d172} };
+static xmlChRangeGroup xmlMcG = {55,2,xmlMcS,xmlMcL};
+
+static const xmlChSRange xmlMnS[] = {{0x300, 0x357}, {0x35d, 0x36f}, 
+    {0x483, 0x486}, {0x591, 0x5a1}, {0x5a3, 0x5b9}, {0x5bb, 0x5bd}, 
+    {0x5bf, 0x5bf}, {0x5c1, 0x5c2}, {0x5c4, 0x5c4}, {0x610, 0x615}, 
+    {0x64b, 0x658}, {0x670, 0x670}, {0x6d6, 0x6dc}, {0x6df, 0x6e4}, 
+    {0x6e7, 0x6e8}, {0x6ea, 0x6ed}, {0x711, 0x711}, {0x730, 0x74a}, 
+    {0x7a6, 0x7b0}, {0x901, 0x902}, {0x93c, 0x93c}, {0x941, 0x948}, 
+    {0x94d, 0x94d}, {0x951, 0x954}, {0x962, 0x963}, {0x981, 0x981}, 
+    {0x9bc, 0x9bc}, {0x9c1, 0x9c4}, {0x9cd, 0x9cd}, {0x9e2, 0x9e3}, 
+    {0xa01, 0xa02}, {0xa3c, 0xa3c}, {0xa41, 0xa42}, {0xa47, 0xa48}, 
+    {0xa4b, 0xa4d}, {0xa70, 0xa71}, {0xa81, 0xa82}, {0xabc, 0xabc}, 
+    {0xac1, 0xac5}, {0xac7, 0xac8}, {0xacd, 0xacd}, {0xae2, 0xae3}, 
+    {0xb01, 0xb01}, {0xb3c, 0xb3c}, {0xb3f, 0xb3f}, {0xb41, 0xb43}, 
+    {0xb4d, 0xb4d}, {0xb56, 0xb56}, {0xb82, 0xb82}, {0xbc0, 0xbc0}, 
+    {0xbcd, 0xbcd}, {0xc3e, 0xc40}, {0xc46, 0xc48}, {0xc4a, 0xc4d}, 
+    {0xc55, 0xc56}, {0xcbc, 0xcbc}, {0xcbf, 0xcbf}, {0xcc6, 0xcc6}, 
+    {0xccc, 0xccd}, {0xd41, 0xd43}, {0xd4d, 0xd4d}, {0xdca, 0xdca}, 
+    {0xdd2, 0xdd4}, {0xdd6, 0xdd6}, {0xe31, 0xe31}, {0xe34, 0xe3a}, 
+    {0xe47, 0xe4e}, {0xeb1, 0xeb1}, {0xeb4, 0xeb9}, {0xebb, 0xebc}, 
+    {0xec8, 0xecd}, {0xf18, 0xf19}, {0xf35, 0xf35}, {0xf37, 0xf37}, 
+    {0xf39, 0xf39}, {0xf71, 0xf7e}, {0xf80, 0xf84}, {0xf86, 0xf87}, 
+    {0xf90, 0xf97}, {0xf99, 0xfbc}, {0xfc6, 0xfc6}, {0x102d, 0x1030}, 
+    {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059}, 
+    {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, {0x1772, 0x1773}, 
+    {0x17b7, 0x17bd}, {0x17c6, 0x17c6}, {0x17c9, 0x17d3}, {0x17dd, 0x17dd}, 
+    {0x180b, 0x180d}, {0x18a9, 0x18a9}, {0x1920, 0x1922}, {0x1927, 0x1928}, 
+    {0x1932, 0x1932}, {0x1939, 0x193b}, {0x20d0, 0x20dc}, {0x20e1, 0x20e1}, 
+    {0x20e5, 0x20ea}, {0x302a, 0x302f}, {0x3099, 0x309a}, {0xfb1e, 0xfb1e}, 
+    {0xfe00, 0xfe0f}, {0xfe20, 0xfe23} };
+static const xmlChLRange xmlMnL[] = {{0x1d167, 0x1d169}, {0x1d17b, 0x1d182}, 
+    {0x1d185, 0x1d18b}, {0x1d1aa, 0x1d1ad}, {0xe0100, 0xe01ef} };
+static xmlChRangeGroup xmlMnG = {108,5,xmlMnS,xmlMnL};
+
+static const xmlChSRange xmlNS[] = {{0x30, 0x39}, {0xb2, 0xb3}, 
+    {0xb9, 0xb9}, {0xbc, 0xbe}, {0x660, 0x669}, {0x6f0, 0x6f9}, 
+    {0x966, 0x96f}, {0x9e6, 0x9ef}, {0x9f4, 0x9f9}, {0xa66, 0xa6f}, 
+    {0xae6, 0xaef}, {0xb66, 0xb6f}, {0xbe7, 0xbf2}, {0xc66, 0xc6f}, 
+    {0xce6, 0xcef}, {0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, 
+    {0xf20, 0xf33}, {0x1040, 0x1049}, {0x1369, 0x137c}, {0x16ee, 0x16f0}, 
+    {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1810, 0x1819}, {0x1946, 0x194f}, 
+    {0x2070, 0x2070}, {0x2074, 0x2079}, {0x2080, 0x2089}, {0x2153, 0x2183}, 
+    {0x2460, 0x249b}, {0x24ea, 0x24ff}, {0x2776, 0x2793}, {0x3007, 0x3007}, 
+    {0x3021, 0x3029}, {0x3038, 0x303a}, {0x3192, 0x3195}, {0x3220, 0x3229}, 
+    {0x3251, 0x325f}, {0x3280, 0x3289}, {0x32b1, 0x32bf}, {0xff10, 0xff19} };
+static const xmlChLRange xmlNL[] = {{0x10107, 0x10133}, {0x10320, 0x10323}, 
+    {0x1034a, 0x1034a}, {0x104a0, 0x104a9}, {0x1d7ce, 0x1d7ff} };
+static xmlChRangeGroup xmlNG = {42,5,xmlNS,xmlNL};
+
+static const xmlChSRange xmlNdS[] = {{0x30, 0x39}, {0x660, 0x669}, 
+    {0x6f0, 0x6f9}, {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, 
+    {0xae6, 0xaef}, {0xb66, 0xb6f}, {0xbe7, 0xbef}, {0xc66, 0xc6f}, 
+    {0xce6, 0xcef}, {0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, 
+    {0xf20, 0xf29}, {0x1040, 0x1049}, {0x1369, 0x1371}, {0x17e0, 0x17e9}, 
+    {0x1810, 0x1819}, {0x1946, 0x194f}, {0xff10, 0xff19} };
+static const xmlChLRange xmlNdL[] = {{0x104a0, 0x104a9}, {0x1d7ce, 0x1d7ff} };
+static xmlChRangeGroup xmlNdG = {21,2,xmlNdS,xmlNdL};
+
+static const xmlChSRange xmlNoS[] = {{0xb2, 0xb3}, {0xb9, 0xb9}, 
+    {0xbc, 0xbe}, {0x9f4, 0x9f9}, {0xbf0, 0xbf2}, {0xf2a, 0xf33}, 
+    {0x1372, 0x137c}, {0x17f0, 0x17f9}, {0x2070, 0x2070}, {0x2074, 0x2079}, 
+    {0x2080, 0x2089}, {0x2153, 0x215f}, {0x2460, 0x249b}, {0x24ea, 0x24ff}, 
+    {0x2776, 0x2793}, {0x3192, 0x3195}, {0x3220, 0x3229}, {0x3251, 0x325f}, 
+    {0x3280, 0x3289}, {0x32b1, 0x32bf} };
+static const xmlChLRange xmlNoL[] = {{0x10107, 0x10133}, {0x10320, 0x10323} };
+static xmlChRangeGroup xmlNoG = {20,2,xmlNoS,xmlNoL};
+
+static const xmlChSRange xmlPS[] = {{0x21, 0x23}, {0x25, 0x2a}, 
+    {0x2c, 0x2f}, {0x3a, 0x3b}, {0x3f, 0x40}, {0x5b, 0x5d}, {0x5f, 0x5f}, 
+    {0x7b, 0x7b}, {0x7d, 0x7d}, {0xa1, 0xa1}, {0xab, 0xab}, {0xb7, 0xb7}, 
+    {0xbb, 0xbb}, {0xbf, 0xbf}, {0x37e, 0x37e}, {0x387, 0x387}, 
+    {0x55a, 0x55f}, {0x589, 0x58a}, {0x5be, 0x5be}, {0x5c0, 0x5c0}, 
+    {0x5c3, 0x5c3}, {0x5f3, 0x5f4}, {0x60c, 0x60d}, {0x61b, 0x61b}, 
+    {0x61f, 0x61f}, {0x66a, 0x66d}, {0x6d4, 0x6d4}, {0x700, 0x70d}, 
+    {0x964, 0x965}, {0x970, 0x970}, {0xdf4, 0xdf4}, {0xe4f, 0xe4f}, 
+    {0xe5a, 0xe5b}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xf85, 0xf85}, 
+    {0x104a, 0x104f}, {0x10fb, 0x10fb}, {0x1361, 0x1368}, {0x166d, 0x166e}, 
+    {0x169b, 0x169c}, {0x16eb, 0x16ed}, {0x1735, 0x1736}, {0x17d4, 0x17d6}, 
+    {0x17d8, 0x17da}, {0x1800, 0x180a}, {0x1944, 0x1945}, {0x2010, 0x2027}, 
+    {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x2054}, {0x2057, 0x2057}, 
+    {0x207d, 0x207e}, {0x208d, 0x208e}, {0x2329, 0x232a}, {0x23b4, 0x23b6}, 
+    {0x2768, 0x2775}, {0x27e6, 0x27eb}, {0x2983, 0x2998}, {0x29d8, 0x29db}, 
+    {0x29fc, 0x29fd}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, 
+    {0x3030, 0x3030}, {0x303d, 0x303d}, {0x30a0, 0x30a0}, {0x30fb, 0x30fb}, 
+    {0xfd3e, 0xfd3f}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61}, {0xfe63, 0xfe63}, 
+    {0xfe68, 0xfe68}, {0xfe6a, 0xfe6b}, {0xff01, 0xff03}, {0xff05, 0xff0a}, 
+    {0xff0c, 0xff0f}, {0xff1a, 0xff1b}, {0xff1f, 0xff20}, {0xff3b, 0xff3d}, 
+    {0xff3f, 0xff3f}, {0xff5b, 0xff5b}, {0xff5d, 0xff5d}, {0xff5f, 0xff65} };
+static const xmlChLRange xmlPL[] = {{0x10100, 0x10101}, {0x1039f, 0x1039f} };
+static xmlChRangeGroup xmlPG = {84,2,xmlPS,xmlPL};
+
+static const xmlChSRange xmlPdS[] = {{0x2d, 0x2d}, {0x58a, 0x58a}, 
+    {0x1806, 0x1806}, {0x2010, 0x2015}, {0x301c, 0x301c}, {0x3030, 0x3030}, 
+    {0x30a0, 0x30a0}, {0xfe31, 0xfe32}, {0xfe58, 0xfe58}, {0xfe63, 0xfe63}, 
+    {0xff0d, 0xff0d} };
+static xmlChRangeGroup xmlPdG = {11,0,xmlPdS,NULL};
+
+static const xmlChSRange xmlPeS[] = {{0x29, 0x29}, {0x5d, 0x5d}, 
+    {0x7d, 0x7d}, {0xf3b, 0xf3b}, {0xf3d, 0xf3d}, {0x169c, 0x169c}, 
+    {0x2046, 0x2046}, {0x207e, 0x207e}, {0x208e, 0x208e}, {0x232a, 0x232a}, 
+    {0x23b5, 0x23b5}, {0x2769, 0x2769}, {0x276b, 0x276b}, {0x276d, 0x276d}, 
+    {0x276f, 0x276f}, {0x2771, 0x2771}, {0x2773, 0x2773}, {0x2775, 0x2775}, 
+    {0x27e7, 0x27e7}, {0x27e9, 0x27e9}, {0x27eb, 0x27eb}, {0x2984, 0x2984}, 
+    {0x2986, 0x2986}, {0x2988, 0x2988}, {0x298a, 0x298a}, {0x298c, 0x298c}, 
+    {0x298e, 0x298e}, {0x2990, 0x2990}, {0x2992, 0x2992}, {0x2994, 0x2994}, 
+    {0x2996, 0x2996}, {0x2998, 0x2998}, {0x29d9, 0x29d9}, {0x29db, 0x29db}, 
+    {0x29fd, 0x29fd}, {0x3009, 0x3009}, {0x300b, 0x300b}, {0x300d, 0x300d}, 
+    {0x300f, 0x300f}, {0x3011, 0x3011}, {0x3015, 0x3015}, {0x3017, 0x3017}, 
+    {0x3019, 0x3019}, {0x301b, 0x301b}, {0x301e, 0x301f}, {0xfd3f, 0xfd3f}, 
+    {0xfe36, 0xfe36}, {0xfe38, 0xfe38}, {0xfe3a, 0xfe3a}, {0xfe3c, 0xfe3c}, 
+    {0xfe3e, 0xfe3e}, {0xfe40, 0xfe40}, {0xfe42, 0xfe42}, {0xfe44, 0xfe44}, 
+    {0xfe48, 0xfe48}, {0xfe5a, 0xfe5a}, {0xfe5c, 0xfe5c}, {0xfe5e, 0xfe5e}, 
+    {0xff09, 0xff09}, {0xff3d, 0xff3d}, {0xff5d, 0xff5d}, {0xff60, 0xff60}, 
+    {0xff63, 0xff63} };
+static xmlChRangeGroup xmlPeG = {63,0,xmlPeS,NULL};
+
+static const xmlChSRange xmlPoS[] = {{0x21, 0x23}, {0x25, 0x27}, 
+    {0x2a, 0x2a}, {0x2c, 0x2c}, {0x2e, 0x2f}, {0x3a, 0x3b}, {0x3f, 0x40}, 
+    {0x5c, 0x5c}, {0xa1, 0xa1}, {0xb7, 0xb7}, {0xbf, 0xbf}, {0x37e, 0x37e}, 
+    {0x387, 0x387}, {0x55a, 0x55f}, {0x589, 0x589}, {0x5be, 0x5be}, 
+    {0x5c0, 0x5c0}, {0x5c3, 0x5c3}, {0x5f3, 0x5f4}, {0x60c, 0x60d}, 
+    {0x61b, 0x61b}, {0x61f, 0x61f}, {0x66a, 0x66d}, {0x6d4, 0x6d4}, 
+    {0x700, 0x70d}, {0x964, 0x965}, {0x970, 0x970}, {0xdf4, 0xdf4}, 
+    {0xe4f, 0xe4f}, {0xe5a, 0xe5b}, {0xf04, 0xf12}, {0xf85, 0xf85}, 
+    {0x104a, 0x104f}, {0x10fb, 0x10fb}, {0x1361, 0x1368}, {0x166d, 0x166e}, 
+    {0x16eb, 0x16ed}, {0x1735, 0x1736}, {0x17d4, 0x17d6}, {0x17d8, 0x17da}, 
+    {0x1800, 0x1805}, {0x1807, 0x180a}, {0x1944, 0x1945}, {0x2016, 0x2017}, 
+    {0x2020, 0x2027}, {0x2030, 0x2038}, {0x203b, 0x203e}, {0x2041, 0x2043}, 
+    {0x2047, 0x2051}, {0x2053, 0x2053}, {0x2057, 0x2057}, {0x23b6, 0x23b6}, 
+    {0x3001, 0x3003}, {0x303d, 0x303d}, {0xfe30, 0xfe30}, {0xfe45, 0xfe46}, 
+    {0xfe49, 0xfe4c}, {0xfe50, 0xfe52}, {0xfe54, 0xfe57}, {0xfe5f, 0xfe61}, 
+    {0xfe68, 0xfe68}, {0xfe6a, 0xfe6b}, {0xff01, 0xff03}, {0xff05, 0xff07}, 
+    {0xff0a, 0xff0a}, {0xff0c, 0xff0c}, {0xff0e, 0xff0f}, {0xff1a, 0xff1b}, 
+    {0xff1f, 0xff20}, {0xff3c, 0xff3c}, {0xff61, 0xff61}, {0xff64, 0xff64} };
+static const xmlChLRange xmlPoL[] = {{0x10100, 0x10101}, {0x1039f, 0x1039f} };
+static xmlChRangeGroup xmlPoG = {72,2,xmlPoS,xmlPoL};
+
+static const xmlChSRange xmlPsS[] = {{0x28, 0x28}, {0x5b, 0x5b}, 
+    {0x7b, 0x7b}, {0xf3a, 0xf3a}, {0xf3c, 0xf3c}, {0x169b, 0x169b}, 
+    {0x201a, 0x201a}, {0x201e, 0x201e}, {0x2045, 0x2045}, {0x207d, 0x207d}, 
+    {0x208d, 0x208d}, {0x2329, 0x2329}, {0x23b4, 0x23b4}, {0x2768, 0x2768}, 
+    {0x276a, 0x276a}, {0x276c, 0x276c}, {0x276e, 0x276e}, {0x2770, 0x2770}, 
+    {0x2772, 0x2772}, {0x2774, 0x2774}, {0x27e6, 0x27e6}, {0x27e8, 0x27e8}, 
+    {0x27ea, 0x27ea}, {0x2983, 0x2983}, {0x2985, 0x2985}, {0x2987, 0x2987}, 
+    {0x2989, 0x2989}, {0x298b, 0x298b}, {0x298d, 0x298d}, {0x298f, 0x298f}, 
+    {0x2991, 0x2991}, {0x2993, 0x2993}, {0x2995, 0x2995}, {0x2997, 0x2997}, 
+    {0x29d8, 0x29d8}, {0x29da, 0x29da}, {0x29fc, 0x29fc}, {0x3008, 0x3008}, 
+    {0x300a, 0x300a}, {0x300c, 0x300c}, {0x300e, 0x300e}, {0x3010, 0x3010}, 
+    {0x3014, 0x3014}, {0x3016, 0x3016}, {0x3018, 0x3018}, {0x301a, 0x301a}, 
+    {0x301d, 0x301d}, {0xfd3e, 0xfd3e}, {0xfe35, 0xfe35}, {0xfe37, 0xfe37}, 
+    {0xfe39, 0xfe39}, {0xfe3b, 0xfe3b}, {0xfe3d, 0xfe3d}, {0xfe3f, 0xfe3f}, 
+    {0xfe41, 0xfe41}, {0xfe43, 0xfe43}, {0xfe47, 0xfe47}, {0xfe59, 0xfe59}, 
+    {0xfe5b, 0xfe5b}, {0xfe5d, 0xfe5d}, {0xff08, 0xff08}, {0xff3b, 0xff3b}, 
+    {0xff5b, 0xff5b}, {0xff5f, 0xff5f}, {0xff62, 0xff62} };
+static xmlChRangeGroup xmlPsG = {65,0,xmlPsS,NULL};
+
+static const xmlChSRange xmlSS[] = {{0x24, 0x24}, {0x2b, 0x2b}, 
+    {0x3c, 0x3e}, {0x5e, 0x5e}, {0x60, 0x60}, {0x7c, 0x7c}, {0x7e, 0x7e}, 
+    {0xa2, 0xa9}, {0xac, 0xac}, {0xae, 0xb1}, {0xb4, 0xb4}, {0xb6, 0xb6}, 
+    {0xb8, 0xb8}, {0xd7, 0xd7}, {0xf7, 0xf7}, {0x2c2, 0x2c5}, 
+    {0x2d2, 0x2df}, {0x2e5, 0x2ed}, {0x2ef, 0x2ff}, {0x374, 0x375}, 
+    {0x384, 0x385}, {0x3f6, 0x3f6}, {0x482, 0x482}, {0x60e, 0x60f}, 
+    {0x6e9, 0x6e9}, {0x6fd, 0x6fe}, {0x9f2, 0x9f3}, {0x9fa, 0x9fa}, 
+    {0xaf1, 0xaf1}, {0xb70, 0xb70}, {0xbf3, 0xbfa}, {0xe3f, 0xe3f}, 
+    {0xf01, 0xf03}, {0xf13, 0xf17}, {0xf1a, 0xf1f}, {0xf34, 0xf34}, 
+    {0xf36, 0xf36}, {0xf38, 0xf38}, {0xfbe, 0xfc5}, {0xfc7, 0xfcc}, 
+    {0xfcf, 0xfcf}, {0x17db, 0x17db}, {0x1940, 0x1940}, {0x19e0, 0x19ff}, 
+    {0x1fbd, 0x1fbd}, {0x1fbf, 0x1fc1}, {0x1fcd, 0x1fcf}, {0x1fdd, 0x1fdf}, 
+    {0x1fed, 0x1fef}, {0x1ffd, 0x1ffe}, {0x2044, 0x2044}, {0x2052, 0x2052}, 
+    {0x207a, 0x207c}, {0x208a, 0x208c}, {0x20a0, 0x20b1}, {0x2100, 0x2101}, 
+    {0x2103, 0x2106}, {0x2108, 0x2109}, {0x2114, 0x2114}, {0x2116, 0x2118}, 
+    {0x211e, 0x2123}, {0x2125, 0x2125}, {0x2127, 0x2127}, {0x2129, 0x2129}, 
+    {0x212e, 0x212e}, {0x2132, 0x2132}, {0x213a, 0x213b}, {0x2140, 0x2144}, 
+    {0x214a, 0x214b}, {0x2190, 0x2328}, {0x232b, 0x23b3}, {0x23b7, 0x23d0}, 
+    {0x2400, 0x2426}, {0x2440, 0x244a}, {0x249c, 0x24e9}, {0x2500, 0x2617}, 
+    {0x2619, 0x267d}, {0x2680, 0x2691}, {0x26a0, 0x26a1}, {0x2701, 0x2704}, 
+    {0x2706, 0x2709}, {0x270c, 0x2727}, {0x2729, 0x274b}, {0x274d, 0x274d}, 
+    {0x274f, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x275e}, {0x2761, 0x2767}, 
+    {0x2794, 0x2794}, {0x2798, 0x27af}, {0x27b1, 0x27be}, {0x27d0, 0x27e5}, 
+    {0x27f0, 0x2982}, {0x2999, 0x29d7}, {0x29dc, 0x29fb}, {0x29fe, 0x2b0d}, 
+    {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, 
+    {0x3004, 0x3004}, {0x3012, 0x3013}, {0x3020, 0x3020}, {0x3036, 0x3037}, 
+    {0x303e, 0x303f}, {0x309b, 0x309c}, {0x3190, 0x3191}, {0x3196, 0x319f}, 
+    {0x3200, 0x321e}, {0x322a, 0x3243}, {0x3250, 0x3250}, {0x3260, 0x327d}, 
+    {0x327f, 0x327f}, {0x328a, 0x32b0}, {0x32c0, 0x32fe}, {0x3300, 0x33ff}, 
+    {0x4dc0, 0x4dff}, {0xa490, 0xa4c6}, {0xfb29, 0xfb29}, {0xfdfc, 0xfdfd}, 
+    {0xfe62, 0xfe62}, {0xfe64, 0xfe66}, {0xfe69, 0xfe69}, {0xff04, 0xff04}, 
+    {0xff0b, 0xff0b}, {0xff1c, 0xff1e}, {0xff3e, 0xff3e}, {0xff40, 0xff40}, 
+    {0xff5c, 0xff5c}, {0xff5e, 0xff5e}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}, 
+    {0xfffc, 0xfffd} };
+static const xmlChLRange xmlSL[] = {{0x10102, 0x10102}, {0x10137, 0x1013f}, 
+    {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d12a, 0x1d164}, 
+    {0x1d16a, 0x1d16c}, {0x1d183, 0x1d184}, {0x1d18c, 0x1d1a9}, 
+    {0x1d1ae, 0x1d1dd}, {0x1d300, 0x1d356}, {0x1d6c1, 0x1d6c1}, 
+    {0x1d6db, 0x1d6db}, {0x1d6fb, 0x1d6fb}, {0x1d715, 0x1d715}, 
+    {0x1d735, 0x1d735}, {0x1d74f, 0x1d74f}, {0x1d76f, 0x1d76f}, 
+    {0x1d789, 0x1d789}, {0x1d7a9, 0x1d7a9}, {0x1d7c3, 0x1d7c3} };
+static xmlChRangeGroup xmlSG = {133,20,xmlSS,xmlSL};
+
+static const xmlChSRange xmlScS[] = {{0x24, 0x24}, {0xa2, 0xa5}, 
+    {0x9f2, 0x9f3}, {0xaf1, 0xaf1}, {0xbf9, 0xbf9}, {0xe3f, 0xe3f}, 
+    {0x17db, 0x17db}, {0x20a0, 0x20b1}, {0xfdfc, 0xfdfc}, {0xfe69, 0xfe69}, 
+    {0xff04, 0xff04}, {0xffe0, 0xffe1}, {0xffe5, 0xffe6} };
+static xmlChRangeGroup xmlScG = {13,0,xmlScS,NULL};
+
+static const xmlChSRange xmlSkS[] = {{0x5e, 0x5e}, {0x60, 0x60}, 
+    {0xa8, 0xa8}, {0xaf, 0xaf}, {0xb4, 0xb4}, {0xb8, 0xb8}, {0x2c2, 0x2c5}, 
+    {0x2d2, 0x2df}, {0x2e5, 0x2ed}, {0x2ef, 0x2ff}, {0x374, 0x375}, 
+    {0x384, 0x385}, {0x1fbd, 0x1fbd}, {0x1fbf, 0x1fc1}, {0x1fcd, 0x1fcf}, 
+    {0x1fdd, 0x1fdf}, {0x1fed, 0x1fef}, {0x1ffd, 0x1ffe}, {0x309b, 0x309c}, 
+    {0xff3e, 0xff3e}, {0xff40, 0xff40}, {0xffe3, 0xffe3} };
+static xmlChRangeGroup xmlSkG = {22,0,xmlSkS,NULL};
+
+static const xmlChSRange xmlSmS[] = {{0x2b, 0x2b}, {0x3c, 0x3e}, 
+    {0x7c, 0x7c}, {0x7e, 0x7e}, {0xac, 0xac}, {0xb1, 0xb1}, {0xd7, 0xd7}, 
+    {0xf7, 0xf7}, {0x3f6, 0x3f6}, {0x2044, 0x2044}, {0x2052, 0x2052}, 
+    {0x207a, 0x207c}, {0x208a, 0x208c}, {0x2140, 0x2144}, {0x214b, 0x214b}, 
+    {0x2190, 0x2194}, {0x219a, 0x219b}, {0x21a0, 0x21a0}, {0x21a3, 0x21a3}, 
+    {0x21a6, 0x21a6}, {0x21ae, 0x21ae}, {0x21ce, 0x21cf}, {0x21d2, 0x21d2}, 
+    {0x21d4, 0x21d4}, {0x21f4, 0x22ff}, {0x2308, 0x230b}, {0x2320, 0x2321}, 
+    {0x237c, 0x237c}, {0x239b, 0x23b3}, {0x25b7, 0x25b7}, {0x25c1, 0x25c1}, 
+    {0x25f8, 0x25ff}, {0x266f, 0x266f}, {0x27d0, 0x27e5}, {0x27f0, 0x27ff}, 
+    {0x2900, 0x2982}, {0x2999, 0x29d7}, {0x29dc, 0x29fb}, {0x29fe, 0x2aff}, 
+    {0xfb29, 0xfb29}, {0xfe62, 0xfe62}, {0xfe64, 0xfe66}, {0xff0b, 0xff0b}, 
+    {0xff1c, 0xff1e}, {0xff5c, 0xff5c}, {0xff5e, 0xff5e}, {0xffe2, 0xffe2}, 
+    {0xffe9, 0xffec} };
+static const xmlChLRange xmlSmL[] = {{0x1d6c1, 0x1d6c1}, {0x1d6db, 0x1d6db}, 
+    {0x1d6fb, 0x1d6fb}, {0x1d715, 0x1d715}, {0x1d735, 0x1d735}, 
+    {0x1d74f, 0x1d74f}, {0x1d76f, 0x1d76f}, {0x1d789, 0x1d789}, 
+    {0x1d7a9, 0x1d7a9}, {0x1d7c3, 0x1d7c3} };
+static xmlChRangeGroup xmlSmG = {48,10,xmlSmS,xmlSmL};
+
+static const xmlChSRange xmlSoS[] = {{0xa6, 0xa7}, {0xa9, 0xa9}, 
+    {0xae, 0xae}, {0xb0, 0xb0}, {0xb6, 0xb6}, {0x482, 0x482}, 
+    {0x60e, 0x60f}, {0x6e9, 0x6e9}, {0x6fd, 0x6fe}, {0x9fa, 0x9fa}, 
+    {0xb70, 0xb70}, {0xbf3, 0xbf8}, {0xbfa, 0xbfa}, {0xf01, 0xf03}, 
+    {0xf13, 0xf17}, {0xf1a, 0xf1f}, {0xf34, 0xf34}, {0xf36, 0xf36}, 
+    {0xf38, 0xf38}, {0xfbe, 0xfc5}, {0xfc7, 0xfcc}, {0xfcf, 0xfcf}, 
+    {0x1940, 0x1940}, {0x19e0, 0x19ff}, {0x2100, 0x2101}, {0x2103, 0x2106}, 
+    {0x2108, 0x2109}, {0x2114, 0x2114}, {0x2116, 0x2118}, {0x211e, 0x2123}, 
+    {0x2125, 0x2125}, {0x2127, 0x2127}, {0x2129, 0x2129}, {0x212e, 0x212e}, 
+    {0x2132, 0x2132}, {0x213a, 0x213b}, {0x214a, 0x214a}, {0x2195, 0x2199}, 
+    {0x219c, 0x219f}, {0x21a1, 0x21a2}, {0x21a4, 0x21a5}, {0x21a7, 0x21ad}, 
+    {0x21af, 0x21cd}, {0x21d0, 0x21d1}, {0x21d3, 0x21d3}, {0x21d5, 0x21f3}, 
+    {0x2300, 0x2307}, {0x230c, 0x231f}, {0x2322, 0x2328}, {0x232b, 0x237b}, 
+    {0x237d, 0x239a}, {0x23b7, 0x23d0}, {0x2400, 0x2426}, {0x2440, 0x244a}, 
+    {0x249c, 0x24e9}, {0x2500, 0x25b6}, {0x25b8, 0x25c0}, {0x25c2, 0x25f7}, 
+    {0x2600, 0x2617}, {0x2619, 0x266e}, {0x2670, 0x267d}, {0x2680, 0x2691}, 
+    {0x26a0, 0x26a1}, {0x2701, 0x2704}, {0x2706, 0x2709}, {0x270c, 0x2727}, 
+    {0x2729, 0x274b}, {0x274d, 0x274d}, {0x274f, 0x2752}, {0x2756, 0x2756}, 
+    {0x2758, 0x275e}, {0x2761, 0x2767}, {0x2794, 0x2794}, {0x2798, 0x27af}, 
+    {0x27b1, 0x27be}, {0x2800, 0x28ff}, {0x2b00, 0x2b0d}, {0x2e80, 0x2e99}, 
+    {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, {0x3004, 0x3004}, 
+    {0x3012, 0x3013}, {0x3020, 0x3020}, {0x3036, 0x3037}, {0x303e, 0x303f}, 
+    {0x3190, 0x3191}, {0x3196, 0x319f}, {0x3200, 0x321e}, {0x322a, 0x3243}, 
+    {0x3250, 0x3250}, {0x3260, 0x327d}, {0x327f, 0x327f}, {0x328a, 0x32b0}, 
+    {0x32c0, 0x32fe}, {0x3300, 0x33ff}, {0x4dc0, 0x4dff}, {0xa490, 0xa4c6}, 
+    {0xfdfd, 0xfdfd}, {0xffe4, 0xffe4}, {0xffe8, 0xffe8}, {0xffed, 0xffee}, 
+    {0xfffc, 0xfffd} };
+static const xmlChLRange xmlSoL[] = {{0x10102, 0x10102}, {0x10137, 0x1013f}, 
+    {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d12a, 0x1d164}, 
+    {0x1d16a, 0x1d16c}, {0x1d183, 0x1d184}, {0x1d18c, 0x1d1a9}, 
+    {0x1d1ae, 0x1d1dd}, {0x1d300, 0x1d356} };
+static xmlChRangeGroup xmlSoG = {103,10,xmlSoS,xmlSoL};
+
+static const xmlChSRange xmlZS[] = {{0x20, 0x20}, {0xa0, 0xa0}, 
+    {0x1680, 0x1680}, {0x180e, 0x180e}, {0x2000, 0x200a}, {0x2028, 0x2029}, 
+    {0x202f, 0x202f}, {0x205f, 0x205f}, {0x3000, 0x3000} };
+static xmlChRangeGroup xmlZG = {9,0,xmlZS,NULL};
+
+static xmlUnicodeNameTable xmlUnicodeBlockTbl = {xmlUnicodeBlocks, 128};
+static xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, 36};
+
+/**
+ * xmlUnicodeLookup:
+ * @tptr: pointer to the name table
+ * @name: name to be found
+ *
+ * binary table lookup for user-supplied name
+ *
+ * Returns pointer to range function if found, otherwise NULL
+ */
+static xmlIntFunc
+*xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname) {
+    int low, high, mid, cmp;
+    xmlUnicodeRange *sptr;
+
+    if ((tptr == NULL) || (tname == NULL)) return(NULL);
+
+    low = 0;
+    high = tptr->numentries - 1;
+    sptr = tptr->table;
+    while (low <= high) {
+	mid = (low + high) / 2;
+	if ((cmp=strcmp(tname, sptr[mid].rangename)) == 0)
+	    return (sptr[mid].func);
+	if (cmp < 0)
+	    high = mid - 1;
+	else
+	    low = mid + 1;
+    }
+    return (NULL);    
+}
+
+/**
+ * xmlUCSIsAegeanNumbers:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of AegeanNumbers UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsAegeanNumbers(int code) {
+    return(((code >= 0x10100) && (code <= 0x1013F)));
+}
+
+/**
+ * xmlUCSIsAlphabeticPresentationForms:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of AlphabeticPresentationForms UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsAlphabeticPresentationForms(int code) {
+    return(((code >= 0xFB00) && (code <= 0xFB4F)));
+}
+
+/**
+ * xmlUCSIsArabic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Arabic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsArabic(int code) {
+    return(((code >= 0x0600) && (code <= 0x06FF)));
+}
+
+/**
+ * xmlUCSIsArabicPresentationFormsA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of ArabicPresentationForms-A UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsArabicPresentationFormsA(int code) {
+    return(((code >= 0xFB50) && (code <= 0xFDFF)));
+}
+
+/**
+ * xmlUCSIsArabicPresentationFormsB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of ArabicPresentationForms-B UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsArabicPresentationFormsB(int code) {
+    return(((code >= 0xFE70) && (code <= 0xFEFF)));
+}
+
+/**
+ * xmlUCSIsArmenian:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Armenian UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsArmenian(int code) {
+    return(((code >= 0x0530) && (code <= 0x058F)));
+}
+
+/**
+ * xmlUCSIsArrows:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Arrows UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsArrows(int code) {
+    return(((code >= 0x2190) && (code <= 0x21FF)));
+}
+
+/**
+ * xmlUCSIsBasicLatin:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of BasicLatin UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBasicLatin(int code) {
+    return(((code >= 0x0000) && (code <= 0x007F)));
+}
+
+/**
+ * xmlUCSIsBengali:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Bengali UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBengali(int code) {
+    return(((code >= 0x0980) && (code <= 0x09FF)));
+}
+
+/**
+ * xmlUCSIsBlockElements:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of BlockElements UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBlockElements(int code) {
+    return(((code >= 0x2580) && (code <= 0x259F)));
+}
+
+/**
+ * xmlUCSIsBopomofo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Bopomofo UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBopomofo(int code) {
+    return(((code >= 0x3100) && (code <= 0x312F)));
+}
+
+/**
+ * xmlUCSIsBopomofoExtended:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of BopomofoExtended UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBopomofoExtended(int code) {
+    return(((code >= 0x31A0) && (code <= 0x31BF)));
+}
+
+/**
+ * xmlUCSIsBoxDrawing:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of BoxDrawing UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBoxDrawing(int code) {
+    return(((code >= 0x2500) && (code <= 0x257F)));
+}
+
+/**
+ * xmlUCSIsBraillePatterns:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of BraillePatterns UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBraillePatterns(int code) {
+    return(((code >= 0x2800) && (code <= 0x28FF)));
+}
+
+/**
+ * xmlUCSIsBuhid:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Buhid UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsBuhid(int code) {
+    return(((code >= 0x1740) && (code <= 0x175F)));
+}
+
+/**
+ * xmlUCSIsByzantineMusicalSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of ByzantineMusicalSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsByzantineMusicalSymbols(int code) {
+    return(((code >= 0x1D000) && (code <= 0x1D0FF)));
+}
+
+/**
+ * xmlUCSIsCJKCompatibility:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKCompatibility UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKCompatibility(int code) {
+    return(((code >= 0x3300) && (code <= 0x33FF)));
+}
+
+/**
+ * xmlUCSIsCJKCompatibilityForms:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKCompatibilityForms UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKCompatibilityForms(int code) {
+    return(((code >= 0xFE30) && (code <= 0xFE4F)));
+}
+
+/**
+ * xmlUCSIsCJKCompatibilityIdeographs:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKCompatibilityIdeographs UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKCompatibilityIdeographs(int code) {
+    return(((code >= 0xF900) && (code <= 0xFAFF)));
+}
+
+/**
+ * xmlUCSIsCJKCompatibilityIdeographsSupplement:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKCompatibilityIdeographsSupplement UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKCompatibilityIdeographsSupplement(int code) {
+    return(((code >= 0x2F800) && (code <= 0x2FA1F)));
+}
+
+/**
+ * xmlUCSIsCJKRadicalsSupplement:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKRadicalsSupplement UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKRadicalsSupplement(int code) {
+    return(((code >= 0x2E80) && (code <= 0x2EFF)));
+}
+
+/**
+ * xmlUCSIsCJKSymbolsandPunctuation:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKSymbolsandPunctuation UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKSymbolsandPunctuation(int code) {
+    return(((code >= 0x3000) && (code <= 0x303F)));
+}
+
+/**
+ * xmlUCSIsCJKUnifiedIdeographs:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKUnifiedIdeographs UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKUnifiedIdeographs(int code) {
+    return(((code >= 0x4E00) && (code <= 0x9FFF)));
+}
+
+/**
+ * xmlUCSIsCJKUnifiedIdeographsExtensionA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKUnifiedIdeographsExtensionA UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKUnifiedIdeographsExtensionA(int code) {
+    return(((code >= 0x3400) && (code <= 0x4DBF)));
+}
+
+/**
+ * xmlUCSIsCJKUnifiedIdeographsExtensionB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CJKUnifiedIdeographsExtensionB UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCJKUnifiedIdeographsExtensionB(int code) {
+    return(((code >= 0x20000) && (code <= 0x2A6DF)));
+}
+
+/**
+ * xmlUCSIsCherokee:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Cherokee UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCherokee(int code) {
+    return(((code >= 0x13A0) && (code <= 0x13FF)));
+}
+
+/**
+ * xmlUCSIsCombiningDiacriticalMarks:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CombiningDiacriticalMarks UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCombiningDiacriticalMarks(int code) {
+    return(((code >= 0x0300) && (code <= 0x036F)));
+}
+
+/**
+ * xmlUCSIsCombiningDiacriticalMarksforSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CombiningDiacriticalMarksforSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCombiningDiacriticalMarksforSymbols(int code) {
+    return(((code >= 0x20D0) && (code <= 0x20FF)));
+}
+
+/**
+ * xmlUCSIsCombiningHalfMarks:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CombiningHalfMarks UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCombiningHalfMarks(int code) {
+    return(((code >= 0xFE20) && (code <= 0xFE2F)));
+}
+
+/**
+ * xmlUCSIsCombiningMarksforSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CombiningMarksforSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCombiningMarksforSymbols(int code) {
+    return(((code >= 0x20D0) && (code <= 0x20FF)));
+}
+
+/**
+ * xmlUCSIsControlPictures:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of ControlPictures UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsControlPictures(int code) {
+    return(((code >= 0x2400) && (code <= 0x243F)));
+}
+
+/**
+ * xmlUCSIsCurrencySymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CurrencySymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCurrencySymbols(int code) {
+    return(((code >= 0x20A0) && (code <= 0x20CF)));
+}
+
+/**
+ * xmlUCSIsCypriotSyllabary:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CypriotSyllabary UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCypriotSyllabary(int code) {
+    return(((code >= 0x10800) && (code <= 0x1083F)));
+}
+
+/**
+ * xmlUCSIsCyrillic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Cyrillic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCyrillic(int code) {
+    return(((code >= 0x0400) && (code <= 0x04FF)));
+}
+
+/**
+ * xmlUCSIsCyrillicSupplement:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of CyrillicSupplement UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCyrillicSupplement(int code) {
+    return(((code >= 0x0500) && (code <= 0x052F)));
+}
+
+/**
+ * xmlUCSIsDeseret:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Deseret UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsDeseret(int code) {
+    return(((code >= 0x10400) && (code <= 0x1044F)));
+}
+
+/**
+ * xmlUCSIsDevanagari:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Devanagari UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsDevanagari(int code) {
+    return(((code >= 0x0900) && (code <= 0x097F)));
+}
+
+/**
+ * xmlUCSIsDingbats:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Dingbats UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsDingbats(int code) {
+    return(((code >= 0x2700) && (code <= 0x27BF)));
+}
+
+/**
+ * xmlUCSIsEnclosedAlphanumerics:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of EnclosedAlphanumerics UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsEnclosedAlphanumerics(int code) {
+    return(((code >= 0x2460) && (code <= 0x24FF)));
+}
+
+/**
+ * xmlUCSIsEnclosedCJKLettersandMonths:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of EnclosedCJKLettersandMonths UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsEnclosedCJKLettersandMonths(int code) {
+    return(((code >= 0x3200) && (code <= 0x32FF)));
+}
+
+/**
+ * xmlUCSIsEthiopic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Ethiopic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsEthiopic(int code) {
+    return(((code >= 0x1200) && (code <= 0x137F)));
+}
+
+/**
+ * xmlUCSIsGeneralPunctuation:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of GeneralPunctuation UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGeneralPunctuation(int code) {
+    return(((code >= 0x2000) && (code <= 0x206F)));
+}
+
+/**
+ * xmlUCSIsGeometricShapes:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of GeometricShapes UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGeometricShapes(int code) {
+    return(((code >= 0x25A0) && (code <= 0x25FF)));
+}
+
+/**
+ * xmlUCSIsGeorgian:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Georgian UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGeorgian(int code) {
+    return(((code >= 0x10A0) && (code <= 0x10FF)));
+}
+
+/**
+ * xmlUCSIsGothic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Gothic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGothic(int code) {
+    return(((code >= 0x10330) && (code <= 0x1034F)));
+}
+
+/**
+ * xmlUCSIsGreek:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Greek UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGreek(int code) {
+    return(((code >= 0x0370) && (code <= 0x03FF)));
+}
+
+/**
+ * xmlUCSIsGreekExtended:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of GreekExtended UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGreekExtended(int code) {
+    return(((code >= 0x1F00) && (code <= 0x1FFF)));
+}
+
+/**
+ * xmlUCSIsGreekandCoptic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of GreekandCoptic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGreekandCoptic(int code) {
+    return(((code >= 0x0370) && (code <= 0x03FF)));
+}
+
+/**
+ * xmlUCSIsGujarati:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Gujarati UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGujarati(int code) {
+    return(((code >= 0x0A80) && (code <= 0x0AFF)));
+}
+
+/**
+ * xmlUCSIsGurmukhi:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Gurmukhi UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsGurmukhi(int code) {
+    return(((code >= 0x0A00) && (code <= 0x0A7F)));
+}
+
+/**
+ * xmlUCSIsHalfwidthandFullwidthForms:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HalfwidthandFullwidthForms UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHalfwidthandFullwidthForms(int code) {
+    return(((code >= 0xFF00) && (code <= 0xFFEF)));
+}
+
+/**
+ * xmlUCSIsHangulCompatibilityJamo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HangulCompatibilityJamo UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHangulCompatibilityJamo(int code) {
+    return(((code >= 0x3130) && (code <= 0x318F)));
+}
+
+/**
+ * xmlUCSIsHangulJamo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HangulJamo UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHangulJamo(int code) {
+    return(((code >= 0x1100) && (code <= 0x11FF)));
+}
+
+/**
+ * xmlUCSIsHangulSyllables:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HangulSyllables UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHangulSyllables(int code) {
+    return(((code >= 0xAC00) && (code <= 0xD7AF)));
+}
+
+/**
+ * xmlUCSIsHanunoo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Hanunoo UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHanunoo(int code) {
+    return(((code >= 0x1720) && (code <= 0x173F)));
+}
+
+/**
+ * xmlUCSIsHebrew:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Hebrew UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHebrew(int code) {
+    return(((code >= 0x0590) && (code <= 0x05FF)));
+}
+
+/**
+ * xmlUCSIsHighPrivateUseSurrogates:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HighPrivateUseSurrogates UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHighPrivateUseSurrogates(int code) {
+    return(((code >= 0xDB80) && (code <= 0xDBFF)));
+}
+
+/**
+ * xmlUCSIsHighSurrogates:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of HighSurrogates UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHighSurrogates(int code) {
+    return(((code >= 0xD800) && (code <= 0xDB7F)));
+}
+
+/**
+ * xmlUCSIsHiragana:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Hiragana UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsHiragana(int code) {
+    return(((code >= 0x3040) && (code <= 0x309F)));
+}
+
+/**
+ * xmlUCSIsIPAExtensions:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of IPAExtensions UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsIPAExtensions(int code) {
+    return(((code >= 0x0250) && (code <= 0x02AF)));
+}
+
+/**
+ * xmlUCSIsIdeographicDescriptionCharacters:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of IdeographicDescriptionCharacters UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsIdeographicDescriptionCharacters(int code) {
+    return(((code >= 0x2FF0) && (code <= 0x2FFF)));
+}
+
+/**
+ * xmlUCSIsKanbun:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Kanbun UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKanbun(int code) {
+    return(((code >= 0x3190) && (code <= 0x319F)));
+}
+
+/**
+ * xmlUCSIsKangxiRadicals:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of KangxiRadicals UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKangxiRadicals(int code) {
+    return(((code >= 0x2F00) && (code <= 0x2FDF)));
+}
+
+/**
+ * xmlUCSIsKannada:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Kannada UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKannada(int code) {
+    return(((code >= 0x0C80) && (code <= 0x0CFF)));
+}
+
+/**
+ * xmlUCSIsKatakana:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Katakana UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKatakana(int code) {
+    return(((code >= 0x30A0) && (code <= 0x30FF)));
+}
+
+/**
+ * xmlUCSIsKatakanaPhoneticExtensions:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of KatakanaPhoneticExtensions UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKatakanaPhoneticExtensions(int code) {
+    return(((code >= 0x31F0) && (code <= 0x31FF)));
+}
+
+/**
+ * xmlUCSIsKhmer:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Khmer UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKhmer(int code) {
+    return(((code >= 0x1780) && (code <= 0x17FF)));
+}
+
+/**
+ * xmlUCSIsKhmerSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of KhmerSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsKhmerSymbols(int code) {
+    return(((code >= 0x19E0) && (code <= 0x19FF)));
+}
+
+/**
+ * xmlUCSIsLao:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Lao UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLao(int code) {
+    return(((code >= 0x0E80) && (code <= 0x0EFF)));
+}
+
+/**
+ * xmlUCSIsLatin1Supplement:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Latin-1Supplement UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLatin1Supplement(int code) {
+    return(((code >= 0x0080) && (code <= 0x00FF)));
+}
+
+/**
+ * xmlUCSIsLatinExtendedA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LatinExtended-A UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLatinExtendedA(int code) {
+    return(((code >= 0x0100) && (code <= 0x017F)));
+}
+
+/**
+ * xmlUCSIsLatinExtendedB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LatinExtended-B UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLatinExtendedB(int code) {
+    return(((code >= 0x0180) && (code <= 0x024F)));
+}
+
+/**
+ * xmlUCSIsLatinExtendedAdditional:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LatinExtendedAdditional UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLatinExtendedAdditional(int code) {
+    return(((code >= 0x1E00) && (code <= 0x1EFF)));
+}
+
+/**
+ * xmlUCSIsLetterlikeSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LetterlikeSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLetterlikeSymbols(int code) {
+    return(((code >= 0x2100) && (code <= 0x214F)));
+}
+
+/**
+ * xmlUCSIsLimbu:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Limbu UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLimbu(int code) {
+    return(((code >= 0x1900) && (code <= 0x194F)));
+}
+
+/**
+ * xmlUCSIsLinearBIdeograms:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LinearBIdeograms UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLinearBIdeograms(int code) {
+    return(((code >= 0x10080) && (code <= 0x100FF)));
+}
+
+/**
+ * xmlUCSIsLinearBSyllabary:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LinearBSyllabary UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLinearBSyllabary(int code) {
+    return(((code >= 0x10000) && (code <= 0x1007F)));
+}
+
+/**
+ * xmlUCSIsLowSurrogates:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of LowSurrogates UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsLowSurrogates(int code) {
+    return(((code >= 0xDC00) && (code <= 0xDFFF)));
+}
+
+/**
+ * xmlUCSIsMalayalam:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Malayalam UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMalayalam(int code) {
+    return(((code >= 0x0D00) && (code <= 0x0D7F)));
+}
+
+/**
+ * xmlUCSIsMathematicalAlphanumericSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MathematicalAlphanumericSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMathematicalAlphanumericSymbols(int code) {
+    return(((code >= 0x1D400) && (code <= 0x1D7FF)));
+}
+
+/**
+ * xmlUCSIsMathematicalOperators:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MathematicalOperators UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMathematicalOperators(int code) {
+    return(((code >= 0x2200) && (code <= 0x22FF)));
+}
+
+/**
+ * xmlUCSIsMiscellaneousMathematicalSymbolsA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MiscellaneousMathematicalSymbols-A UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMiscellaneousMathematicalSymbolsA(int code) {
+    return(((code >= 0x27C0) && (code <= 0x27EF)));
+}
+
+/**
+ * xmlUCSIsMiscellaneousMathematicalSymbolsB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MiscellaneousMathematicalSymbols-B UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMiscellaneousMathematicalSymbolsB(int code) {
+    return(((code >= 0x2980) && (code <= 0x29FF)));
+}
+
+/**
+ * xmlUCSIsMiscellaneousSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MiscellaneousSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMiscellaneousSymbols(int code) {
+    return(((code >= 0x2600) && (code <= 0x26FF)));
+}
+
+/**
+ * xmlUCSIsMiscellaneousSymbolsandArrows:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MiscellaneousSymbolsandArrows UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMiscellaneousSymbolsandArrows(int code) {
+    return(((code >= 0x2B00) && (code <= 0x2BFF)));
+}
+
+/**
+ * xmlUCSIsMiscellaneousTechnical:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MiscellaneousTechnical UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMiscellaneousTechnical(int code) {
+    return(((code >= 0x2300) && (code <= 0x23FF)));
+}
+
+/**
+ * xmlUCSIsMongolian:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Mongolian UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMongolian(int code) {
+    return(((code >= 0x1800) && (code <= 0x18AF)));
+}
+
+/**
+ * xmlUCSIsMusicalSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of MusicalSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMusicalSymbols(int code) {
+    return(((code >= 0x1D100) && (code <= 0x1D1FF)));
+}
+
+/**
+ * xmlUCSIsMyanmar:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Myanmar UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsMyanmar(int code) {
+    return(((code >= 0x1000) && (code <= 0x109F)));
+}
+
+/**
+ * xmlUCSIsNumberForms:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of NumberForms UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsNumberForms(int code) {
+    return(((code >= 0x2150) && (code <= 0x218F)));
+}
+
+/**
+ * xmlUCSIsOgham:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Ogham UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsOgham(int code) {
+    return(((code >= 0x1680) && (code <= 0x169F)));
+}
+
+/**
+ * xmlUCSIsOldItalic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of OldItalic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsOldItalic(int code) {
+    return(((code >= 0x10300) && (code <= 0x1032F)));
+}
+
+/**
+ * xmlUCSIsOpticalCharacterRecognition:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of OpticalCharacterRecognition UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsOpticalCharacterRecognition(int code) {
+    return(((code >= 0x2440) && (code <= 0x245F)));
+}
+
+/**
+ * xmlUCSIsOriya:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Oriya UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsOriya(int code) {
+    return(((code >= 0x0B00) && (code <= 0x0B7F)));
+}
+
+/**
+ * xmlUCSIsOsmanya:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Osmanya UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsOsmanya(int code) {
+    return(((code >= 0x10480) && (code <= 0x104AF)));
+}
+
+/**
+ * xmlUCSIsPhoneticExtensions:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of PhoneticExtensions UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsPhoneticExtensions(int code) {
+    return(((code >= 0x1D00) && (code <= 0x1D7F)));
+}
+
+/**
+ * xmlUCSIsPrivateUse:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of PrivateUse UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsPrivateUse(int code) {
+    return(((code >= 0xE000) && (code <= 0xF8FF)) ||
+           ((code >= 0xF0000) && (code <= 0xFFFFF)) ||
+           ((code >= 0x100000) && (code <= 0x10FFFF)));
+}
+
+/**
+ * xmlUCSIsPrivateUseArea:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of PrivateUseArea UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsPrivateUseArea(int code) {
+    return(((code >= 0xE000) && (code <= 0xF8FF)));
+}
+
+/**
+ * xmlUCSIsRunic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Runic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsRunic(int code) {
+    return(((code >= 0x16A0) && (code <= 0x16FF)));
+}
+
+/**
+ * xmlUCSIsShavian:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Shavian UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsShavian(int code) {
+    return(((code >= 0x10450) && (code <= 0x1047F)));
+}
+
+/**
+ * xmlUCSIsSinhala:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Sinhala UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSinhala(int code) {
+    return(((code >= 0x0D80) && (code <= 0x0DFF)));
+}
+
+/**
+ * xmlUCSIsSmallFormVariants:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SmallFormVariants UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSmallFormVariants(int code) {
+    return(((code >= 0xFE50) && (code <= 0xFE6F)));
+}
+
+/**
+ * xmlUCSIsSpacingModifierLetters:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SpacingModifierLetters UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSpacingModifierLetters(int code) {
+    return(((code >= 0x02B0) && (code <= 0x02FF)));
+}
+
+/**
+ * xmlUCSIsSpecials:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Specials UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSpecials(int code) {
+    return(((code >= 0xFFF0) && (code <= 0xFFFF)));
+}
+
+/**
+ * xmlUCSIsSuperscriptsandSubscripts:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SuperscriptsandSubscripts UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSuperscriptsandSubscripts(int code) {
+    return(((code >= 0x2070) && (code <= 0x209F)));
+}
+
+/**
+ * xmlUCSIsSupplementalArrowsA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SupplementalArrows-A UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSupplementalArrowsA(int code) {
+    return(((code >= 0x27F0) && (code <= 0x27FF)));
+}
+
+/**
+ * xmlUCSIsSupplementalArrowsB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SupplementalArrows-B UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSupplementalArrowsB(int code) {
+    return(((code >= 0x2900) && (code <= 0x297F)));
+}
+
+/**
+ * xmlUCSIsSupplementalMathematicalOperators:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SupplementalMathematicalOperators UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSupplementalMathematicalOperators(int code) {
+    return(((code >= 0x2A00) && (code <= 0x2AFF)));
+}
+
+/**
+ * xmlUCSIsSupplementaryPrivateUseAreaA:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SupplementaryPrivateUseArea-A UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSupplementaryPrivateUseAreaA(int code) {
+    return(((code >= 0xF0000) && (code <= 0xFFFFF)));
+}
+
+/**
+ * xmlUCSIsSupplementaryPrivateUseAreaB:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of SupplementaryPrivateUseArea-B UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSupplementaryPrivateUseAreaB(int code) {
+    return(((code >= 0x100000) && (code <= 0x10FFFF)));
+}
+
+/**
+ * xmlUCSIsSyriac:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Syriac UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsSyriac(int code) {
+    return(((code >= 0x0700) && (code <= 0x074F)));
+}
+
+/**
+ * xmlUCSIsTagalog:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Tagalog UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTagalog(int code) {
+    return(((code >= 0x1700) && (code <= 0x171F)));
+}
+
+/**
+ * xmlUCSIsTagbanwa:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Tagbanwa UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTagbanwa(int code) {
+    return(((code >= 0x1760) && (code <= 0x177F)));
+}
+
+/**
+ * xmlUCSIsTags:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Tags UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTags(int code) {
+    return(((code >= 0xE0000) && (code <= 0xE007F)));
+}
+
+/**
+ * xmlUCSIsTaiLe:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of TaiLe UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTaiLe(int code) {
+    return(((code >= 0x1950) && (code <= 0x197F)));
+}
+
+/**
+ * xmlUCSIsTaiXuanJingSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of TaiXuanJingSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTaiXuanJingSymbols(int code) {
+    return(((code >= 0x1D300) && (code <= 0x1D35F)));
+}
+
+/**
+ * xmlUCSIsTamil:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Tamil UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTamil(int code) {
+    return(((code >= 0x0B80) && (code <= 0x0BFF)));
+}
+
+/**
+ * xmlUCSIsTelugu:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Telugu UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTelugu(int code) {
+    return(((code >= 0x0C00) && (code <= 0x0C7F)));
+}
+
+/**
+ * xmlUCSIsThaana:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Thaana UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsThaana(int code) {
+    return(((code >= 0x0780) && (code <= 0x07BF)));
+}
+
+/**
+ * xmlUCSIsThai:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Thai UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsThai(int code) {
+    return(((code >= 0x0E00) && (code <= 0x0E7F)));
+}
+
+/**
+ * xmlUCSIsTibetan:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Tibetan UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsTibetan(int code) {
+    return(((code >= 0x0F00) && (code <= 0x0FFF)));
+}
+
+/**
+ * xmlUCSIsUgaritic:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Ugaritic UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsUgaritic(int code) {
+    return(((code >= 0x10380) && (code <= 0x1039F)));
+}
+
+/**
+ * xmlUCSIsUnifiedCanadianAboriginalSyllabics:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of UnifiedCanadianAboriginalSyllabics UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsUnifiedCanadianAboriginalSyllabics(int code) {
+    return(((code >= 0x1400) && (code <= 0x167F)));
+}
+
+/**
+ * xmlUCSIsVariationSelectors:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of VariationSelectors UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsVariationSelectors(int code) {
+    return(((code >= 0xFE00) && (code <= 0xFE0F)));
+}
+
+/**
+ * xmlUCSIsVariationSelectorsSupplement:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of VariationSelectorsSupplement UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsVariationSelectorsSupplement(int code) {
+    return(((code >= 0xE0100) && (code <= 0xE01EF)));
+}
+
+/**
+ * xmlUCSIsYiRadicals:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of YiRadicals UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsYiRadicals(int code) {
+    return(((code >= 0xA490) && (code <= 0xA4CF)));
+}
+
+/**
+ * xmlUCSIsYiSyllables:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of YiSyllables UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsYiSyllables(int code) {
+    return(((code >= 0xA000) && (code <= 0xA48F)));
+}
+
+/**
+ * xmlUCSIsYijingHexagramSymbols:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of YijingHexagramSymbols UCS Block
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsYijingHexagramSymbols(int code) {
+    return(((code >= 0x4DC0) && (code <= 0x4DFF)));
+}
+
+/**
+ * xmlUCSIsBlock:
+ * @code: UCS code point
+ * @block: UCS block name
+ *
+ * Check whether the character is part of the UCS Block
+ *
+ * Returns 1 if true, 0 if false and -1 on unknown block
+ */
+int
+xmlUCSIsBlock(int code, const char *block) {
+    xmlIntFunc *func;
+
+    func = xmlUnicodeLookup(&xmlUnicodeBlockTbl, block);
+    if (func == NULL)
+	return (-1);
+    return (func(code));
+}
+
+/**
+ * xmlUCSIsCatC:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of C UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatC(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlCG));
+}
+
+/**
+ * xmlUCSIsCatCc:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Cc UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatCc(int code) {
+    return(((code >= 0x0) && (code <= 0x1f)) ||
+           ((code >= 0x7f) && (code <= 0x9f)));
+}
+
+/**
+ * xmlUCSIsCatCf:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Cf UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatCf(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlCfG));
+}
+
+/**
+ * xmlUCSIsCatCo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Co UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatCo(int code) {
+    return((code == 0xe000) ||
+           (code == 0xf8ff) ||
+           (code == 0xf0000) ||
+           (code == 0xffffd) ||
+           (code == 0x100000) ||
+           (code == 0x10fffd));
+}
+
+/**
+ * xmlUCSIsCatCs:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Cs UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatCs(int code) {
+    return((code == 0xd800) ||
+           ((code >= 0xdb7f) && (code <= 0xdb80)) ||
+           ((code >= 0xdbff) && (code <= 0xdc00)) ||
+           (code == 0xdfff));
+}
+
+/**
+ * xmlUCSIsCatL:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of L UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatL(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLG));
+}
+
+/**
+ * xmlUCSIsCatLl:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Ll UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatLl(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLlG));
+}
+
+/**
+ * xmlUCSIsCatLm:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Lm UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatLm(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLmG));
+}
+
+/**
+ * xmlUCSIsCatLo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Lo UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatLo(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLoG));
+}
+
+/**
+ * xmlUCSIsCatLt:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Lt UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatLt(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLtG));
+}
+
+/**
+ * xmlUCSIsCatLu:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Lu UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatLu(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlLuG));
+}
+
+/**
+ * xmlUCSIsCatM:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of M UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatM(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlMG));
+}
+
+/**
+ * xmlUCSIsCatMc:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Mc UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatMc(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlMcG));
+}
+
+/**
+ * xmlUCSIsCatMe:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Me UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatMe(int code) {
+    return(((code >= 0x488) && (code <= 0x489)) ||
+           (code == 0x6de) ||
+           ((code >= 0x20dd) && (code <= 0x20e0)) ||
+           ((code >= 0x20e2) && (code <= 0x20e4)));
+}
+
+/**
+ * xmlUCSIsCatMn:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Mn UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatMn(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlMnG));
+}
+
+/**
+ * xmlUCSIsCatN:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of N UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatN(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlNG));
+}
+
+/**
+ * xmlUCSIsCatNd:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Nd UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatNd(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlNdG));
+}
+
+/**
+ * xmlUCSIsCatNl:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Nl UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatNl(int code) {
+    return(((code >= 0x16ee) && (code <= 0x16f0)) ||
+           ((code >= 0x2160) && (code <= 0x2183)) ||
+           (code == 0x3007) ||
+           ((code >= 0x3021) && (code <= 0x3029)) ||
+           ((code >= 0x3038) && (code <= 0x303a)) ||
+           (code == 0x1034a));
+}
+
+/**
+ * xmlUCSIsCatNo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of No UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatNo(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlNoG));
+}
+
+/**
+ * xmlUCSIsCatP:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of P UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatP(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlPG));
+}
+
+/**
+ * xmlUCSIsCatPc:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Pc UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPc(int code) {
+    return((code == 0x5f) ||
+           ((code >= 0x203f) && (code <= 0x2040)) ||
+           (code == 0x2054) ||
+           (code == 0x30fb) ||
+           ((code >= 0xfe33) && (code <= 0xfe34)) ||
+           ((code >= 0xfe4d) && (code <= 0xfe4f)) ||
+           (code == 0xff3f) ||
+           (code == 0xff65));
+}
+
+/**
+ * xmlUCSIsCatPd:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Pd UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPd(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlPdG));
+}
+
+/**
+ * xmlUCSIsCatPe:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Pe UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPe(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlPeG));
+}
+
+/**
+ * xmlUCSIsCatPf:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Pf UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPf(int code) {
+    return((code == 0xbb) ||
+           (code == 0x2019) ||
+           (code == 0x201d) ||
+           (code == 0x203a));
+}
+
+/**
+ * xmlUCSIsCatPi:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Pi UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPi(int code) {
+    return((code == 0xab) ||
+           (code == 0x2018) ||
+           ((code >= 0x201b) && (code <= 0x201c)) ||
+           (code == 0x201f) ||
+           (code == 0x2039));
+}
+
+/**
+ * xmlUCSIsCatPo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Po UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPo(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlPoG));
+}
+
+/**
+ * xmlUCSIsCatPs:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Ps UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatPs(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlPsG));
+}
+
+/**
+ * xmlUCSIsCatS:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of S UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatS(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlSG));
+}
+
+/**
+ * xmlUCSIsCatSc:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Sc UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatSc(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlScG));
+}
+
+/**
+ * xmlUCSIsCatSk:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Sk UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatSk(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlSkG));
+}
+
+/**
+ * xmlUCSIsCatSm:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Sm UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatSm(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlSmG));
+}
+
+/**
+ * xmlUCSIsCatSo:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of So UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatSo(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlSoG));
+}
+
+/**
+ * xmlUCSIsCatZ:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Z UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatZ(int code) {
+    return(xmlCharInRange((unsigned int)code, &xmlZG));
+}
+
+/**
+ * xmlUCSIsCatZl:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Zl UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatZl(int code) {
+    return((code == 0x2028));
+}
+
+/**
+ * xmlUCSIsCatZp:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Zp UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatZp(int code) {
+    return((code == 0x2029));
+}
+
+/**
+ * xmlUCSIsCatZs:
+ * @code: UCS code point
+ *
+ * Check whether the character is part of Zs UCS Category
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlUCSIsCatZs(int code) {
+    return((code == 0x20) ||
+           (code == 0xa0) ||
+           (code == 0x1680) ||
+           (code == 0x180e) ||
+           ((code >= 0x2000) && (code <= 0x200a)) ||
+           (code == 0x202f) ||
+           (code == 0x205f) ||
+           (code == 0x3000));
+}
+
+/**
+ * xmlUCSIsCat:
+ * @code: UCS code point
+ * @cat: UCS Category name
+ *
+ * Check whether the character is part of the UCS Category
+ *
+ * Returns 1 if true, 0 if false and -1 on unknown category
+ */
+int
+xmlUCSIsCat(int code, const char *cat) {
+    xmlIntFunc *func;
+
+    func = xmlUnicodeLookup(&xmlUnicodeCatTbl, cat);
+    if (func == NULL)
+	return (-1);
+    return (func(code));
+}
+
+#define bottom_xmlunicode
+#include "elfgcchack.h"
+#endif /* LIBXML_UNICODE_ENABLED */
diff --git a/src/xmlwriter.c b/src/xmlwriter.c
new file mode 100644
index 0000000..11b15e0
--- /dev/null
+++ b/src/xmlwriter.c
@@ -0,0 +1,4713 @@
+
+/*
+ * xmlwriter.c: XML text writer implementation
+ *
+ * For license and disclaimer see the license and disclaimer of
+ * libxml2.
+ *
+ * alfred@mickautsch.de
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/uri.h>
+#include <libxml/HTMLtree.h>
+
+#ifdef LIBXML_WRITER_ENABLED
+
+#include <libxml/xmlwriter.h>
+
+#define B64LINELEN 72
+#define B64CRLF "\r\n"
+
+/*
+ * The following VA_COPY was coded following an example in
+ * the Samba project.  It may not be sufficient for some
+ * esoteric implementations of va_list (i.e. it may need
+ * something involving a memcpy) but (hopefully) will be
+ * sufficient for libxml2.
+ */
+#ifndef VA_COPY
+  #ifdef HAVE_VA_COPY
+    #define VA_COPY(dest, src) va_copy(dest, src)
+  #else
+    #ifdef HAVE___VA_COPY
+      #define VA_COPY(dest,src) __va_copy(dest, src)
+    #else
+      #define VA_COPY(dest,src) (dest) = (src)
+    #endif
+  #endif
+#endif
+
+/*
+ * Types are kept private
+ */
+typedef enum {
+    XML_TEXTWRITER_NONE = 0,
+    XML_TEXTWRITER_NAME,
+    XML_TEXTWRITER_ATTRIBUTE,
+    XML_TEXTWRITER_TEXT,
+    XML_TEXTWRITER_PI,
+    XML_TEXTWRITER_PI_TEXT,
+    XML_TEXTWRITER_CDATA,
+    XML_TEXTWRITER_DTD,
+    XML_TEXTWRITER_DTD_TEXT,
+    XML_TEXTWRITER_DTD_ELEM,
+    XML_TEXTWRITER_DTD_ELEM_TEXT,
+    XML_TEXTWRITER_DTD_ATTL,
+    XML_TEXTWRITER_DTD_ATTL_TEXT,
+    XML_TEXTWRITER_DTD_ENTY,    /* entity */
+    XML_TEXTWRITER_DTD_ENTY_TEXT,
+    XML_TEXTWRITER_DTD_PENT,    /* parameter entity */
+    XML_TEXTWRITER_COMMENT
+} xmlTextWriterState;
+
+typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
+
+struct _xmlTextWriterStackEntry {
+    xmlChar *name;
+    xmlTextWriterState state;
+};
+
+typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
+struct _xmlTextWriterNsStackEntry {
+    xmlChar *prefix;
+    xmlChar *uri;
+    xmlLinkPtr elem;
+};
+
+struct _xmlTextWriter {
+    xmlOutputBufferPtr out;     /* output buffer */
+    xmlListPtr nodes;           /* element name stack */
+    xmlListPtr nsstack;         /* name spaces stack */
+    int level;
+    int indent;                 /* enable indent */
+    int doindent;               /* internal indent flag */
+    xmlChar *ichar;             /* indent character */
+    char qchar;                 /* character used for quoting attribute values */
+    xmlParserCtxtPtr ctxt;
+    int no_doc_free;
+    xmlDocPtr doc;
+};
+
+static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
+static int xmlCmpTextWriterStackEntry(const void *data0,
+                                      const void *data1);
+static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
+static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
+static int xmlCmpTextWriterNsStackEntry(const void *data0,
+                                        const void *data1);
+static int xmlTextWriterWriteDocCallback(void *context,
+                                         const xmlChar * str, int len);
+static int xmlTextWriterCloseDocCallback(void *context);
+
+static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
+static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
+                                      const unsigned char *data);
+static void xmlTextWriterStartDocumentCallback(void *ctx);
+static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
+static int
+  xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
+                                       xmlTextWriterStackEntry * p);
+
+/**
+ * xmlWriterErrMsg:
+ * @ctxt:  a writer context
+ * @error:  the error number
+ * @msg:  the error message
+ *
+ * Handle a writer error
+ */
+static void
+xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
+               const char *msg)
+{
+    if (ctxt != NULL) {
+	__xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
+	            NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
+		    NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
+    } else {
+	__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
+                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
+    }
+}
+
+/**
+ * xmlWriterErrMsgInt:
+ * @ctxt:  a writer context
+ * @error:  the error number
+ * @msg:  the error message
+ * @val:  an int
+ *
+ * Handle a writer error
+ */
+static void
+xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
+               const char *msg, int val)
+{
+    if (ctxt != NULL) {
+	__xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
+	            NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
+		    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
+    } else {
+	__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
+                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
+    }
+}
+
+/**
+ * xmlNewTextWriter:
+ * @out:  an xmlOutputBufferPtr
+ *
+ * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
+ * NOTE: the @out parameter will be deallocated when the writer is closed
+ *       (if the call succeed.)
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriter(xmlOutputBufferPtr out)
+{
+    xmlTextWriterPtr ret;
+
+    ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
+    if (ret == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriter : out of memory!\n");
+        return NULL;
+    }
+    memset(ret, 0, (size_t) sizeof(xmlTextWriter));
+
+    ret->nodes = xmlListCreate((xmlListDeallocator)
+                               xmlFreeTextWriterStackEntry,
+                               (xmlListDataCompare)
+                               xmlCmpTextWriterStackEntry);
+    if (ret->nodes == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriter : out of memory!\n");
+        xmlFree(ret);
+        return NULL;
+    }
+
+    ret->nsstack = xmlListCreate((xmlListDeallocator)
+                                 xmlFreeTextWriterNsStackEntry,
+                                 (xmlListDataCompare)
+                                 xmlCmpTextWriterNsStackEntry);
+    if (ret->nsstack == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriter : out of memory!\n");
+        xmlListDelete(ret->nodes);
+        xmlFree(ret);
+        return NULL;
+    }
+
+    ret->out = out;
+    ret->ichar = xmlStrdup(BAD_CAST " ");
+    ret->qchar = '"';
+
+    if (!ret->ichar) {
+        xmlListDelete(ret->nodes);
+        xmlListDelete(ret->nsstack);
+        xmlFree(ret);
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriter : out of memory!\n");
+        return NULL;
+    }
+
+    ret->doc = xmlNewDoc(NULL);
+
+    ret->no_doc_free = 0;
+
+    return ret;
+}
+
+/**
+ * xmlNewTextWriterFilename:
+ * @uri:  the URI of the resource for the output
+ * @compression:  compress the output?
+ *
+ * Create a new xmlNewTextWriter structure with @uri as output
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriterFilename(const char *uri, int compression)
+{
+    xmlTextWriterPtr ret;
+    xmlOutputBufferPtr out;
+
+    out = xmlOutputBufferCreateFilename(uri, NULL, compression);
+    if (out == NULL) {
+        xmlWriterErrMsg(NULL, XML_IO_EIO,
+                        "xmlNewTextWriterFilename : cannot open uri\n");
+        return NULL;
+    }
+
+    ret = xmlNewTextWriter(out);
+    if (ret == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriterFilename : out of memory!\n");
+        xmlOutputBufferClose(out);
+        return NULL;
+    }
+
+    ret->indent = 0;
+    ret->doindent = 0;
+    return ret;
+}
+
+/**
+ * xmlNewTextWriterMemory:
+ * @buf:  xmlBufferPtr
+ * @compression:  compress the output?
+ *
+ * Create a new xmlNewTextWriter structure with @buf as output
+ * TODO: handle compression
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
+{
+    xmlTextWriterPtr ret;
+    xmlOutputBufferPtr out;
+
+/*::todo handle compression */
+    out = xmlOutputBufferCreateBuffer(buf, NULL);
+
+    if (out == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriterMemory : out of memory!\n");
+        return NULL;
+    }
+
+    ret = xmlNewTextWriter(out);
+    if (ret == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlNewTextWriterMemory : out of memory!\n");
+        xmlOutputBufferClose(out);
+        return NULL;
+    }
+
+    return ret;
+}
+
+/**
+ * xmlNewTextWriterPushParser:
+ * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
+ * @compression:  compress the output?
+ *
+ * Create a new xmlNewTextWriter structure with @ctxt as output
+ * NOTE: the @ctxt context will be freed with the resulting writer
+ *       (if the call succeeds).
+ * TODO: handle compression
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
+                           int compression ATTRIBUTE_UNUSED)
+{
+    xmlTextWriterPtr ret;
+    xmlOutputBufferPtr out;
+
+    if (ctxt == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterPushParser : invalid context!\n");
+        return NULL;
+    }
+
+    out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
+                                  xmlTextWriterWriteDocCallback,
+                                  (xmlOutputCloseCallback)
+                                  xmlTextWriterCloseDocCallback,
+                                  (void *) ctxt, NULL);
+    if (out == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
+        return NULL;
+    }
+
+    ret = xmlNewTextWriter(out);
+    if (ret == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
+        xmlOutputBufferClose(out);
+        return NULL;
+    }
+
+    ret->ctxt = ctxt;
+
+    return ret;
+}
+
+/**
+ * xmlNewTextWriterDoc:
+ * @doc: address of a xmlDocPtr to hold the new XML document tree
+ * @compression:  compress the output?
+ *
+ * Create a new xmlNewTextWriter structure with @*doc as output
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
+{
+    xmlTextWriterPtr ret;
+    xmlSAXHandler saxHandler;
+    xmlParserCtxtPtr ctxt;
+
+    memset(&saxHandler, '\0', sizeof(saxHandler));
+    xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
+    saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
+    saxHandler.startElement = xmlSAX2StartElement;
+    saxHandler.endElement = xmlSAX2EndElement;
+
+    ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
+    if (ctxt == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
+        return NULL;
+    }
+    /*
+     * For some reason this seems to completely break if node names
+     * are interned.
+     */
+    ctxt->dictNames = 0;
+
+    ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
+    if (ctxt->myDoc == NULL) {
+        xmlFreeParserCtxt(ctxt);
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
+        return NULL;
+    }
+
+    ret = xmlNewTextWriterPushParser(ctxt, compression);
+    if (ret == NULL) {
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
+        return NULL;
+    }
+
+    xmlSetDocCompressMode(ctxt->myDoc, compression);
+
+    if (doc != NULL) {
+        *doc = ctxt->myDoc;
+	ret->no_doc_free = 1;
+    }
+
+    return ret;
+}
+
+/**
+ * xmlNewTextWriterTree:
+ * @doc: xmlDocPtr
+ * @node: xmlNodePtr or NULL for doc->children
+ * @compression:  compress the output?
+ *
+ * Create a new xmlNewTextWriter structure with @doc as output
+ * starting at @node
+ *
+ * Returns the new xmlTextWriterPtr or NULL in case of error
+ */
+xmlTextWriterPtr
+xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
+{
+    xmlTextWriterPtr ret;
+    xmlSAXHandler saxHandler;
+    xmlParserCtxtPtr ctxt;
+
+    if (doc == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterTree : invalid document tree!\n");
+        return NULL;
+    }
+
+    memset(&saxHandler, '\0', sizeof(saxHandler));
+    xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
+    saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
+    saxHandler.startElement = xmlSAX2StartElement;
+    saxHandler.endElement = xmlSAX2EndElement;
+
+    ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
+    if (ctxt == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
+        return NULL;
+    }
+    /*
+     * For some reason this seems to completely break if node names
+     * are interned.
+     */
+    ctxt->dictNames = 0;
+
+    ret = xmlNewTextWriterPushParser(ctxt, compression);
+    if (ret == NULL) {
+        xmlFreeParserCtxt(ctxt);
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
+        return NULL;
+    }
+
+    ctxt->myDoc = doc;
+    ctxt->node = node;
+    ret->no_doc_free = 1;
+
+    xmlSetDocCompressMode(doc, compression);
+
+    return ret;
+}
+
+/**
+ * xmlFreeTextWriter:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Deallocate all the resources associated to the writer
+ */
+void
+xmlFreeTextWriter(xmlTextWriterPtr writer)
+{
+    if (writer == NULL)
+        return;
+
+    if (writer->out != NULL)
+        xmlOutputBufferClose(writer->out);
+
+    if (writer->nodes != NULL)
+        xmlListDelete(writer->nodes);
+
+    if (writer->nsstack != NULL)
+        xmlListDelete(writer->nsstack);
+
+    if (writer->ctxt != NULL) {
+        if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
+	    xmlFreeDoc(writer->ctxt->myDoc);
+	    writer->ctxt->myDoc = NULL;
+	}
+        xmlFreeParserCtxt(writer->ctxt);
+    }
+
+    if (writer->doc != NULL)
+        xmlFreeDoc(writer->doc);
+
+    if (writer->ichar != NULL)
+        xmlFree(writer->ichar);
+    xmlFree(writer);
+}
+
+/**
+ * xmlTextWriterStartDocument:
+ * @writer:  the xmlTextWriterPtr
+ * @version:  the xml version ("1.0") or NULL for default ("1.0")
+ * @encoding:  the encoding or NULL for default
+ * @standalone: "yes" or "no" or NULL for default
+ *
+ * Start a new xml document
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
+                           const char *encoding, const char *standalone)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlCharEncodingHandlerPtr encoder;
+
+    if ((writer == NULL) || (writer->out == NULL)) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterStartDocument : invalid writer!\n");
+        return -1;
+    }
+
+    lk = xmlListFront(writer->nodes);
+    if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterStartDocument : not allowed in this context!\n");
+        return -1;
+    }
+
+    encoder = NULL;
+    if (encoding != NULL) {
+        encoder = xmlFindCharEncodingHandler(encoding);
+        if (encoder == NULL) {
+            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                            "xmlTextWriterStartDocument : out of memory!\n");
+            return -1;
+        }
+    }
+
+    writer->out->encoder = encoder;
+    if (encoder != NULL) {
+	if (writer->out->conv == NULL) {
+	    writer->out->conv = xmlBufferCreateSize(4000);
+	}
+        xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
+        if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
+            writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
+    } else
+        writer->out->conv = NULL;
+
+    sum = 0;
+    count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+    if (count < 0)
+        return -1;
+    sum += count;
+    if (version != 0)
+        count = xmlOutputBufferWriteString(writer->out, version);
+    else
+        count = xmlOutputBufferWriteString(writer->out, "1.0");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+    if (count < 0)
+        return -1;
+    sum += count;
+    if (writer->out->encoder != 0) {
+        count = xmlOutputBufferWriteString(writer->out, " encoding=");
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count =
+            xmlOutputBufferWriteString(writer->out,
+                                       writer->out->encoder->name);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (standalone != 0) {
+        count = xmlOutputBufferWriteString(writer->out, " standalone=");
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWriteString(writer->out, standalone);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "?>\n");
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndDocument:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml document. All open elements are closed, and
+ * the content is flushed to the output.
+ *
+ * Returns the bytes written or -1 in case of error
+ */
+int
+xmlTextWriterEndDocument(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterEndDocument : invalid writer!\n");
+        return -1;
+    }
+
+    sum = 0;
+    while ((lk = xmlListFront(writer->nodes)) != NULL) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p == 0)
+            break;
+        switch (p->state) {
+            case XML_TEXTWRITER_NAME:
+            case XML_TEXTWRITER_ATTRIBUTE:
+            case XML_TEXTWRITER_TEXT:
+                count = xmlTextWriterEndElement(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                break;
+            case XML_TEXTWRITER_PI:
+            case XML_TEXTWRITER_PI_TEXT:
+                count = xmlTextWriterEndPI(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                break;
+            case XML_TEXTWRITER_CDATA:
+                count = xmlTextWriterEndCDATA(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                break;
+            case XML_TEXTWRITER_DTD:
+            case XML_TEXTWRITER_DTD_TEXT:
+            case XML_TEXTWRITER_DTD_ELEM:
+            case XML_TEXTWRITER_DTD_ELEM_TEXT:
+            case XML_TEXTWRITER_DTD_ATTL:
+            case XML_TEXTWRITER_DTD_ATTL_TEXT:
+            case XML_TEXTWRITER_DTD_ENTY:
+            case XML_TEXTWRITER_DTD_ENTY_TEXT:
+            case XML_TEXTWRITER_DTD_PENT:
+                count = xmlTextWriterEndDTD(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                break;
+            case XML_TEXTWRITER_COMMENT:
+                count = xmlTextWriterEndComment(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (!writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    sum += xmlTextWriterFlush(writer);
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartComment:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Start an xml comment.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartComment(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterStartComment : invalid writer!\n");
+        return -1;
+    }
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_TEXT:
+                case XML_TEXTWRITER_NONE:
+                    break;
+                case XML_TEXTWRITER_NAME:
+                    /* Output namespace declarations */
+                    count = xmlTextWriterOutputNSDecl(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    count = xmlOutputBufferWriteString(writer->out, ">");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    if (writer->indent) {
+                        count =
+                            xmlOutputBufferWriteString(writer->out, "\n");
+                        if (count < 0)
+                            return -1;
+                        sum += count;
+                    }
+                    p->state = XML_TEXTWRITER_TEXT;
+                    break;
+                default:
+                    return -1;
+            }
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartElement : out of memory!\n");
+        return -1;
+    }
+
+    p->name = NULL;
+    p->state = XML_TEXTWRITER_COMMENT;
+
+    xmlListPushFront(writer->nodes, p);
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<!--");
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndComment:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End the current xml coment.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndComment(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterEndComment : invalid writer!\n");
+        return -1;
+    }
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterEndComment : not allowed in this context!\n");
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_COMMENT:
+            count = xmlOutputBufferWriteString(writer->out, "-->");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatComment:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write an xml comment.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
+                                const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatComment:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write an xml comment.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
+                                 const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteVFormatComment : invalid writer!\n");
+        return -1;
+    }
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteComment(writer, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteComment:
+ * @writer:  the xmlTextWriterPtr
+ * @content:  comment string
+ *
+ * Write an xml comment.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartComment(writer);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterWriteString(writer, content);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterEndComment(writer);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  element name
+ *
+ * Start an xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_PI:
+                case XML_TEXTWRITER_PI_TEXT:
+                    return -1;
+                case XML_TEXTWRITER_NONE:
+                    break;
+				case XML_TEXTWRITER_ATTRIBUTE:
+					count = xmlTextWriterEndAttribute(writer);
+					if (count < 0)
+						return -1;
+					sum += count;
+					/* fallthrough */
+                case XML_TEXTWRITER_NAME:
+                    /* Output namespace declarations */
+                    count = xmlTextWriterOutputNSDecl(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    count = xmlOutputBufferWriteString(writer->out, ">");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    if (writer->indent)
+                        count =
+                            xmlOutputBufferWriteString(writer->out, "\n");
+                    p->state = XML_TEXTWRITER_TEXT;
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartElement : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(name);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartElement : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+    p->state = XML_TEXTWRITER_NAME;
+
+    xmlListPushFront(writer->nodes, p);
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count =
+        xmlOutputBufferWriteString(writer->out, (const char *) p->name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartElementNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix or NULL
+ * @name:  element local name
+ * @namespaceURI:  namespace URI or NULL
+ *
+ * Start an xml element with namespace support.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
+                            const xmlChar * prefix, const xmlChar * name,
+                            const xmlChar * namespaceURI)
+{
+    int count;
+    int sum;
+    xmlChar *buf;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    buf = NULL;
+    if (prefix != 0) {
+        buf = xmlStrdup(prefix);
+        buf = xmlStrcat(buf, BAD_CAST ":");
+    }
+    buf = xmlStrcat(buf, name);
+
+    sum = 0;
+    count = xmlTextWriterStartElement(writer, buf);
+    xmlFree(buf);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    if (namespaceURI != 0) {
+        xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *) 
+        xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
+        if (p == 0) {
+            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 
+                            "xmlTextWriterStartElementNS : out of memory!\n");
+            return -1;
+        }
+
+        buf = xmlStrdup(BAD_CAST "xmlns");
+        if (prefix != 0) {
+            buf = xmlStrcat(buf, BAD_CAST ":");
+            buf = xmlStrcat(buf, prefix);
+        }
+
+        p->prefix = buf;
+        p->uri = xmlStrdup(namespaceURI);
+        if (p->uri == 0) {
+            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                            "xmlTextWriterStartElementNS : out of memory!\n");
+            xmlFree(p);
+            return -1;
+        }
+        p->elem = xmlListFront(writer->nodes);
+
+        xmlListPushFront(writer->nsstack, p);
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndElement:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End the current xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndElement(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        xmlListDelete(writer->nsstack);
+        writer->nsstack = NULL;
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0) {
+        xmlListDelete(writer->nsstack);
+        writer->nsstack = NULL;
+        return -1;
+    }
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_ATTRIBUTE:
+            count = xmlTextWriterEndAttribute(writer);
+            if (count < 0) {
+                xmlListDelete(writer->nsstack);
+                writer->nsstack = NULL;
+                return -1;
+            }
+            sum += count;
+            /* fallthrough */
+        case XML_TEXTWRITER_NAME:
+            /* Output namespace declarations */
+            count = xmlTextWriterOutputNSDecl(writer);
+            if (count < 0)
+                return -1;
+            sum += count;
+
+            if (writer->indent) /* next element needs indent */
+                writer->doindent = 1;
+            count = xmlOutputBufferWriteString(writer->out, "/>");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        case XML_TEXTWRITER_TEXT:
+            if ((writer->indent) && (writer->doindent)) {
+                count = xmlTextWriterWriteIndent(writer);
+                sum += count;
+                writer->doindent = 1;
+            } else
+                writer->doindent = 1;
+            count = xmlOutputBufferWriteString(writer->out, "</");
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out,
+                                               (const char *) p->name);
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterFullEndElement:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End the current xml element. Writes an end tag even if the element is empty
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_ATTRIBUTE:
+            count = xmlTextWriterEndAttribute(writer);
+            if (count < 0)
+                return -1;
+            sum += count;
+            /* fallthrough */
+        case XML_TEXTWRITER_NAME:
+            /* Output namespace declarations */
+            count = xmlTextWriterOutputNSDecl(writer);
+            if (count < 0)
+                return -1;
+            sum += count;
+
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            if (writer->indent)
+                writer->doindent = 0;
+            /* fallthrough */
+        case XML_TEXTWRITER_TEXT:
+            if ((writer->indent) && (writer->doindent)) {
+                count = xmlTextWriterWriteIndent(writer);
+                sum += count;
+                writer->doindent = 1;
+            } else
+                writer->doindent = 1;
+            count = xmlOutputBufferWriteString(writer->out, "</");
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out,
+                                               (const char *) p->name);
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatRaw:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted raw xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
+                            ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatRaw:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted raw xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
+                             va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteRaw(writer, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteRawLen:
+ * @writer:  the xmlTextWriterPtr
+ * @content:  text string
+ * @len:  length of the text string
+ *
+ * Write an xml text.
+ * TODO: what about entities and special chars??
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
+                         int len)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteRawLen : invalid writer!\n");
+        return -1;
+    }
+
+    if ((content == NULL) || (len < 0)) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteRawLen : invalid content!\n");
+        return -1;
+    }
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        count = xmlTextWriterHandleStateDependencies(writer, p);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (writer->indent)
+        writer->doindent = 0;
+
+    if (content != NULL) {
+        count =
+            xmlOutputBufferWrite(writer->out, len, (const char *) content);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteRaw:
+ * @writer:  the xmlTextWriterPtr
+ * @content:  text string
+ *
+ * Write a raw xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
+{
+    return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
+}
+
+/**
+ * xmlTextWriterWriteFormatString:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
+                               ...)
+{
+    int rc;
+    va_list ap;
+
+    if ((writer == NULL) || (format == NULL))
+        return -1;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatString(writer, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatString:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
+                                const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if ((writer == NULL) || (format == NULL))
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteString(writer, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteString:
+ * @writer:  the xmlTextWriterPtr
+ * @content:  text string
+ *
+ * Write an xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+    xmlChar *buf;
+
+    if ((writer == NULL) || (content == NULL))
+        return -1;
+
+    sum = 0;
+    buf = (xmlChar *) content;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_NAME:
+                case XML_TEXTWRITER_TEXT:
+#if 0
+                    buf = NULL;
+		    xmlOutputBufferWriteEscape(writer->out, content, NULL);
+#endif
+                    buf = xmlEncodeSpecialChars(NULL, content);
+                    break;
+                case XML_TEXTWRITER_ATTRIBUTE:
+                    buf = NULL;
+                    xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc,
+                                               NULL, content);
+                    break;
+		default:
+		    break;
+            }
+        }
+    }
+
+    if (buf != NULL) {
+        count = xmlTextWriterWriteRaw(writer, buf);
+
+        if (buf != content)     /* buf was allocated by us, so free it */
+            xmlFree(buf);
+
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlOutputBufferWriteBase64:
+ * @out: the xmlOutputBufferPtr
+ * @data:   binary data
+ * @len:  the number of bytes to encode
+ *
+ * Write base64 encoded data to an xmlOutputBuffer.
+ * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+static int
+xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
+                           const unsigned char *data)
+{
+    static unsigned char dtable[64] =
+            {'A','B','C','D','E','F','G','H','I','J','K','L','M',
+	     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+	     'a','b','c','d','e','f','g','h','i','j','k','l','m',
+	     'n','o','p','q','r','s','t','u','v','w','x','y','z',
+	     '0','1','2','3','4','5','6','7','8','9','+','/'};
+
+    int i;
+    int linelen;
+    int count;
+    int sum;
+
+    if ((out == NULL) || (len < 0) || (data == NULL))
+        return(-1);
+
+    linelen = 0;
+    sum = 0;
+
+    i = 0;
+    while (1) {
+        unsigned char igroup[3];
+        unsigned char ogroup[4];
+        int c;
+        int n;
+
+        igroup[0] = igroup[1] = igroup[2] = 0;
+        for (n = 0; n < 3 && i < len; n++, i++) {
+            c = data[i];
+            igroup[n] = (unsigned char) c;
+        }
+
+        if (n > 0) {
+            ogroup[0] = dtable[igroup[0] >> 2];
+            ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
+            ogroup[2] =
+                dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
+            ogroup[3] = dtable[igroup[2] & 0x3F];
+
+            if (n < 3) {
+                ogroup[3] = '=';
+                if (n < 2) {
+                    ogroup[2] = '=';
+                }
+            }
+
+            if (linelen >= B64LINELEN) {
+                count = xmlOutputBufferWrite(out, 2, B64CRLF);
+                if (count == -1)
+                    return -1;
+                sum += count;
+                linelen = 0;
+            }
+            count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
+            if (count == -1)
+                return -1;
+            sum += count;
+
+            linelen += 4;
+        }
+
+        if (i >= len)
+            break;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteBase64:
+ * @writer: the xmlTextWriterPtr
+ * @data:   binary data
+ * @start:  the position within the data of the first byte to encode
+ * @len:  the number of bytes to encode
+ *
+ * Write an base64 encoded xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
+                         int start, int len)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            count = xmlTextWriterHandleStateDependencies(writer, p);
+            if (count < 0)
+                return -1;
+            sum += count;
+        }
+    }
+
+    if (writer->indent)
+        writer->doindent = 0;
+
+    count =
+        xmlOutputBufferWriteBase64(writer->out, len,
+                                   (unsigned char *) data + start);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlOutputBufferWriteBinHex:
+ * @out: the xmlOutputBufferPtr
+ * @data:   binary data
+ * @len:  the number of bytes to encode
+ *
+ * Write hqx encoded data to an xmlOutputBuffer.
+ * ::todo
+ *
+ * Returns the bytes written (may be 0 because of buffering) 
+ * or -1 in case of error
+ */
+static int
+xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
+                           int len, const unsigned char *data)
+{
+    int count;
+    int sum;
+    static char hex[16] = 
+    	{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+    int i;
+
+    if ((out == NULL) || (data == NULL) || (len < 0)) {
+        return -1;
+    }
+
+    sum = 0;
+    for (i = 0; i < len; i++) {
+        count =
+            xmlOutputBufferWrite(out, 1,
+                                 (const char *) &hex[data[i] >> 4]);
+        if (count == -1)
+            return -1;
+        sum += count;
+        count =
+            xmlOutputBufferWrite(out, 1,
+                                 (const char *) &hex[data[i] & 0xF]);
+        if (count == -1)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteBinHex:
+ * @writer: the xmlTextWriterPtr
+ * @data:   binary data
+ * @start:  the position within the data of the first byte to encode
+ * @len:  the number of bytes to encode
+ *
+ * Write a BinHex encoded xml text.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
+                         int start, int len)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            count = xmlTextWriterHandleStateDependencies(writer, p);
+            if (count < 0)
+                return -1;
+            sum += count;
+        }
+    }
+
+    if (writer->indent)
+        writer->doindent = 0;
+
+    count =
+        xmlOutputBufferWriteBinHex(writer->out, len,
+                                   (unsigned char *) data + start);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartAttribute:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  element name
+ *
+ * Start an xml attribute.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    switch (p->state) {
+        case XML_TEXTWRITER_ATTRIBUTE:
+            count = xmlTextWriterEndAttribute(writer);
+            if (count < 0)
+                return -1;
+            sum += count;
+            /* fallthrough */
+        case XML_TEXTWRITER_NAME:
+            count = xmlOutputBufferWriteString(writer->out, " ");
+            if (count < 0)
+                return -1;
+            sum += count;
+            count =
+                xmlOutputBufferWriteString(writer->out,
+                                           (const char *) name);
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out, "=");
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+            if (count < 0)
+                return -1;
+            sum += count;
+            p->state = XML_TEXTWRITER_ATTRIBUTE;
+            break;
+        default:
+            return -1;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartAttributeNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix or NULL
+ * @name:  element local name
+ * @namespaceURI:  namespace URI or NULL
+ *
+ * Start an xml attribute with namespace support.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
+                              const xmlChar * prefix, const xmlChar * name,
+                              const xmlChar * namespaceURI)
+{
+    int count;
+    int sum;
+    xmlChar *buf;
+    xmlTextWriterNsStackEntry *p;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    /* Handle namespace first in case of error */
+    if (namespaceURI != 0) {
+        xmlTextWriterNsStackEntry nsentry, *curns;
+
+        buf = xmlStrdup(BAD_CAST "xmlns");
+        if (prefix != 0) {
+            buf = xmlStrcat(buf, BAD_CAST ":");
+            buf = xmlStrcat(buf, prefix);
+        }
+
+        nsentry.prefix = buf;
+        nsentry.uri = (xmlChar *)namespaceURI;
+        nsentry.elem = xmlListFront(writer->nodes);
+
+        curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack, 
+                                                           (void *)&nsentry);
+        if ((curns != NULL)) {
+            xmlFree(buf);
+            if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
+                /* Namespace already defined on element skip */
+                buf = NULL;
+            } else {
+                /* Prefix mismatch so error out */
+                return -1;
+            }
+        }
+
+        /* Do not add namespace decl to list - it is already there */
+        if (buf != NULL) {
+            p = (xmlTextWriterNsStackEntry *)
+                xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
+            if (p == 0) {
+                xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+								        "xmlTextWriterStartAttributeNS : out of memory!\n");
+                return -1;
+            }
+
+            p->prefix = buf;
+            p->uri = xmlStrdup(namespaceURI);
+            if (p->uri == 0) {
+                xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartAttributeNS : out of memory!\n");
+                xmlFree(p);
+                return -1;
+            }
+            p->elem = xmlListFront(writer->nodes);
+
+            xmlListPushFront(writer->nsstack, p);
+        }
+    }
+
+    buf = NULL;
+    if (prefix != 0) {
+        buf = xmlStrdup(prefix);
+        buf = xmlStrcat(buf, BAD_CAST ":");
+    }
+    buf = xmlStrcat(buf, name);
+
+    sum = 0;
+    count = xmlTextWriterStartAttribute(writer, buf);
+    xmlFree(buf);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndAttribute:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End the current xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0) {
+        return -1;
+    }
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_ATTRIBUTE:
+            p->state = XML_TEXTWRITER_NAME;
+
+            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+            if (count < 0) {
+                return -1;
+            }
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatAttribute:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  attribute name
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml attribute.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
+                                  const xmlChar * name, const char *format,
+                                  ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatAttribute:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  attribute name
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml attribute.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
+                                   const xmlChar * name,
+                                   const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteAttribute(writer, name, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteAttribute:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  attribute name
+ * @content:  attribute content
+ *
+ * Write an xml attribute.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
+                            const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartAttribute(writer, name);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterWriteString(writer, content);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterEndAttribute(writer);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatAttributeNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  attribute local name
+ * @namespaceURI:  namespace URI
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml attribute.with namespace support
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
+                                    const xmlChar * prefix,
+                                    const xmlChar * name,
+                                    const xmlChar * namespaceURI,
+                                    const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
+                                              namespaceURI, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatAttributeNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  attribute local name
+ * @namespaceURI:  namespace URI
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml attribute.with namespace support
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
+                                     const xmlChar * prefix,
+                                     const xmlChar * name,
+                                     const xmlChar * namespaceURI,
+                                     const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
+                                       buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteAttributeNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  attribute local name
+ * @namespaceURI:  namespace URI
+ * @content:  attribute content
+ *
+ * Write an xml attribute.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
+                              const xmlChar * prefix, const xmlChar * name,
+                              const xmlChar * namespaceURI,
+                              const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    sum = 0;
+    count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterWriteString(writer, content);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterEndAttribute(writer);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  element name
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
+                                const xmlChar * name, const char *format,
+                                ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  element name
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
+                                 const xmlChar * name, const char *format,
+                                 va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteElement(writer, name, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  element name
+ * @content:  element content
+ *
+ * Write an xml element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
+                          const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartElement(writer, name);
+    if (count == -1)
+        return -1;
+    sum += count;
+    count = xmlTextWriterWriteString(writer, content);
+    if (count == -1)
+        return -1;
+    sum += count;
+    count = xmlTextWriterEndElement(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatElementNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  element local name
+ * @namespaceURI:  namespace URI
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml element with namespace support.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
+                                  const xmlChar * prefix,
+                                  const xmlChar * name,
+                                  const xmlChar * namespaceURI,
+                                  const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
+                                            namespaceURI, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatElementNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  element local name
+ * @namespaceURI:  namespace URI
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml element with namespace support.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
+                                   const xmlChar * prefix,
+                                   const xmlChar * name,
+                                   const xmlChar * namespaceURI,
+                                   const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
+                                     buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteElementNS:
+ * @writer:  the xmlTextWriterPtr
+ * @prefix:  namespace prefix
+ * @name:  element local name
+ * @namespaceURI:  namespace URI
+ * @content:  element content
+ *
+ * Write an xml element with namespace support.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
+                            const xmlChar * prefix, const xmlChar * name,
+                            const xmlChar * namespaceURI,
+                            const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
+        return -1;
+
+    sum = 0;
+    count =
+        xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlTextWriterWriteString(writer, content);
+    if (count == -1)
+        return -1;
+    sum += count;
+    count = xmlTextWriterEndElement(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartPI:
+ * @writer:  the xmlTextWriterPtr
+ * @target:  PI target
+ *
+ * Start an xml PI.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if ((writer == NULL) || (target == NULL) || (*target == '\0'))
+        return -1;
+
+    if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
+        return -1;
+    }
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_ATTRIBUTE:
+                    count = xmlTextWriterEndAttribute(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    /* fallthrough */
+                case XML_TEXTWRITER_NAME:
+                    /* Output namespace declarations */
+                    count = xmlTextWriterOutputNSDecl(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    count = xmlOutputBufferWriteString(writer->out, ">");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    p->state = XML_TEXTWRITER_TEXT;
+                    break;
+                case XML_TEXTWRITER_NONE:
+                case XML_TEXTWRITER_TEXT:
+                case XML_TEXTWRITER_DTD:
+                    break;
+                case XML_TEXTWRITER_PI:
+                case XML_TEXTWRITER_PI_TEXT:
+                    xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                                    "xmlTextWriterStartPI : nested PI!\n");
+                    return -1;
+                default:
+                    return -1;
+            }
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartPI : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(target);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartPI : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+    p->state = XML_TEXTWRITER_PI;
+
+    xmlListPushFront(writer->nodes, p);
+
+    count = xmlOutputBufferWriteString(writer->out, "<?");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count =
+        xmlOutputBufferWriteString(writer->out, (const char *) p->name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndPI:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End the current xml PI.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndPI(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return 0;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return 0;
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_PI:
+        case XML_TEXTWRITER_PI_TEXT:
+            count = xmlOutputBufferWriteString(writer->out, "?>");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+      	if (count < 0)
+       	return -1;
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatPI:
+ * @writer:  the xmlTextWriterPtr
+ * @target:  PI target
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted PI.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
+                           const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatPI:
+ * @writer:  the xmlTextWriterPtr
+ * @target:  PI target
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml PI.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
+                            const xmlChar * target, const char *format,
+                            va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWritePI(writer, target, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWritePI:
+ * @writer:  the xmlTextWriterPtr
+ * @target:  PI target
+ * @content:  PI content
+ *
+ * Write an xml PI.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
+                     const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartPI(writer, target);
+    if (count == -1)
+        return -1;
+    sum += count;
+    if (content != 0) {
+        count = xmlTextWriterWriteString(writer, content);
+        if (count == -1)
+            return -1;
+        sum += count;
+    }
+    count = xmlTextWriterEndPI(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartCDATA:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Start an xml CDATA section.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_NONE:
+		case XML_TEXTWRITER_TEXT:
+                case XML_TEXTWRITER_PI:
+                case XML_TEXTWRITER_PI_TEXT:
+                    break;
+                case XML_TEXTWRITER_ATTRIBUTE:
+                    count = xmlTextWriterEndAttribute(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    /* fallthrough */
+                case XML_TEXTWRITER_NAME:
+                    /* Output namespace declarations */
+                    count = xmlTextWriterOutputNSDecl(writer);
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    count = xmlOutputBufferWriteString(writer->out, ">");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    p->state = XML_TEXTWRITER_TEXT;
+                    break;
+                case XML_TEXTWRITER_CDATA:
+                    xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                                    "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
+                    return -1;
+                default:
+                    return -1;
+            }
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartCDATA : out of memory!\n");
+        return -1;
+    }
+
+    p->name = NULL;
+    p->state = XML_TEXTWRITER_CDATA;
+
+    xmlListPushFront(writer->nodes, p);
+
+    count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndCDATA:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml CDATA section.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    sum = 0;
+    switch (p->state) {
+        case XML_TEXTWRITER_CDATA:
+            count = xmlOutputBufferWriteString(writer->out, "]]>");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatCDATA:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted xml CDATA.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
+                              ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatCDATA:
+ * @writer:  the xmlTextWriterPtr
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted xml CDATA.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
+                               va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteCDATA(writer, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteCDATA:
+ * @writer:  the xmlTextWriterPtr
+ * @content:  CDATA content
+ *
+ * Write an xml CDATA.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartCDATA(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+    if (content != 0) {
+        count = xmlTextWriterWriteString(writer, content);
+        if (count == -1)
+            return -1;
+        sum += count;
+    }
+    count = xmlTextWriterEndCDATA(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartDTD:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ *
+ * Start an xml DTD.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartDTD(xmlTextWriterPtr writer,
+                      const xmlChar * name,
+                      const xmlChar * pubid, const xmlChar * sysid)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL || name == NULL || *name == '\0')
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTD : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(name);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTD : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+    p->state = XML_TEXTWRITER_DTD;
+
+    xmlListPushFront(writer->nodes, p);
+
+    count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    if (pubid != 0) {
+        if (sysid == 0) {
+            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                            "xmlTextWriterStartDTD : system identifier needed!\n");
+            return -1;
+        }
+
+        if (writer->indent)
+            count = xmlOutputBufferWrite(writer->out, 1, "\n");
+        else
+            count = xmlOutputBufferWrite(writer->out, 1, " ");
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (sysid != 0) {
+        if (pubid == 0) {
+            if (writer->indent)
+                count = xmlOutputBufferWrite(writer->out, 1, "\n");
+            else
+                count = xmlOutputBufferWrite(writer->out, 1, " ");
+            if (count < 0)
+                return -1;
+            sum += count;
+            count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
+            if (count < 0)
+                return -1;
+            sum += count;
+        } else {
+			if (writer->indent)
+            count = xmlOutputBufferWriteString(writer->out, "\n       ");
+            else
+                count = xmlOutputBufferWrite(writer->out, 1, " ");
+            if (count < 0)
+                return -1;
+            sum += count;
+        }
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndDTD:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml DTD.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTD(xmlTextWriterPtr writer)
+{
+    int loop;
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    sum = 0;
+    loop = 1;
+    while (loop) {
+        lk = xmlListFront(writer->nodes);
+        if (lk == NULL)
+            break;
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p == 0)
+            break;
+        switch (p->state) {
+            case XML_TEXTWRITER_DTD_TEXT:
+                count = xmlOutputBufferWriteString(writer->out, "]");
+                if (count < 0)
+                    return -1;
+                sum += count;
+                /* fallthrough */
+            case XML_TEXTWRITER_DTD:
+                count = xmlOutputBufferWriteString(writer->out, ">");
+
+                if (writer->indent) {
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    count = xmlOutputBufferWriteString(writer->out, "\n");
+                }
+
+                xmlListPopFront(writer->nodes);
+                break;
+            case XML_TEXTWRITER_DTD_ELEM:
+            case XML_TEXTWRITER_DTD_ELEM_TEXT:
+                count = xmlTextWriterEndDTDElement(writer);
+                break;
+            case XML_TEXTWRITER_DTD_ATTL:
+            case XML_TEXTWRITER_DTD_ATTL_TEXT:
+                count = xmlTextWriterEndDTDAttlist(writer);
+                break;
+            case XML_TEXTWRITER_DTD_ENTY:
+            case XML_TEXTWRITER_DTD_PENT:
+            case XML_TEXTWRITER_DTD_ENTY_TEXT:
+                count = xmlTextWriterEndDTDEntity(writer);
+                break;
+            case XML_TEXTWRITER_COMMENT:
+                count = xmlTextWriterEndComment(writer);
+                break;
+            default:
+                loop = 0;
+                continue;
+        }
+
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatDTD:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a DTD with a formatted markup declarations part.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
+                            const xmlChar * name,
+                            const xmlChar * pubid,
+                            const xmlChar * sysid, const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
+                                      ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatDTD:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a DTD with a formatted markup declarations part.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
+                             const xmlChar * name,
+                             const xmlChar * pubid,
+                             const xmlChar * sysid,
+                             const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteDTD:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @subset:  string content of the DTD
+ *
+ * Write a DTD.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
+                      const xmlChar * name,
+                      const xmlChar * pubid,
+                      const xmlChar * sysid, const xmlChar * subset)
+{
+    int count;
+    int sum;
+
+    sum = 0;
+    count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
+    if (count == -1)
+        return -1;
+    sum += count;
+    if (subset != 0) {
+        count = xmlTextWriterWriteString(writer, subset);
+        if (count == -1)
+            return -1;
+        sum += count;
+    }
+    count = xmlTextWriterEndDTD(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartDTDElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD element
+ *
+ * Start an xml DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL || name == NULL || *name == '\0')
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p != 0) {
+        switch (p->state) {
+            case XML_TEXTWRITER_DTD:
+                count = xmlOutputBufferWriteString(writer->out, " [");
+                if (count < 0)
+                    return -1;
+                sum += count;
+                if (writer->indent) {
+                    count = xmlOutputBufferWriteString(writer->out, "\n");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                }
+                p->state = XML_TEXTWRITER_DTD_TEXT;
+                /* fallthrough */
+            case XML_TEXTWRITER_DTD_TEXT:
+            case XML_TEXTWRITER_NONE:
+                break;
+            default:
+                return -1;
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDElement : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(name);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDElement : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+    p->state = XML_TEXTWRITER_DTD_ELEM;
+
+    xmlListPushFront(writer->nodes, p);
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndDTDElement:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    switch (p->state) {
+        case XML_TEXTWRITER_DTD_ELEM:
+        case XML_TEXTWRITER_DTD_ELEM_TEXT:
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatDTDElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD element
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
+                                   const xmlChar * name,
+                                   const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatDTDElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD element
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
+                                    const xmlChar * name,
+                                    const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteDTDElement(writer, name, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteDTDElement:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD element
+ * @content:  content of the element
+ *
+ * Write a DTD element.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
+                             const xmlChar * name, const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    if (content == NULL)
+        return -1;
+
+    sum = 0;
+    count = xmlTextWriterStartDTDElement(writer, name);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterWriteString(writer, content);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterEndDTDElement(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartDTDAttlist:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD ATTLIST
+ *
+ * Start an xml DTD ATTLIST.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL || name == NULL || *name == '\0')
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p != 0) {
+        switch (p->state) {
+            case XML_TEXTWRITER_DTD:
+                count = xmlOutputBufferWriteString(writer->out, " [");
+                if (count < 0)
+                    return -1;
+                sum += count;
+                if (writer->indent) {
+                    count = xmlOutputBufferWriteString(writer->out, "\n");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                }
+                p->state = XML_TEXTWRITER_DTD_TEXT;
+                /* fallthrough */
+            case XML_TEXTWRITER_DTD_TEXT:
+            case XML_TEXTWRITER_NONE:
+                break;
+            default:
+                return -1;
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDAttlist : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(name);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDAttlist : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+    p->state = XML_TEXTWRITER_DTD_ATTL;
+
+    xmlListPushFront(writer->nodes, p);
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndDTDAttlist:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml DTD attribute list.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    switch (p->state) {
+        case XML_TEXTWRITER_DTD_ATTL:
+        case XML_TEXTWRITER_DTD_ATTL_TEXT:
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatDTDAttlist:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD ATTLIST
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted DTD ATTLIST.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
+                                   const xmlChar * name,
+                                   const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatDTDAttlist:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD ATTLIST
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted DTD ATTLIST.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
+                                    const xmlChar * name,
+                                    const char *format, va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteDTDAttlist:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the DTD ATTLIST
+ * @content:  content of the ATTLIST
+ *
+ * Write a DTD ATTLIST.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
+                             const xmlChar * name, const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    if (content == NULL)
+        return -1;
+
+    sum = 0;
+    count = xmlTextWriterStartDTDAttlist(writer, name);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterWriteString(writer, content);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterEndDTDAttlist(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterStartDTDEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD ATTLIST
+ *
+ * Start an xml DTD ATTLIST.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
+                            int pe, const xmlChar * name)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL || name == NULL || *name == '\0')
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk != 0) {
+
+        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+        if (p != 0) {
+            switch (p->state) {
+                case XML_TEXTWRITER_DTD:
+                    count = xmlOutputBufferWriteString(writer->out, " [");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                    if (writer->indent) {
+                        count =
+                            xmlOutputBufferWriteString(writer->out, "\n");
+                        if (count < 0)
+                            return -1;
+                        sum += count;
+                    }
+                    p->state = XML_TEXTWRITER_DTD_TEXT;
+                    /* fallthrough */
+                case XML_TEXTWRITER_DTD_TEXT:
+                case XML_TEXTWRITER_NONE:
+                    break;
+                default:
+                    return -1;
+            }
+        }
+    }
+
+    p = (xmlTextWriterStackEntry *)
+        xmlMalloc(sizeof(xmlTextWriterStackEntry));
+    if (p == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDElement : out of memory!\n");
+        return -1;
+    }
+
+    p->name = xmlStrdup(name);
+    if (p->name == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterStartDTDElement : out of memory!\n");
+        xmlFree(p);
+        return -1;
+    }
+
+    if (pe != 0)
+        p->state = XML_TEXTWRITER_DTD_PENT;
+    else
+        p->state = XML_TEXTWRITER_DTD_ENTY;
+
+    xmlListPushFront(writer->nodes, p);
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    if (pe != 0) {
+        count = xmlOutputBufferWriteString(writer->out, "% ");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterEndDTDEntity:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * End an xml DTD entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL)
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0)
+        return -1;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    switch (p->state) {
+        case XML_TEXTWRITER_DTD_ENTY_TEXT:
+            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+            if (count < 0)
+                return -1;
+            sum += count;
+        case XML_TEXTWRITER_DTD_ENTY:
+        case XML_TEXTWRITER_DTD_PENT:
+            count = xmlOutputBufferWriteString(writer->out, ">");
+            if (count < 0)
+                return -1;
+            sum += count;
+            break;
+        default:
+            return -1;
+    }
+
+    if (writer->indent) {
+        count = xmlOutputBufferWriteString(writer->out, "\n");
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    xmlListPopFront(writer->nodes);
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteFormatDTDInternalEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD entity
+ * @format:  format string (see printf)
+ * @...:  extra parameters for the format
+ *
+ * Write a formatted DTD internal entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int XMLCDECL
+xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
+                                          int pe,
+                                          const xmlChar * name,
+                                          const char *format, ...)
+{
+    int rc;
+    va_list ap;
+
+    va_start(ap, format);
+
+    rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
+                                                    format, ap);
+
+    va_end(ap);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteVFormatDTDInternalEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD entity
+ * @format:  format string (see printf)
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Write a formatted DTD internal entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
+                                           int pe,
+                                           const xmlChar * name,
+                                           const char *format,
+                                           va_list argptr)
+{
+    int rc;
+    xmlChar *buf;
+
+    if (writer == NULL)
+        return -1;
+
+    buf = xmlTextWriterVSprintf(format, argptr);
+    if (buf == NULL)
+        return -1;
+
+    rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
+
+    xmlFree(buf);
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteDTDEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD entity
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @ndataid:  the xml notation name.
+ * @content:  content of the entity
+ *
+ * Write a DTD entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
+                            int pe,
+                            const xmlChar * name,
+                            const xmlChar * pubid,
+                            const xmlChar * sysid,
+                            const xmlChar * ndataid,
+                            const xmlChar * content)
+{
+    if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
+        return -1;
+    if ((pe != 0) && (ndataid != NULL))
+        return -1;
+
+    if ((pubid == NULL) && (sysid == NULL))
+        return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
+                                                   content);
+
+    return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
+                                               sysid, ndataid);
+}
+
+/**
+ * xmlTextWriterWriteDTDInternalEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD entity
+ * @content:  content of the entity
+ *
+ * Write a DTD internal entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
+                                    int pe,
+                                    const xmlChar * name,
+                                    const xmlChar * content)
+{
+    int count;
+    int sum;
+
+    if ((name == NULL) || (*name == '\0') || (content == NULL))
+        return -1;
+
+    sum = 0;
+    count = xmlTextWriterStartDTDEntity(writer, pe, name);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterWriteString(writer, content);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterEndDTDEntity(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteDTDExternalEntity:
+ * @writer:  the xmlTextWriterPtr
+ * @pe:  TRUE if this is a parameter entity, FALSE if not
+ * @name:  the name of the DTD entity
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @ndataid:  the xml notation name.
+ *
+ * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
+                                    int pe,
+                                    const xmlChar * name,
+                                    const xmlChar * pubid,
+                                    const xmlChar * sysid,
+                                    const xmlChar * ndataid)
+{
+    int count;
+    int sum;
+
+    if (((pubid == NULL) && (sysid == NULL)))
+        return -1;
+    if ((pe != 0) && (ndataid != NULL))
+        return -1;
+
+    sum = 0;
+    count = xmlTextWriterStartDTDEntity(writer, pe, name);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    count =
+        xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
+                                                    ndataid);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    count = xmlTextWriterEndDTDEntity(writer);
+    if (count == -1)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteDTDExternalEntityContents:
+ * @writer:  the xmlTextWriterPtr
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ * @ndataid:  the xml notation name.
+ *
+ * Write the contents of a DTD external entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
+                                            const xmlChar * pubid,
+                                            const xmlChar * sysid,
+                                            const xmlChar * ndataid)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
+        return -1;
+    }
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return -1;
+
+    switch (p->state) {
+        case XML_TEXTWRITER_DTD_ENTY:
+            break;
+        case XML_TEXTWRITER_DTD_PENT:
+            if (ndataid != NULL) {
+                xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                                "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
+                return -1;
+            }
+            break;
+        default:
+            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                            "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
+            return -1;
+    }
+
+    if (pubid != 0) {
+        if (sysid == 0) {
+            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
+                            "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
+            return -1;
+        }
+
+        count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (sysid != 0) {
+        if (pubid == 0) {
+            count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
+            if (count < 0)
+                return -1;
+            sum += count;
+        }
+
+        count = xmlOutputBufferWriteString(writer->out, " ");
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (ndataid != NULL) {
+        count = xmlOutputBufferWriteString(writer->out, " NDATA ");
+        if (count < 0)
+            return -1;
+        sum += count;
+
+        count =
+            xmlOutputBufferWriteString(writer->out,
+                                       (const char *) ndataid);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterWriteDTDNotation:
+ * @writer:  the xmlTextWriterPtr
+ * @name:  the name of the xml notation
+ * @pubid:  the public identifier, which is an alternative to the system identifier
+ * @sysid:  the system identifier, which is the URI of the DTD
+ *
+ * Write a DTD entity.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
+                              const xmlChar * name,
+                              const xmlChar * pubid, const xmlChar * sysid)
+{
+    int count;
+    int sum;
+    xmlLinkPtr lk;
+    xmlTextWriterStackEntry *p;
+
+    if (writer == NULL || name == NULL || *name == '\0')
+        return -1;
+
+    sum = 0;
+    lk = xmlListFront(writer->nodes);
+    if (lk == 0) {
+        return -1;
+    }
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p != 0) {
+        switch (p->state) {
+            case XML_TEXTWRITER_DTD:
+                count = xmlOutputBufferWriteString(writer->out, " [");
+                if (count < 0)
+                    return -1;
+                sum += count;
+                if (writer->indent) {
+                    count = xmlOutputBufferWriteString(writer->out, "\n");
+                    if (count < 0)
+                        return -1;
+                    sum += count;
+                }
+                p->state = XML_TEXTWRITER_DTD_TEXT;
+                /* fallthrough */
+            case XML_TEXTWRITER_DTD_TEXT:
+                break;
+            default:
+                return -1;
+        }
+    }
+
+    if (writer->indent) {
+        count = xmlTextWriterWriteIndent(writer);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
+    if (count < 0)
+        return -1;
+    sum += count;
+    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    if (pubid != 0) {
+        count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    if (sysid != 0) {
+        if (pubid == 0) {
+            count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
+            if (count < 0)
+                return -1;
+            sum += count;
+        }
+        count = xmlOutputBufferWriteString(writer->out, " ");
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count =
+            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
+        if (count < 0)
+            return -1;
+        sum += count;
+        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    count = xmlOutputBufferWriteString(writer->out, ">");
+    if (count < 0)
+        return -1;
+    sum += count;
+
+    return sum;
+}
+
+/**
+ * xmlTextWriterFlush:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Flush the output buffer.
+ *
+ * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ */
+int
+xmlTextWriterFlush(xmlTextWriterPtr writer)
+{
+    int count;
+
+    if (writer == NULL)
+        return -1;
+
+    if (writer->out == NULL)
+        count = 0;
+    else
+        count = xmlOutputBufferFlush(writer->out);
+
+    return count;
+}
+
+/**
+ * misc
+ */
+
+/**
+ * xmlFreeTextWriterStackEntry:
+ * @lk:  the xmlLinkPtr
+ *
+ * Free callback for the xmlList.
+ */
+static void
+xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
+{
+    xmlTextWriterStackEntry *p;
+
+    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return;
+
+    if (p->name != 0)
+        xmlFree(p->name);
+    xmlFree(p);
+}
+
+/**
+ * xmlCmpTextWriterStackEntry:
+ * @data0:  the first data
+ * @data1:  the second data
+ *
+ * Compare callback for the xmlList.
+ *
+ * Returns -1, 0, 1
+ */
+static int
+xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
+{
+    xmlTextWriterStackEntry *p0;
+    xmlTextWriterStackEntry *p1;
+
+    if (data0 == data1)
+        return 0;
+
+    if (data0 == 0)
+        return -1;
+
+    if (data1 == 0)
+        return 1;
+
+    p0 = (xmlTextWriterStackEntry *) data0;
+    p1 = (xmlTextWriterStackEntry *) data1;
+
+    return xmlStrcmp(p0->name, p1->name);
+}
+
+/**
+ * misc
+ */
+
+/**
+ * xmlTextWriterOutputNSDecl:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Output the current namespace declarations.
+ */
+static int
+xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
+{
+    xmlLinkPtr lk;
+    xmlTextWriterNsStackEntry *np;
+    int count;
+    int sum;
+
+    sum = 0;
+    while (!xmlListEmpty(writer->nsstack)) {
+        xmlChar *namespaceURI = NULL;
+        xmlChar *prefix = NULL;
+
+        lk = xmlListFront(writer->nsstack);
+        np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
+
+        if (np != 0) {
+            namespaceURI = xmlStrdup(np->uri);
+            prefix = xmlStrdup(np->prefix);
+        }
+
+        xmlListPopFront(writer->nsstack);
+
+        if (np != 0) {
+            count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
+            xmlFree(namespaceURI);
+            xmlFree(prefix);
+
+            if (count < 0) {
+                xmlListDelete(writer->nsstack);
+                writer->nsstack = NULL;
+                return -1;
+            }
+            sum += count;
+        }
+    }
+    return sum;
+}
+
+/**
+ * xmlFreeTextWriterNsStackEntry:
+ * @lk:  the xmlLinkPtr
+ *
+ * Free callback for the xmlList.
+ */
+static void
+xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
+{
+    xmlTextWriterNsStackEntry *p;
+
+    p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
+    if (p == 0)
+        return;
+
+    if (p->prefix != 0)
+        xmlFree(p->prefix);
+    if (p->uri != 0)
+        xmlFree(p->uri);
+
+    xmlFree(p);
+}
+
+/**
+ * xmlCmpTextWriterNsStackEntry:
+ * @data0:  the first data
+ * @data1:  the second data
+ *
+ * Compare callback for the xmlList.
+ *
+ * Returns -1, 0, 1
+ */
+static int
+xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
+{
+    xmlTextWriterNsStackEntry *p0;
+    xmlTextWriterNsStackEntry *p1;
+    int rc;
+
+    if (data0 == data1)
+        return 0;
+
+    if (data0 == 0)
+        return -1;
+
+    if (data1 == 0)
+        return 1;
+
+    p0 = (xmlTextWriterNsStackEntry *) data0;
+    p1 = (xmlTextWriterNsStackEntry *) data1;
+
+    rc = xmlStrcmp(p0->prefix, p1->prefix);
+
+    if ((rc != 0) || (p0->elem != p1->elem))
+        rc = -1;
+
+    return rc;
+}
+
+/**
+ * xmlTextWriterWriteDocCallback:
+ * @context:  the xmlBufferPtr
+ * @str:  the data to write
+ * @len:  the length of the data
+ *
+ * Write callback for the xmlOutputBuffer with target xmlBuffer
+ *
+ * Returns -1, 0, 1
+ */
+static int
+xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
+    int rc;
+
+    if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
+        xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteDocCallback : XML error %d !\n",
+                        rc);
+        return -1;
+    }
+
+    return len;
+}
+
+/**
+ * xmlTextWriterCloseDocCallback:
+ * @context:  the xmlBufferPtr
+ *
+ * Close callback for the xmlOutputBuffer with target xmlBuffer
+ *
+ * Returns -1, 0, 1
+ */
+static int
+xmlTextWriterCloseDocCallback(void *context)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
+    int rc;
+
+    if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
+        xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
+                        "xmlTextWriterWriteDocCallback : XML error %d !\n",
+                        rc);
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * xmlTextWriterVSprintf:
+ * @format:  see printf
+ * @argptr:  pointer to the first member of the variable argument list.
+ *
+ * Utility function for formatted output
+ *
+ * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
+ */
+static xmlChar *
+xmlTextWriterVSprintf(const char *format, va_list argptr)
+{
+    int size;
+    int count;
+    xmlChar *buf;
+    va_list locarg;
+
+    size = BUFSIZ;
+    buf = (xmlChar *) xmlMalloc(size);
+    if (buf == NULL) {
+        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                        "xmlTextWriterVSprintf : out of memory!\n");
+        return NULL;
+    }
+
+    VA_COPY(locarg, argptr);
+    while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
+           || (count == size - 1) || (count == size) || (count > size)) {
+	va_end(locarg);
+        xmlFree(buf);
+        size += BUFSIZ;
+        buf = (xmlChar *) xmlMalloc(size);
+        if (buf == NULL) {
+            xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
+                            "xmlTextWriterVSprintf : out of memory!\n");
+            return NULL;
+        }
+	VA_COPY(locarg, argptr);
+    }
+    va_end(locarg);
+
+    return buf;
+}
+
+/**
+ * xmlTextWriterStartDocumentCallback:
+ * @ctx: the user data (XML parser context)
+ *
+ * called at the start of document processing.
+ */
+static void
+xmlTextWriterStartDocumentCallback(void *ctx)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlDocPtr doc;
+
+    if (ctxt->html) {
+#ifdef LIBXML_HTML_ENABLED
+        if (ctxt->myDoc == NULL)
+            ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
+        if (ctxt->myDoc == NULL) {
+            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+                ctxt->sax->error(ctxt->userData,
+                                 "SAX.startDocument(): out of memory\n");
+            ctxt->errNo = XML_ERR_NO_MEMORY;
+            ctxt->instate = XML_PARSER_EOF;
+            ctxt->disableSAX = 1;
+            return;
+        }
+#else
+        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
+                        "libxml2 built without HTML support\n");
+        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+        ctxt->instate = XML_PARSER_EOF;
+        ctxt->disableSAX = 1;
+        return;
+#endif
+    } else {
+        doc = ctxt->myDoc;
+        if (doc == NULL)
+            doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
+        if (doc != NULL) {
+            if (doc->children == NULL) {
+                if (ctxt->encoding != NULL)
+                    doc->encoding = xmlStrdup(ctxt->encoding);
+                else
+                    doc->encoding = NULL;
+                doc->standalone = ctxt->standalone;
+            }
+        } else {
+            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+                ctxt->sax->error(ctxt->userData,
+                                 "SAX.startDocument(): out of memory\n");
+            ctxt->errNo = XML_ERR_NO_MEMORY;
+            ctxt->instate = XML_PARSER_EOF;
+            ctxt->disableSAX = 1;
+            return;
+        }
+    }
+    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
+        (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
+        ctxt->myDoc->URL =
+            xmlCanonicPath((const xmlChar *) ctxt->input->filename);
+        if (ctxt->myDoc->URL == NULL)
+            ctxt->myDoc->URL =
+                xmlStrdup((const xmlChar *) ctxt->input->filename);
+    }
+}
+
+/**
+ * xmlTextWriterSetIndent:
+ * @writer:  the xmlTextWriterPtr
+ * @indent:  do indentation?
+ *
+ * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
+ *
+ * Returns -1 on error or 0 otherwise.
+ */
+int
+xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
+{
+    if ((writer == NULL) || (indent < 0))
+        return -1;
+
+    writer->indent = indent;
+    writer->doindent = 1;
+
+    return 0;
+}
+
+/**
+ * xmlTextWriterSetIndentString:
+ * @writer:  the xmlTextWriterPtr
+ * @str:  the xmlChar string
+ *
+ * Set string indentation.
+ *
+ * Returns -1 on error or 0 otherwise.
+ */
+int
+xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
+{
+    if ((writer == NULL) || (!str))
+        return -1;
+
+    if (writer->ichar != NULL)
+        xmlFree(writer->ichar);
+    writer->ichar = xmlStrdup(str);
+
+    if (!writer->ichar)
+        return -1;
+    else
+        return 0;
+}
+
+/**
+ * xmlTextWriterWriteIndent:
+ * @writer:  the xmlTextWriterPtr
+ *
+ * Write indent string.
+ *
+ * Returns -1 on error or the number of strings written.
+ */
+static int
+xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
+{
+    int lksize;
+    int i;
+    int ret;
+
+    lksize = xmlListSize(writer->nodes);
+    if (lksize < 1)
+        return (-1);            /* list is empty */
+    for (i = 0; i < (lksize - 1); i++) {
+        ret = xmlOutputBufferWriteString(writer->out,
+                                         (const char *) writer->ichar);
+        if (ret == -1)
+            return (-1);
+    }
+
+    return (lksize - 1);
+}
+
+/**
+ * xmlTextWriterHandleStateDependencies:
+ * @writer:  the xmlTextWriterPtr
+ * @p:  the xmlTextWriterStackEntry
+ *
+ * Write state dependent strings.
+ *
+ * Returns -1 on error or the number of characters written.
+ */
+static int
+xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
+                                     xmlTextWriterStackEntry * p)
+{
+    int count;
+    int sum;
+    char extra[3];
+
+    if (writer == NULL)
+        return -1;
+
+    if (p == NULL)
+        return 0;
+
+    sum = 0;
+    extra[0] = extra[1] = extra[2] = '\0';
+    if (p != 0) {
+        sum = 0;
+        switch (p->state) {
+            case XML_TEXTWRITER_NAME:
+                /* Output namespace declarations */
+                count = xmlTextWriterOutputNSDecl(writer);
+                if (count < 0)
+                    return -1;
+                sum += count;
+                extra[0] = '>';
+                p->state = XML_TEXTWRITER_TEXT;
+                break;
+            case XML_TEXTWRITER_PI:
+                extra[0] = ' ';
+                p->state = XML_TEXTWRITER_PI_TEXT;
+                break;
+            case XML_TEXTWRITER_DTD:
+                extra[0] = ' ';
+                extra[1] = '[';
+                p->state = XML_TEXTWRITER_DTD_TEXT;
+                break;
+            case XML_TEXTWRITER_DTD_ELEM:
+                extra[0] = ' ';
+                p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
+                break;
+            case XML_TEXTWRITER_DTD_ATTL:
+                extra[0] = ' ';
+                p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
+                break;
+            case XML_TEXTWRITER_DTD_ENTY:
+            case XML_TEXTWRITER_DTD_PENT:
+                extra[0] = ' ';
+                extra[1] = writer->qchar;
+                p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (*extra != '\0') {
+        count = xmlOutputBufferWriteString(writer->out, extra);
+        if (count < 0)
+            return -1;
+        sum += count;
+    }
+
+    return sum;
+}
+
+#define bottom_xmlwriter
+#include "elfgcchack.h"
+#endif
diff --git a/src/xpath.c b/src/xpath.c
new file mode 100644
index 0000000..9423ef8
--- /dev/null
+++ b/src/xpath.c
@@ -0,0 +1,15157 @@
+/*
+ * xpath.c: XML Path Language implementation
+ *          XPath is a language for addressing parts of an XML document,
+ *          designed to be used by both XSLT and XPointer
+ *f
+ * Reference: W3C Recommendation 16 November 1999
+ *     http://www.w3.org/TR/1999/REC-xpath-19991116
+ * Public reference:
+ *     http://www.w3.org/TR/xpath
+ *
+ * See Copyright for the status of this software
+ *
+ * Author: daniel@veillard.com
+ *
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/valid.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parserInternals.h>
+#include <libxml/hash.h>
+#ifdef LIBXML_XPTR_ENABLED
+#include <libxml/xpointer.h>
+#endif
+#ifdef LIBXML_DEBUG_ENABLED
+#include <libxml/debugXML.h>
+#endif
+#include <libxml/xmlerror.h>
+#include <libxml/threads.h>
+#include <libxml/globals.h>
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
+
+#ifdef LIBXML_PATTERN_ENABLED
+#define XPATH_STREAMING
+#endif
+
+#define TODO								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+/*
+* XP_OPTIMIZED_NON_ELEM_COMPARISON:
+* If defined, this will use xmlXPathCmpNodesExt() instead of
+* xmlXPathCmpNodes(). The new function is optimized comparison of
+* non-element nodes; actually it will speed up comparison only if
+* xmlXPathOrderDocElems() was called in order to index the elements of
+* a tree in document order; Libxslt does such an indexing, thus it will
+* benefit from this optimization.
+*/
+#define XP_OPTIMIZED_NON_ELEM_COMPARISON
+
+/*
+* XP_OPTIMIZED_FILTER_FIRST:
+* If defined, this will optimize expressions like "key('foo', 'val')[b][1]"
+* in a way, that it stop evaluation at the first node.
+*/
+#define XP_OPTIMIZED_FILTER_FIRST
+
+/*
+* XP_DEBUG_OBJ_USAGE:
+* Internal flag to enable tracking of how much XPath objects have been
+* created.
+*/
+/* #define XP_DEBUG_OBJ_USAGE */
+
+/*
+ * TODO:
+ * There are a few spots where some tests are done which depend upon ascii
+ * data.  These should be enhanced for full UTF8 support (see particularly
+ * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
+ */
+
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+
+/************************************************************************
+ *									*
+ *			Floating point stuff				*
+ *									*
+ ************************************************************************/
+
+#ifndef TRIO_REPLACE_STDIO
+#define TRIO_PUBLIC static
+#endif
+#include "trionan.c"
+
+/*
+ * The lack of portability of this section of the libc is annoying !
+ */
+double xmlXPathNAN = 0;
+double xmlXPathPINF = 1;
+double xmlXPathNINF = -1;
+static double xmlXPathNZERO = 0; /* not exported from headers */
+static int xmlXPathInitialized = 0;
+
+/**
+ * xmlXPathInit:
+ *
+ * Initialize the XPath environment
+ */
+void
+xmlXPathInit(void) {
+    if (xmlXPathInitialized) return;
+
+    xmlXPathPINF = trio_pinf();
+    xmlXPathNINF = trio_ninf();
+    xmlXPathNAN = trio_nan();
+    xmlXPathNZERO = trio_nzero();
+
+    xmlXPathInitialized = 1;
+}
+
+/**
+ * xmlXPathIsNaN:
+ * @val:  a double value
+ *
+ * Provides a portable isnan() function to detect whether a double
+ * is a NotaNumber. Based on trio code
+ * http://sourceforge.net/projects/ctrio/
+ *
+ * Returns 1 if the value is a NaN, 0 otherwise
+ */
+int
+xmlXPathIsNaN(double val) {
+    return(trio_isnan(val));
+}
+
+/**
+ * xmlXPathIsInf:
+ * @val:  a double value
+ *
+ * Provides a portable isinf() function to detect whether a double
+ * is a +Infinite or -Infinite. Based on trio code
+ * http://sourceforge.net/projects/ctrio/
+ *
+ * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise
+ */
+int
+xmlXPathIsInf(double val) {
+    return(trio_isinf(val));
+}
+
+#endif /* SCHEMAS or XPATH */
+#ifdef LIBXML_XPATH_ENABLED
+/**
+ * xmlXPathGetSign:
+ * @val:  a double value
+ *
+ * Provides a portable function to detect the sign of a double
+ * Modified from trio code
+ * http://sourceforge.net/projects/ctrio/
+ *
+ * Returns 1 if the value is Negative, 0 if positive
+ */
+static int
+xmlXPathGetSign(double val) {
+    return(trio_signbit(val));
+}
+
+
+/*
+ * TODO: when compatibility allows remove all "fake node libxslt" strings
+ *       the test should just be name[0] = ' '
+ */
+#ifdef DEBUG_XPATH_EXPRESSION
+#define DEBUG_STEP
+#define DEBUG_EXPR
+#define DEBUG_EVAL_COUNTS
+#endif
+
+static xmlNs xmlXPathXMLNamespaceStruct = {
+    NULL,
+    XML_NAMESPACE_DECL,
+    XML_XML_NAMESPACE,
+    BAD_CAST "xml",
+    NULL,
+    NULL
+};
+static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
+#ifndef LIBXML_THREAD_ENABLED
+/*
+ * Optimizer is disabled only when threaded apps are detected while
+ * the library ain't compiled for thread safety.
+ */
+static int xmlXPathDisableOptimizer = 0;
+#endif
+
+/************************************************************************
+ *									*
+ *			Error handling routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * XP_ERRORNULL:
+ * @X:  the error code
+ *
+ * Macro to raise an XPath error and return NULL.
+ */
+#define XP_ERRORNULL(X)							\
+    { xmlXPathErr(ctxt, X); return(NULL); }
+
+/*
+ * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
+ */
+static const char *xmlXPathErrorMessages[] = {
+    "Ok\n",
+    "Number encoding\n",
+    "Unfinished literal\n",
+    "Start of literal\n",
+    "Expected $ for variable reference\n",
+    "Undefined variable\n",
+    "Invalid predicate\n",
+    "Invalid expression\n",
+    "Missing closing curly brace\n",
+    "Unregistered function\n",
+    "Invalid operand\n",
+    "Invalid type\n",
+    "Invalid number of arguments\n",
+    "Invalid context size\n",
+    "Invalid context position\n",
+    "Memory allocation error\n",
+    "Syntax error\n",
+    "Resource error\n",
+    "Sub resource error\n",
+    "Undefined namespace prefix\n",
+    "Encoding error\n",
+    "Char out of XML range\n",
+    "Invalid or incomplete context\n",
+    "?? Unknown error ??\n"	/* Must be last in the list! */
+};
+#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
+		   sizeof(xmlXPathErrorMessages[0])) - 1)
+/**
+ * xmlXPathErrMemory:
+ * @ctxt:  an XPath context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
+{
+    if (ctxt != NULL) {
+        if (extra) {
+            xmlChar buf[200];
+
+            xmlStrPrintf(buf, 200,
+                         BAD_CAST "Memory allocation failed : %s\n",
+                         extra);
+            ctxt->lastError.message = (char *) xmlStrdup(buf);
+        } else {
+            ctxt->lastError.message = (char *)
+	       xmlStrdup(BAD_CAST "Memory allocation failed\n");
+        }
+        ctxt->lastError.domain = XML_FROM_XPATH;
+        ctxt->lastError.code = XML_ERR_NO_MEMORY;
+	if (ctxt->error != NULL)
+	    ctxt->error(ctxt->userData, &ctxt->lastError);
+    } else {
+        if (extra)
+            __xmlRaiseError(NULL, NULL, NULL,
+                            NULL, NULL, XML_FROM_XPATH,
+                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+                            extra, NULL, NULL, 0, 0,
+                            "Memory allocation failed : %s\n", extra);
+        else
+            __xmlRaiseError(NULL, NULL, NULL,
+                            NULL, NULL, XML_FROM_XPATH,
+                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+                            NULL, NULL, NULL, 0, 0,
+                            "Memory allocation failed\n");
+    }
+}
+
+/**
+ * xmlXPathPErrMemory:
+ * @ctxt:  an XPath parser context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra)
+{
+    if (ctxt == NULL)
+	xmlXPathErrMemory(NULL, extra);
+    else {
+	ctxt->error = XPATH_MEMORY_ERROR;
+	xmlXPathErrMemory(ctxt->context, extra);
+    }
+}
+
+/**
+ * xmlXPathErr:
+ * @ctxt:  a XPath parser context
+ * @error:  the error code
+ *
+ * Handle an XPath error
+ */
+void
+xmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
+{
+    if ((error < 0) || (error > MAXERRNO))
+	error = MAXERRNO;
+    if (ctxt == NULL) {
+	__xmlRaiseError(NULL, NULL, NULL,
+			NULL, NULL, XML_FROM_XPATH,
+			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
+			XML_ERR_ERROR, NULL, 0,
+			NULL, NULL, NULL, 0, 0,
+			"%s", xmlXPathErrorMessages[error]);
+	return;
+    }
+    ctxt->error = error;
+    if (ctxt->context == NULL) {
+	__xmlRaiseError(NULL, NULL, NULL,
+			NULL, NULL, XML_FROM_XPATH,
+			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
+			XML_ERR_ERROR, NULL, 0,
+			(const char *) ctxt->base, NULL, NULL,
+			ctxt->cur - ctxt->base, 0,
+			"%s", xmlXPathErrorMessages[error]);
+	return;
+    }
+
+    /* cleanup current last error */
+    xmlResetError(&ctxt->context->lastError);
+
+    ctxt->context->lastError.domain = XML_FROM_XPATH;
+    ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
+                           XPATH_EXPRESSION_OK;
+    ctxt->context->lastError.level = XML_ERR_ERROR;
+    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
+    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
+    ctxt->context->lastError.node = ctxt->context->debugNode;
+    if (ctxt->context->error != NULL) {
+	ctxt->context->error(ctxt->context->userData,
+	                     &ctxt->context->lastError);
+    } else {
+	__xmlRaiseError(NULL, NULL, NULL,
+			NULL, ctxt->context->debugNode, XML_FROM_XPATH,
+			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
+			XML_ERR_ERROR, NULL, 0,
+			(const char *) ctxt->base, NULL, NULL,
+			ctxt->cur - ctxt->base, 0,
+			"%s", xmlXPathErrorMessages[error]);
+    }
+
+}
+
+/**
+ * xmlXPatherror:
+ * @ctxt:  the XPath Parser context
+ * @file:  the file name
+ * @line:  the line number
+ * @no:  the error number
+ *
+ * Formats an error message.
+ */
+void
+xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
+              int line ATTRIBUTE_UNUSED, int no) {
+    xmlXPathErr(ctxt, no);
+}
+
+/************************************************************************
+ *									*
+ *			Utilities					*
+ *									*
+ ************************************************************************/
+
+/**
+ * xsltPointerList:
+ *
+ * Pointer-list for various purposes.
+ */
+typedef struct _xmlPointerList xmlPointerList;
+typedef xmlPointerList *xmlPointerListPtr;
+struct _xmlPointerList {
+    void **items;
+    int number;
+    int size;
+};
+/*
+* TODO: Since such a list-handling is used in xmlschemas.c and libxslt
+* and here, we should make the functions public.
+*/
+static int
+xmlPointerListAddSize(xmlPointerListPtr list,
+		       void *item,
+		       int initialSize)
+{
+    if (list->items == NULL) {
+	if (initialSize <= 0)
+	    initialSize = 1;
+	list->items = (void **) xmlMalloc(
+	    initialSize * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlXPathErrMemory(NULL,
+		"xmlPointerListCreate: allocating item\n");
+	    return(-1);
+	}
+	list->number = 0;
+	list->size = initialSize;
+    } else if (list->size <= list->number) {
+	list->size *= 2;
+	list->items = (void **) xmlRealloc(list->items,
+	    list->size * sizeof(void *));
+	if (list->items == NULL) {
+	    xmlXPathErrMemory(NULL,
+		"xmlPointerListCreate: re-allocating item\n");
+	    list->size = 0;
+	    return(-1);
+	}
+    }
+    list->items[list->number++] = item;
+    return(0);
+}
+
+/**
+ * xsltPointerListCreate:
+ *
+ * Creates an xsltPointerList structure.
+ *
+ * Returns a xsltPointerList structure or NULL in case of an error.
+ */
+static xmlPointerListPtr
+xmlPointerListCreate(int initialSize)
+{
+    xmlPointerListPtr ret;
+
+    ret = xmlMalloc(sizeof(xmlPointerList));
+    if (ret == NULL) {
+	xmlXPathErrMemory(NULL,
+	    "xmlPointerListCreate: allocating item\n");
+	return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlPointerList));
+    if (initialSize > 0) {
+	xmlPointerListAddSize(ret, NULL, initialSize);
+	ret->number = 0;
+    }
+    return (ret);
+}
+
+/**
+ * xsltPointerListFree:
+ *
+ * Frees the xsltPointerList structure. This does not free
+ * the content of the list.
+ */
+static void
+xmlPointerListFree(xmlPointerListPtr list)
+{
+    if (list == NULL)
+	return;
+    if (list->items != NULL)
+	xmlFree(list->items);
+    xmlFree(list);
+}
+
+/************************************************************************
+ *									*
+ *			Parser Types					*
+ *									*
+ ************************************************************************/
+
+/*
+ * Types are private:
+ */
+
+typedef enum {
+    XPATH_OP_END=0,
+    XPATH_OP_AND,
+    XPATH_OP_OR,
+    XPATH_OP_EQUAL,
+    XPATH_OP_CMP,
+    XPATH_OP_PLUS,
+    XPATH_OP_MULT,
+    XPATH_OP_UNION,
+    XPATH_OP_ROOT,
+    XPATH_OP_NODE,
+    XPATH_OP_RESET, /* 10 */
+    XPATH_OP_COLLECT,
+    XPATH_OP_VALUE, /* 12 */
+    XPATH_OP_VARIABLE,
+    XPATH_OP_FUNCTION,
+    XPATH_OP_ARG,
+    XPATH_OP_PREDICATE,
+    XPATH_OP_FILTER, /* 17 */
+    XPATH_OP_SORT /* 18 */
+#ifdef LIBXML_XPTR_ENABLED
+    ,XPATH_OP_RANGETO
+#endif
+} xmlXPathOp;
+
+typedef enum {
+    AXIS_ANCESTOR = 1,
+    AXIS_ANCESTOR_OR_SELF,
+    AXIS_ATTRIBUTE,
+    AXIS_CHILD,
+    AXIS_DESCENDANT,
+    AXIS_DESCENDANT_OR_SELF,
+    AXIS_FOLLOWING,
+    AXIS_FOLLOWING_SIBLING,
+    AXIS_NAMESPACE,
+    AXIS_PARENT,
+    AXIS_PRECEDING,
+    AXIS_PRECEDING_SIBLING,
+    AXIS_SELF
+} xmlXPathAxisVal;
+
+typedef enum {
+    NODE_TEST_NONE = 0,
+    NODE_TEST_TYPE = 1,
+    NODE_TEST_PI = 2,
+    NODE_TEST_ALL = 3,
+    NODE_TEST_NS = 4,
+    NODE_TEST_NAME = 5
+} xmlXPathTestVal;
+
+typedef enum {
+    NODE_TYPE_NODE = 0,
+    NODE_TYPE_COMMENT = XML_COMMENT_NODE,
+    NODE_TYPE_TEXT = XML_TEXT_NODE,
+    NODE_TYPE_PI = XML_PI_NODE
+} xmlXPathTypeVal;
+
+#define XP_REWRITE_DOS_CHILD_ELEM 1
+
+typedef struct _xmlXPathStepOp xmlXPathStepOp;
+typedef xmlXPathStepOp *xmlXPathStepOpPtr;
+struct _xmlXPathStepOp {
+    xmlXPathOp op;		/* The identifier of the operation */
+    int ch1;			/* First child */
+    int ch2;			/* Second child */
+    int value;
+    int value2;
+    int value3;
+    void *value4;
+    void *value5;
+    void *cache;
+    void *cacheURI;
+    int rewriteType;
+};
+
+struct _xmlXPathCompExpr {
+    int nbStep;			/* Number of steps in this expression */
+    int maxStep;		/* Maximum number of steps allocated */
+    xmlXPathStepOp *steps;	/* ops for computation of this expression */
+    int last;			/* index of last step in expression */
+    xmlChar *expr;		/* the expression being computed */
+    xmlDictPtr dict;		/* the dictionnary to use if any */
+#ifdef DEBUG_EVAL_COUNTS
+    int nb;
+    xmlChar *string;
+#endif
+#ifdef XPATH_STREAMING
+    xmlPatternPtr stream;
+#endif
+};
+
+/************************************************************************
+ *									*
+ *			Forward declarations				*
+ *									*
+ ************************************************************************/
+static void
+xmlXPathFreeValueTree(xmlNodeSetPtr obj);
+static void
+xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj);
+static int
+xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
+                        xmlXPathStepOpPtr op, xmlNodePtr *first);
+static int
+xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
+			    xmlXPathStepOpPtr op,
+			    int isPredicate);
+
+/************************************************************************
+ *									*
+ *			Parser Type functions				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathNewCompExpr:
+ *
+ * Create a new Xpath component
+ *
+ * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
+ */
+static xmlXPathCompExprPtr
+xmlXPathNewCompExpr(void) {
+    xmlXPathCompExprPtr cur;
+
+    cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
+    if (cur == NULL) {
+        xmlXPathErrMemory(NULL, "allocating component\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlXPathCompExpr));
+    cur->maxStep = 10;
+    cur->nbStep = 0;
+    cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
+	                                   sizeof(xmlXPathStepOp));
+    if (cur->steps == NULL) {
+        xmlXPathErrMemory(NULL, "allocating steps\n");
+	xmlFree(cur);
+	return(NULL);
+    }
+    memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
+    cur->last = -1;
+#ifdef DEBUG_EVAL_COUNTS
+    cur->nb = 0;
+#endif
+    return(cur);
+}
+
+/**
+ * xmlXPathFreeCompExpr:
+ * @comp:  an XPATH comp
+ *
+ * Free up the memory allocated by @comp
+ */
+void
+xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
+{
+    xmlXPathStepOpPtr op;
+    int i;
+
+    if (comp == NULL)
+        return;
+    if (comp->dict == NULL) {
+	for (i = 0; i < comp->nbStep; i++) {
+	    op = &comp->steps[i];
+	    if (op->value4 != NULL) {
+		if (op->op == XPATH_OP_VALUE)
+		    xmlXPathFreeObject(op->value4);
+		else
+		    xmlFree(op->value4);
+	    }
+	    if (op->value5 != NULL)
+		xmlFree(op->value5);
+	}
+    } else {
+	for (i = 0; i < comp->nbStep; i++) {
+	    op = &comp->steps[i];
+	    if (op->value4 != NULL) {
+		if (op->op == XPATH_OP_VALUE)
+		    xmlXPathFreeObject(op->value4);
+	    }
+	}
+        xmlDictFree(comp->dict);
+    }
+    if (comp->steps != NULL) {
+        xmlFree(comp->steps);
+    }
+#ifdef DEBUG_EVAL_COUNTS
+    if (comp->string != NULL) {
+        xmlFree(comp->string);
+    }
+#endif
+#ifdef XPATH_STREAMING
+    if (comp->stream != NULL) {
+        xmlFreePatternList(comp->stream);
+    }
+#endif
+    if (comp->expr != NULL) {
+        xmlFree(comp->expr);
+    }
+
+    xmlFree(comp);
+}
+
+/**
+ * xmlXPathCompExprAdd:
+ * @comp:  the compiled expression
+ * @ch1: first child index
+ * @ch2: second child index
+ * @op:  an op
+ * @value:  the first int value
+ * @value2:  the second int value
+ * @value3:  the third int value
+ * @value4:  the first string value
+ * @value5:  the second string value
+ *
+ * Add a step to an XPath Compiled Expression
+ *
+ * Returns -1 in case of failure, the index otherwise
+ */
+static int
+xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
+   xmlXPathOp op, int value,
+   int value2, int value3, void *value4, void *value5) {
+    if (comp->nbStep >= comp->maxStep) {
+	xmlXPathStepOp *real;
+
+	comp->maxStep *= 2;
+	real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
+		                      comp->maxStep * sizeof(xmlXPathStepOp));
+	if (real == NULL) {
+	    comp->maxStep /= 2;
+	    xmlXPathErrMemory(NULL, "adding step\n");
+	    return(-1);
+	}
+	comp->steps = real;
+    }
+    comp->last = comp->nbStep;
+    comp->steps[comp->nbStep].rewriteType = 0;
+    comp->steps[comp->nbStep].ch1 = ch1;
+    comp->steps[comp->nbStep].ch2 = ch2;
+    comp->steps[comp->nbStep].op = op;
+    comp->steps[comp->nbStep].value = value;
+    comp->steps[comp->nbStep].value2 = value2;
+    comp->steps[comp->nbStep].value3 = value3;
+    if ((comp->dict != NULL) &&
+        ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) ||
+	 (op == XPATH_OP_COLLECT))) {
+        if (value4 != NULL) {
+	    comp->steps[comp->nbStep].value4 = (xmlChar *)
+	        (void *)xmlDictLookup(comp->dict, value4, -1);
+	    xmlFree(value4);
+	} else
+	    comp->steps[comp->nbStep].value4 = NULL;
+        if (value5 != NULL) {
+	    comp->steps[comp->nbStep].value5 = (xmlChar *)
+	        (void *)xmlDictLookup(comp->dict, value5, -1);
+	    xmlFree(value5);
+	} else
+	    comp->steps[comp->nbStep].value5 = NULL;
+    } else {
+	comp->steps[comp->nbStep].value4 = value4;
+	comp->steps[comp->nbStep].value5 = value5;
+    }
+    comp->steps[comp->nbStep].cache = NULL;
+    return(comp->nbStep++);
+}
+
+/**
+ * xmlXPathCompSwap:
+ * @comp:  the compiled expression
+ * @op: operation index
+ *
+ * Swaps 2 operations in the compiled expression
+ */
+static void
+xmlXPathCompSwap(xmlXPathStepOpPtr op) {
+    int tmp;
+
+#ifndef LIBXML_THREAD_ENABLED
+    /*
+     * Since this manipulates possibly shared variables, this is
+     * disabled if one detects that the library is used in a multithreaded
+     * application
+     */
+    if (xmlXPathDisableOptimizer)
+	return;
+#endif
+
+    tmp = op->ch1;
+    op->ch1 = op->ch2;
+    op->ch2 = tmp;
+}
+
+#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5)	\
+    xmlXPathCompExprAdd(ctxt->comp, (op1), (op2),			\
+	                (op), (val), (val2), (val3), (val4), (val5))
+#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5)			\
+    xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1,		\
+	                (op), (val), (val2), (val3), (val4), (val5))
+
+#define PUSH_LEAVE_EXPR(op, val, val2)					\
+xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
+
+#define PUSH_UNARY_EXPR(op, ch, val, val2)				\
+xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
+
+#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2)			\
+xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op),			\
+			(val), (val2), 0 ,NULL ,NULL)
+
+/************************************************************************
+ *									*
+ *		XPath object cache structures				*
+ *									*
+ ************************************************************************/
+
+/* #define XP_DEFAULT_CACHE_ON */
+
+#define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL))
+
+typedef struct _xmlXPathContextCache xmlXPathContextCache;
+typedef xmlXPathContextCache *xmlXPathContextCachePtr;
+struct _xmlXPathContextCache {
+    xmlPointerListPtr nodesetObjs;  /* contains xmlXPathObjectPtr */
+    xmlPointerListPtr stringObjs;   /* contains xmlXPathObjectPtr */
+    xmlPointerListPtr booleanObjs;  /* contains xmlXPathObjectPtr */
+    xmlPointerListPtr numberObjs;   /* contains xmlXPathObjectPtr */
+    xmlPointerListPtr miscObjs;     /* contains xmlXPathObjectPtr */
+    int maxNodeset;
+    int maxString;
+    int maxBoolean;
+    int maxNumber;
+    int maxMisc;
+#ifdef XP_DEBUG_OBJ_USAGE
+    int dbgCachedAll;
+    int dbgCachedNodeset;
+    int dbgCachedString;
+    int dbgCachedBool;
+    int dbgCachedNumber;
+    int dbgCachedPoint;
+    int dbgCachedRange;
+    int dbgCachedLocset;
+    int dbgCachedUsers;
+    int dbgCachedXSLTTree;
+    int dbgCachedUndefined;
+
+
+    int dbgReusedAll;
+    int dbgReusedNodeset;
+    int dbgReusedString;
+    int dbgReusedBool;
+    int dbgReusedNumber;
+    int dbgReusedPoint;
+    int dbgReusedRange;
+    int dbgReusedLocset;
+    int dbgReusedUsers;
+    int dbgReusedXSLTTree;
+    int dbgReusedUndefined;
+
+#endif
+};
+
+/************************************************************************
+ *									*
+ *		Debugging related functions				*
+ *									*
+ ************************************************************************/
+
+#define STRANGE							\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Internal error at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#ifdef LIBXML_DEBUG_ENABLED
+static void
+xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+    if (cur == NULL) {
+	fprintf(output, "%s", shift);
+	fprintf(output, "Node is NULL !\n");
+	return;
+
+    }
+
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+	     (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	fprintf(output, "%s", shift);
+	fprintf(output, " /\n");
+    } else if (cur->type == XML_ATTRIBUTE_NODE)
+	xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
+    else
+	xmlDebugDumpOneNode(output, cur, depth);
+}
+static void
+xmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
+    xmlNodePtr tmp;
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+    if (cur == NULL) {
+	fprintf(output, "%s", shift);
+	fprintf(output, "Node is NULL !\n");
+	return;
+
+    }
+
+    while (cur != NULL) {
+	tmp = cur;
+	cur = cur->next;
+	xmlDebugDumpOneNode(output, tmp, depth);
+    }
+}
+
+static void
+xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+    if (cur == NULL) {
+	fprintf(output, "%s", shift);
+	fprintf(output, "NodeSet is NULL !\n");
+	return;
+
+    }
+
+    if (cur != NULL) {
+	fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
+	for (i = 0;i < cur->nodeNr;i++) {
+	    fprintf(output, "%s", shift);
+	    fprintf(output, "%d", i + 1);
+	    xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
+	}
+    }
+}
+
+static void
+xmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+    if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
+	fprintf(output, "%s", shift);
+	fprintf(output, "Value Tree is NULL !\n");
+	return;
+
+    }
+
+    fprintf(output, "%s", shift);
+    fprintf(output, "%d", i + 1);
+    xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
+}
+#if defined(LIBXML_XPTR_ENABLED)
+static void
+xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+    if (cur == NULL) {
+	fprintf(output, "%s", shift);
+	fprintf(output, "LocationSet is NULL !\n");
+	return;
+
+    }
+
+    for (i = 0;i < cur->locNr;i++) {
+	fprintf(output, "%s", shift);
+        fprintf(output, "%d : ", i + 1);
+	xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
+    }
+}
+#endif /* LIBXML_XPTR_ENABLED */
+
+/**
+ * xmlXPathDebugDumpObject:
+ * @output:  the FILE * to dump the output
+ * @cur:  the object to inspect
+ * @depth:  indentation level
+ *
+ * Dump the content of the object for debugging purposes
+ */
+void
+xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
+    int i;
+    char shift[100];
+
+    if (output == NULL) return;
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+
+    fprintf(output, "%s", shift);
+
+    if (cur == NULL) {
+        fprintf(output, "Object is empty (NULL)\n");
+	return;
+    }
+    switch(cur->type) {
+        case XPATH_UNDEFINED:
+	    fprintf(output, "Object is uninitialized\n");
+	    break;
+        case XPATH_NODESET:
+	    fprintf(output, "Object is a Node Set :\n");
+	    xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
+	    break;
+	case XPATH_XSLT_TREE:
+	    fprintf(output, "Object is an XSLT value tree :\n");
+	    xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth);
+	    break;
+        case XPATH_BOOLEAN:
+	    fprintf(output, "Object is a Boolean : ");
+	    if (cur->boolval) fprintf(output, "true\n");
+	    else fprintf(output, "false\n");
+	    break;
+        case XPATH_NUMBER:
+	    switch (xmlXPathIsInf(cur->floatval)) {
+	    case 1:
+		fprintf(output, "Object is a number : Infinity\n");
+		break;
+	    case -1:
+		fprintf(output, "Object is a number : -Infinity\n");
+		break;
+	    default:
+		if (xmlXPathIsNaN(cur->floatval)) {
+		    fprintf(output, "Object is a number : NaN\n");
+		} else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) {
+		    fprintf(output, "Object is a number : 0\n");
+		} else {
+		    fprintf(output, "Object is a number : %0g\n", cur->floatval);
+		}
+	    }
+	    break;
+        case XPATH_STRING:
+	    fprintf(output, "Object is a string : ");
+	    xmlDebugDumpString(output, cur->stringval);
+	    fprintf(output, "\n");
+	    break;
+	case XPATH_POINT:
+	    fprintf(output, "Object is a point : index %d in node", cur->index);
+	    xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
+	    fprintf(output, "\n");
+	    break;
+	case XPATH_RANGE:
+	    if ((cur->user2 == NULL) ||
+		((cur->user2 == cur->user) && (cur->index == cur->index2))) {
+		fprintf(output, "Object is a collapsed range :\n");
+		fprintf(output, "%s", shift);
+		if (cur->index >= 0)
+		    fprintf(output, "index %d in ", cur->index);
+		fprintf(output, "node\n");
+		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
+			              depth + 1);
+	    } else  {
+		fprintf(output, "Object is a range :\n");
+		fprintf(output, "%s", shift);
+		fprintf(output, "From ");
+		if (cur->index >= 0)
+		    fprintf(output, "index %d in ", cur->index);
+		fprintf(output, "node\n");
+		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
+			              depth + 1);
+		fprintf(output, "%s", shift);
+		fprintf(output, "To ");
+		if (cur->index2 >= 0)
+		    fprintf(output, "index %d in ", cur->index2);
+		fprintf(output, "node\n");
+		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
+			              depth + 1);
+		fprintf(output, "\n");
+	    }
+	    break;
+	case XPATH_LOCATIONSET:
+#if defined(LIBXML_XPTR_ENABLED)
+	    fprintf(output, "Object is a Location Set:\n");
+	    xmlXPathDebugDumpLocationSet(output,
+		    (xmlLocationSetPtr) cur->user, depth);
+#endif
+	    break;
+	case XPATH_USERS:
+	    fprintf(output, "Object is user defined\n");
+	    break;
+    }
+}
+
+static void
+xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
+	                     xmlXPathStepOpPtr op, int depth) {
+    int i;
+    char shift[100];
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+    fprintf(output, "%s", shift);
+    if (op == NULL) {
+	fprintf(output, "Step is NULL\n");
+	return;
+    }
+    switch (op->op) {
+        case XPATH_OP_END:
+	    fprintf(output, "END"); break;
+        case XPATH_OP_AND:
+	    fprintf(output, "AND"); break;
+        case XPATH_OP_OR:
+	    fprintf(output, "OR"); break;
+        case XPATH_OP_EQUAL:
+	     if (op->value)
+		 fprintf(output, "EQUAL =");
+	     else
+		 fprintf(output, "EQUAL !=");
+	     break;
+        case XPATH_OP_CMP:
+	     if (op->value)
+		 fprintf(output, "CMP <");
+	     else
+		 fprintf(output, "CMP >");
+	     if (!op->value2)
+		 fprintf(output, "=");
+	     break;
+        case XPATH_OP_PLUS:
+	     if (op->value == 0)
+		 fprintf(output, "PLUS -");
+	     else if (op->value == 1)
+		 fprintf(output, "PLUS +");
+	     else if (op->value == 2)
+		 fprintf(output, "PLUS unary -");
+	     else if (op->value == 3)
+		 fprintf(output, "PLUS unary - -");
+	     break;
+        case XPATH_OP_MULT:
+	     if (op->value == 0)
+		 fprintf(output, "MULT *");
+	     else if (op->value == 1)
+		 fprintf(output, "MULT div");
+	     else
+		 fprintf(output, "MULT mod");
+	     break;
+        case XPATH_OP_UNION:
+	     fprintf(output, "UNION"); break;
+        case XPATH_OP_ROOT:
+	     fprintf(output, "ROOT"); break;
+        case XPATH_OP_NODE:
+	     fprintf(output, "NODE"); break;
+        case XPATH_OP_RESET:
+	     fprintf(output, "RESET"); break;
+        case XPATH_OP_SORT:
+	     fprintf(output, "SORT"); break;
+        case XPATH_OP_COLLECT: {
+	    xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value;
+	    xmlXPathTestVal test = (xmlXPathTestVal)op->value2;
+	    xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3;
+	    const xmlChar *prefix = op->value4;
+	    const xmlChar *name = op->value5;
+
+	    fprintf(output, "COLLECT ");
+	    switch (axis) {
+		case AXIS_ANCESTOR:
+		    fprintf(output, " 'ancestors' "); break;
+		case AXIS_ANCESTOR_OR_SELF:
+		    fprintf(output, " 'ancestors-or-self' "); break;
+		case AXIS_ATTRIBUTE:
+		    fprintf(output, " 'attributes' "); break;
+		case AXIS_CHILD:
+		    fprintf(output, " 'child' "); break;
+		case AXIS_DESCENDANT:
+		    fprintf(output, " 'descendant' "); break;
+		case AXIS_DESCENDANT_OR_SELF:
+		    fprintf(output, " 'descendant-or-self' "); break;
+		case AXIS_FOLLOWING:
+		    fprintf(output, " 'following' "); break;
+		case AXIS_FOLLOWING_SIBLING:
+		    fprintf(output, " 'following-siblings' "); break;
+		case AXIS_NAMESPACE:
+		    fprintf(output, " 'namespace' "); break;
+		case AXIS_PARENT:
+		    fprintf(output, " 'parent' "); break;
+		case AXIS_PRECEDING:
+		    fprintf(output, " 'preceding' "); break;
+		case AXIS_PRECEDING_SIBLING:
+		    fprintf(output, " 'preceding-sibling' "); break;
+		case AXIS_SELF:
+		    fprintf(output, " 'self' "); break;
+	    }
+	    switch (test) {
+                case NODE_TEST_NONE:
+		    fprintf(output, "'none' "); break;
+                case NODE_TEST_TYPE:
+		    fprintf(output, "'type' "); break;
+                case NODE_TEST_PI:
+		    fprintf(output, "'PI' "); break;
+                case NODE_TEST_ALL:
+		    fprintf(output, "'all' "); break;
+                case NODE_TEST_NS:
+		    fprintf(output, "'namespace' "); break;
+                case NODE_TEST_NAME:
+		    fprintf(output, "'name' "); break;
+	    }
+	    switch (type) {
+                case NODE_TYPE_NODE:
+		    fprintf(output, "'node' "); break;
+                case NODE_TYPE_COMMENT:
+		    fprintf(output, "'comment' "); break;
+                case NODE_TYPE_TEXT:
+		    fprintf(output, "'text' "); break;
+                case NODE_TYPE_PI:
+		    fprintf(output, "'PI' "); break;
+	    }
+	    if (prefix != NULL)
+		fprintf(output, "%s:", prefix);
+	    if (name != NULL)
+		fprintf(output, "%s", (const char *) name);
+	    break;
+
+        }
+	case XPATH_OP_VALUE: {
+	    xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;
+
+	    fprintf(output, "ELEM ");
+	    xmlXPathDebugDumpObject(output, object, 0);
+	    goto finish;
+	}
+	case XPATH_OP_VARIABLE: {
+	    const xmlChar *prefix = op->value5;
+	    const xmlChar *name = op->value4;
+
+	    if (prefix != NULL)
+		fprintf(output, "VARIABLE %s:%s", prefix, name);
+	    else
+		fprintf(output, "VARIABLE %s", name);
+	    break;
+	}
+	case XPATH_OP_FUNCTION: {
+	    int nbargs = op->value;
+	    const xmlChar *prefix = op->value5;
+	    const xmlChar *name = op->value4;
+
+	    if (prefix != NULL)
+		fprintf(output, "FUNCTION %s:%s(%d args)",
+			prefix, name, nbargs);
+	    else
+		fprintf(output, "FUNCTION %s(%d args)", name, nbargs);
+	    break;
+	}
+        case XPATH_OP_ARG: fprintf(output, "ARG"); break;
+        case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
+        case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
+#ifdef LIBXML_XPTR_ENABLED
+        case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;
+#endif
+	default:
+        fprintf(output, "UNKNOWN %d\n", op->op); return;
+    }
+    fprintf(output, "\n");
+finish:
+    if (op->ch1 >= 0)
+	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);
+    if (op->ch2 >= 0)
+	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);
+}
+
+/**
+ * xmlXPathDebugDumpCompExpr:
+ * @output:  the FILE * for the output
+ * @comp:  the precompiled XPath expression
+ * @depth:  the indentation level.
+ *
+ * Dumps the tree of the compiled XPath expression.
+ */
+void
+xmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
+	                  int depth) {
+    int i;
+    char shift[100];
+
+    if ((output == NULL) || (comp == NULL)) return;
+
+    for (i = 0;((i < depth) && (i < 25));i++)
+        shift[2 * i] = shift[2 * i + 1] = ' ';
+    shift[2 * i] = shift[2 * i + 1] = 0;
+
+    fprintf(output, "%s", shift);
+
+    fprintf(output, "Compiled Expression : %d elements\n",
+	    comp->nbStep);
+    i = comp->last;
+    xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
+}
+
+#ifdef XP_DEBUG_OBJ_USAGE
+
+/*
+* XPath object usage related debugging variables.
+*/
+static int xmlXPathDebugObjCounterUndefined = 0;
+static int xmlXPathDebugObjCounterNodeset = 0;
+static int xmlXPathDebugObjCounterBool = 0;
+static int xmlXPathDebugObjCounterNumber = 0;
+static int xmlXPathDebugObjCounterString = 0;
+static int xmlXPathDebugObjCounterPoint = 0;
+static int xmlXPathDebugObjCounterRange = 0;
+static int xmlXPathDebugObjCounterLocset = 0;
+static int xmlXPathDebugObjCounterUsers = 0;
+static int xmlXPathDebugObjCounterXSLTTree = 0;
+static int xmlXPathDebugObjCounterAll = 0;
+
+static int xmlXPathDebugObjTotalUndefined = 0;
+static int xmlXPathDebugObjTotalNodeset = 0;
+static int xmlXPathDebugObjTotalBool = 0;
+static int xmlXPathDebugObjTotalNumber = 0;
+static int xmlXPathDebugObjTotalString = 0;
+static int xmlXPathDebugObjTotalPoint = 0;
+static int xmlXPathDebugObjTotalRange = 0;
+static int xmlXPathDebugObjTotalLocset = 0;
+static int xmlXPathDebugObjTotalUsers = 0;
+static int xmlXPathDebugObjTotalXSLTTree = 0;
+static int xmlXPathDebugObjTotalAll = 0;
+
+static int xmlXPathDebugObjMaxUndefined = 0;
+static int xmlXPathDebugObjMaxNodeset = 0;
+static int xmlXPathDebugObjMaxBool = 0;
+static int xmlXPathDebugObjMaxNumber = 0;
+static int xmlXPathDebugObjMaxString = 0;
+static int xmlXPathDebugObjMaxPoint = 0;
+static int xmlXPathDebugObjMaxRange = 0;
+static int xmlXPathDebugObjMaxLocset = 0;
+static int xmlXPathDebugObjMaxUsers = 0;
+static int xmlXPathDebugObjMaxXSLTTree = 0;
+static int xmlXPathDebugObjMaxAll = 0;
+
+/* REVISIT TODO: Make this static when committing */
+static void
+xmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
+{
+    if (ctxt != NULL) {
+	if (ctxt->cache != NULL) {
+	    xmlXPathContextCachePtr cache =
+		(xmlXPathContextCachePtr) ctxt->cache;
+
+	    cache->dbgCachedAll = 0;
+	    cache->dbgCachedNodeset = 0;
+	    cache->dbgCachedString = 0;
+	    cache->dbgCachedBool = 0;
+	    cache->dbgCachedNumber = 0;
+	    cache->dbgCachedPoint = 0;
+	    cache->dbgCachedRange = 0;
+	    cache->dbgCachedLocset = 0;
+	    cache->dbgCachedUsers = 0;
+	    cache->dbgCachedXSLTTree = 0;
+	    cache->dbgCachedUndefined = 0;
+
+	    cache->dbgReusedAll = 0;
+	    cache->dbgReusedNodeset = 0;
+	    cache->dbgReusedString = 0;
+	    cache->dbgReusedBool = 0;
+	    cache->dbgReusedNumber = 0;
+	    cache->dbgReusedPoint = 0;
+	    cache->dbgReusedRange = 0;
+	    cache->dbgReusedLocset = 0;
+	    cache->dbgReusedUsers = 0;
+	    cache->dbgReusedXSLTTree = 0;
+	    cache->dbgReusedUndefined = 0;
+	}
+    }
+
+    xmlXPathDebugObjCounterUndefined = 0;
+    xmlXPathDebugObjCounterNodeset = 0;
+    xmlXPathDebugObjCounterBool = 0;
+    xmlXPathDebugObjCounterNumber = 0;
+    xmlXPathDebugObjCounterString = 0;
+    xmlXPathDebugObjCounterPoint = 0;
+    xmlXPathDebugObjCounterRange = 0;
+    xmlXPathDebugObjCounterLocset = 0;
+    xmlXPathDebugObjCounterUsers = 0;
+    xmlXPathDebugObjCounterXSLTTree = 0;
+    xmlXPathDebugObjCounterAll = 0;
+
+    xmlXPathDebugObjTotalUndefined = 0;
+    xmlXPathDebugObjTotalNodeset = 0;
+    xmlXPathDebugObjTotalBool = 0;
+    xmlXPathDebugObjTotalNumber = 0;
+    xmlXPathDebugObjTotalString = 0;
+    xmlXPathDebugObjTotalPoint = 0;
+    xmlXPathDebugObjTotalRange = 0;
+    xmlXPathDebugObjTotalLocset = 0;
+    xmlXPathDebugObjTotalUsers = 0;
+    xmlXPathDebugObjTotalXSLTTree = 0;
+    xmlXPathDebugObjTotalAll = 0;
+
+    xmlXPathDebugObjMaxUndefined = 0;
+    xmlXPathDebugObjMaxNodeset = 0;
+    xmlXPathDebugObjMaxBool = 0;
+    xmlXPathDebugObjMaxNumber = 0;
+    xmlXPathDebugObjMaxString = 0;
+    xmlXPathDebugObjMaxPoint = 0;
+    xmlXPathDebugObjMaxRange = 0;
+    xmlXPathDebugObjMaxLocset = 0;
+    xmlXPathDebugObjMaxUsers = 0;
+    xmlXPathDebugObjMaxXSLTTree = 0;
+    xmlXPathDebugObjMaxAll = 0;
+
+}
+
+static void
+xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
+			      xmlXPathObjectType objType)
+{
+    int isCached = 0;
+
+    if (ctxt != NULL) {
+	if (ctxt->cache != NULL) {
+	    xmlXPathContextCachePtr cache =
+		(xmlXPathContextCachePtr) ctxt->cache;
+
+	    isCached = 1;
+
+	    cache->dbgReusedAll++;
+	    switch (objType) {
+		case XPATH_UNDEFINED:
+		    cache->dbgReusedUndefined++;
+		    break;
+		case XPATH_NODESET:
+		    cache->dbgReusedNodeset++;
+		    break;
+		case XPATH_BOOLEAN:
+		    cache->dbgReusedBool++;
+		    break;
+		case XPATH_NUMBER:
+		    cache->dbgReusedNumber++;
+		    break;
+		case XPATH_STRING:
+		    cache->dbgReusedString++;
+		    break;
+		case XPATH_POINT:
+		    cache->dbgReusedPoint++;
+		    break;
+		case XPATH_RANGE:
+		    cache->dbgReusedRange++;
+		    break;
+		case XPATH_LOCATIONSET:
+		    cache->dbgReusedLocset++;
+		    break;
+		case XPATH_USERS:
+		    cache->dbgReusedUsers++;
+		    break;
+		case XPATH_XSLT_TREE:
+		    cache->dbgReusedXSLTTree++;
+		    break;
+		default:
+		    break;
+	    }
+	}
+    }
+
+    switch (objType) {
+	case XPATH_UNDEFINED:
+	    if (! isCached)
+		xmlXPathDebugObjTotalUndefined++;
+	    xmlXPathDebugObjCounterUndefined++;
+	    if (xmlXPathDebugObjCounterUndefined >
+		xmlXPathDebugObjMaxUndefined)
+		xmlXPathDebugObjMaxUndefined =
+		    xmlXPathDebugObjCounterUndefined;
+	    break;
+	case XPATH_NODESET:
+	    if (! isCached)
+		xmlXPathDebugObjTotalNodeset++;
+	    xmlXPathDebugObjCounterNodeset++;
+	    if (xmlXPathDebugObjCounterNodeset >
+		xmlXPathDebugObjMaxNodeset)
+		xmlXPathDebugObjMaxNodeset =
+		    xmlXPathDebugObjCounterNodeset;
+	    break;
+	case XPATH_BOOLEAN:
+	    if (! isCached)
+		xmlXPathDebugObjTotalBool++;
+	    xmlXPathDebugObjCounterBool++;
+	    if (xmlXPathDebugObjCounterBool >
+		xmlXPathDebugObjMaxBool)
+		xmlXPathDebugObjMaxBool =
+		    xmlXPathDebugObjCounterBool;
+	    break;
+	case XPATH_NUMBER:
+	    if (! isCached)
+		xmlXPathDebugObjTotalNumber++;
+	    xmlXPathDebugObjCounterNumber++;
+	    if (xmlXPathDebugObjCounterNumber >
+		xmlXPathDebugObjMaxNumber)
+		xmlXPathDebugObjMaxNumber =
+		    xmlXPathDebugObjCounterNumber;
+	    break;
+	case XPATH_STRING:
+	    if (! isCached)
+		xmlXPathDebugObjTotalString++;
+	    xmlXPathDebugObjCounterString++;
+	    if (xmlXPathDebugObjCounterString >
+		xmlXPathDebugObjMaxString)
+		xmlXPathDebugObjMaxString =
+		    xmlXPathDebugObjCounterString;
+	    break;
+	case XPATH_POINT:
+	    if (! isCached)
+		xmlXPathDebugObjTotalPoint++;
+	    xmlXPathDebugObjCounterPoint++;
+	    if (xmlXPathDebugObjCounterPoint >
+		xmlXPathDebugObjMaxPoint)
+		xmlXPathDebugObjMaxPoint =
+		    xmlXPathDebugObjCounterPoint;
+	    break;
+	case XPATH_RANGE:
+	    if (! isCached)
+		xmlXPathDebugObjTotalRange++;
+	    xmlXPathDebugObjCounterRange++;
+	    if (xmlXPathDebugObjCounterRange >
+		xmlXPathDebugObjMaxRange)
+		xmlXPathDebugObjMaxRange =
+		    xmlXPathDebugObjCounterRange;
+	    break;
+	case XPATH_LOCATIONSET:
+	    if (! isCached)
+		xmlXPathDebugObjTotalLocset++;
+	    xmlXPathDebugObjCounterLocset++;
+	    if (xmlXPathDebugObjCounterLocset >
+		xmlXPathDebugObjMaxLocset)
+		xmlXPathDebugObjMaxLocset =
+		    xmlXPathDebugObjCounterLocset;
+	    break;
+	case XPATH_USERS:
+	    if (! isCached)
+		xmlXPathDebugObjTotalUsers++;
+	    xmlXPathDebugObjCounterUsers++;
+	    if (xmlXPathDebugObjCounterUsers >
+		xmlXPathDebugObjMaxUsers)
+		xmlXPathDebugObjMaxUsers =
+		    xmlXPathDebugObjCounterUsers;
+	    break;
+	case XPATH_XSLT_TREE:
+	    if (! isCached)
+		xmlXPathDebugObjTotalXSLTTree++;
+	    xmlXPathDebugObjCounterXSLTTree++;
+	    if (xmlXPathDebugObjCounterXSLTTree >
+		xmlXPathDebugObjMaxXSLTTree)
+		xmlXPathDebugObjMaxXSLTTree =
+		    xmlXPathDebugObjCounterXSLTTree;
+	    break;
+	default:
+	    break;
+    }
+    if (! isCached)
+	xmlXPathDebugObjTotalAll++;
+    xmlXPathDebugObjCounterAll++;
+    if (xmlXPathDebugObjCounterAll >
+	xmlXPathDebugObjMaxAll)
+	xmlXPathDebugObjMaxAll =
+	    xmlXPathDebugObjCounterAll;
+}
+
+static void
+xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
+			      xmlXPathObjectType objType)
+{
+    int isCached = 0;
+
+    if (ctxt != NULL) {
+	if (ctxt->cache != NULL) {
+	    xmlXPathContextCachePtr cache =
+		(xmlXPathContextCachePtr) ctxt->cache;
+
+	    isCached = 1;
+
+	    cache->dbgCachedAll++;
+	    switch (objType) {
+		case XPATH_UNDEFINED:
+		    cache->dbgCachedUndefined++;
+		    break;
+		case XPATH_NODESET:
+		    cache->dbgCachedNodeset++;
+		    break;
+		case XPATH_BOOLEAN:
+		    cache->dbgCachedBool++;
+		    break;
+		case XPATH_NUMBER:
+		    cache->dbgCachedNumber++;
+		    break;
+		case XPATH_STRING:
+		    cache->dbgCachedString++;
+		    break;
+		case XPATH_POINT:
+		    cache->dbgCachedPoint++;
+		    break;
+		case XPATH_RANGE:
+		    cache->dbgCachedRange++;
+		    break;
+		case XPATH_LOCATIONSET:
+		    cache->dbgCachedLocset++;
+		    break;
+		case XPATH_USERS:
+		    cache->dbgCachedUsers++;
+		    break;
+		case XPATH_XSLT_TREE:
+		    cache->dbgCachedXSLTTree++;
+		    break;
+		default:
+		    break;
+	    }
+
+	}
+    }
+    switch (objType) {
+	case XPATH_UNDEFINED:
+	    xmlXPathDebugObjCounterUndefined--;
+	    break;
+	case XPATH_NODESET:
+	    xmlXPathDebugObjCounterNodeset--;
+	    break;
+	case XPATH_BOOLEAN:
+	    xmlXPathDebugObjCounterBool--;
+	    break;
+	case XPATH_NUMBER:
+	    xmlXPathDebugObjCounterNumber--;
+	    break;
+	case XPATH_STRING:
+	    xmlXPathDebugObjCounterString--;
+	    break;
+	case XPATH_POINT:
+	    xmlXPathDebugObjCounterPoint--;
+	    break;
+	case XPATH_RANGE:
+	    xmlXPathDebugObjCounterRange--;
+	    break;
+	case XPATH_LOCATIONSET:
+	    xmlXPathDebugObjCounterLocset--;
+	    break;
+	case XPATH_USERS:
+	    xmlXPathDebugObjCounterUsers--;
+	    break;
+	case XPATH_XSLT_TREE:
+	    xmlXPathDebugObjCounterXSLTTree--;
+	    break;
+	default:
+	    break;
+    }
+    xmlXPathDebugObjCounterAll--;
+}
+
+/* REVISIT TODO: Make this static when committing */
+static void
+xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
+{
+    int reqAll, reqNodeset, reqString, reqBool, reqNumber,
+	reqXSLTTree, reqUndefined;
+    int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
+	caNumber = 0, caXSLTTree = 0, caUndefined = 0;
+    int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
+	reNumber = 0, reXSLTTree = 0, reUndefined = 0;
+    int leftObjs = xmlXPathDebugObjCounterAll;
+
+    reqAll = xmlXPathDebugObjTotalAll;
+    reqNodeset = xmlXPathDebugObjTotalNodeset;
+    reqString = xmlXPathDebugObjTotalString;
+    reqBool = xmlXPathDebugObjTotalBool;
+    reqNumber = xmlXPathDebugObjTotalNumber;
+    reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
+    reqUndefined = xmlXPathDebugObjTotalUndefined;
+
+    printf("# XPath object usage:\n");
+
+    if (ctxt != NULL) {
+	if (ctxt->cache != NULL) {
+	    xmlXPathContextCachePtr cache =
+		(xmlXPathContextCachePtr) ctxt->cache;
+
+	    reAll = cache->dbgReusedAll;
+	    reqAll += reAll;
+	    reNodeset = cache->dbgReusedNodeset;
+	    reqNodeset += reNodeset;
+	    reString = cache->dbgReusedString;
+	    reqString += reString;
+	    reBool = cache->dbgReusedBool;
+	    reqBool += reBool;
+	    reNumber = cache->dbgReusedNumber;
+	    reqNumber += reNumber;
+	    reXSLTTree = cache->dbgReusedXSLTTree;
+	    reqXSLTTree += reXSLTTree;
+	    reUndefined = cache->dbgReusedUndefined;
+	    reqUndefined += reUndefined;
+
+	    caAll = cache->dbgCachedAll;
+	    caBool = cache->dbgCachedBool;
+	    caNodeset = cache->dbgCachedNodeset;
+	    caString = cache->dbgCachedString;
+	    caNumber = cache->dbgCachedNumber;
+	    caXSLTTree = cache->dbgCachedXSLTTree;
+	    caUndefined = cache->dbgCachedUndefined;
+
+	    if (cache->nodesetObjs)
+		leftObjs -= cache->nodesetObjs->number;
+	    if (cache->stringObjs)
+		leftObjs -= cache->stringObjs->number;
+	    if (cache->booleanObjs)
+		leftObjs -= cache->booleanObjs->number;
+	    if (cache->numberObjs)
+		leftObjs -= cache->numberObjs->number;
+	    if (cache->miscObjs)
+		leftObjs -= cache->miscObjs->number;
+	}
+    }
+
+    printf("# all\n");
+    printf("#   total  : %d\n", reqAll);
+    printf("#   left  : %d\n", leftObjs);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalAll);
+    printf("#   reused : %d\n", reAll);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxAll);
+
+    printf("# node-sets\n");
+    printf("#   total  : %d\n", reqNodeset);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalNodeset);
+    printf("#   reused : %d\n", reNodeset);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxNodeset);
+
+    printf("# strings\n");
+    printf("#   total  : %d\n", reqString);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalString);
+    printf("#   reused : %d\n", reString);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxString);
+
+    printf("# booleans\n");
+    printf("#   total  : %d\n", reqBool);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalBool);
+    printf("#   reused : %d\n", reBool);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxBool);
+
+    printf("# numbers\n");
+    printf("#   total  : %d\n", reqNumber);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalNumber);
+    printf("#   reused : %d\n", reNumber);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxNumber);
+
+    printf("# XSLT result tree fragments\n");
+    printf("#   total  : %d\n", reqXSLTTree);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalXSLTTree);
+    printf("#   reused : %d\n", reXSLTTree);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxXSLTTree);
+
+    printf("# undefined\n");
+    printf("#   total  : %d\n", reqUndefined);
+    printf("#   created: %d\n", xmlXPathDebugObjTotalUndefined);
+    printf("#   reused : %d\n", reUndefined);
+    printf("#   max    : %d\n", xmlXPathDebugObjMaxUndefined);
+
+}
+
+#endif /* XP_DEBUG_OBJ_USAGE */
+
+#endif /* LIBXML_DEBUG_ENABLED */
+
+/************************************************************************
+ *									*
+ *			XPath object caching				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathNewCache:
+ *
+ * Create a new object cache
+ *
+ * Returns the xmlXPathCache just allocated.
+ */
+static xmlXPathContextCachePtr
+xmlXPathNewCache(void)
+{
+    xmlXPathContextCachePtr ret;
+
+    ret = (xmlXPathContextCachePtr) xmlMalloc(sizeof(xmlXPathContextCache));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating object cache\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathContextCache));
+    ret->maxNodeset = 100;
+    ret->maxString = 100;
+    ret->maxBoolean = 100;
+    ret->maxNumber = 100;
+    ret->maxMisc = 100;
+    return(ret);
+}
+
+static void
+xmlXPathCacheFreeObjectList(xmlPointerListPtr list)
+{
+    int i;
+    xmlXPathObjectPtr obj;
+
+    if (list == NULL)
+	return;
+
+    for (i = 0; i < list->number; i++) {
+	obj = list->items[i];
+	/*
+	* Note that it is already assured that we don't need to
+	* look out for namespace nodes in the node-set.
+	*/
+	if (obj->nodesetval != NULL) {
+	    if (obj->nodesetval->nodeTab != NULL)
+		xmlFree(obj->nodesetval->nodeTab);
+	    xmlFree(obj->nodesetval);
+	}
+	xmlFree(obj);
+#ifdef XP_DEBUG_OBJ_USAGE
+	xmlXPathDebugObjCounterAll--;
+#endif
+    }
+    xmlPointerListFree(list);
+}
+
+static void
+xmlXPathFreeCache(xmlXPathContextCachePtr cache)
+{
+    if (cache == NULL)
+	return;
+    if (cache->nodesetObjs)
+	xmlXPathCacheFreeObjectList(cache->nodesetObjs);
+    if (cache->stringObjs)
+	xmlXPathCacheFreeObjectList(cache->stringObjs);
+    if (cache->booleanObjs)
+	xmlXPathCacheFreeObjectList(cache->booleanObjs);
+    if (cache->numberObjs)
+	xmlXPathCacheFreeObjectList(cache->numberObjs);
+    if (cache->miscObjs)
+	xmlXPathCacheFreeObjectList(cache->miscObjs);
+    xmlFree(cache);
+}
+
+/**
+ * xmlXPathContextSetCache:
+ *
+ * @ctxt:  the XPath context
+ * @active: enables/disables (creates/frees) the cache
+ * @value: a value with semantics dependant on @options
+ * @options: options (currently only the value 0 is used)
+ *
+ * Creates/frees an object cache on the XPath context.
+ * If activates XPath objects (xmlXPathObject) will be cached internally
+ * to be reused.
+ * @options:
+ *   0: This will set the XPath object caching:
+ *      @value:
+ *        This will set the maximum number of XPath objects
+ *        to be cached per slot
+ *        There are 5 slots for: node-set, string, number, boolean, and
+ *        misc objects. Use <0 for the default number (100).
+ *   Other values for @options have currently no effect.
+ *
+ * Returns 0 if the setting succeeded, and -1 on API or internal errors.
+ */
+int
+xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
+			int active,
+			int value,
+			int options)
+{
+    if (ctxt == NULL)
+	return(-1);
+    if (active) {
+	xmlXPathContextCachePtr cache;
+
+	if (ctxt->cache == NULL) {
+	    ctxt->cache = xmlXPathNewCache();
+	    if (ctxt->cache == NULL)
+		return(-1);
+	}
+	cache = (xmlXPathContextCachePtr) ctxt->cache;
+	if (options == 0) {
+	    if (value < 0)
+		value = 100;
+	    cache->maxNodeset = value;
+	    cache->maxString = value;
+	    cache->maxNumber = value;
+	    cache->maxBoolean = value;
+	    cache->maxMisc = value;
+	}
+    } else if (ctxt->cache != NULL) {
+	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
+	ctxt->cache = NULL;
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathCacheWrapNodeSet:
+ * @ctxt: the XPath context
+ * @val:  the NodePtr value
+ *
+ * This is the cached version of xmlXPathWrapNodeSet().
+ * Wrap the Nodeset @val in a new xmlXPathObjectPtr
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
+{
+    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
+	xmlXPathContextCachePtr cache =
+	    (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+	    ret->type = XPATH_NODESET;
+	    ret->nodesetval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
+#endif
+	    return(ret);
+	}
+    }
+
+    return(xmlXPathWrapNodeSet(val));
+
+}
+
+/**
+ * xmlXPathCacheWrapString:
+ * @ctxt: the XPath context
+ * @val:  the xmlChar * value
+ *
+ * This is the cached version of xmlXPathWrapString().
+ * Wraps the @val string into an XPath object.
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
+{
+    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->stringObjs != NULL) &&
+	    (cache->stringObjs->number != 0))
+	{
+
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->stringObjs->items[--cache->stringObjs->number];
+	    ret->type = XPATH_STRING;
+	    ret->stringval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+	    /*
+	    * Fallback to misc-cache.
+	    */
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_STRING;
+	    ret->stringval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathWrapString(val));
+}
+
+/**
+ * xmlXPathCacheNewNodeSet:
+ * @ctxt: the XPath context
+ * @val:  the NodePtr value
+ *
+ * This is the cached version of xmlXPathNewNodeSet().
+ * Acquire an xmlXPathObjectPtr of type NodeSet and initialize
+ * it with the single Node @val
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
+{
+    if ((ctxt != NULL) && (ctxt->cache)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->nodesetObjs != NULL) &&
+	    (cache->nodesetObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+	    /*
+	    * Use the nodset-cache.
+	    */
+	    ret = (xmlXPathObjectPtr)
+		cache->nodesetObjs->items[--cache->nodesetObjs->number];
+	    ret->type = XPATH_NODESET;
+	    ret->boolval = 0;
+	    if (val) {
+		if ((ret->nodesetval->nodeMax == 0) ||
+		    (val->type == XML_NAMESPACE_DECL))
+		{
+		    xmlXPathNodeSetAddUnique(ret->nodesetval, val);
+		} else {
+		    ret->nodesetval->nodeTab[0] = val;
+		    ret->nodesetval->nodeNr = 1;
+		}
+	    }
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+	    /*
+	    * Fallback to misc-cache.
+	    */
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_NODESET;
+	    ret->boolval = 0;
+	    ret->nodesetval = xmlXPathNodeSetCreate(val);
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathNewNodeSet(val));
+}
+
+/**
+ * xmlXPathCacheNewCString:
+ * @ctxt: the XPath context
+ * @val:  the char * value
+ *
+ * This is the cached version of xmlXPathNewCString().
+ * Acquire an xmlXPathObjectPtr of type string and of value @val
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
+{
+    if ((ctxt != NULL) && (ctxt->cache)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->stringObjs != NULL) &&
+	    (cache->stringObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->stringObjs->items[--cache->stringObjs->number];
+
+	    ret->type = XPATH_STRING;
+	    ret->stringval = xmlStrdup(BAD_CAST val);
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_STRING;
+	    ret->stringval = xmlStrdup(BAD_CAST val);
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathNewCString(val));
+}
+
+/**
+ * xmlXPathCacheNewString:
+ * @ctxt: the XPath context
+ * @val:  the xmlChar * value
+ *
+ * This is the cached version of xmlXPathNewString().
+ * Acquire an xmlXPathObjectPtr of type string and of value @val
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
+{
+    if ((ctxt != NULL) && (ctxt->cache)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->stringObjs != NULL) &&
+	    (cache->stringObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->stringObjs->items[--cache->stringObjs->number];
+	    ret->type = XPATH_STRING;
+	    if (val != NULL)
+		ret->stringval = xmlStrdup(val);
+	    else
+		ret->stringval = xmlStrdup((const xmlChar *)"");
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_STRING;
+	    if (val != NULL)
+		ret->stringval = xmlStrdup(val);
+	    else
+		ret->stringval = xmlStrdup((const xmlChar *)"");
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathNewString(val));
+}
+
+/**
+ * xmlXPathCacheNewBoolean:
+ * @ctxt: the XPath context
+ * @val:  the boolean value
+ *
+ * This is the cached version of xmlXPathNewBoolean().
+ * Acquires an xmlXPathObjectPtr of type boolean and of value @val
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
+{
+    if ((ctxt != NULL) && (ctxt->cache)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->booleanObjs != NULL) &&
+	    (cache->booleanObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->booleanObjs->items[--cache->booleanObjs->number];
+	    ret->type = XPATH_BOOLEAN;
+	    ret->boolval = (val != 0);
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_BOOLEAN;
+	    ret->boolval = (val != 0);
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathNewBoolean(val));
+}
+
+/**
+ * xmlXPathCacheNewFloat:
+ * @ctxt: the XPath context
+ * @val:  the double value
+ *
+ * This is the cached version of xmlXPathNewFloat().
+ * Acquires an xmlXPathObjectPtr of type double and of value @val
+ *
+ * Returns the created or reused object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
+{
+     if ((ctxt != NULL) && (ctxt->cache)) {
+	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
+
+	if ((cache->numberObjs != NULL) &&
+	    (cache->numberObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->numberObjs->items[--cache->numberObjs->number];
+	    ret->type = XPATH_NUMBER;
+	    ret->floatval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
+#endif
+	    return(ret);
+	} else if ((cache->miscObjs != NULL) &&
+	    (cache->miscObjs->number != 0))
+	{
+	    xmlXPathObjectPtr ret;
+
+	    ret = (xmlXPathObjectPtr)
+		cache->miscObjs->items[--cache->miscObjs->number];
+
+	    ret->type = XPATH_NUMBER;
+	    ret->floatval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
+#endif
+	    return(ret);
+	}
+    }
+    return(xmlXPathNewFloat(val));
+}
+
+/**
+ * xmlXPathCacheConvertString:
+ * @ctxt: the XPath context
+ * @val:  an XPath object
+ *
+ * This is the cached version of xmlXPathConvertString().
+ * Converts an existing object to its string() equivalent
+ *
+ * Returns a created or reused object, the old one is freed (cached)
+ *         (or the operation is done directly on @val)
+ */
+
+static xmlXPathObjectPtr
+xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
+    xmlChar *res = NULL;
+
+    if (val == NULL)
+	return(xmlXPathCacheNewCString(ctxt, ""));
+
+    switch (val->type) {
+    case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
+#endif
+	break;
+    case XPATH_NODESET:
+    case XPATH_XSLT_TREE:
+	res = xmlXPathCastNodeSetToString(val->nodesetval);
+	break;
+    case XPATH_STRING:
+	return(val);
+    case XPATH_BOOLEAN:
+	res = xmlXPathCastBooleanToString(val->boolval);
+	break;
+    case XPATH_NUMBER:
+	res = xmlXPathCastNumberToString(val->floatval);
+	break;
+    case XPATH_USERS:
+    case XPATH_POINT:
+    case XPATH_RANGE:
+    case XPATH_LOCATIONSET:
+	TODO;
+	break;
+    }
+    xmlXPathReleaseObject(ctxt, val);
+    if (res == NULL)
+	return(xmlXPathCacheNewCString(ctxt, ""));
+    return(xmlXPathCacheWrapString(ctxt, res));
+}
+
+/**
+ * xmlXPathCacheObjectCopy:
+ * @ctxt: the XPath context
+ * @val:  the original object
+ *
+ * This is the cached version of xmlXPathObjectCopy().
+ * Acquire a copy of a given object
+ *
+ * Returns a created or reused created object.
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheObjectCopy(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val)
+{
+    if (val == NULL)
+	return(NULL);
+
+    if (XP_HAS_CACHE(ctxt)) {
+	switch (val->type) {
+	    case XPATH_NODESET:
+		return(xmlXPathCacheWrapNodeSet(ctxt,
+		    xmlXPathNodeSetMerge(NULL, val->nodesetval)));
+	    case XPATH_STRING:
+		return(xmlXPathCacheNewString(ctxt, val->stringval));
+	    case XPATH_BOOLEAN:
+		return(xmlXPathCacheNewBoolean(ctxt, val->boolval));
+	    case XPATH_NUMBER:
+		return(xmlXPathCacheNewFloat(ctxt, val->floatval));
+	    default:
+		break;
+	}
+    }
+    return(xmlXPathObjectCopy(val));
+}
+
+/**
+ * xmlXPathCacheConvertBoolean:
+ * @ctxt: the XPath context
+ * @val:  an XPath object
+ *
+ * This is the cached version of xmlXPathConvertBoolean().
+ * Converts an existing object to its boolean() equivalent
+ *
+ * Returns a created or reused object, the old one is freed (or the operation
+ *         is done directly on @val)
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
+    xmlXPathObjectPtr ret;
+
+    if (val == NULL)
+	return(xmlXPathCacheNewBoolean(ctxt, 0));
+    if (val->type == XPATH_BOOLEAN)
+	return(val);
+    ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(val));
+    xmlXPathReleaseObject(ctxt, val);
+    return(ret);
+}
+
+/**
+ * xmlXPathCacheConvertNumber:
+ * @ctxt: the XPath context
+ * @val:  an XPath object
+ *
+ * This is the cached version of xmlXPathConvertNumber().
+ * Converts an existing object to its number() equivalent
+ *
+ * Returns a created or reused object, the old one is freed (or the operation
+ *         is done directly on @val)
+ */
+static xmlXPathObjectPtr
+xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
+    xmlXPathObjectPtr ret;
+
+    if (val == NULL)
+	return(xmlXPathCacheNewFloat(ctxt, 0.0));
+    if (val->type == XPATH_NUMBER)
+	return(val);
+    ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(val));
+    xmlXPathReleaseObject(ctxt, val);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		Parser stacks related functions and macros		*
+ *									*
+ ************************************************************************/
+
+/**
+ * valuePop:
+ * @ctxt: an XPath evaluation context
+ *
+ * Pops the top XPath object from the value stack
+ *
+ * Returns the XPath object just removed
+ */
+xmlXPathObjectPtr
+valuePop(xmlXPathParserContextPtr ctxt)
+{
+    xmlXPathObjectPtr ret;
+
+    if ((ctxt == NULL) || (ctxt->valueNr <= 0))
+        return (NULL);
+    ctxt->valueNr--;
+    if (ctxt->valueNr > 0)
+        ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
+    else
+        ctxt->value = NULL;
+    ret = ctxt->valueTab[ctxt->valueNr];
+    ctxt->valueTab[ctxt->valueNr] = NULL;
+    return (ret);
+}
+/**
+ * valuePush:
+ * @ctxt:  an XPath evaluation context
+ * @value:  the XPath object
+ *
+ * Pushes a new XPath object on top of the value stack
+ *
+ * returns the number of items on the value stack
+ */
+int
+valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
+{
+    if ((ctxt == NULL) || (value == NULL)) return(-1);
+    if (ctxt->valueNr >= ctxt->valueMax) {
+        xmlXPathObjectPtr *tmp;
+
+        tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
+                                             2 * ctxt->valueMax *
+                                             sizeof(ctxt->valueTab[0]));
+        if (tmp == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
+            return (0);
+        }
+        ctxt->valueMax *= 2;
+	ctxt->valueTab = tmp;
+    }
+    ctxt->valueTab[ctxt->valueNr] = value;
+    ctxt->value = value;
+    return (ctxt->valueNr++);
+}
+
+/**
+ * xmlXPathPopBoolean:
+ * @ctxt:  an XPath parser context
+ *
+ * Pops a boolean from the stack, handling conversion if needed.
+ * Check error with #xmlXPathCheckError.
+ *
+ * Returns the boolean
+ */
+int
+xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr obj;
+    int ret;
+
+    obj = valuePop(ctxt);
+    if (obj == NULL) {
+	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
+	return(0);
+    }
+    if (obj->type != XPATH_BOOLEAN)
+	ret = xmlXPathCastToBoolean(obj);
+    else
+        ret = obj->boolval;
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return(ret);
+}
+
+/**
+ * xmlXPathPopNumber:
+ * @ctxt:  an XPath parser context
+ *
+ * Pops a number from the stack, handling conversion if needed.
+ * Check error with #xmlXPathCheckError.
+ *
+ * Returns the number
+ */
+double
+xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr obj;
+    double ret;
+
+    obj = valuePop(ctxt);
+    if (obj == NULL) {
+	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
+	return(0);
+    }
+    if (obj->type != XPATH_NUMBER)
+	ret = xmlXPathCastToNumber(obj);
+    else
+        ret = obj->floatval;
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return(ret);
+}
+
+/**
+ * xmlXPathPopString:
+ * @ctxt:  an XPath parser context
+ *
+ * Pops a string from the stack, handling conversion if needed.
+ * Check error with #xmlXPathCheckError.
+ *
+ * Returns the string
+ */
+xmlChar *
+xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr obj;
+    xmlChar * ret;
+
+    obj = valuePop(ctxt);
+    if (obj == NULL) {
+	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
+	return(NULL);
+    }
+    ret = xmlXPathCastToString(obj);	/* this does required strdup */
+    /* TODO: needs refactoring somewhere else */
+    if (obj->stringval == ret)
+	obj->stringval = NULL;
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return(ret);
+}
+
+/**
+ * xmlXPathPopNodeSet:
+ * @ctxt:  an XPath parser context
+ *
+ * Pops a node-set from the stack, handling conversion if needed.
+ * Check error with #xmlXPathCheckError.
+ *
+ * Returns the node-set
+ */
+xmlNodeSetPtr
+xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr obj;
+    xmlNodeSetPtr ret;
+
+    if (ctxt == NULL) return(NULL);
+    if (ctxt->value == NULL) {
+	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
+	return(NULL);
+    }
+    if (!xmlXPathStackIsNodeSet(ctxt)) {
+	xmlXPathSetTypeError(ctxt);
+	return(NULL);
+    }
+    obj = valuePop(ctxt);
+    ret = obj->nodesetval;
+#if 0
+    /* to fix memory leak of not clearing obj->user */
+    if (obj->boolval && obj->user != NULL)
+        xmlFreeNodeList((xmlNodePtr) obj->user);
+#endif
+    obj->nodesetval = NULL;
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return(ret);
+}
+
+/**
+ * xmlXPathPopExternal:
+ * @ctxt:  an XPath parser context
+ *
+ * Pops an external object from the stack, handling conversion if needed.
+ * Check error with #xmlXPathCheckError.
+ *
+ * Returns the object
+ */
+void *
+xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr obj;
+    void * ret;
+
+    if ((ctxt == NULL) || (ctxt->value == NULL)) {
+	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
+	return(NULL);
+    }
+    if (ctxt->value->type != XPATH_USERS) {
+	xmlXPathSetTypeError(ctxt);
+	return(NULL);
+    }
+    obj = valuePop(ctxt);
+    ret = obj->user;
+    obj->user = NULL;
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return(ret);
+}
+
+/*
+ * Macros for accessing the content. Those should be used only by the parser,
+ * and not exported.
+ *
+ * Dirty macros, i.e. one need to make assumption on the context to use them
+ *
+ *   CUR_PTR return the current pointer to the xmlChar to be parsed.
+ *   CUR     returns the current xmlChar value, i.e. a 8 bit value
+ *           in ISO-Latin or UTF-8.
+ *           This should be used internally by the parser
+ *           only to compare to ASCII values otherwise it would break when
+ *           running with UTF-8 encoding.
+ *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
+ *           to compare on ASCII based substring.
+ *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
+ *           strings within the parser.
+ *   CURRENT Returns the current char value, with the full decoding of
+ *           UTF-8 if we are using this mode. It returns an int.
+ *   NEXT    Skip to the next character, this does the proper decoding
+ *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
+ *           It returns the pointer to the current xmlChar.
+ */
+
+#define CUR (*ctxt->cur)
+#define SKIP(val) ctxt->cur += (val)
+#define NXT(val) ctxt->cur[(val)]
+#define CUR_PTR ctxt->cur
+#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
+
+#define COPY_BUF(l,b,i,v)                                              \
+    if (l == 1) b[i++] = (xmlChar) v;                                  \
+    else i += xmlCopyChar(l,&b[i],v)
+
+#define NEXTL(l)  ctxt->cur += l
+
+#define SKIP_BLANKS							\
+    while (IS_BLANK_CH(*(ctxt->cur))) NEXT
+
+#define CURRENT (*ctxt->cur)
+#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
+
+
+#ifndef DBL_DIG
+#define DBL_DIG 16
+#endif
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 1E-9
+#endif
+
+#define UPPER_DOUBLE 1E9
+#define LOWER_DOUBLE 1E-5
+#define	LOWER_DOUBLE_EXP 5
+
+#define INTEGER_DIGITS DBL_DIG
+#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
+#define EXPONENT_DIGITS (3 + 2)
+
+/**
+ * xmlXPathFormatNumber:
+ * @number:     number to format
+ * @buffer:     output buffer
+ * @buffersize: size of output buffer
+ *
+ * Convert the number into a string representation.
+ */
+static void
+xmlXPathFormatNumber(double number, char buffer[], int buffersize)
+{
+    switch (xmlXPathIsInf(number)) {
+    case 1:
+	if (buffersize > (int)sizeof("Infinity"))
+	    snprintf(buffer, buffersize, "Infinity");
+	break;
+    case -1:
+	if (buffersize > (int)sizeof("-Infinity"))
+	    snprintf(buffer, buffersize, "-Infinity");
+	break;
+    default:
+	if (xmlXPathIsNaN(number)) {
+	    if (buffersize > (int)sizeof("NaN"))
+		snprintf(buffer, buffersize, "NaN");
+	} else if (number == 0 && xmlXPathGetSign(number) != 0) {
+	    snprintf(buffer, buffersize, "0");
+	} else if (number == ((int) number)) {
+	    char work[30];
+	    char *ptr, *cur;
+	    int value = (int) number;
+
+            ptr = &buffer[0];
+	    if (value == 0) {
+		*ptr++ = '0';
+	    } else {
+		snprintf(work, 29, "%d", value);
+		cur = &work[0];
+		while ((*cur) && (ptr - buffer < buffersize)) {
+		    *ptr++ = *cur++;
+		}
+	    }
+	    if (ptr - buffer < buffersize) {
+		*ptr = 0;
+	    } else if (buffersize > 0) {
+		ptr--;
+		*ptr = 0;
+	    }
+	} else {
+	    /*
+	      For the dimension of work,
+	          DBL_DIG is number of significant digits
+		  EXPONENT is only needed for "scientific notation"
+	          3 is sign, decimal point, and terminating zero
+		  LOWER_DOUBLE_EXP is max number of leading zeroes in fraction
+	      Note that this dimension is slightly (a few characters)
+	      larger than actually necessary.
+	    */
+	    char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
+	    int integer_place, fraction_place;
+	    char *ptr;
+	    char *after_fraction;
+	    double absolute_value;
+	    int size;
+
+	    absolute_value = fabs(number);
+
+	    /*
+	     * First choose format - scientific or regular floating point.
+	     * In either case, result is in work, and after_fraction points
+	     * just past the fractional part.
+	    */
+	    if ( ((absolute_value > UPPER_DOUBLE) ||
+		  (absolute_value < LOWER_DOUBLE)) &&
+		 (absolute_value != 0.0) ) {
+		/* Use scientific notation */
+		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
+		fraction_place = DBL_DIG - 1;
+		size = snprintf(work, sizeof(work),"%*.*e",
+			 integer_place, fraction_place, number);
+		while ((size > 0) && (work[size] != 'e')) size--;
+
+	    }
+	    else {
+		/* Use regular notation */
+		if (absolute_value > 0.0) {
+		    integer_place = (int)log10(absolute_value);
+		    if (integer_place > 0)
+		        fraction_place = DBL_DIG - integer_place - 1;
+		    else
+		        fraction_place = DBL_DIG - integer_place;
+		} else {
+		    fraction_place = 1;
+		}
+		size = snprintf(work, sizeof(work), "%0.*f",
+				fraction_place, number);
+	    }
+
+	    /* Remove fractional trailing zeroes */
+	    after_fraction = work + size;
+	    ptr = after_fraction;
+	    while (*(--ptr) == '0')
+		;
+	    if (*ptr != '.')
+	        ptr++;
+	    while ((*ptr++ = *after_fraction++) != 0);
+
+	    /* Finally copy result back to caller */
+	    size = strlen(work) + 1;
+	    if (size > buffersize) {
+		work[buffersize - 1] = 0;
+		size = buffersize;
+	    }
+	    memmove(buffer, work, size);
+	}
+	break;
+    }
+}
+
+
+/************************************************************************
+ *									*
+ *			Routines to handle NodeSets			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathOrderDocElems:
+ * @doc:  an input 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.
+ */
+long
+xmlXPathOrderDocElems(xmlDocPtr doc) {
+    long count = 0;
+    xmlNodePtr cur;
+
+    if (doc == NULL)
+	return(-1);
+    cur = doc->children;
+    while (cur != NULL) {
+	if (cur->type == XML_ELEMENT_NODE) {
+	    cur->content = (void *) (-(++count));
+	    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 == (xmlNodePtr) doc) {
+		cur = NULL;
+		break;
+	    }
+	    if (cur->next != NULL) {
+		cur = cur->next;
+		break;
+	    }
+	} while (cur != NULL);
+    }
+    return(count);
+}
+
+/**
+ * xmlXPathCmpNodes:
+ * @node1:  the first node
+ * @node2:  the second node
+ *
+ * Compare two nodes w.r.t document order
+ *
+ * Returns -2 in case of error 1 if first point < second point, 0 if
+ *         it's the same node, -1 otherwise
+ */
+int
+xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
+    int depth1, depth2;
+    int attr1 = 0, attr2 = 0;
+    xmlNodePtr attrNode1 = NULL, attrNode2 = NULL;
+    xmlNodePtr cur, root;
+
+    if ((node1 == NULL) || (node2 == NULL))
+	return(-2);
+    /*
+     * a couple of optimizations which will avoid computations in most cases
+     */
+    if (node1 == node2)		/* trivial case */
+	return(0);
+    if (node1->type == XML_ATTRIBUTE_NODE) {
+	attr1 = 1;
+	attrNode1 = node1;
+	node1 = node1->parent;
+    }
+    if (node2->type == XML_ATTRIBUTE_NODE) {
+	attr2 = 1;
+	attrNode2 = node2;
+	node2 = node2->parent;
+    }
+    if (node1 == node2) {
+	if (attr1 == attr2) {
+	    /* not required, but we keep attributes in order */
+	    if (attr1 != 0) {
+	        cur = attrNode2->prev;
+		while (cur != NULL) {
+		    if (cur == attrNode1)
+		        return (1);
+		    cur = cur->prev;
+		}
+		return (-1);
+	    }
+	    return(0);
+	}
+	if (attr2 == 1)
+	    return(1);
+	return(-1);
+    }
+    if ((node1->type == XML_NAMESPACE_DECL) ||
+        (node2->type == XML_NAMESPACE_DECL))
+	return(1);
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+	long l1, l2;
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+    /*
+     * compute depth to root
+     */
+    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
+	if (cur == node1)
+	    return(1);
+	depth2++;
+    }
+    root = cur;
+    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
+	if (cur == node2)
+	    return(-1);
+	depth1++;
+    }
+    /*
+     * Distinct document (or distinct entities :-( ) case.
+     */
+    if (root != cur) {
+	return(-2);
+    }
+    /*
+     * get the nearest common ancestor.
+     */
+    while (depth1 > depth2) {
+	depth1--;
+	node1 = node1->parent;
+    }
+    while (depth2 > depth1) {
+	depth2--;
+	node2 = node2->parent;
+    }
+    while (node1->parent != node2->parent) {
+	node1 = node1->parent;
+	node2 = node2->parent;
+	/* should not happen but just in case ... */
+	if ((node1 == NULL) || (node2 == NULL))
+	    return(-2);
+    }
+    /*
+     * Find who's first.
+     */
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+	long l1, l2;
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+    for (cur = node1->next;cur != NULL;cur = cur->next)
+	if (cur == node2)
+	    return(1);
+    return(-1); /* assume there is no sibling list corruption */
+}
+
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+/**
+ * xmlXPathCmpNodesExt:
+ * @node1:  the first node
+ * @node2:  the second node
+ *
+ * Compare two nodes w.r.t document order.
+ * This one is optimized for handling of non-element nodes.
+ *
+ * Returns -2 in case of error 1 if first point < second point, 0 if
+ *         it's the same node, -1 otherwise
+ */
+static int
+xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
+    int depth1, depth2;
+    int misc = 0, precedence1 = 0, precedence2 = 0;
+    xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
+    xmlNodePtr cur, root;
+    long l1, l2;
+
+    if ((node1 == NULL) || (node2 == NULL))
+	return(-2);
+
+    if (node1 == node2)
+	return(0);
+
+    /*
+     * a couple of optimizations which will avoid computations in most cases
+     */
+    switch (node1->type) {
+	case XML_ELEMENT_NODE:
+	    if (node2->type == XML_ELEMENT_NODE) {
+		if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
+		    (0 > (long) node2->content) &&
+		    (node1->doc == node2->doc))
+		{
+		    l1 = -((long) node1->content);
+		    l2 = -((long) node2->content);
+		    if (l1 < l2)
+			return(1);
+		    if (l1 > l2)
+			return(-1);
+		} else
+		    goto turtle_comparison;
+	    }
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    precedence1 = 1; /* element is owner */
+	    miscNode1 = node1;
+	    node1 = node1->parent;
+	    misc = 1;
+	    break;
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_COMMENT_NODE:
+	case XML_PI_NODE: {
+	    miscNode1 = node1;
+	    /*
+	    * Find nearest element node.
+	    */
+	    if (node1->prev != NULL) {
+		do {
+		    node1 = node1->prev;
+		    if (node1->type == XML_ELEMENT_NODE) {
+			precedence1 = 3; /* element in prev-sibl axis */
+			break;
+		    }
+		    if (node1->prev == NULL) {
+			precedence1 = 2; /* element is parent */
+			/*
+			* URGENT TODO: Are there any cases, where the
+			* parent of such a node is not an element node?
+			*/
+			node1 = node1->parent;
+			break;
+		    }
+		} while (1);
+	    } else {
+		precedence1 = 2; /* element is parent */
+		node1 = node1->parent;
+	    }
+	    if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
+		(0 <= (long) node1->content)) {
+		/*
+		* Fallback for whatever case.
+		*/
+		node1 = miscNode1;
+		precedence1 = 0;
+	    } else
+		misc = 1;
+	}
+	    break;
+	case XML_NAMESPACE_DECL:
+	    /*
+	    * TODO: why do we return 1 for namespace nodes?
+	    */
+	    return(1);
+	default:
+	    break;
+    }
+    switch (node2->type) {
+	case XML_ELEMENT_NODE:
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    precedence2 = 1; /* element is owner */
+	    miscNode2 = node2;
+	    node2 = node2->parent;
+	    misc = 1;
+	    break;
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_COMMENT_NODE:
+	case XML_PI_NODE: {
+	    miscNode2 = node2;
+	    if (node2->prev != NULL) {
+		do {
+		    node2 = node2->prev;
+		    if (node2->type == XML_ELEMENT_NODE) {
+			precedence2 = 3; /* element in prev-sibl axis */
+			break;
+		    }
+		    if (node2->prev == NULL) {
+			precedence2 = 2; /* element is parent */
+			node2 = node2->parent;
+			break;
+		    }
+		} while (1);
+	    } else {
+		precedence2 = 2; /* element is parent */
+		node2 = node2->parent;
+	    }
+	    if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
+		(0 <= (long) node1->content))
+	    {
+		node2 = miscNode2;
+		precedence2 = 0;
+	    } else
+		misc = 1;
+	}
+	    break;
+	case XML_NAMESPACE_DECL:
+	    return(1);
+	default:
+	    break;
+    }
+    if (misc) {
+	if (node1 == node2) {
+	    if (precedence1 == precedence2) {
+		/*
+		* The ugly case; but normally there aren't many
+		* adjacent non-element nodes around.
+		*/
+		cur = miscNode2->prev;
+		while (cur != NULL) {
+		    if (cur == miscNode1)
+			return(1);
+		    if (cur->type == XML_ELEMENT_NODE)
+			return(-1);
+		    cur = cur->prev;
+		}
+		return (-1);
+	    } else {
+		/*
+		* Evaluate based on higher precedence wrt to the element.
+		* TODO: This assumes attributes are sorted before content.
+		*   Is this 100% correct?
+		*/
+		if (precedence1 < precedence2)
+		    return(1);
+		else
+		    return(-1);
+	    }
+	}
+	/*
+	* Special case: One of the helper-elements is contained by the other.
+	* <foo>
+	*   <node2>
+	*     <node1>Text-1(precedence1 == 2)</node1>
+	*   </node2>
+	*   Text-6(precedence2 == 3)
+	* </foo>
+	*/
+	if ((precedence2 == 3) && (precedence1 > 1)) {
+	    cur = node1->parent;
+	    while (cur) {
+		if (cur == node2)
+		    return(1);
+		cur = cur->parent;
+	    }
+	}
+	if ((precedence1 == 3) && (precedence2 > 1)) {
+	    cur = node2->parent;
+	    while (cur) {
+		if (cur == node1)
+		    return(-1);
+		cur = cur->parent;
+	    }
+	}
+    }
+
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+turtle_comparison:
+
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+    /*
+     * compute depth to root
+     */
+    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
+	if (cur == node1)
+	    return(1);
+	depth2++;
+    }
+    root = cur;
+    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
+	if (cur == node2)
+	    return(-1);
+	depth1++;
+    }
+    /*
+     * Distinct document (or distinct entities :-( ) case.
+     */
+    if (root != cur) {
+	return(-2);
+    }
+    /*
+     * get the nearest common ancestor.
+     */
+    while (depth1 > depth2) {
+	depth1--;
+	node1 = node1->parent;
+    }
+    while (depth2 > depth1) {
+	depth2--;
+	node2 = node2->parent;
+    }
+    while (node1->parent != node2->parent) {
+	node1 = node1->parent;
+	node2 = node2->parent;
+	/* should not happen but just in case ... */
+	if ((node1 == NULL) || (node2 == NULL))
+	    return(-2);
+    }
+    /*
+     * Find who's first.
+     */
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+    for (cur = node1->next;cur != NULL;cur = cur->next)
+	if (cur == node2)
+	    return(1);
+    return(-1); /* assume there is no sibling list corruption */
+}
+#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
+
+/**
+ * xmlXPathNodeSetSort:
+ * @set:  the node set
+ *
+ * Sort the node set in document order
+ */
+void
+xmlXPathNodeSetSort(xmlNodeSetPtr set) {
+    int i, j, incr, len;
+    xmlNodePtr tmp;
+
+    if (set == NULL)
+	return;
+
+    /* Use Shell's sort to sort the node-set */
+    len = set->nodeNr;
+    for (incr = len / 2; incr > 0; incr /= 2) {
+	for (i = incr; i < len; i++) {
+	    j = i - incr;
+	    while (j >= 0) {
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+		if (xmlXPathCmpNodesExt(set->nodeTab[j],
+			set->nodeTab[j + incr]) == -1)
+#else
+		if (xmlXPathCmpNodes(set->nodeTab[j],
+			set->nodeTab[j + incr]) == -1)
+#endif
+		{
+		    tmp = set->nodeTab[j];
+		    set->nodeTab[j] = set->nodeTab[j + incr];
+		    set->nodeTab[j + incr] = tmp;
+		    j -= incr;
+		} else
+		    break;
+	    }
+	}
+    }
+}
+
+#define XML_NODESET_DEFAULT	10
+/**
+ * xmlXPathNodeSetDupNs:
+ * @node:  the parent node of the namespace XPath node
+ * @ns:  the libxml namespace declaration node.
+ *
+ * Namespace node in libxml don't match the XPath semantic. In a node set
+ * the namespace nodes are duplicated and the next pointer is set to the
+ * parent node in the XPath semantic.
+ *
+ * Returns the newly created object.
+ */
+static xmlNodePtr
+xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
+    xmlNsPtr cur;
+
+    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
+	return(NULL);
+    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
+	return((xmlNodePtr) ns);
+
+    /*
+     * Allocate a new Namespace and fill the fields.
+     */
+    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+    if (cur == NULL) {
+        xmlXPathErrMemory(NULL, "duplicating namespace\n");
+	return(NULL);
+    }
+    memset(cur, 0, sizeof(xmlNs));
+    cur->type = XML_NAMESPACE_DECL;
+    if (ns->href != NULL)
+	cur->href = xmlStrdup(ns->href);
+    if (ns->prefix != NULL)
+	cur->prefix = xmlStrdup(ns->prefix);
+    cur->next = (xmlNsPtr) node;
+    return((xmlNodePtr) cur);
+}
+
+/**
+ * xmlXPathNodeSetFreeNs:
+ * @ns:  the XPath namespace node found in a nodeset.
+ *
+ * Namespace nodes in libxml don't match the XPath semantic. In a node set
+ * the namespace nodes are duplicated and the next pointer is set to the
+ * parent node in the XPath semantic. Check if such a node needs to be freed
+ */
+void
+xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
+    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
+	return;
+
+    if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) {
+	if (ns->href != NULL)
+	    xmlFree((xmlChar *)ns->href);
+	if (ns->prefix != NULL)
+	    xmlFree((xmlChar *)ns->prefix);
+	xmlFree(ns);
+    }
+}
+
+/**
+ * xmlXPathNodeSetCreate:
+ * @val:  an initial xmlNodePtr, or NULL
+ *
+ * Create a new xmlNodeSetPtr of type double and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlNodeSetPtr
+xmlXPathNodeSetCreate(xmlNodePtr val) {
+    xmlNodeSetPtr ret;
+
+    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating nodeset\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
+    if (val != NULL) {
+        ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+					     sizeof(xmlNodePtr));
+	if (ret->nodeTab == NULL) {
+	    xmlXPathErrMemory(NULL, "creating nodeset\n");
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	memset(ret->nodeTab, 0 ,
+	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+        ret->nodeMax = XML_NODESET_DEFAULT;
+	if (val->type == XML_NAMESPACE_DECL) {
+	    xmlNsPtr ns = (xmlNsPtr) val;
+
+	    ret->nodeTab[ret->nodeNr++] =
+		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+	} else
+	    ret->nodeTab[ret->nodeNr++] = val;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathNodeSetCreateSize:
+ * @size:  the initial size of the set
+ *
+ * Create a new xmlNodeSetPtr of type double and of value @val
+ *
+ * Returns the newly created object.
+ */
+static xmlNodeSetPtr
+xmlXPathNodeSetCreateSize(int size) {
+    xmlNodeSetPtr ret;
+
+    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating nodeset\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
+    if (size < XML_NODESET_DEFAULT)
+	size = XML_NODESET_DEFAULT;
+    ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr));
+    if (ret->nodeTab == NULL) {
+	xmlXPathErrMemory(NULL, "creating nodeset\n");
+	xmlFree(ret);
+	return(NULL);
+    }
+    memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr));
+    ret->nodeMax = size;
+    return(ret);
+}
+
+/**
+ * xmlXPathNodeSetContains:
+ * @cur:  the node-set
+ * @val:  the node
+ *
+ * checks whether @cur contains @val
+ *
+ * Returns true (1) if @cur contains @val, false (0) otherwise
+ */
+int
+xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
+    int i;
+
+    if ((cur == NULL) || (val == NULL)) return(0);
+    if (val->type == XML_NAMESPACE_DECL) {
+	for (i = 0; i < cur->nodeNr; i++) {
+	    if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+		xmlNsPtr ns1, ns2;
+
+		ns1 = (xmlNsPtr) val;
+		ns2 = (xmlNsPtr) cur->nodeTab[i];
+		if (ns1 == ns2)
+		    return(1);
+		if ((ns1->next != NULL) && (ns2->next == ns1->next) &&
+	            (xmlStrEqual(ns1->prefix, ns2->prefix)))
+		    return(1);
+	    }
+	}
+    } else {
+	for (i = 0; i < cur->nodeNr; i++) {
+	    if (cur->nodeTab[i] == val)
+		return(1);
+	}
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathNodeSetAddNs:
+ * @cur:  the initial node set
+ * @node:  the hosting node
+ * @ns:  a the namespace node
+ *
+ * add a new namespace node to an existing NodeSet
+ */
+void
+xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+    int i;
+
+
+    if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
+        (ns->type != XML_NAMESPACE_DECL) ||
+	(node->type != XML_ELEMENT_NODE))
+	return;
+
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+    /*
+     * prevent duplicates
+     */
+    for (i = 0;i < cur->nodeNr;i++) {
+        if ((cur->nodeTab[i] != NULL) &&
+	    (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
+	    (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
+	    (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
+	    return;
+    }
+
+    /*
+     * grow the nodeTab if needed
+     */
+    if (cur->nodeMax == 0) {
+        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+					     sizeof(xmlNodePtr));
+	if (cur->nodeTab == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	memset(cur->nodeTab, 0 ,
+	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+        cur->nodeMax = XML_NODESET_DEFAULT;
+    } else if (cur->nodeNr == cur->nodeMax) {
+        xmlNodePtr *temp;
+
+        cur->nodeMax *= 2;
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+				      sizeof(xmlNodePtr));
+	if (temp == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	cur->nodeTab = temp;
+    }
+    cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
+}
+
+/**
+ * xmlXPathNodeSetAdd:
+ * @cur:  the initial node set
+ * @val:  a new xmlNodePtr
+ *
+ * add a new xmlNodePtr to an existing NodeSet
+ */
+void
+xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+    int i;
+
+    if ((cur == NULL) || (val == NULL)) return;
+
+#if 0
+    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
+	return;	/* an XSLT fake node */
+#endif
+
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+    /*
+     * prevent duplcates
+     */
+    for (i = 0;i < cur->nodeNr;i++)
+        if (cur->nodeTab[i] == val) return;
+
+    /*
+     * grow the nodeTab if needed
+     */
+    if (cur->nodeMax == 0) {
+        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+					     sizeof(xmlNodePtr));
+	if (cur->nodeTab == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	memset(cur->nodeTab, 0 ,
+	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+        cur->nodeMax = XML_NODESET_DEFAULT;
+    } else if (cur->nodeNr == cur->nodeMax) {
+        xmlNodePtr *temp;
+
+        cur->nodeMax *= 2;
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+				      sizeof(xmlNodePtr));
+	if (temp == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	cur->nodeTab = temp;
+    }
+    if (val->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) val;
+
+	cur->nodeTab[cur->nodeNr++] =
+	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+    } else
+	cur->nodeTab[cur->nodeNr++] = val;
+}
+
+/**
+ * xmlXPathNodeSetAddUnique:
+ * @cur:  the initial node set
+ * @val:  a new xmlNodePtr
+ *
+ * add a new xmlNodePtr to an existing NodeSet, optimized version
+ * when we are sure the node is not already in the set.
+ */
+void
+xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+    if ((cur == NULL) || (val == NULL)) return;
+
+#if 0
+    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
+	return;	/* an XSLT fake node */
+#endif
+
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+    /*
+     * grow the nodeTab if needed
+     */
+    if (cur->nodeMax == 0) {
+        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+					     sizeof(xmlNodePtr));
+	if (cur->nodeTab == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	memset(cur->nodeTab, 0 ,
+	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+        cur->nodeMax = XML_NODESET_DEFAULT;
+    } else if (cur->nodeNr == cur->nodeMax) {
+        xmlNodePtr *temp;
+
+        cur->nodeMax *= 2;
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+				      sizeof(xmlNodePtr));
+	if (temp == NULL) {
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+	    return;
+	}
+	cur->nodeTab = temp;
+    }
+    if (val->type == XML_NAMESPACE_DECL) {
+	xmlNsPtr ns = (xmlNsPtr) val;
+
+	cur->nodeTab[cur->nodeNr++] =
+	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+    } else
+	cur->nodeTab[cur->nodeNr++] = val;
+}
+
+/**
+ * xmlXPathNodeSetMerge:
+ * @val1:  the first NodeSet or NULL
+ * @val2:  the second NodeSet
+ *
+ * Merges two nodesets, all nodes from @val2 are added to @val1
+ * if @val1 is NULL, a new set is created and copied from @val2
+ *
+ * Returns @val1 once extended or NULL in case of error.
+ */
+xmlNodeSetPtr
+xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+    int i, j, initNr, skip;
+    xmlNodePtr n1, n2;
+
+    if (val2 == NULL) return(val1);
+    if (val1 == NULL) {
+	val1 = xmlXPathNodeSetCreate(NULL);
+    if (val1 == NULL)
+        return (NULL);
+#if 0
+	/*
+	* TODO: The optimization won't work in every case, since
+	*  those nasty namespace nodes need to be added with
+	*  xmlXPathNodeSetDupNs() to the set; thus a pure
+	*  memcpy is not possible.
+	*  If there was a flag on the nodesetval, indicating that
+	*  some temporary nodes are in, that would be helpfull.
+	*/
+	/*
+	* Optimization: Create an equally sized node-set
+	* and memcpy the content.
+	*/
+	val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
+	if (val1 == NULL)
+	    return(NULL);
+	if (val2->nodeNr != 0) {
+	    if (val2->nodeNr == 1)
+		*(val1->nodeTab) = *(val2->nodeTab);
+	    else {
+		memcpy(val1->nodeTab, val2->nodeTab,
+		    val2->nodeNr * sizeof(xmlNodePtr));
+	    }
+	    val1->nodeNr = val2->nodeNr;
+	}
+	return(val1);
+#endif
+    }
+
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+    initNr = val1->nodeNr;
+
+    for (i = 0;i < val2->nodeNr;i++) {
+	n2 = val2->nodeTab[i];
+	/*
+	 * check against duplicates
+	 */
+	skip = 0;
+	for (j = 0; j < initNr; j++) {
+	    n1 = val1->nodeTab[j];
+	    if (n1 == n2) {
+		skip = 1;
+		break;
+	    } else if ((n1->type == XML_NAMESPACE_DECL) &&
+		       (n2->type == XML_NAMESPACE_DECL)) {
+		if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
+		    (xmlStrEqual(((xmlNsPtr) n1)->prefix,
+			((xmlNsPtr) n2)->prefix)))
+		{
+		    skip = 1;
+		    break;
+		}
+	    }
+	}
+	if (skip)
+	    continue;
+
+	/*
+	 * grow the nodeTab if needed
+	 */
+	if (val1->nodeMax == 0) {
+	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+						    sizeof(xmlNodePtr));
+	    if (val1->nodeTab == NULL) {
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+		return(NULL);
+	    }
+	    memset(val1->nodeTab, 0 ,
+		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+	    val1->nodeMax = XML_NODESET_DEFAULT;
+	} else if (val1->nodeNr == val1->nodeMax) {
+	    xmlNodePtr *temp;
+
+	    val1->nodeMax *= 2;
+	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+					     sizeof(xmlNodePtr));
+	    if (temp == NULL) {
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+		return(NULL);
+	    }
+	    val1->nodeTab = temp;
+	}
+	if (n2->type == XML_NAMESPACE_DECL) {
+	    xmlNsPtr ns = (xmlNsPtr) n2;
+
+	    val1->nodeTab[val1->nodeNr++] =
+		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+	} else
+	    val1->nodeTab[val1->nodeNr++] = n2;
+    }
+
+    return(val1);
+}
+
+#if 0 /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
+/**
+ * xmlXPathNodeSetMergeUnique:
+ * @val1:  the first NodeSet or NULL
+ * @val2:  the second NodeSet
+ *
+ * Merges two nodesets, all nodes from @val2 are added to @val1
+ * if @val1 is NULL, a new set is created and copied from @val2
+ *
+ * Returns @val1 once extended or NULL in case of error.
+ */
+static xmlNodeSetPtr
+xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+    int i;
+
+    if (val2 == NULL) return(val1);
+    if (val1 == NULL) {
+	val1 = xmlXPathNodeSetCreate(NULL);
+    }
+    if (val1 == NULL)
+        return (NULL);
+
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+
+    for (i = 0;i < val2->nodeNr;i++) {
+	/*
+	 * grow the nodeTab if needed
+	 */
+	if (val1->nodeMax == 0) {
+	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+						    sizeof(xmlNodePtr));
+	    if (val1->nodeTab == NULL) {
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+		return(NULL);
+	    }
+	    memset(val1->nodeTab, 0 ,
+		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+	    val1->nodeMax = XML_NODESET_DEFAULT;
+	} else if (val1->nodeNr == val1->nodeMax) {
+	    xmlNodePtr *temp;
+
+	    val1->nodeMax *= 2;
+	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+					     sizeof(xmlNodePtr));
+	    if (temp == NULL) {
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+		return(NULL);
+	    }
+	    val1->nodeTab = temp;
+	}
+	if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+	    xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];
+
+	    val1->nodeTab[val1->nodeNr++] =
+		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+	} else
+	    val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
+    }
+
+    return(val1);
+}
+#endif /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
+
+/**
+ * xmlXPathNodeSetMergeAndClear:
+ * @set1:  the first NodeSet or NULL
+ * @set2:  the second NodeSet
+ * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
+ *
+ * Merges two nodesets, all nodes from @set2 are added to @set1
+ * if @set1 is NULL, a new set is created and copied from @set2.
+ * Checks for duplicate nodes. Clears set2.
+ *
+ * Returns @set1 once extended or NULL in case of error.
+ */
+static xmlNodeSetPtr
+xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+			     int hasNullEntries)
+{
+    if ((set1 == NULL) && (hasNullEntries == 0)) {
+	/*
+	* Note that doing a memcpy of the list, namespace nodes are
+	* just assigned to set1, since set2 is cleared anyway.
+	*/
+	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
+	if (set1 == NULL)
+	    return(NULL);
+	if (set2->nodeNr != 0) {
+	    memcpy(set1->nodeTab, set2->nodeTab,
+		set2->nodeNr * sizeof(xmlNodePtr));
+	    set1->nodeNr = set2->nodeNr;
+	}
+    } else {
+	int i, j, initNbSet1;
+	xmlNodePtr n1, n2;
+
+	if (set1 == NULL)
+            set1 = xmlXPathNodeSetCreate(NULL);
+        if (set1 == NULL)
+            return (NULL);
+
+	initNbSet1 = set1->nodeNr;
+	for (i = 0;i < set2->nodeNr;i++) {
+	    n2 = set2->nodeTab[i];
+	    /*
+	    * Skip NULLed entries.
+	    */
+	    if (n2 == NULL)
+		continue;
+	    /*
+	    * Skip duplicates.
+	    */
+	    for (j = 0; j < initNbSet1; j++) {
+		n1 = set1->nodeTab[j];
+		if (n1 == n2) {
+		    goto skip_node;
+		} else if ((n1->type == XML_NAMESPACE_DECL) &&
+		    (n2->type == XML_NAMESPACE_DECL))
+		{
+		    if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
+			(xmlStrEqual(((xmlNsPtr) n1)->prefix,
+			((xmlNsPtr) n2)->prefix)))
+		    {
+			/*
+			* Free the namespace node.
+			*/
+			set2->nodeTab[i] = NULL;
+			xmlXPathNodeSetFreeNs((xmlNsPtr) n2);
+			goto skip_node;
+		    }
+		}
+	    }
+	    /*
+	    * grow the nodeTab if needed
+	    */
+	    if (set1->nodeMax == 0) {
+		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
+		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
+		if (set1->nodeTab == NULL) {
+		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+		    return(NULL);
+		}
+		memset(set1->nodeTab, 0,
+		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+		set1->nodeMax = XML_NODESET_DEFAULT;
+	    } else if (set1->nodeNr >= set1->nodeMax) {
+		xmlNodePtr *temp;
+
+		set1->nodeMax *= 2;
+		temp = (xmlNodePtr *) xmlRealloc(
+		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+		if (temp == NULL) {
+		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+		    return(NULL);
+		}
+		set1->nodeTab = temp;
+	    }
+	    if (n2->type == XML_NAMESPACE_DECL) {
+		xmlNsPtr ns = (xmlNsPtr) n2;
+
+		set1->nodeTab[set1->nodeNr++] =
+		    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+	    } else
+		set1->nodeTab[set1->nodeNr++] = n2;
+skip_node:
+	    {}
+	}
+    }
+    set2->nodeNr = 0;
+    return(set1);
+}
+
+/**
+ * xmlXPathNodeSetMergeAndClearNoDupls:
+ * @set1:  the first NodeSet or NULL
+ * @set2:  the second NodeSet
+ * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
+ *
+ * Merges two nodesets, all nodes from @set2 are added to @set1
+ * if @set1 is NULL, a new set is created and copied from @set2.
+ * Doesn't chack for duplicate nodes. Clears set2.
+ *
+ * Returns @set1 once extended or NULL in case of error.
+ */
+static xmlNodeSetPtr
+xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+				    int hasNullEntries)
+{
+    if (set2 == NULL)
+	return(set1);
+    if ((set1 == NULL) && (hasNullEntries == 0)) {
+	/*
+	* Note that doing a memcpy of the list, namespace nodes are
+	* just assigned to set1, since set2 is cleared anyway.
+	*/
+	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
+	if (set1 == NULL)
+	    return(NULL);
+	if (set2->nodeNr != 0) {
+	    memcpy(set1->nodeTab, set2->nodeTab,
+		set2->nodeNr * sizeof(xmlNodePtr));
+	    set1->nodeNr = set2->nodeNr;
+	}
+    } else {
+	int i;
+	xmlNodePtr n2;
+
+	if (set1 == NULL)
+	    set1 = xmlXPathNodeSetCreate(NULL);
+        if (set1 == NULL)
+            return (NULL);
+
+	for (i = 0;i < set2->nodeNr;i++) {
+	    n2 = set2->nodeTab[i];
+	    /*
+	    * Skip NULLed entries.
+	    */
+	    if (n2 == NULL)
+		continue;
+	    if (set1->nodeMax == 0) {
+		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
+		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
+		if (set1->nodeTab == NULL) {
+		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+		    return(NULL);
+		}
+		memset(set1->nodeTab, 0,
+		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+		set1->nodeMax = XML_NODESET_DEFAULT;
+	    } else if (set1->nodeNr >= set1->nodeMax) {
+		xmlNodePtr *temp;
+
+		set1->nodeMax *= 2;
+		temp = (xmlNodePtr *) xmlRealloc(
+		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+		if (temp == NULL) {
+		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+		    return(NULL);
+		}
+		set1->nodeTab = temp;
+	    }
+	    set1->nodeTab[set1->nodeNr++] = n2;
+	}
+    }
+    set2->nodeNr = 0;
+    return(set1);
+}
+
+/**
+ * xmlXPathNodeSetDel:
+ * @cur:  the initial node set
+ * @val:  an xmlNodePtr
+ *
+ * Removes an xmlNodePtr from an existing NodeSet
+ */
+void
+xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
+    int i;
+
+    if (cur == NULL) return;
+    if (val == NULL) return;
+
+    /*
+     * find node in nodeTab
+     */
+    for (i = 0;i < cur->nodeNr;i++)
+        if (cur->nodeTab[i] == val) break;
+
+    if (i >= cur->nodeNr) {	/* not found */
+#ifdef DEBUG
+        xmlGenericError(xmlGenericErrorContext,
+	        "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
+		val->name);
+#endif
+        return;
+    }
+    if ((cur->nodeTab[i] != NULL) &&
+	(cur->nodeTab[i]->type == XML_NAMESPACE_DECL))
+	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]);
+    cur->nodeNr--;
+    for (;i < cur->nodeNr;i++)
+        cur->nodeTab[i] = cur->nodeTab[i + 1];
+    cur->nodeTab[cur->nodeNr] = NULL;
+}
+
+/**
+ * xmlXPathNodeSetRemove:
+ * @cur:  the initial node set
+ * @val:  the index to remove
+ *
+ * Removes an entry from an existing NodeSet list.
+ */
+void
+xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
+    if (cur == NULL) return;
+    if (val >= cur->nodeNr) return;
+    if ((cur->nodeTab[val] != NULL) &&
+	(cur->nodeTab[val]->type == XML_NAMESPACE_DECL))
+	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]);
+    cur->nodeNr--;
+    for (;val < cur->nodeNr;val++)
+        cur->nodeTab[val] = cur->nodeTab[val + 1];
+    cur->nodeTab[cur->nodeNr] = NULL;
+}
+
+/**
+ * xmlXPathFreeNodeSet:
+ * @obj:  the xmlNodeSetPtr to free
+ *
+ * Free the NodeSet compound (not the actual nodes !).
+ */
+void
+xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
+    if (obj == NULL) return;
+    if (obj->nodeTab != NULL) {
+	int i;
+
+	/* @@ with_ns to check whether namespace nodes should be looked at @@ */
+	for (i = 0;i < obj->nodeNr;i++)
+	    if ((obj->nodeTab[i] != NULL) &&
+		(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
+		xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
+	xmlFree(obj->nodeTab);
+    }
+    xmlFree(obj);
+}
+
+/**
+ * xmlXPathNodeSetClear:
+ * @set:  the node set to clear
+ *
+ * Clears the list from all temporary XPath objects (e.g. namespace nodes
+ * are feed), but does *not* free the list itself. Sets the length of the
+ * list to 0.
+ */
+static void
+xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes)
+{
+    if ((set == NULL) || (set->nodeNr <= 0))
+	return;
+    else if (hasNsNodes) {
+	int i;
+	xmlNodePtr node;
+
+	for (i = 0; i < set->nodeNr; i++) {
+	    node = set->nodeTab[i];
+	    if ((node != NULL) &&
+		(node->type == XML_NAMESPACE_DECL))
+		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
+	}
+    }
+    set->nodeNr = 0;
+}
+
+/**
+ * xmlXPathNodeSetClearFromPos:
+ * @set: the node set to be cleared
+ * @pos: the start position to clear from
+ *
+ * Clears the list from temporary XPath objects (e.g. namespace nodes
+ * are feed) starting with the entry at @pos, but does *not* free the list
+ * itself. Sets the length of the list to @pos.
+ */
+static void
+xmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes)
+{
+    if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr))
+	return;
+    else if ((hasNsNodes)) {
+	int i;
+	xmlNodePtr node;
+
+	for (i = pos; i < set->nodeNr; i++) {
+	    node = set->nodeTab[i];
+	    if ((node != NULL) &&
+		(node->type == XML_NAMESPACE_DECL))
+		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
+	}
+    }
+    set->nodeNr = pos;
+}
+
+/**
+ * xmlXPathFreeValueTree:
+ * @obj:  the xmlNodeSetPtr to free
+ *
+ * Free the NodeSet compound and the actual tree, this is different
+ * from xmlXPathFreeNodeSet()
+ */
+static void
+xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
+    int i;
+
+    if (obj == NULL) return;
+
+    if (obj->nodeTab != NULL) {
+	for (i = 0;i < obj->nodeNr;i++) {
+	    if (obj->nodeTab[i] != NULL) {
+		if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+		    xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
+		} else {
+		    xmlFreeNodeList(obj->nodeTab[i]);
+		}
+	    }
+	}
+	xmlFree(obj->nodeTab);
+    }
+    xmlFree(obj);
+}
+
+#if defined(DEBUG) || defined(DEBUG_STEP)
+/**
+ * xmlGenericErrorContextNodeSet:
+ * @output:  a FILE * for the output
+ * @obj:  the xmlNodeSetPtr to display
+ *
+ * Quick display of a NodeSet
+ */
+void
+xmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
+    int i;
+
+    if (output == NULL) output = xmlGenericErrorContext;
+    if (obj == NULL)  {
+        fprintf(output, "NodeSet == NULL !\n");
+	return;
+    }
+    if (obj->nodeNr == 0) {
+        fprintf(output, "NodeSet is empty\n");
+	return;
+    }
+    if (obj->nodeTab == NULL) {
+	fprintf(output, " nodeTab == NULL !\n");
+	return;
+    }
+    for (i = 0; i < obj->nodeNr; i++) {
+        if (obj->nodeTab[i] == NULL) {
+	    fprintf(output, " NULL !\n");
+	    return;
+        }
+	if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
+	    (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
+	    fprintf(output, " /");
+	else if (obj->nodeTab[i]->name == NULL)
+	    fprintf(output, " noname!");
+	else fprintf(output, " %s", obj->nodeTab[i]->name);
+    }
+    fprintf(output, "\n");
+}
+#endif
+
+/**
+ * xmlXPathNewNodeSet:
+ * @val:  the NodePtr value
+ *
+ * Create a new xmlXPathObjectPtr of type NodeSet and initialize
+ * it with the single Node @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewNodeSet(xmlNodePtr val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating nodeset\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_NODESET;
+    ret->boolval = 0;
+    ret->nodesetval = xmlXPathNodeSetCreate(val);
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathNewValueTree:
+ * @val:  the NodePtr value
+ *
+ * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
+ * it with the tree root @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewValueTree(xmlNodePtr val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating result value tree\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_XSLT_TREE;
+    ret->boolval = 1;
+    ret->user = (void *) val;
+    ret->nodesetval = xmlXPathNodeSetCreate(val);
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_XSLT_TREE);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathNewNodeSetList:
+ * @val:  an existing NodeSet
+ *
+ * Create a new xmlXPathObjectPtr of type NodeSet and initialize
+ * it with the Nodeset @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewNodeSetList(xmlNodeSetPtr val)
+{
+    xmlXPathObjectPtr ret;
+    int i;
+
+    if (val == NULL)
+        ret = NULL;
+    else if (val->nodeTab == NULL)
+        ret = xmlXPathNewNodeSet(NULL);
+    else {
+        ret = xmlXPathNewNodeSet(val->nodeTab[0]);
+        if (ret)
+            for (i = 1; i < val->nodeNr; ++i)
+                xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
+    }
+
+    return (ret);
+}
+
+/**
+ * xmlXPathWrapNodeSet:
+ * @val:  the NodePtr value
+ *
+ * Wrap the Nodeset @val in a new xmlXPathObjectPtr
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating node set object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_NODESET;
+    ret->nodesetval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathFreeNodeSetList:
+ * @obj:  an existing NodeSetList object
+ *
+ * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
+ * the list contrary to xmlXPathFreeObject().
+ */
+void
+xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
+    if (obj == NULL) return;
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageReleased(NULL, obj->type);
+#endif
+    xmlFree(obj);
+}
+
+/**
+ * xmlXPathDifference:
+ * @nodes1:  a node-set
+ * @nodes2:  a node-set
+ *
+ * Implements the EXSLT - Sets difference() function:
+ *    node-set set:difference (node-set, node-set)
+ *
+ * Returns the difference between the two node sets, or nodes1 if
+ *         nodes2 is empty
+ */
+xmlNodeSetPtr
+xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    xmlNodeSetPtr ret;
+    int i, l1;
+    xmlNodePtr cur;
+
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(nodes1);
+
+    ret = xmlXPathNodeSetCreate(NULL);
+    if (xmlXPathNodeSetIsEmpty(nodes1))
+	return(ret);
+
+    l1 = xmlXPathNodeSetGetLength(nodes1);
+
+    for (i = 0; i < l1; i++) {
+	cur = xmlXPathNodeSetItem(nodes1, i);
+	if (!xmlXPathNodeSetContains(nodes2, cur))
+	    xmlXPathNodeSetAddUnique(ret, cur);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathIntersection:
+ * @nodes1:  a node-set
+ * @nodes2:  a node-set
+ *
+ * Implements the EXSLT - Sets intersection() function:
+ *    node-set set:intersection (node-set, node-set)
+ *
+ * Returns a node set comprising the nodes that are within both the
+ *         node sets passed as arguments
+ */
+xmlNodeSetPtr
+xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
+    int i, l1;
+    xmlNodePtr cur;
+
+    if (ret == NULL)
+        return(ret);
+    if (xmlXPathNodeSetIsEmpty(nodes1))
+	return(ret);
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(ret);
+
+    l1 = xmlXPathNodeSetGetLength(nodes1);
+
+    for (i = 0; i < l1; i++) {
+	cur = xmlXPathNodeSetItem(nodes1, i);
+	if (xmlXPathNodeSetContains(nodes2, cur))
+	    xmlXPathNodeSetAddUnique(ret, cur);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathDistinctSorted:
+ * @nodes:  a node-set, sorted by document order
+ *
+ * Implements the EXSLT - Sets distinct() function:
+ *    node-set set:distinct (node-set)
+ *
+ * Returns a subset of the nodes contained in @nodes, or @nodes if
+ *         it is empty
+ */
+xmlNodeSetPtr
+xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
+    xmlNodeSetPtr ret;
+    xmlHashTablePtr hash;
+    int i, l;
+    xmlChar * strval;
+    xmlNodePtr cur;
+
+    if (xmlXPathNodeSetIsEmpty(nodes))
+	return(nodes);
+
+    ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
+    l = xmlXPathNodeSetGetLength(nodes);
+    hash = xmlHashCreate (l);
+    for (i = 0; i < l; i++) {
+	cur = xmlXPathNodeSetItem(nodes, i);
+	strval = xmlXPathCastNodeToString(cur);
+	if (xmlHashLookup(hash, strval) == NULL) {
+	    xmlHashAddEntry(hash, strval, strval);
+	    xmlXPathNodeSetAddUnique(ret, cur);
+	} else {
+	    xmlFree(strval);
+	}
+    }
+    xmlHashFree(hash, (xmlHashDeallocator) xmlFree);
+    return(ret);
+}
+
+/**
+ * xmlXPathDistinct:
+ * @nodes:  a node-set
+ *
+ * Implements the EXSLT - Sets distinct() function:
+ *    node-set set:distinct (node-set)
+ * @nodes is sorted by document order, then #exslSetsDistinctSorted
+ * is called with the sorted node-set
+ *
+ * Returns a subset of the nodes contained in @nodes, or @nodes if
+ *         it is empty
+ */
+xmlNodeSetPtr
+xmlXPathDistinct (xmlNodeSetPtr nodes) {
+    if (xmlXPathNodeSetIsEmpty(nodes))
+	return(nodes);
+
+    xmlXPathNodeSetSort(nodes);
+    return(xmlXPathDistinctSorted(nodes));
+}
+
+/**
+ * xmlXPathHasSameNodes:
+ * @nodes1:  a node-set
+ * @nodes2:  a node-set
+ *
+ * Implements the EXSLT - Sets has-same-nodes function:
+ *    boolean set:has-same-node(node-set, node-set)
+ *
+ * Returns true (1) if @nodes1 shares any node with @nodes2, false (0)
+ *         otherwise
+ */
+int
+xmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    int i, l;
+    xmlNodePtr cur;
+
+    if (xmlXPathNodeSetIsEmpty(nodes1) ||
+	xmlXPathNodeSetIsEmpty(nodes2))
+	return(0);
+
+    l = xmlXPathNodeSetGetLength(nodes1);
+    for (i = 0; i < l; i++) {
+	cur = xmlXPathNodeSetItem(nodes1, i);
+	if (xmlXPathNodeSetContains(nodes2, cur))
+	    return(1);
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathNodeLeadingSorted:
+ * @nodes: a node-set, sorted by document order
+ * @node: a node
+ *
+ * Implements the EXSLT - Sets leading() function:
+ *    node-set set:leading (node-set, node-set)
+ *
+ * Returns the nodes in @nodes that precede @node in document order,
+ *         @nodes if @node is NULL or an empty node-set if @nodes
+ *         doesn't contain @node
+ */
+xmlNodeSetPtr
+xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
+    int i, l;
+    xmlNodePtr cur;
+    xmlNodeSetPtr ret;
+
+    if (node == NULL)
+	return(nodes);
+
+    ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
+    if (xmlXPathNodeSetIsEmpty(nodes) ||
+	(!xmlXPathNodeSetContains(nodes, node)))
+	return(ret);
+
+    l = xmlXPathNodeSetGetLength(nodes);
+    for (i = 0; i < l; i++) {
+	cur = xmlXPathNodeSetItem(nodes, i);
+	if (cur == node)
+	    break;
+	xmlXPathNodeSetAddUnique(ret, cur);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathNodeLeading:
+ * @nodes:  a node-set
+ * @node:  a node
+ *
+ * Implements the EXSLT - Sets leading() function:
+ *    node-set set:leading (node-set, node-set)
+ * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted
+ * is called.
+ *
+ * Returns the nodes in @nodes that precede @node in document order,
+ *         @nodes if @node is NULL or an empty node-set if @nodes
+ *         doesn't contain @node
+ */
+xmlNodeSetPtr
+xmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) {
+    xmlXPathNodeSetSort(nodes);
+    return(xmlXPathNodeLeadingSorted(nodes, node));
+}
+
+/**
+ * xmlXPathLeadingSorted:
+ * @nodes1:  a node-set, sorted by document order
+ * @nodes2:  a node-set, sorted by document order
+ *
+ * Implements the EXSLT - Sets leading() function:
+ *    node-set set:leading (node-set, node-set)
+ *
+ * Returns the nodes in @nodes1 that precede the first node in @nodes2
+ *         in document order, @nodes1 if @nodes2 is NULL or empty or
+ *         an empty node-set if @nodes1 doesn't contain @nodes2
+ */
+xmlNodeSetPtr
+xmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(nodes1);
+    return(xmlXPathNodeLeadingSorted(nodes1,
+				     xmlXPathNodeSetItem(nodes2, 1)));
+}
+
+/**
+ * xmlXPathLeading:
+ * @nodes1:  a node-set
+ * @nodes2:  a node-set
+ *
+ * Implements the EXSLT - Sets leading() function:
+ *    node-set set:leading (node-set, node-set)
+ * @nodes1 and @nodes2 are sorted by document order, then
+ * #exslSetsLeadingSorted is called.
+ *
+ * Returns the nodes in @nodes1 that precede the first node in @nodes2
+ *         in document order, @nodes1 if @nodes2 is NULL or empty or
+ *         an empty node-set if @nodes1 doesn't contain @nodes2
+ */
+xmlNodeSetPtr
+xmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(nodes1);
+    if (xmlXPathNodeSetIsEmpty(nodes1))
+	return(xmlXPathNodeSetCreate(NULL));
+    xmlXPathNodeSetSort(nodes1);
+    xmlXPathNodeSetSort(nodes2);
+    return(xmlXPathNodeLeadingSorted(nodes1,
+				     xmlXPathNodeSetItem(nodes2, 1)));
+}
+
+/**
+ * xmlXPathNodeTrailingSorted:
+ * @nodes: a node-set, sorted by document order
+ * @node: a node
+ *
+ * Implements the EXSLT - Sets trailing() function:
+ *    node-set set:trailing (node-set, node-set)
+ *
+ * Returns the nodes in @nodes that follow @node in document order,
+ *         @nodes if @node is NULL or an empty node-set if @nodes
+ *         doesn't contain @node
+ */
+xmlNodeSetPtr
+xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
+    int i, l;
+    xmlNodePtr cur;
+    xmlNodeSetPtr ret;
+
+    if (node == NULL)
+	return(nodes);
+
+    ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
+    if (xmlXPathNodeSetIsEmpty(nodes) ||
+	(!xmlXPathNodeSetContains(nodes, node)))
+	return(ret);
+
+    l = xmlXPathNodeSetGetLength(nodes);
+    for (i = l - 1; i >= 0; i--) {
+	cur = xmlXPathNodeSetItem(nodes, i);
+	if (cur == node)
+	    break;
+	xmlXPathNodeSetAddUnique(ret, cur);
+    }
+    xmlXPathNodeSetSort(ret);	/* bug 413451 */
+    return(ret);
+}
+
+/**
+ * xmlXPathNodeTrailing:
+ * @nodes:  a node-set
+ * @node:  a node
+ *
+ * Implements the EXSLT - Sets trailing() function:
+ *    node-set set:trailing (node-set, node-set)
+ * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted
+ * is called.
+ *
+ * Returns the nodes in @nodes that follow @node in document order,
+ *         @nodes if @node is NULL or an empty node-set if @nodes
+ *         doesn't contain @node
+ */
+xmlNodeSetPtr
+xmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) {
+    xmlXPathNodeSetSort(nodes);
+    return(xmlXPathNodeTrailingSorted(nodes, node));
+}
+
+/**
+ * xmlXPathTrailingSorted:
+ * @nodes1:  a node-set, sorted by document order
+ * @nodes2:  a node-set, sorted by document order
+ *
+ * Implements the EXSLT - Sets trailing() function:
+ *    node-set set:trailing (node-set, node-set)
+ *
+ * Returns the nodes in @nodes1 that follow the first node in @nodes2
+ *         in document order, @nodes1 if @nodes2 is NULL or empty or
+ *         an empty node-set if @nodes1 doesn't contain @nodes2
+ */
+xmlNodeSetPtr
+xmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(nodes1);
+    return(xmlXPathNodeTrailingSorted(nodes1,
+				      xmlXPathNodeSetItem(nodes2, 0)));
+}
+
+/**
+ * xmlXPathTrailing:
+ * @nodes1:  a node-set
+ * @nodes2:  a node-set
+ *
+ * Implements the EXSLT - Sets trailing() function:
+ *    node-set set:trailing (node-set, node-set)
+ * @nodes1 and @nodes2 are sorted by document order, then
+ * #xmlXPathTrailingSorted is called.
+ *
+ * Returns the nodes in @nodes1 that follow the first node in @nodes2
+ *         in document order, @nodes1 if @nodes2 is NULL or empty or
+ *         an empty node-set if @nodes1 doesn't contain @nodes2
+ */
+xmlNodeSetPtr
+xmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+    if (xmlXPathNodeSetIsEmpty(nodes2))
+	return(nodes1);
+    if (xmlXPathNodeSetIsEmpty(nodes1))
+	return(xmlXPathNodeSetCreate(NULL));
+    xmlXPathNodeSetSort(nodes1);
+    xmlXPathNodeSetSort(nodes2);
+    return(xmlXPathNodeTrailingSorted(nodes1,
+				      xmlXPathNodeSetItem(nodes2, 0)));
+}
+
+/************************************************************************
+ *									*
+ *		Routines to handle extra functions			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathRegisterFunc:
+ * @ctxt:  the XPath context
+ * @name:  the function name
+ * @f:  the function implementation or NULL
+ *
+ * Register a new function. If @f is NULL it unregisters the function
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
+		     xmlXPathFunction f) {
+    return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
+}
+
+/**
+ * xmlXPathRegisterFuncNS:
+ * @ctxt:  the XPath context
+ * @name:  the function name
+ * @ns_uri:  the function namespace URI
+ * @f:  the function implementation or NULL
+ *
+ * Register a new function. If @f is NULL it unregisters the function
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
+		       const xmlChar *ns_uri, xmlXPathFunction f) {
+    if (ctxt == NULL)
+	return(-1);
+    if (name == NULL)
+	return(-1);
+
+    if (ctxt->funcHash == NULL)
+	ctxt->funcHash = xmlHashCreate(0);
+    if (ctxt->funcHash == NULL)
+	return(-1);
+    if (f == NULL)
+        return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL));
+    return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f)));
+}
+
+/**
+ * xmlXPathRegisterFuncLookup:
+ * @ctxt:  the XPath context
+ * @f:  the lookup function
+ * @funcCtxt:  the lookup data
+ *
+ * Registers an external mechanism to do function lookup.
+ */
+void
+xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
+			    xmlXPathFuncLookupFunc f,
+			    void *funcCtxt) {
+    if (ctxt == NULL)
+	return;
+    ctxt->funcLookupFunc = f;
+    ctxt->funcLookupData = funcCtxt;
+}
+
+/**
+ * xmlXPathFunctionLookup:
+ * @ctxt:  the XPath context
+ * @name:  the function name
+ *
+ * Search in the Function array of the context for the given
+ * function.
+ *
+ * Returns the xmlXPathFunction or NULL if not found
+ */
+xmlXPathFunction
+xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
+    if (ctxt == NULL)
+	return (NULL);
+
+    if (ctxt->funcLookupFunc != NULL) {
+	xmlXPathFunction ret;
+	xmlXPathFuncLookupFunc f;
+
+	f = ctxt->funcLookupFunc;
+	ret = f(ctxt->funcLookupData, name, NULL);
+	if (ret != NULL)
+	    return(ret);
+    }
+    return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
+}
+
+/**
+ * xmlXPathFunctionLookupNS:
+ * @ctxt:  the XPath context
+ * @name:  the function name
+ * @ns_uri:  the function namespace URI
+ *
+ * Search in the Function array of the context for the given
+ * function.
+ *
+ * Returns the xmlXPathFunction or NULL if not found
+ */
+xmlXPathFunction
+xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
+			 const xmlChar *ns_uri) {
+    xmlXPathFunction ret;
+
+    if (ctxt == NULL)
+	return(NULL);
+    if (name == NULL)
+	return(NULL);
+
+    if (ctxt->funcLookupFunc != NULL) {
+	xmlXPathFuncLookupFunc f;
+
+	f = ctxt->funcLookupFunc;
+	ret = f(ctxt->funcLookupData, name, ns_uri);
+	if (ret != NULL)
+	    return(ret);
+    }
+
+    if (ctxt->funcHash == NULL)
+	return(NULL);
+
+    XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri);
+    return(ret);
+}
+
+/**
+ * xmlXPathRegisteredFuncsCleanup:
+ * @ctxt:  the XPath context
+ *
+ * Cleanup the XPath context data associated to registered functions
+ */
+void
+xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
+    if (ctxt == NULL)
+	return;
+
+    xmlHashFree(ctxt->funcHash, NULL);
+    ctxt->funcHash = NULL;
+}
+
+/************************************************************************
+ *									*
+ *			Routines to handle Variables			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathRegisterVariable:
+ * @ctxt:  the XPath context
+ * @name:  the variable name
+ * @value:  the variable value or NULL
+ *
+ * Register a new variable value. If @value is NULL it unregisters
+ * the variable
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
+			 xmlXPathObjectPtr value) {
+    return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
+}
+
+/**
+ * xmlXPathRegisterVariableNS:
+ * @ctxt:  the XPath context
+ * @name:  the variable name
+ * @ns_uri:  the variable namespace URI
+ * @value:  the variable value or NULL
+ *
+ * Register a new variable value. If @value is NULL it unregisters
+ * the variable
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
+			   const xmlChar *ns_uri,
+			   xmlXPathObjectPtr value) {
+    if (ctxt == NULL)
+	return(-1);
+    if (name == NULL)
+	return(-1);
+
+    if (ctxt->varHash == NULL)
+	ctxt->varHash = xmlHashCreate(0);
+    if (ctxt->varHash == NULL)
+	return(-1);
+    if (value == NULL)
+        return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri,
+	                           (xmlHashDeallocator)xmlXPathFreeObject));
+    return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
+			       (void *) value,
+			       (xmlHashDeallocator)xmlXPathFreeObject));
+}
+
+/**
+ * xmlXPathRegisterVariableLookup:
+ * @ctxt:  the XPath context
+ * @f:  the lookup function
+ * @data:  the lookup data
+ *
+ * register an external mechanism to do variable lookup
+ */
+void
+xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
+	 xmlXPathVariableLookupFunc f, void *data) {
+    if (ctxt == NULL)
+	return;
+    ctxt->varLookupFunc = f;
+    ctxt->varLookupData = data;
+}
+
+/**
+ * xmlXPathVariableLookup:
+ * @ctxt:  the XPath context
+ * @name:  the variable name
+ *
+ * Search in the Variable array of the context for the given
+ * variable value.
+ *
+ * Returns a copy of the value or NULL if not found
+ */
+xmlXPathObjectPtr
+xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
+    if (ctxt == NULL)
+	return(NULL);
+
+    if (ctxt->varLookupFunc != NULL) {
+	xmlXPathObjectPtr ret;
+
+	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
+	        (ctxt->varLookupData, name, NULL);
+	return(ret);
+    }
+    return(xmlXPathVariableLookupNS(ctxt, name, NULL));
+}
+
+/**
+ * xmlXPathVariableLookupNS:
+ * @ctxt:  the XPath context
+ * @name:  the variable name
+ * @ns_uri:  the variable namespace URI
+ *
+ * Search in the Variable array of the context for the given
+ * variable value.
+ *
+ * Returns the a copy of the value or NULL if not found
+ */
+xmlXPathObjectPtr
+xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
+			 const xmlChar *ns_uri) {
+    if (ctxt == NULL)
+	return(NULL);
+
+    if (ctxt->varLookupFunc != NULL) {
+	xmlXPathObjectPtr ret;
+
+	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
+	        (ctxt->varLookupData, name, ns_uri);
+	if (ret != NULL) return(ret);
+    }
+
+    if (ctxt->varHash == NULL)
+	return(NULL);
+    if (name == NULL)
+	return(NULL);
+
+    return(xmlXPathCacheObjectCopy(ctxt, (xmlXPathObjectPtr)
+		xmlHashLookup2(ctxt->varHash, name, ns_uri)));
+}
+
+/**
+ * xmlXPathRegisteredVariablesCleanup:
+ * @ctxt:  the XPath context
+ *
+ * Cleanup the XPath context data associated to registered variables
+ */
+void
+xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
+    if (ctxt == NULL)
+	return;
+
+    xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
+    ctxt->varHash = NULL;
+}
+
+/**
+ * xmlXPathRegisterNs:
+ * @ctxt:  the XPath context
+ * @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
+ * 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 (prefix[0] == 0)
+	return(-1);
+
+    if (ctxt->nsHash == NULL)
+	ctxt->nsHash = xmlHashCreate(10);
+    if (ctxt->nsHash == NULL)
+	return(-1);
+    if (ns_uri == NULL)
+        return(xmlHashRemoveEntry(ctxt->nsHash, prefix,
+	                          (xmlHashDeallocator)xmlFree));
+    return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(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);
+
+#ifdef XML_XML_NAMESPACE
+    if (xmlStrEqual(prefix, (const xmlChar *) "xml"))
+	return(XML_XML_NAMESPACE);
+#endif
+
+    if (ctxt->namespaces != NULL) {
+	int i;
+
+	for (i = 0;i < ctxt->nsNr;i++) {
+	    if ((ctxt->namespaces[i] != NULL) &&
+		(xmlStrEqual(ctxt->namespaces[i]->prefix, prefix)))
+		return(ctxt->namespaces[i]->href);
+	}
+    }
+
+    return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
+}
+
+/**
+ * xmlXPathRegisteredNsCleanup:
+ * @ctxt:  the XPath context
+ *
+ * Cleanup the XPath context data associated to registered variables
+ */
+void
+xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
+    if (ctxt == NULL)
+	return;
+
+    xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree);
+    ctxt->nsHash = NULL;
+}
+
+/************************************************************************
+ *									*
+ *			Routines to handle Values			*
+ *									*
+ ************************************************************************/
+
+/* Allocations are terrible, one needs to optimize all this !!! */
+
+/**
+ * xmlXPathNewFloat:
+ * @val:  the double value
+ *
+ * Create a new xmlXPathObjectPtr of type double and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewFloat(double val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating float object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_NUMBER;
+    ret->floatval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_NUMBER);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathNewBoolean:
+ * @val:  the boolean value
+ *
+ * Create a new xmlXPathObjectPtr of type boolean and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewBoolean(int val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating boolean object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_BOOLEAN;
+    ret->boolval = (val != 0);
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_BOOLEAN);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathNewString:
+ * @val:  the xmlChar * value
+ *
+ * Create a new xmlXPathObjectPtr of type string and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewString(const xmlChar *val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating string object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_STRING;
+    if (val != NULL)
+	ret->stringval = xmlStrdup(val);
+    else
+	ret->stringval = xmlStrdup((const xmlChar *)"");
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathWrapString:
+ * @val:  the xmlChar * value
+ *
+ * Wraps the @val string into an XPath object.
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathWrapString (xmlChar *val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating string object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_STRING;
+    ret->stringval = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathNewCString:
+ * @val:  the char * value
+ *
+ * Create a new xmlXPathObjectPtr of type string and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathNewCString(const char *val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating string object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_STRING;
+    ret->stringval = xmlStrdup(BAD_CAST val);
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathWrapCString:
+ * @val:  the char * value
+ *
+ * Wraps a string into an XPath object.
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathWrapCString (char * val) {
+    return(xmlXPathWrapString((xmlChar *)(val)));
+}
+
+/**
+ * xmlXPathWrapExternal:
+ * @val:  the user data
+ *
+ * Wraps the @val data into an XPath object.
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathWrapExternal (void *val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating user object\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_USERS;
+    ret->user = val;
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, XPATH_USERS);
+#endif
+    return(ret);
+}
+
+/**
+ * xmlXPathObjectCopy:
+ * @val:  the original object
+ *
+ * allocate a new copy of a given object
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPathObjectCopy(xmlXPathObjectPtr val) {
+    xmlXPathObjectPtr ret;
+
+    if (val == NULL)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "copying object\n");
+	return(NULL);
+    }
+    memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageRequested(NULL, val->type);
+#endif
+    switch (val->type) {
+	case XPATH_BOOLEAN:
+	case XPATH_NUMBER:
+	case XPATH_POINT:
+	case XPATH_RANGE:
+	    break;
+	case XPATH_STRING:
+	    ret->stringval = xmlStrdup(val->stringval);
+	    break;
+	case XPATH_XSLT_TREE:
+#if 0
+/*
+  Removed 11 July 2004 - the current handling of xslt tmpRVT nodes means that
+  this previous handling is no longer correct, and can cause some serious
+  problems (ref. bug 145547)
+*/
+	    if ((val->nodesetval != NULL) &&
+		(val->nodesetval->nodeTab != NULL)) {
+		xmlNodePtr cur, tmp;
+		xmlDocPtr top;
+
+		ret->boolval = 1;
+		top =  xmlNewDoc(NULL);
+		top->name = (char *)
+		    xmlStrdup(val->nodesetval->nodeTab[0]->name);
+		ret->user = top;
+		if (top != NULL) {
+		    top->doc = top;
+		    cur = val->nodesetval->nodeTab[0]->children;
+		    while (cur != NULL) {
+			tmp = xmlDocCopyNode(cur, top, 1);
+			xmlAddChild((xmlNodePtr) top, tmp);
+			cur = cur->next;
+		    }
+		}
+
+		ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top);
+	    } else
+		ret->nodesetval = xmlXPathNodeSetCreate(NULL);
+	    /* Deallocate the copied tree value */
+	    break;
+#endif
+	case XPATH_NODESET:
+	    ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
+	    /* Do not deallocate the copied tree value */
+	    ret->boolval = 0;
+	    break;
+	case XPATH_LOCATIONSET:
+#ifdef LIBXML_XPTR_ENABLED
+	{
+	    xmlLocationSetPtr loc = val->user;
+	    ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
+	    break;
+	}
+#endif
+        case XPATH_USERS:
+	    ret->user = val->user;
+	    break;
+        case XPATH_UNDEFINED:
+	    xmlGenericError(xmlGenericErrorContext,
+		    "xmlXPathObjectCopy: unsupported type %d\n",
+		    val->type);
+	    break;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathFreeObject:
+ * @obj:  the object to free
+ *
+ * Free up an xmlXPathObjectPtr object.
+ */
+void
+xmlXPathFreeObject(xmlXPathObjectPtr obj) {
+    if (obj == NULL) return;
+    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
+	if (obj->boolval) {
+#if 0
+	    if (obj->user != NULL) {
+                xmlXPathFreeNodeSet(obj->nodesetval);
+		xmlFreeNodeList((xmlNodePtr) obj->user);
+	    } else
+#endif
+	    obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */
+	    if (obj->nodesetval != NULL)
+		xmlXPathFreeValueTree(obj->nodesetval);
+	} else {
+	    if (obj->nodesetval != NULL)
+		xmlXPathFreeNodeSet(obj->nodesetval);
+	}
+#ifdef LIBXML_XPTR_ENABLED
+    } else if (obj->type == XPATH_LOCATIONSET) {
+	if (obj->user != NULL)
+	    xmlXPtrFreeLocationSet(obj->user);
+#endif
+    } else if (obj->type == XPATH_STRING) {
+	if (obj->stringval != NULL)
+	    xmlFree(obj->stringval);
+    }
+#ifdef XP_DEBUG_OBJ_USAGE
+    xmlXPathDebugObjUsageReleased(NULL, obj->type);
+#endif
+    xmlFree(obj);
+}
+
+/**
+ * xmlXPathReleaseObject:
+ * @obj:  the xmlXPathObjectPtr to free or to cache
+ *
+ * Depending on the state of the cache this frees the given
+ * XPath object or stores it in the cache.
+ */
+static void
+xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj)
+{
+#define XP_CACHE_ADD(sl, o) if (sl == NULL) { \
+	sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \
+    if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj;
+
+#define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n))
+
+    if (obj == NULL)
+	return;
+    if ((ctxt == NULL) || (ctxt->cache == NULL)) {
+	 xmlXPathFreeObject(obj);
+    } else {
+	xmlXPathContextCachePtr cache =
+	    (xmlXPathContextCachePtr) ctxt->cache;
+
+	switch (obj->type) {
+	    case XPATH_NODESET:
+	    case XPATH_XSLT_TREE:
+		if (obj->nodesetval != NULL) {
+		    if (obj->boolval) {
+			/*
+			* It looks like the @boolval is used for
+			* evaluation if this an XSLT Result Tree Fragment.
+			* TODO: Check if this assumption is correct.
+			*/
+			obj->type = XPATH_XSLT_TREE; /* just for debugging */
+			xmlXPathFreeValueTree(obj->nodesetval);
+			obj->nodesetval = NULL;
+		    } else if ((obj->nodesetval->nodeMax <= 40) &&
+			(XP_CACHE_WANTS(cache->nodesetObjs,
+					cache->maxNodeset)))
+		    {
+			XP_CACHE_ADD(cache->nodesetObjs, obj);
+			goto obj_cached;
+		    } else {
+			xmlXPathFreeNodeSet(obj->nodesetval);
+			obj->nodesetval = NULL;
+		    }
+		}
+		break;
+	    case XPATH_STRING:
+		if (obj->stringval != NULL)
+		    xmlFree(obj->stringval);
+
+		if (XP_CACHE_WANTS(cache->stringObjs, cache->maxString)) {
+		    XP_CACHE_ADD(cache->stringObjs, obj);
+		    goto obj_cached;
+		}
+		break;
+	    case XPATH_BOOLEAN:
+		if (XP_CACHE_WANTS(cache->booleanObjs, cache->maxBoolean)) {
+		    XP_CACHE_ADD(cache->booleanObjs, obj);
+		    goto obj_cached;
+		}
+		break;
+	    case XPATH_NUMBER:
+		if (XP_CACHE_WANTS(cache->numberObjs, cache->maxNumber)) {
+		    XP_CACHE_ADD(cache->numberObjs, obj);
+		    goto obj_cached;
+		}
+		break;
+#ifdef LIBXML_XPTR_ENABLED
+	    case XPATH_LOCATIONSET:
+		if (obj->user != NULL) {
+		    xmlXPtrFreeLocationSet(obj->user);
+		}
+		goto free_obj;
+#endif
+	    default:
+		goto free_obj;
+	}
+
+	/*
+	* Fallback to adding to the misc-objects slot.
+	*/
+	if (XP_CACHE_WANTS(cache->miscObjs, cache->maxMisc)) {
+	    XP_CACHE_ADD(cache->miscObjs, obj);
+	} else
+	    goto free_obj;
+
+obj_cached:
+
+#ifdef XP_DEBUG_OBJ_USAGE
+	xmlXPathDebugObjUsageReleased(ctxt, obj->type);
+#endif
+
+	if (obj->nodesetval != NULL) {
+	    xmlNodeSetPtr tmpset = obj->nodesetval;
+
+	    /*
+	    * TODO: Due to those nasty ns-nodes, we need to traverse
+	    *  the list and free the ns-nodes.
+	    * URGENT TODO: Check if it's actually slowing things down.
+	    *  Maybe we shouldn't try to preserve the list.
+	    */
+	    if (tmpset->nodeNr > 1) {
+		int i;
+		xmlNodePtr node;
+
+		for (i = 0; i < tmpset->nodeNr; i++) {
+		    node = tmpset->nodeTab[i];
+		    if ((node != NULL) &&
+			(node->type == XML_NAMESPACE_DECL))
+		    {
+			xmlXPathNodeSetFreeNs((xmlNsPtr) node);
+		    }
+		}
+	    } else if (tmpset->nodeNr == 1) {
+		if ((tmpset->nodeTab[0] != NULL) &&
+		    (tmpset->nodeTab[0]->type == XML_NAMESPACE_DECL))
+		    xmlXPathNodeSetFreeNs((xmlNsPtr) tmpset->nodeTab[0]);
+	    }
+	    tmpset->nodeNr = 0;
+	    memset(obj, 0, sizeof(xmlXPathObject));
+	    obj->nodesetval = tmpset;
+	} else
+	    memset(obj, 0, sizeof(xmlXPathObject));
+
+	return;
+
+free_obj:
+	/*
+	* Cache is full; free the object.
+	*/
+	if (obj->nodesetval != NULL)
+	    xmlXPathFreeNodeSet(obj->nodesetval);
+#ifdef XP_DEBUG_OBJ_USAGE
+	xmlXPathDebugObjUsageReleased(NULL, obj->type);
+#endif
+	xmlFree(obj);
+    }
+    return;
+}
+
+
+/************************************************************************
+ *									*
+ *			Type Casting Routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathCastBooleanToString:
+ * @val:  a boolean
+ *
+ * Converts a boolean to its string value.
+ *
+ * Returns a newly allocated string.
+ */
+xmlChar *
+xmlXPathCastBooleanToString (int val) {
+    xmlChar *ret;
+    if (val)
+	ret = xmlStrdup((const xmlChar *) "true");
+    else
+	ret = xmlStrdup((const xmlChar *) "false");
+    return(ret);
+}
+
+/**
+ * xmlXPathCastNumberToString:
+ * @val:  a number
+ *
+ * Converts a number to its string value.
+ *
+ * Returns a newly allocated string.
+ */
+xmlChar *
+xmlXPathCastNumberToString (double val) {
+    xmlChar *ret;
+    switch (xmlXPathIsInf(val)) {
+    case 1:
+	ret = xmlStrdup((const xmlChar *) "Infinity");
+	break;
+    case -1:
+	ret = xmlStrdup((const xmlChar *) "-Infinity");
+	break;
+    default:
+	if (xmlXPathIsNaN(val)) {
+	    ret = xmlStrdup((const xmlChar *) "NaN");
+	} else if (val == 0 && xmlXPathGetSign(val) != 0) {
+	    ret = xmlStrdup((const xmlChar *) "0");
+	} else {
+	    /* could be improved */
+	    char buf[100];
+	    xmlXPathFormatNumber(val, buf, 99);
+	    buf[99] = 0;
+	    ret = xmlStrdup((const xmlChar *) buf);
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathCastNodeToString:
+ * @node:  a node
+ *
+ * Converts a node to its string value.
+ *
+ * Returns a newly allocated string.
+ */
+xmlChar *
+xmlXPathCastNodeToString (xmlNodePtr node) {
+xmlChar *ret;
+    if ((ret = xmlNodeGetContent(node)) == NULL)
+	ret = xmlStrdup((const xmlChar *) "");
+    return(ret);
+}
+
+/**
+ * xmlXPathCastNodeSetToString:
+ * @ns:  a node-set
+ *
+ * Converts a node-set to its string value.
+ *
+ * Returns a newly allocated string.
+ */
+xmlChar *
+xmlXPathCastNodeSetToString (xmlNodeSetPtr ns) {
+    if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL))
+	return(xmlStrdup((const xmlChar *) ""));
+
+    if (ns->nodeNr > 1)
+	xmlXPathNodeSetSort(ns);
+    return(xmlXPathCastNodeToString(ns->nodeTab[0]));
+}
+
+/**
+ * xmlXPathCastToString:
+ * @val:  an XPath object
+ *
+ * Converts an existing object to its string() equivalent
+ *
+ * Returns the allocated string value of the object, NULL in case of error.
+ *         It's up to the caller to free the string memory with xmlFree().
+ */
+xmlChar *
+xmlXPathCastToString(xmlXPathObjectPtr val) {
+    xmlChar *ret = NULL;
+
+    if (val == NULL)
+	return(xmlStrdup((const xmlChar *) ""));
+    switch (val->type) {
+	case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+	    xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
+#endif
+	    ret = xmlStrdup((const xmlChar *) "");
+	    break;
+        case XPATH_NODESET:
+        case XPATH_XSLT_TREE:
+	    ret = xmlXPathCastNodeSetToString(val->nodesetval);
+	    break;
+	case XPATH_STRING:
+	    return(xmlStrdup(val->stringval));
+        case XPATH_BOOLEAN:
+	    ret = xmlXPathCastBooleanToString(val->boolval);
+	    break;
+	case XPATH_NUMBER: {
+	    ret = xmlXPathCastNumberToString(val->floatval);
+	    break;
+	}
+	case XPATH_USERS:
+	case XPATH_POINT:
+	case XPATH_RANGE:
+	case XPATH_LOCATIONSET:
+	    TODO
+	    ret = xmlStrdup((const xmlChar *) "");
+	    break;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathConvertString:
+ * @val:  an XPath object
+ *
+ * Converts an existing object to its string() equivalent
+ *
+ * Returns the new object, the old one is freed (or the operation
+ *         is done directly on @val)
+ */
+xmlXPathObjectPtr
+xmlXPathConvertString(xmlXPathObjectPtr val) {
+    xmlChar *res = NULL;
+
+    if (val == NULL)
+	return(xmlXPathNewCString(""));
+
+    switch (val->type) {
+    case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
+#endif
+	break;
+    case XPATH_NODESET:
+    case XPATH_XSLT_TREE:
+	res = xmlXPathCastNodeSetToString(val->nodesetval);
+	break;
+    case XPATH_STRING:
+	return(val);
+    case XPATH_BOOLEAN:
+	res = xmlXPathCastBooleanToString(val->boolval);
+	break;
+    case XPATH_NUMBER:
+	res = xmlXPathCastNumberToString(val->floatval);
+	break;
+    case XPATH_USERS:
+    case XPATH_POINT:
+    case XPATH_RANGE:
+    case XPATH_LOCATIONSET:
+	TODO;
+	break;
+    }
+    xmlXPathFreeObject(val);
+    if (res == NULL)
+	return(xmlXPathNewCString(""));
+    return(xmlXPathWrapString(res));
+}
+
+/**
+ * xmlXPathCastBooleanToNumber:
+ * @val:  a boolean
+ *
+ * Converts a boolean to its number value
+ *
+ * Returns the number value
+ */
+double
+xmlXPathCastBooleanToNumber(int val) {
+    if (val)
+	return(1.0);
+    return(0.0);
+}
+
+/**
+ * xmlXPathCastStringToNumber:
+ * @val:  a string
+ *
+ * Converts a string to its number value
+ *
+ * Returns the number value
+ */
+double
+xmlXPathCastStringToNumber(const xmlChar * val) {
+    return(xmlXPathStringEvalNumber(val));
+}
+
+/**
+ * xmlXPathCastNodeToNumber:
+ * @node:  a node
+ *
+ * Converts a node to its number value
+ *
+ * Returns the number value
+ */
+double
+xmlXPathCastNodeToNumber (xmlNodePtr node) {
+    xmlChar *strval;
+    double ret;
+
+    if (node == NULL)
+	return(xmlXPathNAN);
+    strval = xmlXPathCastNodeToString(node);
+    if (strval == NULL)
+	return(xmlXPathNAN);
+    ret = xmlXPathCastStringToNumber(strval);
+    xmlFree(strval);
+
+    return(ret);
+}
+
+/**
+ * xmlXPathCastNodeSetToNumber:
+ * @ns:  a node-set
+ *
+ * Converts a node-set to its number value
+ *
+ * Returns the number value
+ */
+double
+xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
+    xmlChar *str;
+    double ret;
+
+    if (ns == NULL)
+	return(xmlXPathNAN);
+    str = xmlXPathCastNodeSetToString(ns);
+    ret = xmlXPathCastStringToNumber(str);
+    xmlFree(str);
+    return(ret);
+}
+
+/**
+ * xmlXPathCastToNumber:
+ * @val:  an XPath object
+ *
+ * Converts an XPath object to its number value
+ *
+ * Returns the number value
+ */
+double
+xmlXPathCastToNumber(xmlXPathObjectPtr val) {
+    double ret = 0.0;
+
+    if (val == NULL)
+	return(xmlXPathNAN);
+    switch (val->type) {
+    case XPATH_UNDEFINED:
+#ifdef DEGUB_EXPR
+	xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
+#endif
+	ret = xmlXPathNAN;
+	break;
+    case XPATH_NODESET:
+    case XPATH_XSLT_TREE:
+	ret = xmlXPathCastNodeSetToNumber(val->nodesetval);
+	break;
+    case XPATH_STRING:
+	ret = xmlXPathCastStringToNumber(val->stringval);
+	break;
+    case XPATH_NUMBER:
+	ret = val->floatval;
+	break;
+    case XPATH_BOOLEAN:
+	ret = xmlXPathCastBooleanToNumber(val->boolval);
+	break;
+    case XPATH_USERS:
+    case XPATH_POINT:
+    case XPATH_RANGE:
+    case XPATH_LOCATIONSET:
+	TODO;
+	ret = xmlXPathNAN;
+	break;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathConvertNumber:
+ * @val:  an XPath object
+ *
+ * Converts an existing object to its number() equivalent
+ *
+ * Returns the new object, the old one is freed (or the operation
+ *         is done directly on @val)
+ */
+xmlXPathObjectPtr
+xmlXPathConvertNumber(xmlXPathObjectPtr val) {
+    xmlXPathObjectPtr ret;
+
+    if (val == NULL)
+	return(xmlXPathNewFloat(0.0));
+    if (val->type == XPATH_NUMBER)
+	return(val);
+    ret = xmlXPathNewFloat(xmlXPathCastToNumber(val));
+    xmlXPathFreeObject(val);
+    return(ret);
+}
+
+/**
+ * xmlXPathCastNumberToBoolean:
+ * @val:  a number
+ *
+ * Converts a number to its boolean value
+ *
+ * Returns the boolean value
+ */
+int
+xmlXPathCastNumberToBoolean (double val) {
+     if (xmlXPathIsNaN(val) || (val == 0.0))
+	 return(0);
+     return(1);
+}
+
+/**
+ * xmlXPathCastStringToBoolean:
+ * @val:  a string
+ *
+ * Converts a string to its boolean value
+ *
+ * Returns the boolean value
+ */
+int
+xmlXPathCastStringToBoolean (const xmlChar *val) {
+    if ((val == NULL) || (xmlStrlen(val) == 0))
+	return(0);
+    return(1);
+}
+
+/**
+ * xmlXPathCastNodeSetToBoolean:
+ * @ns:  a node-set
+ *
+ * Converts a node-set to its boolean value
+ *
+ * Returns the boolean value
+ */
+int
+xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) {
+    if ((ns == NULL) || (ns->nodeNr == 0))
+	return(0);
+    return(1);
+}
+
+/**
+ * xmlXPathCastToBoolean:
+ * @val:  an XPath object
+ *
+ * Converts an XPath object to its boolean value
+ *
+ * Returns the boolean value
+ */
+int
+xmlXPathCastToBoolean (xmlXPathObjectPtr val) {
+    int ret = 0;
+
+    if (val == NULL)
+	return(0);
+    switch (val->type) {
+    case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+	xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
+#endif
+	ret = 0;
+	break;
+    case XPATH_NODESET:
+    case XPATH_XSLT_TREE:
+	ret = xmlXPathCastNodeSetToBoolean(val->nodesetval);
+	break;
+    case XPATH_STRING:
+	ret = xmlXPathCastStringToBoolean(val->stringval);
+	break;
+    case XPATH_NUMBER:
+	ret = xmlXPathCastNumberToBoolean(val->floatval);
+	break;
+    case XPATH_BOOLEAN:
+	ret = val->boolval;
+	break;
+    case XPATH_USERS:
+    case XPATH_POINT:
+    case XPATH_RANGE:
+    case XPATH_LOCATIONSET:
+	TODO;
+	ret = 0;
+	break;
+    }
+    return(ret);
+}
+
+
+/**
+ * xmlXPathConvertBoolean:
+ * @val:  an XPath object
+ *
+ * Converts an existing object to its boolean() equivalent
+ *
+ * Returns the new object, the old one is freed (or the operation
+ *         is done directly on @val)
+ */
+xmlXPathObjectPtr
+xmlXPathConvertBoolean(xmlXPathObjectPtr val) {
+    xmlXPathObjectPtr ret;
+
+    if (val == NULL)
+	return(xmlXPathNewBoolean(0));
+    if (val->type == XPATH_BOOLEAN)
+	return(val);
+    ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val));
+    xmlXPathFreeObject(val);
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *		Routines to handle XPath contexts			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathNewContext:
+ * @doc:  the XML document
+ *
+ * Create a new xmlXPathContext
+ *
+ * Returns the xmlXPathContext just allocated. The caller will need to free it.
+ */
+xmlXPathContextPtr
+xmlXPathNewContext(xmlDocPtr doc) {
+    xmlXPathContextPtr ret;
+
+    ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
+    if (ret == NULL) {
+        xmlXPathErrMemory(NULL, "creating context\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
+    ret->doc = doc;
+    ret->node = NULL;
+
+    ret->varHash = NULL;
+
+    ret->nb_types = 0;
+    ret->max_types = 0;
+    ret->types = NULL;
+
+    ret->funcHash = xmlHashCreate(0);
+
+    ret->nb_axis = 0;
+    ret->max_axis = 0;
+    ret->axis = NULL;
+
+    ret->nsHash = NULL;
+    ret->user = NULL;
+
+    ret->contextSize = -1;
+    ret->proximityPosition = -1;
+
+#ifdef XP_DEFAULT_CACHE_ON
+    if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
+	xmlXPathFreeContext(ret);
+	return(NULL);
+    }
+#endif
+
+    xmlXPathRegisterAllFunctions(ret);
+
+    return(ret);
+}
+
+/**
+ * xmlXPathFreeContext:
+ * @ctxt:  the context to free
+ *
+ * Free up an xmlXPathContext
+ */
+void
+xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
+    if (ctxt == NULL) return;
+
+    if (ctxt->cache != NULL)
+	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
+    xmlXPathRegisteredNsCleanup(ctxt);
+    xmlXPathRegisteredFuncsCleanup(ctxt);
+    xmlXPathRegisteredVariablesCleanup(ctxt);
+    xmlResetError(&ctxt->lastError);
+    xmlFree(ctxt);
+}
+
+/************************************************************************
+ *									*
+ *		Routines to handle XPath parser contexts		*
+ *									*
+ ************************************************************************/
+
+#define CHECK_CTXT(ctxt)						\
+    if (ctxt == NULL) {						\
+	__xmlRaiseError(NULL, NULL, NULL,				\
+		NULL, NULL, XML_FROM_XPATH,				\
+		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
+		__FILE__, __LINE__,					\
+		NULL, NULL, NULL, 0, 0,					\
+		"NULL context pointer\n");				\
+	return(NULL);							\
+    }									\
+
+#define CHECK_CTXT_NEG(ctxt)						\
+    if (ctxt == NULL) {						\
+	__xmlRaiseError(NULL, NULL, NULL,				\
+		NULL, NULL, XML_FROM_XPATH,				\
+		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
+		__FILE__, __LINE__,					\
+		NULL, NULL, NULL, 0, 0,					\
+		"NULL context pointer\n");				\
+	return(-1);							\
+    }									\
+
+
+#define CHECK_CONTEXT(ctxt)						\
+    if ((ctxt == NULL) || (ctxt->doc == NULL) ||			\
+        (ctxt->doc->children == NULL)) {				\
+	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT);	\
+	return(NULL);							\
+    }
+
+
+/**
+ * xmlXPathNewParserContext:
+ * @str:  the XPath expression
+ * @ctxt:  the XPath context
+ *
+ * Create a new xmlXPathParserContext
+ *
+ * Returns the xmlXPathParserContext just allocated.
+ */
+xmlXPathParserContextPtr
+xmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
+    xmlXPathParserContextPtr ret;
+
+    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
+    if (ret == NULL) {
+        xmlXPathErrMemory(ctxt, "creating parser context\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
+    ret->cur = ret->base = str;
+    ret->context = ctxt;
+
+    ret->comp = xmlXPathNewCompExpr();
+    if (ret->comp == NULL) {
+	xmlFree(ret->valueTab);
+	xmlFree(ret);
+	return(NULL);
+    }
+    if ((ctxt != NULL) && (ctxt->dict != NULL)) {
+        ret->comp->dict = ctxt->dict;
+	xmlDictReference(ret->comp->dict);
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlXPathCompParserContext:
+ * @comp:  the XPath compiled expression
+ * @ctxt:  the XPath context
+ *
+ * Create a new xmlXPathParserContext when processing a compiled expression
+ *
+ * Returns the xmlXPathParserContext just allocated.
+ */
+static xmlXPathParserContextPtr
+xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
+    xmlXPathParserContextPtr ret;
+
+    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
+    if (ret == NULL) {
+        xmlXPathErrMemory(ctxt, "creating evaluation context\n");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
+
+    /* Allocate the value stack */
+    ret->valueTab = (xmlXPathObjectPtr *)
+                     xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
+    if (ret->valueTab == NULL) {
+	xmlFree(ret);
+	xmlXPathErrMemory(ctxt, "creating evaluation context\n");
+	return(NULL);
+    }
+    ret->valueNr = 0;
+    ret->valueMax = 10;
+    ret->value = NULL;
+
+    ret->context = ctxt;
+    ret->comp = comp;
+
+    return(ret);
+}
+
+/**
+ * xmlXPathFreeParserContext:
+ * @ctxt:  the context to free
+ *
+ * Free up an xmlXPathParserContext
+ */
+void
+xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
+    if (ctxt->valueTab != NULL) {
+        xmlFree(ctxt->valueTab);
+    }
+    if (ctxt->comp != NULL) {
+#ifdef XPATH_STREAMING
+	if (ctxt->comp->stream != NULL) {
+	    xmlFreePatternList(ctxt->comp->stream);
+	    ctxt->comp->stream = NULL;
+	}
+#endif
+	xmlXPathFreeCompExpr(ctxt->comp);
+    }
+    xmlFree(ctxt);
+}
+
+/************************************************************************
+ *									*
+ *		The implicit core function library			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathNodeValHash:
+ * @node:  a node pointer
+ *
+ * Function computing the beginning of the string value of the node,
+ * used to speed up comparisons
+ *
+ * Returns an int usable as a hash
+ */
+static unsigned int
+xmlXPathNodeValHash(xmlNodePtr node) {
+    int len = 2;
+    const xmlChar * string = NULL;
+    xmlNodePtr tmp = NULL;
+    unsigned int ret = 0;
+
+    if (node == NULL)
+	return(0);
+
+    if (node->type == XML_DOCUMENT_NODE) {
+	tmp = xmlDocGetRootElement((xmlDocPtr) node);
+	if (tmp == NULL)
+	    node = node->children;
+	else
+	    node = tmp;
+
+	if (node == NULL)
+	    return(0);
+    }
+
+    switch (node->type) {
+	case XML_COMMENT_NODE:
+	case XML_PI_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_TEXT_NODE:
+	    string = node->content;
+	    if (string == NULL)
+		return(0);
+	    if (string[0] == 0)
+		return(0);
+	    return(((unsigned int) string[0]) +
+		   (((unsigned int) string[1]) << 8));
+	case XML_NAMESPACE_DECL:
+	    string = ((xmlNsPtr)node)->href;
+	    if (string == NULL)
+		return(0);
+	    if (string[0] == 0)
+		return(0);
+	    return(((unsigned int) string[0]) +
+		   (((unsigned int) string[1]) << 8));
+	case XML_ATTRIBUTE_NODE:
+	    tmp = ((xmlAttrPtr) node)->children;
+	    break;
+	case XML_ELEMENT_NODE:
+	    tmp = node->children;
+	    break;
+	default:
+	    return(0);
+    }
+    while (tmp != NULL) {
+	switch (tmp->type) {
+	    case XML_COMMENT_NODE:
+	    case XML_PI_NODE:
+	    case XML_CDATA_SECTION_NODE:
+	    case XML_TEXT_NODE:
+		string = tmp->content;
+		break;
+	    case XML_NAMESPACE_DECL:
+		string = ((xmlNsPtr)tmp)->href;
+		break;
+	    default:
+		break;
+	}
+	if ((string != NULL) && (string[0] != 0)) {
+	    if (len == 1) {
+		return(ret + (((unsigned int) string[0]) << 8));
+	    }
+	    if (string[1] == 0) {
+		len = 1;
+		ret = (unsigned int) string[0];
+	    } else {
+		return(((unsigned int) string[0]) +
+		       (((unsigned int) string[1]) << 8));
+	    }
+	}
+	/*
+	 * Skip to next node
+	 */
+	if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) {
+	    if (tmp->children->type != XML_ENTITY_DECL) {
+		tmp = tmp->children;
+		continue;
+	    }
+	}
+	if (tmp == node)
+	    break;
+
+	if (tmp->next != NULL) {
+	    tmp = tmp->next;
+	    continue;
+	}
+
+	do {
+	    tmp = tmp->parent;
+	    if (tmp == NULL)
+		break;
+	    if (tmp == node) {
+		tmp = NULL;
+		break;
+	    }
+	    if (tmp->next != NULL) {
+		tmp = tmp->next;
+		break;
+	    }
+	} while (tmp != NULL);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathStringHash:
+ * @string:  a string
+ *
+ * Function computing the beginning of the string value of the node,
+ * used to speed up comparisons
+ *
+ * Returns an int usable as a hash
+ */
+static unsigned int
+xmlXPathStringHash(const xmlChar * string) {
+    if (string == NULL)
+	return((unsigned int) 0);
+    if (string[0] == 0)
+	return(0);
+    return(((unsigned int) string[0]) +
+	   (((unsigned int) string[1]) << 8));
+}
+
+/**
+ * xmlXPathCompareNodeSetFloat:
+ * @ctxt:  the XPath Parser context
+ * @inf:  less than (1) or greater than (0)
+ * @strict:  is the comparison strict
+ * @arg:  the node set
+ * @f:  the value
+ *
+ * Implement the compare operation between a nodeset and a number
+ *     @ns < @val    (1, 1, ...
+ *     @ns <= @val   (1, 0, ...
+ *     @ns > @val    (0, 1, ...
+ *     @ns >= @val   (0, 0, ...
+ *
+ * If one object to be compared is a node-set and the other is a number,
+ * then the comparison will be true if and only if there is a node in the
+ * node-set such that the result of performing the comparison on the number
+ * to be compared and on the result of converting the string-value of that
+ * node to a number using the number function is true.
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
+	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
+    int i, ret = 0;
+    xmlNodeSetPtr ns;
+    xmlChar *str2;
+
+    if ((f == NULL) || (arg == NULL) ||
+	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
+	xmlXPathReleaseObject(ctxt->context, arg);
+	xmlXPathReleaseObject(ctxt->context, f);
+        return(0);
+    }
+    ns = arg->nodesetval;
+    if (ns != NULL) {
+	for (i = 0;i < ns->nodeNr;i++) {
+	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
+	     if (str2 != NULL) {
+		 valuePush(ctxt,
+			   xmlXPathCacheNewString(ctxt->context, str2));
+		 xmlFree(str2);
+		 xmlXPathNumberFunction(ctxt, 1);
+		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, f));
+		 ret = xmlXPathCompareValues(ctxt, inf, strict);
+		 if (ret)
+		     break;
+	     }
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, arg);
+    xmlXPathReleaseObject(ctxt->context, f);
+    return(ret);
+}
+
+/**
+ * xmlXPathCompareNodeSetString:
+ * @ctxt:  the XPath Parser context
+ * @inf:  less than (1) or greater than (0)
+ * @strict:  is the comparison strict
+ * @arg:  the node set
+ * @s:  the value
+ *
+ * Implement the compare operation between a nodeset and a string
+ *     @ns < @val    (1, 1, ...
+ *     @ns <= @val   (1, 0, ...
+ *     @ns > @val    (0, 1, ...
+ *     @ns >= @val   (0, 0, ...
+ *
+ * If one object to be compared is a node-set and the other is a string,
+ * then the comparison will be true if and only if there is a node in
+ * the node-set such that the result of performing the comparison on the
+ * string-value of the node and the other string is true.
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
+	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
+    int i, ret = 0;
+    xmlNodeSetPtr ns;
+    xmlChar *str2;
+
+    if ((s == NULL) || (arg == NULL) ||
+	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
+	xmlXPathReleaseObject(ctxt->context, arg);
+	xmlXPathReleaseObject(ctxt->context, s);
+        return(0);
+    }
+    ns = arg->nodesetval;
+    if (ns != NULL) {
+	for (i = 0;i < ns->nodeNr;i++) {
+	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
+	     if (str2 != NULL) {
+		 valuePush(ctxt,
+			   xmlXPathCacheNewString(ctxt->context, str2));
+		 xmlFree(str2);
+		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, s));
+		 ret = xmlXPathCompareValues(ctxt, inf, strict);
+		 if (ret)
+		     break;
+	     }
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, arg);
+    xmlXPathReleaseObject(ctxt->context, s);
+    return(ret);
+}
+
+/**
+ * xmlXPathCompareNodeSets:
+ * @inf:  less than (1) or greater than (0)
+ * @strict:  is the comparison strict
+ * @arg1:  the first node set object
+ * @arg2:  the second node set object
+ *
+ * Implement the compare operation on nodesets:
+ *
+ * If both objects to be compared are node-sets, then the comparison
+ * will be true if and only if there is a node in the first node-set
+ * and a node in the second node-set such that the result of performing
+ * the comparison on the string-values of the two nodes is true.
+ * ....
+ * When neither object to be compared is a node-set and the operator
+ * is <=, <, >= or >, then the objects are compared by converting both
+ * objects to numbers and comparing the numbers according to IEEE 754.
+ * ....
+ * The number function converts its argument to a number as follows:
+ *  - a string that consists of optional whitespace followed by an
+ *    optional minus sign followed by a Number followed by whitespace
+ *    is converted to the IEEE 754 number that is nearest (according
+ *    to the IEEE 754 round-to-nearest rule) to the mathematical value
+ *    represented by the string; any other string is converted to NaN
+ *
+ * Conclusion all nodes need to be converted first to their string value
+ * and then the comparison must be done when possible
+ */
+static int
+xmlXPathCompareNodeSets(int inf, int strict,
+	                xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
+    int i, j, init = 0;
+    double val1;
+    double *values2;
+    int ret = 0;
+    xmlNodeSetPtr ns1;
+    xmlNodeSetPtr ns2;
+
+    if ((arg1 == NULL) ||
+	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) {
+	xmlXPathFreeObject(arg2);
+        return(0);
+    }
+    if ((arg2 == NULL) ||
+	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) {
+	xmlXPathFreeObject(arg1);
+	xmlXPathFreeObject(arg2);
+        return(0);
+    }
+
+    ns1 = arg1->nodesetval;
+    ns2 = arg2->nodesetval;
+
+    if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
+	xmlXPathFreeObject(arg1);
+	xmlXPathFreeObject(arg2);
+	return(0);
+    }
+    if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
+	xmlXPathFreeObject(arg1);
+	xmlXPathFreeObject(arg2);
+	return(0);
+    }
+
+    values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
+    if (values2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
+	xmlXPathFreeObject(arg1);
+	xmlXPathFreeObject(arg2);
+	return(0);
+    }
+    for (i = 0;i < ns1->nodeNr;i++) {
+	val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
+	if (xmlXPathIsNaN(val1))
+	    continue;
+	for (j = 0;j < ns2->nodeNr;j++) {
+	    if (init == 0) {
+		values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
+	    }
+	    if (xmlXPathIsNaN(values2[j]))
+		continue;
+	    if (inf && strict)
+		ret = (val1 < values2[j]);
+	    else if (inf && !strict)
+		ret = (val1 <= values2[j]);
+	    else if (!inf && strict)
+		ret = (val1 > values2[j]);
+	    else if (!inf && !strict)
+		ret = (val1 >= values2[j]);
+	    if (ret)
+		break;
+	}
+	if (ret)
+	    break;
+	init = 1;
+    }
+    xmlFree(values2);
+    xmlXPathFreeObject(arg1);
+    xmlXPathFreeObject(arg2);
+    return(ret);
+}
+
+/**
+ * xmlXPathCompareNodeSetValue:
+ * @ctxt:  the XPath Parser context
+ * @inf:  less than (1) or greater than (0)
+ * @strict:  is the comparison strict
+ * @arg:  the node set
+ * @val:  the value
+ *
+ * Implement the compare operation between a nodeset and a value
+ *     @ns < @val    (1, 1, ...
+ *     @ns <= @val   (1, 0, ...
+ *     @ns > @val    (0, 1, ...
+ *     @ns >= @val   (0, 0, ...
+ *
+ * If one object to be compared is a node-set and the other is a boolean,
+ * then the comparison will be true if and only if the result of performing
+ * the comparison on the boolean and on the result of converting
+ * the node-set to a boolean using the boolean function is true.
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
+	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
+    if ((val == NULL) || (arg == NULL) ||
+	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
+        return(0);
+
+    switch(val->type) {
+        case XPATH_NUMBER:
+	    return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
+        case XPATH_NODESET:
+        case XPATH_XSLT_TREE:
+	    return(xmlXPathCompareNodeSets(inf, strict, arg, val));
+        case XPATH_STRING:
+	    return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
+        case XPATH_BOOLEAN:
+	    valuePush(ctxt, arg);
+	    xmlXPathBooleanFunction(ctxt, 1);
+	    valuePush(ctxt, val);
+	    return(xmlXPathCompareValues(ctxt, inf, strict));
+	default:
+	    TODO
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathEqualNodeSetString:
+ * @arg:  the nodeset object argument
+ * @str:  the string to compare to.
+ * @neq:  flag to show whether for '=' (0) or '!=' (1)
+ *
+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
+ * If one object to be compared is a node-set and the other is a string,
+ * then the comparison will be true if and only if there is a node in
+ * the node-set such that the result of performing the comparison on the
+ * string-value of the node and the other string is true.
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq)
+{
+    int i;
+    xmlNodeSetPtr ns;
+    xmlChar *str2;
+    unsigned int hash;
+
+    if ((str == NULL) || (arg == NULL) ||
+        ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
+        return (0);
+    ns = arg->nodesetval;
+    /*
+     * A NULL nodeset compared with a string is always false
+     * (since there is no node equal, and no node not equal)
+     */
+    if ((ns == NULL) || (ns->nodeNr <= 0) )
+        return (0);
+    hash = xmlXPathStringHash(str);
+    for (i = 0; i < ns->nodeNr; i++) {
+        if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) {
+            str2 = xmlNodeGetContent(ns->nodeTab[i]);
+            if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
+                xmlFree(str2);
+		if (neq)
+		    continue;
+                return (1);
+	    } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) {
+		if (neq)
+		    continue;
+                return (1);
+            } else if (neq) {
+		if (str2 != NULL)
+		    xmlFree(str2);
+		return (1);
+	    }
+            if (str2 != NULL)
+                xmlFree(str2);
+        } else if (neq)
+	    return (1);
+    }
+    return (0);
+}
+
+/**
+ * xmlXPathEqualNodeSetFloat:
+ * @arg:  the nodeset object argument
+ * @f:  the float to compare to
+ * @neq:  flag to show whether to compare '=' (0) or '!=' (1)
+ *
+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
+ * If one object to be compared is a node-set and the other is a number,
+ * then the comparison will be true if and only if there is a node in
+ * the node-set such that the result of performing the comparison on the
+ * number to be compared and on the result of converting the string-value
+ * of that node to a number using the number function is true.
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt,
+    xmlXPathObjectPtr arg, double f, int neq) {
+  int i, ret=0;
+  xmlNodeSetPtr ns;
+  xmlChar *str2;
+  xmlXPathObjectPtr val;
+  double v;
+
+    if ((arg == NULL) ||
+	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
+        return(0);
+
+    ns = arg->nodesetval;
+    if (ns != NULL) {
+	for (i=0;i<ns->nodeNr;i++) {
+	    str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
+	    if (str2 != NULL) {
+		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, str2));
+		xmlFree(str2);
+		xmlXPathNumberFunction(ctxt, 1);
+		val = valuePop(ctxt);
+		v = val->floatval;
+		xmlXPathReleaseObject(ctxt->context, val);
+		if (!xmlXPathIsNaN(v)) {
+		    if ((!neq) && (v==f)) {
+			ret = 1;
+			break;
+		    } else if ((neq) && (v!=f)) {
+			ret = 1;
+			break;
+		    }
+		} else {	/* NaN is unequal to any value */
+		    if (neq)
+			ret = 1;
+		}
+	    }
+	}
+    }
+
+    return(ret);
+}
+
+
+/**
+ * xmlXPathEqualNodeSets:
+ * @arg1:  first nodeset object argument
+ * @arg2:  second nodeset object argument
+ * @neq:   flag to show whether to test '=' (0) or '!=' (1)
+ *
+ * Implement the equal / not equal operation on XPath nodesets:
+ * @arg1 == @arg2  or  @arg1 != @arg2
+ * If both objects to be compared are node-sets, then the comparison
+ * will be true if and only if there is a node in the first node-set and
+ * a node in the second node-set such that the result of performing the
+ * comparison on the string-values of the two nodes is true.
+ *
+ * (needless to say, this is a costly operation)
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+static int
+xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) {
+    int i, j;
+    unsigned int *hashs1;
+    unsigned int *hashs2;
+    xmlChar **values1;
+    xmlChar **values2;
+    int ret = 0;
+    xmlNodeSetPtr ns1;
+    xmlNodeSetPtr ns2;
+
+    if ((arg1 == NULL) ||
+	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
+        return(0);
+    if ((arg2 == NULL) ||
+	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
+        return(0);
+
+    ns1 = arg1->nodesetval;
+    ns2 = arg2->nodesetval;
+
+    if ((ns1 == NULL) || (ns1->nodeNr <= 0))
+	return(0);
+    if ((ns2 == NULL) || (ns2->nodeNr <= 0))
+	return(0);
+
+    /*
+     * for equal, check if there is a node pertaining to both sets
+     */
+    if (neq == 0)
+	for (i = 0;i < ns1->nodeNr;i++)
+	    for (j = 0;j < ns2->nodeNr;j++)
+		if (ns1->nodeTab[i] == ns2->nodeTab[j])
+		    return(1);
+
+    values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
+    if (values1 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
+	return(0);
+    }
+    hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
+    if (hashs1 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
+	xmlFree(values1);
+	return(0);
+    }
+    memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
+    values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
+    if (values2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
+	xmlFree(hashs1);
+	xmlFree(values1);
+	return(0);
+    }
+    hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
+    if (hashs2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
+	xmlFree(hashs1);
+	xmlFree(values1);
+	xmlFree(values2);
+	return(0);
+    }
+    memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *));
+    for (i = 0;i < ns1->nodeNr;i++) {
+	hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]);
+	for (j = 0;j < ns2->nodeNr;j++) {
+	    if (i == 0)
+		hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]);
+	    if (hashs1[i] != hashs2[j]) {
+		if (neq) {
+		    ret = 1;
+		    break;
+		}
+	    }
+	    else {
+		if (values1[i] == NULL)
+		    values1[i] = xmlNodeGetContent(ns1->nodeTab[i]);
+		if (values2[j] == NULL)
+		    values2[j] = xmlNodeGetContent(ns2->nodeTab[j]);
+		ret = xmlStrEqual(values1[i], values2[j]) ^ neq;
+		if (ret)
+		    break;
+	    }
+	}
+	if (ret)
+	    break;
+    }
+    for (i = 0;i < ns1->nodeNr;i++)
+	if (values1[i] != NULL)
+	    xmlFree(values1[i]);
+    for (j = 0;j < ns2->nodeNr;j++)
+	if (values2[j] != NULL)
+	    xmlFree(values2[j]);
+    xmlFree(values1);
+    xmlFree(values2);
+    xmlFree(hashs1);
+    xmlFree(hashs2);
+    return(ret);
+}
+
+static int
+xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
+  xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
+    int ret = 0;
+    /*
+     *At this point we are assured neither arg1 nor arg2
+     *is a nodeset, so we can just pick the appropriate routine.
+     */
+    switch (arg1->type) {
+        case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+	    xmlGenericError(xmlGenericErrorContext,
+		    "Equal: undefined\n");
+#endif
+	    break;
+        case XPATH_BOOLEAN:
+	    switch (arg2->type) {
+	        case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Equal: undefined\n");
+#endif
+		    break;
+		case XPATH_BOOLEAN:
+#ifdef DEBUG_EXPR
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Equal: %d boolean %d \n",
+			    arg1->boolval, arg2->boolval);
+#endif
+		    ret = (arg1->boolval == arg2->boolval);
+		    break;
+		case XPATH_NUMBER:
+		    ret = (arg1->boolval ==
+			   xmlXPathCastNumberToBoolean(arg2->floatval));
+		    break;
+		case XPATH_STRING:
+		    if ((arg2->stringval == NULL) ||
+			(arg2->stringval[0] == 0)) ret = 0;
+		    else
+			ret = 1;
+		    ret = (arg1->boolval == ret);
+		    break;
+		case XPATH_USERS:
+		case XPATH_POINT:
+		case XPATH_RANGE:
+		case XPATH_LOCATIONSET:
+		    TODO
+		    break;
+		case XPATH_NODESET:
+		case XPATH_XSLT_TREE:
+		    break;
+	    }
+	    break;
+        case XPATH_NUMBER:
+	    switch (arg2->type) {
+	        case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Equal: undefined\n");
+#endif
+		    break;
+		case XPATH_BOOLEAN:
+		    ret = (arg2->boolval==
+			   xmlXPathCastNumberToBoolean(arg1->floatval));
+		    break;
+		case XPATH_STRING:
+		    valuePush(ctxt, arg2);
+		    xmlXPathNumberFunction(ctxt, 1);
+		    arg2 = valuePop(ctxt);
+		    /* no break on purpose */
+		case XPATH_NUMBER:
+		    /* Hand check NaN and Infinity equalities */
+		    if (xmlXPathIsNaN(arg1->floatval) ||
+			    xmlXPathIsNaN(arg2->floatval)) {
+		        ret = 0;
+		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
+		        if (xmlXPathIsInf(arg2->floatval) == 1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
+			if (xmlXPathIsInf(arg2->floatval) == -1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
+			if (xmlXPathIsInf(arg1->floatval) == 1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
+			if (xmlXPathIsInf(arg1->floatval) == -1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else {
+		        ret = (arg1->floatval == arg2->floatval);
+		    }
+		    break;
+		case XPATH_USERS:
+		case XPATH_POINT:
+		case XPATH_RANGE:
+		case XPATH_LOCATIONSET:
+		    TODO
+		    break;
+		case XPATH_NODESET:
+		case XPATH_XSLT_TREE:
+		    break;
+	    }
+	    break;
+        case XPATH_STRING:
+	    switch (arg2->type) {
+	        case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+		    xmlGenericError(xmlGenericErrorContext,
+			    "Equal: undefined\n");
+#endif
+		    break;
+		case XPATH_BOOLEAN:
+		    if ((arg1->stringval == NULL) ||
+			(arg1->stringval[0] == 0)) ret = 0;
+		    else
+			ret = 1;
+		    ret = (arg2->boolval == ret);
+		    break;
+		case XPATH_STRING:
+		    ret = xmlStrEqual(arg1->stringval, arg2->stringval);
+		    break;
+		case XPATH_NUMBER:
+		    valuePush(ctxt, arg1);
+		    xmlXPathNumberFunction(ctxt, 1);
+		    arg1 = valuePop(ctxt);
+		    /* Hand check NaN and Infinity equalities */
+		    if (xmlXPathIsNaN(arg1->floatval) ||
+			    xmlXPathIsNaN(arg2->floatval)) {
+		        ret = 0;
+		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
+			if (xmlXPathIsInf(arg2->floatval) == 1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
+			if (xmlXPathIsInf(arg2->floatval) == -1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
+			if (xmlXPathIsInf(arg1->floatval) == 1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
+			if (xmlXPathIsInf(arg1->floatval) == -1)
+			    ret = 1;
+			else
+			    ret = 0;
+		    } else {
+		        ret = (arg1->floatval == arg2->floatval);
+		    }
+		    break;
+		case XPATH_USERS:
+		case XPATH_POINT:
+		case XPATH_RANGE:
+		case XPATH_LOCATIONSET:
+		    TODO
+		    break;
+		case XPATH_NODESET:
+		case XPATH_XSLT_TREE:
+		    break;
+	    }
+	    break;
+        case XPATH_USERS:
+	case XPATH_POINT:
+	case XPATH_RANGE:
+	case XPATH_LOCATIONSET:
+	    TODO
+	    break;
+	case XPATH_NODESET:
+	case XPATH_XSLT_TREE:
+	    break;
+    }
+    xmlXPathReleaseObject(ctxt->context, arg1);
+    xmlXPathReleaseObject(ctxt->context, arg2);
+    return(ret);
+}
+
+/**
+ * xmlXPathEqualValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+int
+xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg1, arg2, argtmp;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
+    arg2 = valuePop(ctxt);
+    arg1 = valuePop(ctxt);
+    if ((arg1 == NULL) || (arg2 == NULL)) {
+	if (arg1 != NULL)
+	    xmlXPathReleaseObject(ctxt->context, arg1);
+	else
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+	XP_ERROR0(XPATH_INVALID_OPERAND);
+    }
+
+    if (arg1 == arg2) {
+#ifdef DEBUG_EXPR
+        xmlGenericError(xmlGenericErrorContext,
+		"Equal: by pointer\n");
+#endif
+	xmlXPathFreeObject(arg1);
+        return(1);
+    }
+
+    /*
+     *If either argument is a nodeset, it's a 'special case'
+     */
+    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
+      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
+	/*
+	 *Hack it to assure arg1 is the nodeset
+	 */
+	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
+		argtmp = arg2;
+		arg2 = arg1;
+		arg1 = argtmp;
+	}
+	switch (arg2->type) {
+	    case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+		xmlGenericError(xmlGenericErrorContext,
+			"Equal: undefined\n");
+#endif
+		break;
+	    case XPATH_NODESET:
+	    case XPATH_XSLT_TREE:
+		ret = xmlXPathEqualNodeSets(arg1, arg2, 0);
+		break;
+	    case XPATH_BOOLEAN:
+		if ((arg1->nodesetval == NULL) ||
+		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
+		else
+		    ret = 1;
+		ret = (ret == arg2->boolval);
+		break;
+	    case XPATH_NUMBER:
+		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0);
+		break;
+	    case XPATH_STRING:
+		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0);
+		break;
+	    case XPATH_USERS:
+	    case XPATH_POINT:
+	    case XPATH_RANGE:
+	    case XPATH_LOCATIONSET:
+		TODO
+		break;
+	}
+	xmlXPathReleaseObject(ctxt->context, arg1);
+	xmlXPathReleaseObject(ctxt->context, arg2);
+	return(ret);
+    }
+
+    return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
+}
+
+/**
+ * xmlXPathNotEqualValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the equal operation on XPath objects content: @arg1 == @arg2
+ *
+ * Returns 0 or 1 depending on the results of the test.
+ */
+int
+xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg1, arg2, argtmp;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
+    arg2 = valuePop(ctxt);
+    arg1 = valuePop(ctxt);
+    if ((arg1 == NULL) || (arg2 == NULL)) {
+	if (arg1 != NULL)
+	    xmlXPathReleaseObject(ctxt->context, arg1);
+	else
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+	XP_ERROR0(XPATH_INVALID_OPERAND);
+    }
+
+    if (arg1 == arg2) {
+#ifdef DEBUG_EXPR
+        xmlGenericError(xmlGenericErrorContext,
+		"NotEqual: by pointer\n");
+#endif
+	xmlXPathReleaseObject(ctxt->context, arg1);
+        return(0);
+    }
+
+    /*
+     *If either argument is a nodeset, it's a 'special case'
+     */
+    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
+      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
+	/*
+	 *Hack it to assure arg1 is the nodeset
+	 */
+	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
+		argtmp = arg2;
+		arg2 = arg1;
+		arg1 = argtmp;
+	}
+	switch (arg2->type) {
+	    case XPATH_UNDEFINED:
+#ifdef DEBUG_EXPR
+		xmlGenericError(xmlGenericErrorContext,
+			"NotEqual: undefined\n");
+#endif
+		break;
+	    case XPATH_NODESET:
+	    case XPATH_XSLT_TREE:
+		ret = xmlXPathEqualNodeSets(arg1, arg2, 1);
+		break;
+	    case XPATH_BOOLEAN:
+		if ((arg1->nodesetval == NULL) ||
+		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
+		else
+		    ret = 1;
+		ret = (ret != arg2->boolval);
+		break;
+	    case XPATH_NUMBER:
+		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1);
+		break;
+	    case XPATH_STRING:
+		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1);
+		break;
+	    case XPATH_USERS:
+	    case XPATH_POINT:
+	    case XPATH_RANGE:
+	    case XPATH_LOCATIONSET:
+		TODO
+		break;
+	}
+	xmlXPathReleaseObject(ctxt->context, arg1);
+	xmlXPathReleaseObject(ctxt->context, arg2);
+	return(ret);
+    }
+
+    return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
+}
+
+/**
+ * xmlXPathCompareValues:
+ * @ctxt:  the XPath Parser context
+ * @inf:  less than (1) or greater than (0)
+ * @strict:  is the comparison strict
+ *
+ * Implement the compare operation on XPath objects:
+ *     @arg1 < @arg2    (1, 1, ...
+ *     @arg1 <= @arg2   (1, 0, ...
+ *     @arg1 > @arg2    (0, 1, ...
+ *     @arg1 >= @arg2   (0, 0, ...
+ *
+ * When neither object to be compared is a node-set and the operator is
+ * <=, <, >=, >, then the objects are compared by converted both objects
+ * to numbers and comparing the numbers according to IEEE 754. The <
+ * comparison will be true if and only if the first number is less than the
+ * second number. The <= comparison will be true if and only if the first
+ * number is less than or equal to the second number. The > comparison
+ * will be true if and only if the first number is greater than the second
+ * number. The >= comparison will be true if and only if the first number
+ * is greater than or equal to the second number.
+ *
+ * Returns 1 if the comparison succeeded, 0 if it failed
+ */
+int
+xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
+    int ret = 0, arg1i = 0, arg2i = 0;
+    xmlXPathObjectPtr arg1, arg2;
+
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
+    arg2 = valuePop(ctxt);
+    arg1 = valuePop(ctxt);
+    if ((arg1 == NULL) || (arg2 == NULL)) {
+	if (arg1 != NULL)
+	    xmlXPathReleaseObject(ctxt->context, arg1);
+	else
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+	XP_ERROR0(XPATH_INVALID_OPERAND);
+    }
+
+    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
+      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
+	/*
+	 * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments
+	 * are not freed from within this routine; they will be freed from the
+	 * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue
+	 */
+	if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) &&
+	  ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){
+	    ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2);
+	} else {
+	    if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
+		ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict,
+			                          arg1, arg2);
+	    } else {
+		ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict,
+			                          arg2, arg1);
+	    }
+	}
+	return(ret);
+    }
+
+    if (arg1->type != XPATH_NUMBER) {
+	valuePush(ctxt, arg1);
+	xmlXPathNumberFunction(ctxt, 1);
+	arg1 = valuePop(ctxt);
+    }
+    if (arg1->type != XPATH_NUMBER) {
+	xmlXPathFreeObject(arg1);
+	xmlXPathFreeObject(arg2);
+	XP_ERROR0(XPATH_INVALID_OPERAND);
+    }
+    if (arg2->type != XPATH_NUMBER) {
+	valuePush(ctxt, arg2);
+	xmlXPathNumberFunction(ctxt, 1);
+	arg2 = valuePop(ctxt);
+    }
+    if (arg2->type != XPATH_NUMBER) {
+	xmlXPathReleaseObject(ctxt->context, arg1);
+	xmlXPathReleaseObject(ctxt->context, arg2);
+	XP_ERROR0(XPATH_INVALID_OPERAND);
+    }
+    /*
+     * Add tests for infinity and nan
+     * => feedback on 3.4 for Inf and NaN
+     */
+    /* Hand check NaN and Infinity comparisons */
+    if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
+	ret=0;
+    } else {
+	arg1i=xmlXPathIsInf(arg1->floatval);
+	arg2i=xmlXPathIsInf(arg2->floatval);
+	if (inf && strict) {
+	    if ((arg1i == -1 && arg2i != -1) ||
+		(arg2i == 1 && arg1i != 1)) {
+		ret = 1;
+	    } else if (arg1i == 0 && arg2i == 0) {
+		ret = (arg1->floatval < arg2->floatval);
+	    } else {
+		ret = 0;
+	    }
+	}
+	else if (inf && !strict) {
+	    if (arg1i == -1 || arg2i == 1) {
+		ret = 1;
+	    } else if (arg1i == 0 && arg2i == 0) {
+		ret = (arg1->floatval <= arg2->floatval);
+	    } else {
+		ret = 0;
+	    }
+	}
+	else if (!inf && strict) {
+	    if ((arg1i == 1 && arg2i != 1) ||
+		(arg2i == -1 && arg1i != -1)) {
+		ret = 1;
+	    } else if (arg1i == 0 && arg2i == 0) {
+		ret = (arg1->floatval > arg2->floatval);
+	    } else {
+		ret = 0;
+	    }
+	}
+	else if (!inf && !strict) {
+	    if (arg1i == 1 || arg2i == -1) {
+		ret = 1;
+	    } else if (arg1i == 0 && arg2i == 0) {
+		ret = (arg1->floatval >= arg2->floatval);
+	    } else {
+		ret = 0;
+	    }
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, arg1);
+    xmlXPathReleaseObject(ctxt->context, arg2);
+    return(ret);
+}
+
+/**
+ * xmlXPathValueFlipSign:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the unary - operation on an XPath object
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return;
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    if (xmlXPathIsNaN(ctxt->value->floatval))
+        ctxt->value->floatval=xmlXPathNAN;
+    else if (xmlXPathIsInf(ctxt->value->floatval) == 1)
+        ctxt->value->floatval=xmlXPathNINF;
+    else if (xmlXPathIsInf(ctxt->value->floatval) == -1)
+        ctxt->value->floatval=xmlXPathPINF;
+    else if (ctxt->value->floatval == 0) {
+        if (xmlXPathGetSign(ctxt->value->floatval) == 0)
+	    ctxt->value->floatval = xmlXPathNZERO;
+	else
+	    ctxt->value->floatval = 0;
+    }
+    else
+        ctxt->value->floatval = - ctxt->value->floatval;
+}
+
+/**
+ * xmlXPathAddValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the add operation on XPath objects:
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg;
+    double val;
+
+    arg = valuePop(ctxt);
+    if (arg == NULL)
+	XP_ERROR(XPATH_INVALID_OPERAND);
+    val = xmlXPathCastToNumber(arg);
+    xmlXPathReleaseObject(ctxt->context, arg);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    ctxt->value->floatval += val;
+}
+
+/**
+ * xmlXPathSubValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the subtraction operation on XPath objects:
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg;
+    double val;
+
+    arg = valuePop(ctxt);
+    if (arg == NULL)
+	XP_ERROR(XPATH_INVALID_OPERAND);
+    val = xmlXPathCastToNumber(arg);
+    xmlXPathReleaseObject(ctxt->context, arg);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    ctxt->value->floatval -= val;
+}
+
+/**
+ * xmlXPathMultValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the multiply operation on XPath objects:
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg;
+    double val;
+
+    arg = valuePop(ctxt);
+    if (arg == NULL)
+	XP_ERROR(XPATH_INVALID_OPERAND);
+    val = xmlXPathCastToNumber(arg);
+    xmlXPathReleaseObject(ctxt->context, arg);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    ctxt->value->floatval *= val;
+}
+
+/**
+ * xmlXPathDivValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the div operation on XPath objects @arg1 / @arg2:
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg;
+    double val;
+
+    arg = valuePop(ctxt);
+    if (arg == NULL)
+	XP_ERROR(XPATH_INVALID_OPERAND);
+    val = xmlXPathCastToNumber(arg);
+    xmlXPathReleaseObject(ctxt->context, arg);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval))
+	ctxt->value->floatval = xmlXPathNAN;
+    else if (val == 0 && xmlXPathGetSign(val) != 0) {
+	if (ctxt->value->floatval == 0)
+	    ctxt->value->floatval = xmlXPathNAN;
+	else if (ctxt->value->floatval > 0)
+	    ctxt->value->floatval = xmlXPathNINF;
+	else if (ctxt->value->floatval < 0)
+	    ctxt->value->floatval = xmlXPathPINF;
+    }
+    else if (val == 0) {
+	if (ctxt->value->floatval == 0)
+	    ctxt->value->floatval = xmlXPathNAN;
+	else if (ctxt->value->floatval > 0)
+	    ctxt->value->floatval = xmlXPathPINF;
+	else if (ctxt->value->floatval < 0)
+	    ctxt->value->floatval = xmlXPathNINF;
+    } else
+	ctxt->value->floatval /= val;
+}
+
+/**
+ * xmlXPathModValues:
+ * @ctxt:  the XPath Parser context
+ *
+ * Implement the mod operation on XPath objects: @arg1 / @arg2
+ * The numeric operators convert their operands to numbers as if
+ * by calling the number function.
+ */
+void
+xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
+    xmlXPathObjectPtr arg;
+    double arg1, arg2;
+
+    arg = valuePop(ctxt);
+    if (arg == NULL)
+	XP_ERROR(XPATH_INVALID_OPERAND);
+    arg2 = xmlXPathCastToNumber(arg);
+    xmlXPathReleaseObject(ctxt->context, arg);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    arg1 = ctxt->value->floatval;
+    if (arg2 == 0)
+	ctxt->value->floatval = xmlXPathNAN;
+    else {
+	ctxt->value->floatval = fmod(arg1, arg2);
+    }
+}
+
+/************************************************************************
+ *									*
+ *		The traversal functions					*
+ *									*
+ ************************************************************************/
+
+/*
+ * A traversal function enumerates nodes along an axis.
+ * Initially it must be called with NULL, and it indicates
+ * termination on the axis by returning NULL.
+ */
+typedef xmlNodePtr (*xmlXPathTraversalFunction)
+                    (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
+
+/*
+ * xmlXPathTraversalFunctionExt:
+ * A traversal function enumerates nodes along an axis.
+ * Initially it must be called with NULL, and it indicates
+ * termination on the axis by returning NULL.
+ * The context node of the traversal is specified via @contextNode.
+ */
+typedef xmlNodePtr (*xmlXPathTraversalFunctionExt)
+                    (xmlNodePtr cur, xmlNodePtr contextNode);
+
+/*
+ * xmlXPathNodeSetMergeFunction:
+ * Used for merging node sets in xmlXPathCollectAndTest().
+ */
+typedef xmlNodeSetPtr (*xmlXPathNodeSetMergeFunction)
+		    (xmlNodeSetPtr, xmlNodeSetPtr, int);
+
+
+/**
+ * xmlXPathNextSelf:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "self" direction
+ * The self axis contains just the context node itself
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL)
+        return(ctxt->context->node);
+    return(NULL);
+}
+
+/**
+ * xmlXPathNextChild:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "child" direction
+ * The child axis contains the children of the context node in document order.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL) {
+	if (ctxt->context->node == NULL) return(NULL);
+	switch (ctxt->context->node->type) {
+            case XML_ELEMENT_NODE:
+            case XML_TEXT_NODE:
+            case XML_CDATA_SECTION_NODE:
+            case XML_ENTITY_REF_NODE:
+            case XML_ENTITY_NODE:
+            case XML_PI_NODE:
+            case XML_COMMENT_NODE:
+            case XML_NOTATION_NODE:
+            case XML_DTD_NODE:
+		return(ctxt->context->node->children);
+            case XML_DOCUMENT_NODE:
+            case XML_DOCUMENT_TYPE_NODE:
+            case XML_DOCUMENT_FRAG_NODE:
+            case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+		return(((xmlDocPtr) ctxt->context->node)->children);
+	    case XML_ELEMENT_DECL:
+	    case XML_ATTRIBUTE_DECL:
+	    case XML_ENTITY_DECL:
+            case XML_ATTRIBUTE_NODE:
+	    case XML_NAMESPACE_DECL:
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		return(NULL);
+	}
+	return(NULL);
+    }
+    if ((cur->type == XML_DOCUMENT_NODE) ||
+        (cur->type == XML_HTML_DOCUMENT_NODE))
+	return(NULL);
+    return(cur->next);
+}
+
+/**
+ * xmlXPathNextChildElement:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "child" direction and nodes of type element.
+ * The child axis contains the children of the context node in document order.
+ *
+ * Returns the next element following that axis
+ */
+static xmlNodePtr
+xmlXPathNextChildElement(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL) {
+	cur = ctxt->context->node;
+	if (cur == NULL) return(NULL);
+	/*
+	* Get the first element child.
+	*/
+	switch (cur->type) {
+            case XML_ELEMENT_NODE:
+	    case XML_DOCUMENT_FRAG_NODE:
+	    case XML_ENTITY_REF_NODE: /* URGENT TODO: entify-refs as well? */
+            case XML_ENTITY_NODE:
+		cur = cur->children;
+		if (cur != NULL) {
+		    if (cur->type == XML_ELEMENT_NODE)
+			return(cur);
+		    do {
+			cur = cur->next;
+		    } while ((cur != NULL) &&
+			(cur->type != XML_ELEMENT_NODE));
+		    return(cur);
+		}
+		return(NULL);
+            case XML_DOCUMENT_NODE:
+            case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+		return(xmlDocGetRootElement((xmlDocPtr) cur));
+	    default:
+		return(NULL);
+	}
+	return(NULL);
+    }
+    /*
+    * Get the next sibling element node.
+    */
+    switch (cur->type) {
+	case XML_ELEMENT_NODE:
+	case XML_TEXT_NODE:
+	case XML_ENTITY_REF_NODE:
+	case XML_ENTITY_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_PI_NODE:
+	case XML_COMMENT_NODE:
+	case XML_XINCLUDE_END:
+	    break;
+	/* case XML_DTD_NODE: */ /* URGENT TODO: DTD-node as well? */
+	default:
+	    return(NULL);
+    }
+    if (cur->next != NULL) {
+	if (cur->next->type == XML_ELEMENT_NODE)
+	    return(cur->next);
+	cur = cur->next;
+	do {
+	    cur = cur->next;
+	} while ((cur != NULL) && (cur->type != XML_ELEMENT_NODE));
+	return(cur);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPathNextDescendantOrSelfElemParent:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "descendant-or-self" axis.
+ * Additionally it returns only nodes which can be parents of
+ * element nodes.
+ *
+ *
+ * Returns the next element following that axis
+ */
+static xmlNodePtr
+xmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur,
+				       xmlNodePtr contextNode)
+{
+    if (cur == NULL) {
+	if (contextNode == NULL)
+	    return(NULL);
+	switch (contextNode->type) {
+	    case XML_ELEMENT_NODE:
+	    case XML_XINCLUDE_START:
+	    case XML_DOCUMENT_FRAG_NODE:
+	    case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    case XML_HTML_DOCUMENT_NODE:	    
+		return(contextNode);
+	    default:
+		return(NULL);
+	}
+	return(NULL);
+    } else {
+	xmlNodePtr start = cur;
+
+	while (cur != NULL) {
+	    switch (cur->type) {
+		case XML_ELEMENT_NODE:
+		/* TODO: OK to have XInclude here? */
+		case XML_XINCLUDE_START:
+		case XML_DOCUMENT_FRAG_NODE:
+		    if (cur != start)
+			return(cur);
+		    if (cur->children != NULL) {
+			cur = cur->children;
+			continue;
+		    }
+		    break;
+		/* Not sure if we need those here. */
+		case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+		case XML_DOCB_DOCUMENT_NODE:
+#endif
+		case XML_HTML_DOCUMENT_NODE:
+		    if (cur != start)
+			return(cur);
+		    return(xmlDocGetRootElement((xmlDocPtr) cur));
+		default:
+		    break;
+	    }
+
+next_sibling:
+	    if ((cur == NULL) || (cur == contextNode))
+		return(NULL);
+	    if (cur->next != NULL) {
+		cur = cur->next;
+	    } else {
+		cur = cur->parent;
+		goto next_sibling;
+	    }
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPathNextDescendant:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "descendant" direction
+ * the descendant axis contains the descendants of the context node in document
+ * order; a descendant is a child or a child of a child and so on.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL) {
+	if (ctxt->context->node == NULL)
+	    return(NULL);
+	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
+	    return(NULL);
+
+        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
+	    return(ctxt->context->doc->children);
+        return(ctxt->context->node->children);
+    }
+
+    if (cur->children != NULL) {
+	/*
+	 * Do not descend on entities declarations
+	 */
+	if (cur->children->type != XML_ENTITY_DECL) {
+	    cur = cur->children;
+	    /*
+	     * Skip DTDs
+	     */
+	    if (cur->type != XML_DTD_NODE)
+		return(cur);
+	}
+    }
+
+    if (cur == ctxt->context->node) return(NULL);
+
+    while (cur->next != NULL) {
+	cur = cur->next;
+	if ((cur->type != XML_ENTITY_DECL) &&
+	    (cur->type != XML_DTD_NODE))
+	    return(cur);
+    }
+
+    do {
+        cur = cur->parent;
+	if (cur == NULL) break;
+	if (cur == ctxt->context->node) return(NULL);
+	if (cur->next != NULL) {
+	    cur = cur->next;
+	    return(cur);
+	}
+    } while (cur != NULL);
+    return(cur);
+}
+
+/**
+ * xmlXPathNextDescendantOrSelf:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "descendant-or-self" direction
+ * the descendant-or-self axis contains the context node and the descendants
+ * of the context node in document order; thus the context node is the first
+ * node on the axis, and the first child of the context node is the second node
+ * on the axis
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL) {
+	if (ctxt->context->node == NULL)
+	    return(NULL);
+	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
+	    return(NULL);
+        return(ctxt->context->node);
+    }
+
+    return(xmlXPathNextDescendant(ctxt, cur));
+}
+
+/**
+ * xmlXPathNextParent:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "parent" direction
+ * The parent axis contains the parent of the context node, if there is one.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    /*
+     * the parent of an attribute or namespace node is the element
+     * to which the attribute or namespace node is attached
+     * Namespace handling !!!
+     */
+    if (cur == NULL) {
+	if (ctxt->context->node == NULL) return(NULL);
+	switch (ctxt->context->node->type) {
+            case XML_ELEMENT_NODE:
+            case XML_TEXT_NODE:
+            case XML_CDATA_SECTION_NODE:
+            case XML_ENTITY_REF_NODE:
+            case XML_ENTITY_NODE:
+            case XML_PI_NODE:
+            case XML_COMMENT_NODE:
+            case XML_NOTATION_NODE:
+            case XML_DTD_NODE:
+	    case XML_ELEMENT_DECL:
+	    case XML_ATTRIBUTE_DECL:
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+	    case XML_ENTITY_DECL:
+		if (ctxt->context->node->parent == NULL)
+		    return((xmlNodePtr) ctxt->context->doc);
+		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
+		    ((ctxt->context->node->parent->name[0] == ' ') ||
+		     (xmlStrEqual(ctxt->context->node->parent->name,
+				 BAD_CAST "fake node libxslt"))))
+		    return(NULL);
+		return(ctxt->context->node->parent);
+            case XML_ATTRIBUTE_NODE: {
+		xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
+
+		return(att->parent);
+	    }
+            case XML_DOCUMENT_NODE:
+            case XML_DOCUMENT_TYPE_NODE:
+            case XML_DOCUMENT_FRAG_NODE:
+            case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+                return(NULL);
+	    case XML_NAMESPACE_DECL: {
+		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
+
+		if ((ns->next != NULL) &&
+		    (ns->next->type != XML_NAMESPACE_DECL))
+		    return((xmlNodePtr) ns->next);
+                return(NULL);
+	    }
+	}
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPathNextAncestor:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "ancestor" direction
+ * the ancestor axis contains the ancestors of the context node; the ancestors
+ * of the context node consist of the parent of context node and the parent's
+ * parent and so on; the nodes are ordered in reverse document order; thus the
+ * parent is the first node on the axis, and the parent's parent is the second
+ * node on the axis
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    /*
+     * the parent of an attribute or namespace node is the element
+     * to which the attribute or namespace node is attached
+     * !!!!!!!!!!!!!
+     */
+    if (cur == NULL) {
+	if (ctxt->context->node == NULL) return(NULL);
+	switch (ctxt->context->node->type) {
+            case XML_ELEMENT_NODE:
+            case XML_TEXT_NODE:
+            case XML_CDATA_SECTION_NODE:
+            case XML_ENTITY_REF_NODE:
+            case XML_ENTITY_NODE:
+            case XML_PI_NODE:
+            case XML_COMMENT_NODE:
+	    case XML_DTD_NODE:
+	    case XML_ELEMENT_DECL:
+	    case XML_ATTRIBUTE_DECL:
+	    case XML_ENTITY_DECL:
+            case XML_NOTATION_NODE:
+	    case XML_XINCLUDE_START:
+	    case XML_XINCLUDE_END:
+		if (ctxt->context->node->parent == NULL)
+		    return((xmlNodePtr) ctxt->context->doc);
+		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
+		    ((ctxt->context->node->parent->name[0] == ' ') ||
+		     (xmlStrEqual(ctxt->context->node->parent->name,
+				 BAD_CAST "fake node libxslt"))))
+		    return(NULL);
+		return(ctxt->context->node->parent);
+            case XML_ATTRIBUTE_NODE: {
+		xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node;
+
+		return(tmp->parent);
+	    }
+            case XML_DOCUMENT_NODE:
+            case XML_DOCUMENT_TYPE_NODE:
+            case XML_DOCUMENT_FRAG_NODE:
+            case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	    case XML_DOCB_DOCUMENT_NODE:
+#endif
+                return(NULL);
+	    case XML_NAMESPACE_DECL: {
+		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
+
+		if ((ns->next != NULL) &&
+		    (ns->next->type != XML_NAMESPACE_DECL))
+		    return((xmlNodePtr) ns->next);
+		/* Bad, how did that namespace end up here ? */
+                return(NULL);
+	    }
+	}
+	return(NULL);
+    }
+    if (cur == ctxt->context->doc->children)
+	return((xmlNodePtr) ctxt->context->doc);
+    if (cur == (xmlNodePtr) ctxt->context->doc)
+	return(NULL);
+    switch (cur->type) {
+	case XML_ELEMENT_NODE:
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_ENTITY_REF_NODE:
+	case XML_ENTITY_NODE:
+	case XML_PI_NODE:
+	case XML_COMMENT_NODE:
+	case XML_NOTATION_NODE:
+	case XML_DTD_NODE:
+        case XML_ELEMENT_DECL:
+        case XML_ATTRIBUTE_DECL:
+        case XML_ENTITY_DECL:
+	case XML_XINCLUDE_START:
+	case XML_XINCLUDE_END:
+	    if (cur->parent == NULL)
+		return(NULL);
+	    if ((cur->parent->type == XML_ELEMENT_NODE) &&
+		((cur->parent->name[0] == ' ') ||
+		 (xmlStrEqual(cur->parent->name,
+			      BAD_CAST "fake node libxslt"))))
+		return(NULL);
+	    return(cur->parent);
+	case XML_ATTRIBUTE_NODE: {
+	    xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
+
+	    return(att->parent);
+	}
+	case XML_NAMESPACE_DECL: {
+	    xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
+
+	    if ((ns->next != NULL) &&
+	        (ns->next->type != XML_NAMESPACE_DECL))
+	        return((xmlNodePtr) ns->next);
+	    /* Bad, how did that namespace end up here ? */
+            return(NULL);
+	}
+	case XML_DOCUMENT_NODE:
+	case XML_DOCUMENT_TYPE_NODE:
+	case XML_DOCUMENT_FRAG_NODE:
+	case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+	case XML_DOCB_DOCUMENT_NODE:
+#endif
+	    return(NULL);
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPathNextAncestorOrSelf:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "ancestor-or-self" direction
+ * he ancestor-or-self axis contains the context node and ancestors of
+ * the context node in reverse document order; thus the context node is
+ * the first node on the axis, and the context node's parent the second;
+ * parent here is defined the same as with the parent axis.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL)
+        return(ctxt->context->node);
+    return(xmlXPathNextAncestor(ctxt, cur));
+}
+
+/**
+ * xmlXPathNextFollowingSibling:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "following-sibling" direction
+ * The following-sibling axis contains the following siblings of the context
+ * node in document order.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+	(ctxt->context->node->type == XML_NAMESPACE_DECL))
+	return(NULL);
+    if (cur == (xmlNodePtr) ctxt->context->doc)
+        return(NULL);
+    if (cur == NULL)
+        return(ctxt->context->node->next);
+    return(cur->next);
+}
+
+/**
+ * xmlXPathNextPrecedingSibling:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "preceding-sibling" direction
+ * The preceding-sibling axis contains the preceding siblings of the context
+ * node in reverse document order; the first preceding sibling is first on the
+ * axis; the sibling preceding that node is the second on the axis and so on.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+	(ctxt->context->node->type == XML_NAMESPACE_DECL))
+	return(NULL);
+    if (cur == (xmlNodePtr) ctxt->context->doc)
+        return(NULL);
+    if (cur == NULL)
+        return(ctxt->context->node->prev);
+    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
+	cur = cur->prev;
+	if (cur == NULL)
+	    return(ctxt->context->node->prev);
+    }
+    return(cur->prev);
+}
+
+/**
+ * xmlXPathNextFollowing:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "following" direction
+ * The following axis contains all nodes in the same document as the context
+ * node that are after the context node in document order, excluding any
+ * descendants and excluding attribute nodes and namespace nodes; the nodes
+ * are ordered in document order
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    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 {
+        cur = cur->parent;
+        if (cur == NULL) break;
+        if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
+        if (cur->next != NULL) return(cur->next);
+    } while (cur != NULL);
+    return(cur);
+}
+
+/*
+ * xmlXPathIsAncestor:
+ * @ancestor:  the ancestor node
+ * @node:  the current node
+ *
+ * Check that @ancestor is a @node's ancestor
+ *
+ * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
+ */
+static int
+xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
+    if ((ancestor == NULL) || (node == NULL)) return(0);
+    /* nodes need to be in the same document */
+    if (ancestor->doc != node->doc) return(0);
+    /* avoid searching if ancestor or node is the root node */
+    if (ancestor == (xmlNodePtr) node->doc) return(1);
+    if (node == (xmlNodePtr) ancestor->doc) return(0);
+    while (node->parent != NULL) {
+        if (node->parent == ancestor)
+            return(1);
+	node = node->parent;
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathNextPreceding:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "preceding" direction
+ * the preceding axis contains all nodes in the same document as the context
+ * node that are before the context node in document order, excluding any
+ * ancestors and excluding attribute nodes and namespace nodes; the nodes are
+ * ordered in reverse document order
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
+{
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(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))
+	cur = cur->prev;
+    do {
+        if (cur->prev != NULL) {
+            for (cur = cur->prev; cur->last != NULL; cur = cur->last) ;
+            return (cur);
+        }
+
+        cur = cur->parent;
+        if (cur == NULL)
+            return (NULL);
+        if (cur == ctxt->context->doc->children)
+            return (NULL);
+    } while (xmlXPathIsAncestor(cur, ctxt->context->node));
+    return (cur);
+}
+
+/**
+ * xmlXPathNextPrecedingInternal:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current node in the traversal
+ *
+ * Traversal function for the "preceding" direction
+ * the preceding axis contains all nodes in the same document as the context
+ * node that are before the context node in document order, excluding any
+ * ancestors and excluding attribute nodes and namespace nodes; the nodes are
+ * ordered in reverse document order
+ * This is a faster implementation but internal only since it requires a
+ * state kept in the parser context: ctxt->ancestor.
+ *
+ * Returns the next element following that axis
+ */
+static xmlNodePtr
+xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
+                              xmlNodePtr cur)
+{
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (cur == NULL) {
+        cur = ctxt->context->node;
+        if (cur == NULL)
+            return (NULL);
+        if (cur->type == XML_NAMESPACE_DECL)
+            return (NULL);
+        ctxt->ancestor = cur->parent;
+    }
+    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
+	cur = cur->prev;
+    while (cur->prev == NULL) {
+        cur = cur->parent;
+        if (cur == NULL)
+            return (NULL);
+        if (cur == ctxt->context->doc->children)
+            return (NULL);
+        if (cur != ctxt->ancestor)
+            return (cur);
+        ctxt->ancestor = cur->parent;
+    }
+    cur = cur->prev;
+    while (cur->last != NULL)
+        cur = cur->last;
+    return (cur);
+}
+
+/**
+ * xmlXPathNextNamespace:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current attribute in the traversal
+ *
+ * Traversal function for the "namespace" direction
+ * the namespace axis contains the namespace nodes of the context node;
+ * the order of nodes on this axis is implementation-defined; the axis will
+ * be empty unless the context node is an element
+ *
+ * We keep the XML namespace node at the end of the list.
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
+    if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
+        if (ctxt->context->tmpNsList != NULL)
+	    xmlFree(ctxt->context->tmpNsList);
+	ctxt->context->tmpNsList =
+	    xmlGetNsList(ctxt->context->doc, ctxt->context->node);
+	ctxt->context->tmpNsNr = 0;
+	if (ctxt->context->tmpNsList != NULL) {
+	    while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
+		ctxt->context->tmpNsNr++;
+	    }
+	}
+	return((xmlNodePtr) xmlXPathXMLNamespace);
+    }
+    if (ctxt->context->tmpNsNr > 0) {
+	return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
+    } else {
+	if (ctxt->context->tmpNsList != NULL)
+	    xmlFree(ctxt->context->tmpNsList);
+	ctxt->context->tmpNsList = NULL;
+	return(NULL);
+    }
+}
+
+/**
+ * xmlXPathNextAttribute:
+ * @ctxt:  the XPath Parser context
+ * @cur:  the current attribute in the traversal
+ *
+ * Traversal function for the "attribute" direction
+ * TODO: support DTD inherited default attributes
+ *
+ * Returns the next element following that axis
+ */
+xmlNodePtr
+xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
+    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
+    if (ctxt->context->node == NULL)
+	return(NULL);
+    if (ctxt->context->node->type != XML_ELEMENT_NODE)
+	return(NULL);
+    if (cur == NULL) {
+        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
+	    return(NULL);
+        return((xmlNodePtr)ctxt->context->node->properties);
+    }
+    return((xmlNodePtr)cur->next);
+}
+
+/************************************************************************
+ *									*
+ *		NodeTest Functions					*
+ *									*
+ ************************************************************************/
+
+#define IS_FUNCTION			200
+
+
+/************************************************************************
+ *									*
+ *		Implicit tree core function library			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathRoot:
+ * @ctxt:  the XPath Parser context
+ *
+ * Initialize the context to the root of the document
+ */
+void
+xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
+    if ((ctxt == NULL) || (ctxt->context == NULL))
+	return;
+    ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
+    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+	ctxt->context->node));
+}
+
+/************************************************************************
+ *									*
+ *		The explicit core function library			*
+ *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	*
+ *									*
+ ************************************************************************/
+
+
+/**
+ * xmlXPathLastFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the last() XPath function
+ *    number last()
+ * The last function returns the number of nodes in the context node list.
+ */
+void
+xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+    if (ctxt->context->contextSize >= 0) {
+	valuePush(ctxt,
+	    xmlXPathCacheNewFloat(ctxt->context,
+		(double) ctxt->context->contextSize));
+#ifdef DEBUG_EXPR
+	xmlGenericError(xmlGenericErrorContext,
+		"last() : %d\n", ctxt->context->contextSize);
+#endif
+    } else {
+	XP_ERROR(XPATH_INVALID_CTXT_SIZE);
+    }
+}
+
+/**
+ * xmlXPathPositionFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the position() XPath function
+ *    number position()
+ * The position function returns the position of the context node in the
+ * context node list. The first position is 1, and so the last position
+ * will be equal to last().
+ */
+void
+xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+    if (ctxt->context->proximityPosition >= 0) {
+	valuePush(ctxt,
+	      xmlXPathCacheNewFloat(ctxt->context,
+		(double) ctxt->context->proximityPosition));
+#ifdef DEBUG_EXPR
+	xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
+		ctxt->context->proximityPosition);
+#endif
+    } else {
+	XP_ERROR(XPATH_INVALID_CTXT_POSITION);
+    }
+}
+
+/**
+ * xmlXPathCountFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the count() XPath function
+ *    number count(node-set)
+ */
+void
+xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_NODESET) &&
+	 (ctxt->value->type != XPATH_XSLT_TREE)))
+	XP_ERROR(XPATH_INVALID_TYPE);
+    cur = valuePop(ctxt);
+
+    if ((cur == NULL) || (cur->nodesetval == NULL))
+	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
+    else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
+	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
+	    (double) cur->nodesetval->nodeNr));
+    } else {
+	if ((cur->nodesetval->nodeNr != 1) ||
+	    (cur->nodesetval->nodeTab == NULL)) {
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
+	} else {
+	    xmlNodePtr tmp;
+	    int i = 0;
+
+	    tmp = cur->nodesetval->nodeTab[0];
+	    if (tmp != NULL) {
+		tmp = tmp->children;
+		while (tmp != NULL) {
+		    tmp = tmp->next;
+		    i++;
+		}
+	    }
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) i));
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+/**
+ * xmlXPathGetElementsByIds:
+ * @doc:  the document
+ * @ids:  a whitespace separated list of IDs
+ *
+ * Selects elements by their unique ID.
+ *
+ * Returns a node-set of selected elements.
+ */
+static xmlNodeSetPtr
+xmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) {
+    xmlNodeSetPtr ret;
+    const xmlChar *cur = ids;
+    xmlChar *ID;
+    xmlAttrPtr attr;
+    xmlNodePtr elem = NULL;
+
+    if (ids == NULL) return(NULL);
+
+    ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
+
+    while (IS_BLANK_CH(*cur)) cur++;
+    while (*cur != 0) {
+	while ((!IS_BLANK_CH(*cur)) && (*cur != 0))
+	    cur++;
+
+        ID = xmlStrndup(ids, cur - ids);
+	if (ID != NULL) {
+	    /*
+	     * We used to check the fact that the value passed
+	     * was an NCName, but this generated much troubles for
+	     * me and Aleksey Sanin, people blatantly violated that
+	     * constaint, like Visa3D spec.
+	     * if (xmlValidateNCName(ID, 1) == 0)
+	     */
+	    attr = xmlGetID(doc, ID);
+	    if (attr != NULL) {
+		if (attr->type == XML_ATTRIBUTE_NODE)
+		    elem = attr->parent;
+		else if (attr->type == XML_ELEMENT_NODE)
+		    elem = (xmlNodePtr) attr;
+		else
+		    elem = NULL;
+		if (elem != NULL)
+		    xmlXPathNodeSetAdd(ret, elem);
+	    }
+	    xmlFree(ID);
+	}
+
+	while (IS_BLANK_CH(*cur)) cur++;
+	ids = cur;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathIdFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the id() XPath function
+ *    node-set id(object)
+ * The id function selects elements by their unique ID
+ * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
+ * then the result is the union of the result of applying id to the
+ * string value of each of the nodes in the argument node-set. When the
+ * argument to id is of any other type, the argument is converted to a
+ * string as if by a call to the string function; the string is split
+ * into a whitespace-separated list of tokens (whitespace is any sequence
+ * of characters matching the production S); the result is a node-set
+ * containing the elements in the same document as the context node that
+ * have a unique ID equal to any of the tokens in the list.
+ */
+void
+xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlChar *tokens;
+    xmlNodeSetPtr ret;
+    xmlXPathObjectPtr obj;
+
+    CHECK_ARITY(1);
+    obj = valuePop(ctxt);
+    if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
+    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
+	xmlNodeSetPtr ns;
+	int i;
+
+	ret = xmlXPathNodeSetCreate(NULL);
+        /*
+         * FIXME -- in an out-of-memory condition this will behave badly.
+         * The solution is not clear -- we already popped an item from
+         * ctxt, so the object is in a corrupt state.
+         */
+
+	if (obj->nodesetval != NULL) {
+	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
+		tokens =
+		    xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
+		ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
+		ret = xmlXPathNodeSetMerge(ret, ns);
+		xmlXPathFreeNodeSet(ns);
+		if (tokens != NULL)
+		    xmlFree(tokens);
+	    }
+	}
+	xmlXPathReleaseObject(ctxt->context, obj);
+	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
+	return;
+    }
+    obj = xmlXPathCacheConvertString(ctxt->context, obj);
+    ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
+    valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
+    xmlXPathReleaseObject(ctxt->context, obj);
+    return;
+}
+
+/**
+ * xmlXPathLocalNameFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the local-name() XPath function
+ *    string local-name(node-set?)
+ * The local-name function returns a string containing the local part
+ * of the name of the node in the argument node-set that is first in
+ * document order. If the node-set is empty or the first node has no
+ * name, an empty string is returned. If the argument is omitted it
+ * defaults to the context node.
+ */
+void
+xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    if (ctxt == NULL) return;
+
+    if (nargs == 0) {
+	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+	    ctxt->context->node));
+	nargs = 1;
+    }
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_NODESET) &&
+	 (ctxt->value->type != XPATH_XSLT_TREE)))
+	XP_ERROR(XPATH_INVALID_TYPE);
+    cur = valuePop(ctxt);
+
+    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
+	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+    } else {
+	int i = 0; /* Should be first in document order !!!!! */
+	switch (cur->nodesetval->nodeTab[i]->type) {
+	case XML_ELEMENT_NODE:
+	case XML_ATTRIBUTE_NODE:
+	case XML_PI_NODE:
+	    if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
+		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+	    else
+		valuePush(ctxt,
+		      xmlXPathCacheNewString(ctxt->context,
+			cur->nodesetval->nodeTab[i]->name));
+	    break;
+	case XML_NAMESPACE_DECL:
+	    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+			((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
+	    break;
+	default:
+	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+/**
+ * xmlXPathNamespaceURIFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the namespace-uri() XPath function
+ *    string namespace-uri(node-set?)
+ * The namespace-uri function returns a string containing the
+ * namespace URI of the expanded name of the node in the argument
+ * node-set that is first in document order. If the node-set is empty,
+ * the first node has no name, or the expanded name has no namespace
+ * URI, an empty string is returned. If the argument is omitted it
+ * defaults to the context node.
+ */
+void
+xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    if (ctxt == NULL) return;
+
+    if (nargs == 0) {
+	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+	    ctxt->context->node));
+	nargs = 1;
+    }
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_NODESET) &&
+	 (ctxt->value->type != XPATH_XSLT_TREE)))
+	XP_ERROR(XPATH_INVALID_TYPE);
+    cur = valuePop(ctxt);
+
+    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
+	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+    } else {
+	int i = 0; /* Should be first in document order !!!!! */
+	switch (cur->nodesetval->nodeTab[i]->type) {
+	case XML_ELEMENT_NODE:
+	case XML_ATTRIBUTE_NODE:
+	    if (cur->nodesetval->nodeTab[i]->ns == NULL)
+		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+	    else
+		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+			  cur->nodesetval->nodeTab[i]->ns->href));
+	    break;
+	default:
+	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+	}
+    }
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+/**
+ * xmlXPathNameFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the name() XPath function
+ *    string name(node-set?)
+ * The name function returns a string containing a QName representing
+ * the name of the node in the argument node-set that is first in document
+ * order. The QName must represent the name with respect to the namespace
+ * declarations in effect on the node whose name is being represented.
+ * Typically, this will be the form in which the name occurred in the XML
+ * source. This need not be the case if there are namespace declarations
+ * in effect on the node that associate multiple prefixes with the same
+ * namespace. However, an implementation may include information about
+ * the original prefix in its representation of nodes; in this case, an
+ * implementation can ensure that the returned string is always the same
+ * as the QName used in the XML source. If the argument it omitted it
+ * defaults to the context node.
+ * Libxml keep the original prefix so the "real qualified name" used is
+ * returned.
+ */
+static void
+xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
+{
+    xmlXPathObjectPtr cur;
+
+    if (nargs == 0) {
+	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+	    ctxt->context->node));
+        nargs = 1;
+    }
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+        ((ctxt->value->type != XPATH_NODESET) &&
+         (ctxt->value->type != XPATH_XSLT_TREE)))
+        XP_ERROR(XPATH_INVALID_TYPE);
+    cur = valuePop(ctxt);
+
+    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
+        valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+    } else {
+        int i = 0;              /* Should be first in document order !!!!! */
+
+        switch (cur->nodesetval->nodeTab[i]->type) {
+            case XML_ELEMENT_NODE:
+            case XML_ATTRIBUTE_NODE:
+		if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
+		    valuePush(ctxt,
+			xmlXPathCacheNewCString(ctxt->context, ""));
+		else if ((cur->nodesetval->nodeTab[i]->ns == NULL) ||
+                         (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) {
+		    valuePush(ctxt,
+		        xmlXPathCacheNewString(ctxt->context,
+			    cur->nodesetval->nodeTab[i]->name));
+		} else {
+		    xmlChar *fullname;
+
+		    fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name,
+				     cur->nodesetval->nodeTab[i]->ns->prefix,
+				     NULL, 0);
+		    if (fullname == cur->nodesetval->nodeTab[i]->name)
+			fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name);
+		    if (fullname == NULL) {
+			XP_ERROR(XPATH_MEMORY_ERROR);
+		    }
+		    valuePush(ctxt, xmlXPathCacheWrapString(
+			ctxt->context, fullname));
+                }
+                break;
+            default:
+		valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+		    cur->nodesetval->nodeTab[i]));
+                xmlXPathLocalNameFunction(ctxt, 1);
+        }
+    }
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+
+/**
+ * xmlXPathStringFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the string() XPath function
+ *    string string(object?)
+ * The string function converts an object to a string as follows:
+ *    - A node-set is converted to a string by returning the value of
+ *      the node in the node-set that is first in document order.
+ *      If the node-set is empty, an empty string is returned.
+ *    - A number is converted to a string as follows
+ *      + NaN is converted to the string NaN
+ *      + positive zero is converted to the string 0
+ *      + negative zero is converted to the string 0
+ *      + positive infinity is converted to the string Infinity
+ *      + negative infinity is converted to the string -Infinity
+ *      + if the number is an integer, the number is represented in
+ *        decimal form as a Number with no decimal point and no leading
+ *        zeros, preceded by a minus sign (-) if the number is negative
+ *      + otherwise, the number is represented in decimal form as a
+ *        Number including a decimal point with at least one digit
+ *        before the decimal point and at least one digit after the
+ *        decimal point, preceded by a minus sign (-) if the number
+ *        is negative; there must be no leading zeros before the decimal
+ *        point apart possibly from the one required digit immediately
+ *        before the decimal point; beyond the one required digit
+ *        after the decimal point there must be as many, but only as
+ *        many, more digits as are needed to uniquely distinguish the
+ *        number from all other IEEE 754 numeric values.
+ *    - The boolean false value is converted to the string false.
+ *      The boolean true value is converted to the string true.
+ *
+ * If the argument is omitted, it defaults to a node-set with the
+ * context node as its only member.
+ */
+void
+xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    if (ctxt == NULL) return;
+    if (nargs == 0) {
+    valuePush(ctxt,
+	xmlXPathCacheWrapString(ctxt->context,
+	    xmlXPathCastNodeToString(ctxt->context->node)));
+	return;
+    }
+
+    CHECK_ARITY(1);
+    cur = valuePop(ctxt);
+    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
+    valuePush(ctxt, xmlXPathCacheConvertString(ctxt->context, cur));
+}
+
+/**
+ * xmlXPathStringLengthFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the string-length() XPath function
+ *    number string-length(string?)
+ * The string-length returns the number of characters in the string
+ * (see [3.6 Strings]). If the argument is omitted, it defaults to
+ * the context node converted to a string, in other words the value
+ * of the context node.
+ */
+void
+xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    if (nargs == 0) {
+        if ((ctxt == NULL) || (ctxt->context == NULL))
+	    return;
+	if (ctxt->context->node == NULL) {
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0));
+	} else {
+	    xmlChar *content;
+
+	    content = xmlXPathCastNodeToString(ctxt->context->node);
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
+		xmlUTF8Strlen(content)));
+	    xmlFree(content);
+	}
+	return;
+    }
+    CHECK_ARITY(1);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    cur = valuePop(ctxt);
+    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
+	xmlUTF8Strlen(cur->stringval)));
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+/**
+ * xmlXPathConcatFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the concat() XPath function
+ *    string concat(string, string, string*)
+ * The concat function returns the concatenation of its arguments.
+ */
+void
+xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur, newobj;
+    xmlChar *tmp;
+
+    if (ctxt == NULL) return;
+    if (nargs < 2) {
+	CHECK_ARITY(2);
+    }
+
+    CAST_TO_STRING;
+    cur = valuePop(ctxt);
+    if ((cur == NULL) || (cur->type != XPATH_STRING)) {
+	xmlXPathReleaseObject(ctxt->context, cur);
+	return;
+    }
+    nargs--;
+
+    while (nargs > 0) {
+	CAST_TO_STRING;
+	newobj = valuePop(ctxt);
+	if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
+	    xmlXPathReleaseObject(ctxt->context, newobj);
+	    xmlXPathReleaseObject(ctxt->context, cur);
+	    XP_ERROR(XPATH_INVALID_TYPE);
+	}
+	tmp = xmlStrcat(newobj->stringval, cur->stringval);
+	newobj->stringval = cur->stringval;
+	cur->stringval = tmp;
+	xmlXPathReleaseObject(ctxt->context, newobj);
+	nargs--;
+    }
+    valuePush(ctxt, cur);
+}
+
+/**
+ * xmlXPathContainsFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the contains() XPath function
+ *    boolean contains(string, string)
+ * The contains function returns true if the first argument string
+ * contains the second argument string, and otherwise returns false.
+ */
+void
+xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr hay, needle;
+
+    CHECK_ARITY(2);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    needle = valuePop(ctxt);
+    CAST_TO_STRING;
+    hay = valuePop(ctxt);
+
+    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
+	xmlXPathReleaseObject(ctxt->context, hay);
+	xmlXPathReleaseObject(ctxt->context, needle);
+	XP_ERROR(XPATH_INVALID_TYPE);
+    }
+    if (xmlStrstr(hay->stringval, needle->stringval))
+	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
+    else
+	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
+    xmlXPathReleaseObject(ctxt->context, hay);
+    xmlXPathReleaseObject(ctxt->context, needle);
+}
+
+/**
+ * xmlXPathStartsWithFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the starts-with() XPath function
+ *    boolean starts-with(string, string)
+ * The starts-with function returns true if the first argument string
+ * starts with the second argument string, and otherwise returns false.
+ */
+void
+xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr hay, needle;
+    int n;
+
+    CHECK_ARITY(2);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    needle = valuePop(ctxt);
+    CAST_TO_STRING;
+    hay = valuePop(ctxt);
+
+    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
+	xmlXPathReleaseObject(ctxt->context, hay);
+	xmlXPathReleaseObject(ctxt->context, needle);
+	XP_ERROR(XPATH_INVALID_TYPE);
+    }
+    n = xmlStrlen(needle->stringval);
+    if (xmlStrncmp(hay->stringval, needle->stringval, n))
+        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
+    else
+        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
+    xmlXPathReleaseObject(ctxt->context, hay);
+    xmlXPathReleaseObject(ctxt->context, needle);
+}
+
+/**
+ * xmlXPathSubstringFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the substring() XPath function
+ *    string substring(string, number, number?)
+ * The substring function returns the substring of the first argument
+ * starting at the position specified in the second argument with
+ * length specified in the third argument. For example,
+ * substring("12345",2,3) returns "234". If the third argument is not
+ * specified, it returns the substring starting at the position specified
+ * in the second argument and continuing to the end of the string. For
+ * example, substring("12345",2) returns "2345".  More precisely, each
+ * character in the string (see [3.6 Strings]) is considered to have a
+ * numeric position: the position of the first character is 1, the position
+ * of the second character is 2 and so on. The returned substring contains
+ * those characters for which the position of the character is greater than
+ * or equal to the second argument and, if the third argument is specified,
+ * less than the sum of the second and third arguments; the comparisons
+ * and addition used for the above follow the standard IEEE 754 rules. Thus:
+ *  - substring("12345", 1.5, 2.6) returns "234"
+ *  - substring("12345", 0, 3) returns "12"
+ *  - substring("12345", 0 div 0, 3) returns ""
+ *  - substring("12345", 1, 0 div 0) returns ""
+ *  - substring("12345", -42, 1 div 0) returns "12345"
+ *  - substring("12345", -1 div 0, 1 div 0) returns ""
+ */
+void
+xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr str, start, len;
+    double le=0, in;
+    int i, l, m;
+    xmlChar *ret;
+
+    if (nargs < 2) {
+	CHECK_ARITY(2);
+    }
+    if (nargs > 3) {
+	CHECK_ARITY(3);
+    }
+    /*
+     * take care of possible last (position) argument
+    */
+    if (nargs == 3) {
+	CAST_TO_NUMBER;
+	CHECK_TYPE(XPATH_NUMBER);
+	len = valuePop(ctxt);
+	le = len->floatval;
+	xmlXPathReleaseObject(ctxt->context, len);
+    }
+
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+    start = valuePop(ctxt);
+    in = start->floatval;
+    xmlXPathReleaseObject(ctxt->context, start);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    str = valuePop(ctxt);
+    m = xmlUTF8Strlen((const unsigned char *)str->stringval);
+
+    /*
+     * If last pos not present, calculate last position
+    */
+    if (nargs != 3) {
+	le = (double)m;
+	if (in < 1.0)
+	    in = 1.0;
+    }
+
+    /* Need to check for the special cases where either
+     * the index is NaN, the length is NaN, or both
+     * arguments are infinity (relying on Inf + -Inf = NaN)
+     */
+    if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
+        /*
+         * To meet the requirements of the spec, the arguments
+	 * must be converted to integer format before
+	 * initial index calculations are done
+         *
+         * First we go to integer form, rounding up
+	 * and checking for special cases
+         */
+        i = (int) in;
+        if (((double)i)+0.5 <= in) i++;
+
+	if (xmlXPathIsInf(le) == 1) {
+	    l = m;
+	    if (i < 1)
+		i = 1;
+	}
+	else if (xmlXPathIsInf(le) == -1 || le < 0.0)
+	    l = 0;
+	else {
+	    l = (int) le;
+	    if (((double)l)+0.5 <= le) l++;
+	}
+
+	/* Now we normalize inidices */
+        i -= 1;
+        l += i;
+        if (i < 0)
+            i = 0;
+        if (l > m)
+            l = m;
+
+        /* number of chars to copy */
+        l -= i;
+
+        ret = xmlUTF8Strsub(str->stringval, i, l);
+    }
+    else {
+        ret = NULL;
+    }
+    if (ret == NULL)
+	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
+    else {
+	valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, ret));
+	xmlFree(ret);
+    }
+    xmlXPathReleaseObject(ctxt->context, str);
+}
+
+/**
+ * xmlXPathSubstringBeforeFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the substring-before() XPath function
+ *    string substring-before(string, string)
+ * The substring-before function returns the substring of the first
+ * argument string that precedes the first occurrence of the second
+ * argument string in the first argument string, or the empty string
+ * if the first argument string does not contain the second argument
+ * string. For example, substring-before("1999/04/01","/") returns 1999.
+ */
+void
+xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+  xmlXPathObjectPtr str;
+  xmlXPathObjectPtr find;
+  xmlBufferPtr target;
+  const xmlChar *point;
+  int offset;
+
+  CHECK_ARITY(2);
+  CAST_TO_STRING;
+  find = valuePop(ctxt);
+  CAST_TO_STRING;
+  str = valuePop(ctxt);
+
+  target = xmlBufferCreate();
+  if (target) {
+    point = xmlStrstr(str->stringval, find->stringval);
+    if (point) {
+      offset = (int)(point - str->stringval);
+      xmlBufferAdd(target, str->stringval, offset);
+    }
+    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+	xmlBufferContent(target)));
+    xmlBufferFree(target);
+  }
+  xmlXPathReleaseObject(ctxt->context, str);
+  xmlXPathReleaseObject(ctxt->context, find);
+}
+
+/**
+ * xmlXPathSubstringAfterFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the substring-after() XPath function
+ *    string substring-after(string, string)
+ * The substring-after function returns the substring of the first
+ * argument string that follows the first occurrence of the second
+ * argument string in the first argument string, or the empty stringi
+ * if the first argument string does not contain the second argument
+ * string. For example, substring-after("1999/04/01","/") returns 04/01,
+ * and substring-after("1999/04/01","19") returns 99/04/01.
+ */
+void
+xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+  xmlXPathObjectPtr str;
+  xmlXPathObjectPtr find;
+  xmlBufferPtr target;
+  const xmlChar *point;
+  int offset;
+
+  CHECK_ARITY(2);
+  CAST_TO_STRING;
+  find = valuePop(ctxt);
+  CAST_TO_STRING;
+  str = valuePop(ctxt);
+
+  target = xmlBufferCreate();
+  if (target) {
+    point = xmlStrstr(str->stringval, find->stringval);
+    if (point) {
+      offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
+      xmlBufferAdd(target, &str->stringval[offset],
+		   xmlStrlen(str->stringval) - offset);
+    }
+    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+	xmlBufferContent(target)));
+    xmlBufferFree(target);
+  }
+  xmlXPathReleaseObject(ctxt->context, str);
+  xmlXPathReleaseObject(ctxt->context, find);
+}
+
+/**
+ * xmlXPathNormalizeFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the normalize-space() XPath function
+ *    string normalize-space(string?)
+ * The normalize-space function returns the argument string with white
+ * space normalized by stripping leading and trailing whitespace
+ * and replacing sequences of whitespace characters by a single
+ * space. Whitespace characters are the same allowed by the S production
+ * in XML. If the argument is omitted, it defaults to the context
+ * node converted to a string, in other words the value of the context node.
+ */
+void
+xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+  xmlXPathObjectPtr obj = NULL;
+  xmlChar *source = NULL;
+  xmlBufferPtr target;
+  xmlChar blank;
+
+  if (ctxt == NULL) return;
+  if (nargs == 0) {
+    /* Use current context node */
+      valuePush(ctxt,
+	  xmlXPathCacheWrapString(ctxt->context,
+	    xmlXPathCastNodeToString(ctxt->context->node)));
+    nargs = 1;
+  }
+
+  CHECK_ARITY(1);
+  CAST_TO_STRING;
+  CHECK_TYPE(XPATH_STRING);
+  obj = valuePop(ctxt);
+  source = obj->stringval;
+
+  target = xmlBufferCreate();
+  if (target && source) {
+
+    /* Skip leading whitespaces */
+    while (IS_BLANK_CH(*source))
+      source++;
+
+    /* Collapse intermediate whitespaces, and skip trailing whitespaces */
+    blank = 0;
+    while (*source) {
+      if (IS_BLANK_CH(*source)) {
+	blank = 0x20;
+      } else {
+	if (blank) {
+	  xmlBufferAdd(target, &blank, 1);
+	  blank = 0;
+	}
+	xmlBufferAdd(target, source, 1);
+      }
+      source++;
+    }
+    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+	xmlBufferContent(target)));
+    xmlBufferFree(target);
+  }
+  xmlXPathReleaseObject(ctxt->context, obj);
+}
+
+/**
+ * xmlXPathTranslateFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the translate() XPath function
+ *    string translate(string, string, string)
+ * The translate function returns the first argument string with
+ * occurrences of characters in the second argument string replaced
+ * by the character at the corresponding position in the third argument
+ * string. For example, translate("bar","abc","ABC") returns the string
+ * BAr. If there is a character in the second argument string with no
+ * character at a corresponding position in the third argument string
+ * (because the second argument string is longer than the third argument
+ * string), then occurrences of that character in the first argument
+ * string are removed. For example, translate("--aaa--","abc-","ABC")
+ * returns "AAA". If a character occurs more than once in second
+ * argument string, then the first occurrence determines the replacement
+ * character. If the third argument string is longer than the second
+ * argument string, then excess characters are ignored.
+ */
+void
+xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr str;
+    xmlXPathObjectPtr from;
+    xmlXPathObjectPtr to;
+    xmlBufferPtr target;
+    int offset, max;
+    xmlChar ch;
+    const xmlChar *point;
+    xmlChar *cptr;
+
+    CHECK_ARITY(3);
+
+    CAST_TO_STRING;
+    to = valuePop(ctxt);
+    CAST_TO_STRING;
+    from = valuePop(ctxt);
+    CAST_TO_STRING;
+    str = valuePop(ctxt);
+
+    target = xmlBufferCreate();
+    if (target) {
+	max = xmlUTF8Strlen(to->stringval);
+	for (cptr = str->stringval; (ch=*cptr); ) {
+	    offset = xmlUTF8Strloc(from->stringval, cptr);
+	    if (offset >= 0) {
+		if (offset < max) {
+		    point = xmlUTF8Strpos(to->stringval, offset);
+		    if (point)
+			xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1));
+		}
+	    } else
+		xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
+
+	    /* Step to next character in input */
+	    cptr++;
+	    if ( ch & 0x80 ) {
+		/* if not simple ascii, verify proper format */
+		if ( (ch & 0xc0) != 0xc0 ) {
+		    xmlGenericError(xmlGenericErrorContext,
+			"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+		    break;
+		}
+		/* then skip over remaining bytes for this char */
+		while ( (ch <<= 1) & 0x80 )
+		    if ( (*cptr++ & 0xc0) != 0x80 ) {
+			xmlGenericError(xmlGenericErrorContext,
+			    "xmlXPathTranslateFunction: Invalid UTF8 string\n");
+			break;
+		    }
+		if (ch & 0x80) /* must have had error encountered */
+		    break;
+	    }
+	}
+    }
+    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+	xmlBufferContent(target)));
+    xmlBufferFree(target);
+    xmlXPathReleaseObject(ctxt->context, str);
+    xmlXPathReleaseObject(ctxt->context, from);
+    xmlXPathReleaseObject(ctxt->context, to);
+}
+
+/**
+ * xmlXPathBooleanFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the boolean() XPath function
+ *    boolean boolean(object)
+ * The boolean function converts its argument to a boolean as follows:
+ *    - a number is true if and only if it is neither positive or
+ *      negative zero nor NaN
+ *    - a node-set is true if and only if it is non-empty
+ *    - a string is true if and only if its length is non-zero
+ */
+void
+xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+
+    CHECK_ARITY(1);
+    cur = valuePop(ctxt);
+    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
+    cur = xmlXPathCacheConvertBoolean(ctxt->context, cur);
+    valuePush(ctxt, cur);
+}
+
+/**
+ * xmlXPathNotFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the not() XPath function
+ *    boolean not(boolean)
+ * The not function returns true if its argument is false,
+ * and false otherwise.
+ */
+void
+xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(1);
+    CAST_TO_BOOLEAN;
+    CHECK_TYPE(XPATH_BOOLEAN);
+    ctxt->value->boolval = ! ctxt->value->boolval;
+}
+
+/**
+ * xmlXPathTrueFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the true() XPath function
+ *    boolean true()
+ */
+void
+xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
+}
+
+/**
+ * xmlXPathFalseFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the false() XPath function
+ *    boolean false()
+ */
+void
+xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
+}
+
+/**
+ * xmlXPathLangFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the lang() XPath function
+ *    boolean lang(string)
+ * The lang function returns true or false depending on whether the
+ * language of the context node as specified by xml:lang attributes
+ * is the same as or is a sublanguage of the language specified by
+ * the argument string. The language of the context node is determined
+ * by the value of the xml:lang attribute on the context node, or, if
+ * the context node has no xml:lang attribute, by the value of the
+ * xml:lang attribute on the nearest ancestor of the context node that
+ * has an xml:lang attribute. If there is no such attribute, then lang
+ * returns false. If there is such an attribute, then lang returns
+ * true if the attribute value is equal to the argument ignoring case,
+ * or if there is some suffix starting with - such that the attribute
+ * value is equal to the argument ignoring that suffix of the attribute
+ * value and ignoring case.
+ */
+void
+xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr val = NULL;
+    const xmlChar *theLang = NULL;
+    const xmlChar *lang;
+    int ret = 0;
+    int i;
+
+    CHECK_ARITY(1);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    val = valuePop(ctxt);
+    lang = val->stringval;
+    theLang = xmlNodeGetLang(ctxt->context->node);
+    if ((theLang != NULL) && (lang != NULL)) {
+        for (i = 0;lang[i] != 0;i++)
+	    if (toupper(lang[i]) != toupper(theLang[i]))
+	        goto not_equal;
+	if ((theLang[i] == 0) || (theLang[i] == '-'))
+	    ret = 1;
+    }
+not_equal:
+    if (theLang != NULL)
+	xmlFree((void *)theLang);
+
+    xmlXPathReleaseObject(ctxt->context, val);
+    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
+}
+
+/**
+ * xmlXPathNumberFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the number() XPath function
+ *    number number(object?)
+ */
+void
+xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+    double res;
+
+    if (ctxt == NULL) return;
+    if (nargs == 0) {
+	if (ctxt->context->node == NULL) {
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0.0));
+	} else {
+	    xmlChar* content = xmlNodeGetContent(ctxt->context->node);
+
+	    res = xmlXPathStringEvalNumber(content);
+	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
+	    xmlFree(content);
+	}
+	return;
+    }
+
+    CHECK_ARITY(1);
+    cur = valuePop(ctxt);
+    valuePush(ctxt, xmlXPathCacheConvertNumber(ctxt->context, cur));
+}
+
+/**
+ * xmlXPathSumFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the sum() XPath function
+ *    number sum(node-set)
+ * The sum function returns the sum of the values of the nodes in
+ * the argument node-set.
+ */
+void
+xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr cur;
+    int i;
+    double res = 0.0;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_NODESET) &&
+	 (ctxt->value->type != XPATH_XSLT_TREE)))
+	XP_ERROR(XPATH_INVALID_TYPE);
+    cur = valuePop(ctxt);
+
+    if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
+	for (i = 0; i < cur->nodesetval->nodeNr; i++) {
+	    res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
+	}
+    }
+    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
+    xmlXPathReleaseObject(ctxt->context, cur);
+}
+
+/*
+ * To assure working code on multiple platforms, we want to only depend
+ * upon the characteristic truncation of converting a floating point value
+ * to an integer.  Unfortunately, because of the different storage sizes
+ * of our internal floating point value (double) and integer (int), we
+ * can't directly convert (see bug 301162).  This macro is a messy
+ * 'workaround'
+ */
+#define XTRUNC(f, v)            \
+    f = fmod((v), INT_MAX);     \
+    f = (v) - (f) + (double)((int)(f));
+
+/**
+ * xmlXPathFloorFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the floor() XPath function
+ *    number floor(number)
+ * The floor function returns the largest (closest to positive infinity)
+ * number that is not greater than the argument and that is an integer.
+ */
+void
+xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    double f;
+
+    CHECK_ARITY(1);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+
+    XTRUNC(f, ctxt->value->floatval);
+    if (f != ctxt->value->floatval) {
+	if (ctxt->value->floatval > 0)
+	    ctxt->value->floatval = f;
+	else
+	    ctxt->value->floatval = f - 1;
+    }
+}
+
+/**
+ * xmlXPathCeilingFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the ceiling() XPath function
+ *    number ceiling(number)
+ * The ceiling function returns the smallest (closest to negative infinity)
+ * number that is not less than the argument and that is an integer.
+ */
+void
+xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    double f;
+
+    CHECK_ARITY(1);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+
+#if 0
+    ctxt->value->floatval = ceil(ctxt->value->floatval);
+#else
+    XTRUNC(f, ctxt->value->floatval);
+    if (f != ctxt->value->floatval) {
+	if (ctxt->value->floatval > 0)
+	    ctxt->value->floatval = f + 1;
+	else {
+	    if (ctxt->value->floatval < 0 && f == 0)
+	        ctxt->value->floatval = xmlXPathNZERO;
+	    else
+	        ctxt->value->floatval = f;
+	}
+
+    }
+#endif
+}
+
+/**
+ * xmlXPathRoundFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the round() XPath function
+ *    number round(number)
+ * The round function returns the number that is closest to the
+ * argument and that is an integer. If there are two such numbers,
+ * then the one that is even is returned.
+ */
+void
+xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    double f;
+
+    CHECK_ARITY(1);
+    CAST_TO_NUMBER;
+    CHECK_TYPE(XPATH_NUMBER);
+
+    if ((xmlXPathIsNaN(ctxt->value->floatval)) ||
+	(xmlXPathIsInf(ctxt->value->floatval) == 1) ||
+	(xmlXPathIsInf(ctxt->value->floatval) == -1) ||
+	(ctxt->value->floatval == 0.0))
+	return;
+
+    XTRUNC(f, ctxt->value->floatval);
+    if (ctxt->value->floatval < 0) {
+	if (ctxt->value->floatval < f - 0.5)
+	    ctxt->value->floatval = f - 1;
+	else
+	    ctxt->value->floatval = f;
+	if (ctxt->value->floatval == 0)
+	    ctxt->value->floatval = xmlXPathNZERO;
+    } else {
+	if (ctxt->value->floatval < f + 0.5)
+	    ctxt->value->floatval = f;
+	else
+	    ctxt->value->floatval = f + 1;
+    }
+}
+
+/************************************************************************
+ *									*
+ *			The Parser					*
+ *									*
+ ************************************************************************/
+
+/*
+ * a few forward declarations since we use a recursive call based
+ * implementation.
+ */
+static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort);
+static void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
+static void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
+static void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt);
+static xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt,
+	                                  int qualified);
+
+/**
+ * xmlXPathCurrentChar:
+ * @ctxt:  the XPath parser context
+ * @cur:  pointer to the beginning of the char
+ * @len:  pointer to the length of the char read
+ *
+ * The current char value, if using UTF-8 this may actually span multiple
+ * bytes in the input buffer.
+ *
+ * Returns the current char value and its length
+ */
+
+static int
+xmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
+    unsigned char c;
+    unsigned int val;
+    const xmlChar *cur;
+
+    if (ctxt == NULL)
+	return(0);
+    cur = ctxt->cur;
+
+    /*
+     * We are supposed to handle UTF8, check it's valid
+     * From rfc2044: encoding of the Unicode values on UTF-8:
+     *
+     * 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
+     *
+     * Check for the 0x110000 limit too
+     */
+    c = *cur;
+    if (c & 0x80) {
+	if ((cur[1] & 0xc0) != 0x80)
+	    goto encoding_error;
+	if ((c & 0xe0) == 0xe0) {
+
+	    if ((cur[2] & 0xc0) != 0x80)
+		goto encoding_error;
+	    if ((c & 0xf0) == 0xf0) {
+		if (((c & 0xf8) != 0xf0) ||
+		    ((cur[3] & 0xc0) != 0x80))
+		    goto encoding_error;
+		/* 4-byte code */
+		*len = 4;
+		val = (cur[0] & 0x7) << 18;
+		val |= (cur[1] & 0x3f) << 12;
+		val |= (cur[2] & 0x3f) << 6;
+		val |= cur[3] & 0x3f;
+	    } else {
+	      /* 3-byte code */
+		*len = 3;
+		val = (cur[0] & 0xf) << 12;
+		val |= (cur[1] & 0x3f) << 6;
+		val |= cur[2] & 0x3f;
+	    }
+	} else {
+	  /* 2-byte code */
+	    *len = 2;
+	    val = (cur[0] & 0x1f) << 6;
+	    val |= cur[1] & 0x3f;
+	}
+	if (!IS_CHAR(val)) {
+	    XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
+	}
+	return(val);
+    } else {
+	/* 1-byte code */
+	*len = 1;
+	return((int) *cur);
+    }
+encoding_error:
+    /*
+     * If we detect an UTF8 error that probably means that the
+     * input encoding didn't get properly advertised in the
+     * declaration header. Report the error and switch the encoding
+     * to ISO-Latin-1 (if you don't like this policy, just declare the
+     * encoding !)
+     */
+    *len = 0;
+    XP_ERROR0(XPATH_ENCODING_ERROR);
+}
+
+/**
+ * xmlXPathParseNCName:
+ * @ctxt:  the XPath Parser context
+ *
+ * parse an XML namespace non qualified name.
+ *
+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
+ *
+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
+ *                       CombiningChar | Extender
+ *
+ * Returns the namespace name or NULL
+ */
+
+xmlChar *
+xmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
+    const xmlChar *in;
+    xmlChar *ret;
+    int count = 0;
+
+    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == '.') ||
+	       (*in == '-'))
+	    in++;
+	if ((*in == ' ') || (*in == '>') || (*in == '/') ||
+            (*in == '[') || (*in == ']') || (*in == ':') ||
+            (*in == '@') || (*in == '*')) {
+	    count = in - ctxt->cur;
+	    if (count == 0)
+		return(NULL);
+	    ret = xmlStrndup(ctxt->cur, count);
+	    ctxt->cur = in;
+	    return(ret);
+	}
+    }
+    return(xmlXPathParseNameComplex(ctxt, 0));
+}
+
+
+/**
+ * xmlXPathParseQName:
+ * @ctxt:  the XPath Parser context
+ * @prefix:  a xmlChar **
+ *
+ * parse an XML qualified name
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns the function returns the local part, and prefix is updated
+ *   to get the Prefix if any.
+ */
+
+static xmlChar *
+xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
+    xmlChar *ret = NULL;
+
+    *prefix = NULL;
+    ret = xmlXPathParseNCName(ctxt);
+    if (ret && CUR == ':') {
+        *prefix = ret;
+	NEXT;
+	ret = xmlXPathParseNCName(ctxt);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathParseName:
+ * @ctxt:  the XPath Parser context
+ *
+ * parse an XML name
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * Returns the namespace name or NULL
+ */
+
+xmlChar *
+xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
+    const xmlChar *in;
+    xmlChar *ret;
+    int count = 0;
+
+    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_') || (*in == ':')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == '-') ||
+	       (*in == ':') || (*in == '.'))
+	    in++;
+	if ((*in > 0) && (*in < 0x80)) {
+	    count = in - ctxt->cur;
+	    ret = xmlStrndup(ctxt->cur, count);
+	    ctxt->cur = in;
+	    return(ret);
+	}
+    }
+    return(xmlXPathParseNameComplex(ctxt, 1));
+}
+
+static xmlChar *
+xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
+    xmlChar buf[XML_MAX_NAMELEN + 5];
+    int len = 0, l;
+    int c;
+
+    /*
+     * Handler for more complex cases
+     */
+    c = CUR_CHAR(l);
+    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+        (c == '[') || (c == ']') || (c == '@') || /* accelerators */
+        (c == '*') || /* accelerators */
+	(!IS_LETTER(c) && (c != '_') &&
+         ((qualified) && (c != ':')))) {
+	return(NULL);
+    }
+
+    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || ((qualified) && (c == ':')) ||
+	    (IS_COMBINING(c)) ||
+	    (IS_EXTENDER(c)))) {
+	COPY_BUF(l,buf,len,c);
+	NEXTL(l);
+	c = CUR_CHAR(l);
+	if (len >= XML_MAX_NAMELEN) {
+	    /*
+	     * Okay someone managed to make a huge name, so he's ready to pay
+	     * for the processing speed.
+	     */
+	    xmlChar *buffer;
+	    int max = len * 2;
+
+	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+	    if (buffer == NULL) {
+		XP_ERRORNULL(XPATH_MEMORY_ERROR);
+	    }
+	    memcpy(buffer, buf, len);
+	    while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
+		   (c == '.') || (c == '-') ||
+		   (c == '_') || ((qualified) && (c == ':')) ||
+		   (IS_COMBINING(c)) ||
+		   (IS_EXTENDER(c))) {
+		if (len + 10 > max) {
+		    max *= 2;
+		    buffer = (xmlChar *) xmlRealloc(buffer,
+			                            max * sizeof(xmlChar));
+		    if (buffer == NULL) {
+			XP_ERRORNULL(XPATH_MEMORY_ERROR);
+		    }
+		}
+		COPY_BUF(l,buffer,len,c);
+		NEXTL(l);
+		c = CUR_CHAR(l);
+	    }
+	    buffer[len] = 0;
+	    return(buffer);
+	}
+    }
+    if (len == 0)
+	return(NULL);
+    return(xmlStrndup(buf, len));
+}
+
+#define MAX_FRAC 20
+
+/*
+ * These are used as divisors for the fractional part of a number.
+ * Since the table includes 1.0 (representing '0' fractional digits),
+ * it must be dimensioned at MAX_FRAC+1 (bug 133921)
+ */
+static double my_pow10[MAX_FRAC+1] = {
+    1.0, 10.0, 100.0, 1000.0, 10000.0,
+    100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
+    10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0,
+    100000000000000.0,
+    1000000000000000.0, 10000000000000000.0, 100000000000000000.0,
+    1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0
+};
+
+/**
+ * xmlXPathStringEvalNumber:
+ * @str:  A string to scan
+ *
+ *  [30a]  Float  ::= Number ('e' Digits?)?
+ *
+ *  [30]   Number ::=   Digits ('.' Digits?)?
+ *                    | '.' Digits
+ *  [31]   Digits ::=   [0-9]+
+ *
+ * Compile a Number in the string
+ * In complement of the Number expression, this function also handles
+ * negative values : '-' Number.
+ *
+ * Returns the double value.
+ */
+double
+xmlXPathStringEvalNumber(const xmlChar *str) {
+    const xmlChar *cur = str;
+    double ret;
+    int ok = 0;
+    int isneg = 0;
+    int exponent = 0;
+    int is_exponent_negative = 0;
+#ifdef __GNUC__
+    unsigned long tmp = 0;
+    double temp;
+#endif
+    if (cur == NULL) return(0);
+    while (IS_BLANK_CH(*cur)) cur++;
+    if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
+        return(xmlXPathNAN);
+    }
+    if (*cur == '-') {
+	isneg = 1;
+	cur++;
+    }
+
+#ifdef __GNUC__
+    /*
+     * tmp/temp is a workaround against a gcc compiler bug
+     * http://veillard.com/gcc.bug
+     */
+    ret = 0;
+    while ((*cur >= '0') && (*cur <= '9')) {
+	ret = ret * 10;
+	tmp = (*cur - '0');
+	ok = 1;
+	cur++;
+	temp = (double) tmp;
+	ret = ret + temp;
+    }
+#else
+    ret = 0;
+    while ((*cur >= '0') && (*cur <= '9')) {
+	ret = ret * 10 + (*cur - '0');
+	ok = 1;
+	cur++;
+    }
+#endif
+
+    if (*cur == '.') {
+	int v, frac = 0;
+	double fraction = 0;
+
+        cur++;
+	if (((*cur < '0') || (*cur > '9')) && (!ok)) {
+	    return(xmlXPathNAN);
+	}
+	while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) {
+	    v = (*cur - '0');
+	    fraction = fraction * 10 + v;
+	    frac = frac + 1;
+	    cur++;
+	}
+	fraction /= my_pow10[frac];
+	ret = ret + fraction;
+	while ((*cur >= '0') && (*cur <= '9'))
+	    cur++;
+    }
+    if ((*cur == 'e') || (*cur == 'E')) {
+      cur++;
+      if (*cur == '-') {
+	is_exponent_negative = 1;
+	cur++;
+      } else if (*cur == '+') {
+        cur++;
+      }
+      while ((*cur >= '0') && (*cur <= '9')) {
+	exponent = exponent * 10 + (*cur - '0');
+	cur++;
+      }
+    }
+    while (IS_BLANK_CH(*cur)) cur++;
+    if (*cur != 0) return(xmlXPathNAN);
+    if (isneg) ret = -ret;
+    if (is_exponent_negative) exponent = -exponent;
+    ret *= pow(10.0, (double)exponent);
+    return(ret);
+}
+
+/**
+ * xmlXPathCompNumber:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [30]   Number ::=   Digits ('.' Digits?)?
+ *                    | '.' Digits
+ *  [31]   Digits ::=   [0-9]+
+ *
+ * Compile a Number, then push it on the stack
+ *
+ */
+static void
+xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
+{
+    double ret = 0.0;
+    double mult = 1;
+    int ok = 0;
+    int exponent = 0;
+    int is_exponent_negative = 0;
+#ifdef __GNUC__
+    unsigned long tmp = 0;
+    double temp;
+#endif
+
+    CHECK_ERROR;
+    if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
+        XP_ERROR(XPATH_NUMBER_ERROR);
+    }
+#ifdef __GNUC__
+    /*
+     * tmp/temp is a workaround against a gcc compiler bug
+     * http://veillard.com/gcc.bug
+     */
+    ret = 0;
+    while ((CUR >= '0') && (CUR <= '9')) {
+	ret = ret * 10;
+	tmp = (CUR - '0');
+        ok = 1;
+        NEXT;
+	temp = (double) tmp;
+	ret = ret + temp;
+    }
+#else
+    ret = 0;
+    while ((CUR >= '0') && (CUR <= '9')) {
+	ret = ret * 10 + (CUR - '0');
+	ok = 1;
+	NEXT;
+    }
+#endif
+    if (CUR == '.') {
+        NEXT;
+        if (((CUR < '0') || (CUR > '9')) && (!ok)) {
+            XP_ERROR(XPATH_NUMBER_ERROR);
+        }
+        while ((CUR >= '0') && (CUR <= '9')) {
+            mult /= 10;
+            ret = ret + (CUR - '0') * mult;
+            NEXT;
+        }
+    }
+    if ((CUR == 'e') || (CUR == 'E')) {
+        NEXT;
+        if (CUR == '-') {
+            is_exponent_negative = 1;
+            NEXT;
+        } else if (CUR == '+') {
+	    NEXT;
+	}
+        while ((CUR >= '0') && (CUR <= '9')) {
+            exponent = exponent * 10 + (CUR - '0');
+            NEXT;
+        }
+        if (is_exponent_negative)
+            exponent = -exponent;
+        ret *= pow(10.0, (double) exponent);
+    }
+    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
+                   xmlXPathCacheNewFloat(ctxt->context, ret), NULL);
+}
+
+/**
+ * xmlXPathParseLiteral:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parse a Literal
+ *
+ *  [29]   Literal ::=   '"' [^"]* '"'
+ *                    | "'" [^']* "'"
+ *
+ * Returns the value found or NULL in case of error
+ */
+static xmlChar *
+xmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
+    const xmlChar *q;
+    xmlChar *ret = NULL;
+
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	XP_ERRORNULL(XPATH_START_LITERAL_ERROR);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathCompLiteral:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parse a Literal and push it on the stack.
+ *
+ *  [29]   Literal ::=   '"' [^"]* '"'
+ *                    | "'" [^']* "'"
+ *
+ * TODO: xmlXPathCompLiteral memory allocation could be improved.
+ */
+static void
+xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
+    const xmlChar *q;
+    xmlChar *ret = NULL;
+
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (!IS_CHAR_CH(CUR)) {
+	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	XP_ERROR(XPATH_START_LITERAL_ERROR);
+    }
+    if (ret == NULL) return;
+    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
+	           xmlXPathCacheNewString(ctxt->context, ret), NULL);
+    xmlFree(ret);
+}
+
+/**
+ * xmlXPathCompVariableReference:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parse a VariableReference, evaluate it and push it on the stack.
+ *
+ * The variable bindings consist of a mapping from variable names
+ * to variable values. The value of a variable is an object, which can be
+ * of any of the types that are possible for the value of an expression,
+ * and may also be of additional types not specified here.
+ *
+ * Early evaluation is possible since:
+ * The variable bindings [...] used to evaluate a subexpression are
+ * always the same as those used to evaluate the containing expression.
+ *
+ *  [36]   VariableReference ::=   '$' QName
+ */
+static void
+xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
+    xmlChar *name;
+    xmlChar *prefix;
+
+    SKIP_BLANKS;
+    if (CUR != '$') {
+	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
+    }
+    NEXT;
+    name = xmlXPathParseQName(ctxt, &prefix);
+    if (name == NULL) {
+	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
+    }
+    ctxt->comp->last = -1;
+    PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
+	           name, prefix);
+    SKIP_BLANKS;
+    if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
+	XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);
+    }
+}
+
+/**
+ * xmlXPathIsNodeType:
+ * @name:  a name string
+ *
+ * Is the name given a NodeType one.
+ *
+ *  [38]   NodeType ::=   'comment'
+ *                    | 'text'
+ *                    | 'processing-instruction'
+ *                    | 'node'
+ *
+ * Returns 1 if true 0 otherwise
+ */
+int
+xmlXPathIsNodeType(const xmlChar *name) {
+    if (name == NULL)
+	return(0);
+
+    if (xmlStrEqual(name, BAD_CAST "node"))
+	return(1);
+    if (xmlStrEqual(name, BAD_CAST "text"))
+	return(1);
+    if (xmlStrEqual(name, BAD_CAST "comment"))
+	return(1);
+    if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
+	return(1);
+    return(0);
+}
+
+/**
+ * xmlXPathCompFunctionCall:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [16]   FunctionCall ::=   FunctionName '(' ( Argument ( ',' Argument)*)? ')'
+ *  [17]   Argument ::=   Expr
+ *
+ * Compile a function call, the evaluation of all arguments are
+ * pushed on the stack
+ */
+static void
+xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
+    xmlChar *name;
+    xmlChar *prefix;
+    int nbargs = 0;
+    int sort = 1;
+
+    name = xmlXPathParseQName(ctxt, &prefix);
+    if (name == NULL) {
+	xmlFree(prefix);
+	XP_ERROR(XPATH_EXPR_ERROR);
+    }
+    SKIP_BLANKS;
+#ifdef DEBUG_EXPR
+    if (prefix == NULL)
+	xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
+			name);
+    else
+	xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
+			prefix, name);
+#endif
+
+    if (CUR != '(') {
+	XP_ERROR(XPATH_EXPR_ERROR);
+    }
+    NEXT;
+    SKIP_BLANKS;
+
+    /*
+    * Optimization for count(): we don't need the node-set to be sorted.
+    */
+    if ((prefix == NULL) && (name[0] == 'c') &&
+	xmlStrEqual(name, BAD_CAST "count"))
+    {
+	sort = 0;
+    }
+    ctxt->comp->last = -1;
+    if (CUR != ')') {
+	while (CUR != 0) {
+	    int op1 = ctxt->comp->last;
+	    ctxt->comp->last = -1;
+	    xmlXPathCompileExpr(ctxt, sort);
+	    if (ctxt->error != XPATH_EXPRESSION_OK) {
+		xmlFree(name);
+		xmlFree(prefix);
+		return;
+	    }
+	    PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
+	    nbargs++;
+	    if (CUR == ')') break;
+	    if (CUR != ',') {
+		XP_ERROR(XPATH_EXPR_ERROR);
+	    }
+	    NEXT;
+	    SKIP_BLANKS;
+	}
+    }
+    PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
+	           name, prefix);
+    NEXT;
+    SKIP_BLANKS;
+}
+
+/**
+ * xmlXPathCompPrimaryExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [15]   PrimaryExpr ::=   VariableReference
+ *                | '(' Expr ')'
+ *                | Literal
+ *                | Number
+ *                | FunctionCall
+ *
+ * Compile a primary expression.
+ */
+static void
+xmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
+    SKIP_BLANKS;
+    if (CUR == '$') xmlXPathCompVariableReference(ctxt);
+    else if (CUR == '(') {
+	NEXT;
+	SKIP_BLANKS;
+	xmlXPathCompileExpr(ctxt, 1);
+	CHECK_ERROR;
+	if (CUR != ')') {
+	    XP_ERROR(XPATH_EXPR_ERROR);
+	}
+	NEXT;
+	SKIP_BLANKS;
+    } else if (IS_ASCII_DIGIT(CUR) || (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
+	xmlXPathCompNumber(ctxt);
+    } else if ((CUR == '\'') || (CUR == '"')) {
+	xmlXPathCompLiteral(ctxt);
+    } else {
+	xmlXPathCompFunctionCall(ctxt);
+    }
+    SKIP_BLANKS;
+}
+
+/**
+ * xmlXPathCompFilterExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [20]   FilterExpr ::=   PrimaryExpr
+ *               | FilterExpr Predicate
+ *
+ * Compile a filter expression.
+ * Square brackets are used to filter expressions in the same way that
+ * they are used in location paths. It is an error if the expression to
+ * be filtered does not evaluate to a node-set. The context node list
+ * used for evaluating the expression in square brackets is the node-set
+ * to be filtered listed in document order.
+ */
+
+static void
+xmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompPrimaryExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+
+    while (CUR == '[') {
+	xmlXPathCompPredicate(ctxt, 1);
+	SKIP_BLANKS;
+    }
+
+
+}
+
+/**
+ * xmlXPathScanName:
+ * @ctxt:  the XPath Parser context
+ *
+ * Trickery: parse an XML name but without consuming the input flow
+ * Needed to avoid insanity in the parser state.
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (S Name)*
+ *
+ * Returns the Name parsed or NULL
+ */
+
+static xmlChar *
+xmlXPathScanName(xmlXPathParserContextPtr ctxt) {
+    int len = 0, l;
+    int c;
+    const xmlChar *cur;
+    xmlChar *ret;
+
+    cur = ctxt->cur;
+
+    c = CUR_CHAR(l);
+    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
+	(!IS_LETTER(c) && (c != '_') &&
+         (c != ':'))) {
+	return(NULL);
+    }
+
+    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+	    (c == '_') || (c == ':') ||
+	    (IS_COMBINING(c)) ||
+	    (IS_EXTENDER(c)))) {
+	len += l;
+	NEXTL(l);
+	c = CUR_CHAR(l);
+    }
+    ret = xmlStrndup(cur, ctxt->cur - cur);
+    ctxt->cur = cur;
+    return(ret);
+}
+
+/**
+ * xmlXPathCompPathExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [19]   PathExpr ::=   LocationPath
+ *               | FilterExpr
+ *               | FilterExpr '/' RelativeLocationPath
+ *               | FilterExpr '//' RelativeLocationPath
+ *
+ * Compile a path expression.
+ * The / operator and // operators combine an arbitrary expression
+ * and a relative location path. It is an error if the expression
+ * does not evaluate to a node-set.
+ * The / operator does composition in the same way as when / is
+ * used in a location path. As in location paths, // is short for
+ * /descendant-or-self::node()/.
+ */
+
+static void
+xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
+    int lc = 1;           /* Should we branch to LocationPath ?         */
+    xmlChar *name = NULL; /* we may have to preparse a name to find out */
+
+    SKIP_BLANKS;
+    if ((CUR == '$') || (CUR == '(') ||
+	(IS_ASCII_DIGIT(CUR)) ||
+        (CUR == '\'') || (CUR == '"') ||
+	(CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
+	lc = 0;
+    } else if (CUR == '*') {
+	/* relative or absolute location path */
+	lc = 1;
+    } else if (CUR == '/') {
+	/* relative or absolute location path */
+	lc = 1;
+    } else if (CUR == '@') {
+	/* relative abbreviated attribute location path */
+	lc = 1;
+    } else if (CUR == '.') {
+	/* relative abbreviated attribute location path */
+	lc = 1;
+    } else {
+	/*
+	 * Problem is finding if we have a name here whether it's:
+	 *   - a nodetype
+	 *   - a function call in which case it's followed by '('
+	 *   - an axis in which case it's followed by ':'
+	 *   - a element name
+	 * We do an a priori analysis here rather than having to
+	 * maintain parsed token content through the recursive function
+	 * calls. This looks uglier but makes the code easier to
+	 * read/write/debug.
+	 */
+	SKIP_BLANKS;
+	name = xmlXPathScanName(ctxt);
+	if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
+#ifdef DEBUG_STEP
+	    xmlGenericError(xmlGenericErrorContext,
+		    "PathExpr: Axis\n");
+#endif
+	    lc = 1;
+	    xmlFree(name);
+	} else if (name != NULL) {
+	    int len =xmlStrlen(name);
+
+
+	    while (NXT(len) != 0) {
+		if (NXT(len) == '/') {
+		    /* element name */
+#ifdef DEBUG_STEP
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PathExpr: AbbrRelLocation\n");
+#endif
+		    lc = 1;
+		    break;
+		} else if (IS_BLANK_CH(NXT(len))) {
+		    /* ignore blanks */
+		    ;
+		} else if (NXT(len) == ':') {
+#ifdef DEBUG_STEP
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PathExpr: AbbrRelLocation\n");
+#endif
+		    lc = 1;
+		    break;
+		} else if ((NXT(len) == '(')) {
+		    /* Note Type or Function */
+		    if (xmlXPathIsNodeType(name)) {
+#ifdef DEBUG_STEP
+		        xmlGenericError(xmlGenericErrorContext,
+				"PathExpr: Type search\n");
+#endif
+			lc = 1;
+		    } else {
+#ifdef DEBUG_STEP
+		        xmlGenericError(xmlGenericErrorContext,
+				"PathExpr: function call\n");
+#endif
+			lc = 0;
+		    }
+                    break;
+		} else if ((NXT(len) == '[')) {
+		    /* element name */
+#ifdef DEBUG_STEP
+		    xmlGenericError(xmlGenericErrorContext,
+			    "PathExpr: AbbrRelLocation\n");
+#endif
+		    lc = 1;
+		    break;
+		} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
+			   (NXT(len) == '=')) {
+		    lc = 1;
+		    break;
+		} else {
+		    lc = 1;
+		    break;
+		}
+		len++;
+	    }
+	    if (NXT(len) == 0) {
+#ifdef DEBUG_STEP
+		xmlGenericError(xmlGenericErrorContext,
+			"PathExpr: AbbrRelLocation\n");
+#endif
+		/* element name */
+		lc = 1;
+	    }
+	    xmlFree(name);
+	} else {
+	    /* make sure all cases are covered explicitly */
+	    XP_ERROR(XPATH_EXPR_ERROR);
+	}
+    }
+
+    if (lc) {
+	if (CUR == '/') {
+	    PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
+	} else {
+	    PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
+	}
+	xmlXPathCompLocationPath(ctxt);
+    } else {
+	xmlXPathCompFilterExpr(ctxt);
+	CHECK_ERROR;
+	if ((CUR == '/') && (NXT(1) == '/')) {
+	    SKIP(2);
+	    SKIP_BLANKS;
+
+	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
+		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
+	    PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
+
+	    xmlXPathCompRelativeLocationPath(ctxt);
+	} else if (CUR == '/') {
+	    xmlXPathCompRelativeLocationPath(ctxt);
+	}
+    }
+    SKIP_BLANKS;
+}
+
+/**
+ * xmlXPathCompUnionExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [18]   UnionExpr ::=   PathExpr
+ *               | UnionExpr '|' PathExpr
+ *
+ * Compile an union expression.
+ */
+
+static void
+xmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompPathExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while (CUR == '|') {
+	int op1 = ctxt->comp->last;
+	PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
+
+	NEXT;
+	SKIP_BLANKS;
+	xmlXPathCompPathExpr(ctxt);
+
+	PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
+
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompUnaryExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [27]   UnaryExpr ::=   UnionExpr
+ *                   | '-' UnaryExpr
+ *
+ * Compile an unary expression.
+ */
+
+static void
+xmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
+    int minus = 0;
+    int found = 0;
+
+    SKIP_BLANKS;
+    while (CUR == '-') {
+        minus = 1 - minus;
+	found = 1;
+	NEXT;
+	SKIP_BLANKS;
+    }
+
+    xmlXPathCompUnionExpr(ctxt);
+    CHECK_ERROR;
+    if (found) {
+	if (minus)
+	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
+	else
+	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
+    }
+}
+
+/**
+ * xmlXPathCompMultiplicativeExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [26]   MultiplicativeExpr ::=   UnaryExpr
+ *                   | MultiplicativeExpr MultiplyOperator UnaryExpr
+ *                   | MultiplicativeExpr 'div' UnaryExpr
+ *                   | MultiplicativeExpr 'mod' UnaryExpr
+ *  [34]   MultiplyOperator ::=   '*'
+ *
+ * Compile an Additive expression.
+ */
+
+static void
+xmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompUnaryExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == '*') ||
+           ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
+           ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
+	int op = -1;
+	int op1 = ctxt->comp->last;
+
+        if (CUR == '*') {
+	    op = 0;
+	    NEXT;
+	} else if (CUR == 'd') {
+	    op = 1;
+	    SKIP(3);
+	} else if (CUR == 'm') {
+	    op = 2;
+	    SKIP(3);
+	}
+	SKIP_BLANKS;
+        xmlXPathCompUnaryExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompAdditiveExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [25]   AdditiveExpr ::=   MultiplicativeExpr
+ *                   | AdditiveExpr '+' MultiplicativeExpr
+ *                   | AdditiveExpr '-' MultiplicativeExpr
+ *
+ * Compile an Additive expression.
+ */
+
+static void
+xmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
+
+    xmlXPathCompMultiplicativeExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == '+') || (CUR == '-')) {
+	int plus;
+	int op1 = ctxt->comp->last;
+
+        if (CUR == '+') plus = 1;
+	else plus = 0;
+	NEXT;
+	SKIP_BLANKS;
+        xmlXPathCompMultiplicativeExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompRelationalExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [24]   RelationalExpr ::=   AdditiveExpr
+ *                 | RelationalExpr '<' AdditiveExpr
+ *                 | RelationalExpr '>' AdditiveExpr
+ *                 | RelationalExpr '<=' AdditiveExpr
+ *                 | RelationalExpr '>=' AdditiveExpr
+ *
+ *  A <= B > C is allowed ? Answer from James, yes with
+ *  (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
+ *  which is basically what got implemented.
+ *
+ * Compile a Relational expression, then push the result
+ * on the stack
+ */
+
+static void
+xmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompAdditiveExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == '<') ||
+           (CUR == '>') ||
+           ((CUR == '<') && (NXT(1) == '=')) ||
+           ((CUR == '>') && (NXT(1) == '='))) {
+	int inf, strict;
+	int op1 = ctxt->comp->last;
+
+        if (CUR == '<') inf = 1;
+	else inf = 0;
+	if (NXT(1) == '=') strict = 0;
+	else strict = 1;
+	NEXT;
+	if (!strict) NEXT;
+	SKIP_BLANKS;
+        xmlXPathCompAdditiveExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompEqualityExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [23]   EqualityExpr ::=   RelationalExpr
+ *                 | EqualityExpr '=' RelationalExpr
+ *                 | EqualityExpr '!=' RelationalExpr
+ *
+ *  A != B != C is allowed ? Answer from James, yes with
+ *  (RelationalExpr = RelationalExpr) = RelationalExpr
+ *  (RelationalExpr != RelationalExpr) != RelationalExpr
+ *  which is basically what got implemented.
+ *
+ * Compile an Equality expression.
+ *
+ */
+static void
+xmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompRelationalExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
+	int eq;
+	int op1 = ctxt->comp->last;
+
+        if (CUR == '=') eq = 1;
+	else eq = 0;
+	NEXT;
+	if (!eq) NEXT;
+	SKIP_BLANKS;
+        xmlXPathCompRelationalExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompAndExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [22]   AndExpr ::=   EqualityExpr
+ *                 | AndExpr 'and' EqualityExpr
+ *
+ * Compile an AND expression.
+ *
+ */
+static void
+xmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
+    xmlXPathCompEqualityExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
+	int op1 = ctxt->comp->last;
+        SKIP(3);
+	SKIP_BLANKS;
+        xmlXPathCompEqualityExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompileExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [14]   Expr ::=   OrExpr
+ *  [21]   OrExpr ::=   AndExpr
+ *                 | OrExpr 'or' AndExpr
+ *
+ * Parse and compile an expression
+ */
+static void
+xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
+    xmlXPathCompAndExpr(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while ((CUR == 'o') && (NXT(1) == 'r')) {
+	int op1 = ctxt->comp->last;
+        SKIP(2);
+	SKIP_BLANKS;
+        xmlXPathCompAndExpr(ctxt);
+	CHECK_ERROR;
+	PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
+	SKIP_BLANKS;
+    }
+    if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
+	/* more ops could be optimized too */
+	/*
+	* This is the main place to eliminate sorting for
+	* operations which don't require a sorted node-set.
+	* E.g. count().
+	*/
+	PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
+    }
+}
+
+/**
+ * xmlXPathCompPredicate:
+ * @ctxt:  the XPath Parser context
+ * @filter:  act as a filter
+ *
+ *  [8]   Predicate ::=   '[' PredicateExpr ']'
+ *  [9]   PredicateExpr ::=   Expr
+ *
+ * Compile a predicate expression
+ */
+static void
+xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
+    int op1 = ctxt->comp->last;
+
+    SKIP_BLANKS;
+    if (CUR != '[') {
+	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
+    }
+    NEXT;
+    SKIP_BLANKS;
+
+    ctxt->comp->last = -1;
+    /*
+    * This call to xmlXPathCompileExpr() will deactivate sorting
+    * of the predicate result.
+    * TODO: Sorting is still activated for filters, since I'm not
+    *  sure if needed. Normally sorting should not be needed, since
+    *  a filter can only diminish the number of items in a sequence,
+    *  but won't change its order; so if the initial sequence is sorted,
+    *  subsequent sorting is not needed.
+    */
+    if (! filter)
+	xmlXPathCompileExpr(ctxt, 0);
+    else
+	xmlXPathCompileExpr(ctxt, 1);
+    CHECK_ERROR;
+
+    if (CUR != ']') {
+	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
+    }
+
+    if (filter)
+	PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
+    else
+	PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
+
+    NEXT;
+    SKIP_BLANKS;
+}
+
+/**
+ * xmlXPathCompNodeTest:
+ * @ctxt:  the XPath Parser context
+ * @test:  pointer to a xmlXPathTestVal
+ * @type:  pointer to a xmlXPathTypeVal
+ * @prefix:  placeholder for a possible name prefix
+ *
+ * [7] NodeTest ::=   NameTest
+ *		    | NodeType '(' ')'
+ *		    | 'processing-instruction' '(' Literal ')'
+ *
+ * [37] NameTest ::=  '*'
+ *		    | NCName ':' '*'
+ *		    | QName
+ * [38] NodeType ::= 'comment'
+ *		   | 'text'
+ *		   | 'processing-instruction'
+ *		   | 'node'
+ *
+ * Returns the name found and updates @test, @type and @prefix appropriately
+ */
+static xmlChar *
+xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
+	             xmlXPathTypeVal *type, const xmlChar **prefix,
+		     xmlChar *name) {
+    int blanks;
+
+    if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
+	STRANGE;
+	return(NULL);
+    }
+    *type = (xmlXPathTypeVal) 0;
+    *test = (xmlXPathTestVal) 0;
+    *prefix = NULL;
+    SKIP_BLANKS;
+
+    if ((name == NULL) && (CUR == '*')) {
+	/*
+	 * All elements
+	 */
+	NEXT;
+	*test = NODE_TEST_ALL;
+	return(NULL);
+    }
+
+    if (name == NULL)
+	name = xmlXPathParseNCName(ctxt);
+    if (name == NULL) {
+	XP_ERRORNULL(XPATH_EXPR_ERROR);
+    }
+
+    blanks = IS_BLANK_CH(CUR);
+    SKIP_BLANKS;
+    if (CUR == '(') {
+	NEXT;
+	/*
+	 * NodeType or PI search
+	 */
+	if (xmlStrEqual(name, BAD_CAST "comment"))
+	    *type = NODE_TYPE_COMMENT;
+	else if (xmlStrEqual(name, BAD_CAST "node"))
+	    *type = NODE_TYPE_NODE;
+	else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
+	    *type = NODE_TYPE_PI;
+	else if (xmlStrEqual(name, BAD_CAST "text"))
+	    *type = NODE_TYPE_TEXT;
+	else {
+	    if (name != NULL)
+		xmlFree(name);
+	    XP_ERRORNULL(XPATH_EXPR_ERROR);
+	}
+
+	*test = NODE_TEST_TYPE;
+
+	SKIP_BLANKS;
+	if (*type == NODE_TYPE_PI) {
+	    /*
+	     * Specific case: search a PI by name.
+	     */
+	    if (name != NULL)
+		xmlFree(name);
+	    name = NULL;
+	    if (CUR != ')') {
+		name = xmlXPathParseLiteral(ctxt);
+		CHECK_ERROR NULL;
+		*test = NODE_TEST_PI;
+		SKIP_BLANKS;
+	    }
+	}
+	if (CUR != ')') {
+	    if (name != NULL)
+		xmlFree(name);
+	    XP_ERRORNULL(XPATH_UNCLOSED_ERROR);
+	}
+	NEXT;
+	return(name);
+    }
+    *test = NODE_TEST_NAME;
+    if ((!blanks) && (CUR == ':')) {
+	NEXT;
+
+	/*
+	 * Since currently the parser context don't have a
+	 * namespace list associated:
+	 * The namespace name for this prefix can be computed
+	 * only at evaluation time. The compilation is done
+	 * outside of any context.
+	 */
+#if 0
+	*prefix = xmlXPathNsLookup(ctxt->context, name);
+	if (name != NULL)
+	    xmlFree(name);
+	if (*prefix == NULL) {
+	    XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
+	}
+#else
+	*prefix = name;
+#endif
+
+	if (CUR == '*') {
+	    /*
+	     * All elements
+	     */
+	    NEXT;
+	    *test = NODE_TEST_ALL;
+	    return(NULL);
+	}
+
+	name = xmlXPathParseNCName(ctxt);
+	if (name == NULL) {
+	    XP_ERRORNULL(XPATH_EXPR_ERROR);
+	}
+    }
+    return(name);
+}
+
+/**
+ * xmlXPathIsAxisName:
+ * @name:  a preparsed name token
+ *
+ * [6] AxisName ::=   'ancestor'
+ *                  | 'ancestor-or-self'
+ *                  | 'attribute'
+ *                  | 'child'
+ *                  | 'descendant'
+ *                  | 'descendant-or-self'
+ *                  | 'following'
+ *                  | 'following-sibling'
+ *                  | 'namespace'
+ *                  | 'parent'
+ *                  | 'preceding'
+ *                  | 'preceding-sibling'
+ *                  | 'self'
+ *
+ * Returns the axis or 0
+ */
+static xmlXPathAxisVal
+xmlXPathIsAxisName(const xmlChar *name) {
+    xmlXPathAxisVal ret = (xmlXPathAxisVal) 0;
+    switch (name[0]) {
+	case 'a':
+	    if (xmlStrEqual(name, BAD_CAST "ancestor"))
+		ret = AXIS_ANCESTOR;
+	    if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
+		ret = AXIS_ANCESTOR_OR_SELF;
+	    if (xmlStrEqual(name, BAD_CAST "attribute"))
+		ret = AXIS_ATTRIBUTE;
+	    break;
+	case 'c':
+	    if (xmlStrEqual(name, BAD_CAST "child"))
+		ret = AXIS_CHILD;
+	    break;
+	case 'd':
+	    if (xmlStrEqual(name, BAD_CAST "descendant"))
+		ret = AXIS_DESCENDANT;
+	    if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
+		ret = AXIS_DESCENDANT_OR_SELF;
+	    break;
+	case 'f':
+	    if (xmlStrEqual(name, BAD_CAST "following"))
+		ret = AXIS_FOLLOWING;
+	    if (xmlStrEqual(name, BAD_CAST "following-sibling"))
+		ret = AXIS_FOLLOWING_SIBLING;
+	    break;
+	case 'n':
+	    if (xmlStrEqual(name, BAD_CAST "namespace"))
+		ret = AXIS_NAMESPACE;
+	    break;
+	case 'p':
+	    if (xmlStrEqual(name, BAD_CAST "parent"))
+		ret = AXIS_PARENT;
+	    if (xmlStrEqual(name, BAD_CAST "preceding"))
+		ret = AXIS_PRECEDING;
+	    if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
+		ret = AXIS_PRECEDING_SIBLING;
+	    break;
+	case 's':
+	    if (xmlStrEqual(name, BAD_CAST "self"))
+		ret = AXIS_SELF;
+	    break;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPathCompStep:
+ * @ctxt:  the XPath Parser context
+ *
+ * [4] Step ::=   AxisSpecifier NodeTest Predicate*
+ *                  | AbbreviatedStep
+ *
+ * [12] AbbreviatedStep ::=   '.' | '..'
+ *
+ * [5] AxisSpecifier ::= AxisName '::'
+ *                  | AbbreviatedAxisSpecifier
+ *
+ * [13] AbbreviatedAxisSpecifier ::= '@'?
+ *
+ * Modified for XPtr range support as:
+ *
+ *  [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
+ *                     | AbbreviatedStep
+ *                     | 'range-to' '(' Expr ')' Predicate*
+ *
+ * Compile one step in a Location Path
+ * A location step of . is short for self::node(). This is
+ * particularly useful in conjunction with //. For example, the
+ * location path .//para is short for
+ * self::node()/descendant-or-self::node()/child::para
+ * and so will select all para descendant elements of the context
+ * node.
+ * Similarly, a location step of .. is short for parent::node().
+ * For example, ../title is short for parent::node()/child::title
+ * and so will select the title children of the parent of the context
+ * node.
+ */
+static void
+xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
+#ifdef LIBXML_XPTR_ENABLED
+    int rangeto = 0;
+    int op2 = -1;
+#endif
+
+    SKIP_BLANKS;
+    if ((CUR == '.') && (NXT(1) == '.')) {
+	SKIP(2);
+	SKIP_BLANKS;
+	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT,
+		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
+    } else if (CUR == '.') {
+	NEXT;
+	SKIP_BLANKS;
+    } else {
+	xmlChar *name = NULL;
+	const xmlChar *prefix = NULL;
+	xmlXPathTestVal test = (xmlXPathTestVal) 0;
+	xmlXPathAxisVal axis = (xmlXPathAxisVal) 0;
+	xmlXPathTypeVal type = (xmlXPathTypeVal) 0;
+	int op1;
+
+	/*
+	 * The modification needed for XPointer change to the production
+	 */
+#ifdef LIBXML_XPTR_ENABLED
+	if (ctxt->xptr) {
+	    name = xmlXPathParseNCName(ctxt);
+	    if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
+                op2 = ctxt->comp->last;
+		xmlFree(name);
+		SKIP_BLANKS;
+		if (CUR != '(') {
+		    XP_ERROR(XPATH_EXPR_ERROR);
+		}
+		NEXT;
+		SKIP_BLANKS;
+
+		xmlXPathCompileExpr(ctxt, 1);
+		/* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */
+		CHECK_ERROR;
+
+		SKIP_BLANKS;
+		if (CUR != ')') {
+		    XP_ERROR(XPATH_EXPR_ERROR);
+		}
+		NEXT;
+		rangeto = 1;
+		goto eval_predicates;
+	    }
+	}
+#endif
+	if (CUR == '*') {
+	    axis = AXIS_CHILD;
+	} else {
+	    if (name == NULL)
+		name = xmlXPathParseNCName(ctxt);
+	    if (name != NULL) {
+		axis = xmlXPathIsAxisName(name);
+		if (axis != 0) {
+		    SKIP_BLANKS;
+		    if ((CUR == ':') && (NXT(1) == ':')) {
+			SKIP(2);
+			xmlFree(name);
+			name = NULL;
+		    } else {
+			/* an element name can conflict with an axis one :-\ */
+			axis = AXIS_CHILD;
+		    }
+		} else {
+		    axis = AXIS_CHILD;
+		}
+	    } else if (CUR == '@') {
+		NEXT;
+		axis = AXIS_ATTRIBUTE;
+	    } else {
+		axis = AXIS_CHILD;
+	    }
+	}
+
+	CHECK_ERROR;
+
+	name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
+	if (test == 0)
+	    return;
+
+        if ((prefix != NULL) && (ctxt->context != NULL) &&
+	    (ctxt->context->flags & XML_XPATH_CHECKNS)) {
+	    if (xmlXPathNsLookup(ctxt->context, prefix) == NULL) {
+		xmlXPathErr(ctxt, XPATH_UNDEF_PREFIX_ERROR);
+	    }
+	}
+#ifdef DEBUG_STEP
+	xmlGenericError(xmlGenericErrorContext,
+		"Basis : computing new set\n");
+#endif
+
+#ifdef DEBUG_STEP
+	xmlGenericError(xmlGenericErrorContext, "Basis : ");
+	if (ctxt->value == NULL)
+	    xmlGenericError(xmlGenericErrorContext, "no value\n");
+	else if (ctxt->value->nodesetval == NULL)
+	    xmlGenericError(xmlGenericErrorContext, "Empty\n");
+	else
+	    xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
+#endif
+
+#ifdef LIBXML_XPTR_ENABLED
+eval_predicates:
+#endif
+	op1 = ctxt->comp->last;
+	ctxt->comp->last = -1;
+
+	SKIP_BLANKS;
+	while (CUR == '[') {
+	    xmlXPathCompPredicate(ctxt, 0);
+	}
+
+#ifdef LIBXML_XPTR_ENABLED
+	if (rangeto) {
+	    PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
+	} else
+#endif
+	    PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
+			   test, type, (void *)prefix, (void *)name);
+
+    }
+#ifdef DEBUG_STEP
+    xmlGenericError(xmlGenericErrorContext, "Step : ");
+    if (ctxt->value == NULL)
+	xmlGenericError(xmlGenericErrorContext, "no value\n");
+    else if (ctxt->value->nodesetval == NULL)
+	xmlGenericError(xmlGenericErrorContext, "Empty\n");
+    else
+	xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
+		ctxt->value->nodesetval);
+#endif
+}
+
+/**
+ * xmlXPathCompRelativeLocationPath:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [3]   RelativeLocationPath ::=   Step
+ *                     | RelativeLocationPath '/' Step
+ *                     | AbbreviatedRelativeLocationPath
+ *  [11]  AbbreviatedRelativeLocationPath ::=   RelativeLocationPath '//' Step
+ *
+ * Compile a relative location path.
+ */
+static void
+xmlXPathCompRelativeLocationPath
+(xmlXPathParserContextPtr ctxt) {
+    SKIP_BLANKS;
+    if ((CUR == '/') && (NXT(1) == '/')) {
+	SKIP(2);
+	SKIP_BLANKS;
+	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
+		         NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
+    } else if (CUR == '/') {
+	    NEXT;
+	SKIP_BLANKS;
+    }
+    xmlXPathCompStep(ctxt);
+    CHECK_ERROR;
+    SKIP_BLANKS;
+    while (CUR == '/') {
+	if ((CUR == '/') && (NXT(1) == '/')) {
+	    SKIP(2);
+	    SKIP_BLANKS;
+	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
+			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
+	    xmlXPathCompStep(ctxt);
+	} else if (CUR == '/') {
+	    NEXT;
+	    SKIP_BLANKS;
+	    xmlXPathCompStep(ctxt);
+	}
+	SKIP_BLANKS;
+    }
+}
+
+/**
+ * xmlXPathCompLocationPath:
+ * @ctxt:  the XPath Parser context
+ *
+ *  [1]   LocationPath ::=   RelativeLocationPath
+ *                     | AbsoluteLocationPath
+ *  [2]   AbsoluteLocationPath ::=   '/' RelativeLocationPath?
+ *                     | AbbreviatedAbsoluteLocationPath
+ *  [10]   AbbreviatedAbsoluteLocationPath ::=
+ *                           '//' RelativeLocationPath
+ *
+ * Compile a location path
+ *
+ * // is short for /descendant-or-self::node()/. For example,
+ * //para is short for /descendant-or-self::node()/child::para and
+ * so will select any para element in the document (even a para element
+ * that is a document element will be selected by //para since the
+ * document element node is a child of the root node); div//para is
+ * short for div/descendant-or-self::node()/child::para and so will
+ * select all para descendants of div children.
+ */
+static void
+xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
+    SKIP_BLANKS;
+    if (CUR != '/') {
+        xmlXPathCompRelativeLocationPath(ctxt);
+    } else {
+	while (CUR == '/') {
+	    if ((CUR == '/') && (NXT(1) == '/')) {
+		SKIP(2);
+		SKIP_BLANKS;
+		PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
+			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
+		xmlXPathCompRelativeLocationPath(ctxt);
+	    } else if (CUR == '/') {
+		NEXT;
+		SKIP_BLANKS;
+		if ((CUR != 0 ) &&
+		    ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
+		     (CUR == '@') || (CUR == '*')))
+		    xmlXPathCompRelativeLocationPath(ctxt);
+	    }
+	    CHECK_ERROR;
+	}
+    }
+}
+
+/************************************************************************
+ *									*
+ *		XPath precompiled expression evaluation			*
+ *									*
+ ************************************************************************/
+
+static int
+xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
+
+#ifdef DEBUG_STEP
+static void
+xmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op,
+			  int nbNodes)
+{
+    xmlGenericError(xmlGenericErrorContext, "new step : ");
+    switch (op->value) {
+        case AXIS_ANCESTOR:
+            xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
+            break;
+        case AXIS_ANCESTOR_OR_SELF:
+            xmlGenericError(xmlGenericErrorContext,
+                            "axis 'ancestors-or-self' ");
+            break;
+        case AXIS_ATTRIBUTE:
+            xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
+            break;
+        case AXIS_CHILD:
+            xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
+            break;
+        case AXIS_DESCENDANT:
+            xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
+            break;
+        case AXIS_DESCENDANT_OR_SELF:
+            xmlGenericError(xmlGenericErrorContext,
+                            "axis 'descendant-or-self' ");
+            break;
+        case AXIS_FOLLOWING:
+            xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
+            break;
+        case AXIS_FOLLOWING_SIBLING:
+            xmlGenericError(xmlGenericErrorContext,
+                            "axis 'following-siblings' ");
+            break;
+        case AXIS_NAMESPACE:
+            xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
+            break;
+        case AXIS_PARENT:
+            xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
+            break;
+        case AXIS_PRECEDING:
+            xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
+            break;
+        case AXIS_PRECEDING_SIBLING:
+            xmlGenericError(xmlGenericErrorContext,
+                            "axis 'preceding-sibling' ");
+            break;
+        case AXIS_SELF:
+            xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
+            break;
+    }
+    xmlGenericError(xmlGenericErrorContext,
+	" context contains %d nodes\n", nbNodes);
+    switch (op->value2) {
+        case NODE_TEST_NONE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for none !!!\n");
+            break;
+        case NODE_TEST_TYPE:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for type %d\n", op->value3);
+            break;
+        case NODE_TEST_PI:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for PI !!!\n");
+            break;
+        case NODE_TEST_ALL:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for *\n");
+            break;
+        case NODE_TEST_NS:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for namespace %s\n",
+                            op->value5);
+            break;
+        case NODE_TEST_NAME:
+            xmlGenericError(xmlGenericErrorContext,
+                            "           searching for name %s\n", op->value5);
+            if (op->value4)
+                xmlGenericError(xmlGenericErrorContext,
+                                "           with namespace %s\n", op->value4);
+            break;
+    }
+    xmlGenericError(xmlGenericErrorContext, "Testing : ");
+}
+#endif /* DEBUG_STEP */
+
+static int
+xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
+			    xmlXPathStepOpPtr op,
+			    xmlNodeSetPtr set,
+			    int contextSize,
+			    int hasNsNodes)
+{
+    if (op->ch1 != -1) {
+	xmlXPathCompExprPtr comp = ctxt->comp;
+	/*
+	* Process inner predicates first.
+	*/
+	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
+	    /*
+	    * TODO: raise an internal error.
+	    */
+	}
+	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
+	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
+	CHECK_ERROR0;
+	if (contextSize <= 0)
+	    return(0);
+    }
+    if (op->ch2 != -1) {
+	xmlXPathContextPtr xpctxt = ctxt->context;
+	xmlNodePtr contextNode, oldContextNode;
+	xmlDocPtr oldContextDoc;
+	int i, res, contextPos = 0, newContextSize;
+	xmlXPathStepOpPtr exprOp;
+	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
+
+#ifdef LIBXML_XPTR_ENABLED
+	/*
+	* URGENT TODO: Check the following:
+	*  We don't expect location sets if evaluating prediates, right?
+	*  Only filters should expect location sets, right?
+	*/
+#endif
+	/*
+	* SPEC XPath 1.0:
+	*  "For each node in the node-set to be filtered, the
+	*  PredicateExpr is evaluated with that node as the
+	*  context node, with the number of nodes in the
+	*  node-set as the context size, and with the proximity
+	*  position of the node in the node-set with respect to
+	*  the axis as the context position;"
+	* @oldset is the node-set" to be filtered.
+	*
+	* SPEC XPath 1.0:
+	*  "only predicates change the context position and
+	*  context size (see [2.4 Predicates])."
+	* Example:
+	*   node-set  context pos
+	*    nA         1
+	*    nB         2
+	*    nC         3
+	*   After applying predicate [position() > 1] :
+	*   node-set  context pos
+	*    nB         1
+	*    nC         2
+	*/
+	oldContextNode = xpctxt->node;
+	oldContextDoc = xpctxt->doc;
+	/*
+	* Get the expression of this predicate.
+	*/
+	exprOp = &ctxt->comp->steps[op->ch2];
+	newContextSize = 0;
+	for (i = 0; i < set->nodeNr; i++) {
+	    if (set->nodeTab[i] == NULL)
+		continue;
+
+	    contextNode = set->nodeTab[i];
+	    xpctxt->node = contextNode;
+	    xpctxt->contextSize = contextSize;
+	    xpctxt->proximityPosition = ++contextPos;
+
+	    /*
+	    * Also set the xpath document in case things like
+	    * key() are evaluated in the predicate.
+	    */
+	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
+		(contextNode->doc != NULL))
+		xpctxt->doc = contextNode->doc;
+	    /*
+	    * Evaluate the predicate expression with 1 context node
+	    * at a time; this node is packaged into a node set; this
+	    * node set is handed over to the evaluation mechanism.
+	    */
+	    if (contextObj == NULL)
+		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
+	    else
+		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+		    contextNode);
+
+	    valuePush(ctxt, contextObj);
+
+	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
+
+	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
+		xmlXPathNodeSetClear(set, hasNsNodes);
+		newContextSize = 0;
+		goto evaluation_exit;
+	    }
+
+	    if (res != 0) {
+		newContextSize++;
+	    } else {
+		/*
+		* Remove the entry from the initial node set.
+		*/
+		set->nodeTab[i] = NULL;
+		if (contextNode->type == XML_NAMESPACE_DECL)
+		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
+	    }
+	    if (ctxt->value == contextObj) {
+		/*
+		* Don't free the temporary XPath object holding the
+		* context node, in order to avoid massive recreation
+		* inside this loop.
+		*/
+		valuePop(ctxt);
+		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
+	    } else {
+		/*
+		* TODO: The object was lost in the evaluation machinery.
+		*  Can this happen? Maybe in internal-error cases.
+		*/
+		contextObj = NULL;
+	    }
+	}
+
+	if (contextObj != NULL) {
+	    if (ctxt->value == contextObj)
+		valuePop(ctxt);
+	    xmlXPathReleaseObject(xpctxt, contextObj);
+	}
+evaluation_exit:
+	if (exprRes != NULL)
+	    xmlXPathReleaseObject(ctxt->context, exprRes);
+	/*
+	* Reset/invalidate the context.
+	*/
+	xpctxt->node = oldContextNode;
+	xpctxt->doc = oldContextDoc;
+	xpctxt->contextSize = -1;
+	xpctxt->proximityPosition = -1;
+	return(newContextSize);
+    }
+    return(contextSize);
+}
+
+static int
+xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+				      xmlXPathStepOpPtr op,
+				      xmlNodeSetPtr set,
+				      int contextSize,
+				      int minPos,
+				      int maxPos,
+				      int hasNsNodes)
+{
+    if (op->ch1 != -1) {
+	xmlXPathCompExprPtr comp = ctxt->comp;
+	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
+	    /*
+	    * TODO: raise an internal error.
+	    */
+	}
+	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
+	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
+	CHECK_ERROR0;
+	if (contextSize <= 0)
+	    return(0);
+    }
+    /*
+    * Check if the node set contains a sufficient number of nodes for
+    * the requested range.
+    */
+    if (contextSize < minPos) {
+	xmlXPathNodeSetClear(set, hasNsNodes);
+	return(0);
+    }
+    if (op->ch2 == -1) {
+	/*
+	* TODO: Can this ever happen?
+	*/
+	return (contextSize);
+    } else {
+	xmlDocPtr oldContextDoc;
+	int i, pos = 0, newContextSize = 0, contextPos = 0, res;
+	xmlXPathStepOpPtr exprOp;
+	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
+	xmlNodePtr oldContextNode, contextNode = NULL;
+	xmlXPathContextPtr xpctxt = ctxt->context;
+
+#ifdef LIBXML_XPTR_ENABLED
+	    /*
+	    * URGENT TODO: Check the following:
+	    *  We don't expect location sets if evaluating prediates, right?
+	    *  Only filters should expect location sets, right?
+	*/
+#endif /* LIBXML_XPTR_ENABLED */
+
+	/*
+	* Save old context.
+	*/
+	oldContextNode = xpctxt->node;
+	oldContextDoc = xpctxt->doc;
+	/*
+	* Get the expression of this predicate.
+	*/
+	exprOp = &ctxt->comp->steps[op->ch2];
+	for (i = 0; i < set->nodeNr; i++) {
+	    if (set->nodeTab[i] == NULL)
+		continue;
+
+	    contextNode = set->nodeTab[i];
+	    xpctxt->node = contextNode;
+	    xpctxt->contextSize = contextSize;
+	    xpctxt->proximityPosition = ++contextPos;
+
+	    /*
+	    * Initialize the new set.
+	    * Also set the xpath document in case things like
+	    * key() evaluation are attempted on the predicate
+	    */
+	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
+		(contextNode->doc != NULL))
+		xpctxt->doc = contextNode->doc;
+	    /*
+	    * Evaluate the predicate expression with 1 context node
+	    * at a time; this node is packaged into a node set; this
+	    * node set is handed over to the evaluation mechanism.
+	    */
+	    if (contextObj == NULL)
+		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
+	    else
+		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+		    contextNode);
+
+	    valuePush(ctxt, contextObj);
+	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
+
+	    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);
+                }
+		goto evaluation_error;
+	    }
+
+	    if (res)
+		pos++;
+
+	    if (res && (pos >= minPos) && (pos <= maxPos)) {
+		/*
+		* Fits in the requested range.
+		*/
+		newContextSize++;
+		if (minPos == maxPos) {
+		    /*
+		    * Only 1 node was requested.
+		    */
+		    if (contextNode->type == XML_NAMESPACE_DECL) {
+			/*
+			* As always: take care of those nasty
+			* namespace nodes.
+			*/
+			set->nodeTab[i] = NULL;
+		    }
+		    xmlXPathNodeSetClear(set, hasNsNodes);
+		    set->nodeNr = 1;
+		    set->nodeTab[0] = contextNode;
+		    goto evaluation_exit;
+		}
+		if (pos == maxPos) {
+		    /*
+		    * We are done.
+		    */
+		    xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes);
+		    goto evaluation_exit;
+		}
+	    } else {
+		/*
+		* Remove the entry from the initial node set.
+		*/
+		set->nodeTab[i] = NULL;
+		if (contextNode->type == XML_NAMESPACE_DECL)
+		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
+	    }
+	    if (exprRes != NULL) {
+		xmlXPathReleaseObject(ctxt->context, exprRes);
+		exprRes = NULL;
+	    }
+	    if (ctxt->value == contextObj) {
+		/*
+		* Don't free the temporary XPath object holding the
+		* context node, in order to avoid massive recreation
+		* inside this loop.
+		*/
+		valuePop(ctxt);
+		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
+	    } else {
+		/*
+		* The object was lost in the evaluation machinery.
+		* Can this happen? Maybe in case of internal-errors.
+		*/
+		contextObj = NULL;
+	    }
+	}
+	goto evaluation_exit;
+
+evaluation_error:
+	xmlXPathNodeSetClear(set, hasNsNodes);
+	newContextSize = 0;
+
+evaluation_exit:
+	if (contextObj != NULL) {
+	    if (ctxt->value == contextObj)
+		valuePop(ctxt);
+	    xmlXPathReleaseObject(xpctxt, contextObj);
+	}
+	if (exprRes != NULL)
+	    xmlXPathReleaseObject(ctxt->context, exprRes);
+	/*
+	* Reset/invalidate the context.
+	*/
+	xpctxt->node = oldContextNode;
+	xpctxt->doc = oldContextDoc;
+	xpctxt->contextSize = -1;
+	xpctxt->proximityPosition = -1;
+	return(newContextSize);
+    }
+    return(contextSize);
+}
+
+static int
+xmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt,
+			    xmlXPathStepOpPtr op,
+			    int *maxPos)
+{
+
+    xmlXPathStepOpPtr exprOp;
+
+    /*
+    * BIG NOTE: This is not intended for XPATH_OP_FILTER yet!
+    */
+
+    /*
+    * If not -1, then ch1 will point to:
+    * 1) For predicates (XPATH_OP_PREDICATE):
+    *    - an inner predicate operator
+    * 2) For filters (XPATH_OP_FILTER):
+    *    - an inner filter operater OR
+    *    - an expression selecting the node set.
+    *      E.g. "key('a', 'b')" or "(//foo | //bar)".
+    */
+    if ((op->op != XPATH_OP_PREDICATE) && (op->op != XPATH_OP_FILTER))
+	return(0);
+
+    if (op->ch2 != -1) {
+	exprOp = &ctxt->comp->steps[op->ch2];
+    } else
+	return(0);
+
+    if ((exprOp != NULL) &&
+	(exprOp->op == XPATH_OP_VALUE) &&
+	(exprOp->value4 != NULL) &&
+	(((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER))
+    {
+	/*
+	* We have a "[n]" predicate here.
+	* TODO: Unfortunately this simplistic test here is not
+	* able to detect a position() predicate in compound
+	* expressions like "[@attr = 'a" and position() = 1],
+	* and even not the usage of position() in
+	* "[position() = 1]"; thus - obviously - a position-range,
+	* like it "[position() < 5]", is also not detected.
+	* Maybe we could rewrite the AST to ease the optimization.
+	*/
+	*maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval;
+
+	if (((xmlXPathObjectPtr) exprOp->value4)->floatval ==
+	    (float) *maxPos)
+	{
+	    return(1);
+	}
+    }
+    return(0);
+}
+
+static int
+xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
+                           xmlXPathStepOpPtr op,
+			   xmlNodePtr * first, xmlNodePtr * last,
+			   int toBool)
+{
+
+#define XP_TEST_HIT \
+    if (hasAxisRange != 0) { \
+	if (++pos == maxPos) { \
+	    addNode(seq, cur); \
+	goto axis_range_end; } \
+    } else { \
+	addNode(seq, cur); \
+	if (breakOnFirstHit) goto first_hit; }
+
+#define XP_TEST_HIT_NS \
+    if (hasAxisRange != 0) { \
+	if (++pos == maxPos) { \
+	    hasNsNodes = 1; \
+	    xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur); \
+	goto axis_range_end; } \
+    } else { \
+	hasNsNodes = 1; \
+	xmlXPathNodeSetAddNs(seq, \
+	xpctxt->node, (xmlNsPtr) cur); \
+	if (breakOnFirstHit) goto first_hit; }
+
+    xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
+    xmlXPathTestVal test = (xmlXPathTestVal) op->value2;
+    xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3;
+    const xmlChar *prefix = op->value4;
+    const xmlChar *name = op->value5;
+    const xmlChar *URI = NULL;
+
+#ifdef DEBUG_STEP
+    int nbMatches = 0, prevMatches = 0;
+#endif
+    int total = 0, hasNsNodes = 0;
+    /* The popped object holding the context nodes */
+    xmlXPathObjectPtr obj;
+    /* The set of context nodes for the node tests */
+    xmlNodeSetPtr contextSeq;
+    int contextIdx;
+    xmlNodePtr contextNode;
+    /* The context node for a compound traversal */
+    xmlNodePtr outerContextNode;
+    /* The final resulting node set wrt to all context nodes */
+    xmlNodeSetPtr outSeq;
+    /*
+    * The temporary resulting node set wrt 1 context node.
+    * Used to feed predicate evaluation.
+    */
+    xmlNodeSetPtr seq;
+    xmlNodePtr cur;
+    /* First predicate operator */
+    xmlXPathStepOpPtr predOp;
+    int maxPos; /* The requested position() (when a "[n]" predicate) */
+    int hasPredicateRange, hasAxisRange, pos, size, newSize;
+    int breakOnFirstHit;
+
+    xmlXPathTraversalFunction next = NULL;
+    /* compound axis traversal */
+    xmlXPathTraversalFunctionExt outerNext = NULL;
+    void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
+    xmlXPathNodeSetMergeFunction mergeAndClear;
+    xmlNodePtr oldContextNode;
+    xmlXPathContextPtr xpctxt = ctxt->context;
+
+
+    CHECK_TYPE0(XPATH_NODESET);
+    obj = valuePop(ctxt);
+    /*
+    * Setup namespaces.
+    */
+    if (prefix != NULL) {
+        URI = xmlXPathNsLookup(xpctxt, prefix);
+        if (URI == NULL) {
+	    xmlXPathReleaseObject(xpctxt, obj);
+            XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
+	}
+    }
+    /*
+    * Setup axis.
+    *
+    * MAYBE FUTURE TODO: merging optimizations:
+    * - If the nodes to be traversed wrt to the initial nodes and
+    *   the current axis cannot overlap, then we could avoid searching
+    *   for duplicates during the merge.
+    *   But the question is how/when to evaluate if they cannot overlap.
+    *   Example: if we know that for two initial nodes, the one is
+    *   not in the ancestor-or-self axis of the other, then we could safely
+    *   avoid a duplicate-aware merge, if the axis to be traversed is e.g.
+    *   the descendant-or-self axis.
+    */
+    mergeAndClear = xmlXPathNodeSetMergeAndClear;
+    switch (axis) {
+        case AXIS_ANCESTOR:
+            first = NULL;
+            next = xmlXPathNextAncestor;
+            break;
+        case AXIS_ANCESTOR_OR_SELF:
+            first = NULL;
+            next = xmlXPathNextAncestorOrSelf;
+            break;
+        case AXIS_ATTRIBUTE:
+            first = NULL;
+	    last = NULL;
+            next = xmlXPathNextAttribute;
+	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
+            break;
+        case AXIS_CHILD:
+	    last = NULL;
+	    if (op->rewriteType == XP_REWRITE_DOS_CHILD_ELEM) {
+		/*
+		* This iterator will give us only nodes which can
+		* hold element nodes.
+		*/
+		outerNext = xmlXPathNextDescendantOrSelfElemParent;
+	    }
+	    if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&
+		(type == NODE_TYPE_NODE))
+	    {
+		/*
+		* Optimization if an element node type is 'element'.
+		*/
+		next = xmlXPathNextChildElement;
+	    } else
+		next = xmlXPathNextChild;
+	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
+            break;
+        case AXIS_DESCENDANT:
+	    last = NULL;
+            next = xmlXPathNextDescendant;
+            break;
+        case AXIS_DESCENDANT_OR_SELF:
+	    last = NULL;
+            next = xmlXPathNextDescendantOrSelf;
+            break;
+        case AXIS_FOLLOWING:
+	    last = NULL;
+            next = xmlXPathNextFollowing;
+            break;
+        case AXIS_FOLLOWING_SIBLING:
+	    last = NULL;
+            next = xmlXPathNextFollowingSibling;
+            break;
+        case AXIS_NAMESPACE:
+            first = NULL;
+	    last = NULL;
+            next = (xmlXPathTraversalFunction) xmlXPathNextNamespace;
+	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
+            break;
+        case AXIS_PARENT:
+            first = NULL;
+            next = xmlXPathNextParent;
+            break;
+        case AXIS_PRECEDING:
+            first = NULL;
+            next = xmlXPathNextPrecedingInternal;
+            break;
+        case AXIS_PRECEDING_SIBLING:
+            first = NULL;
+            next = xmlXPathNextPrecedingSibling;
+            break;
+        case AXIS_SELF:
+            first = NULL;
+	    last = NULL;
+            next = xmlXPathNextSelf;
+	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
+            break;
+    }
+
+#ifdef DEBUG_STEP
+    xmlXPathDebugDumpStepAxis(op,
+	(obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0);
+#endif
+
+    if (next == NULL) {
+	xmlXPathReleaseObject(xpctxt, obj);
+        return(0);
+    }
+    contextSeq = obj->nodesetval;
+    if ((contextSeq == NULL) || (contextSeq->nodeNr <= 0)) {
+	xmlXPathReleaseObject(xpctxt, obj);
+        valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, NULL));
+        return(0);
+    }
+    /*
+    * Predicate optimization ---------------------------------------------
+    * If this step has a last predicate, which contains a position(),
+    * then we'll optimize (although not exactly "position()", but only
+    * the  short-hand form, i.e., "[n]".
+    *
+    * Example - expression "/foo[parent::bar][1]":
+    *
+    * COLLECT 'child' 'name' 'node' foo    -- op (we are here)
+    *   ROOT                               -- op->ch1
+    *   PREDICATE                          -- op->ch2 (predOp)
+    *     PREDICATE                          -- predOp->ch1 = [parent::bar]
+    *       SORT
+    *         COLLECT  'parent' 'name' 'node' bar
+    *           NODE
+    *     ELEM Object is a number : 1        -- predOp->ch2 = [1]
+    *
+    */
+    maxPos = 0;
+    predOp = NULL;
+    hasPredicateRange = 0;
+    hasAxisRange = 0;
+    if (op->ch2 != -1) {
+	/*
+	* There's at least one predicate. 16 == XPATH_OP_PREDICATE
+	*/
+	predOp = &ctxt->comp->steps[op->ch2];
+	if (xmlXPathIsPositionalPredicate(ctxt, predOp, &maxPos)) {
+	    if (predOp->ch1 != -1) {
+		/*
+		* Use the next inner predicate operator.
+		*/
+		predOp = &ctxt->comp->steps[predOp->ch1];
+		hasPredicateRange = 1;
+	    } else {
+		/*
+		* There's no other predicate than the [n] predicate.
+		*/
+		predOp = NULL;
+		hasAxisRange = 1;
+	    }
+	}
+    }
+    breakOnFirstHit = ((toBool) && (predOp == NULL)) ? 1 : 0;
+    /*
+    * Axis traversal -----------------------------------------------------
+    */
+    /*
+     * 2.3 Node Tests
+     *  - For the attribute axis, the principal node type is attribute.
+     *  - For the namespace axis, the principal node type is namespace.
+     *  - For other axes, the principal node type is element.
+     *
+     * A node test * is true for any node of the
+     * principal node type. For example, child::* will
+     * select all element children of the context node
+     */
+    oldContextNode = xpctxt->node;
+    addNode = xmlXPathNodeSetAddUnique;
+    outSeq = NULL;
+    seq = NULL;
+    outerContextNode = NULL;
+    contextNode = NULL;
+    contextIdx = 0;
+
+
+    while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) {
+	if (outerNext != NULL) {
+	    /*
+	    * This is a compound traversal.
+	    */
+	    if (contextNode == NULL) {
+		/*
+		* Set the context for the outer traversal.
+		*/
+		outerContextNode = contextSeq->nodeTab[contextIdx++];
+		contextNode = outerNext(NULL, outerContextNode);
+	    } else
+		contextNode = outerNext(contextNode, outerContextNode);
+	    if (contextNode == NULL)
+		continue;
+	    /*
+	    * Set the context for the main traversal.
+	    */
+	    xpctxt->node = contextNode;
+	} else
+	    xpctxt->node = contextSeq->nodeTab[contextIdx++];
+
+	if (seq == NULL) {
+	    seq = xmlXPathNodeSetCreate(NULL);
+	    if (seq == NULL) {
+		total = 0;
+		goto error;
+	    }
+	}
+	/*
+	* Traverse the axis and test the nodes.
+	*/
+	pos = 0;
+	cur = NULL;
+	hasNsNodes = 0;
+        do {
+            cur = next(ctxt, cur);
+            if (cur == NULL)
+                break;
+
+	    /*
+	    * QUESTION TODO: What does the "first" and "last" stuff do?
+	    */
+            if ((first != NULL) && (*first != NULL)) {
+		if (*first == cur)
+		    break;
+		if (((total % 256) == 0) &&
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+		    (xmlXPathCmpNodesExt(*first, cur) >= 0))
+#else
+		    (xmlXPathCmpNodes(*first, cur) >= 0))
+#endif
+		{
+		    break;
+		}
+	    }
+	    if ((last != NULL) && (*last != NULL)) {
+		if (*last == cur)
+		    break;
+		if (((total % 256) == 0) &&
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+		    (xmlXPathCmpNodesExt(cur, *last) >= 0))
+#else
+		    (xmlXPathCmpNodes(cur, *last) >= 0))
+#endif
+		{
+		    break;
+		}
+	    }
+
+            total++;
+
+#ifdef DEBUG_STEP
+            xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
+#endif
+
+	    switch (test) {
+                case NODE_TEST_NONE:
+		    total = 0;
+                    STRANGE
+		    goto error;
+                case NODE_TEST_TYPE:
+		    /*
+		    * TODO: Don't we need to use
+		    *  xmlXPathNodeSetAddNs() for namespace nodes here?
+		    *  Surprisingly, some c14n tests fail, if we do this.
+		    */
+		    if (type == NODE_TYPE_NODE) {
+			switch (cur->type) {
+			    case XML_DOCUMENT_NODE:
+			    case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+			    case XML_DOCB_DOCUMENT_NODE:
+#endif
+			    case XML_ELEMENT_NODE:
+			    case XML_ATTRIBUTE_NODE:
+			    case XML_PI_NODE:
+			    case XML_COMMENT_NODE:
+			    case XML_CDATA_SECTION_NODE:
+			    case XML_TEXT_NODE:
+			    case XML_NAMESPACE_DECL:
+				XP_TEST_HIT
+				break;
+			    default:
+				break;
+			}
+		    } else if (cur->type == type) {
+			if (cur->type == XML_NAMESPACE_DECL)
+			    XP_TEST_HIT_NS
+			else
+			    XP_TEST_HIT
+		    } else if ((type == NODE_TYPE_TEXT) &&
+			 (cur->type == XML_CDATA_SECTION_NODE))
+		    {
+			XP_TEST_HIT
+		    }
+		    break;
+                case NODE_TEST_PI:
+                    if ((cur->type == XML_PI_NODE) &&
+                        ((name == NULL) || xmlStrEqual(name, cur->name)))
+		    {
+			XP_TEST_HIT
+                    }
+                    break;
+                case NODE_TEST_ALL:
+                    if (axis == AXIS_ATTRIBUTE) {
+                        if (cur->type == XML_ATTRIBUTE_NODE)
+			{
+			    XP_TEST_HIT
+                        }
+                    } else if (axis == AXIS_NAMESPACE) {
+                        if (cur->type == XML_NAMESPACE_DECL)
+			{
+			    XP_TEST_HIT_NS
+                        }
+                    } else {
+                        if (cur->type == XML_ELEMENT_NODE) {
+                            if (prefix == NULL)
+			    {
+				XP_TEST_HIT
+
+                            } else if ((cur->ns != NULL) &&
+				(xmlStrEqual(URI, cur->ns->href)))
+			    {
+				XP_TEST_HIT
+                            }
+                        }
+                    }
+                    break;
+                case NODE_TEST_NS:{
+                        TODO;
+                        break;
+                    }
+                case NODE_TEST_NAME:
+                    if (axis == AXIS_ATTRIBUTE) {
+                        if (cur->type != XML_ATTRIBUTE_NODE)
+			    break;
+		    } else if (axis == AXIS_NAMESPACE) {
+                        if (cur->type != XML_NAMESPACE_DECL)
+			    break;
+		    } else {
+		        if (cur->type != XML_ELEMENT_NODE)
+			    break;
+		    }
+                    switch (cur->type) {
+                        case XML_ELEMENT_NODE:
+                            if (xmlStrEqual(name, cur->name)) {
+                                if (prefix == NULL) {
+                                    if (cur->ns == NULL)
+				    {
+					XP_TEST_HIT
+                                    }
+                                } else {
+                                    if ((cur->ns != NULL) &&
+                                        (xmlStrEqual(URI, cur->ns->href)))
+				    {
+					XP_TEST_HIT
+                                    }
+                                }
+                            }
+                            break;
+                        case XML_ATTRIBUTE_NODE:{
+                                xmlAttrPtr attr = (xmlAttrPtr) cur;
+
+                                if (xmlStrEqual(name, attr->name)) {
+                                    if (prefix == NULL) {
+                                        if ((attr->ns == NULL) ||
+                                            (attr->ns->prefix == NULL))
+					{
+					    XP_TEST_HIT
+                                        }
+                                    } else {
+                                        if ((attr->ns != NULL) &&
+                                            (xmlStrEqual(URI,
+					      attr->ns->href)))
+					{
+					    XP_TEST_HIT
+                                        }
+                                    }
+                                }
+                                break;
+                            }
+                        case XML_NAMESPACE_DECL:
+                            if (cur->type == XML_NAMESPACE_DECL) {
+                                xmlNsPtr ns = (xmlNsPtr) cur;
+
+                                if ((ns->prefix != NULL) && (name != NULL)
+                                    && (xmlStrEqual(ns->prefix, name)))
+				{
+				    XP_TEST_HIT_NS
+                                }
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
+	    } /* switch(test) */
+        } while (cur != NULL);
+
+	goto apply_predicates;
+
+axis_range_end: /* ----------------------------------------------------- */
+	/*
+	* We have a "/foo[n]", and position() = n was reached.
+	* Note that we can have as well "/foo/::parent::foo[1]", so
+	* a duplicate-aware merge is still needed.
+	* Merge with the result.
+	*/
+	if (outSeq == NULL) {
+	    outSeq = seq;
+	    seq = NULL;
+	} else
+	    outSeq = mergeAndClear(outSeq, seq, 0);
+	/*
+	* Break if only a true/false result was requested.
+	*/
+	if (toBool)
+	    break;
+	continue;
+
+first_hit: /* ---------------------------------------------------------- */
+	/*
+	* Break if only a true/false result was requested and
+	* no predicates existed and a node test succeeded.
+	*/
+	if (outSeq == NULL) {
+	    outSeq = seq;
+	    seq = NULL;
+	} else
+	    outSeq = mergeAndClear(outSeq, seq, 0);
+	break;
+
+#ifdef DEBUG_STEP
+	if (seq != NULL)
+	    nbMatches += seq->nodeNr;
+#endif
+
+apply_predicates: /* --------------------------------------------------- */
+        /*
+	* Apply predicates.
+	*/
+        if ((predOp != NULL) && (seq->nodeNr > 0)) {
+	    /*
+	    * E.g. when we have a "/foo[some expression][n]".
+	    */	    
+	    /*
+	    * QUESTION TODO: The old predicate evaluation took into
+	    *  account location-sets.
+	    *  (E.g. ctxt->value->type == XPATH_LOCATIONSET)
+	    *  Do we expect such a set here?
+	    *  All what I learned now from the evaluation semantics
+	    *  does not indicate that a location-set will be processed
+	    *  here, so this looks OK.
+	    */	    
+	    /*
+	    * Iterate over all predicates, starting with the outermost
+	    * predicate.
+	    * TODO: Problem: we cannot execute the inner predicates first
+	    *  since we cannot go back *up* the operator tree!
+	    *  Options we have:
+	    *  1) Use of recursive functions (like is it currently done
+	    *     via xmlXPathCompOpEval())
+	    *  2) Add a predicate evaluation information stack to the
+	    *     context struct
+	    *  3) Change the way the operators are linked; we need a
+	    *     "parent" field on xmlXPathStepOp
+	    *
+	    * For the moment, I'll try to solve this with a recursive
+	    * function: xmlXPathCompOpEvalPredicate().
+	    */
+	    size = seq->nodeNr;
+	    if (hasPredicateRange != 0)
+		newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt,
+		    predOp, seq, size, maxPos, maxPos, hasNsNodes);
+	    else
+		newSize = xmlXPathCompOpEvalPredicate(ctxt,
+		    predOp, seq, size, hasNsNodes);
+
+	    if (ctxt->error != XPATH_EXPRESSION_OK) {
+		total = 0;
+		goto error;
+	    }
+	    /*
+	    * Add the filtered set of nodes to the result node set.
+	    */
+	    if (newSize == 0) {
+		/*
+		* The predicates filtered all nodes out.
+		*/
+		xmlXPathNodeSetClear(seq, hasNsNodes);
+	    } else if (seq->nodeNr > 0) {
+		/*
+		* Add to result set.
+		*/
+		if (outSeq == NULL) {
+		    if (size != newSize) {
+			/*
+			* We need to merge and clear here, since
+			* the sequence will contained NULLed entries.
+			*/
+			outSeq = mergeAndClear(NULL, seq, 1);
+		    } else {
+			outSeq = seq;
+			seq = NULL;
+		    }
+		} else
+		    outSeq = mergeAndClear(outSeq, seq,
+			(size != newSize) ? 1: 0);
+		/*
+		* Break if only a true/false result was requested.
+		*/
+		if (toBool)
+		    break;
+	    }
+        } else if (seq->nodeNr > 0) {
+	    /*
+	    * Add to result set.
+	    */
+	    if (outSeq == NULL) {
+		outSeq = seq;
+		seq = NULL;
+	    } else {
+		outSeq = mergeAndClear(outSeq, seq, 0);
+	    }
+	}
+    }
+
+error:
+    if ((obj->boolval) && (obj->user != NULL)) {
+	/*
+	* QUESTION TODO: What does this do and why?
+	* TODO: Do we have to do this also for the "error"
+	* cleanup further down?
+	*/
+	ctxt->value->boolval = 1;
+	ctxt->value->user = obj->user;
+	obj->user = NULL;
+	obj->boolval = 0;
+    }
+    xmlXPathReleaseObject(xpctxt, obj);
+
+    /*
+    * Ensure we return at least an emtpy set.
+    */
+    if (outSeq == NULL) {
+	if ((seq != NULL) && (seq->nodeNr == 0))
+	    outSeq = seq;
+	else
+	    outSeq = xmlXPathNodeSetCreate(NULL);
+        /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
+    }
+    if ((seq != NULL) && (seq != outSeq)) {
+	 xmlXPathFreeNodeSet(seq);
+    }
+    /*
+    * Hand over the result. Better to push the set also in
+    * case of errors.
+    */
+    valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq));
+    /*
+    * Reset the context node.
+    */
+    xpctxt->node = oldContextNode;
+
+#ifdef DEBUG_STEP
+    xmlGenericError(xmlGenericErrorContext,
+	"\nExamined %d nodes, found %d nodes at that step\n",
+	total, nbMatches);
+#endif
+
+    return(total);
+}
+
+static int
+xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
+			      xmlXPathStepOpPtr op, xmlNodePtr * first);
+
+/**
+ * xmlXPathCompOpEvalFirst:
+ * @ctxt:  the XPath parser context with the compiled expression
+ * @op:  an XPath compiled operation
+ * @first:  the first elem found so far
+ *
+ * Evaluate the Precompiled XPath operation searching only the first
+ * element in document order
+ *
+ * Returns the number of examined objects.
+ */
+static int
+xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
+                        xmlXPathStepOpPtr op, xmlNodePtr * first)
+{
+    int total = 0, cur;
+    xmlXPathCompExprPtr comp;
+    xmlXPathObjectPtr arg1, arg2;
+
+    CHECK_ERROR0;
+    comp = ctxt->comp;
+    switch (op->op) {
+        case XPATH_OP_END:
+            return (0);
+        case XPATH_OP_UNION:
+            total =
+                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
+                                        first);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL)
+                && (ctxt->value->type == XPATH_NODESET)
+                && (ctxt->value->nodesetval != NULL)
+                && (ctxt->value->nodesetval->nodeNr >= 1)) {
+                /*
+                 * limit tree traversing to first node in the result
+                 */
+		/*
+		* OPTIMIZE TODO: This implicitely sorts
+		*  the result, even if not needed. E.g. if the argument
+		*  of the count() function, no sorting is needed.
+		* OPTIMIZE TODO: How do we know if the node-list wasn't
+		*  aready sorted?
+		*/
+		if (ctxt->value->nodesetval->nodeNr > 1)
+		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
+                *first = ctxt->value->nodesetval->nodeTab[0];
+            }
+            cur =
+                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2],
+                                        first);
+	    CHECK_ERROR0;
+            CHECK_TYPE0(XPATH_NODESET);
+            arg2 = valuePop(ctxt);
+
+            CHECK_TYPE0(XPATH_NODESET);
+            arg1 = valuePop(ctxt);
+
+            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
+                                                    arg2->nodesetval);
+            valuePush(ctxt, arg1);
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+            /* optimizer */
+	    if (total > cur)
+		xmlXPathCompSwap(op);
+            return (total + cur);
+        case XPATH_OP_ROOT:
+            xmlXPathRoot(ctxt);
+            return (0);
+        case XPATH_OP_NODE:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+		ctxt->context->node));
+            return (total);
+        case XPATH_OP_RESET:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            ctxt->context->node = NULL;
+            return (total);
+        case XPATH_OP_COLLECT:{
+                if (op->ch1 == -1)
+                    return (total);
+
+                total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+		CHECK_ERROR0;
+
+                total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL, 0);
+                return (total);
+            }
+        case XPATH_OP_VALUE:
+            valuePush(ctxt,
+                      xmlXPathCacheObjectCopy(ctxt->context,
+			(xmlXPathObjectPtr) op->value4));
+            return (0);
+        case XPATH_OP_SORT:
+            if (op->ch1 != -1)
+                total +=
+                    xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
+                                            first);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL)
+                && (ctxt->value->type == XPATH_NODESET)
+                && (ctxt->value->nodesetval != NULL)
+		&& (ctxt->value->nodesetval->nodeNr > 1))
+                xmlXPathNodeSetSort(ctxt->value->nodesetval);
+            return (total);
+#ifdef XP_OPTIMIZED_FILTER_FIRST
+	case XPATH_OP_FILTER:
+                total += xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
+            return (total);
+#endif
+        default:
+            return (xmlXPathCompOpEval(ctxt, op));
+    }
+}
+
+/**
+ * xmlXPathCompOpEvalLast:
+ * @ctxt:  the XPath parser context with the compiled expression
+ * @op:  an XPath compiled operation
+ * @last:  the last elem found so far
+ *
+ * Evaluate the Precompiled XPath operation searching only the last
+ * element in document order
+ *
+ * Returns the number of nodes traversed
+ */
+static int
+xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
+                       xmlNodePtr * last)
+{
+    int total = 0, cur;
+    xmlXPathCompExprPtr comp;
+    xmlXPathObjectPtr arg1, arg2;
+    xmlNodePtr bak;
+    xmlDocPtr bakd;
+    int pp;
+    int cs;
+
+    CHECK_ERROR0;
+    comp = ctxt->comp;
+    switch (op->op) {
+        case XPATH_OP_END:
+            return (0);
+        case XPATH_OP_UNION:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total =
+                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL)
+                && (ctxt->value->type == XPATH_NODESET)
+                && (ctxt->value->nodesetval != NULL)
+                && (ctxt->value->nodesetval->nodeNr >= 1)) {
+                /*
+                 * limit tree traversing to first node in the result
+                 */
+		if (ctxt->value->nodesetval->nodeNr > 1)
+		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
+                *last =
+                    ctxt->value->nodesetval->nodeTab[ctxt->value->
+                                                     nodesetval->nodeNr -
+                                                     1];
+            }
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            cur =
+                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL)
+                && (ctxt->value->type == XPATH_NODESET)
+                && (ctxt->value->nodesetval != NULL)
+                && (ctxt->value->nodesetval->nodeNr >= 1)) { /* TODO: NOP ? */
+            }
+            CHECK_TYPE0(XPATH_NODESET);
+            arg2 = valuePop(ctxt);
+
+            CHECK_TYPE0(XPATH_NODESET);
+            arg1 = valuePop(ctxt);
+
+            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
+                                                    arg2->nodesetval);
+            valuePush(ctxt, arg1);
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+            /* optimizer */
+	    if (total > cur)
+		xmlXPathCompSwap(op);
+            return (total + cur);
+        case XPATH_OP_ROOT:
+            xmlXPathRoot(ctxt);
+            return (0);
+        case XPATH_OP_NODE:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+		ctxt->context->node));
+            return (total);
+        case XPATH_OP_RESET:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            ctxt->context->node = NULL;
+            return (total);
+        case XPATH_OP_COLLECT:{
+                if (op->ch1 == -1)
+                    return (0);
+
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+		CHECK_ERROR0;
+
+                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last, 0);
+                return (total);
+            }
+        case XPATH_OP_VALUE:
+            valuePush(ctxt,
+                      xmlXPathCacheObjectCopy(ctxt->context,
+			(xmlXPathObjectPtr) op->value4));
+            return (0);
+        case XPATH_OP_SORT:
+            if (op->ch1 != -1)
+                total +=
+                    xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1],
+                                           last);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL)
+                && (ctxt->value->type == XPATH_NODESET)
+                && (ctxt->value->nodesetval != NULL)
+		&& (ctxt->value->nodesetval->nodeNr > 1))
+                xmlXPathNodeSetSort(ctxt->value->nodesetval);
+            return (total);
+        default:
+            return (xmlXPathCompOpEval(ctxt, op));
+    }
+}
+
+#ifdef XP_OPTIMIZED_FILTER_FIRST
+static int
+xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
+			      xmlXPathStepOpPtr op, xmlNodePtr * first)
+{
+    int total = 0;
+    xmlXPathCompExprPtr comp;
+    xmlXPathObjectPtr res;
+    xmlXPathObjectPtr obj;
+    xmlNodeSetPtr oldset;
+    xmlNodePtr oldnode;
+    xmlDocPtr oldDoc;
+    int i;
+
+    CHECK_ERROR0;
+    comp = ctxt->comp;
+    /*
+    * Optimization for ()[last()] selection i.e. the last elem
+    */
+    if ((op->ch1 != -1) && (op->ch2 != -1) &&
+	(comp->steps[op->ch1].op == XPATH_OP_SORT) &&
+	(comp->steps[op->ch2].op == XPATH_OP_SORT)) {
+	int f = comp->steps[op->ch2].ch1;
+
+	if ((f != -1) &&
+	    (comp->steps[f].op == XPATH_OP_FUNCTION) &&
+	    (comp->steps[f].value5 == NULL) &&
+	    (comp->steps[f].value == 0) &&
+	    (comp->steps[f].value4 != NULL) &&
+	    (xmlStrEqual
+	    (comp->steps[f].value4, BAD_CAST "last"))) {
+	    xmlNodePtr last = NULL;
+
+	    total +=
+		xmlXPathCompOpEvalLast(ctxt,
+		    &comp->steps[op->ch1],
+		    &last);
+	    CHECK_ERROR0;
+	    /*
+	    * The nodeset should be in document order,
+	    * Keep only the last value
+	    */
+	    if ((ctxt->value != NULL) &&
+		(ctxt->value->type == XPATH_NODESET) &&
+		(ctxt->value->nodesetval != NULL) &&
+		(ctxt->value->nodesetval->nodeTab != NULL) &&
+		(ctxt->value->nodesetval->nodeNr > 1)) {
+		ctxt->value->nodesetval->nodeTab[0] =
+		    ctxt->value->nodesetval->nodeTab[ctxt->
+		    value->
+		    nodesetval->
+		    nodeNr -
+		    1];
+		ctxt->value->nodesetval->nodeNr = 1;
+		*first = *(ctxt->value->nodesetval->nodeTab);
+	    }
+	    return (total);
+	}
+    }
+
+    if (op->ch1 != -1)
+	total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+    CHECK_ERROR0;
+    if (op->ch2 == -1)
+	return (total);
+    if (ctxt->value == NULL)
+	return (total);
+
+#ifdef LIBXML_XPTR_ENABLED
+    oldnode = ctxt->context->node;
+    /*
+    * Hum are we filtering the result of an XPointer expression
+    */
+    if (ctxt->value->type == XPATH_LOCATIONSET) {
+	xmlXPathObjectPtr tmp = NULL;
+	xmlLocationSetPtr newlocset = NULL;
+	xmlLocationSetPtr oldlocset;
+
+	/*
+	* Extract the old locset, and then evaluate the result of the
+	* expression for all the element in the locset. use it to grow
+	* up a new locset.
+	*/
+	CHECK_TYPE0(XPATH_LOCATIONSET);
+	obj = valuePop(ctxt);
+	oldlocset = obj->user;
+	ctxt->context->node = NULL;
+
+	if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
+	    ctxt->context->contextSize = 0;
+	    ctxt->context->proximityPosition = 0;
+	    if (op->ch2 != -1)
+		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    res = valuePop(ctxt);
+	    if (res != NULL) {
+		xmlXPathReleaseObject(ctxt->context, res);
+	    }
+	    valuePush(ctxt, obj);
+	    CHECK_ERROR0;
+	    return (total);
+	}
+	newlocset = xmlXPtrLocationSetCreate(NULL);
+
+	for (i = 0; i < oldlocset->locNr; i++) {
+	    /*
+	    * Run the evaluation with a node list made of a
+	    * single item in the nodelocset.
+	    */
+	    ctxt->context->node = oldlocset->locTab[i]->user;
+	    ctxt->context->contextSize = oldlocset->locNr;
+	    ctxt->context->proximityPosition = i + 1;
+	    if (tmp == NULL) {
+		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+		    ctxt->context->node);
+	    } else {
+		xmlXPathNodeSetAddUnique(tmp->nodesetval,
+		    ctxt->context->node);
+	    }
+	    valuePush(ctxt, tmp);
+	    if (op->ch2 != -1)
+		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    if (ctxt->error != XPATH_EXPRESSION_OK) {
+		xmlXPathFreeObject(obj);
+		return(0);
+	    }
+	    /*
+	    * The result of the evaluation need to be tested to
+	    * decided whether the filter succeeded or not
+	    */
+	    res = valuePop(ctxt);
+	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+		xmlXPtrLocationSetAdd(newlocset,
+		    xmlXPathCacheObjectCopy(ctxt->context,
+			oldlocset->locTab[i]));
+	    }
+	    /*
+	    * Cleanup
+	    */
+	    if (res != NULL) {
+		xmlXPathReleaseObject(ctxt->context, res);
+	    }
+	    if (ctxt->value == tmp) {
+		valuePop(ctxt);
+		xmlXPathNodeSetClear(tmp->nodesetval, 1);
+		/*
+		* REVISIT TODO: Don't create a temporary nodeset
+		* for everly iteration.
+		*/
+		/* OLD: xmlXPathFreeObject(res); */
+	    } else
+		tmp = NULL;
+	    ctxt->context->node = NULL;
+	    /*
+	    * Only put the first node in the result, then leave.
+	    */
+	    if (newlocset->locNr > 0) {
+		*first = (xmlNodePtr) oldlocset->locTab[i]->user;
+		break;
+	    }
+	}
+	if (tmp != NULL) {
+	    xmlXPathReleaseObject(ctxt->context, tmp);
+	}
+	/*
+	* The result is used as the new evaluation locset.
+	*/
+	xmlXPathReleaseObject(ctxt->context, obj);
+	ctxt->context->node = NULL;
+	ctxt->context->contextSize = -1;
+	ctxt->context->proximityPosition = -1;
+	valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
+	ctxt->context->node = oldnode;
+	return (total);
+    }
+#endif /* LIBXML_XPTR_ENABLED */
+
+    /*
+    * Extract the old set, and then evaluate the result of the
+    * expression for all the element in the set. use it to grow
+    * up a new set.
+    */
+    CHECK_TYPE0(XPATH_NODESET);
+    obj = valuePop(ctxt);
+    oldset = obj->nodesetval;
+
+    oldnode = ctxt->context->node;
+    oldDoc = ctxt->context->doc;
+    ctxt->context->node = NULL;
+
+    if ((oldset == NULL) || (oldset->nodeNr == 0)) {
+	ctxt->context->contextSize = 0;
+	ctxt->context->proximityPosition = 0;
+	/* QUESTION TODO: Why was this code commented out?
+	    if (op->ch2 != -1)
+		total +=
+		    xmlXPathCompOpEval(ctxt,
+			&comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+	    res = valuePop(ctxt);
+	    if (res != NULL)
+		xmlXPathFreeObject(res);
+	*/
+	valuePush(ctxt, obj);
+	ctxt->context->node = oldnode;
+	CHECK_ERROR0;
+    } else {
+	xmlNodeSetPtr newset;
+	xmlXPathObjectPtr tmp = NULL;
+	/*
+	* Initialize the new set.
+	* Also set the xpath document in case things like
+	* key() evaluation are attempted on the predicate
+	*/
+	newset = xmlXPathNodeSetCreate(NULL);
+        /* XXX what if xmlXPathNodeSetCreate returned NULL? */
+
+	for (i = 0; i < oldset->nodeNr; i++) {
+	    /*
+	    * Run the evaluation with a node list made of
+	    * a single item in the nodeset.
+	    */
+	    ctxt->context->node = oldset->nodeTab[i];
+	    if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
+		(oldset->nodeTab[i]->doc != NULL))
+		ctxt->context->doc = oldset->nodeTab[i]->doc;
+	    if (tmp == NULL) {
+		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+		    ctxt->context->node);
+	    } else {
+		xmlXPathNodeSetAddUnique(tmp->nodesetval,
+		    ctxt->context->node);
+	    }
+	    valuePush(ctxt, tmp);
+	    ctxt->context->contextSize = oldset->nodeNr;
+	    ctxt->context->proximityPosition = i + 1;
+	    if (op->ch2 != -1)
+		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    if (ctxt->error != XPATH_EXPRESSION_OK) {
+		xmlXPathFreeNodeSet(newset);
+		xmlXPathFreeObject(obj);
+		return(0);
+	    }
+	    /*
+	    * The result of the evaluation needs to be tested to
+	    * decide whether the filter succeeded or not
+	    */
+	    res = valuePop(ctxt);
+	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+		xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
+	    }
+	    /*
+	    * Cleanup
+	    */
+	    if (res != NULL) {
+		xmlXPathReleaseObject(ctxt->context, res);
+	    }
+	    if (ctxt->value == tmp) {
+		valuePop(ctxt);
+		/*
+		* Don't free the temporary nodeset
+		* in order to avoid massive recreation inside this
+		* loop.
+		*/
+		xmlXPathNodeSetClear(tmp->nodesetval, 1);
+	    } else
+		tmp = NULL;
+	    ctxt->context->node = NULL;
+	    /*
+	    * Only put the first node in the result, then leave.
+	    */
+	    if (newset->nodeNr > 0) {
+		*first = *(newset->nodeTab);
+		break;
+	    }
+	}
+	if (tmp != NULL) {
+	    xmlXPathReleaseObject(ctxt->context, tmp);
+	}
+	/*
+	* The result is used as the new evaluation set.
+	*/
+	xmlXPathReleaseObject(ctxt->context, obj);
+	ctxt->context->node = NULL;
+	ctxt->context->contextSize = -1;
+	ctxt->context->proximityPosition = -1;
+	/* may want to move this past the '}' later */
+	ctxt->context->doc = oldDoc;
+	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
+    }
+    ctxt->context->node = oldnode;
+    return(total);
+}
+#endif /* XP_OPTIMIZED_FILTER_FIRST */
+
+/**
+ * xmlXPathCompOpEval:
+ * @ctxt:  the XPath parser context with the compiled expression
+ * @op:  an XPath compiled operation
+ *
+ * Evaluate the Precompiled XPath operation
+ * Returns the number of nodes traversed
+ */
+static int
+xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+{
+    int total = 0;
+    int equal, ret;
+    xmlXPathCompExprPtr comp;
+    xmlXPathObjectPtr arg1, arg2;
+    xmlNodePtr bak;
+    xmlDocPtr bakd;
+    int pp;
+    int cs;
+
+    CHECK_ERROR0;
+    comp = ctxt->comp;
+    switch (op->op) {
+        case XPATH_OP_END:
+            return (0);
+        case XPATH_OP_AND:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            xmlXPathBooleanFunction(ctxt, 1);
+            if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
+                return (total);
+            arg2 = valuePop(ctxt);
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    if (ctxt->error) {
+		xmlXPathFreeObject(arg2);
+		return(0);
+	    }
+            xmlXPathBooleanFunction(ctxt, 1);
+            arg1 = valuePop(ctxt);
+            arg1->boolval &= arg2->boolval;
+            valuePush(ctxt, arg1);
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+            return (total);
+        case XPATH_OP_OR:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            xmlXPathBooleanFunction(ctxt, 1);
+            if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
+                return (total);
+            arg2 = valuePop(ctxt);
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    if (ctxt->error) {
+		xmlXPathFreeObject(arg2);
+		return(0);
+	    }
+            xmlXPathBooleanFunction(ctxt, 1);
+            arg1 = valuePop(ctxt);
+            arg1->boolval |= arg2->boolval;
+            valuePush(ctxt, arg1);
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+            return (total);
+        case XPATH_OP_EQUAL:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+	    if (op->value)
+		equal = xmlXPathEqualValues(ctxt);
+	    else
+		equal = xmlXPathNotEqualValues(ctxt);
+	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
+            return (total);
+        case XPATH_OP_CMP:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
+	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
+            return (total);
+        case XPATH_OP_PLUS:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1) {
+		ctxt->context->doc = bakd;
+		ctxt->context->node = bak;
+		ctxt->context->proximityPosition = pp;
+		ctxt->context->contextSize = cs;
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    }
+	    CHECK_ERROR0;
+            if (op->value == 0)
+                xmlXPathSubValues(ctxt);
+            else if (op->value == 1)
+                xmlXPathAddValues(ctxt);
+            else if (op->value == 2)
+                xmlXPathValueFlipSign(ctxt);
+            else if (op->value == 3) {
+                CAST_TO_NUMBER;
+                CHECK_TYPE0(XPATH_NUMBER);
+            }
+            return (total);
+        case XPATH_OP_MULT:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            if (op->value == 0)
+                xmlXPathMultValues(ctxt);
+            else if (op->value == 1)
+                xmlXPathDivValues(ctxt);
+            else if (op->value == 2)
+                xmlXPathModValues(ctxt);
+            return (total);
+        case XPATH_OP_UNION:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+	    ctxt->context->doc = bakd;
+	    ctxt->context->node = bak;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->contextSize = cs;
+            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            CHECK_TYPE0(XPATH_NODESET);
+            arg2 = valuePop(ctxt);
+
+            CHECK_TYPE0(XPATH_NODESET);
+            arg1 = valuePop(ctxt);
+
+	    if ((arg1->nodesetval == NULL) ||
+		((arg2->nodesetval != NULL) &&
+		 (arg2->nodesetval->nodeNr != 0)))
+	    {
+		arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
+							arg2->nodesetval);
+	    }
+
+            valuePush(ctxt, arg1);
+	    xmlXPathReleaseObject(ctxt->context, arg2);
+            return (total);
+        case XPATH_OP_ROOT:
+            xmlXPathRoot(ctxt);
+            return (total);
+        case XPATH_OP_NODE:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
+		ctxt->context->node));
+            return (total);
+        case XPATH_OP_RESET:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if (op->ch2 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	    CHECK_ERROR0;
+            ctxt->context->node = NULL;
+            return (total);
+        case XPATH_OP_COLLECT:{
+                if (op->ch1 == -1)
+                    return (total);
+
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+		CHECK_ERROR0;
+
+                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 0);
+                return (total);
+            }
+        case XPATH_OP_VALUE:
+            valuePush(ctxt,
+                      xmlXPathCacheObjectCopy(ctxt->context,
+			(xmlXPathObjectPtr) op->value4));
+            return (total);
+        case XPATH_OP_VARIABLE:{
+		xmlXPathObjectPtr val;
+
+                if (op->ch1 != -1)
+                    total +=
+                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+                if (op->value5 == NULL) {
+		    val = xmlXPathVariableLookup(ctxt->context, op->value4);
+		    if (val == NULL) {
+			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
+			return(0);
+		    }
+                    valuePush(ctxt, val);
+		} else {
+                    const xmlChar *URI;
+
+                    URI = xmlXPathNsLookup(ctxt->context, op->value5);
+                    if (URI == NULL) {
+                        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,
+                                                       op->value4, URI);
+		    if (val == NULL) {
+			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
+			return(0);
+		    }
+                    valuePush(ctxt, val);
+                }
+                return (total);
+            }
+        case XPATH_OP_FUNCTION:{
+                xmlXPathFunction func;
+                const xmlChar *oldFunc, *oldFuncURI;
+		int i;
+
+                if (op->ch1 != -1)
+                    total +=
+                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+		if (ctxt->valueNr < op->value) {
+		    xmlGenericError(xmlGenericErrorContext,
+			    "xmlXPathCompOpEval: parameter error\n");
+		    ctxt->error = XPATH_INVALID_OPERAND;
+		    return (total);
+		}
+		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;
+			return (total);
+		    }
+                if (op->cache != NULL)
+                    XML_CAST_FPTR(func) = op->cache;
+                else {
+                    const xmlChar *URI = NULL;
+
+                    if (op->value5 == NULL)
+                        func =
+                            xmlXPathFunctionLookup(ctxt->context,
+                                                   op->value4);
+                    else {
+                        URI = xmlXPathNsLookup(ctxt->context, op->value5);
+                        if (URI == NULL) {
+                            xmlGenericError(xmlGenericErrorContext,
+            "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
+                                    (char *)op->value4, (char *)op->value5);
+                            ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
+                            return (total);
+                        }
+                        func = xmlXPathFunctionLookupNS(ctxt->context,
+                                                        op->value4, URI);
+                    }
+                    if (func == NULL) {
+                        xmlGenericError(xmlGenericErrorContext,
+                                "xmlXPathCompOpEval: function %s not found\n",
+                                        (char *)op->value4);
+                        XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR);
+                    }
+                    op->cache = XML_CAST_FPTR(func);
+                    op->cacheURI = (void *) URI;
+                }
+                oldFunc = ctxt->context->function;
+                oldFuncURI = ctxt->context->functionURI;
+                ctxt->context->function = op->value4;
+                ctxt->context->functionURI = op->cacheURI;
+                func(ctxt, op->value);
+                ctxt->context->function = oldFunc;
+                ctxt->context->functionURI = oldFuncURI;
+                return (total);
+            }
+        case XPATH_OP_ARG:
+	    bakd = ctxt->context->doc;
+	    bak = ctxt->context->node;
+	    pp = ctxt->context->proximityPosition;
+	    cs = ctxt->context->contextSize;
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    ctxt->context->contextSize = cs;
+	    ctxt->context->proximityPosition = pp;
+	    ctxt->context->node = bak;
+	    ctxt->context->doc = bakd;
+	    CHECK_ERROR0;
+            if (op->ch2 != -1) {
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+	        ctxt->context->doc = bakd;
+	        ctxt->context->node = bak;
+	        CHECK_ERROR0;
+	    }
+            return (total);
+        case XPATH_OP_PREDICATE:
+        case XPATH_OP_FILTER:{
+                xmlXPathObjectPtr res;
+                xmlXPathObjectPtr obj, tmp;
+                xmlNodeSetPtr newset = NULL;
+                xmlNodeSetPtr oldset;
+                xmlNodePtr oldnode;
+		xmlDocPtr oldDoc;
+                int i;
+
+                /*
+                 * Optimization for ()[1] selection i.e. the first elem
+                 */
+                if ((op->ch1 != -1) && (op->ch2 != -1) &&
+#ifdef XP_OPTIMIZED_FILTER_FIRST
+		    /*
+		    * FILTER TODO: Can we assume that the inner processing
+		    *  will result in an ordered list if we have an
+		    *  XPATH_OP_FILTER?
+		    *  What about an additional field or flag on
+		    *  xmlXPathObject like @sorted ? This way we wouln'd need
+		    *  to assume anything, so it would be more robust and
+		    *  easier to optimize.
+		    */
+                    ((comp->steps[op->ch1].op == XPATH_OP_SORT) || /* 18 */
+		     (comp->steps[op->ch1].op == XPATH_OP_FILTER)) && /* 17 */
+#else
+		    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
+#endif
+                    (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { /* 12 */
+                    xmlXPathObjectPtr val;
+
+                    val = comp->steps[op->ch2].value4;
+                    if ((val != NULL) && (val->type == XPATH_NUMBER) &&
+                        (val->floatval == 1.0)) {
+                        xmlNodePtr first = NULL;
+
+                        total +=
+                            xmlXPathCompOpEvalFirst(ctxt,
+                                                    &comp->steps[op->ch1],
+                                                    &first);
+			CHECK_ERROR0;
+                        /*
+                         * The nodeset should be in document order,
+                         * Keep only the first value
+                         */
+                        if ((ctxt->value != NULL) &&
+                            (ctxt->value->type == XPATH_NODESET) &&
+                            (ctxt->value->nodesetval != NULL) &&
+                            (ctxt->value->nodesetval->nodeNr > 1))
+                            ctxt->value->nodesetval->nodeNr = 1;
+                        return (total);
+                    }
+                }
+                /*
+                 * Optimization for ()[last()] selection i.e. the last elem
+                 */
+                if ((op->ch1 != -1) && (op->ch2 != -1) &&
+                    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
+                    (comp->steps[op->ch2].op == XPATH_OP_SORT)) {
+                    int f = comp->steps[op->ch2].ch1;
+
+                    if ((f != -1) &&
+                        (comp->steps[f].op == XPATH_OP_FUNCTION) &&
+                        (comp->steps[f].value5 == NULL) &&
+                        (comp->steps[f].value == 0) &&
+                        (comp->steps[f].value4 != NULL) &&
+                        (xmlStrEqual
+                         (comp->steps[f].value4, BAD_CAST "last"))) {
+                        xmlNodePtr last = NULL;
+
+                        total +=
+                            xmlXPathCompOpEvalLast(ctxt,
+                                                   &comp->steps[op->ch1],
+                                                   &last);
+			CHECK_ERROR0;
+                        /*
+                         * The nodeset should be in document order,
+                         * Keep only the last value
+                         */
+                        if ((ctxt->value != NULL) &&
+                            (ctxt->value->type == XPATH_NODESET) &&
+                            (ctxt->value->nodesetval != NULL) &&
+                            (ctxt->value->nodesetval->nodeTab != NULL) &&
+                            (ctxt->value->nodesetval->nodeNr > 1)) {
+                            ctxt->value->nodesetval->nodeTab[0] =
+                                ctxt->value->nodesetval->nodeTab[ctxt->
+                                                                 value->
+                                                                 nodesetval->
+                                                                 nodeNr -
+                                                                 1];
+                            ctxt->value->nodesetval->nodeNr = 1;
+                        }
+                        return (total);
+                    }
+                }
+		/*
+		* Process inner predicates first.
+		* Example "index[parent::book][1]":
+		* ...
+		*   PREDICATE   <-- we are here "[1]"
+		*     PREDICATE <-- process "[parent::book]" first
+		*       SORT
+		*         COLLECT  'parent' 'name' 'node' book
+		*           NODE
+		*     ELEM Object is a number : 1
+		*/
+                if (op->ch1 != -1)
+                    total +=
+                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+		CHECK_ERROR0;
+                if (op->ch2 == -1)
+                    return (total);
+                if (ctxt->value == NULL)
+                    return (total);
+
+                oldnode = ctxt->context->node;
+
+#ifdef LIBXML_XPTR_ENABLED
+                /*
+                 * Hum are we filtering the result of an XPointer expression
+                 */
+                if (ctxt->value->type == XPATH_LOCATIONSET) {
+                    xmlLocationSetPtr newlocset = NULL;
+                    xmlLocationSetPtr oldlocset;
+
+                    /*
+                     * Extract the old locset, and then evaluate the result of the
+                     * expression for all the element in the locset. use it to grow
+                     * up a new locset.
+                     */
+                    CHECK_TYPE0(XPATH_LOCATIONSET);
+                    obj = valuePop(ctxt);
+                    oldlocset = obj->user;
+                    ctxt->context->node = NULL;
+
+                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
+                        ctxt->context->contextSize = 0;
+                        ctxt->context->proximityPosition = 0;
+                        if (op->ch2 != -1)
+                            total +=
+                                xmlXPathCompOpEval(ctxt,
+                                                   &comp->steps[op->ch2]);
+                        res = valuePop(ctxt);
+                        if (res != NULL) {
+			    xmlXPathReleaseObject(ctxt->context, res);
+			}
+                        valuePush(ctxt, obj);
+                        CHECK_ERROR0;
+                        return (total);
+                    }
+                    newlocset = xmlXPtrLocationSetCreate(NULL);
+
+                    for (i = 0; i < oldlocset->locNr; i++) {
+                        /*
+                         * Run the evaluation with a node list made of a
+                         * single item in the nodelocset.
+                         */
+                        ctxt->context->node = oldlocset->locTab[i]->user;
+                        ctxt->context->contextSize = oldlocset->locNr;
+                        ctxt->context->proximityPosition = i + 1;
+			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+			    ctxt->context->node);
+                        valuePush(ctxt, tmp);
+
+                        if (op->ch2 != -1)
+                            total +=
+                                xmlXPathCompOpEval(ctxt,
+                                                   &comp->steps[op->ch2]);
+			if (ctxt->error != XPATH_EXPRESSION_OK) {
+			    xmlXPathFreeObject(obj);
+			    return(0);
+			}
+
+                        /*
+                         * The result of the evaluation need to be tested to
+                         * decided whether the filter succeeded or not
+                         */
+                        res = valuePop(ctxt);
+                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+                            xmlXPtrLocationSetAdd(newlocset,
+                                                  xmlXPathObjectCopy
+                                                  (oldlocset->locTab[i]));
+                        }
+
+                        /*
+                         * Cleanup
+                         */
+                        if (res != NULL) {
+			    xmlXPathReleaseObject(ctxt->context, res);
+			}
+                        if (ctxt->value == tmp) {
+                            res = valuePop(ctxt);
+			    xmlXPathReleaseObject(ctxt->context, res);
+                        }
+
+                        ctxt->context->node = NULL;
+                    }
+
+                    /*
+                     * The result is used as the new evaluation locset.
+                     */
+		    xmlXPathReleaseObject(ctxt->context, obj);
+                    ctxt->context->node = NULL;
+                    ctxt->context->contextSize = -1;
+                    ctxt->context->proximityPosition = -1;
+                    valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
+                    ctxt->context->node = oldnode;
+                    return (total);
+                }
+#endif /* LIBXML_XPTR_ENABLED */
+
+                /*
+                 * Extract the old set, and then evaluate the result of the
+                 * expression for all the element in the set. use it to grow
+                 * up a new set.
+                 */
+                CHECK_TYPE0(XPATH_NODESET);
+                obj = valuePop(ctxt);
+                oldset = obj->nodesetval;
+
+                oldnode = ctxt->context->node;
+		oldDoc = ctxt->context->doc;
+                ctxt->context->node = NULL;
+
+                if ((oldset == NULL) || (oldset->nodeNr == 0)) {
+                    ctxt->context->contextSize = 0;
+                    ctxt->context->proximityPosition = 0;
+/*
+                    if (op->ch2 != -1)
+                        total +=
+                            xmlXPathCompOpEval(ctxt,
+                                               &comp->steps[op->ch2]);
+		    CHECK_ERROR0;
+                    res = valuePop(ctxt);
+                    if (res != NULL)
+                        xmlXPathFreeObject(res);
+*/
+                    valuePush(ctxt, obj);
+                    ctxt->context->node = oldnode;
+                    CHECK_ERROR0;
+                } else {
+		    tmp = NULL;
+                    /*
+                     * Initialize the new set.
+		     * Also set the xpath document in case things like
+		     * key() evaluation are attempted on the predicate
+                     */
+                    newset = xmlXPathNodeSetCreate(NULL);
+		    /*
+		    * SPEC XPath 1.0:
+		    *  "For each node in the node-set to be filtered, the
+		    *  PredicateExpr is evaluated with that node as the
+		    *  context node, with the number of nodes in the
+		    *  node-set as the context size, and with the proximity
+		    *  position of the node in the node-set with respect to
+		    *  the axis as the context position;"
+		    * @oldset is the node-set" to be filtered.
+		    *
+		    * SPEC XPath 1.0:
+		    *  "only predicates change the context position and
+		    *  context size (see [2.4 Predicates])."
+		    * Example:
+		    *   node-set  context pos
+		    *    nA         1
+		    *    nB         2
+		    *    nC         3
+		    *   After applying predicate [position() > 1] :
+		    *   node-set  context pos
+		    *    nB         1
+		    *    nC         2
+		    *
+		    * removed the first node in the node-set, then
+		    * the context position of the
+		    */
+                    for (i = 0; i < oldset->nodeNr; i++) {
+                        /*
+                         * Run the evaluation with a node list made of
+                         * a single item in the nodeset.
+                         */
+                        ctxt->context->node = oldset->nodeTab[i];
+			if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
+			    (oldset->nodeTab[i]->doc != NULL))
+		            ctxt->context->doc = oldset->nodeTab[i]->doc;
+			if (tmp == NULL) {
+			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+				ctxt->context->node);
+			} else {
+			    xmlXPathNodeSetAddUnique(tmp->nodesetval,
+				ctxt->context->node);
+			}
+                        valuePush(ctxt, tmp);
+                        ctxt->context->contextSize = oldset->nodeNr;
+                        ctxt->context->proximityPosition = i + 1;
+			/*
+			* Evaluate the predicate against the context node.
+			* Can/should we optimize position() predicates
+			* here (e.g. "[1]")?
+			*/
+                        if (op->ch2 != -1)
+                            total +=
+                                xmlXPathCompOpEval(ctxt,
+                                                   &comp->steps[op->ch2]);
+			if (ctxt->error != XPATH_EXPRESSION_OK) {
+			    xmlXPathFreeNodeSet(newset);
+			    xmlXPathFreeObject(obj);
+			    return(0);
+			}
+
+                        /*
+                         * The result of the evaluation needs to be tested to
+                         * decide whether the filter succeeded or not
+                         */
+			/*
+			* OPTIMIZE TODO: Can we use
+			* xmlXPathNodeSetAdd*Unique()* instead?
+			*/
+                        res = valuePop(ctxt);
+                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+                            xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
+                        }
+
+                        /*
+                         * Cleanup
+                         */
+                        if (res != NULL) {
+			    xmlXPathReleaseObject(ctxt->context, res);
+			}
+                        if (ctxt->value == tmp) {
+                            valuePop(ctxt);
+			    xmlXPathNodeSetClear(tmp->nodesetval, 1);
+			    /*
+			    * Don't free the temporary nodeset
+			    * in order to avoid massive recreation inside this
+			    * loop.
+			    */
+                        } else
+			    tmp = NULL;
+                        ctxt->context->node = NULL;
+                    }
+		    if (tmp != NULL)
+			xmlXPathReleaseObject(ctxt->context, tmp);
+                    /*
+                     * The result is used as the new evaluation set.
+                     */
+		    xmlXPathReleaseObject(ctxt->context, obj);
+                    ctxt->context->node = NULL;
+                    ctxt->context->contextSize = -1;
+                    ctxt->context->proximityPosition = -1;
+		    /* may want to move this past the '}' later */
+		    ctxt->context->doc = oldDoc;
+		    valuePush(ctxt,
+			xmlXPathCacheWrapNodeSet(ctxt->context, newset));
+                }
+                ctxt->context->node = oldnode;
+                return (total);
+            }
+        case XPATH_OP_SORT:
+            if (op->ch1 != -1)
+                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+	    CHECK_ERROR0;
+            if ((ctxt->value != NULL) &&
+                (ctxt->value->type == XPATH_NODESET) &&
+                (ctxt->value->nodesetval != NULL) &&
+		(ctxt->value->nodesetval->nodeNr > 1))
+	    {
+                xmlXPathNodeSetSort(ctxt->value->nodesetval);
+	    }
+            return (total);
+#ifdef LIBXML_XPTR_ENABLED
+        case XPATH_OP_RANGETO:{
+                xmlXPathObjectPtr range;
+                xmlXPathObjectPtr res, obj;
+                xmlXPathObjectPtr tmp;
+                xmlLocationSetPtr newlocset = NULL;
+		    xmlLocationSetPtr oldlocset;
+                xmlNodeSetPtr oldset;
+                int i, j;
+
+                if (op->ch1 != -1)
+                    total +=
+                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+                if (op->ch2 == -1)
+                    return (total);
+
+                if (ctxt->value->type == XPATH_LOCATIONSET) {
+                    /*
+                     * Extract the old locset, and then evaluate the result of the
+                     * expression for all the element in the locset. use it to grow
+                     * up a new locset.
+                     */
+                    CHECK_TYPE0(XPATH_LOCATIONSET);
+                    obj = valuePop(ctxt);
+                    oldlocset = obj->user;
+
+                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
+		        ctxt->context->node = NULL;
+                        ctxt->context->contextSize = 0;
+                        ctxt->context->proximityPosition = 0;
+                        total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
+                        res = valuePop(ctxt);
+                        if (res != NULL) {
+			    xmlXPathReleaseObject(ctxt->context, res);
+			}
+                        valuePush(ctxt, obj);
+                        CHECK_ERROR0;
+                        return (total);
+                    }
+                    newlocset = xmlXPtrLocationSetCreate(NULL);
+
+                    for (i = 0; i < oldlocset->locNr; i++) {
+                        /*
+                         * Run the evaluation with a node list made of a
+                         * single item in the nodelocset.
+                         */
+                        ctxt->context->node = oldlocset->locTab[i]->user;
+                        ctxt->context->contextSize = oldlocset->locNr;
+                        ctxt->context->proximityPosition = i + 1;
+			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+			    ctxt->context->node);
+                        valuePush(ctxt, tmp);
+
+                        if (op->ch2 != -1)
+                            total +=
+                                xmlXPathCompOpEval(ctxt,
+                                                   &comp->steps[op->ch2]);
+			if (ctxt->error != XPATH_EXPRESSION_OK) {
+			    xmlXPathFreeObject(obj);
+			    return(0);
+			}
+
+                        res = valuePop(ctxt);
+			if (res->type == XPATH_LOCATIONSET) {
+			    xmlLocationSetPtr rloc =
+			        (xmlLocationSetPtr)res->user;
+			    for (j=0; j<rloc->locNr; j++) {
+			        range = xmlXPtrNewRange(
+				  oldlocset->locTab[i]->user,
+				  oldlocset->locTab[i]->index,
+				  rloc->locTab[j]->user2,
+				  rloc->locTab[j]->index2);
+				if (range != NULL) {
+				    xmlXPtrLocationSetAdd(newlocset, range);
+				}
+			    }
+			} else {
+			    range = xmlXPtrNewRangeNodeObject(
+				(xmlNodePtr)oldlocset->locTab[i]->user, res);
+                            if (range != NULL) {
+                                xmlXPtrLocationSetAdd(newlocset,range);
+			    }
+                        }
+
+                        /*
+                         * Cleanup
+                         */
+                        if (res != NULL) {
+			    xmlXPathReleaseObject(ctxt->context, res);
+			}
+                        if (ctxt->value == tmp) {
+                            res = valuePop(ctxt);
+			    xmlXPathReleaseObject(ctxt->context, res);
+                        }
+
+                        ctxt->context->node = NULL;
+                    }
+		} else {	/* Not a location set */
+                    CHECK_TYPE0(XPATH_NODESET);
+                    obj = valuePop(ctxt);
+                    oldset = obj->nodesetval;
+                    ctxt->context->node = NULL;
+
+                    newlocset = xmlXPtrLocationSetCreate(NULL);
+
+                    if (oldset != NULL) {
+                        for (i = 0; i < oldset->nodeNr; i++) {
+                            /*
+                             * Run the evaluation with a node list made of a single item
+                             * in the nodeset.
+                             */
+                            ctxt->context->node = oldset->nodeTab[i];
+			    /*
+			    * OPTIMIZE TODO: Avoid recreation for every iteration.
+			    */
+			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+				ctxt->context->node);
+                            valuePush(ctxt, tmp);
+
+                            if (op->ch2 != -1)
+                                total +=
+                                    xmlXPathCompOpEval(ctxt,
+                                                   &comp->steps[op->ch2]);
+			    if (ctxt->error != XPATH_EXPRESSION_OK) {
+				xmlXPathFreeObject(obj);
+				return(0);
+			    }
+
+                            res = valuePop(ctxt);
+                            range =
+                                xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
+                                                      res);
+                            if (range != NULL) {
+                                xmlXPtrLocationSetAdd(newlocset, range);
+                            }
+
+                            /*
+                             * Cleanup
+                             */
+                            if (res != NULL) {
+				xmlXPathReleaseObject(ctxt->context, res);
+			    }
+                            if (ctxt->value == tmp) {
+                                res = valuePop(ctxt);
+				xmlXPathReleaseObject(ctxt->context, res);
+                            }
+
+                            ctxt->context->node = NULL;
+                        }
+                    }
+                }
+
+                /*
+                 * The result is used as the new evaluation set.
+                 */
+		xmlXPathReleaseObject(ctxt->context, obj);
+                ctxt->context->node = NULL;
+                ctxt->context->contextSize = -1;
+                ctxt->context->proximityPosition = -1;
+                valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
+                return (total);
+            }
+#endif /* LIBXML_XPTR_ENABLED */
+    }
+    xmlGenericError(xmlGenericErrorContext,
+                    "XPath: unknown precompiled operation %d\n", op->op);
+    return (total);
+}
+
+/**
+ * xmlXPathCompOpEvalToBoolean:
+ * @ctxt:  the XPath parser context
+ *
+ * Evaluates if the expression evaluates to true.
+ *
+ * Returns 1 if true, 0 if false and -1 on API or internal errors.
+ */
+static int
+xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
+			    xmlXPathStepOpPtr op,
+			    int isPredicate)
+{
+    xmlXPathObjectPtr resObj = NULL;
+
+start:
+    /* comp = ctxt->comp; */
+    switch (op->op) {
+        case XPATH_OP_END:
+            return (0);
+	case XPATH_OP_VALUE:
+	    resObj = (xmlXPathObjectPtr) op->value4;
+	    if (isPredicate)
+		return(xmlXPathEvaluatePredicateResult(ctxt, resObj));
+	    return(xmlXPathCastToBoolean(resObj));
+	case XPATH_OP_SORT:
+	    /*
+	    * We don't need sorting for boolean results. Skip this one.
+	    */
+            if (op->ch1 != -1) {
+		op = &ctxt->comp->steps[op->ch1];
+		goto start;
+	    }
+	    return(0);
+	case XPATH_OP_COLLECT:
+	    if (op->ch1 == -1)
+		return(0);
+
+            xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch1]);
+	    if (ctxt->error != XPATH_EXPRESSION_OK)
+		return(-1);
+
+            xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 1);
+	    if (ctxt->error != XPATH_EXPRESSION_OK)
+		return(-1);
+
+	    resObj = valuePop(ctxt);
+	    if (resObj == NULL)
+		return(-1);
+	    break;
+	default:
+	    /*
+	    * Fallback to call xmlXPathCompOpEval().
+	    */
+	    xmlXPathCompOpEval(ctxt, op);
+	    if (ctxt->error != XPATH_EXPRESSION_OK)
+		return(-1);
+
+	    resObj = valuePop(ctxt);
+	    if (resObj == NULL)
+		return(-1);
+	    break;
+    }
+
+    if (resObj) {
+	int res;
+
+	if (resObj->type == XPATH_BOOLEAN) {
+	    res = resObj->boolval;
+	} else if (isPredicate) {
+	    /*
+	    * For predicates a result of type "number" is handled
+	    * differently:
+	    * SPEC XPath 1.0:
+	    * "If the result is a number, the result will be converted
+	    *  to true if the number is equal to the context position
+	    *  and will be converted to false otherwise;"
+	    */
+	    res = xmlXPathEvaluatePredicateResult(ctxt, resObj);
+	} else {
+	    res = xmlXPathCastToBoolean(resObj);
+	}
+	xmlXPathReleaseObject(ctxt->context, resObj);
+	return(res);
+    }
+
+    return(0);
+}
+
+#ifdef XPATH_STREAMING
+/**
+ * xmlXPathRunStreamEval:
+ * @ctxt:  the XPath parser context with the compiled expression
+ *
+ * Evaluate the Precompiled Streamable XPath expression in the given context.
+ */
+static int
+xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp,
+		      xmlXPathObjectPtr *resultSeq, int toBool)
+{
+    int max_depth, min_depth;
+    int from_root;
+    int ret, depth;
+    int eval_all_nodes;
+    xmlNodePtr cur = NULL, limit = NULL;
+    xmlStreamCtxtPtr patstream = NULL;
+
+    int nb_nodes = 0;
+
+    if ((ctxt == NULL) || (comp == NULL))
+        return(-1);
+    max_depth = xmlPatternMaxDepth(comp);
+    if (max_depth == -1)
+        return(-1);
+    if (max_depth == -2)
+        max_depth = 10000;
+    min_depth = xmlPatternMinDepth(comp);
+    if (min_depth == -1)
+        return(-1);
+    from_root = xmlPatternFromRoot(comp);
+    if (from_root < 0)
+        return(-1);
+#if 0
+    printf("stream eval: depth %d from root %d\n", max_depth, from_root);
+#endif
+
+    if (! toBool) {
+	if (resultSeq == NULL)
+	    return(-1);
+	*resultSeq = xmlXPathCacheNewNodeSet(ctxt, NULL);
+	if (*resultSeq == NULL)
+	    return(-1);
+    }
+
+    /*
+     * handle the special cases of "/" amd "." being matched
+     */
+    if (min_depth == 0) {
+	if (from_root) {
+	    /* Select "/" */
+	    if (toBool)
+		return(1);
+	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
+		(xmlNodePtr) ctxt->doc);
+	} else {
+	    /* Select "self::node()" */
+	    if (toBool)
+		return(1);
+	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, ctxt->node);
+	}
+    }
+    if (max_depth == 0) {
+	return(0);
+    }
+
+    if (from_root) {
+        cur = (xmlNodePtr)ctxt->doc;
+    } else if (ctxt->node != NULL) {
+        switch (ctxt->node->type) {
+            case XML_ELEMENT_NODE:
+            case XML_DOCUMENT_NODE:
+            case XML_DOCUMENT_FRAG_NODE:
+            case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+            case XML_DOCB_DOCUMENT_NODE:
+#endif
+	        cur = ctxt->node;
+		break;
+            case XML_ATTRIBUTE_NODE:
+            case XML_TEXT_NODE:
+            case XML_CDATA_SECTION_NODE:
+            case XML_ENTITY_REF_NODE:
+            case XML_ENTITY_NODE:
+            case XML_PI_NODE:
+            case XML_COMMENT_NODE:
+            case XML_NOTATION_NODE:
+            case XML_DTD_NODE:
+            case XML_DOCUMENT_TYPE_NODE:
+            case XML_ELEMENT_DECL:
+            case XML_ATTRIBUTE_DECL:
+            case XML_ENTITY_DECL:
+            case XML_NAMESPACE_DECL:
+            case XML_XINCLUDE_START:
+            case XML_XINCLUDE_END:
+		break;
+	}
+	limit = cur;
+    }
+    if (cur == NULL) {
+        return(0);
+    }
+
+    patstream = xmlPatternGetStreamCtxt(comp);
+    if (patstream == NULL) {
+	/*
+	* QUESTION TODO: Is this an error?
+	*/
+	return(0);
+    }
+
+    eval_all_nodes = xmlStreamWantsAnyNode(patstream);
+
+    if (from_root) {
+	ret = xmlStreamPush(patstream, NULL, NULL);
+	if (ret < 0) {
+	} else if (ret == 1) {
+	    if (toBool)
+		goto return_1;
+	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
+	}
+    }
+    depth = 0;
+    goto scan_children;
+next_node:
+    do {
+        nb_nodes++;
+
+	switch (cur->type) {
+	    case XML_ELEMENT_NODE:
+	    case XML_TEXT_NODE:
+	    case XML_CDATA_SECTION_NODE:
+	    case XML_COMMENT_NODE:
+	    case XML_PI_NODE:
+		if (cur->type == XML_ELEMENT_NODE) {
+		    ret = xmlStreamPush(patstream, cur->name,
+				(cur->ns ? cur->ns->href : NULL));
+		} else if (eval_all_nodes)
+		    ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type);
+		else
+		    break;
+
+		if (ret < 0) {
+		    /* NOP. */
+		} else if (ret == 1) {
+		    if (toBool)
+			goto return_1;
+		    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
+		}
+		if ((cur->children == NULL) || (depth >= max_depth)) {
+		    ret = xmlStreamPop(patstream);
+		    while (cur->next != NULL) {
+			cur = cur->next;
+			if ((cur->type != XML_ENTITY_DECL) &&
+			    (cur->type != XML_DTD_NODE))
+			    goto next_node;
+		    }
+		}
+	    default:
+		break;
+	}
+
+scan_children:
+	if ((cur->children != NULL) && (depth < max_depth)) {
+	    /*
+	     * Do not descend on entities declarations
+	     */
+	    if (cur->children->type != XML_ENTITY_DECL) {
+		cur = cur->children;
+		depth++;
+		/*
+		 * Skip DTDs
+		 */
+		if (cur->type != XML_DTD_NODE)
+		    continue;
+	    }
+	}
+
+	if (cur == limit)
+	    break;
+
+	while (cur->next != NULL) {
+	    cur = cur->next;
+	    if ((cur->type != XML_ENTITY_DECL) &&
+		(cur->type != XML_DTD_NODE))
+		goto next_node;
+	}
+
+	do {
+	    cur = cur->parent;
+	    depth--;
+	    if ((cur == NULL) || (cur == limit))
+	        goto done;
+	    if (cur->type == XML_ELEMENT_NODE) {
+		ret = xmlStreamPop(patstream);
+	    } else if ((eval_all_nodes) &&
+		((cur->type == XML_TEXT_NODE) ||
+		 (cur->type == XML_CDATA_SECTION_NODE) ||
+		 (cur->type == XML_COMMENT_NODE) ||
+		 (cur->type == XML_PI_NODE)))
+	    {
+		ret = xmlStreamPop(patstream);
+	    }
+	    if (cur->next != NULL) {
+		cur = cur->next;
+		break;
+	    }
+	} while (cur != NULL);
+
+    } while ((cur != NULL) && (depth >= 0));
+
+done:
+
+#if 0
+    printf("stream eval: checked %d nodes selected %d\n",
+           nb_nodes, retObj->nodesetval->nodeNr);
+#endif
+
+    if (patstream)
+	xmlFreeStreamCtxt(patstream);
+    return(0);
+
+return_1:
+    if (patstream)
+	xmlFreeStreamCtxt(patstream);
+    return(1);
+}
+#endif /* XPATH_STREAMING */
+
+/**
+ * xmlXPathRunEval:
+ * @ctxt:  the XPath parser context with the compiled expression
+ * @toBool:  evaluate to a boolean result
+ *
+ * Evaluate the Precompiled XPath expression in the given context.
+ */
+static int
+xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
+{
+    xmlXPathCompExprPtr comp;
+
+    if ((ctxt == NULL) || (ctxt->comp == NULL))
+	return(-1);
+
+    if (ctxt->valueTab == NULL) {
+	/* Allocate the value stack */
+	ctxt->valueTab = (xmlXPathObjectPtr *)
+			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
+	if (ctxt->valueTab == NULL) {
+	    xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
+	    xmlFree(ctxt);
+	}
+	ctxt->valueNr = 0;
+	ctxt->valueMax = 10;
+	ctxt->value = NULL;
+    }
+#ifdef XPATH_STREAMING
+    if (ctxt->comp->stream) {
+	int res;
+
+	if (toBool) {
+	    /*
+	    * Evaluation to boolean result.
+	    */
+	    res = xmlXPathRunStreamEval(ctxt->context,
+		ctxt->comp->stream, NULL, 1);
+	    if (res != -1)
+		return(res);
+	} else {
+	    xmlXPathObjectPtr resObj = NULL;
+
+	    /*
+	    * Evaluation to a sequence.
+	    */
+	    res = xmlXPathRunStreamEval(ctxt->context,
+		ctxt->comp->stream, &resObj, 0);
+
+	    if ((res != -1) && (resObj != NULL)) {
+		valuePush(ctxt, resObj);
+		return(0);
+	    }
+	    if (resObj != NULL)
+		xmlXPathReleaseObject(ctxt->context, resObj);
+	}
+	/*
+	* QUESTION TODO: This falls back to normal XPath evaluation
+	* if res == -1. Is this intended?
+	*/
+    }
+#endif
+    comp = ctxt->comp;
+    if (comp->last < 0) {
+	xmlGenericError(xmlGenericErrorContext,
+	    "xmlXPathRunEval: last is less than zero\n");
+	return(-1);
+    }
+    if (toBool)
+	return(xmlXPathCompOpEvalToBoolean(ctxt,
+	    &comp->steps[comp->last], 0));
+    else
+	xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
+
+    return(0);
+}
+
+/************************************************************************
+ *									*
+ *			Public interfaces				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPathEvalPredicate:
+ * @ctxt:  the XPath context
+ * @res:  the Predicate Expression evaluation result
+ *
+ * Evaluate a predicate result for the current node.
+ * A PredicateExpr is evaluated by evaluating the Expr and converting
+ * the result to a boolean. If the result is a number, the result will
+ * be converted to true if the number is equal to the position of the
+ * context node in the context node list (as returned by the position
+ * function) and will be converted to false otherwise; if the result
+ * is not a number, then the result will be converted as if by a call
+ * to the boolean function.
+ *
+ * Returns 1 if predicate is true, 0 otherwise
+ */
+int
+xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
+    if ((ctxt == NULL) || (res == NULL)) return(0);
+    switch (res->type) {
+        case XPATH_BOOLEAN:
+	    return(res->boolval);
+        case XPATH_NUMBER:
+	    return(res->floatval == ctxt->proximityPosition);
+        case XPATH_NODESET:
+        case XPATH_XSLT_TREE:
+	    if (res->nodesetval == NULL)
+		return(0);
+	    return(res->nodesetval->nodeNr != 0);
+        case XPATH_STRING:
+	    return((res->stringval != NULL) &&
+	           (xmlStrlen(res->stringval) != 0));
+        default:
+	    STRANGE
+    }
+    return(0);
+}
+
+/**
+ * xmlXPathEvaluatePredicateResult:
+ * @ctxt:  the XPath Parser context
+ * @res:  the Predicate Expression evaluation result
+ *
+ * Evaluate a predicate result for the current node.
+ * A PredicateExpr is evaluated by evaluating the Expr and converting
+ * the result to a boolean. If the result is a number, the result will
+ * be converted to true if the number is equal to the position of the
+ * context node in the context node list (as returned by the position
+ * function) and will be converted to false otherwise; if the result
+ * is not a number, then the result will be converted as if by a call
+ * to the boolean function.
+ *
+ * Returns 1 if predicate is true, 0 otherwise
+ */
+int
+xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
+                                xmlXPathObjectPtr res) {
+    if ((ctxt == NULL) || (res == NULL)) return(0);
+    switch (res->type) {
+        case XPATH_BOOLEAN:
+	    return(res->boolval);
+        case XPATH_NUMBER:
+#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200))
+	    return((res->floatval == ctxt->context->proximityPosition) &&
+	           (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/
+#else
+	    return(res->floatval == ctxt->context->proximityPosition);
+#endif
+        case XPATH_NODESET:
+        case XPATH_XSLT_TREE:
+	    if (res->nodesetval == NULL)
+		return(0);
+	    return(res->nodesetval->nodeNr != 0);
+        case XPATH_STRING:
+	    return((res->stringval != NULL) && (res->stringval[0] != 0));
+#ifdef LIBXML_XPTR_ENABLED
+	case XPATH_LOCATIONSET:{
+	    xmlLocationSetPtr ptr = res->user;
+	    if (ptr == NULL)
+	        return(0);
+	    return (ptr->locNr != 0);
+	    }
+#endif
+        default:
+	    STRANGE
+    }
+    return(0);
+}
+
+#ifdef XPATH_STREAMING
+/**
+ * xmlXPathTryStreamCompile:
+ * @ctxt: an XPath context
+ * @str:  the XPath expression
+ *
+ * Try to compile the XPath expression as a streamable subset.
+ *
+ * Returns the compiled expression or NULL if failed to compile.
+ */
+static xmlXPathCompExprPtr
+xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
+    /*
+     * Optimization: use streaming patterns when the XPath expression can
+     * be compiled to a stream lookup
+     */
+    xmlPatternPtr stream;
+    xmlXPathCompExprPtr comp;
+    xmlDictPtr dict = NULL;
+    const xmlChar **namespaces = NULL;
+    xmlNsPtr ns;
+    int i, j;
+
+    if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) &&
+        (!xmlStrchr(str, '@'))) {
+	const xmlChar *tmp;
+
+	/*
+	 * We don't try to handle expressions using the verbose axis
+	 * specifiers ("::"), just the simplied form at this point.
+	 * Additionally, if there is no list of namespaces available and
+	 *  there's a ":" in the expression, indicating a prefixed QName,
+	 *  then we won't try to compile either. xmlPatterncompile() needs
+	 *  to have a list of namespaces at compilation time in order to
+	 *  compile prefixed name tests.
+	 */
+	tmp = xmlStrchr(str, ':');
+	if ((tmp != NULL) &&
+	    ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':')))
+	    return(NULL);
+
+	if (ctxt != NULL) {
+	    dict = ctxt->dict;
+	    if (ctxt->nsNr > 0) {
+		namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*));
+		if (namespaces == NULL) {
+		    xmlXPathErrMemory(ctxt, "allocating namespaces array\n");
+		    return(NULL);
+		}
+		for (i = 0, j = 0; (j < ctxt->nsNr); j++) {
+		    ns = ctxt->namespaces[j];
+		    namespaces[i++] = ns->href;
+		    namespaces[i++] = ns->prefix;
+		}
+		namespaces[i++] = NULL;
+		namespaces[i] = NULL;
+	    }
+	}
+
+	stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH,
+			&namespaces[0]);
+	if (namespaces != NULL) {
+	    xmlFree((xmlChar **)namespaces);
+	}
+	if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) {
+	    comp = xmlXPathNewCompExpr();
+	    if (comp == NULL) {
+		xmlXPathErrMemory(ctxt, "allocating streamable expression\n");
+		return(NULL);
+	    }
+	    comp->stream = stream;
+	    comp->dict = dict;
+	    if (comp->dict)
+		xmlDictReference(comp->dict);
+	    return(comp);
+	}
+	xmlFreePattern(stream);
+    }
+    return(NULL);
+}
+#endif /* XPATH_STREAMING */
+
+static int
+xmlXPathCanRewriteDosExpression(xmlChar *expr)
+{
+    if (expr == NULL)
+	return(0);
+    do {
+        if ((*expr == '/') && (*(++expr) == '/'))
+	    return(1);
+    } while (*expr++);
+    return(0);
+}
+static void
+xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
+{
+    /*
+    * Try to rewrite "descendant-or-self::node()/foo" to an optimized
+    * internal representation.
+    */
+    if (op->ch1 != -1) {
+	if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
+	    ((xmlXPathAxisVal) op->value == AXIS_CHILD /* 4 */) &&
+	    ((xmlXPathTestVal) op->value2 == NODE_TEST_NAME /* 5 */) &&
+	    ((xmlXPathTypeVal) op->value3 == NODE_TYPE_NODE /* 0 */))
+	{
+	    /*
+	    * This is a "child::foo"
+	    */
+	    xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
+
+	    if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
+		(prevop->ch1 != -1) &&
+		((xmlXPathAxisVal) prevop->value ==
+		    AXIS_DESCENDANT_OR_SELF) &&
+		(prevop->ch2 == -1) &&
+		((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
+		((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) &&
+		(comp->steps[prevop->ch1].op == XPATH_OP_ROOT))
+	    {
+		/*
+		* This is a "/descendant-or-self::node()" without predicates.
+		* Eliminate it.
+		*/
+		op->ch1 = prevop->ch1;
+		op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;
+	    }
+	}
+	if (op->ch1 != -1)
+	    xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]);
+    }
+    if (op->ch2 != -1)
+	xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]);
+}
+
+/**
+ * xmlXPathCtxtCompile:
+ * @ctxt: an XPath context
+ * @str:  the XPath expression
+ *
+ * Compile an XPath expression
+ *
+ * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathCompExprPtr
+xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
+    xmlXPathParserContextPtr pctxt;
+    xmlXPathCompExprPtr comp;
+
+#ifdef XPATH_STREAMING
+    comp = xmlXPathTryStreamCompile(ctxt, str);
+    if (comp != NULL)
+        return(comp);
+#endif
+
+    xmlXPathInit();
+
+    pctxt = xmlXPathNewParserContext(str, ctxt);
+    if (pctxt == NULL)
+        return NULL;
+    xmlXPathCompileExpr(pctxt, 1);
+
+    if( pctxt->error != XPATH_EXPRESSION_OK )
+    {
+        xmlXPathFreeParserContext(pctxt);
+        return(NULL);
+    }
+
+    if (*pctxt->cur != 0) {
+	/*
+	 * aleksey: in some cases this line prints *second* error message
+	 * (see bug #78858) and probably this should be fixed.
+	 * However, we are not sure that all error messages are printed
+	 * out in other places. It's not critical so we leave it as-is for now
+	 */
+	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
+	comp = NULL;
+    } else {
+	comp = pctxt->comp;
+	pctxt->comp = NULL;
+    }
+    xmlXPathFreeParserContext(pctxt);
+
+    if (comp != NULL) {
+	comp->expr = xmlStrdup(str);
+#ifdef DEBUG_EVAL_COUNTS
+	comp->string = xmlStrdup(str);
+	comp->nb = 0;
+#endif
+	if ((comp->expr != NULL) &&
+	    (comp->nbStep > 2) &&
+	    (comp->last >= 0) &&
+	    (xmlXPathCanRewriteDosExpression(comp->expr) == 1))
+	{
+	    xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]);
+	}
+    }
+    return(comp);
+}
+
+/**
+ * xmlXPathCompile:
+ * @str:  the XPath expression
+ *
+ * Compile an XPath expression
+ *
+ * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathCompExprPtr
+xmlXPathCompile(const xmlChar *str) {
+    return(xmlXPathCtxtCompile(NULL, str));
+}
+
+/**
+ * xmlXPathCompiledEvalInternal:
+ * @comp:  the compiled XPath expression
+ * @ctxt:  the XPath context
+ * @resObj: the resulting XPath object or NULL
+ * @toBool: 1 if only a boolean result is requested
+ *
+ * Evaluate the Precompiled XPath expression in the given context.
+ * The caller has to free @resObj.
+ *
+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
+ *         the caller has to free the object.
+ */
+static int
+xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
+			     xmlXPathContextPtr ctxt,
+			     xmlXPathObjectPtr *resObj,
+			     int toBool)
+{
+    xmlXPathParserContextPtr pctxt;
+#ifndef LIBXML_THREAD_ENABLED
+    static int reentance = 0;
+#endif
+    int res;
+
+    CHECK_CTXT_NEG(ctxt)
+
+    if (comp == NULL)
+	return(-1);
+    xmlXPathInit();
+
+#ifndef LIBXML_THREAD_ENABLED
+    reentance++;
+    if (reentance > 1)
+	xmlXPathDisableOptimizer = 1;
+#endif
+
+#ifdef DEBUG_EVAL_COUNTS
+    comp->nb++;
+    if ((comp->string != NULL) && (comp->nb > 100)) {
+	fprintf(stderr, "100 x %s\n", comp->string);
+	comp->nb = 0;
+    }
+#endif
+    pctxt = xmlXPathCompParserContext(comp, ctxt);
+    res = xmlXPathRunEval(pctxt, toBool);
+
+    if (resObj) {
+	if (pctxt->value == NULL) {
+	    xmlGenericError(xmlGenericErrorContext,
+		"xmlXPathCompiledEval: evaluation failed\n");
+	    *resObj = NULL;
+	} else {
+	    *resObj = valuePop(pctxt);
+	}
+    }
+
+    /*
+    * Pop all remaining objects from the stack.
+    */
+    if (pctxt->valueNr > 0) {
+	xmlXPathObjectPtr tmp;
+	int stack = 0;
+
+	do {
+	    tmp = valuePop(pctxt);
+	    if (tmp != NULL) {
+		stack++;
+		xmlXPathReleaseObject(ctxt, tmp);
+	    }
+	} while (tmp != NULL);
+	if ((stack != 0) &&
+	    ((toBool) || ((resObj) && (*resObj))))
+	{
+	    xmlGenericError(xmlGenericErrorContext,
+		"xmlXPathCompiledEval: %d objects left on the stack.\n",
+		stack);
+	}
+    }
+
+    if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) {
+	xmlXPathFreeObject(*resObj);
+	*resObj = NULL;
+    }
+    pctxt->comp = NULL;
+    xmlXPathFreeParserContext(pctxt);
+#ifndef LIBXML_THREAD_ENABLED
+    reentance--;
+#endif
+
+    return(res);
+}
+
+/**
+ * xmlXPathCompiledEval:
+ * @comp:  the compiled XPath expression
+ * @ctx:  the XPath context
+ *
+ * Evaluate the Precompiled XPath expression in the given context.
+ *
+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathObjectPtr
+xmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx)
+{
+    xmlXPathObjectPtr res = NULL;
+
+    xmlXPathCompiledEvalInternal(comp, ctx, &res, 0);
+    return(res);
+}
+
+/**
+ * xmlXPathCompiledEvalToBoolean:
+ * @comp:  the compiled XPath expression
+ * @ctxt:  the XPath context
+ *
+ * Applies the XPath boolean() function on the result of the given
+ * compiled expression.
+ *
+ * Returns 1 if the expression evaluated to true, 0 if to false and
+ *         -1 in API and internal errors.
+ */
+int
+xmlXPathCompiledEvalToBoolean(xmlXPathCompExprPtr comp,
+			      xmlXPathContextPtr ctxt)
+{
+    return(xmlXPathCompiledEvalInternal(comp, ctxt, NULL, 1));
+}
+
+/**
+ * xmlXPathEvalExpr:
+ * @ctxt:  the XPath Parser context
+ *
+ * Parse and evaluate an XPath expression in the given context,
+ * then push the result on the context stack
+ */
+void
+xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
+#ifdef XPATH_STREAMING
+    xmlXPathCompExprPtr comp;
+#endif
+
+    if (ctxt == NULL) return;
+
+#ifdef XPATH_STREAMING
+    comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base);
+    if (comp != NULL) {
+        if (ctxt->comp != NULL)
+	    xmlXPathFreeCompExpr(ctxt->comp);
+        ctxt->comp = comp;
+	if (ctxt->cur != NULL)
+	    while (*ctxt->cur != 0) ctxt->cur++;
+    } else
+#endif
+    {
+	xmlXPathCompileExpr(ctxt, 1);
+	/*
+	* In this scenario the expression string will sit in ctxt->base.
+	*/
+	if ((ctxt->error == XPATH_EXPRESSION_OK) &&
+	    (ctxt->comp != NULL) &&
+	    (ctxt->base != NULL) &&
+	    (ctxt->comp->nbStep > 2) &&
+	    (ctxt->comp->last >= 0) &&
+	    (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1))
+	{
+	    xmlXPathRewriteDOSExpression(ctxt->comp,
+		&ctxt->comp->steps[ctxt->comp->last]);
+	}
+    }
+    CHECK_ERROR;
+    xmlXPathRunEval(ctxt, 0);
+}
+
+/**
+ * xmlXPathEval:
+ * @str:  the XPath expression
+ * @ctx:  the XPath context
+ *
+ * Evaluate the XPath Location Path in the given context.
+ *
+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathObjectPtr
+xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
+    xmlXPathParserContextPtr ctxt;
+    xmlXPathObjectPtr res, tmp, init = NULL;
+    int stack = 0;
+
+    CHECK_CTXT(ctx)
+
+    xmlXPathInit();
+
+    ctxt = xmlXPathNewParserContext(str, ctx);
+    if (ctxt == NULL)
+        return NULL;
+    xmlXPathEvalExpr(ctxt);
+
+    if (ctxt->value == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlXPathEval: evaluation failed\n");
+	res = NULL;
+    } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL)
+#ifdef XPATH_STREAMING
+            && (ctxt->comp->stream == NULL)
+#endif
+	      ) {
+	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
+	res = NULL;
+    } else {
+	res = valuePop(ctxt);
+    }
+
+    do {
+        tmp = valuePop(ctxt);
+	if (tmp != NULL) {
+	    if (tmp != init)
+		stack++;
+	    xmlXPathReleaseObject(ctx, tmp);
+        }
+    } while (tmp != NULL);
+    if ((stack != 0) && (res != NULL)) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlXPathEval: %d object left on the stack\n",
+	        stack);
+    }
+    if (ctxt->error != XPATH_EXPRESSION_OK) {
+	xmlXPathFreeObject(res);
+	res = NULL;
+    }
+
+    xmlXPathFreeParserContext(ctxt);
+    return(res);
+}
+
+/**
+ * xmlXPathEvalExpression:
+ * @str:  the XPath expression
+ * @ctxt:  the XPath context
+ *
+ * Evaluate the XPath expression in the given context.
+ *
+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathObjectPtr
+xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
+    xmlXPathParserContextPtr pctxt;
+    xmlXPathObjectPtr res, tmp;
+    int stack = 0;
+
+    CHECK_CTXT(ctxt)
+
+    xmlXPathInit();
+
+    pctxt = xmlXPathNewParserContext(str, ctxt);
+    if (pctxt == NULL)
+        return NULL;
+    xmlXPathEvalExpr(pctxt);
+
+    if ((*pctxt->cur != 0) || (pctxt->error != XPATH_EXPRESSION_OK)) {
+	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
+	res = NULL;
+    } else {
+	res = valuePop(pctxt);
+    }
+    do {
+        tmp = valuePop(pctxt);
+	if (tmp != NULL) {
+	    xmlXPathReleaseObject(ctxt, tmp);
+	    stack++;
+	}
+    } while (tmp != NULL);
+    if ((stack != 0) && (res != NULL)) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlXPathEvalExpression: %d object left on the stack\n",
+	        stack);
+    }
+    xmlXPathFreeParserContext(pctxt);
+    return(res);
+}
+
+/************************************************************************
+ *									*
+ *	Extra functions not pertaining to the XPath spec		*
+ *									*
+ ************************************************************************/
+/**
+ * xmlXPathEscapeUriFunction:
+ * @ctxt:  the XPath Parser context
+ * @nargs:  the number of arguments
+ *
+ * Implement the escape-uri() XPath function
+ *    string escape-uri(string $str, bool $escape-reserved)
+ *
+ * This function applies the URI escaping rules defined in section 2 of [RFC
+ * 2396] to the string supplied as $uri-part, which typically represents all
+ * or part of a URI. The effect of the function is to replace any special
+ * character in the string by an escape sequence of the form %xx%yy...,
+ * where xxyy... is the hexadecimal representation of the octets used to
+ * represent the character in UTF-8.
+ *
+ * The set of characters that are escaped depends on the setting of the
+ * boolean argument $escape-reserved.
+ *
+ * If $escape-reserved is true, all characters are escaped other than lower
+ * case letters a-z, upper case letters A-Z, digits 0-9, and the characters
+ * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!"
+ * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only
+ * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and
+ * A-F).
+ *
+ * If $escape-reserved is false, the behavior differs in that characters
+ * referred to in [RFC 2396] as reserved characters are not escaped. These
+ * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
+ *
+ * [RFC 2396] does not define whether escaped URIs should use lower case or
+ * upper case for hexadecimal digits. To ensure that escaped URIs can be
+ * compared using string comparison functions, this function must always use
+ * the upper-case letters A-F.
+ *
+ * Generally, $escape-reserved should be set to true when escaping a string
+ * that is to form a single part of a URI, and to false when escaping an
+ * entire URI or URI reference.
+ *
+ * In the case of non-ascii characters, the string is encoded according to
+ * utf-8 and then converted according to RFC 2396.
+ *
+ * Examples
+ *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true())
+ *  returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean"
+ *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false())
+ *  returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean"
+ *
+ */
+static void
+xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr str;
+    int escape_reserved;
+    xmlBufferPtr target;
+    xmlChar *cptr;
+    xmlChar escape[4];
+
+    CHECK_ARITY(2);
+
+    escape_reserved = xmlXPathPopBoolean(ctxt);
+
+    CAST_TO_STRING;
+    str = valuePop(ctxt);
+
+    target = xmlBufferCreate();
+
+    escape[0] = '%';
+    escape[3] = 0;
+
+    if (target) {
+	for (cptr = str->stringval; *cptr; cptr++) {
+	    if ((*cptr >= 'A' && *cptr <= 'Z') ||
+		(*cptr >= 'a' && *cptr <= 'z') ||
+		(*cptr >= '0' && *cptr <= '9') ||
+		*cptr == '-' || *cptr == '_' || *cptr == '.' ||
+		*cptr == '!' || *cptr == '~' || *cptr == '*' ||
+		*cptr == '\''|| *cptr == '(' || *cptr == ')' ||
+		(*cptr == '%' &&
+		 ((cptr[1] >= 'A' && cptr[1] <= 'F') ||
+		  (cptr[1] >= 'a' && cptr[1] <= 'f') ||
+		  (cptr[1] >= '0' && cptr[1] <= '9')) &&
+		 ((cptr[2] >= 'A' && cptr[2] <= 'F') ||
+		  (cptr[2] >= 'a' && cptr[2] <= 'f') ||
+		  (cptr[2] >= '0' && cptr[2] <= '9'))) ||
+		(!escape_reserved &&
+		 (*cptr == ';' || *cptr == '/' || *cptr == '?' ||
+		  *cptr == ':' || *cptr == '@' || *cptr == '&' ||
+		  *cptr == '=' || *cptr == '+' || *cptr == '$' ||
+		  *cptr == ','))) {
+		xmlBufferAdd(target, cptr, 1);
+	    } else {
+		if ((*cptr >> 4) < 10)
+		    escape[1] = '0' + (*cptr >> 4);
+		else
+		    escape[1] = 'A' - 10 + (*cptr >> 4);
+		if ((*cptr & 0xF) < 10)
+		    escape[2] = '0' + (*cptr & 0xF);
+		else
+		    escape[2] = 'A' - 10 + (*cptr & 0xF);
+
+		xmlBufferAdd(target, &escape[0], 3);
+	    }
+	}
+    }
+    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
+	xmlBufferContent(target)));
+    xmlBufferFree(target);
+    xmlXPathReleaseObject(ctxt->context, str);
+}
+
+/**
+ * xmlXPathRegisterAllFunctions:
+ * @ctxt:  the XPath context
+ *
+ * Registers all default XPath functions in this context
+ */
+void
+xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
+{
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
+                         xmlXPathBooleanFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
+                         xmlXPathCeilingFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
+                         xmlXPathCountFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
+                         xmlXPathConcatFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
+                         xmlXPathContainsFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
+                         xmlXPathIdFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
+                         xmlXPathFalseFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
+                         xmlXPathFloorFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
+                         xmlXPathLastFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
+                         xmlXPathLangFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
+                         xmlXPathLocalNameFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
+                         xmlXPathNotFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
+                         xmlXPathNameFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
+                         xmlXPathNamespaceURIFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
+                         xmlXPathNormalizeFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
+                         xmlXPathNumberFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
+                         xmlXPathPositionFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
+                         xmlXPathRoundFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
+                         xmlXPathStringFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
+                         xmlXPathStringLengthFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
+                         xmlXPathStartsWithFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
+                         xmlXPathSubstringFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
+                         xmlXPathSubstringBeforeFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
+                         xmlXPathSubstringAfterFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
+                         xmlXPathSumFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
+                         xmlXPathTrueFunction);
+    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
+                         xmlXPathTranslateFunction);
+
+    xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
+	 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
+                         xmlXPathEscapeUriFunction);
+}
+
+#endif /* LIBXML_XPATH_ENABLED */
+#define bottom_xpath
+#include "elfgcchack.h"
diff --git a/src/xpointer.c b/src/xpointer.c
new file mode 100644
index 0000000..ae5dd08
--- /dev/null
+++ b/src/xpointer.c
@@ -0,0 +1,3004 @@
+/*
+ * xpointer.c : Code to handle XML Pointer
+ *
+ * Base implementation was made accordingly to
+ * W3C Candidate Recommendation 7 June 2000
+ * http://www.w3.org/TR/2000/CR-xptr-20000607
+ *
+ * Added support for the element() scheme described in:
+ * W3C Proposed Recommendation 13 November 2002
+ * http://www.w3.org/TR/2002/PR-xptr-element-20021113/  
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#define IN_LIBXML
+#include "libxml.h"
+
+/*
+ * TODO: better handling of error cases, the full expression should
+ *       be parsed beforehand instead of a progressive evaluation
+ * TODO: Access into entities references are not supported now ...
+ *       need a start to be able to pop out of entities refs since
+ *       parent is the endity declaration, not the ref.
+ */
+
+#include <string.h>
+#include <libxml/xpointer.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parserInternals.h>
+#include <libxml/uri.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/globals.h>
+
+#ifdef LIBXML_XPTR_ENABLED
+
+/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
+#define XPTR_XMLNS_SCHEME
+
+/* #define DEBUG_RANGES */
+#ifdef DEBUG_RANGES
+#ifdef LIBXML_DEBUG_ENABLED
+#include <libxml/debugXML.h>
+#endif
+#endif
+
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+#define STRANGE 							\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Internal error at %s:%d\n",				\
+            __FILE__, __LINE__);
+
+/************************************************************************
+ *									*
+ * 		Some factorized error routines				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPtrErrMemory:
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPtrErrMemory(const char *extra)
+{
+    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
+		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
+		    NULL, NULL, 0, 0,
+		    "Memory allocation failed : %s\n", extra);
+}
+
+/**
+ * xmlXPtrErr:
+ * @ctxt:  an XPTR evaluation context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
+           const char * msg, const xmlChar *extra)
+{
+    if (ctxt != NULL)
+        ctxt->error = error;
+    if ((ctxt == NULL) || (ctxt->context == NULL)) {
+	__xmlRaiseError(NULL, NULL, NULL,
+			NULL, NULL, XML_FROM_XPOINTER, error,
+			XML_ERR_ERROR, NULL, 0,
+			(const char *) extra, NULL, NULL, 0, 0,
+			msg, extra);
+	return;
+    }
+    ctxt->context->lastError.domain = XML_FROM_XPOINTER;
+    ctxt->context->lastError.code = error;
+    ctxt->context->lastError.level = XML_ERR_ERROR;
+    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
+    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
+    ctxt->context->lastError.node = ctxt->context->debugNode;
+    if (ctxt->context->error != NULL) {
+	ctxt->context->error(ctxt->context->userData,
+	                     &ctxt->context->lastError);
+    } else {
+	__xmlRaiseError(NULL, NULL, NULL,
+			NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
+			error, XML_ERR_ERROR, NULL, 0,
+			(const char *) extra, (const char *) ctxt->base, NULL,
+			ctxt->cur - ctxt->base, 0,
+			msg, extra);
+    }
+}
+
+/************************************************************************
+ *									*
+ *		A few helper functions for child sequences		*
+ *									*
+ ************************************************************************/
+/* xmlXPtrAdvanceNode is a private function, but used by xinclude.c */
+xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level);
+/**
+ * xmlXPtrGetArity:
+ * @cur:  the node
+ *
+ * Returns the number of child for an element, -1 in case of error
+ */
+static int
+xmlXPtrGetArity(xmlNodePtr cur) {
+    int i;
+    if (cur == NULL) 
+	return(-1);
+    cur = cur->children;
+    for (i = 0;cur != NULL;cur = cur->next) {
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_DOCUMENT_NODE) ||
+	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	    i++;
+	}
+    }
+    return(i);
+}
+
+/**
+ * xmlXPtrGetIndex:
+ * @cur:  the node
+ *
+ * Returns the index of the node in its parent children list, -1
+ *         in case of error
+ */
+static int
+xmlXPtrGetIndex(xmlNodePtr cur) {
+    int i;
+    if (cur == NULL) 
+	return(-1);
+    for (i = 1;cur != NULL;cur = cur->prev) {
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_DOCUMENT_NODE) ||
+	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	    i++;
+	}
+    }
+    return(i);
+}
+
+/**
+ * xmlXPtrGetNthChild:
+ * @cur:  the node
+ * @no:  the child number
+ *
+ * Returns the @no'th element child of @cur or NULL
+ */
+static xmlNodePtr
+xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
+    int i;
+    if (cur == NULL) 
+	return(cur);
+    cur = cur->children;
+    for (i = 0;i <= no;cur = cur->next) {
+	if (cur == NULL) 
+	    return(cur);
+	if ((cur->type == XML_ELEMENT_NODE) ||
+	    (cur->type == XML_DOCUMENT_NODE) ||
+	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
+	    i++;
+	    if (i == no)
+		break;
+	}
+    }
+    return(cur);
+}
+
+/************************************************************************
+ *									*
+ *		Handling of XPointer specific types			*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPtrCmpPoints:
+ * @node1:  the first node
+ * @index1:  the first index
+ * @node2:  the second node
+ * @index2:  the second index
+ *
+ * Compare two points w.r.t document order
+ *
+ * Returns -2 in case of error 1 if first point < second point, 0 if
+ *         that's the same point, -1 otherwise
+ */
+static int
+xmlXPtrCmpPoints(xmlNodePtr node1, int index1, xmlNodePtr node2, int index2) {
+    if ((node1 == NULL) || (node2 == NULL))
+	return(-2);
+    /*
+     * a couple of optimizations which will avoid computations in most cases
+     */
+    if (node1 == node2) {
+	if (index1 < index2)
+	    return(1);
+	if (index1 > index2)
+	    return(-1);
+	return(0);
+    }
+    return(xmlXPathCmpNodes(node1, node2));
+}
+
+/**
+ * xmlXPtrNewPoint:
+ * @node:  the xmlNodePtr
+ * @indx:  the indx within the node
+ *
+ * Create a new xmlXPathObjectPtr of type point
+ *
+ * Returns the newly created object.
+ */
+static xmlXPathObjectPtr
+xmlXPtrNewPoint(xmlNodePtr node, int indx) {
+    xmlXPathObjectPtr ret;
+
+    if (node == NULL)
+	return(NULL);
+    if (indx < 0)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating point");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_POINT;
+    ret->user = (void *) node;
+    ret->index = indx;
+    return(ret);
+}
+
+/**
+ * xmlXPtrRangeCheckOrder:
+ * @range:  an object range
+ *
+ * Make sure the points in the range are in the right order
+ */
+static void
+xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
+    int tmp;
+    xmlNodePtr tmp2;
+    if (range == NULL)
+	return;
+    if (range->type != XPATH_RANGE)
+	return;
+    if (range->user2 == NULL)
+	return;
+    tmp = xmlXPtrCmpPoints(range->user, range->index,
+	                     range->user2, range->index2);
+    if (tmp == -1) {
+	tmp2 = range->user;
+	range->user = range->user2;
+	range->user2 = tmp2;
+	tmp = range->index;
+	range->index = range->index2;
+	range->index2 = tmp;
+    }
+}
+
+/**
+ * xmlXPtrRangesEqual:
+ * @range1:  the first range
+ * @range2:  the second range
+ *
+ * Compare two ranges
+ *
+ * Returns 1 if equal, 0 otherwise
+ */
+static int
+xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
+    if (range1 == range2)
+	return(1);
+    if ((range1 == NULL) || (range2 == NULL))
+	return(0);
+    if (range1->type != range2->type)
+	return(0);
+    if (range1->type != XPATH_RANGE)
+	return(0);
+    if (range1->user != range2->user)
+	return(0);
+    if (range1->index != range2->index)
+	return(0);
+    if (range1->user2 != range2->user2)
+	return(0);
+    if (range1->index2 != range2->index2)
+	return(0);
+    return(1);
+}
+
+/**
+ * xmlXPtrNewRange:
+ * @start:  the starting node
+ * @startindex:  the start index
+ * @end:  the ending point
+ * @endindex:  the ending index
+ *
+ * Create a new xmlXPathObjectPtr of type range
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRange(xmlNodePtr start, int startindex,
+	        xmlNodePtr end, int endindex) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+    if (startindex < 0)
+	return(NULL);
+    if (endindex < 0)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = startindex;
+    ret->user2 = end;
+    ret->index2 = endindex;
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewRangePoints:
+ * @start:  the starting point
+ * @end:  the ending point
+ *
+ * Create a new xmlXPathObjectPtr of type range using 2 Points
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+    if (start->type != XPATH_POINT)
+	return(NULL);
+    if (end->type != XPATH_POINT)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start->user;
+    ret->index = start->index;
+    ret->user2 = end->user;
+    ret->index2 = end->index;
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewRangePointNode:
+ * @start:  the starting point
+ * @end:  the ending node
+ *
+ * Create a new xmlXPathObjectPtr of type range from a point to a node
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+    if (start->type != XPATH_POINT)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start->user;
+    ret->index = start->index;
+    ret->user2 = end;
+    ret->index2 = -1;
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewRangeNodePoint:
+ * @start:  the starting node
+ * @end:  the ending point
+ *
+ * Create a new xmlXPathObjectPtr of type range from a node to a point
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+    if (start->type != XPATH_POINT)
+	return(NULL);
+    if (end->type != XPATH_POINT)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = -1;
+    ret->user2 = end->user;
+    ret->index2 = end->index;
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewRangeNodes:
+ * @start:  the starting node
+ * @end:  the ending node
+ *
+ * Create a new xmlXPathObjectPtr of type range using 2 nodes
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = -1;
+    ret->user2 = end;
+    ret->index2 = -1;
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewCollapsedRange:
+ * @start:  the starting and ending node
+ *
+ * Create a new xmlXPathObjectPtr of type range using a single nodes
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewCollapsedRange(xmlNodePtr start) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = -1;
+    ret->user2 = NULL;
+    ret->index2 = -1;
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewRangeNodeObject:
+ * @start:  the starting node
+ * @end:  the ending object
+ *
+ * Create a new xmlXPathObjectPtr of type range from a not to an object
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+    xmlXPathObjectPtr ret;
+
+    if (start == NULL)
+	return(NULL);
+    if (end == NULL)
+	return(NULL);
+    switch (end->type) {
+	case XPATH_POINT:
+	case XPATH_RANGE:
+	    break;
+	case XPATH_NODESET:
+	    /*
+	     * Empty set ... 
+	     */
+	    if (end->nodesetval->nodeNr <= 0)
+		return(NULL);
+	    break;
+	default:
+	    /* TODO */
+	    return(NULL);
+    }
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = -1;
+    switch (end->type) {
+	case XPATH_POINT:
+	    ret->user2 = end->user;
+	    ret->index2 = end->index;
+	    break;
+	case XPATH_RANGE:
+	    ret->user2 = end->user2;
+	    ret->index2 = end->index2;
+	    break;
+	case XPATH_NODESET: {
+	    ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+	    ret->index2 = -1;
+	    break;
+	}
+	default:
+	    STRANGE
+	    return(NULL);
+    }
+    xmlXPtrRangeCheckOrder(ret);
+    return(ret);
+}
+
+#define XML_RANGESET_DEFAULT	10
+
+/**
+ * xmlXPtrLocationSetCreate:
+ * @val:  an initial xmlXPathObjectPtr, or NULL
+ *
+ * Create a new xmlLocationSetPtr of type double and of value @val
+ *
+ * Returns the newly created object.
+ */
+xmlLocationSetPtr
+xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
+    xmlLocationSetPtr ret;
+
+    ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating locationset");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlLocationSet));
+    if (val != NULL) {
+        ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
+					     sizeof(xmlXPathObjectPtr));
+	if (ret->locTab == NULL) {
+	    xmlXPtrErrMemory("allocating locationset");
+	    xmlFree(ret);
+	    return(NULL);
+	}
+	memset(ret->locTab, 0 ,
+	       XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
+        ret->locMax = XML_RANGESET_DEFAULT;
+	ret->locTab[ret->locNr++] = val;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPtrLocationSetAdd:
+ * @cur:  the initial range set
+ * @val:  a new xmlXPathObjectPtr
+ *
+ * add a new xmlXPathObjectPtr to an existing LocationSet
+ * If the location already exist in the set @val is freed.
+ */
+void
+xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
+    int i;
+
+    if ((cur == NULL) || (val == NULL)) return;
+
+    /*
+     * check against doublons
+     */
+    for (i = 0;i < cur->locNr;i++) {
+	if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
+	    xmlXPathFreeObject(val);
+	    return;
+	}
+    }
+
+    /*
+     * grow the locTab if needed
+     */
+    if (cur->locMax == 0) {
+        cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
+					     sizeof(xmlXPathObjectPtr));
+	if (cur->locTab == NULL) {
+	    xmlXPtrErrMemory("adding location to set");
+	    return;
+	}
+	memset(cur->locTab, 0 ,
+	       XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
+        cur->locMax = XML_RANGESET_DEFAULT;
+    } else if (cur->locNr == cur->locMax) {
+        xmlXPathObjectPtr *temp;
+
+        cur->locMax *= 2;
+	temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax *
+				      sizeof(xmlXPathObjectPtr));
+	if (temp == NULL) {
+	    xmlXPtrErrMemory("adding location to set");
+	    return;
+	}
+	cur->locTab = temp;
+    }
+    cur->locTab[cur->locNr++] = val;
+}
+
+/**
+ * xmlXPtrLocationSetMerge:
+ * @val1:  the first LocationSet
+ * @val2:  the second LocationSet
+ *
+ * Merges two rangesets, all ranges from @val2 are added to @val1
+ *
+ * Returns val1 once extended or NULL in case of error.
+ */
+xmlLocationSetPtr
+xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) {
+    int i;
+
+    if (val1 == NULL) return(NULL);
+    if (val2 == NULL) return(val1);
+
+    /*
+     * !!!!! this can be optimized a lot, knowing that both
+     *       val1 and val2 already have unicity of their values.
+     */
+
+    for (i = 0;i < val2->locNr;i++)
+        xmlXPtrLocationSetAdd(val1, val2->locTab[i]);
+
+    return(val1);
+}
+
+/**
+ * xmlXPtrLocationSetDel:
+ * @cur:  the initial range set
+ * @val:  an xmlXPathObjectPtr
+ *
+ * Removes an xmlXPathObjectPtr from an existing LocationSet
+ */
+void
+xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
+    int i;
+
+    if (cur == NULL) return;
+    if (val == NULL) return;
+
+    /*
+     * check against doublons
+     */
+    for (i = 0;i < cur->locNr;i++)
+        if (cur->locTab[i] == val) break;
+
+    if (i >= cur->locNr) {
+#ifdef DEBUG
+        xmlGenericError(xmlGenericErrorContext, 
+	        "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n");
+#endif
+        return;
+    }
+    cur->locNr--;
+    for (;i < cur->locNr;i++)
+        cur->locTab[i] = cur->locTab[i + 1];
+    cur->locTab[cur->locNr] = NULL;
+}
+
+/**
+ * xmlXPtrLocationSetRemove:
+ * @cur:  the initial range set
+ * @val:  the index to remove
+ *
+ * Removes an entry from an existing LocationSet list.
+ */
+void
+xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) {
+    if (cur == NULL) return;
+    if (val >= cur->locNr) return;
+    cur->locNr--;
+    for (;val < cur->locNr;val++)
+        cur->locTab[val] = cur->locTab[val + 1];
+    cur->locTab[cur->locNr] = NULL;
+}
+
+/**
+ * xmlXPtrFreeLocationSet:
+ * @obj:  the xmlLocationSetPtr to free
+ *
+ * Free the LocationSet compound (not the actual ranges !).
+ */
+void
+xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) {
+    int i;
+
+    if (obj == NULL) return;
+    if (obj->locTab != NULL) {
+	for (i = 0;i < obj->locNr; i++) {
+            xmlXPathFreeObject(obj->locTab[i]);
+	}
+	xmlFree(obj->locTab);
+    }
+    xmlFree(obj);
+}
+
+/**
+ * xmlXPtrNewLocationSetNodes:
+ * @start:  the start NodePtr value
+ * @end:  the end NodePtr value or NULL
+ *
+ * Create a new xmlXPathObjectPtr of type LocationSet and initialize
+ * it with the single range made of the two nodes @start and @end
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating locationset");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_LOCATIONSET;
+    if (end == NULL)
+	ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start));
+    else
+	ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end));
+    return(ret);
+}
+
+/**
+ * xmlXPtrNewLocationSetNodeSet:
+ * @set:  a node set
+ *
+ * Create a new xmlXPathObjectPtr of type LocationSet and initialize
+ * it with all the nodes from @set
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating locationset");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_LOCATIONSET;
+    if (set != NULL) {
+	int i;
+	xmlLocationSetPtr newset;
+
+	newset = xmlXPtrLocationSetCreate(NULL);
+	if (newset == NULL)
+	    return(ret);
+
+	for (i = 0;i < set->nodeNr;i++)
+	    xmlXPtrLocationSetAdd(newset,
+		        xmlXPtrNewCollapsedRange(set->nodeTab[i]));
+
+	ret->user = (void *) newset;
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPtrWrapLocationSet:
+ * @val:  the LocationSet value
+ *
+ * Wrap the LocationSet @val in a new xmlXPathObjectPtr
+ *
+ * Returns the newly created object.
+ */
+xmlXPathObjectPtr
+xmlXPtrWrapLocationSet(xmlLocationSetPtr val) {
+    xmlXPathObjectPtr ret;
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating locationset");
+	return(NULL);
+    }
+    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+    ret->type = XPATH_LOCATIONSET;
+    ret->user = (void *) val;
+    return(ret);
+}
+
+/************************************************************************
+ *									*
+ *			The parser					*
+ *									*
+ ************************************************************************/
+
+static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
+
+/*
+ * Macros for accessing the content. Those should be used only by the parser,
+ * and not exported.
+ *
+ * Dirty macros, i.e. one need to make assumption on the context to use them
+ *
+ *   CUR_PTR return the current pointer to the xmlChar to be parsed.
+ *   CUR     returns the current xmlChar value, i.e. a 8 bit value
+ *           in ISO-Latin or UTF-8.
+ *           This should be used internally by the parser
+ *           only to compare to ASCII values otherwise it would break when
+ *           running with UTF-8 encoding.
+ *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
+ *           to compare on ASCII based substring.
+ *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
+ *           strings within the parser.
+ *   CURRENT Returns the current char value, with the full decoding of
+ *           UTF-8 if we are using this mode. It returns an int.
+ *   NEXT    Skip to the next character, this does the proper decoding
+ *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
+ *           It returns the pointer to the current xmlChar.
+ */
+
+#define CUR (*ctxt->cur)
+#define SKIP(val) ctxt->cur += (val)
+#define NXT(val) ctxt->cur[(val)]
+#define CUR_PTR ctxt->cur
+
+#define SKIP_BLANKS 							\
+    while (IS_BLANK_CH(*(ctxt->cur))) NEXT
+
+#define CURRENT (*ctxt->cur)
+#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
+
+/*
+ * xmlXPtrGetChildNo:
+ * @ctxt:  the XPointer Parser context
+ * @index:  the child number
+ *
+ * Move the current node of the nodeset on the stack to the
+ * given child if found
+ */
+static void
+xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
+    xmlNodePtr cur = NULL;
+    xmlXPathObjectPtr obj;
+    xmlNodeSetPtr oldset;
+
+    CHECK_TYPE(XPATH_NODESET);
+    obj = valuePop(ctxt);
+    oldset = obj->nodesetval;
+    if ((indx <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) {
+	xmlXPathFreeObject(obj);
+	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
+	return;
+    }
+    cur = xmlXPtrGetNthChild(oldset->nodeTab[0], indx);
+    if (cur == NULL) {
+	xmlXPathFreeObject(obj);
+	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
+	return;
+    }
+    oldset->nodeTab[0] = cur;
+    valuePush(ctxt, obj);
+}
+
+/**
+ * xmlXPtrEvalXPtrPart:
+ * @ctxt:  the XPointer Parser context
+ * @name:  the preparsed Scheme for the XPtrPart
+ * 
+ * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
+ *            | Scheme '(' SchemeSpecificExpr ')'
+ *
+ * Scheme   ::=  NCName - 'xpointer' [VC: Non-XPointer schemes]
+ *
+ * SchemeSpecificExpr ::= StringWithBalancedParens
+ *
+ * StringWithBalancedParens ::=  
+ *              [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
+ *              [VC: Parenthesis escaping]
+ *
+ * XPtrExpr ::= Expr [VC: Parenthesis escaping]
+ *
+ * VC: Parenthesis escaping:
+ *   The end of an XPointer part is signaled by the right parenthesis ")"
+ *   character that is balanced with the left parenthesis "(" character
+ *   that began the part. Any unbalanced parenthesis character inside the
+ *   expression, even within literals, must be escaped with a circumflex (^)
+ *   character preceding it. If the expression contains any literal
+ *   occurrences of the circumflex, each must be escaped with an additional
+ *   circumflex (that is, ^^). If the unescaped parentheses in the expression
+ *   are not balanced, a syntax error results.
+ *
+ * Parse and evaluate an XPtrPart. Basically it generates the unescaped
+ * string and if the scheme is 'xpointer' it will call the XPath interpreter.
+ * 
+ * TODO: there is no new scheme registration mechanism
+ */
+
+static void
+xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
+    xmlChar *buffer, *cur;
+    int len;
+    int level;
+
+    if (name == NULL)
+    name = xmlXPathParseName(ctxt);
+    if (name == NULL)
+	XP_ERROR(XPATH_EXPR_ERROR);
+
+    if (CUR != '(')
+	XP_ERROR(XPATH_EXPR_ERROR);
+    NEXT;
+    level = 1;
+
+    len = xmlStrlen(ctxt->cur);
+    len++;
+    buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar));
+    if (buffer == NULL) {
+        xmlXPtrErrMemory("allocating buffer");
+	return;
+    }
+
+    cur = buffer;
+    while (CUR != 0) {
+	if (CUR == ')') {
+	    level--;
+	    if (level == 0) {
+		NEXT;
+		break;
+	    }
+	} else if (CUR == '(') {
+	    level++;
+	} else if (CUR == '^') {
+	    if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) {
+	        NEXT;
+	    }
+	}
+	*cur++ = CUR;
+	NEXT;
+    }
+    *cur = 0;
+
+    if ((level != 0) && (CUR == 0)) {
+	xmlFree(buffer);
+	XP_ERROR(XPTR_SYNTAX_ERROR);
+    }
+
+    if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
+	const xmlChar *left = CUR_PTR;
+
+	CUR_PTR = buffer;
+	/*
+	 * To evaluate an xpointer scheme element (4.3) we need:
+	 *   context initialized to the root
+	 *   context position initalized to 1
+	 *   context size initialized to 1
+	 */
+	ctxt->context->node = (xmlNodePtr)ctxt->context->doc;
+	ctxt->context->proximityPosition = 1;
+	ctxt->context->contextSize = 1;
+	xmlXPathEvalExpr(ctxt);
+	CUR_PTR=left;
+    } else if (xmlStrEqual(name, (xmlChar *) "element")) {
+	const xmlChar *left = CUR_PTR;
+	xmlChar *name2;
+
+	CUR_PTR = buffer;
+	if (buffer[0] == '/') {
+	    xmlXPathRoot(ctxt);
+	    xmlXPtrEvalChildSeq(ctxt, NULL);
+	} else {
+	    name2 = xmlXPathParseName(ctxt);
+	    if (name2 == NULL) {
+		CUR_PTR = left;
+		xmlFree(buffer);
+		XP_ERROR(XPATH_EXPR_ERROR);
+	    }
+	    xmlXPtrEvalChildSeq(ctxt, name2);
+	}
+	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;
+	xmlFree(URI);
+	xmlFree(prefix);
+#endif /* XPTR_XMLNS_SCHEME */
+    } else {
+        xmlXPtrErr(ctxt, XML_XPTR_UNKNOWN_SCHEME,
+		   "unsupported scheme '%s'\n", name);
+    }
+    xmlFree(buffer);
+    xmlFree(name);
+}
+
+/**
+ * xmlXPtrEvalFullXPtr:
+ * @ctxt:  the XPointer Parser context
+ * @name:  the preparsed Scheme for the first XPtrPart
+ *
+ * FullXPtr ::= XPtrPart (S? XPtrPart)*
+ *
+ * As the specs says:
+ * -----------
+ * When multiple XPtrParts are provided, they must be evaluated in
+ * left-to-right order. If evaluation of one part fails, the nexti
+ * is evaluated. The following conditions cause XPointer part failure:
+ *
+ * - An unknown scheme
+ * - A scheme that does not locate any sub-resource present in the resource
+ * - A scheme that is not applicable to the media type of the resource
+ *
+ * The XPointer application must consume a failed XPointer part and
+ * attempt to evaluate the next one, if any. The result of the first
+ * XPointer part whose evaluation succeeds is taken to be the fragment
+ * located by the XPointer as a whole. If all the parts fail, the result
+ * for the XPointer as a whole is a sub-resource error.
+ * -----------
+ *
+ * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based
+ * expressions or other schemes.
+ */
+static void
+xmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {
+    if (name == NULL)
+    name = xmlXPathParseName(ctxt);
+    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) &&
+            (ctxt->error != XML_XPTR_UNKNOWN_SCHEME))
+	    return;
+
+	/*
+	 * If the returned value is a non-empty nodeset
+	 * or location set, return here.
+	 */
+	if (ctxt->value != NULL) {
+	    xmlXPathObjectPtr obj = ctxt->value;
+
+	    switch (obj->type) {
+		case XPATH_LOCATIONSET: {
+		    xmlLocationSetPtr loc = ctxt->value->user;
+		    if ((loc != NULL) && (loc->locNr > 0))
+			return;
+		    break;
+		}
+		case XPATH_NODESET: {
+		    xmlNodeSetPtr loc = ctxt->value->nodesetval;
+		    if ((loc != NULL) && (loc->nodeNr > 0))
+			return;
+		    break;
+		}
+		default:
+		    break;
+	    }
+
+	    /*
+	     * Evaluating to improper values is equivalent to
+	     * a sub-resource error, clean-up the stack
+	     */
+	    do {
+		obj = valuePop(ctxt);
+		if (obj != NULL) {
+		    xmlXPathFreeObject(obj);
+		}
+	    } while (obj != NULL);
+	}
+
+	/*
+	 * Is there another XPointer part.
+	 */
+	SKIP_BLANKS;
+	name = xmlXPathParseName(ctxt);
+    }
+}
+
+/**
+ * xmlXPtrEvalChildSeq:
+ * @ctxt:  the XPointer Parser context
+ * @name:  a possible ID name of the child sequence
+ *
+ *  ChildSeq ::= '/1' ('/' [0-9]*)*
+ *             | Name ('/' [0-9]*)+
+ *
+ * Parse and evaluate a Child Sequence. This routine also handle the
+ * case of a Bare Name used to get a document ID.
+ */
+static void
+xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
+    /*
+     * XPointer don't allow by syntax to address in mutirooted trees
+     * this might prove useful in some cases, warn about it.
+     */
+    if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {
+        xmlXPtrErr(ctxt, XML_XPTR_CHILDSEQ_START,
+		   "warning: ChildSeq not starting by /1\n", NULL);
+    }
+
+    if (name != NULL) {
+	valuePush(ctxt, xmlXPathNewString(name));
+	xmlFree(name);
+	xmlXPathIdFunction(ctxt, 1);
+	CHECK_ERROR;
+    }
+
+    while (CUR == '/') {
+	int child = 0;
+	NEXT;
+        
+	while ((CUR >= '0') && (CUR <= '9')) {
+	    child = child * 10 + (CUR - '0');
+	    NEXT;
+	}
+	xmlXPtrGetChildNo(ctxt, child);
+    }
+}
+
+
+/**
+ * xmlXPtrEvalXPointer:
+ * @ctxt:  the XPointer Parser context
+ *
+ *  XPointer ::= Name
+ *             | ChildSeq
+ *             | FullXPtr
+ *
+ * Parse and evaluate an XPointer
+ */
+static void
+xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
+    if (ctxt->valueTab == NULL) {
+	/* Allocate the value stack */
+	ctxt->valueTab = (xmlXPathObjectPtr *) 
+			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
+	if (ctxt->valueTab == NULL) {
+	    xmlXPtrErrMemory("allocating evaluation context");
+	    return;
+	}
+	ctxt->valueNr = 0;
+	ctxt->valueMax = 10;
+	ctxt->value = NULL;
+    }
+    SKIP_BLANKS;
+    if (CUR == '/') {
+	xmlXPathRoot(ctxt);
+        xmlXPtrEvalChildSeq(ctxt, NULL);
+    } else {
+	xmlChar *name;
+
+	name = xmlXPathParseName(ctxt);
+	if (name == NULL)
+	    XP_ERROR(XPATH_EXPR_ERROR);
+	if (CUR == '(') {
+	    xmlXPtrEvalFullXPtr(ctxt, name);
+	    /* Short evaluation */
+	    return;
+	} else {
+	    /* this handle both Bare Names and Child Sequences */
+	    xmlXPtrEvalChildSeq(ctxt, name);
+	}
+    }
+    SKIP_BLANKS;
+    if (CUR != 0)
+	XP_ERROR(XPATH_EXPR_ERROR);
+}
+
+
+/************************************************************************
+ *									*
+ *			General routines				*
+ *									*
+ ************************************************************************/
+
+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);
+
+/**
+ * xmlXPtrNewContext:
+ * @doc:  the XML document
+ * @here:  the node that directly contains the XPointer being evaluated or NULL
+ * @origin:  the element from which a user or program initiated traversal of
+ *           the link, or NULL.
+ *
+ * Create a new XPointer context
+ *
+ * Returns the xmlXPathContext just allocated.
+ */
+xmlXPathContextPtr
+xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
+    xmlXPathContextPtr ret;
+
+    ret = xmlXPathNewContext(doc);
+    if (ret == NULL)
+	return(ret);
+    ret->xptr = 1;
+    ret->here = here;
+    ret->origin = origin;
+
+    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
+	                 xmlXPtrRangeToFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"range",
+	                 xmlXPtrRangeFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
+	                 xmlXPtrRangeInsideFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",
+	                 xmlXPtrStringRangeFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",
+	                 xmlXPtrStartPointFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",
+	                 xmlXPtrEndPointFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)"here",
+	                 xmlXPtrHereFunction);
+    xmlXPathRegisterFunc(ret, (xmlChar *)" origin",
+	                 xmlXPtrOriginFunction);
+
+    return(ret);
+}
+
+/**
+ * xmlXPtrEval:
+ * @str:  the XPointer expression
+ * @ctx:  the XPointer context
+ *
+ * Evaluate the XPath Location Path in the given context.
+ *
+ * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
+ *         the caller has to free the object.
+ */
+xmlXPathObjectPtr
+xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
+    xmlXPathParserContextPtr ctxt;
+    xmlXPathObjectPtr res = NULL, tmp;
+    xmlXPathObjectPtr init = NULL;
+    int stack = 0;
+
+    xmlXPathInit();
+
+    if ((ctx == NULL) || (str == NULL))
+	return(NULL);
+
+    ctxt = xmlXPathNewParserContext(str, ctx);
+    ctxt->xptr = 1;
+    xmlXPtrEvalXPointer(ctxt);
+
+    if ((ctxt->value != NULL) &&
+	(ctxt->value->type != XPATH_NODESET) &&
+	(ctxt->value->type != XPATH_LOCATIONSET)) {
+        xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED,
+		"xmlXPtrEval: evaluation failed to return a node set\n",
+		   NULL);
+    } else {
+	res = valuePop(ctxt);
+    }
+
+    do {
+        tmp = valuePop(ctxt);
+	if (tmp != NULL) {
+	    if (tmp != init) {
+		if (tmp->type == XPATH_NODESET) {
+		    /*
+		     * Evaluation may push a root nodeset which is unused
+		     */
+		    xmlNodeSetPtr set; 
+		    set = tmp->nodesetval;
+		    if ((set->nodeNr != 1) ||
+			(set->nodeTab[0] != (xmlNodePtr) ctx->doc))
+			stack++;
+		} else
+		    stack++;    
+	    }
+	    xmlXPathFreeObject(tmp);
+        }
+    } while (tmp != NULL);
+    if (stack != 0) {
+        xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS,
+		   "xmlXPtrEval: object(s) left on the eval stack\n",
+		   NULL);
+    }
+    if (ctxt->error != XPATH_EXPRESSION_OK) {
+	xmlXPathFreeObject(res);
+	res = NULL;
+    }
+        
+    xmlXPathFreeParserContext(ctxt);
+    return(res);
+}
+
+/**
+ * xmlXPtrBuildRangeNodeList:
+ * @range:  a range object
+ *
+ * Build a node list tree copy of the range
+ *
+ * Returns an xmlNodePtr list or NULL.
+ *         the caller has to free the node tree.
+ */
+static xmlNodePtr
+xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
+    /* pointers to generated nodes */
+    xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
+    /* pointers to traversal nodes */
+    xmlNodePtr start, cur, end;
+    int index1, index2;
+
+    if (range == NULL)
+	return(NULL);
+    if (range->type != XPATH_RANGE)
+	return(NULL);
+    start = (xmlNodePtr) range->user;
+
+    if (start == NULL)
+	return(NULL);
+    end = range->user2;
+    if (end == NULL)
+	return(xmlCopyNode(start, 1));
+
+    cur = start;
+    index1 = range->index;
+    index2 = range->index2;
+    while (cur != NULL) {
+	if (cur == end) {
+	    if (cur->type == XML_TEXT_NODE) {
+		const xmlChar *content = cur->content;
+		int len;
+
+		if (content == NULL) {
+		    tmp = xmlNewTextLen(NULL, 0);
+		} else {
+		    len = index2;
+		    if ((cur == start) && (index1 > 1)) {
+			content += (index1 - 1);
+			len -= (index1 - 1);
+			index1 = 0;
+		    } else {
+			len = index2;
+		    }
+		    tmp = xmlNewTextLen(content, len);
+		}
+		/* single sub text node selection */
+		if (list == NULL)
+		    return(tmp);
+		/* prune and return full set */
+		if (last != NULL)
+		    xmlAddNextSibling(last, tmp);
+		else 
+		    xmlAddChild(parent, tmp);
+		return(list);
+	    } else {
+		tmp = xmlCopyNode(cur, 0);
+		if (list == NULL)
+		    list = tmp;
+		else {
+		    if (last != NULL)
+			xmlAddNextSibling(last, tmp);
+		    else
+			xmlAddChild(parent, tmp);
+		}
+		last = NULL;
+		parent = tmp;
+
+		if (index2 > 1) {
+		    end = xmlXPtrGetNthChild(cur, index2 - 1);
+		    index2 = 0;
+		}
+		if ((cur == start) && (index1 > 1)) {
+		    cur = xmlXPtrGetNthChild(cur, index1 - 1);
+		    index1 = 0;
+		} else {
+		    cur = cur->children;
+		}
+		/*
+		 * Now gather the remaining nodes from cur to end
+		 */
+		continue; /* while */
+	    }
+	} else if ((cur == start) &&
+		   (list == NULL) /* looks superfluous but ... */ ) {
+	    if ((cur->type == XML_TEXT_NODE) ||
+		(cur->type == XML_CDATA_SECTION_NODE)) {
+		const xmlChar *content = cur->content;
+
+		if (content == NULL) {
+		    tmp = xmlNewTextLen(NULL, 0);
+		} else {
+		    if (index1 > 1) {
+			content += (index1 - 1);
+		    }
+		    tmp = xmlNewText(content);
+		}
+		last = list = tmp;
+	    } else {
+		if ((cur == start) && (index1 > 1)) {
+		    tmp = xmlCopyNode(cur, 0);
+		    list = tmp;
+		    parent = tmp;
+		    last = NULL;
+		    cur = xmlXPtrGetNthChild(cur, index1 - 1);
+		    index1 = 0;
+		    /*
+		     * Now gather the remaining nodes from cur to end
+		     */
+		    continue; /* while */
+		}
+		tmp = xmlCopyNode(cur, 1);
+		list = tmp;
+		parent = NULL;
+		last = tmp;
+	    }
+	} else {
+	    tmp = NULL;
+	    switch (cur->type) {
+		case XML_DTD_NODE:
+		case XML_ELEMENT_DECL:
+		case XML_ATTRIBUTE_DECL:
+		case XML_ENTITY_NODE:
+		    /* Do not copy DTD informations */
+		    break;
+		case XML_ENTITY_DECL:
+		    TODO /* handle crossing entities -> stack needed */
+		    break;
+		case XML_XINCLUDE_START:
+		case XML_XINCLUDE_END:
+		    /* don't consider it part of the tree content */
+		    break;
+		case XML_ATTRIBUTE_NODE:
+		    /* Humm, should not happen ! */
+		    STRANGE
+		    break;
+		default:
+		    tmp = xmlCopyNode(cur, 1);
+		    break;
+	    }
+	    if (tmp != NULL) {
+		if ((list == NULL) || ((last == NULL) && (parent == NULL)))  {
+		    STRANGE
+		    return(NULL);
+		}
+		if (last != NULL)
+		    xmlAddNextSibling(last, tmp);
+		else {
+		    xmlAddChild(parent, tmp);
+		    last = tmp;
+		}
+	    }
+	}
+	/*
+	 * Skip to next node in document order
+	 */
+	if ((list == NULL) || ((last == NULL) && (parent == NULL)))  {
+	    STRANGE
+	    return(NULL);
+	}
+	cur = xmlXPtrAdvanceNode(cur, NULL);
+    }
+    return(list);
+}
+
+/**
+ * xmlXPtrBuildNodeList:
+ * @obj:  the XPointer result from the evaluation.
+ *
+ * Build a node list tree copy of the XPointer result.
+ * This will drop Attributes and Namespace declarations.
+ *
+ * Returns an xmlNodePtr list or NULL.
+ *         the caller has to free the node tree.
+ */
+xmlNodePtr
+xmlXPtrBuildNodeList(xmlXPathObjectPtr obj) {
+    xmlNodePtr list = NULL, last = NULL;
+    int i;
+
+    if (obj == NULL)
+	return(NULL);
+    switch (obj->type) {
+        case XPATH_NODESET: {
+	    xmlNodeSetPtr set = obj->nodesetval;
+	    if (set == NULL)
+		return(NULL);
+	    for (i = 0;i < set->nodeNr;i++) {
+		if (set->nodeTab[i] == NULL)
+		    continue;
+		switch (set->nodeTab[i]->type) {
+		    case XML_TEXT_NODE:
+		    case XML_CDATA_SECTION_NODE:
+		    case XML_ELEMENT_NODE:
+		    case XML_ENTITY_REF_NODE:
+		    case XML_ENTITY_NODE:
+		    case XML_PI_NODE:
+		    case XML_COMMENT_NODE:
+		    case XML_DOCUMENT_NODE:
+		    case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+		    case XML_DOCB_DOCUMENT_NODE:
+#endif
+		    case XML_XINCLUDE_START:
+		    case XML_XINCLUDE_END:
+			break;
+		    case XML_ATTRIBUTE_NODE:
+		    case XML_NAMESPACE_DECL:
+		    case XML_DOCUMENT_TYPE_NODE:
+		    case XML_DOCUMENT_FRAG_NODE:
+		    case XML_NOTATION_NODE:
+		    case XML_DTD_NODE:
+		    case XML_ELEMENT_DECL:
+		    case XML_ATTRIBUTE_DECL:
+		    case XML_ENTITY_DECL:
+			continue; /* for */
+		}
+		if (last == NULL)
+		    list = last = xmlCopyNode(set->nodeTab[i], 1);
+		else {
+		    xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1));
+		    if (last->next != NULL)
+			last = last->next;
+		}
+	    }
+	    break;
+	}
+	case XPATH_LOCATIONSET: {
+	    xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
+	    if (set == NULL)
+		return(NULL);
+	    for (i = 0;i < set->locNr;i++) {
+		if (last == NULL)
+		    list = last = xmlXPtrBuildNodeList(set->locTab[i]);
+		else
+		    xmlAddNextSibling(last,
+			    xmlXPtrBuildNodeList(set->locTab[i]));
+		if (last != NULL) {
+		    while (last->next != NULL)
+			last = last->next;
+		}
+	    }
+	    break;
+	}
+	case XPATH_RANGE:
+	    return(xmlXPtrBuildRangeNodeList(obj));
+	case XPATH_POINT:
+	    return(xmlCopyNode(obj->user, 0));
+	default:
+	    break;
+    }
+    return(list);
+}
+
+/************************************************************************
+ *									*
+ *			XPointer functions				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlXPtrNbLocChildren:
+ * @node:  an xmlNodePtr
+ *
+ * Count the number of location children of @node or the length of the
+ * string value in case of text/PI/Comments nodes
+ *
+ * Returns the number of location children
+ */
+static int
+xmlXPtrNbLocChildren(xmlNodePtr node) {
+    int ret = 0;
+    if (node == NULL)
+	return(-1);
+    switch (node->type) {
+        case XML_HTML_DOCUMENT_NODE:
+        case XML_DOCUMENT_NODE:
+        case XML_ELEMENT_NODE:
+	    node = node->children;
+	    while (node != NULL) {
+		if (node->type == XML_ELEMENT_NODE)
+		    ret++;
+		node = node->next;
+	    }
+	    break;
+        case XML_ATTRIBUTE_NODE:
+	    return(-1);
+
+        case XML_PI_NODE:
+        case XML_COMMENT_NODE:
+        case XML_TEXT_NODE:
+        case XML_CDATA_SECTION_NODE:
+        case XML_ENTITY_REF_NODE:
+	    ret = xmlStrlen(node->content);
+	    break;
+	default:
+	    return(-1);
+    }
+    return(ret);
+}
+
+/**
+ * xmlXPtrHereFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing here() operation 
+ * as described in 5.4.3
+ */
+static void
+xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+
+    if (ctxt->context->here == NULL)
+	XP_ERROR(XPTR_SYNTAX_ERROR);
+    
+    valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
+}
+
+/**
+ * xmlXPtrOriginFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing origin() operation 
+ * as described in 5.4.3
+ */
+static void
+xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    CHECK_ARITY(0);
+
+    if (ctxt->context->origin == NULL)
+	XP_ERROR(XPTR_SYNTAX_ERROR);
+    
+    valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
+}
+
+/**
+ * xmlXPtrStartPointFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing start-point() operation 
+ * as described in 5.4.3
+ * ----------------
+ * location-set start-point(location-set)
+ *
+ * For each location x in the argument location-set, start-point adds a
+ * location of type point to the result location-set. That point represents
+ * the start point of location x and is determined by the following rules:
+ *
+ * - If x is of type point, the start point is x.
+ * - If x is of type range, the start point is the start point of x.
+ * - If x is of type root, element, text, comment, or processing instruction,
+ * - the container node of the start point is x and the index is 0.
+ * - If x is of type attribute or namespace, the function must signal a
+ *   syntax error.
+ * ----------------
+ *
+ */
+static void
+xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr tmp, obj, point;
+    xmlLocationSetPtr newset = NULL;
+    xmlLocationSetPtr oldset = NULL;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_LOCATIONSET) &&
+	 (ctxt->value->type != XPATH_NODESET)))
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+    obj = valuePop(ctxt);
+    if (obj->type == XPATH_NODESET) {
+	/*
+	 * First convert to a location set
+	 */
+	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
+	xmlXPathFreeObject(obj);
+	obj = tmp;
+    }
+
+    newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+	xmlXPathFreeObject(obj);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
+    oldset = (xmlLocationSetPtr) obj->user;
+    if (oldset != NULL) {
+	int i;
+
+	for (i = 0; i < oldset->locNr; i++) {
+	    tmp = oldset->locTab[i];
+	    if (tmp == NULL)
+		continue;
+	    point = NULL;
+	    switch (tmp->type) {
+		case XPATH_POINT:
+		    point = xmlXPtrNewPoint(tmp->user, tmp->index);
+		    break;
+		case XPATH_RANGE: {
+		    xmlNodePtr node = tmp->user;
+		    if (node != NULL) {
+			if (node->type == XML_ATTRIBUTE_NODE) {
+			    /* TODO: Namespace Nodes ??? */
+			    xmlXPathFreeObject(obj);
+			    xmlXPtrFreeLocationSet(newset);
+			    XP_ERROR(XPTR_SYNTAX_ERROR);
+			}
+			point = xmlXPtrNewPoint(node, tmp->index);
+		    }
+		    break;
+	        }
+		default:
+		    /*** Should we raise an error ?
+		    xmlXPathFreeObject(obj);
+		    xmlXPathFreeObject(newset);
+		    XP_ERROR(XPATH_INVALID_TYPE)
+		    ***/
+		    break;
+	    }
+            if (point != NULL)
+		xmlXPtrLocationSetAdd(newset, point);
+	}
+    }
+    xmlXPathFreeObject(obj);
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+}
+
+/**
+ * xmlXPtrEndPointFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing end-point() operation 
+ * as described in 5.4.3
+ * ----------------------------
+ * location-set end-point(location-set)
+ *
+ * For each location x in the argument location-set, end-point adds a
+ * location of type point to the result location-set. That point represents
+ * the end point of location x and is determined by the following rules:
+ *
+ * - If x is of type point, the resulting point is x.
+ * - If x is of type range, the resulting point is the end point of x.
+ * - If x is of type root or element, the container node of the resulting
+ *   point is x and the index is the number of location children of x.
+ * - If x is of type text, comment, or processing instruction, the container
+ *   node of the resulting point is x and the index is the length of the
+ *   string-value of x.
+ * - If x is of type attribute or namespace, the function must signal a
+ *   syntax error.
+ * ----------------------------
+ */
+static void
+xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr tmp, obj, point;
+    xmlLocationSetPtr newset = NULL;
+    xmlLocationSetPtr oldset = NULL;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_LOCATIONSET) &&
+	 (ctxt->value->type != XPATH_NODESET)))
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+    obj = valuePop(ctxt);
+    if (obj->type == XPATH_NODESET) {
+	/*
+	 * First convert to a location set
+	 */
+	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
+	xmlXPathFreeObject(obj);
+	obj = tmp;
+    }
+
+    newset = xmlXPtrLocationSetCreate(NULL);
+    oldset = (xmlLocationSetPtr) obj->user;
+    if (oldset != NULL) {
+	int i;
+
+	for (i = 0; i < oldset->locNr; i++) {
+	    tmp = oldset->locTab[i];
+	    if (tmp == NULL)
+		continue;
+	    point = NULL;
+	    switch (tmp->type) {
+		case XPATH_POINT:
+		    point = xmlXPtrNewPoint(tmp->user, tmp->index);
+		    break;
+		case XPATH_RANGE: {
+		    xmlNodePtr node = tmp->user2;
+		    if (node != NULL) {
+			if (node->type == XML_ATTRIBUTE_NODE) {
+			    /* TODO: Namespace Nodes ??? */
+			    xmlXPathFreeObject(obj);
+			    xmlXPtrFreeLocationSet(newset);
+			    XP_ERROR(XPTR_SYNTAX_ERROR);
+			}
+			point = xmlXPtrNewPoint(node, tmp->index2);
+		    } else if (tmp->user == NULL) {
+			point = xmlXPtrNewPoint(node,
+				       xmlXPtrNbLocChildren(node));
+		    }
+		    break;
+	        }
+		default:
+		    /*** Should we raise an error ?
+		    xmlXPathFreeObject(obj);
+		    xmlXPathFreeObject(newset);
+		    XP_ERROR(XPATH_INVALID_TYPE)
+		    ***/
+		    break;
+	    }
+            if (point != NULL)
+		xmlXPtrLocationSetAdd(newset, point);
+	}
+    }
+    xmlXPathFreeObject(obj);
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+}
+
+
+/**
+ * xmlXPtrCoveringRange:
+ * @ctxt:  the XPointer Parser context
+ * @loc:  the location for which the covering range must be computed
+ *
+ * A covering range is a range that wholly encompasses a location
+ * Section 5.3.3. Covering Ranges for All Location Types
+ *        http://www.w3.org/TR/xptr#N2267
+ *
+ * Returns a new location or NULL in case of error
+ */
+static xmlXPathObjectPtr
+xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
+    if (loc == NULL)
+	return(NULL);
+    if ((ctxt == NULL) || (ctxt->context == NULL) ||
+	(ctxt->context->doc == NULL))
+	return(NULL);
+    switch (loc->type) {
+        case XPATH_POINT:
+	    return(xmlXPtrNewRange(loc->user, loc->index,
+			           loc->user, loc->index));
+        case XPATH_RANGE:
+	    if (loc->user2 != NULL) {
+		return(xmlXPtrNewRange(loc->user, loc->index,
+			              loc->user2, loc->index2));
+	    } else {
+		xmlNodePtr node = (xmlNodePtr) loc->user;
+		if (node == (xmlNodePtr) ctxt->context->doc) {
+		    return(xmlXPtrNewRange(node, 0, node,
+					   xmlXPtrGetArity(node)));
+		} else {
+		    switch (node->type) {
+			case XML_ATTRIBUTE_NODE:
+			/* !!! our model is slightly different than XPath */
+			    return(xmlXPtrNewRange(node, 0, node,
+					           xmlXPtrGetArity(node)));
+			case XML_ELEMENT_NODE:
+			case XML_TEXT_NODE:
+			case XML_CDATA_SECTION_NODE:
+			case XML_ENTITY_REF_NODE:
+			case XML_PI_NODE:
+			case XML_COMMENT_NODE:
+			case XML_DOCUMENT_NODE:
+			case XML_NOTATION_NODE:
+			case XML_HTML_DOCUMENT_NODE: {
+			    int indx = xmlXPtrGetIndex(node);
+			     
+			    node = node->parent;
+			    return(xmlXPtrNewRange(node, indx - 1,
+					           node, indx + 1));
+			}
+			default:
+			    return(NULL);
+		    }
+		}
+	    }
+	default:
+	    TODO /* missed one case ??? */
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPtrRangeFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing the range() function 5.4.3
+ *  location-set range(location-set )
+ *
+ *  The range function returns ranges covering the locations in
+ *  the argument location-set. For each location x in the argument
+ *  location-set, a range location representing the covering range of
+ *  x is added to the result location-set.
+ */
+static void
+xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    int i;
+    xmlXPathObjectPtr set;
+    xmlLocationSetPtr oldset;
+    xmlLocationSetPtr newset;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_LOCATIONSET) &&
+	 (ctxt->value->type != XPATH_NODESET)))
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+    set = valuePop(ctxt);
+    if (set->type == XPATH_NODESET) {
+	xmlXPathObjectPtr tmp;
+
+	/*
+	 * First convert to a location set
+	 */
+	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
+	xmlXPathFreeObject(set);
+	set = tmp;
+    }
+    oldset = (xmlLocationSetPtr) set->user;
+
+    /*
+     * The loop is to compute the covering range for each item and add it
+     */
+    newset = xmlXPtrLocationSetCreate(NULL);
+    for (i = 0;i < oldset->locNr;i++) {
+	xmlXPtrLocationSetAdd(newset,
+		xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
+    }
+
+    /*
+     * Save the new value and cleanup
+     */
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+    xmlXPathFreeObject(set);
+}
+
+/**
+ * xmlXPtrInsideRange:
+ * @ctxt:  the XPointer Parser context
+ * @loc:  the location for which the inside range must be computed
+ *
+ * A inside range is a range described in the range-inside() description
+ *
+ * Returns a new location or NULL in case of error
+ */
+static xmlXPathObjectPtr
+xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
+    if (loc == NULL)
+	return(NULL);
+    if ((ctxt == NULL) || (ctxt->context == NULL) ||
+	(ctxt->context->doc == NULL))
+	return(NULL);
+    switch (loc->type) {
+        case XPATH_POINT: {
+	    xmlNodePtr node = (xmlNodePtr) loc->user;
+	    switch (node->type) {
+		case XML_PI_NODE:
+		case XML_COMMENT_NODE:
+		case XML_TEXT_NODE:
+		case XML_CDATA_SECTION_NODE: {
+		    if (node->content == NULL) {
+			return(xmlXPtrNewRange(node, 0, node, 0));
+		    } else {
+			return(xmlXPtrNewRange(node, 0, node,
+					       xmlStrlen(node->content)));
+		    }
+		}
+		case XML_ATTRIBUTE_NODE:
+		case XML_ELEMENT_NODE:
+		case XML_ENTITY_REF_NODE:
+		case XML_DOCUMENT_NODE:
+		case XML_NOTATION_NODE:
+		case XML_HTML_DOCUMENT_NODE: {
+		    return(xmlXPtrNewRange(node, 0, node,
+					   xmlXPtrGetArity(node)));
+		}
+		default:
+		    break;
+	    }
+	    return(NULL);
+	}
+        case XPATH_RANGE: {
+	    xmlNodePtr node = (xmlNodePtr) loc->user;
+	    if (loc->user2 != NULL) {
+		return(xmlXPtrNewRange(node, loc->index,
+			               loc->user2, loc->index2));
+	    } else {
+		switch (node->type) {
+		    case XML_PI_NODE:
+		    case XML_COMMENT_NODE:
+		    case XML_TEXT_NODE:
+		    case XML_CDATA_SECTION_NODE: {
+			if (node->content == NULL) {
+			    return(xmlXPtrNewRange(node, 0, node, 0));
+			} else {
+			    return(xmlXPtrNewRange(node, 0, node,
+						   xmlStrlen(node->content)));
+			}
+		    }
+		    case XML_ATTRIBUTE_NODE:
+		    case XML_ELEMENT_NODE:
+		    case XML_ENTITY_REF_NODE:
+		    case XML_DOCUMENT_NODE:
+		    case XML_NOTATION_NODE:
+		    case XML_HTML_DOCUMENT_NODE: {
+			return(xmlXPtrNewRange(node, 0, node,
+					       xmlXPtrGetArity(node)));
+		    }
+		    default:
+			break;
+		}
+		return(NULL);
+	    }
+        }
+	default:
+	    TODO /* missed one case ??? */
+    }
+    return(NULL);
+}
+
+/**
+ * xmlXPtrRangeInsideFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing the range-inside() function 5.4.3
+ *  location-set range-inside(location-set )
+ *
+ *  The range-inside function returns ranges covering the contents of
+ *  the locations in the argument location-set. For each location x in
+ *  the argument location-set, a range location is added to the result
+ *  location-set. If x is a range location, then x is added to the
+ *  result location-set. If x is not a range location, then x is used
+ *  as the container location of the start and end points of the range
+ *  location to be added; the index of the start point of the range is
+ *  zero; if the end point is a character point then its index is the
+ *  length of the string-value of x, and otherwise is the number of
+ *  location children of x.
+ *
+ */
+static void
+xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    int i;
+    xmlXPathObjectPtr set;
+    xmlLocationSetPtr oldset;
+    xmlLocationSetPtr newset;
+
+    CHECK_ARITY(1);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_LOCATIONSET) &&
+	 (ctxt->value->type != XPATH_NODESET)))
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+    set = valuePop(ctxt);
+    if (set->type == XPATH_NODESET) {
+	xmlXPathObjectPtr tmp;
+
+	/*
+	 * First convert to a location set
+	 */
+	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
+	xmlXPathFreeObject(set);
+	set = tmp;
+    }
+    oldset = (xmlLocationSetPtr) set->user;
+
+    /*
+     * The loop is to compute the covering range for each item and add it
+     */
+    newset = xmlXPtrLocationSetCreate(NULL);
+    for (i = 0;i < oldset->locNr;i++) {
+	xmlXPtrLocationSetAdd(newset,
+		xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
+    }
+
+    /*
+     * Save the new value and cleanup
+     */
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+    xmlXPathFreeObject(set);
+}
+
+/**
+ * xmlXPtrRangeToFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Implement the range-to() XPointer function
+ */
+void
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    xmlXPathObjectPtr range;
+    const xmlChar *cur;
+    xmlXPathObjectPtr res, obj;
+    xmlXPathObjectPtr tmp;
+    xmlLocationSetPtr newset = NULL;
+    xmlNodeSetPtr oldset;
+    int i;
+
+    if (ctxt == NULL) return;
+    CHECK_ARITY(1);
+    /*
+     * Save the expression pointer since we will have to evaluate
+     * it multiple times. Initialize the new set.
+     */
+    CHECK_TYPE(XPATH_NODESET);
+    obj = valuePop(ctxt);
+    oldset = obj->nodesetval;
+    ctxt->context->node = NULL;
+
+    cur = ctxt->cur;
+    newset = xmlXPtrLocationSetCreate(NULL);
+    
+    for (i = 0; i < oldset->nodeNr; i++) {
+	ctxt->cur = cur;
+
+	/*
+	 * Run the evaluation with a node list made of a single item
+	 * in the nodeset.
+	 */
+	ctxt->context->node = oldset->nodeTab[i];
+	tmp = xmlXPathNewNodeSet(ctxt->context->node);
+	valuePush(ctxt, tmp);
+
+	xmlXPathEvalExpr(ctxt);
+	CHECK_ERROR;
+
+	/*
+	 * The result of the evaluation need to be tested to
+	 * decided whether the filter succeeded or not
+	 */
+	res = valuePop(ctxt);
+	range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
+	if (range != NULL) {
+	    xmlXPtrLocationSetAdd(newset, range);
+	}
+
+	/*
+	 * Cleanup
+	 */
+	if (res != NULL)
+	    xmlXPathFreeObject(res);
+	if (ctxt->value == tmp) {
+	    res = valuePop(ctxt);
+	    xmlXPathFreeObject(res);
+	}
+	
+	ctxt->context->node = NULL;
+    }
+
+    /*
+     * The result is used as the new evaluation set.
+     */
+    xmlXPathFreeObject(obj);
+    ctxt->context->node = NULL;
+    ctxt->context->contextSize = -1;
+    ctxt->context->proximityPosition = -1;
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+}
+
+/**
+ * xmlXPtrAdvanceNode:
+ * @cur:  the node
+ * @level: incremented/decremented to show level in tree
+ *
+ * Advance to the next element or text node in document order
+ * TODO: add a stack for entering/exiting entities 
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+xmlNodePtr
+xmlXPtrAdvanceNode(xmlNodePtr cur, int *level) {
+next:
+    if (cur == NULL)
+	return(NULL);
+    if (cur->children != NULL) {
+        cur = cur->children ;
+	if (level != NULL)
+	    (*level)++;
+	goto found;
+    }
+skip:		/* This label should only be needed if something is wrong! */
+    if (cur->next != NULL) {
+	cur = cur->next;
+	goto found;
+    }
+    do {
+        cur = cur->parent;
+	if (level != NULL)
+	    (*level)--;
+        if (cur == NULL) return(NULL);
+        if (cur->next != NULL) {
+	    cur = cur->next;
+	    goto found;
+	}
+    } while (cur != NULL);
+
+found:
+    if ((cur->type != XML_ELEMENT_NODE) &&
+	(cur->type != XML_TEXT_NODE) &&
+	(cur->type != XML_DOCUMENT_NODE) &&
+	(cur->type != XML_HTML_DOCUMENT_NODE) &&
+	(cur->type != XML_CDATA_SECTION_NODE)) {
+	    if (cur->type == XML_ENTITY_REF_NODE) {	/* Shouldn't happen */
+		TODO
+		goto skip;
+	    }
+	    goto next;
+	}
+    return(cur);
+}
+
+/**
+ * xmlXPtrAdvanceChar:
+ * @node:  the node
+ * @indx:  the indx
+ * @bytes:  the number of bytes
+ *
+ * Advance a point of the associated number of bytes (not UTF8 chars)
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+static int
+xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
+    xmlNodePtr cur;
+    int pos;
+    int len;
+
+    if ((node == NULL) || (indx == NULL))
+	return(-1);
+    cur = *node;
+    if (cur == NULL)
+	return(-1);
+    pos = *indx;
+
+    while (bytes >= 0) {
+	/*
+	 * First position to the beginning of the first text node
+	 * corresponding to this point
+	 */
+	while ((cur != NULL) &&
+	       ((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;
+	    } else {
+		cur = xmlXPtrAdvanceNode(cur, NULL);
+		pos = 0;
+	    }
+	}
+
+	if (cur == NULL) {
+	    *node = NULL;
+	    *indx = 0;
+	    return(-1);
+	}
+
+	/*
+	 * if there is no move needed return the current value.
+	 */
+	if (pos == 0) pos = 1;
+	if (bytes == 0) {
+	    *node = cur;
+	    *indx = pos;
+	    return(0);
+	}
+	/*
+	 * We should have a text (or cdata) node ... 
+	 */
+	len = 0;
+	if ((cur->type != XML_ELEMENT_NODE) &&
+            (cur->content != NULL)) {
+	    len = xmlStrlen(cur->content);
+	}
+	if (pos > len) {
+	    /* Strange, the indx in the text node is greater than it's len */
+	    STRANGE
+	    pos = len;
+	}
+	if (pos + bytes >= len) {
+	    bytes -= (len - pos);
+	    cur = xmlXPtrAdvanceNode(cur, NULL);
+	    pos = 0;
+	} else if (pos + bytes < len) {
+	    pos += bytes;
+	    *node = cur;
+	    *indx = pos;
+	    return(0);
+	}
+    }
+    return(-1);
+}
+
+/**
+ * xmlXPtrMatchString:
+ * @string:  the string to search
+ * @start:  the start textnode
+ * @startindex:  the start index
+ * @end:  the end textnode IN/OUT
+ * @endindex:  the end index IN/OUT
+ *
+ * Check whether the document contains @string at the position
+ * (@start, @startindex) and limited by the (@end, @endindex) point
+ *
+ * Returns -1 in case of failure, 0 if not found, 1 if found in which case
+ *            (@start, @startindex) will indicate the position of the beginning
+ *            of the range and (@end, @endindex) will indicate the end
+ *            of the range
+ */
+static int
+xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
+	            xmlNodePtr *end, int *endindex) {
+    xmlNodePtr cur;
+    int pos; /* 0 based */
+    int len; /* in bytes */
+    int stringlen; /* in bytes */
+    int match;
+
+    if (string == NULL)
+	return(-1);
+    if (start == NULL)
+	return(-1);
+    if ((end == NULL) || (endindex == NULL))
+	return(-1);
+    cur = start;
+    if (cur == NULL)
+	return(-1);
+    pos = startindex - 1;
+    stringlen = xmlStrlen(string);
+
+    while (stringlen > 0) {
+	if ((cur == *end) && (pos + stringlen > *endindex))
+	    return(0);
+
+	if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
+	    len = xmlStrlen(cur->content);
+	    if (len >= pos + stringlen) {
+		match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
+		if (match) {
+#ifdef DEBUG_RANGES
+		    xmlGenericError(xmlGenericErrorContext,
+			    "found range %d bytes at index %d of ->",
+			    stringlen, pos + 1);
+		    xmlDebugDumpString(stdout, cur->content);
+		    xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+		    *end = cur;
+		    *endindex = pos + stringlen;
+		    return(1);
+		} else {
+		    return(0);
+		}
+	    } else {
+                int sub = len - pos;
+		match = (!xmlStrncmp(&cur->content[pos], string, sub));
+		if (match) {
+#ifdef DEBUG_RANGES
+		    xmlGenericError(xmlGenericErrorContext,
+			    "found subrange %d bytes at index %d of ->",
+			    sub, pos + 1);
+		    xmlDebugDumpString(stdout, cur->content);
+		    xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+                    string = &string[sub];
+		    stringlen -= sub;
+		} else {
+		    return(0);
+		}
+	    }
+	}
+	cur = xmlXPtrAdvanceNode(cur, NULL);
+	if (cur == NULL)
+	    return(0);
+	pos = 0;
+    }
+    return(1);
+}
+
+/**
+ * xmlXPtrSearchString:
+ * @string:  the string to search
+ * @start:  the start textnode IN/OUT
+ * @startindex:  the start index IN/OUT
+ * @end:  the end textnode
+ * @endindex:  the end index
+ *
+ * Search the next occurrence of @string within the document content
+ * until the (@end, @endindex) point is reached
+ *
+ * Returns -1 in case of failure, 0 if not found, 1 if found in which case
+ *            (@start, @startindex) will indicate the position of the beginning
+ *            of the range and (@end, @endindex) will indicate the end
+ *            of the range
+ */
+static int
+xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
+	            xmlNodePtr *end, int *endindex) {
+    xmlNodePtr cur;
+    const xmlChar *str;
+    int pos; /* 0 based */
+    int len; /* in bytes */
+    xmlChar first;
+
+    if (string == NULL)
+	return(-1);
+    if ((start == NULL) || (startindex == NULL))
+	return(-1);
+    if ((end == NULL) || (endindex == NULL))
+	return(-1);
+    cur = *start;
+    if (cur == NULL)
+	return(-1);
+    pos = *startindex - 1;
+    first = string[0];
+
+    while (cur != NULL) {
+	if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
+	    len = xmlStrlen(cur->content);
+	    while (pos <= len) {
+		if (first != 0) {
+		    str = xmlStrchr(&cur->content[pos], first);
+		    if (str != NULL) {
+			pos = (str - (xmlChar *)(cur->content));
+#ifdef DEBUG_RANGES
+			xmlGenericError(xmlGenericErrorContext,
+				"found '%c' at index %d of ->",
+				first, pos + 1);
+			xmlDebugDumpString(stdout, cur->content);
+			xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+			if (xmlXPtrMatchString(string, cur, pos + 1,
+					       end, endindex)) {
+			    *start = cur;
+			    *startindex = pos + 1;
+			    return(1);
+			}
+			pos++;
+		    } else {
+			pos = len + 1;
+		    }
+		} else {
+		    /*
+		     * An empty string is considered to match before each
+		     * character of the string-value and after the final
+		     * character. 
+		     */
+#ifdef DEBUG_RANGES
+		    xmlGenericError(xmlGenericErrorContext,
+			    "found '' at index %d of ->",
+			    pos + 1);
+		    xmlDebugDumpString(stdout, cur->content);
+		    xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+		    *start = cur;
+		    *startindex = pos + 1;
+		    *end = cur;
+		    *endindex = pos + 1;
+		    return(1);
+		}
+	    }
+	}
+	if ((cur == *end) && (pos >= *endindex))
+	    return(0);
+	cur = xmlXPtrAdvanceNode(cur, NULL);
+	if (cur == NULL)
+	    return(0);
+	pos = 1;
+    }
+    return(0);
+}
+
+/**
+ * xmlXPtrGetLastChar:
+ * @node:  the node
+ * @index:  the index
+ *
+ * Computes the point coordinates of the last char of this point
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+static int
+xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) {
+    xmlNodePtr cur;
+    int pos, len = 0;
+
+    if ((node == NULL) || (indx == NULL))
+	return(-1);
+    cur = *node;
+    pos = *indx;
+
+    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);
+	}
+    }
+    while (cur != NULL) {
+	if (cur->last != NULL)
+	    cur = cur->last;
+	else if ((cur->type != XML_ELEMENT_NODE) &&
+	         (cur->content != NULL)) {
+	    len = xmlStrlen(cur->content);
+	    break;
+	} else {
+	    return(-1);
+	}
+    }
+    if (cur == NULL)
+	return(-1);
+    *node = cur;
+    *indx = len;
+    return(0);
+}
+
+/**
+ * xmlXPtrGetStartPoint:
+ * @obj:  an range
+ * @node:  the resulting node
+ * @indx:  the resulting index
+ *
+ * read the object and return the start point coordinates.
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+static int
+xmlXPtrGetStartPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
+    if ((obj == NULL) || (node == NULL) || (indx == NULL))
+	return(-1);
+
+    switch (obj->type) {
+        case XPATH_POINT:
+	    *node = obj->user;
+	    if (obj->index <= 0)
+		*indx = 0;
+	    else
+		*indx = obj->index;
+	    return(0);
+        case XPATH_RANGE:
+	    *node = obj->user;
+	    if (obj->index <= 0)
+		*indx = 0;
+	    else
+		*indx = obj->index;
+	    return(0);
+	default:
+	    break;
+    }
+    return(-1);
+}
+
+/**
+ * xmlXPtrGetEndPoint:
+ * @obj:  an range
+ * @node:  the resulting node
+ * @indx:  the resulting indx
+ *
+ * read the object and return the end point coordinates.
+ *
+ * Returns -1 in case of failure, 0 otherwise
+ */
+static int
+xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
+    if ((obj == NULL) || (node == NULL) || (indx == NULL))
+	return(-1);
+
+    switch (obj->type) {
+        case XPATH_POINT:
+	    *node = obj->user;
+	    if (obj->index <= 0)
+		*indx = 0;
+	    else
+		*indx = obj->index;
+	    return(0);
+        case XPATH_RANGE:
+	    *node = obj->user;
+	    if (obj->index <= 0)
+		*indx = 0;
+	    else
+		*indx = obj->index;
+	    return(0);
+	default:
+	    break;
+    }
+    return(-1);
+}
+
+/**
+ * xmlXPtrStringRangeFunction:
+ * @ctxt:  the XPointer Parser context
+ * @nargs:  the number of args
+ *
+ * Function implementing the string-range() function
+ * range as described in 5.4.2 
+ *
+ * ------------------------------
+ * [Definition: For each location in the location-set argument,
+ * string-range returns a set of string ranges, a set of substrings in a
+ * string. Specifically, the string-value of the location is searched for
+ * substrings that match the string argument, and the resulting location-set
+ * will contain a range location for each non-overlapping match.]
+ * An empty string is considered to match before each character of the
+ * string-value and after the final character. Whitespace in a string
+ * is matched literally, with no normalization except that provided by
+ * XML for line ends. The third argument gives the position of the first
+ * character to be in the resulting range, relative to the start of the
+ * match. The default value is 1, which makes the range start immediately
+ * before the first character of the matched string. The fourth argument
+ * gives the number of characters in the range; the default is that the
+ * range extends to the end of the matched string.
+ *
+ * Element boundaries, as well as entire embedded nodes such as processing
+ * instructions and comments, are ignored as defined in [XPath].
+ *
+ * If the string in the second argument is not found in the string-value
+ * of the location, or if a value in the third or fourth argument indicates
+ * a string that is beyond the beginning or end of the document, the
+ * expression fails.
+ *
+ * The points of the range-locations in the returned location-set will
+ * all be character points.
+ * ------------------------------
+ */
+static void
+xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+    int i, startindex, endindex = 0, fendindex;
+    xmlNodePtr start, end = 0, fend;
+    xmlXPathObjectPtr set;
+    xmlLocationSetPtr oldset;
+    xmlLocationSetPtr newset;
+    xmlXPathObjectPtr string;
+    xmlXPathObjectPtr position = NULL;
+    xmlXPathObjectPtr number = NULL;
+    int found, pos = 0, num = 0;
+
+    /*
+     * Grab the arguments
+     */
+    if ((nargs < 2) || (nargs > 4))
+	XP_ERROR(XPATH_INVALID_ARITY);
+
+    if (nargs >= 4) {
+	CHECK_TYPE(XPATH_NUMBER);
+	number = valuePop(ctxt);
+	if (number != NULL)
+	    num = (int) number->floatval;
+    }
+    if (nargs >= 3) {
+	CHECK_TYPE(XPATH_NUMBER);
+	position = valuePop(ctxt);
+	if (position != NULL)
+	    pos = (int) position->floatval;
+    }
+    CHECK_TYPE(XPATH_STRING);
+    string = valuePop(ctxt);
+    if ((ctxt->value == NULL) ||
+	((ctxt->value->type != XPATH_LOCATIONSET) &&
+	 (ctxt->value->type != XPATH_NODESET)))
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+    set = valuePop(ctxt);
+    newset = xmlXPtrLocationSetCreate(NULL);
+    if (set->nodesetval == NULL) {
+        goto error;
+    }
+    if (set->type == XPATH_NODESET) {
+	xmlXPathObjectPtr tmp;
+
+	/*
+	 * First convert to a location set
+	 */
+	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
+	xmlXPathFreeObject(set);
+	set = tmp;
+    }
+    oldset = (xmlLocationSetPtr) set->user;
+
+    /*
+     * The loop is to search for each element in the location set
+     * the list of location set corresponding to that search
+     */
+    for (i = 0;i < oldset->locNr;i++) {
+#ifdef DEBUG_RANGES
+	xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
+#endif
+
+	xmlXPtrGetStartPoint(oldset->locTab[i], &start, &startindex);
+	xmlXPtrGetEndPoint(oldset->locTab[i], &end, &endindex);
+	xmlXPtrAdvanceChar(&start, &startindex, 0);
+	xmlXPtrGetLastChar(&end, &endindex);
+
+#ifdef DEBUG_RANGES
+	xmlGenericError(xmlGenericErrorContext,
+		"from index %d of ->", startindex);
+	xmlDebugDumpString(stdout, start->content);
+	xmlGenericError(xmlGenericErrorContext, "\n");
+	xmlGenericError(xmlGenericErrorContext,
+		"to index %d of ->", endindex);
+	xmlDebugDumpString(stdout, end->content);
+	xmlGenericError(xmlGenericErrorContext, "\n");
+#endif
+	do {
+            fend = end;
+            fendindex = endindex;
+	    found = xmlXPtrSearchString(string->stringval, &start, &startindex,
+		                        &fend, &fendindex);
+	    if (found == 1) {
+		if (position == NULL) {
+		    xmlXPtrLocationSetAdd(newset,
+			 xmlXPtrNewRange(start, startindex, fend, fendindex));
+		} else if (xmlXPtrAdvanceChar(&start, &startindex,
+			                      pos - 1) == 0) {
+		    if ((number != NULL) && (num > 0)) {
+			int rindx;
+			xmlNodePtr rend;
+			rend = start;
+			rindx = startindex - 1;
+			if (xmlXPtrAdvanceChar(&rend, &rindx,
+				               num) == 0) {
+			    xmlXPtrLocationSetAdd(newset,
+					xmlXPtrNewRange(start, startindex,
+							rend, rindx));
+			}
+		    } else if ((number != NULL) && (num <= 0)) {
+			xmlXPtrLocationSetAdd(newset,
+				    xmlXPtrNewRange(start, startindex,
+						    start, startindex));
+		    } else {
+			xmlXPtrLocationSetAdd(newset,
+				    xmlXPtrNewRange(start, startindex,
+						    fend, fendindex));
+		    }
+		}
+		start = fend;
+		startindex = fendindex;
+		if (string->stringval[0] == 0)
+		    startindex++;
+	    }
+	} while (found == 1);
+    }
+
+    /*
+     * Save the new value and cleanup
+     */
+error:
+    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+    xmlXPathFreeObject(set);
+    xmlXPathFreeObject(string);
+    if (position) xmlXPathFreeObject(position);
+    if (number) xmlXPathFreeObject(number);
+}
+
+/**
+ * xmlXPtrEvalRangePredicate:
+ * @ctxt:  the XPointer Parser context
+ *
+ *  [8]   Predicate ::=   '[' PredicateExpr ']'
+ *  [9]   PredicateExpr ::=   Expr 
+ *
+ * Evaluate a predicate as in xmlXPathEvalPredicate() but for
+ * a Location Set instead of a node set
+ */
+void
+xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
+    const xmlChar *cur;
+    xmlXPathObjectPtr res;
+    xmlXPathObjectPtr obj, tmp;
+    xmlLocationSetPtr newset = NULL;
+    xmlLocationSetPtr oldset;
+    int i;
+
+    if (ctxt == NULL) return;
+
+    SKIP_BLANKS;
+    if (CUR != '[') {
+	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
+    }
+    NEXT;
+    SKIP_BLANKS;
+
+    /*
+     * Extract the old set, and then evaluate the result of the
+     * expression for all the element in the set. use it to grow
+     * up a new set.
+     */
+    CHECK_TYPE(XPATH_LOCATIONSET);
+    obj = valuePop(ctxt);
+    oldset = obj->user;
+    ctxt->context->node = NULL;
+
+    if ((oldset == NULL) || (oldset->locNr == 0)) {
+	ctxt->context->contextSize = 0;
+	ctxt->context->proximityPosition = 0;
+	xmlXPathEvalExpr(ctxt);
+	res = valuePop(ctxt);
+	if (res != NULL)
+	    xmlXPathFreeObject(res);
+	valuePush(ctxt, obj);
+	CHECK_ERROR;
+    } else {
+	/*
+	 * Save the expression pointer since we will have to evaluate
+	 * it multiple times. Initialize the new set.
+	 */
+        cur = ctxt->cur;
+	newset = xmlXPtrLocationSetCreate(NULL);
+	
+        for (i = 0; i < oldset->locNr; i++) {
+	    ctxt->cur = cur;
+
+	    /*
+	     * Run the evaluation with a node list made of a single item
+	     * in the nodeset.
+	     */
+	    ctxt->context->node = oldset->locTab[i]->user;
+	    tmp = xmlXPathNewNodeSet(ctxt->context->node);
+	    valuePush(ctxt, tmp);
+	    ctxt->context->contextSize = oldset->locNr;
+	    ctxt->context->proximityPosition = i + 1;
+
+	    xmlXPathEvalExpr(ctxt);
+	    CHECK_ERROR;
+
+	    /*
+	     * The result of the evaluation need to be tested to
+	     * decided whether the filter succeeded or not
+	     */
+	    res = valuePop(ctxt);
+	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+	        xmlXPtrLocationSetAdd(newset,
+			xmlXPathObjectCopy(oldset->locTab[i]));
+	    }
+
+	    /*
+	     * Cleanup
+	     */
+	    if (res != NULL)
+		xmlXPathFreeObject(res);
+	    if (ctxt->value == tmp) {
+		res = valuePop(ctxt);
+		xmlXPathFreeObject(res);
+	    }
+	    
+	    ctxt->context->node = NULL;
+	}
+
+	/*
+	 * The result is used as the new evaluation set.
+	 */
+	xmlXPathFreeObject(obj);
+	ctxt->context->node = NULL;
+	ctxt->context->contextSize = -1;
+	ctxt->context->proximityPosition = -1;
+	valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+    }
+    if (CUR != ']') {
+	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
+    }
+
+    NEXT;
+    SKIP_BLANKS;
+}
+
+#define bottom_xpointer
+#include "elfgcchack.h"
+#endif
+
diff --git a/win32/config.h b/win32/config.h
new file mode 100644
index 0000000..5112ce6
--- /dev/null
+++ b/win32/config.h
@@ -0,0 +1,126 @@
+#ifndef __LIBXML_WIN32_CONFIG__
+#define __LIBXML_WIN32_CONFIG__
+
+#define HAVE_CTYPE_H
+#define HAVE_STDARG_H
+#define HAVE_MALLOC_H
+#define HAVE_ERRNO_H
+
+#if defined(_WIN32_WCE)
+#undef HAVE_ERRNO_H
+#include <windows.h>
+#include "wincecompat.h"
+#else
+#define HAVE_SYS_STAT_H
+#define HAVE__STAT
+#define HAVE_STAT
+#define HAVE_STDLIB_H
+#define HAVE_TIME_H
+#define HAVE_FCNTL_H
+#include <io.h>
+#include <direct.h>
+#endif
+
+#include <libxml/xmlversion.h>
+
+#ifndef ICONV_CONST
+#define ICONV_CONST const
+#endif
+
+#ifdef NEED_SOCKETS
+#include <wsockcompat.h>
+#endif
+
+/*
+ * Windows platforms may define except 
+ */
+#undef except
+
+#define HAVE_ISINF
+#define HAVE_ISNAN
+#include <math.h>
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+/* MS C-runtime has functions which can be used in order to determine if
+   a given floating-point variable contains NaN, (+-)INF. These are 
+   preferred, because floating-point technology is considered propriatary
+   by MS and we can assume that their functions know more about their 
+   oddities than we do. */
+#include <float.h>
+/* Bjorn Reese figured a quite nice construct for isinf() using the _fpclass
+   function. */
+#ifndef isinf
+#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
+	: ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
+#endif
+/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
+#ifndef isnan
+#define isnan(d) (_isnan(d))
+#endif
+#else /* _MSC_VER */
+#ifndef isinf
+static int isinf (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 1;
+        } else if (val == -0.5) {
+            return -1;
+        } else {
+            return 0;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#ifndef isnan
+static int isnan (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 0;
+        } else if (val == -0.5) {
+            return 0;
+        } else {
+            return 1;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#endif /* _MSC_VER */
+
+#if defined(_MSC_VER)
+#define mkdir(p,m) _mkdir(p)
+#if _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+#if _MSC_VER < 1500
+#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+#endif
+#elif defined(__MINGW32__)
+#define mkdir(p,m) _mkdir(p)
+#endif
+
+/* Threading API to use should be specified here for compatibility reasons.
+   This is however best specified on the compiler's command-line. */
+#if defined(LIBXML_THREAD_ENABLED)
+#if !defined(HAVE_PTHREAD_H) && !defined(HAVE_WIN32_THREADS) && !defined(_WIN32_WCE)
+#define HAVE_WIN32_THREADS
+#endif
+#endif
+
+/* Some third-party libraries far from our control assume the following
+   is defined, which it is not if we don't include windows.h. */
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!(FALSE))
+#endif
+
+#endif /* __LIBXML_WIN32_CONFIG__ */
+
diff --git a/win32/include/libxml/xmlversion.h b/win32/include/libxml/xmlversion.h
new file mode 100644
index 0000000..90f38d5
--- /dev/null
+++ b/win32/include/libxml/xmlversion.h
@@ -0,0 +1,467 @@
+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.7.7"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 20707
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "20707"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA ""
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * 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(20707);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 1
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if 1
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if 1
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if 1
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if 1
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if 1
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if 1
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if 1
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 0
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 0
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if 1
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 1
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if 1
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 1
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 1
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 1
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 1
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 1
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 1
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ICU_ENABLED:
+ *
+ * Whether icu support is available
+ */
+#if 1
+#define LIBXML_ICU_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if 0
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 1
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 1
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 1
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if 1
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION ".dll" 
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if 0
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+